这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
1 高质量编程
1.1 简介
-
什么是高质量
- 各种边界条件是否考虑完备
- 异常情况处理,稳定性保证
- 易读易维护
-
编程原则:简单性,可读性,生产力
1.2 编码规范
- 代码格式:使用
gofmt自动格式化代码 - 注释:
- 注释应该解释代码作用
- 注释应该解释代码如何做的
- 注视应该解释代码实现的原因(解释外部因素,提供额外上下文)
- 注释应该解释代码什么情况会出错(限制条件)
- 公共符号始终要注释
- 命名规范:降低阅读理解代码的成本;重点考虑上下文信息,设计简洁清晰的名称
- 变量
- 缩略词:不位于变量开头全大写
- 外部调用的变量名:需要包含上下文信息
- 函数名
- 函数名不包含包名的上下文信息,因为包名和函数名总是成对出现的
- 尽量简短
- 包名
- 全小写字母
- 尽量使用单数而非复数
- 变量
- 控制流程:线性流程
- 避免嵌套,保持正常流程清晰
- 尽量保持正常代码路径为最小缩进,这样新增条件判断不会对其他的产生影响
- 错误和异常处理
- 简单错误
- 优先使用
errors.New来创建匿名变量来直接表示简单错误 - 如果有格式化需求,使用
fmt.Errorf
- 优先使用
- error的跟踪链:在
fmt.Errorf中使用%w关键字来将一个错误关联至错误链中 - 错误判定:
errors.Iserrors.As panic:当程序启动阶段发生不可逆转的错误recover:只能在当前goroutine的被defer的函数中使用;使用debug.Stack在log中记录当前的调用栈
- 简单错误
1.3 性能优化建议-Benchmark
-
Slice
- 预分配内存
- 大内存未释放的问题
- 如果原始切片较大,在该切片基础上创建小切片,则原底层数组在内存中有引用,得不到释放
- 使用copy替代re-slice,减少内存开销
-
map
- 预分配内存:提前分配好空间可以减少内存拷贝和rehash的消耗
-
string
strings.Builderbytes.Buffer✅
-
struct
- 使用空结构体节省内存(考虑使用
map空结构体实现set)
- 使用空结构体节省内存(考虑使用
-
多线程
- atomic包(通过硬件实现,效率好) ✅
- 加锁
参考资料