这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
学习内容
高质量编程
如何编写更简洁更清晰的代码?
高质量代码:正确可靠、边界处理合理、异常处理稳定、易读易维护。
编程原则:简单性、可读性、生产力(团队整体工作效率) —— Go 语言开发者
编码规范:
-
公共符号始终要注释,包括对外的函数、结构体等;
-
gofmt:自动格式化代码,goimports:自动依赖包管理; -
注释包含四个方面(见名知意的内容不需要额外注释):
- 代码作用,适合注释公共内容;
- 如何做的,代码的实现过程;
- 实现的原因,适合解释代码的外部因素,需要联系上下文进行理解;
- 什么情况下会出错,适合解释代码的限制条件。
-
命名规范:
- 缩略词全大写;
- 变量距使用的地方越远,需要携带更多的上下文信息;
- 见名知意;
- 函数名不需要携带包名的上下文信息;
- 包名只由小写字母组成,不包含大写字母和下划线,并且不使用常用变量名作为包名;
-
控制流程:
- 尽量减少代码嵌套;
- 尽量保持正常代码路径为最小缩进;
-
错误和异常处理:
-
简单错误是指仅出现一次的错误,优先使用
errors.New()来表示错误;// 使用%w将一个错误关联至错误链中 fmt.Errorf("...: %w", err) // 错误判定,错误链上是否有指定错误 if errors.if(err, fs.ErrNotExist) // 获取指定种类错误 if errors.As(err, &pathError) -
panic,在程序启动阶段中发生不可逆转的错误时,需要使用panic;
-
recover,只能在被defer的函数中使用。
-
好的命名就像一个好笑话,如果你解释它的话,那就不好笑了。 —— Dave Cheney
性能调优
常用的优化手段,常用的性能分析工具、优化过程中的原则和流程。
性能表现需要实际数据衡量。
性能优化建议:
- 尽可能使用
make()初始化 slice\map 时提供容量信息; - 拼接字符串时,
string.Builder\bytes.Buffer性能更好; - 使用空结构体节省内存,常见于用map实现set;
- atomic包相对于锁来说,性能更高。
项目实战
原则:
- 看数据而不是猜测;
- 要关注与最大瓶颈;
- 不需要过早优化;
- 不需要过度优化,可能会在后续的更新产生不兼容
性能分析工具 pprof 。
业务服务优化流程:
- 建立服务性能评估手段
- 分析性能数据,定位性能瓶颈
- 重点优化项目改造
- 优化效果验证
个人总结
- 我想一个好的注释,应该是两三年之后,我看到注释仍然能够了解到代码的作用、实现过程等;
- 异常处理尽量提供相应的上下文信息,这样可以更方便快速排查错误;
- 性能优化过程中,一定要用数据说话。