这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
注释
接口不需要注释,因为接口具体实现因业务而不同。
package
推荐全小写,不要下划线等字符 尽量使用单数
错误和异常处理
fmt. Errorf 使用%w 关联 Wrap, Unwrap 嵌套错误
错误判断使用 errors. Is,不使== errors. As
panic 和 recover 的使用
小节: error 方便定位问题 panic 真正异常 recover 在当前 gorutine 的被 defer 的函数中生效。
类 STL
切片操作并不复制切片指向的内容 创建新切片会复用原来切片的底层数组 陷阱:大内存未释放 使用 copy 代替 re-slice
map 也可以预分配内存 减少 map 扩容,内存拷贝,rehash 的消耗
字符串是不可变类型,+操作会重新分配内存 strings. Builder, bytes. Buffer 底层是[]byte 数组 +操作性能较差 同样 strings. Builder 和 bytes. Buffer 也有预分配内存的方式
空结构体 struct{}不占任何空间 作占位符使用,比如 set 的实现,用 map 如何实现。
atomic 包 原子变量 锁是操作系统实现,属于系统调用 原子操作是硬件实现 对于非数值操作,可以使用 atomic. Value, 能承载一个 interface{}
pprof
flat == cum,函数中没有调用其他函数 flat == 0,函数中只有其他函数的调用
flat 当前函数本身消耗 cum 当前函数本身和调用其他函数消耗
list 显示代码每一行消耗
heap 分析堆内存
goroutine 泄露会导致内存泄露
锁问题
Tips:分析步骤(Sample 采样) CPU、Mem、goroutine、锁、block(阻塞)、线程创建
命令行可能显示部分资源消耗(隐藏了某些资源消耗很少的),去浏览器可以看到所有的。
了解 pprof 的采样工作流程
优化
- 业务服务优化
- 基础库优化
- Go 语言优化
benchmark 只是单机,后面还需要集群压测
复现请求、复现服务(可以在更换服务后,相同的参数进行重新测试)