编码规范| 青训营笔记

128 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记

良好的的代码习惯能体现出程序员的内功。

编码规范:

注释

  • 解释代码作用

    • 所有的公共符号都需要注释
    • 无论长度和复杂程度如何,库中任何函数都必须进行注释
  • 解释代码如何做

    • 注释实现过程
  • 实现的原因

    • 解释代码的外部因素
    • 提供额外上下文
  • 什么情况会出错

    • 解释代码的限制条件

代码是最好的注释,注释应该提供代码未表达的上下文,提供额外的有效信息。

命名规范

  • 简洁
  • 缩略词全大写,处于变量开头且不需要导出,使用全小写
  • 变量距离其被使用的地方越远,则需要更多上下文信息,使得容易被辨认其含义
  • package:只由小写字母组成。不包含大写字母和下划线的字符。尽量使用单数。

控制流程

  • 避免嵌套,保持正常流程流畅
  • 尽量保持正常代码路径为最小缩进
  • 线性原则,处理流程尽量直线,避免复杂的嵌套分支
  • 正常代码沿着屏幕向下移动
  • 提高可维护性和可读性
  • 故障问题大多出现在复杂的条件语句和循环语句中

错误和异常处理

  • 优先使用 errors.New 来创建匿名变量来直接表示简单错误
  • 如果有格式化需求,使用 fmt.Errorf

性能优化建议

  • 正确可靠、简洁清晰
  • 综合评估空间效率与时间效率

Benchmark

Go 语言提供支持基准性能测试的工具 benchmark

 go test -bench=. -benchmem

image-20220511155953896

  • 尽可能在使用make() 初始化切片时提供容量信息

    • 切片本质是一个数组片段的描述:数组指针、片段的长度、片段的容量
  • map 预分配内存

    • 不断向map添加元素的操作会触发map的扩容
    • 提前分配好空间可以减少内存拷贝和Rehash的消耗
    • 根据实际提前评估好需要的空间
  • 字符串在Go语言中是不可变类型,占用内存大小固定,使用 + 每次都会重新分配内存,而 strings.Builder, bytes.Buffer底层都是 byte[]数组,不需要每次重新分配内存
  • 使用空结构体节省内存
  • 多线程开发中使用 atomic 包:锁的实现通过操作系统实现,属于系统调用。 atomic 操作通过硬件实现,效率比锁高。锁 sync.Mutex 应该用来保护一段逻辑,不仅仅用于保护一个变量

总结:

  1. 避免性能陷阱
  2. 普通应用代码,不用一味追求性能
  3. 越高级性能优化手段越容易出问题
  4. 满足正确可靠、简洁清晰的质量要求下提高性能