Go / C / Python / Java 四语言对照学习总览
目录
12.8 Java record 与 Python dataclass
Java 26 预览:Structured Concurrency
Java 25:Module Import Declarations(定稿)
往期总结链接:
Java语法总结——软考备战最终篇_java软考-CSDN博客
FastAPI框架学习文档_fastapi学习文档 博客-CSDN博客
python-docx库学习文档_python doc库-CSDN博客
python-docx库简单应用(三)_python-docx 占位符-CSDN博客
python-docx库简单应用(一)_pydocx-CSDN博客
计算机二级考试Python知识复习(八)_python计算机二级的几个库运用-CSDN博客
计算机二级考试Python知识复习(七)_生态式编程方法-CSDN博客
计算机二级考试Python知识复习(一)_计算机二级python复习资料-CSDN博客
0 介绍
- 版本基线(2026 年中)
|
语言 |
学习基线 |
说明 |
|
Go |
1.26(2026-02) |
1.27(预计 2026-08)引入泛型方法,本文以 1.26 稳定语法为主,并标注 1.27 前瞻 |
|
C |
C23(ISO/IEC 9899:2024) |
GCC 15+ 默认 gnu23;下一代 C2y 仍在草案阶段,仅作备注 |
|
Python |
3.14.x(3.14.6,2026-06) |
含 t-string、延迟注解求值、自由线程官方支持等 |
|
Java |
25 LTS + 26 特性了解 |
生产优先学 25 LTS;26(2026-03)为非 LTS,文中标注预览特性 |
各语言语法更新
Go 1.26
new(expr):可对表达式分配并初始化,返回指针(如p := new(42)→*int)- 泛型类型可在自身类型参数列表中自引用(更强约束表达)
- Green Tea GC 默认开启;
go fix现代化重写
Go 1.27(前瞻)
- 泛型方法(method 可声明自己的类型参数)
encoding/json/v2等标准库大改
C23
- 关键字:
bool/true/false、nullptr、constexpr、typeof/typeof_unqual、alignas/alignof、thread_local、static_assert - 字面量:二进制
0b、数字分隔符1'000'000、空初始化={} - 预处理:
#embed、#elifdef/#elifndef、#warning - 类型:
_BitInt(N)、可选十进制浮点_Decimal* - 属性:
[[nodiscard]]、[[deprecated]]、[[fallthrough]]等 - 新头文件:
<stdbit.h>、<stdckdint.h>
Python 3.14
- t-string(PEP 750):
t"..."→Template,用于安全的自定义字符串处理 - 注解延迟求值(PEP 649/749)
except/except*可省略括号(PEP 758)- 禁止从
finally中return/break/continue跳出(PEP 765) - Free-threaded Python 官方支持(PEP 779,可选构建)
compression.zstd、多解释器 stdlib 支持
Java 25 LTS(定稿重点)
- Compact Source Files + Instance Main Methods(简化入门)
- Module Import Declarations(
import module ...) - Flexible Constructor Bodies
- Scoped Values(定稿)
- 虚线程(Java 21 已定稿,25 继续强化生态)
Java 26(了解)
- 原语类型进入 pattern /
instanceof/switch(第 4 次预览) - Structured Concurrency(第 6 次预览)
- HTTP/3 for HttpClient
- Lazy Constants(第 2 次预览)
- 四语言定位
|
语言 |
定位 |
典型场景 |
|
C |
贴近硬件的系统级过程式语言 |
OS、嵌入式、驱动、高性能库、语言运行时 |
|
Go |
带 GC 的静态类型、偏后端并发的工程语言 |
云原生、微服务、CLI、网络代理 |
|
Python |
动态类型、表达力优先的通用脚本/应用语言 |
数据/AI、自动化、Web、胶水代码 |
|
Java |
强静态类型、JVM 生态的企业级面向对象语言 |
后端服务、Android(Kotlin 为主)、大数据中间件 |
- 文档地图(按维度索引)
|
章节文件 |
覆盖维度 |
|
01程序结构与入口 |
源文件组织、main、包/模块、编译运行 |
|
02变量常量作用域 |
声明、可变性、作用域、零值/默认值 |
|
03数据类型 |
标量、复合、类型系统哲学 |
|
04运算符与表达式 |
算术/逻辑/位运算、优先级差异 |
|
05控制流 |
if/switch/循环/模式匹配 |
|
06函数与方法 |
定义、参数传递、多返回值、闭包 |
|
07字符串与字符 |
编码、字面量、常用操作 |
|
08集合与复合结构 |
数组/切片/列表/Map/结构体 |
|
09指针引用内存 |
指针、引用、GC、所有权直觉 |
|
10输入输出 |
控制台、文件、格式化 IO |
|
11错误与异常 |
error 值 vs 异常 vs errno |
|
12面向对象与组合 |
class/interface/struct+方法 |
|
13泛型与类型参数 |
泛型语法与约束 |
|
14并发模型 |
线程/协程/CSP/虚线程 |
|
15模块包依赖 |
依赖管理与可见性 |
|
16标准库速览与学习路径 |
常用库对照 + 建议学法 |
- 四语言对比
- 类型:C 裸内存 → Go 静态+推导 → Java 静态+装箱 → Python 运行时对象
- 错误:C 返回码/errno → Go
error值 → Java 受检/非受检异常 → Python 异常 - 并发:C 自己管线程 → Go goroutine+channel → Java 线程/虚线程 → Python GIL/自由线程/async
- 内存:C 手动 → Go/Java GC → Python 引用计数+GC
- OOP:C 无(可用 struct+函数模拟)→ Go 组合+接口 → Java 经典 OOP → Python 万物皆对象
1.1 源文件与组织
|
维度 |
C |
Go |
Python |
Java |
|
源文件后缀 |
.c + .h |
.go |
.py |
.java |
|
编译单元 |
每个 .c 独立编译,链接合并 |
以 package 为单位 |
以 模块/文件 为单位,解释执行 |
以 class 为单位,编译为 .class/JAR |
|
头文件/声明分离 |
.h 声明 + .c 实现 |
无头文件,同包内可见 |
无头文件 |
无头文件,靠 import |
|
命名空间 |
无(靠前缀/静态) |
package 名 |
模块 __name__ |
package 声明 |
C
// main.c
#include <stdio.h>
int main(void) { puts("hello"); return 0; }
Go
package main
import "fmt"
func main() { fmt.Println("hello") }
Python
def main():
print("hello")
if __name__ == "__main__":
main()
Java(传统)
public class App {
public static void main(String[] args) {
System.out.println("hello");
}
}
Java 25+ Compact Source(定稿)
// 无 class 包裹,实例 main
void main() {
IO.println("hello");
}
01 程序结构与入口
1.2 入口函数规则
|
语言 |
入口 |
返回值 |
参数 |
|
C |
main |
int(0 成功) |
argc, argv 或 void |
|
Go |
main(必须在 package main) |
无返回值 |
无参数 |
|
Python |
无强制入口;惯例 if __name__ == "__main__" |
— |
sys.argv 可选 |
|
Java |
public static void main(String[] args) |
void |
String[] args |
|
Java 25 |
还可用实例 void main() |
void |
可简化 |
差异要点
- 只有 C 和 Java(传统) 把
main签名写进语言规范。 - Go 的
main不能带参数,命令行用os.Args。 - Python 脚本可直接顶层执行,入口是约定而非语法强制。
1.3 编译与运行流程
C: 源码 → 预处理 → 编译(.o) → 链接 → 可执行文件Go: 源码 → 编译(静态链接)→ 可执行文件Python:源码 → 字节码(.pyc) → 解释器执行Java: 源码 → 字节码(.class) → JVM 解释/JIT
|
语言 |
典型命令 |
产物 |
|
C |
gcc -std=c23 main.c -o app |
原生二进制 |
|
Go |
go build / go run |
原生二进制 |
|
Python |
python3 script.py |
无独立二进制(可用 PyInstaller 打包) |
|
Java |
javac App.java && java App |
JVM 字节码 |
1.4 语句与块
|
特性 |
C |
Go |
Python |
Java |
|
语句结束 |
; 必须 |
无 ;(可选) |
换行/冒号块 |
; 必须 |
|
代码块 |
{ } |
{ } |
缩进 |
{ } |
|
单行多语句 |
支持 |
支持 |
用 ; |
支持 |
Python 独特点:用缩进(通常 4 空格)表达块,这是语法的一部分,不是风格问题。
1.5 注释
|
类型 |
C |
Go |
Python |
Java |
|
单行 |
// |
// |
# |
// |
|
多行 |
/* */ |
/* */ |
""" """ 或 ''' ''' |
/* */ |
|
文档注释 |
— |
— |
模块/函数 docstring |
/** */ Javadoc |
1.6 易混点
- Go 的
package main≠ Java 的package com.foo:前者决定可执行,后者是命名空间。 - C 的
main返回 int 给操作系统;Gomain返回 nothing,进程退出码用os.Exit。 - Java 25 紧凑源文件 降低入门门槛,但企业项目仍以传统 class 结构为主。
- Python 的
name在导入时为模块名,直接运行为"main"。
02 变量常量作用域
2.1 声明 vs 定义 vs 赋值
|
语言 |
声明语法 |
必须先声明? |
未初始化行为 |
|
C |
int x; / int x = 1; |
是(C23 支持 auto 推断) |
局部变量未定义值(危险) |
|
Go |
var x int / x := 1 |
是 |
包级/局部有零值 |
|
Python |
x = 1(赋值即绑定) |
否 |
未赋值就使用 → NameError |
|
Java |
int x; / int x = 1; |
是 |
局部变量必须显式赋值后才可用 |
示例对照
// C23
auto count = 42; // 类型推断
constexpr int MAX = 100; // 编译期常量对象
var a int // 0
b := 3.14 // 短变量声明,类型推断
const Pi = 3.14 // 编译期常量
x = 10 # 动态绑定,类型可随时变
x = "hello" # 合法
MAX: int = 100 # 类型注解 + 赋值(运行时检查,非强制)
final int MAX = 100;
var list = List.of(1, 2); // 局部变量类型推断(Java 10+)
2.2 可变性
|
概念 |
C |
Go |
Python |
Java |
|
常量 |
const / constexpr |
const |
无真正常量关键字;惯例 MAX = 1 大写 |
final |
|
只读指针 |
const int *p |
无 const 指针 |
— |
final 引用 |
|
深不可变 |
靠约定 |
靠约定 |
tuple、frozenset |
record 字段默认可设 final |
Go 注意:const 只能是编译期可求值的常量表达式;没有 const 修饰变量引用。
Python 注意:tuple 不可变指的是引用不可重新绑定元素(若元素是可变对象,内容仍可改)。
2.3 作用域规则
|
作用域 |
C |
Go |
Python |
Java |
|
块级 |
✅ { } 内 |
✅ |
✅(函数内赋值产生局部变量) |
✅ |
|
函数级 |
✅ |
✅ |
✅ |
✅ |
|
文件/包级 |
static/全局 |
包级 var |
模块全局 |
类字段 / 包 |
|
闭包捕获 |
无闭包 |
捕获外部变量 |
nonlocal/global |
匿名类/lambda 捕获 effectively final |
Python 的 LEGB 规则
Local → Enclosing → Global → Built-in
x = 1
def f():
global x # 修改模块级 x
x = 2
Go 的短声明陷阱
if x := compute(); x > 0 { } // x 仅 if 块内
2.4 零值 / 默认值
|
类型 |
C(未初始化局部) |
Go 零值 |
Python |
Java 默认值 |
|
整数 |
垃圾值 |
0 |
— |
0 |
|
浮点 |
垃圾值 |
0 |
— |
0 |
|
布尔 |
垃圾值 |
FALSE |
FALSE |
FALSE |
|
指针/引用 |
垃圾值 |
nil |
None |
null |
|
字符串 |
垃圾值 |
"" |
— |
null(对象引用) |
关键差异:只有 Go 和 Java(字段) 系统性提供零值;C 局部变量 不初始化是经典 bug 源。
2.5 类型推断对照
|
语言 |
机制 |
示例 |
|
C23 |
auto(对象定义) |
auto x = 1; |
|
C23 |
typeof / typeof_unqual |
typeof(x) y = 0; |
|
Go |
:=、泛型推断 |
n := 1 |
|
Python |
动态,无需声明 |
x = [1,2] |
|
Java |
var(局部,Java 10+) |
var m = Map.of() |
2.6 易混点
- Go
:=只能在函数内(局部变量可以简便来写);包级必须用var。 - Java
final只保证引用不变,对象内容仍可变(除非不可变类)。 - C
const与 C++const不同,C 的 const 不是类型系统核心。 - Python 类型注解(3.14 延迟求值)主要用于静态检查工具,运行时 largely 可选。
03 数据类型
3.1 类型系统哲学
|
语言 |
分类 |
检查时机 |
核心特征 |
|
C |
静态、弱 |
编译期 |
贴近机器,隐式转换多 |
|
Go |
静态、强 |
编译期 |
简洁,无隐式数值窄化 |
|
Python |
动态、强 |
运行时 |
一切皆对象 |
|
Java |
静态、强 |
编译期 |
原始类型 + 包装类双轨 |
3.2 整数类型
|
语言 |
常见类型 |
任意精度 |
|
C |
char, short, int, long, long long + stdint.h 定宽类型 |
无(C23 _BitInt(N) 可指定位宽) |
|
Go |
int, int8(8bit位也就是1byte)…int64, uint, uintptr |
无 |
|
Python |
单一 int(任意精度) |
✅ 内置 |
|
Java |
byte, short, int, long |
BigInteger |
#include <stdint.h>
int32_t a = 1;
_BitInt(128) big; // C23
var n int = 42 // int 大小随平台(32或64位)
int x = 1;
long y = 1L;
3.3 浮点
|
语言 |
类型 |
备注 |
|
C |
float, double, long double;C23 可选 _Decimal32/64/128 |
IEEE 754 |
|
Go |
float32, float64 |
无 float 别名 |
|
Python |
float(双精度) |
还有 decimal.Decimal 模块 |
|
Java |
float, double |
BigDecimal 精确十进制 |
3.4 布尔
|
语言 |
类型 |
与整数关系 |
|
C23 |
bool(关键字) |
不能与整数隐式混用 |
|
C(旧) |
_Bool / <stdbool.h> |
历史上有 0/1 习惯 |
|
Go |
bool |
独立类型 |
|
Python |
bool 是 int 子类 |
True == 1 为真 |
|
Java |
boolean |
完全独立 |
3.5 字符与字符串类型
|
语言 |
字符 |
字符串 |
|
C |
char, wchar_t, char8_t(C23), char16_t, char32_t |
char* / 数组,不以 \0 结尾会出问题 |
|
Go |
byte(uint8 别名), rune(int32,码点) |
string 不可变 UTF-8 |
|
Python |
无独立 char;str 是 Unicode 码点序列 |
str 不可变 |
|
Java |
char(UTF-16 代码单元) |
String 不可变 |
3.6 复合类型总览
|
概念 |
C |
Go |
Python |
Java |
|
固定数组 |
int a[10] |
[10]int |
list 可模拟 |
int[] |
|
动态序列 |
手动 malloc |
slice []int |
list |
ArrayList 等 |
|
关联映射 |
无内置 |
map[K]V |
dict |
HashMap 等 |
|
结构体 |
struct |
struct |
无;用 class/dataclass |
class / record |
|
枚举 |
enum(C23 增强) |
const + iota / 自定义 |
Enum 类 |
enum |
|
联合体 |
union |
无 |
无 |
无 |
|
指针 |
int *p |
*int |
无用户可见指针 |
无指针(只有引用) |
3.7 类型转换规则
|
语言 |
隐式转换 |
显式转换 |
|
C |
大量(整数提升、算术转换) |
(int)x 强制转换 |
|
Go |
极少(如 untyped constant) |
int(x), strconv |
|
Python |
不强调“转换”,运行时多态 |
int(), str() 等构造 |
|
Java |
小范围拓宽(widening) |
强制 (int)x,装箱拆箱 |
记忆:C 最“松”,Go/Java 最“严”,Python 不靠编译期转换而靠对象协议。
3.8 空值表示
|
语言 |
空值 |
类型安全 |
|
C |
NULL / C23 nullptr |
C23 nullptr_t 更安全 |
|
Go |
nil(指针、slice、map、chan、func、interface) |
有 |
|
Python |
None |
有 |
|
Java |
null |
有;Optional 可表达“可能无值” |
3.9 易混点
- Go
int宽度平台相关;跨平台协议用int32/int64。 - Java
intvsInteger:泛型只能用包装类。 - C 字符串 = 字符数组 +
\0,长度用strlen,不是sizeof。 - Python
isvs==:is比身份,==比值。 - C23
nullptr不要与整数0混用做泛型宏。
04 运算符与表达式
4.1 算术运算符
|
运算符 |
C |
Go |
Python |
Java |
|
+ - * / |
✅ |
✅ |
✅ |
✅ |
|
整数除法 |
截断向零 |
截断向零 |
// 整除,/ 真除 |
截断向零 |
|
% 取模 |
✅ |
✅ |
✅(与除法一致) |
✅ |
|
自增自减 ++ -- |
✅ |
❌(无) |
❌ |
✅ |
7 / 2 # 3.5
7 // 2 # 3
7 / 2 // 3(整数除法)
4.2 比较与逻辑
|
运算符 |
C |
Go |
Python |
Java |
|
== != |
✅ |
✅(slice/map 不可比) |
✅ |
✅ |
|
< > <= >= |
✅ |
✅ |
✅ |
✅ |
|
&& || |
✅ 短路 |
✅ |
and or 短路 |
✅ |
|
! |
✅ |
✅ |
not |
✅ |
|
三元 ?: |
✅ |
❌ 用 if |
x if c else y |
✅ |
Go 特殊:== 可用于 struct(字段都可比时)、array;不能比较 slice、map、func。
4.3 位运算
|
运算符 |
C |
Go |
Python |
Java |
|
& | ^ ~ |
✅ |
✅ |
✅(整数无限精度需注意) |
✅ |
|
<< >> |
✅ |
✅ |
✅ |
✅ |
|
&^ 位清除 |
❌ |
✅ Go 特有 |
❌ |
❌ |
C23 提供 <stdbit.h>:stdc_count_ones、stdc_leading_zeros 等可移植位操作。
4.4 赋值与复合赋值
四语言均支持 +=, -=, *=, /=, %=, 位运算复合赋值。
Go 独有::= 声明并赋值(非单纯赋值运算符)。
4.5 地址、解引用、成员访问
|
操作 |
C |
Go |
Python |
Java |
|
取地址 & |
✅ |
✅ |
❌ |
❌ |
|
解引用 * |
✅ |
✅ |
❌ |
❌ |
|
成员 . |
✅ |
✅ |
✅ |
✅ |
|
指针成员 -> |
✅ |
用 .(自动解引用) |
— |
— |
|
安全导航 |
— |
— |
无内置 |
?.(可选链无,但 Optional) |
4.6 运算符优先级(记忆版)
共同规律:一元 > 乘除 > 加减 > 移位 > 比较 > 相等 > 位与 > 位异或 > 位或 > 逻辑与 > 逻辑或 > 赋值
差异:
- Python 逻辑用英文单词,优先级更清晰
- Go 无
++参与表达式(i++是语句) - C 逗号运算符
,可作为表达式一部分
4.7 类型相关运算符/表达式
|
特性 |
C |
Go |
Python |
Java |
|
sizeof |
✅ |
unsafe.Sizeof |
sys.getsizeof(对象大小) |
无 |
|
类型查询 |
_Generic(C11) |
reflect |
type(), isinstance |
instanceof |
|
类型 switch |
— |
switch x.(type) |
无 |
pattern matching |
4.8 易混点
- Python
/vs//是初学者最常错点。 - Go 无三元运算符,惯用短 if 或 helper 函数。
- Java 字符串
+会拼接,但==比较引用;内容用equals。 - C 有符号移位 实现定义/未定义行为需查编译器文档。
05 控制流
5.1 条件分支 if
|
特性 |
C |
Go |
Python |
Java |
|
语法 |
if (cond) |
if cond(无括号) |
if cond: |
if (cond) |
|
else if |
✅ |
✅ |
elif |
else if |
|
条件类型 |
标量/指针 |
bool 必须 |
真值测试 |
boolean 必须 |
Python 真值测试
空容器、0、None、False 为假;其余多为真。
Go 的 if 初始化语句
if err := do(); err != nil {
return err
}
5.2 switch
|
特性 |
C |
Go |
Python |
Java |
|
形式 |
switch(expr) |
switch 可表达式/无标签 |
3.10+ match |
switch + 3.14+ 增强 pattern |
|
fallthrough |
默认贯穿 |
默认不贯穿 |
— |
默认不贯穿 |
|
多值匹配 |
需 case 1: case 2: |
逗号 case 1, 2: |
case 1 | 2: |
多 case 标签 |
|
类型 switch |
— |
switch x.(type) |
— |
pattern switch |
switch n {
case 1, 2:
fmt.Println("small")
default:
fmt.Println("other")
}
match command:
case "quit" | "exit":
break
case int(n) if n > 0:
print(n)
// Java 21+ switch 表达式
String result = switch (day) {
case MONDAY, FRIDAY -> "work";
case SATURDAY, SUNDAY -> "rest";
default -> "unknown";
};
5.3 循环
|
循环 |
C |
Go |
Python |
Java |
|
while |
while(cond) |
for cond {} |
while cond: |
while(cond) |
|
do-while |
do {} while |
无 |
无 |
do {} while |
|
for 三段式 |
✅ |
✅ |
— |
✅ |
|
for-each |
— |
for k, v := range |
for x in |
enhanced for |
|
无限循环 |
while(1) |
for {} |
while True |
while(true) |
for i := 0; i < n; i++ { }
for _, v := range slice { }
for i, v in enumerate(items):
...
5.4 跳转语句
|
语句 |
C |
Go |
Python |
Java |
|
break |
✅ |
✅ |
✅ |
✅ |
|
continue |
✅ |
✅ |
✅ |
✅ |
|
goto |
✅ |
✅(少用) |
无 |
无 |
|
return |
✅ |
✅ |
✅ |
✅ |
|
带标签 break |
— |
break Outer |
— |
— |
5.5 模式匹配(2026 水平)
|
语言 |
支持度 |
示例场景 |
|
C |
无 |
用 switch + 手动拆 |
|
Go |
无完整 PM |
switch + type assertion |
|
Python 3.10+ |
match/case |
结构、类、守卫 |
|
Java 21+ |
record pattern、switch |
instanceof + destructure |
// Java 25 预览:原语也可 pattern
if (obj instanceof int i) {
System.out.println(i);
}
5.6 异常与控制流(交叉)
|
语言 |
用异常做控制流? |
|
C |
否(goto/setjmp 极少) |
|
Go |
否(显式 error) |
|
Python |
偶尔(EAFP 风格) |
|
Java |
不推荐,但受检异常影响流程 |
Python EAFP:Easier to Ask Forgiveness than Permission
try:
return data[key]
except KeyError:
return default
5.7 易混点
- C switch 缺 break 会贯穿;Go/Java 默认不贯穿。
- Go 只有
for,没有 while 关键字。 - Python
for是迭代器iterator协议,不是 C 风格索引循环。 - Java switch 表达式 要覆盖所有 case 或用
default。
06 函数与方法
6.1 函数定义语法
|
语言 |
语法要点 |
|
C |
返回类型在前;旧式 K&R 已在 C23 移除 |
|
Go |
func name(args) ret {};可多返回值 |
|
Python |
def name(args) -> ret: |
|
Java |
在 class 内;ReturnType name(args) |
int add(int a, int b) { return a + b; }
func divide(a, b int) (q int, err error) {
if b == 0 { return 0, errors.New("div by zero") }
return a / b, nil
}
def greet(name: str, *, loud: bool = False) -> str:
s = f"hello {name}"
return s.upper() if loud else s
public static int add(int a, int b) { return a + b; }
6.2 参数传递语义
|
语言 |
默认传递 |
说明 |
|
C |
值传递 |
数组名退化为指针;显式指针传递引用 |
|
Go |
值传递 |
slice/map/channel 是引用类型头;struct 大对象常传指针 |
|
Python |
对象引用传递 |
形参绑定到对象,重新赋值不影响外部变量 |
|
Java |
值传递(引用值) |
不能改引用指向,但能改对象内容 |
统一记忆:只有 C 有真正的“按值复制整个对象”;其余语言“值传递”常指传递指针/引用的副本。
6.3 多返回值 / 可选返回
|
语言 |
机制 |
|
C |
只能单返回;多结果用指针参数/out 或 struct |
|
Go |
原生多返回值 (T, error) |
|
Python |
return a, b → 实际是 tuple |
|
Java |
单返回;可用 record/Pair 或异常 |
6.4 默认参数 / 重载 / 可变参数
|
特性 |
C |
Go |
Python |
Java |
|
默认参数 |
❌ |
❌ |
✅ |
❌(重载代替) |
|
函数重载 |
❌(_Generic 模拟) |
❌ |
❌ |
✅ |
|
可变参数 |
... 无 |
...T |
*args |
String... args |
|
关键字参数 |
— |
— |
**kwargs |
— |
func sum(nums ...int) int { ... }
void log(String fmt, Object... args) { ... }
6.5 闭包与高阶函数
|
语言 |
闭包 |
函数是一等公民 |
|
C |
无(函数指针) |
函数指针 |
|
Go |
✅ |
✅ |
|
Python |
✅ |
✅ |
|
Java |
lambda 捕获 effectively final |
✅(Java 8+) |
func counter() func() int {
n := 0
return func() int { n++; return n }
}
def counter():
n = 0
def inc():
nonlocal n
n += 1
return n
return inc
6.6 方法与接收者
|
语言 |
方法语法 |
接收者 |
|
C |
无;struct + 函数指针模拟 |
— |
|
Go |
func (r T) M() |
值/指针接收者 |
|
Python |
def method(self, ...) |
self 显式 |
|
Java |
在 class 内定义 |
隐式 this |
Go 指针接收者:需要修改接收者或避免复制大 struct 时用 *T。
6.7 递归、内联、尾调用
|
语言 |
递归 |
尾调用优化 |
|
C |
✅ |
编译器可能优化 |
|
Go |
✅ |
不保证 |
|
Python |
✅(注意深度限制) |
无 |
|
Java |
✅ |
JVM 一般不优化为循环 |
6.8 易混点
- Python 默认参数不要用可变对象
def f(a=[])陷阱。 - Go 没有函数重载,用不同函数名或接口。
- C 函数指针 类型声明难读:
int (*cmp)(const void*, const void*)。 - Java 静态方法 vs 实例方法 不能重写静态方法。
07 字符串与字符
7.1 内部表示
|
语言 |
字符串编码 |
可变性 |
|
C |
字节序列 + \0 终止;宽字符另说 |
可改(危险) |
|
Go |
UTF-8 字节序列 |
不可变 |
|
Python |
Unicode 码点(内部实现优化) |
不可变 |
|
Java |
UTF-16 char 序列 |
不可变 |
7.2 字面量形式
|
形式 |
C |
Go |
Python |
Java |
|
双引号 |
"hi" |
"hi" |
"hi" |
"hi" |
|
单引号字符 |
'a' |
字符用 rune 字面量 'a' |
无单字符类型 |
'a' |
|
原始/不转义 |
无 |
`raw` |
r"..." |
text block """...""" |
|
多行 |
拼接 |
反引号 |
""" |
text block |
|
格式化 |
printf |
fmt |
f-string f"{x}" |
String.format |
|
模板串(2026) |
— |
— |
t-string t"{x}" |
— |
Python 3.14 t-string
from string.templatelib import Template
name = "world"
tpl: Template = t"Hello, {name}!"
# 可遍历 tpl.strings / tpl.interpolations 做安全处理
7.3 常用操作对照
|
操作 |
C |
Go |
Python |
Java |
|
长度 |
strlen(O(n)) |
len(s) 字节数 |
len(s) 字符数 |
s.length() UTF-16 单元 |
|
拼接 |
strcat/snprintf |
+ / strings.Builder |
+ / join |
+ / StringBuilder |
|
切片 |
strncmp 等 |
s[i:j] |
s[i:j] |
substring |
|
查找 |
strstr |
strings.Contains |
in / find |
contains / indexOf |
|
分割 |
strtok |
strings.Split |
split |
split |
|
格式化 |
sprintf |
fmt.Sprintf |
f-string |
formatted(Java 21+) |
7.4 转义与 Unicode
|
语言 |
常见转义 |
Unicode |
|
C |
\n \t \\ \" |
\uXXXX(C11/u8) |
|
Go |
同 C + ` 内不转义 |
\u \U |
|
Python |
\n \t |
\u \U \N{name} |
|
Java |
\n \t |
\uXXXX |
7.5 C 字符串特别说明
char s[] = "hi"; // 可修改数组
char *p = "hi"; // 字符串字面量,常不可写
// C23
const char *q = u8"你好";
经典坑
char *与char[]不同sizeof(s)vsstrlen(s)- 缓冲区溢出 → 用
snprintf、边界检查
7.6 Go 字符串与 rune
s := "你好"
for i, r := range s { // r 是 rune,i 是字节偏移
_ = i; _ = r
}
len(s) 是字节数,不是字符数;计数用 utf8.RuneCountInString。
7.7 易混点
- Java
String拼接大量用+性能差,用StringBuilder。 - Go 字符串不可变,修改用
[]byte或strings.Builder。 - Python f-string 表达式里不能有反斜杠(语法限制)。
- C 没有内置字符串类型,标准库全是裸指针约定。
08 集合与复合结构
8.1 数组 / 定长序列
|
语言 |
语法 |
长度 |
越界 |
|
C |
int a[10] |
编译期常量 |
未定义行为 |
|
Go |
[10]int |
类型一部分 |
编译/运行 panic |
|
Python |
无真数组;array.array 少用 |
— |
IndexError |
|
Java |
int[] a = new int[10] |
运行时 |
ArrayIndexOutOfBounds |
8.2 动态序列
|
语言 |
核心类型 |
扩容 |
|
C |
手动 malloc + realloc |
程序员负责 |
|
Go |
slice []T |
自动,共享底层数组 |
|
Python |
list |
自动 |
|
Java |
ArrayList<T> |
自动 |
s := make([]int, 0, 10) // len=0, cap=10
s = append(s, 1)
lst = [1, 2, 3]
lst.append(4)
var list = new ArrayList<Integer>();
list.add(1);
Go slice 三要素
pointer + len + cap —— 理解 slice 是学 Go 的关键。
8.3 映射(键值对)
|
语言 |
类型 |
有序? |
缺失键 |
|
C |
无;用哈希库或自己实现 |
— |
— |
|
Go |
map[K]V |
遍历顺序随机 |
零值 + ok |
|
Python |
dict |
3.7+ 插入有序 |
KeyError / get |
|
Java |
HashMap / LinkedHashMap |
Hash 无序 |
null / getOrDefault |
v, ok := m["key"]
if !ok { /* 不存在 */ }
v = d.get("key", default)
8.4 结构体 / 记录
|
语言 |
定义 |
特点 |
|
C |
struct Point { int x, y; }; |
内存布局可控,可对齐 |
|
Go |
type Point struct { X, Y int } |
导出字段靠首字母大写 |
|
Python |
@dataclass / class |
动态属性 |
|
Java |
class / record |
record 不可变数据载体 |
record Point(int x, int y) {}
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
8.5 集合类型扩展
|
类型 |
C |
Go |
Python |
Java |
|
集合 Set |
无 |
map[T]struct{} 惯用法 |
set |
HashSet |
|
队列 |
手写 |
container/list 或 channel |
deque |
Queue |
|
栈 |
手写 |
slice 模拟 |
list 模拟 |
Deque |
|
元组 |
无 |
无 |
tuple |
无(record 替代) |
8.6 迭代
|
语言 |
惯用法 |
|
C |
for (i=0; i<n; i++) 或指针遍历 |
|
Go |
for i, v := range |
|
Python |
for x in iterable |
|
Java |
enhanced for 或 Iterator / Stream |
8.7 内存布局(C/Go 重点)
C struct 填充(padding) 影响 ABI、网络协议、嵌入式。
struct S { char a; int b; }; // 可能有 3 字节 padding
Go 编译器也会对齐,可用 unsafe 分析但不建议依赖。
Python/Java 对象布局对用户不透明。
8.8 易混点
- Go array vs slice:
[3]int与[]int是不同类型。 - Go map 未初始化nil,不能写入;要先
make。 - Python list 是引用数组,
a = b共享对象。 - Java
Arrays.asList返回定长列表,不能add。
09 指针引用内存
9.1 有无指针
|
语言 |
用户层指针 |
空值 |
|
C |
✅ 核心 |
NULL / nullptr |
|
Go |
✅ 有限使用 |
nil |
|
Python |
❌ 一切是引用 |
None |
|
Java |
❌ 只有引用类型 |
null |
9.2 指针基础(C / Go)
int x = 10;
int *p = &x;
*p = 20;
x := 10
p := &x
*p = 20
|
概念 |
C |
Go |
|
取址 |
& |
& |
|
解引用 |
* |
* |
|
指针算术 |
✅ p++ |
❌ |
|
函数指针 |
✅ |
✅ func 类型 |
9.3 内存分配与释放
|
语言 |
分配 |
释放 |
|
C |
malloc / calloc / realloc / aligned_alloc |
free |
|
C23 |
同上 + strdup 等标准函数 |
free |
|
Go |
new(T) / make / 取址 |
GC 自动 |
|
Python |
自动 |
GC 自动 |
|
Java |
new |
GC 自动 |
Go 1.26:new(expr)
p := new(42) // *int,值为 42
age := new(18) // 用于可选 JSON 字段等
旧写法:v := 42; p := &v
9.4 栈 vs 堆
|
语言 |
谁决定 |
|
C |
程序员(局部通常在栈,malloc 在堆) |
|
Go |
逃逸分析 编译器决定 |
|
Python/Java |
运行时 + JIT,对开发者透明 |
9.5 垃圾回收
|
语言 |
机制 |
程序员职责 |
|
C |
无 |
手动 free,防泄漏/悬垂 |
|
Go |
并发 GC(1.26 Green Tea 默认) |
注意 goroutine 泄漏 |
|
Python |
引用计数 + 循环 GC |
注意全局引用 |
|
Java |
分代 GC(G1/ZGC/Shenandoah) |
注意静态集合持有引用 |
9.6 常见内存问题
|
问题 |
C |
Go |
Python |
Java |
|
内存泄漏 |
✅ 高发 |
较少 |
较少 |
较少 |
|
悬垂指针 |
✅ |
GC 避免 |
GC 避免 |
GC 避免 |
|
双重释放 |
✅ |
— |
— |
— |
|
缓冲区溢出 |
✅ |
边界检查 |
边界检查 |
边界检查 |
|
数据竞争 |
✅ |
✅ race detector |
GIL/锁 |
✅ |
C23 memset_explicit:安全擦除敏感内存。
9.7 引用语义对比
Java
StringBuilder sb = new StringBuilder();
foo(sb); // 可修改对象内容
Python
def foo(lst):
lst.append(1) # 修改外部可见
Go — 传 slice 可改底层元素:
func add1(s []int) { s[0]++ } // 外部 slice 元素会变
9.8 unsafe / 底层操作
|
语言 |
机制 |
|
C |
全是 unsafe |
|
Go |
unsafe 包 + unsafe.Pointer |
|
Python |
ctypes / C 扩展 |
|
Java |
Foreign Function & Memory API(替代 JNI 方向) |
9.9 易混点
- Go
newvsmake:new分配零值;make用于 slice/map/chan。 - C
free后绝不使用指针。 - Java
==比较引用,不是对象内容。 - Python
is比较身份,小整数缓存导致is有时“碰巧”为真。
10 输入输出
10.1 标准流模型
|
语言 |
stdin |
stdout |
stderr |
|
C |
stdin |
stdout |
stderr |
|
Go |
os.Stdin |
os.Stdout |
os.Stderr |
|
Python |
sys.stdin |
sys.stdout |
sys.stderr |
|
Java |
System.out |
System.err |
10.2 控制台输出
|
语言 |
最简输出 |
格式化输出 |
|
C |
puts("hi") |
printf("%d\n", n) |
|
Go |
fmt.Println("hi") |
fmt.Printf("%d\n", n) |
|
Python |
print("hi") |
print(f"{n}") / format |
|
Java |
System.out.println("hi") |
System.out.printf("%d%n", n) |
换行差异
- C
printf不自动换行 - Go
Println自动换行 - Python
print默认换行,end=可改 - Java
println自动换行
10.3 控制台输入
|
语言 |
读一行 |
读格式化 |
|
C |
fgets(buf, size, stdin) |
scanf("%d", &n) |
|
Go |
bufio.NewReader / fmt.Scanln |
fmt.Scanf |
|
Python |
input() |
手动转换 int(input()) |
|
Java |
Scanner.nextLine() |
Scanner.nextInt() |
// C:scanf 有缓冲区溢出风险,优先 fgets + sscanf
char line[128];
if (fgets(line, sizeof line, stdin))
sscanf(line, "%d", &n);
reader := bufio.NewReader(os.Stdin)
line, _ := reader.ReadString('\n')
line = input().strip()
n = int(line)
var sc = new Scanner(System.in);
int n = sc.nextInt();
10.4 文件 I/O
|
语言 |
打开 |
读文本 |
写文本 |
关闭 |
|
C |
fopen |
fgets/fread |
fprintf/fwrite |
fclose |
|
Go |
os.Open |
io.ReadAll |
os.WriteFile |
defer f.Close() |
|
Python |
open() |
read() |
write() |
with 自动 |
|
Java |
Files / FileReader |
readString |
writeString |
try-with-resources |
Python 推荐
with open("data.txt", encoding="utf-8") as f:
content = f.read()
Go 推荐
data, err := os.ReadFile("data.txt")
Java 推荐
String s = Files.readString(Path.of("data.txt"));
10.5 二进制 I/O
|
语言 |
方式 |
|
C |
fread/fwrite + memcpy |
|
C23 |
#embed "file.bin" 编译期嵌入 |
|
Go |
encoding/binary 大端小端 |
|
Python |
struct.pack / unpack |
|
Java |
DataInputStream / ByteBuffer |
// C23 嵌入资源
const unsigned char icon[] = {
#embed "icon.png"
};
10.6 缓冲 I/O
|
语言 |
缓冲 |
|
C |
全缓冲 stdio,setvbuf 可调 |
|
Go |
bufio.Reader/Writer |
|
Python |
文本 IO 默认缓冲 |
|
Java |
BufferedReader |
教训:C/Go 的 printf 无换行时可能因缓冲延迟显示;调试可加 \n 或 fflush(stdout)。
10.7 序列化(JSON 等)
|
语言 |
JSON 常用库 |
|
C |
cJSON, jansson(第三方) |
|
Go |
encoding/json(1.27 将有 v2) |
|
Python |
json 标准库 |
|
Java |
Jackson / Gson / javax.json |
10.8 易混点
- C
scanf("%s")永不裸用,无宽度限制。 - Go 别用
fmt.Scan读带空格输入。 - Python 打开文件要指定
encoding="utf-8"(Windows 尤其)。 - Java
System.out是字节流包装,字符应用PrintWriter。
11 错误与异常
11.1 对照
|
语言 |
主模型 |
理念 |
|
C |
返回码 + errno |
程序员显式检查每一步 |
|
Go |
error 值 |
错误是值,不是控制流 |
|
Python |
异常 |
EAFP:先做事,出错再捕获 |
|
Java |
异常 |
受检 + 非受检双轨 |
11.2 C:返回码与 errno
#include <errno.h>
#include <string.h>
FILE *f = fopen("missing.txt", "r");
if (!f) {
fprintf(stderr, "open failed: %s\n", strerror(errno));
return 1;
}
|
机制 |
用途 |
|
函数返回值 |
NULL、-1、EOF 表示失败 |
|
errno |
系统调用错误码 |
|
perror / strerror |
人类可读消息 |
无异常,也无强制检查返回码——C 最大风险源。
11.3 Go:error 接口
func readConfig(path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("read config %s: %w", path, err)
}
return data, nil
}
|
要点 |
说明 |
|
error 是接口 |
Error() string |
|
惯用法 |
if err != nil { return ... } |
|
包装 |
fmt.Errorf("...: %w", err) |
|
panic |
仅用于不可恢复编程错误 |
Go 没有 try/catch;panic/recover 类似 defer 级异常,不用于业务错误。
11.4 Python:异常
try:
with open("missing.txt", encoding="utf-8") as f:
data = f.read()
except FileNotFoundError as e:
print("not found:", e)
except OSError as e:
print("io error:", e)
else:
print("ok", len(data))
finally:
print("cleanup")
|
语法 |
3.14 更新 |
|
except X: |
可写 except X 省略括号(PEP 758) |
|
except* |
ExceptionGroup 相关 |
|
finally |
禁止 return/break/continue 跳出(PEP 765) |
11.5 Java:受检与非受检
try {
Files.readString(Path.of("missing.txt"));
} catch (IOException e) {
throw new RuntimeException(e);
}
|
类型 |
继承 |
必须处理? |
|
受检 |
Exception(非 Runtime) |
编译器强制 try/catch 或 throws |
|
非受检 |
RuntimeException |
否 |
|
错误 |
Error |
一般不捕 |
现代 Java 趋势:新 API 更少受检异常;用 Optional / Result 风格在库层表达。
11.6 四语言错误处理对照表
|
场景 |
C |
Go |
Python |
Java |
|
文件不存在 |
NULL + errno |
error 包装 os.ErrNotExist |
FileNotFoundError |
NoSuchFileException |
|
除零 |
未定义行为/ SIGFPE |
panic(整数除零) |
ZeroDivisionError |
ArithmeticException |
|
类型错误 |
编译期 |
编译期 |
TypeError |
编译期 |
|
自定义错误 |
错误码枚举 |
errors.New / 自定义类型 |
继承 Exception |
继承 Exception |
11.7 资源管理与错误
|
语言 |
RAII / 自动清理 |
|
C |
手动;goto cleanup 模式 |
|
Go |
defer |
|
Python |
with 上下文管理器 |
|
Java |
try-with-resources |
f, err := os.Open(path)
if err != nil { return err }
defer f.Close()
11.8 选型直觉
- C:每个调用都检查;失败路径与成功路径同样重要。
- Go:错误是返回值的一部分;链式
if err != nil是文化。 - Python:用异常表达“意外”;不要用异常做普通分支。
- Java:API 设计要想清楚受检异常是否值得。
11.9 易混点
- Go 不要滥用 panic 代替 error。
- Python 捕获
Exception太宽,尽量具体类型。 - Java 吞掉异常
catch (Exception e) {}是维护噩梦。 - C
errno只在失败后读,成功调用可能不改 errno。
12 面向对象与组合
12.1 范式定位
|
语言 |
官方范式 |
现实写法 |
|
C |
过程式 |
struct + 函数指针模拟 OOP |
|
Go |
组合优于继承 |
struct + interface |
|
Python |
多范式 OOP |
类 + 魔术方法 |
|
Java |
单继承 OOP |
class + interface + record |
12.2 类 / 结构体定义
|
语言 |
定义 |
构造 |
|
C |
struct |
手动初始化字段 |
|
Go |
type T struct |
字面量 T{a:1} |
|
Python |
class T: |
__init__ |
|
Java |
class T / record T |
构造器 |
class Dog:
def __init__(self, name: str):
self.name = name
def bark(self) -> str:
return "woof"
public class Dog {
private final String name;
public Dog(String name) { this.name = name; }
public String bark() { return "woof"; }
}
12.3 继承 vs 组合
|
语言 |
继承 |
推荐 |
|
C |
无 |
组合 struct |
|
Go |
无类继承 |
嵌入 struct(匿名字段) |
|
Python |
单继承 + Mixin |
组合 + 协议 |
|
Java |
单继承 class |
接口组合 |
Go 嵌入(组合)
type Engine struct { Power int }
type Car struct {
Engine // 匿名字段,方法提升
Brand string
}
Python 继承
class Animal: ...
class Dog(Animal): ...
Java
class Dog extends Animal implements Pet { }
12.4 接口 / 抽象
|
语言 |
接口机制 |
实现方式 |
|
C |
函数指针表 vtable |
手动 |
|
Go |
interface 隐式实现 |
无需 implements |
|
Python |
类型 + Protocol |
有方法即可 |
|
Java |
interface 显式实现 |
implements |
type Reader interface {
Read(p []byte) (n int, err error)
}
// 任何有 Read 方法的类型都满足 Reader
interface Readable {
int read(byte[] buf);
}
class MyReader implements Readable { ... }
12.5 多态
|
语言 |
机制 |
|
C |
函数指针 / _Generic |
|
Go |
interface 动态分发 |
|
Python |
运行时方法查找 |
|
Java |
虚方法表 + interface |
12.6 访问控制
|
语言 |
public |
private |
protected |
包可见 |
|
C |
约定 |
约定 |
— |
static 文件内 |
|
Go |
大写导出 |
小写包内 |
— |
包级 |
|
Python |
无强制 |
_ 约定 |
— |
— |
|
Java |
public |
private |
protected |
默认包私有 |
Go 规则:Foo 导出,foo 不导出——极简但有效。
12.7 特殊 OOP 特性
|
特性 |
C |
Go |
Python |
Java |
|
抽象类 |
模拟 |
无 |
abc.ABC |
abstract class |
|
静态方法 |
无 |
无(包级函数) |
@staticmethod |
static |
|
类方法 |
— |
— |
@classmethod |
static 工厂 |
|
属性 getter |
— |
— |
@property |
getter/setter |
|
record/数据类 |
— |
— |
@dataclass |
record |
|
枚举 |
enum(C23) |
iota 常量组 |
Enum |
enum |
|
析构 |
无 |
无 |
__del__(少用) |
finalize 废弃 |
12.8 Java record 与 Python dataclass
record User(String name, int age) {
public User {
if (age < 0) throw new IllegalArgumentException();
}
}
from dataclasses import dataclass
@dataclass(frozen=True)
class User:
name: str
age: int
两者都适合不可变数据载体,替代冗长 POJO。
12.9 易混点
- Go 没有
class,别硬套 Java OOP 思维。 - Python 的
self必须显式,不是语法糖能省略的(实例方法)。 - Java 接口可有 default/static 方法(Java 8+)。
- C++ 的 OOP 别和 C 混淆——C 没有构造/析构函数。
13 泛型与类型参数
13.1 支持概览
|
语言 |
泛型 |
引入版本 |
类型擦除? |
|
C |
宏 + _Generic |
C11 |
预处理/编译期选择 |
|
Go |
✅ 泛型 |
Go 1.18 |
单态化(monomorphization) |
|
Python |
类型参数(PEP 695) |
3.12+ |
运行时擦除(注解用) |
|
Java |
✅ 泛型 |
Java 5 |
有擦除 |
13.2 C:宏与 _Generic
#define MAX(a, b) ((a) > (b) ? (a) : (b)) // 副作用陷阱
// C11 _Generic:类型分发
#define print_val(x) _Generic((x), \
int: print_int, \
double: print_double \
)(x)
C23 改进了 _Generic;但 C 仍无真正“类型参数函数”。
13.3 Go 泛型
func Map[T, U any](slice []T, f func(T) U) []U {
out := make([]U, len(slice))
for i, v := range slice {
out[i] = f(v)
}
return out
}
type Stack[T any] struct { items []T }
func (s *Stack[T]) Push(v T) { s.items = append(s.items, v) }
|
概念 |
语法 |
|
类型参数 |
[T any] |
|
约束 |
interface 约束集 |
|
实例化 |
通常自动推断 |
Go 1.26:泛型类型可自引用约束。
Go 1.27(前瞻):泛型方法 func (s *Set[T]) Union[U ...](...)
13.4 Python 类型参数
# PEP 695 风格
def first[T](items: list[T]) -> T:
return items[0]
class Stack[T]:
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
|
要点 |
说明 |
|
运行时 |
仍是鸭子类型,泛型主要服务静态检查 |
|
TypeVar |
旧写法仍可用 |
|
联合 |
`int |
Python 3.14:注解延迟求值,前向引用更简单。
13.5 Java 泛型
public static <T> T first(List<T> list) {
return list.get(0);
}
public class Box<T> {
private T value;
public T get() { return value; }
}
|
限制 |
原因 |
|
不能用 int 作类型参数 |
擦除 + 原始类型并行 |
|
不能 new T() |
擦除 |
|
不能创建 T[] |
数组协变问题 |
原始类型 workaround:List<int> 不存在 → List<Integer>。
Java 25+ 改进方向
- 更丰富的 pattern matching
- Primitive Types in Patterns(预览):减少装箱
13.6 约束 / 边界对照
|
语言 |
约束写法 |
|
Go |
interface{ ~int | ~int64 } 等 |
|
Python |
T: Comparable / bound= |
|
Java |
<T extends Number> |
public <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
13.7 协变与逆变(进阶)
|
语言 |
数组/集合协变 |
|
C |
无泛型集合 |
|
Go |
slice 不变;interface 有协变感觉 |
|
Python |
类型检查器处理 |
|
Java |
数组协变(String[] 是 Object[]);泛型不变 |
List<String> list = List.of("a");
// List<Object> objs = list; // 编译错误
13.8 易混点
- Java 泛型擦除:运行时
List<String>和List<Integer>都是List。 - Go 泛型不是 C++ 模板元编程,保持简单。
- C 宏泛型 不做类型检查,副作用是经典坑。
- Python 泛型主要给 mypy/pyright,运行时不强制。
14 并发模型
14.1 总览
|
语言 |
核心模型 |
默认并行? |
|
C |
pthread / 手动线程 |
是(OS 线程) |
|
Go |
goroutine + channel(CSP) |
M:N 调度 |
|
Python |
threading / asyncio / multiprocessing |
GIL 限制 CPU 并行(3.14 可选自由线程) |
|
Java |
Thread / 虚拟线程 / java.util.concurrent |
真并行 |
14.2 C:POSIX 线程
#include <pthread.h>
void *worker(void *arg) {
// ...
return NULL;
}
pthread_t t;
pthread_create(&t, NULL, worker, NULL);
pthread_join(t, NULL);
|
要点 |
说明 |
|
同步 |
mutex, cond, semaphore |
|
风险 |
数据竞争、死锁、悬垂指针 |
|
工具 |
ThreadSanitizer, Valgrind |
C 没有语言级并发原语,全靠库和纪律。
14.3 Go:goroutine 与 channel
ch := make(chan int, 10)
go func() {
ch <- 42
}()
v := <-ch
|
概念 |
说明 |
|
go f() |
启动 goroutine,极轻量 |
|
chan T |
CSP 通信 |
|
select |
多路复用 |
|
sync.Mutex |
共享内存时备用 |
|
context |
取消与超时传播 |
Don't communicate by sharing memory;
share memory by communicating.
Go 1.26:实验性 goroutine 泄漏检测工具。
14.4 Python:GIL、asyncio、多进程
threading(I/O 密集)
import threading
def work():
...
t = threading.Thread(target=work)
t.start()
t.join()
CPython GIL:同一时刻只有一个线程执行 Python 字节码 → CPU 密集 用 multiprocessing。
asyncio(协作式并发)
import asyncio
async def fetch():
await asyncio.sleep(1)
return "ok"
asyncio.run(fetch())
Python 3.14 自由线程(可选构建)
- PEP 779:无 GIL 构建官方支持
- 需专门安装
python3.14t类构建 - 扩展模块兼容性仍在演进
14.5 Java:平台线程与虚拟线程
传统线程
Thread t = Thread.ofPlatform().start(() -> {
System.out.println("hi");
});
t.join();
虚拟线程(Java 21+,生产可用)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> System.out.println("vt"));
}
|
特性 |
平台线程 |
虚拟线程 |
|
数量级 |
数千 |
数百万 |
|
调度 |
OS |
JVM |
|
适用 |
CPU 密集 |
I/O 密集 |
Java 25 定稿:Scoped Values
// 替代 ThreadLocal,不可变、低开销
ScopedValue.where(KEY, value).run(() -> { ... });
Java 26 预览:Structured Concurrency
把子任务生命周期绑定到父作用域,失败时自动取消兄弟任务。
14.6 同步原语对照
|
原语 |
C |
Go |
Python |
Java |
|
互斥锁 |
pthread_mutex |
sync.Mutex |
threading.Lock |
synchronized / ReentrantLock |
|
条件变量 |
pthread_cond |
sync.Cond |
Condition |
Condition |
|
信号量 |
sem_t |
第三方/chan |
Semaphore |
Semaphore |
|
原子操作 |
_Atomic |
sync/atomic |
有限 |
AtomicInteger 等 |
|
WaitGroup |
手动 |
sync.WaitGroup |
Barrier |
CountDownLatch |
14.7 并发选型建议
|
场景 |
首选 |
|
系统底层、极致控制 |
C |
|
云原生网络服务 |
Go |
|
脚本、数据胶水、async Web |
Python |
|
企业后端、JVM 生态 |
Java(虚拟线程处理 I/O) |
14.8 易混点
- Go map 并发写会 panic,用
sync.Map或加锁。 - Python 多线程不等于多核 CPU 并行(除非 free-threaded 或 multiprocessing)。
- Java 虚拟线程不要 pin 到平台线程(如
synchronized块内长时间 I/O 需注意)。 - C 数据竞争是未定义行为,比 panic 更危险。
15 模块包依赖
15.1 组织单元对照
|
语言 |
逻辑单元 |
物理单元 |
导入语句 |
|
C |
无模块;编译单元 .c |
.h + .c |
#include |
|
Go |
package |
目录 = 包 |
import "path" |
|
Python |
module |
.py 文件 |
import / from |
|
Java |
package |
目录结构 = 包 |
import |
15.2 C:头文件与链接
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif
// main.c
#include "math_utils.h"
|
阶段 |
工具 |
|
预处理 |
#include, #ifdef |
|
编译 |
各 .c → .o |
|
链接 |
gcc ... -o app |
C23:#embed 可把资源编进翻译单元。
依赖管理:无统一标准 → Makefile, CMake, Meson, vcpkg, Conan。
15.3 Go:module
myapp/
go.mod
go.sum
cmd/app/main.go
internal/pkg/...
module example.com/myapp
go 1.26
require (
golang.org/x/sync v0.10.0
)
|
命令 |
作用 |
|
go mod init |
初始化模块 |
|
go get pkg@version |
加依赖 |
|
go mod tidy |
整理依赖 |
可见性:internal/ 目录外不可导入(编译器强制)。
15.4 Python:包与 pyproject
myproject/
pyproject.toml
src/myapp/
__init__.py
main.py
[project]
name = "myapp"
version = "0.1.0"
dependencies = ["requests>=2.31"]
|
工具 |
用途 |
|
pip |
安装 |
|
venv |
虚拟环境 |
|
uv / poetry |
现代依赖锁定 |
import myapp.utils
from myapp.utils import helper
Python 3.14:
标准库多解释器支持(concurrent.interpreters),与打包独立。
15.5 Java:包、模块系统、构建
传统包
src/com/example/app/Main.java
package com.example.app;
Java 9+ 模块(module-info.java)
module com.example.app {
requires java.logging;
exports com.example.api;
}
Java 25:Module Import Declarations(定稿)
import module java.base;
// 简化入门,减少冗长 import
|
构建工具 |
说明 |
|
Maven |
pom.xml |
|
Gradle |
build.gradle.kts |
15.6 版本与发布
|
语言 |
版本语义 |
注册中心 |
|
C |
库各自版本 |
无中心 |
|
Go |
MVS 最小版本选择 |
模块代理 |
|
Python |
PEP 440 |
PyPI |
|
Java |
Maven 坐标 |
Maven Central |
15.7 可见性总结
|
级别 |
Go |
Python |
Java |
|
公开 |
大写标识符 |
无下划线 |
public |
|
内部 |
小写 |
_ 前缀 |
package-private |
|
私有 |
— |
__ 名修饰 |
private |
C 靠 static 限制文件作用域 + 头文件只暴露声明。
15.8 易混点
- Go 一个目录一个 package(除
main),目录名不必等于包名但建议一致。 - Python 相对导入
from . import x只在包内有效。 - Java 包名与目录必须一致(传统布局)。
- C
#include "local.h"vs<stdio.h>搜索路径不同。
16 标准库速览与学习路径
16.1 标准库哲学
|
语言 |
规模 |
特点 |
|
C |
极小(C23 略增) |
偏底层;其余靠 POSIX/第三方 |
|
Go |
中等偏大 |
电池够用,风格统一 |
|
Python |
大而全 |
“自带电池” |
|
Java |
超大(JDK) |
企业级 API 齐全 |
16.2 按领域对照
字符串与文本
|
领域 |
C |
Go |
Python |
Java |
|
核心 |
<string.h>, <ctype.h> |
strings, strconv, unicode/utf8 |
str, re |
java.lang.String |
|
格式化 |
printf 家族 |
fmt |
f-string, t-string |
String.formatted |
容器与算法
|
领域 |
C |
Go |
Python |
Java |
|
动态数组 |
手写 |
slice + append |
list |
ArrayList |
|
映射 |
手写/uthash |
map |
dict |
HashMap |
|
算法 |
qsort, bsearch |
sort |
sorted, heapq |
Collections |
I/O 与文件
|
领域 |
C |
Go |
Python |
Java |
|
文件 |
stdio, fcntl |
os, io, bufio |
pathlib, open |
java.nio.file |
|
网络 |
Berkeley sockets |
net, net/http |
socket, urllib, asyncio |
java.net, HttpClient |
时间与随机
|
领域 |
C |
Go |
Python |
Java |
|
时间 |
<time.h> |
time |
datetime |
java.time |
|
随机 |
rand |
math/rand, crypto/rand |
random, secrets |
Random, SecureRandom |
加密与安全
|
领域 |
C |
Go |
Python |
Java |
|
哈希 |
OpenSSL 等 |
crypto/* |
hashlib |
MessageDigest |
|
TLS |
OpenSSL |
crypto/tls |
ssl |
javax.net.ssl |
测试
|
语言 |
框架 |
|
C |
Unity, Criterion, Check |
|
Go |
testing, testify |
|
Python |
pytest, unittest |
|
Java |
JUnit 5 |
并发
|
语言 |
库 |
|
C |
pthread |
|
Go |
sync, context, goroutine 内置 |
|
Python |
threading, asyncio, multiprocessing |
|
Java |
java.util.concurrent, 虚拟线程 API |
16.3 C23 新增库要点
|
头文件 |
作用 |
|
<stdbit.h> |
位计数、前导零等 |
|
<stdckdint.h> |
checked 整数运算防溢出 |
|
char8_t / UTF-8 API |
国际化文本 |
|
memset_explicit |
安全清零 |
|
strdup / strndup |
字符串复制进标准 |
16.4 Python 3.14 值得知道的标准库
|
模块 |
作用 |
|
string.templatelib |
t-string 处理 |
|
compression.zstd |
Zstandard 压缩 |
|
concurrent.interpreters |
子解释器 |
|
asyncio 增强 |
更强 introspection |
|
pdb |
可 attach 运行中进程 |
16.5 Java 25/26 值得知道的标准库
|
API |
状态 |
|
虚拟线程 Executors.newVirtualThreadPerTaskExecutor |
定稿 |
|
Scoped Values |
定稿(25) |
|
Structured Concurrency |
预览(26) |
|
HttpClient HTTP/3 |
26 |
|
Vector API |
孵化器 |
|
Foreign Function & Memory |
替代 JNI 的现代本地接口 |
16.6 Go 1.26/1.27 标准库动态
|
包 |
说明 |
|
crypto/hpke |
1.26 新增混合公钥加密 |
|
testing/cryptotest |
加密测试辅助 |
|
encoding/json/v2 |
1.27 大改版(与 v1 并存) |
|
simd/archsimd |
1.26 实验性 SIMD |
16.7 推荐学习路径(交叉强化)
阶段 1:共性基础(2–3 周)
- 变量、类型、控制流 —— 用同一算法(斐波那契、素数筛)写四份
- 函数与 I/O —— 做「读 N 个数求平均」CLI
- 错误处理 —— 故意制造文件不存在、除零
阶段 2:数据结构(3–4 周)
- 数组/列表/切片
- map/dict/HashMap
- struct/class/record
阶段 3:抽象与工程(4–6 周)
- 接口与多态
- 泛型(Go/Java/Python 注解)
- 模块与依赖管理
- 单元测试
阶段 4:系统能力(按兴趣)
|
方向 |
主攻语言 |
|
系统/嵌入式 |
C |
|
后端服务 |
Go / Java |
|
数据/自动化 |
Python |
|
高并发 I/O |
Go + Java 虚线程 + Python asyncio |
阶段 5:2026 新特性补课
- C23:
nullptr,#embed,<stdbit.h> - Go 1.26:
new(expr), 泛型自引用 - Python 3.14:t-string, 延迟注解
- Java 25:compact main, scoped values, record
16.8 工具链速查
|
语言 |
格式化 |
静态检查 |
包管理 |
|
C |
clang-format |
clang-tidy, cppcheck |
CMake/Conan |
|
Go |
gofmt/goimports |
go vet, staticcheck |
go modules |
|
Python |
black, ruff format |
ruff, mypy, pyright |
pip/uv/poetry |
|
Java |
google-java-format |
SpotBugs, Error Prone |
Maven/Gradle |
更多推荐




所有评论(0)