GO--高质量编程与调优|青训营笔记
这是我参与「第五届青训营」伴学笔记创作活动的第10天
在后面会依次倒叙回顾之前的学习课程,便于复习~
一、课程重点内容
- 高质量编程
- 性能调优
下面是对课程重点内容的思考与总结,有问题或者错误,可以批评指正呐~
二、高质量编程
定义:编写的代码能够达到正确可靠、简洁清晰的目标。
-
特点分析
- 正确性:是否考虑各种边界条件,错误的调用是否能够处理
- 可靠性:异常情况或者错误的处理策略是否明确,依赖的服务出现异常是否能够处理
- 简洁:逻辑是否简单,后续调整功能或新增功能是否能够快速支持
- 清晰:其他人在阅读代码的时候是否能清楚明白,重构或修改功能是否不用担心出现无法预料的问题
-
Go的高质量编程
-
代码格式:使用gofmt自动格式化代码
-
代码的注释:
- 解释代码作用
- 解释代码如何做的
- 解释代码实现的原因
- 解释代码什么情况会出错
- 公共符号始终要注释
-
代码的命名规范:
- 简洁胜于冗长
- 缩略词全大写,但当期位于变量开头且不需要导出时,使用全小写
- 变量距离其被使用的地方越远,则需要携带越多的上下文信息
- 函数名不携带包名的上下文信息且尽量简短
- package名只由小写字母组成
-
控制流程
- 避免嵌套,保持正常流程清晰,例如去掉不必要的
else - 尽量保持正常代码路径为最小缩进,能对称就对称
- 故障问题的大多出现在复杂的条件语句和循环语句中,尽量化简为单个函数进行测试
- 避免嵌套,保持正常流程清晰,例如去掉不必要的
-
异常处理
- 简单错误:指仅出现一次的错误,且在其他地方不需要捕获该错误
- 优先使用
errors.New来创建匿名变量来直接表示简单错误 - 如果有格式化需求,请使用
fmt.Errorf
-
三、性能优化
-
概念:
- 从资源视角出发来对一台服务器进行审视的话,CPU、内存、磁盘与网络是后端服务最需要关注的四种资源类型。
- 对于计算密集型的程序来说,优化的主要精力会放在 CPU 上,要知道 CPU 基本的流水线概念,知道怎么样在使用少的 CPU 资源的情况下,达到相同的计算目标。
- 对于 IO 密集型的程序(后端服务一般都是 IO 密集型)来说,优化可以是降低程序的服务延迟,也可以是提升系统整体的吞吐量。
-
GO的检测方法
CPU profile:报告程序的 CPU 使用情况,按照一定频率去采集应用程序在 CPU 和寄存器上面的数据
Memory Profile(Heap Profile):报告程序的内存使用情况
Block Profiling:报告 goroutines 不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈
Goroutine Profiling:报告 goroutines 的使用情况,有哪些 goroutine,它们的调用关系是怎样的
-
Go的优化手段
-
协程池
-
绝大部分应用场景,go是不需要协程池的。当然,协程池还是有一些自己的优势:
- 可以限制goroutine数量,避免无限制的增长。
- 减少栈扩容的次数。
- 频繁创建goroutine的场景下,资源复用,节省内存。(需要一定规模。一般场景下,效果不太明显)
-
-
反射
go里面的反射代码可读性本来就差,常见的优化手段进一步牺牲可读性。而且后续马上就有范型的支持,所以若非必要,建议不要优化反射部分的代码
- 缓存反射结果,减少不必要的反射次数。例如json-iterator
- 直接使用
unsafe.Pointer根据各个字段偏移赋值 - 消除一般的
struct反射内存消耗go-reflect - 避免一些类型转换,如
interface->[]byte。可以参考zerolog
-
锁
并发场景下,对临界区加锁比较常见。带来的性能隐患也必须重视。
- 减小锁力度
- 原子操作atomic
-
五、课程总结
了解到Go的编程技巧与代码规范,同时如何进行代码性能分析与测试,以后一定好好用这些工具