这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记
一、高质量编程
1 简介
高质量:正确可靠、简洁清晰。
- 各种边界条件是否考虑完备
- 异常情况处理,稳定性保证
- 易读易维护
编程原则
简单性:
- 消除“多余的复杂性”,以简单清晰的逻辑编写代码
- 不理解的代码无法修复改进 可读性:
- 代码是写给人看的,而不是机器
- 编写可维护代码的第一步是确保代码可读 生产力:
- 团队整体工作效率非常重要
2 编码规范
代码格式;注释;命名规范;控制流程;错误和异常处理
1)代码格式
gofmt自动格式化代码;
goimports等于gofmt加上依赖包管理;
2)注释
- 解释代码作用(适合注释公共符号)
- 解释代码如何做的(适合注释实现过程)
- 解释代码实现的原因(适合解释代码的外部因素,提供额外上下文)
- 解释代码什么情况会出错(适合解释代码的限制条件)
- 公共符号始终要注释(不需要注释实现接口的方法)
3)命名规范
variable:
- 简洁胜于冗长
- 缩略词全大写,但当其位于开头且不需要导出时,用全小写
- 需要导出的,首字母大写,不需要的小写
- 变量距离使用地方越远,上下文信息应该越多
function:
- 函数名不用携带包名的上下文信息
- 尽量简短
- 名为foo的包如果返回类型也是Foo,函数名可以省略类型;返回类型不一致时,函数名可以加入
package:
- 小写字母组成,不含大写字母和下划线
- 简短,包含一定上下文
- 不要与标准库同名
- 尽量不使用常用变量名
- 尽量使用单数,不是复数
- 缩写要谨慎
4)流程控制
- 避免嵌套,冗余的else可以去除
- 尽量保持正常代码路径为最小缩进(比如,优先处理错误/特殊情况)
- 线性原理,处理逻辑尽量走直线,避免复杂的嵌套分支
- 正常流程代码沿着屏幕向下移动
- 提升代码的可读性和可维护性
5)错误和异常处理
简单错误:
- 仅出现一次的,其他地方不需要捕获
- 优先使用errors.New来创建匿名变量
- fmt.Errorf来格式化
错误的Wrap和Unwrap:
- 错误的Wrap是一个error嵌套另一个error,生成error的跟踪链
- fmt.Errorf中使用%w来将一个error关联至一个错误链 错误判定:
- errors.Is来判断
- errors.As可以提取类型
panic:
- 不建议在业务代码中使用panic
- 调用哈数不包含recover会造成程序崩溃
3 性能优化
benchmark
基准性能测试的benchmark工具;
go test -bench=. -benchmem
slice
- 预分配内存
- slice的底层是一个数组片段,扩容时需要复制(类似java的list)
- 在已有切片的基础上创建切片,不会创建新的底层数组,原底层数组在内存中引用,建议使用copy
map
- 预分配内存
strings.Builder
- 类似java的StringBuilder
空结构体来节省内存
- 比如实现set用map来代替,map的值用空struct
atomic包
- atomic包的效率比锁搞,锁是通过操作系统来实现的
二、性能调优实战
1 简介
性能调优原则
- 依靠数据不是猜测
- 定位最大瓶颈而不是细枝末节
- 不要过早优化或者过度优化
2 性能分析工具pprof
- 用于可视化和分析性能分析数据的工具
- 知道应用在什么地方耗费了多少CPU和memory
3 性能调优案例
- 业务服务优化
- 基础库优化
- Go语言优化