这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
1 高质量编程
1.1 什么是高质量的代码
- 边界考虑完备
- 异常情况的处理,稳定性的保证
- 易读易维护
1.2 编程原则
- 简单性:简单清晰的逻辑编程代码
- 可读性:编写可维护的代码的第一步就是确保代码可以阅读
- 生产力:团队整体工作效率非常重要
1.3 代码编写规范(如何编写高质量的Go代码)
1.3.1 注释应该做的
-
解释代码的作用
- 公共符号始终要注释,就是对外提供的方法或者变量等都要提供注释
-
解释代码是如何做的
- 适合注释实现过程
-
解释代码实现的原因
- 解释代码的外部因素,提供额外的上下文
-
解释代码为什么会出错
- 解释代码的限制条件
代码是最好的注释,要提供代码未表达出的上下文信息
1.3.2 代码格式
- 使用
go fmt自动格式化代码。 - goimports对依赖包进行分类
1.3.3 命名规范
1.3.3.1 变量
- 越简洁越好
- 缩略词要大写,但是如果位于开头并且不需要导出的话就小写
- 变量距离其名字使用的地方越远,则需要越多的上下文信息
1.3.3.2 函数
- 函数名不懈怠包名的上下文信息
- 尽可能简短
比如调用http包中的函数,第一个这种方式就会更好,因为要用http.funtionName
1.3.3.3 包名
- 只有小写字母组成,不包含大写字母和下划线
- 简短并且包含一定的上下文信息
- 不要于标准库同名
以下规则尽量满足
- 不要用常用变量名,比如用bufio而不是buf
- 使用单数而不是复数,比如encoding而不是encodings
- 谨慎的使用缩写,避免歧义
1.3.4 控制流程
- 避免嵌套
- 尽量保持正常代码路径为最小缩进(优先处理错误情况和特殊情况,尽早返回或者继续循环来减少嵌套)
1.3.5 错误和异常处理
-
简单错误
-
简单错误指的是支持出现一次的错误,其他地方不需要捕获该错误,那么使用errors.New来创建一个匿名变量来直接表示简单错误。
- 有格式化的要求的话,使用fmt.Errorf
-
-
错误的嵌套
-
异常
- 不建议在与代码中使用panic,如果可以屏蔽或者结局的时候,检验使用error,当程序启动阶段发生不可逆的错误的时候,就可以在init中使用panic,因为启动起来也没意义。
2 性能优化建议
2.1 Slice,map优化
切片本质上是一个数组片段的描述
-
尽可能在初始化的时候提供容量信息,这样会避免多次进行分配(slice,map)
-
大内存未释放,在一个已有的切片上进行切片操作的话,不会创建新的底层数组,如果原来的切片不使用了,推荐使用copy(target,origin[:2]),而不是直接在原始切片上进行操作(slice)
2.2 字符串处理
字符串拼接使用strings.Builder更快,使用bytes.Buffer也可以,直接加最慢
因为string是不可变类型,占用你村是固定的,使用+每次都会重新分配内存。另外两个的底层都是[]byte数组,内存扩容不需要每次都重新分配内存
如果知道最后拼接字符串的大小,就可以预分配容量,这样就和刚才提到的一样,减少扩容次数,提高性能。
2.3 使用空结构体,节省内存
使用空结构体。可以现一个set。使用布尔变量也可以实现一个set。但是他比用空结构体多一个字节。结构体它这里不需要有任何语义。不需要有任何值,仅作为占位符。
3 性能调优
3.1 原则
- 要依靠数据而不是,而不是猜测。
- 要定位最大的瓶颈,而不是细枝末节。
- 不要过早优化。
- 不要过度优化。
3.2 性能分析工具pprof
他可以知道应用在什么地方,耗费了多少CPU、memory。可以可视化的进行分析数据。
3.2.1 pprof功能简介
3.2.2 排查实战
先把clone下来的代码跑起来,