代码 Review 指南
date
May 4, 2023
slug
go-code-review-guide
status
Published
tags
Code
Collection
summary
Go 语言代码 review 指南(内容还在不断修订中)
type
Post
Created Time
Oct 28, 2023 01:45 PM
Updated Time
Oct 28, 2023 01:45 PM
AI summary
Status
注释规范
众所周知,好的方法名、变量名,就是最好的注释。除此之外,在一些情况下,应该添加必要的注释:
- 所有的结构体都必须添加简单的注释描述;
- 方法内部复杂的业务逻辑或者算法,应当添加简介的注释(可以考虑粘贴需求链接);
- 任何需要提醒、警告、TODO,都要添加清晰的注释;
- 业务代码里避免使用多行注释
/* */
;
- 一段代码逻辑,同事如果第一遍没看懂,就需要添加注释了;
日志规范
好的日志能够快速定位和解决问题!如何正确的打印日志?
- 根据业务场景,选择合适的日志级别:
error
、warn
、info
、debug
等,使用开关进行输出判断。
- 日志必须包含基本信息:时间、日志级别、函数调用栈、
- 方法的日志,必须打印入参和出参;
- 在进入条件判断前就记录日志;
- 建议使用异步的方式来输出日志;
- 对日志文件进行分类管理;
- 核心功能,关键功能模块需要打印相对完整的日志;
- 日志中的关键信息,比如手机号、身份证、密码等,需要脱敏处理;
命名规范
毋庸置疑,非常重要!
- 结构体和接口应全部使用首字母大写的驼峰命名法;
- 常量应使用全大写字母和下划线命名;
- 选择正确且易于理解的英文进行命名,慎用简称!
参数校验
敲黑板!方法的参数必须进行校验,如手机号码、身份证号码、金额范围、用户 ID 等,避免异常参数入库!
判空处理
interface
、指针对象的使用都必须进行判空处理,避免发生空指针异常!异常处理规范
- 业务代码里不要使用
panic
,如果发生错误,该函数必须返回错误,由调用方决定如何处理它;
- 类型转换失败会导致进程
panic
,所以对于类型转换,一定要使用!ok
的范式来处理;
- Panic/Recover 并不是 Error 处理策略,除了程序初始化,只有在发生不可恢复的事件时,程序才必须 Panic。
并发编程
- 不要在
init()
中使用goroutines
;
- 为了防止 goroutine 泄漏,每个 goroutine 都必须有一个可预测的停止时间或者有一种方法可以向 goroutine 发出信号,使其停止;
- 推荐使用 go.uber.org/goleak 测试 goroutine 泄漏,使用方式可以参考这篇文章;
- 必须有一种方式阻塞并等待 goroutine 完成,可选择的方案包括:
sync.WaitGroup
、chan struct{}
,另外,Channel 的 size 要么是 1,要么是无缓冲的;
单元测试
- 单元测试需要遵守幂等性;
代码格式
良好的代码格式,可以使代码更容易阅读和理解。一些常见的代码格式化建议如下:
- 代码提交前必须使用 gofmt 进行格式化;
- 对外暴露的方法避免超过 100 行,未导出的方法避免超过 80 行;
- 顶层使用
var
关键字,请勿指定类型,除非它与表达式的类型不同;
- 对于未导出的顶层常量和变量,使用 _作为前缀;
- 缩小变量的作用范围;
- 程序圈复杂度(Cyclomatic complexity,CC),也称条件复杂度,应尽量低于 10;
接口兼容性
- 老接口的修改必须考虑接口的兼容性;
程序应逻辑应清晰、主次分明
- 这里推荐一个开源仓库;
- 最重要的:业精于勤,荒于嬉;行成于思,毁于随。
安全规范
- 输入校验:任何外部输入数据都应当谨慎对待,确保不会对系统造成伤害,校验应包括检查数据类型、大小和格式。
- 防范 SQL 注入攻击:应使用参数化查询或预处理语句,防止 SQL 注入攻击。
- 防范跨站脚本攻击(XSS)
- 避免敏感信息泄露:使用加密传输,并且避免在日志、调试信息或错误消息中泄露敏感信息。
- 防范跨站请求伪造(CSRF)
事务控制
- 尽量避免在事务中处理非数据库操作的复杂逻辑;
- 不要在事务中进行远程调用;
- 需要查询的数据应尽量在事务执行之前就准备好,避免处理太多的数据;
中间件注意事项
- 数据库
- 查询多条数据时,必须设置 limit;
- 业务代码中尽量避免连表查询;
- 必须有慢 SQL 监控;
- 索引的创建必须有两人或两人以上确认;
- ……
- Redis
- 所有 Key 都必须有过期时间;
- 尽量避免使用 hgetall、smember 命令;
- 避免缓存穿透、缓存雪崩、缓存击穿;
- ……