Day3 (上)高质量编程与性能调优 | 青训营笔记

90 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

1 高质量编程

1.1 简介

  • 什么是高质量

    • 各种边界条件是否考虑完备
    • 异常情况处理,稳定性保证
    • 易读易维护
  • 编程原则:简单性,可读性,生产力

1.2 编码规范

  • 代码格式:使用gofmt自动格式化代码
  • 注释:
    • 注释应该解释代码作用
    • 注释应该解释代码如何做的
    • 注视应该解释代码实现的原因(解释外部因素,提供额外上下文)
    • 注释应该解释代码什么情况会出错(限制条件)
    • 公共符号始终要注释
  • 命名规范:降低阅读理解代码的成本;重点考虑上下文信息,设计简洁清晰的名称
    • 变量
      • 缩略词:不位于变量开头全大写
      • 外部调用的变量名:需要包含上下文信息
    • 函数名
      • 函数名不包含包名的上下文信息,因为包名和函数名总是成对出现的
      • 尽量简短
    • 包名
      • 全小写字母
      • 尽量使用单数而非复数
  • 控制流程:线性流程
    • 避免嵌套,保持正常流程清晰
    • 尽量保持正常代码路径为最小缩进,这样新增条件判断不会对其他的产生影响 image.png
  • 错误和异常处理
    • 简单错误
      • 优先使用errors.New来创建匿名变量来直接表示简单错误
      • 如果有格式化需求,使用fmt.Errorf
    • error的跟踪链:在fmt.Errorf中使用%w关键字来将一个错误关联至错误链中
    • 错误判定:errors.Is errors.As
    • panic:当程序启动阶段发生不可逆转的错误
    • recover:只能在当前goroutine的被defer的函数中使用;使用debug.Stack在log中记录当前的调用栈

1.3 性能优化建议-Benchmark

  • Slice

    • 预分配内存
    • 大内存未释放的问题
      • 如果原始切片较大,在该切片基础上创建小切片,则原底层数组在内存中有引用,得不到释放
      • 使用copy替代re-slice,减少内存开销
  • map

    • 预分配内存:提前分配好空间可以减少内存拷贝和rehash的消耗
  • string

    • strings.Builder
    • bytes.Buffer
  • struct

    • 使用空结构体节省内存(考虑使用map空结构体实现set
  • 多线程

    • atomic包(通过硬件实现,效率好) ✅
    • 加锁

参考资料

  1. github.com/RaymondCode…
  2. github.com/golang/go/w…
  3. juejin.cn/post/718822…