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

71 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第3天,感觉比昨天容易理解,但与之相对的,非常需要实践去支撑,遗憾的是时间有点不够,争取快速过一遍数据库和网络,有对应基础好好完成项目。

1.高质量编程

1.1 简介

易读易维护
各种边界环境考虑完备
异常情况处理,稳定性保证

通用原则 简单性

可读性

生产力

1.2 编码规范

1.2.1 代码格式

gofmt自动格式化代码为官方同一风格
goimports
等于gofmt加上依赖包管理
自动增删pkg的引用,并按字母排序

1.2.2 注释

包中每个公共的符号
库中任何函数都要注释
解释代码作用,
如何做的,
实现原因,给出额外上下文
什么情况会出错,解释代码的限制条件

1.2.3 命名规范

variable

  • 缩略词全大写,在变量开头不需要导出时全小写

  • 变量对使用地方越远,携带越多上下文信息

function

  • 函数名不携带包名的上下文信息,因为两者总是成对存在

pkg

  • 只有小写字母构成
  • 包含一定上下文
  • 与标准库不同名

以下规则尽量满足

  • 不要用常用变量名做包名
  • 使用单数
  • 谨慎地使用缩写

1.2.4 控制流程

避免嵌套 保持正常代码路径为最小缩进

1.2.5 错误和异常处理

简单错误

  • 仅出现一次的错误,其他地方不需要捕获该错误
  • 优先使用 errors.New来创建匿名变量来直接表示匿名错误
  • 有格式化要求,使用fmt.Errorf

错误的Wrap和Unwrap

  • 错误的Wrap提供一个error嵌套另一个error的能力,生成error的跟踪链
  • 在fmt.Errorf中使用%w关键字将一个错误关联至错误链中

错误判定

  • 判断一个错误是否是特定错误,使用errors.ls
  • 不同于使用 ==,使用该方法可以判定错误链上的所有错误是否含有特定的错误

错误判定

在错误链获取特定种类的错误,使用errors.As

panic

  • 真正异常的情况
  • 不建议在业务中使用panic
  • 发生不可逆错误时在init和mian函数使用panic

recover

  • recover 只能在被defer的函数中使用
  • 嵌套无法生效
  • 只在当前goroutine生效
  • defer的语句是后进先出

1.3 性能优化建议

1.3.1 benchmark

1.3.2 Slice

slice预分配内存

  • 尽可能在使用make初始化切片时提高容量大小
  • 本质是避免数组复制

大内存释放

  • 在已有切片上创建新切片
  • 原底层数组在内存中有引用,得不到释放
  • 可使用copy代替re-slice

map预分配内存

  • 不断向map添加元素会触发扩容
  • 提前分配好空间可以减少内存拷贝消耗

1.3.4 字符串处理

使用strings.Builder

  • s+=str涉及内存分配 string.builder底层是[]byte数组,再变回string

1.3.5 空结构体

实例不占用任何内存空间 占位符

1.3.6 atomic包

多线程

2. 性能调优实战