这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
一、本堂课重点内容:
- 高质量编程
- 性能调优实战
二、详细知识点介绍:
1、高质量编程
1.1 简介
- 简单性
消除“多余的复杂性”,以简单清晰的逻辑编写代码
不理解的代码无法修复改进
- 可读性
代码是写给人看的,而非机器
编写可维护代码的第一步是确保代码可读
- 生产力
团队整体工作效率非常重要
1.2 编码规范
- 如何编写高质量的代码
代码格式
注释
命名规范
控制流程
错误和异常处理
- 公共符号始终要注释
解释代码作用
解释代码如何做的
解释代码实现的原因
解释代码什么情况会出错
- 推荐使用 gofmt 自动格式化代码(另有goimports)
1.3 命名规范
- 变量名
简洁
缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写
变量距离其被使用的地方越远,则需要携带越多的上下文信息
- 函数
函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的
函数名尽量简短
当名为 foo 的包某个函数返回类型 Foo 时,可以省略类型信息而不导致歧义
当名为 foo 的包某个函数返回类型 T 时(T 并不是 Foo),可以在函数名中加入类型信息
- 包
只由小写字母组成。不包含大写字母和下划线等字符 简短并包含一定的上下文信息。例如 schema、task 等 不要与标准库同名。例如不要使用 sync 或者 strings
1.4 控制流程
- 避免嵌套,保持正常流程清晰
- 尽量保持正常代码路径为最小缩进
1.5 错误和异常处理
- 简单错误
优先使用 errors.New
需要格式化,使用 fmt.Errorf,%w 将错误关联至错误链中
- 错误判定(errors.Is)
- 错误链上获取特定种类错误(errors.As)
- 程序启动阶段发生不可逆准错误(panic)
- recover(只能在当前 goroutine 被 defer 的函数中使用)
1.6 性能优化
- 建议
Benchmark
slice 预分配内存
map 预分配内存
空结构体
atomic 包
2、性能调优
2.1 性能分析工具 pprof
- 分析 Profile
- 工具 Tool
- 展示 View
- 采样 Sample
2.2 cpu 采样
采样对象:函数调用和它们占用的时间
采样率:100次/秒,固定值
采样时间:从手动启动到手动结束
2.3 Heap-堆内存
采样程序通过内存分配器在堆上分配和释放的内存,记录分配/释放的大小和数量
采样率:每分配512KB记录一次,可在运行开头修改,1为每次分配均记录
采样时间:从程序运行开始到采样时
采样指标:alloc_space, alloc_objects, inuse_space, inuse_objects
计算方式:inuse = alloc - free
2.4 性能评估手段
服务性能评估方式
- 单独 benchmark 无法满足复杂逻辑分析
- 不同负载情况下性能表现差异
请求流量构造
- 不同请求参数覆盖逻辑不同
- 线上真实流量情况
压测范围
- 单机器压测
- 集群压测
性能数据采集
- 单机性能数据
- 集群性能数据