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

52 阅读4分钟

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

1 高质量编程

1.1 什么是高质量的代码

  • 边界考虑完备
  • 异常情况的处理,稳定性的保证
  • 易读易维护

1.2 编程原则

  • 简单性:简单清晰的逻辑编程代码
  • 可读性:编写可维护的代码的第一步就是确保代码可以阅读
  • 生产力:团队整体工作效率非常重要

1.3 代码编写规范(如何编写高质量的Go代码)

1.3.1 注释应该做的

  1. 解释代码的作用

    1. 公共符号始终要注释,就是对外提供的方法或者变量等都要提供注释
  2. 解释代码是如何做的

    1. 适合注释实现过程
  3. 解释代码实现的原因

    1. 解释代码的外部因素,提供额外的上下文
  4. 解释代码为什么会出错

    1. 解释代码的限制条件

代码是最好的注释,要提供代码未表达出的上下文信息

1.3.2 代码格式

  • 使用 go fmt 自动格式化代码。
  • goimports对依赖包进行分类

1.3.3 命名规范

1.3.3.1 变量

  1. 越简洁越好
  2. 缩略词要大写,但是如果位于开头并且不需要导出的话就小写

  1. 变量距离其名字使用的地方越远,则需要越多的上下文信息

1.3.3.2 函数

  • 函数名不懈怠包名的上下文信息
  • 尽可能简短

比如调用http包中的函数,第一个这种方式就会更好,因为要用http.funtionName

1.3.3.3 包名

  • 只有小写字母组成,不包含大写字母和下划线
  • 简短并且包含一定的上下文信息
  • 不要于标准库同名

以下规则尽量满足

  • 不要用常用变量名,比如用bufio而不是buf
  • 使用单数而不是复数,比如encoding而不是encodings
  • 谨慎的使用缩写,避免歧义

1.3.4 控制流程

  • 避免嵌套
  • 尽量保持正常代码路径为最小缩进(优先处理错误情况和特殊情况,尽早返回或者继续循环来减少嵌套)

1.3.5 错误和异常处理

  1. 简单错误

    1. 简单错误指的是支持出现一次的错误,其他地方不需要捕获该错误,那么使用errors.New来创建一个匿名变量来直接表示简单错误。

      •     有格式化的要求的话,使用fmt.Errorf
  2. 错误的嵌套

  3. 异常

    1.   不建议在与代码中使用panic,如果可以屏蔽或者结局的时候,检验使用error,当程序启动阶段发生不可逆的错误的时候,就可以在init中使用panic,因为启动起来也没意义。

2 性能优化建议

2.1 Slice,map优化

切片本质上是一个数组片段的描述

  1. 尽可能在初始化的时候提供容量信息,这样会避免多次进行分配(slice,map)

  2. 大内存未释放,在一个已有的切片上进行切片操作的话,不会创建新的底层数组,如果原来的切片不使用了,推荐使用copy(target,origin[:2]),而不是直接在原始切片上进行操作(slice)

2.2 字符串处理

字符串拼接使用strings.Builder更快,使用bytes.Buffer也可以,直接加最慢

因为string是不可变类型,占用你村是固定的,使用+每次都会重新分配内存。另外两个的底层都是[]byte数组,内存扩容不需要每次都重新分配内存

如果知道最后拼接字符串的大小,就可以预分配容量,这样就和刚才提到的一样,减少扩容次数,提高性能。

2.3 使用空结构体,节省内存

使用空结构体。可以现一个set。使用布尔变量也可以实现一个set。但是他比用空结构体多一个字节。结构体它这里不需要有任何语义。不需要有任何值,仅作为占位符。

3 性能调优

3.1 原则

  1. 要依靠数据而不是,而不是猜测。
  2. 要定位最大的瓶颈,而不是细枝末节。
  3. 不要过早优化。
  4. 不要过度优化。

3.2 性能分析工具pprof

他可以知道应用在什么地方,耗费了多少CPU、memory。可以可视化的进行分析数据。

3.2.1 pprof功能简介

3.2.2 排查实战

先把clone下来的代码跑起来,