这是我参与「第五届青训营 」笔记创作活动的的第3天
本文导航:
- 高质量编程
- 性能调优实战
高质量编程
定义:编写的代码能够达到正确可靠、简洁清晰的目标。
- 各种边界条件是否考虑完备
- 异常情况处理,稳定性保证
- 易读易维护
编程原则:简单性,可读性,生产力
编码的规范:代码格式,注释,命名规范,控制流程,错误和异常处理
-
代码格式:推荐使用gofmt自动格式化代码
-
注释
- 解释代码作用
- 描述如何编写的
- 实现的原因
- 什么情况会出错
- 公共符号始终要注释
-
命名规范
- 简洁胜于冗长
- 缩略词全大写
- 变量越远越要多的携带上下文信息
- 函数名不携带包名的上下文信息
- 函数名尽量简短
- 包名只由小写字母组成,简短包含上下文信息,不与标准库同名
- 推荐:不使用常用变量名作为包名,使用单数而不是复数,谨慎地使用缩写
-
控制流程
- 避免嵌套,保持正常流程清晰
- 尽量保持代码路径为最小缩进
-
错误和异常处理
-
简单错误:仅出现一次的错误,优先使用errors.New创建匿名变量,有格式化需求,使用fmt.Errorf
func main() { //errors.New的使用 err:= errors.New("Sample Error") if err != nil { fmt.Print(err) } //fmt.Errof的 const name, dept = "GeeksforGeeks", "CS" err:= fmt.Errorf("%q is a %q Portal.", name, dept) fmt.Println(err.Error()) }
-
Error Wrapping:提供了可以一个
error
嵌套另一个error
功能,好处就是我们可以根据嵌套的error
序列,生成一个error
错误跟踪链。e := errors.New("原始错误e") w := fmt.Errorf("Wrap了一个错误%w", e)//%w来生成一个可以Wrapping Error
errors
包添加了3个工具函数,他们分别是
Unwrap、
Is和
As- Unwrap函数:为了获得被嵌套的error
func main() { e := errors.New("原始错误e") w := fmt.Errorf("Wrap了一个错误%w", e) fmt.Println(errors.Unwrap(w))//得到一次嵌套的一个错误 }
-
Is函数:解决嵌套的error是否相等问题
func Is(err, target error) bool
- 如果
err
和target
是同一个,那么返回true
- 如果
err
是一个wrap error,target
也包含在这个嵌套error链中的话,那么也返回true
。
- 如果
-
As函数:把error转为另外一个error(在wrapping error加入之后)
var perr *os.PathError if errors.As(err, &perr) { fmt.Println(perr.Path) }
-
Go中引入的Exception处理:defer, panic, recover
- Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理
package main import "fmt" func main(){ fmt.Println("c") defer func(){ // 必须要先声明defer,否则不能捕获到panic异常 fmt.Println("d") if err:=recover();err!=nil{ fmt.Println(err) // 这里的err其实就是panic传入的内容,55 } fmt.Println("e") }() f() //开始调用f fmt.Println("f") //这里开始下面代码不会再执行 } func f(){ fmt.Println("a") panic("异常信息") fmt.Println("b") //这里开始下面代码不会再执行 fmt.Println("f") } 输出结果: c a d 异常信息 e
-
性能优化建议-Benchmark
benchmark工具
go test -bench=. -benchmem
性能优化建议-Slice
-
slice预分配内存
-
大内存未释放
go test -run=. -v
性能优化建议-Map
- map预分配内存
性能优化建议-字符串处理
strings. Builder
使用+拼接性能最差,strings. Builder,bytes. Builder相近,strings. Buffer更快
性能优化建议-空结构体
- 使用空结构体节省内存
性能优化建议-atomic包
atomic包:原子性
性能调优实战
性能调优原则:依靠数据,定位最大瓶颈而不是细枝末节,不要过早优化,不要过度优化
性能分析工具:pprof
可视化和分析性能分析数据
CPU,Heap堆内存,goroutine协程,mutex锁,block阻塞
pprof-排查实战
pprof-采样过程和原理
性能调优案例-业务服务优化
流程:
- 建立服务性能评估手段
- 分析性能数据,定位性能瓶颈
- 重点优化项改造
- 优化效果验证
性能调优案例-基础库优化
- AB实验SDK的优化
性能调优案例-Go语言优化
- 编译器&运行时优化