高质量编程
- 各种边界条件的考虑
- 异常情况处理,稳定性保证
- 易读易维护
注释
公共符号始终要注释
- 包中声明的每个公共符号:变量,常量,函数以及结构都需要注释
- 任何既不明显也不简短的公共功能必须注释
- 无论长度或复杂程度如何,对库中的任何函数都必须进行注释
代码格式
推荐使用gofmt自动格式化代码
命名规范
降低阅读和理解代码成本
变量
- 简洁胜于冗长
- 缩略词全部大写,但是其位于变量开头且不需要导出,使用全小写
- 距离使用地方远,尽量带更多上下文信息
函数
- 不需要携带包名的信息
- 尽量简短
- 当名为foo的包,某个返回类型为Foo,可以省略类型信息而不产生歧义
包
- 只由小写字母组成。
- 简短并且包含一定上下文信息
- 不要和标准库重名
- 谨慎使用缩写
控制流程
-
避免嵌套,保证正常流程清晰。
-
尽量保持正常代码路径为最小缩进。
- 优先处理错误情况/特殊情况,尽早返回或继续循环来减少嵌套
错误和异常处理
简单错误
- 仅出现一次的错误,优先使用
errors.New来创建匿名变量来直接表示简单错误。 - 错误的Wrap和Unwarp
性能优化
性能表现需要实际数据衡量,Go语言提供了基准性能测试的benchmark工具
性能优化建议
-
slice预分配内存,尽可能使用
make()初始化切片时提供容量信息 -
map预分配内存
-
字符串处理
- 使用strings.Builder处理字符串。因为字符串在Go中时不可变类型,每次使用
+操作符会重新分配内存 Grow方法初始化空间
- 使用strings.Builder处理字符串。因为字符串在Go中时不可变类型,每次使用
-
使用空结构体节省内存
- 空结构体
struct{}不占用任何内存空间,当作占位符使用 - 使用场景:使用map来实现set
make(map[int]struct{})
- 空结构体
-
使用atomic包,多线程安全,比使用加锁效率高。
性能优化工具
性能调优原则
- 要依靠数据
- 要定位最大瓶颈而不是细节
- 不要过早优化
- 不要过度优化
分析工具 pprof
pprof是用于可视化和分析性能的工具
功能简介
启动服务后,使用命令
命令行工具(CPU分析)
go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"(加入http参数可以使用网页可视化)
进入pprof,键入命令top产生结果
flat指的是当前函数本身执行耗时flat%flat占CPU总时间的比例sum%上面每一行flat%的总和cum指当前函数本身加上其调用函数的总耗时cum%cun占cpu总时间的比例
当flat == Cum的时候表明函数中没有调用其他函数
当flat == 0函数中只有其他函数调用
list Eat查看消耗在哪里
web命令
可以打开网页可视化结果,调用关系可视化
goroutine
gouroutine泄漏也会导致内存泄漏
火焰图
- 由上到下表示调用顺序
- 每一块代表一个函数,长度代表占用cpu时间
- 可以进行交互分析