这是我参与「第五届青训营 」伴学笔记创作活动的第2天
高质量编程简介及编码规范
1 高质量编程
1.1 高质量编程简介
高质量是指编写的代码能够达到正确可靠、简洁清晰的目标可称之为高质量代码。
通常也会考虑各种边界条件是否完备;异常情况处理,稳定性保证;易读性维护。
编程原则:简单性、可读性、生产力
简单性:消除“多余的复杂性”,以简单清晰的逻辑编写代码;不理解的代码无法修复改进。
可读性:代码是写给人的,而不是机器;编写可维护代码的第一步是确保代码可读。
生产力:团队整体工作效率非常重要。
1.2 编码规范
如何编写高质量的代码:代码格式、注释命名规范、控制流程、错误和异常处理。
1.2.1 编码规范-代码格式
推荐使用gofmt自动化代码:gofmt 、goimports。
1.2.2 编码规范-注释
简介:注释应该做的:解释代码作用、解释代码如何做的、解释代码实现的原因、解释代码什么情况会出错。
tips:公共符号始终要注释。
1.2.3 命名规范
variable
简洁胜于冗长。
缩略词全大写,但当其位于变量开头且不需要导出,使用全小写。
将deadline替换成t降低了变量名的信息量;t常代指任意时间;deadline指截止时间,有特定的含义。
小结:核心目标是降低阅读理解代码的成本;重点考虑上下文信息,设计简洁清晰的名称。
1.2.4 控制流程
避免嵌套保持正常流程清晰。
如果两个分支中都包含return语句,则可以去除冗余的else。
尽量保持正常代码路径为最小缩进:优先处理错误情况,尽早返回或继续循环来减少嵌套。
1.2.5 错误和异常处理
简单错误:优先使用errors.New来创建匿名变量来直接表示简单错误,如有格式化的需求,使用fmt。Errorf。
错误的Wrap和Unwrap。
错误判定:判定一个错误链上获取特定种类的错误,使用errors.As。
recover:recover只能在被defer的函数中使用、嵌套无法生效、只在当前goroutine生效、defer的语句是后进先出。
1.3 性能优化建议
1.3.1 性能优化建议-Benchmark
性能表现需要实际数据衡量,Go语言提供了支持基准性能测试的benchmark工具。
结果说明:
1.3.2 性能优化建议-Slice
slice预分配内存:尽可能在使用make()初始化切片时提供容量信息。
1.3.3 性能优化建议-Map map预分配内存:
1.3.4 性能优化建议-字符串处理
使用string.Builder:
1.3.5 性能优化建议-空结构体
使用空结构体节省内存。
实现Set,可以考虑用map来代替; 对于这个场景,只需要用到map的键,而不需要值; 即使是将map的值设置为bool类型,也会多占据1个字节空间。
1.3.6 性能优化建议-atomic包
atomic包操作是通过硬件实现,效率比锁高。
sync.Mutex应该用来保护一段逻辑,不仅仅用于保护一个变量
对于非数值操作,可以使用atomic.Value,能承载一个interface{}
2 性能调优实战
2.1 简介
性能调优原则:要依靠数据不是猜测;要定位最大瓶颈而不是细枝末节;不要过早优化;不要过度优化。
2.2 性能分析工具pprof
说明:希望知道应用在什么地方耗费了多少CPU、Memory;pprof是用于可视化和分析性能分析数据的工具。
2.2.1 性能分析工具pprof-功能简介
2.2.2 性能分析工具pprof-排查实战
搭建pprof实践项目:
浏览器查看指标:
CPU:
Head-堆内存:
goroutine协程:goroutine泄露也会导致内存泄露。