这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
今天也是青训营开始的第三天,在观看完学习视频并跟着做了一些练习之后,我感到收获颇丰,下面就来总结一下。
一、本堂课重点内容
- 高质量编程简介
- 高质量编程之编码规范
- 高质量编程之性能优化
- 性能调优实战
二、详细知识点介绍
高质量编程
--简介--
定义
编写的代码能够达到正确可靠、简洁清晰的目标可称之为高质量代码
原则
- 简单性
- 可读性
- 生产力
--编码规范--
代码格式
推荐使用gofmt自动格式化代码,也可以使用goimports,额外增加了依赖包管理的功能。
注释
注释应该的表现:
- 注释应该解释代码作用
- 注释应该解释代码如何做的
- 注释应该解释代码实现的原因
- 注释应该解释代码什么情况会出错
命名规范
变量
- 要尽量简洁
- 缩写词全大写,当位于开头但不需要导出时全小写。
- 变量声明和使用的地方越远,就越需要携带更多的上下文信息
函数
- 尽量简洁
- 不用携带包名的上下文信息
- 返回类型信息可以根据包名而加入省略
包
必须满足的原则:
- 只由小写字母组成
- 简短并包含一定的上下文信息
- 不要与标准库同名
尽量满足的原则:
- 不使用常用变量名作为包名
- 使用单数而不是复数
- 谨慎地使用缩写
控制流程
- 线性原理,处理逻辑尽量走直线,避免复杂的嵌套
- 尽量保持正常代码路径为最小缩进
- 分支正常流程代码沿着屏幕向下移动
错误和异常处理
- 简单错误:使用errors.New,如果有格式化需求使用fmt.Errorf
- 错误的warp和unwarp:warp提供了错误嵌套的能力,生成跟踪链,fmt.Errorf中使用%w关键字来将一个错误关联到错误链中。
- 错误的判定:判断一个错误是否为特定错误使用errors.Is而不是==,从错误链中获取特定错误用erros.As
- panic:不建议在业务代码中使用,可以用error代替,只在程序开头发生无法逆转错误时使用。
- recover:只能在被defer的函数中使用,嵌套无法生效,当前协程生效
--性能优化指南--
Benchmark
合理使用go语言提供的基准性能测试来查看数据,便于调优。
slice
- 尽量在make初始化切片时提供容量信息
- copy代替re-slice,防止大内存未释放
map
同样在make初始化时最好预分配内存。
字符串处理
优先使用strings.Builder、其次是strings.Buffer、最后才是+号来连接字符串。
空结构体
在需要占位的地方使用空结构体可以节省内存
atomic包
硬件实现,优于sync.Mutex,可以用于仅仅保护一个变量,对于非数值操作可以使用atomic.Value。
性能调优
原则
- 要依靠数据不是猜测
- 要定位最大瓶颈而不是细枝末节不要过早优化
- 不要过度优化
pprof
pprof是用于可视化和分析性能分析数据的工具
三、实践练习例子
pprof排查实战
wolfogre/go-pprof-practice: go pprof practice. (github.com)
业务服务优化
- 建立服务性能评估手段:服务性能评估方式、请求流量构造、压测范围、数据采集
- 分析性能数据,定位性能瓶颈:使用库不规范、高并发优化不足
- 重点优化项改造:正确性保证、响应数据diff
- 优化效果验证:重复压测、上线评估优化效果
- 进一步优化:服务整体链路分析
基础库优化
- 分析基础库核心逻辑和性能瓶颈
- 内部压测验证
- 推广业务服务落地验证
Go语言优化
- 优化内存分配策略
- 优化代码编译流程,生成更高效的程序
- 内部压测验证
- 推广业务服务落地验证
四、课后个人总结
还需要进一步熟练pprof工具的使用,业务服务优化的流程较为复杂,基础库优化和Go语言优化也接触不多,需要进一步熟悉,最好有相应的其他项目再进行自我训练。