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

55 阅读3分钟

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

一、高质量编程

1 简介

高质量:正确可靠、简洁清晰。

  • 各种边界条件是否考虑完备
  • 异常情况处理,稳定性保证
  • 易读易维护

编程原则

简单性:

  • 消除“多余的复杂性”,以简单清晰的逻辑编写代码
  • 不理解的代码无法修复改进 可读性:
  • 代码是写给人看的,而不是机器
  • 编写可维护代码的第一步是确保代码可读 生产力:
  • 团队整体工作效率非常重要

2 编码规范

代码格式;注释;命名规范;控制流程;错误和异常处理

1)代码格式

gofmt自动格式化代码;
goimports等于gofmt加上依赖包管理;

2)注释

  • 解释代码作用(适合注释公共符号)
  • 解释代码如何做的(适合注释实现过程)
  • 解释代码实现的原因(适合解释代码的外部因素,提供额外上下文)
  • 解释代码什么情况会出错(适合解释代码的限制条件)
  • 公共符号始终要注释(不需要注释实现接口的方法)

3)命名规范

variable:

  • 简洁胜于冗长
  • 缩略词全大写,但当其位于开头且不需要导出时,用全小写
  • 需要导出的,首字母大写,不需要的小写
  • 变量距离使用地方越远,上下文信息应该越多

function:

  • 函数名不用携带包名的上下文信息
  • 尽量简短
  • 名为foo的包如果返回类型也是Foo,函数名可以省略类型;返回类型不一致时,函数名可以加入

package:

  • 小写字母组成,不含大写字母和下划线
  • 简短,包含一定上下文
  • 不要与标准库同名
  • 尽量不使用常用变量名
  • 尽量使用单数,不是复数
  • 缩写要谨慎

4)流程控制

  • 避免嵌套,冗余的else可以去除
  • 尽量保持正常代码路径为最小缩进(比如,优先处理错误/特殊情况)
  • 线性原理,处理逻辑尽量走直线,避免复杂的嵌套分支
  • 正常流程代码沿着屏幕向下移动
  • 提升代码的可读性和可维护性

5)错误和异常处理

简单错误:

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

错误的Wrap和Unwrap:

  • 错误的Wrap是一个error嵌套另一个error,生成error的跟踪链
  • fmt.Errorf中使用%w来将一个error关联至一个错误链 错误判定:
  • errors.Is来判断
  • errors.As可以提取类型

panic:

  • 不建议在业务代码中使用panic
  • 调用哈数不包含recover会造成程序崩溃

3 性能优化

benchmark

基准性能测试的benchmark工具;
go test -bench=. -benchmem

slice

  • 预分配内存
  • slice的底层是一个数组片段,扩容时需要复制(类似java的list)
  • 在已有切片的基础上创建切片,不会创建新的底层数组,原底层数组在内存中引用,建议使用copy

map

  • 预分配内存

strings.Builder

  • 类似java的StringBuilder

空结构体来节省内存

  • 比如实现set用map来代替,map的值用空struct

atomic包

  • atomic包的效率比锁搞,锁是通过操作系统来实现的

二、性能调优实战

1 简介

性能调优原则

  • 依靠数据不是猜测
  • 定位最大瓶颈而不是细枝末节
  • 不要过早优化或者过度优化

2 性能分析工具pprof

  • 用于可视化和分析性能分析数据的工具
  • 知道应用在什么地方耗费了多少CPU和memory

3 性能调优案例

  • 业务服务优化
  • 基础库优化
  • Go语言优化