这是我参与「第五届青训营 」笔记创作活动的第3天
本节课重点
高质量代码
是什么
编写的代码能够达到正确可靠、简洁清晰的目标可称之为高质量代码
- 各种边界条件考虑完备。
- 异常情况处理,稳定性保证。
- 易读易维护。
为什么
- 简洁
- 消除“多余的复杂性”,逻辑应追求简单清晰
- 不理解的代码无法修复改进
- 可读性
- 代码面向程序员的
- 可维护代码的基石是具有可读性
- 生产力
- 团队整体工作效率非常重要
怎么做
代码格式
代码格式化的工具:
- gofmt
- goimports
注释
Good code has lots of comments, bad code requires lots of comments.
应该做什么
- 应该解释代码的作用
- 应该解释代码如何做的
- 注释实现过程
- 应该解释代码实现的原因
- 解释代码的外部因素
- 提供额外上下文
- 应该解释代码的边界条件、什么情况会出错
- 解释代码的限制条件
应该注意什么
- 对于包中的变量,常量,函数及其结构添加合理的注释
- 对于功能不明显也不简短的代码必须给予注释
- 对库中的任何函数都必须进行注释
- 对于实现接口的方法不需要注释
命名规范
Good naming is like a good joke. If you have to explain it, it's not funny.
variable
- 简洁胜于冗长
- 缩略词全大写, 但当是变量开头且不需要导出,使用全部小写
- 变量声明距离被使用的地方越远越要携带更多上下文信息
functino
- 函数名不携带包名的上下文信息,因为包名和函数名总是成对出现
- 函数名尽量简短
- 当包名和包中函数返回类型一致时可以省略类型信息
package
- 小写
- 简短且需要包含上下文信息
- 不与标准库重名
- 不使用常用变量名作为包名
- 单数
- 缩写要尽量不丢失信息
控制流程
- 避免嵌套
good
if foo {
return x
} else {
return nil
}
better
if foo {
return x
}
return nil
- 优先处理特殊情况,使代码保持最小缩进 原则
- 处理逻辑尽量走直线,避免复杂的分支嵌套(事故高发区)
- 正常流程代码沿着屏幕向下移动
- 提升代码可维护性和可读性
错误和异常处理
- 优先使用erros.Now创建匿名变量来表示错误
- 如果需要格式化使用fmt.Errorf
- 使用errors.Is进行错误类型的判断
- 获取特定种类的错误使用errors.As
- 在程序启动阶段发生不可逆转的错误时在init/main使用panic
- recover在当前goroutine的被defer的函数中生效
性能优化建议
Benchmark
go test -bench =. -benchmem
- 预分配大小
- slice (不会创建一个新数组)
- map
- 字符串拼接
- +、strings.Builder, bytes.Buffer、strings.Buffer 性能递增
- 空结构体节省内存
- 空结构体(struct{})不占用任何内存空间
func EmptySructMap(n int) {
m := make(map[int] struct{})
for i := 0; i < n; i ++ {
m[i] = struct{}{}
}
}
for BoolMap(n int) {
m := make(map[int] bool)
for i := 0; i < n; i ++ {
m[i] = flase
}
}
- 使用atomic包
//high
type atomicCounter strucrt {
i int32
}
func AtomicAddOne(c *atomicCounter) {
atomic.AddInt32(&c, i, 1)
}
// low
type mutexCounter struct {
i int32
m sync.Mutex//保护一段逻辑
}
func MutexAddOne(c *mutexCounter) {
c.m.Lock()
c.i++
c.m.Unlock()
}
实例
工具
pprof,用于可视化和分析性能分析数据的工具。
排查实战
使用浏览器查看指标。
- CPU查看,
go tool pprof "address"topN查看占用最多的函数web调用关系可视化
- heap堆内存
go tool pprof -http=:8080 "address/heap"
- 协程
go tool pprof -http=:8080 "address/goroutine"
- mutex-锁
go tool pprof -http=:8080 "address/mutex"
- block
go tool pprof -http=:8080 "address/goroutine"