这是我参与「第三届青训营 -后端场」笔记创作活动的的第 4 篇笔记
本文为个人创作将会在本人掘金以及CSDN等平台发布
今天上完张雷老师所讲的《高质量编程与性能调优实战》课程,其中收获颇多,下面我分享以下上课做的笔记吧~
- 如何编写更简洁清晰的代码
- 常用Go语言程序优化手段
- 熟悉Go程序性能分析工具
- 了解工程中性能优化的原则和流程
1.高质量编程(编写的代码能够达到正确可靠、简洁清晰的目标)
- 各种边界条件是否考虑完备
- 异常情况处理,稳定性保证
- 易读易维护
1.1.简介
- 简单性
- 可读性
- 生产力(团队整体工作效率非常重要)
1.2.编码规范
-
代码格式
-
注释
a.解释代码的作用
b.解释代码如何做的
c.解释代码实现的原因(为什么这么做)
d.解释代码什么情况下会出错
e.公共符号始终要注释
- 代码是最好的注释
- 注释应该提供代码未表达出的上下文信息
-
命名规范(简洁)
- 核心目标是降低阅读理解代码的成本
- 重点考虑上下文信息,设计简洁清晰的名称
-
控制流程
a.避免嵌套,保证正常流程清晰
b.尽量保持正常代码路径为最小缩进
- 线性原理,处理逻辑尽量走直线,避免复杂的嵌套分支
- 正常流程代码沿着屏幕向下移动
- 提升代码可维护性和可读性
- 故障问题大多出现在复杂的条件语句和循环语句中
-
错误和异常处理
- error尽可能提供简明的上下文信息链,方便定位问题
- panic用于真正异常的情况
- recover生效范围,在当前goroutine的被defer的函数中生效
1.3.性能优化建议
1.3.1 Benchmark(Go自带)
1.3.2 Slice
slice预分配内存
type slice struct{
array unsafe.Pointer //数组指针
len int //片段长度
cap int //片段容量
}
1.3.3 map
map预分配内存
- 不断向map中添加元素的操作会触发map的扩容
- 提前分配好空间可以减少内存拷贝和Rehash的消耗
- 建议根据实际需求提前预估好需要的空间
1.3.4 字符串处理
使用string.Builder
1.3.5 空结构体(使用空结构体节省内存)
1.3.6 atomic包
- 锁的实现是通过操作系统来实现,属于系统调用
- atomic操作是通过硬件实现,效率比锁高
- sync.Mutex应该用来保护一段逻辑,不仅仅用于保护一个变量
- 对于非数组操作,可以使用atomic.Value,能承载一个接口
- 避免常见的性能陷阱可以保证大部分程序的性能
- 普通应用代码,不要一味追求程序性能
- 越高级的性能优化手段越容易出现问题
- 在满足正确可靠、简洁清晰的质量要求的前提下提高程序性能
2.性能调优原则
- 要依靠数据不是猜测
- 要定位最大瓶颈而不是细枝末节
- 不要过早优化
- 不要过度优化