高质量编程、编码规范以及性能优化 | 青训营笔记

96 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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是用于可视化和分析性能分析数据的工具

image.png

三、实践练习例子

pprof排查实战

wolfogre/go-pprof-practice: go pprof practice. (github.com)

业务服务优化

  • 建立服务性能评估手段:服务性能评估方式、请求流量构造、压测范围、数据采集
  • 分析性能数据,定位性能瓶颈:使用库不规范、高并发优化不足
  • 重点优化项改造:正确性保证、响应数据diff
  • 优化效果验证:重复压测、上线评估优化效果
  • 进一步优化:服务整体链路分析

基础库优化

  • 分析基础库核心逻辑和性能瓶颈
  • 内部压测验证
  • 推广业务服务落地验证

Go语言优化

  • 优化内存分配策略
  • 优化代码编译流程,生成更高效的程序
  • 内部压测验证
  • 推广业务服务落地验证

四、课后个人总结

还需要进一步熟练pprof工具的使用,业务服务优化的流程较为复杂,基础库优化和Go语言优化也接触不多,需要进一步熟悉,最好有相应的其他项目再进行自我训练。