这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记
课程简图:
1.高质量编程
1.1 简介
编写的代码能够达到正确可靠、简洁清晰的目标可称为高质量代码
- 各种边界条件是否考虑完备
- 异常情况处理,稳定性保证
- 易读易维护
编程原则
实际应用场景千变万化,各种语言特性和语法各不相同,但是高质量编程遵循的原则是相通的
- 简单性
- 可读性
- 生产力
1.2 编码规范
如何编写高质量的go代码
- 代码格式
- 注释
- 命名规范
- 控制流程
- 错误和异常处理
代码格式
推荐使用gofmt自动格式化代码
注释
- 解释代码作用
- 适合注释公共符号
- 解释代码如何做的
- 适合注释实现过程
- 解释代码实现的原因
- 适合解释代码的外部因素
- 提供额外上下文
- 解释代码什么时候会出错
- 适合解释代码的限制条件
公共符号始终要注释
但是有一个例外: 不需要注释实现接口的方法。
- 代码是最好的注释
- 注释应该提供代码未表达出的上下文关系
命名规范
- 简洁胜于冗长
- 缩略词全大写,但是当它位于变量开头且不需要导出的时候,使用全小写
- 变量距离它被使用的地方越远,则需要携带的上下文信息越多
原因
- 将deadline 代替成t降低了变量名的信息量
- t 常☞任意时间
- deadline ☞ 截止时间,有特殊的含义
原因:在实际调用该函数时会首先通过调用http包,所以使用第二个会造成http信息的重复,代码冗杂。
调用函数:
第一个:http.Serve(I net.Listener,handler Handler) error
第二个:http.ServeHTTP(I net.Listener,handler Handler) error
结果显而易见
package
基本规则:
- 只由小写字母组成,不包含大写字母和下划线等字符
- 简短并包含一定的上下文信息
- 不要与标准库同名 以下规则尽量满足:
- 不使用常用变量名作为包名
- 使用单数而不是复数。如encoding而不是encodings
- 谨慎的使用缩写
核心目标是降低阅读理解代码的成本,重点考虑上下文信息,设计简洁清晰的名称
控制流程
避免嵌套,保证正常流程清晰
保证正常代码路径为最小缩进
- 提升代码可维护性和可读性
- 正常流程代码沿着屏幕向下移动
- 线性原理,处理逻辑尽量走直线,避免复杂的嵌套分支
- 故障问题大多出现在复杂的条件语句和循环语句中
错误和异常处理
简单错误
复杂的错误
错误判定
在错误链上获取特定种类的错误,使用error.As
panic
recover
defer
- defer语句会在函数返回前调用
- 多个defer语句是后进先出的(类似与栈结构)
代码:
import "fmt"
func main() {
if true {
defer fmt.Printf("1")
} else {
defer fmt.Printf("2")
}
defer fmt.Printf("3")
}
结果:
1.3 性能优化建议
slice预分配内存
- 尽可能的在使用make()初始化切片时提供容量信息
- 另一个陷阱 在已有的切片的基础上创建切片,不会创建新的底层数组
原切片比较大,代码在原切片基础上新建小切片
原底层数组在内存中有引用,得不到释放
可以使用copy 代替re-slice
map
StringBuilder 和 ByteBuffer 的性能更高效,而且StringBuilder 比 ByteBuffer 性能要好一点
开源链接: github.com/deckarep/go…
性能优化建议:
- 避免常见的性能陷阱可以保证大部分程序的性能
- 普通应用代码,不要一味的追求程序的性能
2.性能调优实战
2.1 性能调优原则
- 要依赖数据而不是猜测
- 要定位最大瓶颈而不是细枝末节
- 不要过早优化
- 不要过度优化
pprof工具
由于本人能力有限,没法调试出来这个项目,所以今天的笔记就到这里了。