Go代码审查应从main、init、HTTP handler、context.WithTimeout及自定义error类型入手,重点检查阻塞操作、资源泄漏、ctx监听、cancel配对、error链完整性。

Go 代码审查该从哪几个函数/结构体开始看
Go 代码审查不是通读全文件,而是盯住几个关键节点:入口、边界、并发、错误处理。真正容易出问题的,往往就藏在 main、init、http.HandlerFunc、context.WithTimeout 和自定义 error 类型里。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 先搜
func main()和func init():看是否有阻塞操作、全局变量初始化顺序依赖、未关闭的资源(如os.File、sql.DB) - HTTP handler 函数重点查:
ctx.Done()是否被监听、defer是否漏掉response.Body.Close()、是否直接用http.Error返回 500 而没记录日志 - 所有带
context.WithCancel/WithTimeout的地方,必须配对cancel();常见坑是 defer 在 goroutine 里调用,导致 cancel 永远不执行 - 自定义 error 类型如果实现了
Error()但没实现Unwrap()或Is(),会导致errors.Is()判断失效
go vet 和 staticcheck 能发现但常被忽略的警告
go vet 是 Go 官方静态检查工具,但默认只开基础检查;staticcheck 更严格,能揪出真实线上隐患——比如 time.Now().Unix() 在跨秒时可能返回重复值,或 for range 循环中把指针存进切片导致全部指向最后一个元素。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- CI 中至少启用:
go vet -tags=unit(注意加构建标签)、staticcheck -checks=all(可排除SA1019这类过时警告) - 特别关注
SA1017(defer 在循环中可能覆盖)、SA1021(用fmt.Sprint拼接 error 而非%w)、SA1029(map 遍历时直接取地址) - 别 suppress
SA9003(空 select case),它往往意味着 goroutine 泄漏
并发安全审查:sync.Map、channel、mutex 怎么选才不翻车
Go 并发模型不是“有 goroutine 就安全”,而是“谁读谁写、谁负责同步”。sync.Map 不是万能缓存方案,chan 也不是线程安全替代品,sync.RWMutex 错用反而比 sync.Mutex 更慢。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 高频读+低频写场景才考虑
sync.Map;普通 map +sync.RWMutex更可控,且支持len()、range等操作 - channel 用于协程通信,不是共享内存工具;禁止用
chan struct{}当信号量替代 mutex,容易死锁 - 用
sync.Mutex保护字段时,确保所有访问路径都加锁(包括 getter/setter 方法),常见坑是方法里忘了加锁,或锁了指针但没锁结构体字段 - goroutine 启动前必须确认 context 是否已 cancel;常见错误是
go fn(ctx)但 ctx 来自上层 HTTP 请求,没传 timeout
测试覆盖率高 ≠ 代码可靠:哪些 test 文件该重点审
Go 的 go test -cover 数字骗不了人,但能骗过人——比如只测 happy path、mock 掉所有 error 分支、用 t.Parallel() 导致数据竞争没暴露。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 重点看
*_test.go里有没有if err != nil { t.Fatal(err) }这种粗暴断言;应该用require.NoError或显式检查 error 类型 - HTTP handler 测试必须覆盖 status code、header、body 三者,不能只 check
resp.StatusCode == 200 - 并发测试加
-race是必须项;但更关键的是测试本身要触发竞争,比如用sync.WaitGroup控制多个 goroutine 同时读写同一变量 - 别信 mock 工具生成的 “完美” 测试;重点审 mock 的
Return值是否覆盖了nil、io.EOF、超时等边界情况
真正难审的从来不是语法或风格,是那些没写进 test 的隐式契约:context 生命周期、error 传播链、map/channel 的所有权转移。这些地方不报错,但一到压测或灰度就崩。


















