1. 如何编写更简洁清晰的代码
高质量代码的要求:正确可靠、简洁清晰。其遵循如下的编程原则:
- 简单性: 以简单清晰的逻辑编写代码
- 可读性
- 生产力
编写高质量的代码主要体现在:代码格式、注释、命名规范、控制流程、错误和异常处理等几个方面。
1.1 编码规范-代码格式
推荐使用 gofmt 自动格式化代码。
1.2 编码规范-注释
注释应该包含如下几部分内容:
- 解释代码作用: 注释公共符号
- 解释代码如何做的: 注释实现过程
- 解释代码实现的原因: 解释代码的外部因素 或提供额外上下文
- 解释代码什么情况会出错:解释代码的限制条件
1.3 命名规范
变量命名遵循如下几点:
- 简洁胜于冗长
- 缩略词全大写,但当其位于变量头且不需要导出时,使用全小写。
- 变量距离被使用的地方越远,则需要携带越多的上下文信息。
函数名命名规范:
- 函数名不携带报名的上下文信息。
- 函数名尽量简短
包名命名规范:
- 只由小写字母组成,不包含大写字母和下划线等。
- 简短并包含一定的上下文信息。
- 不要与标准库同名
1.4 控制流程
避免嵌套,保持流程正常清晰。
尽量保持正常代码路径为最小缩进,同时优先处理错误情况/特殊情况,尽早返回或继续循环来减少嵌套。
1.5 错误和异常处理
简单错误:优先使用errors.New来创建匿名变量直接表示,如果有格式化的需求,使用fmt.Errorf.
错误的Wrap和Unwrap 使用fmt.Errorf来进行表示。错误判定使用error.Is,在错误链上获取特定种类的错误,使用erros.As.
recover只能在被defer的函数中使用,且只在当前goroutine生效。
2. 性能优化建议
Go 语言提供了支持基准性能测试的benchmark工具。具体建议如下:
- slice采用预分配策略,在已有切片基础上创建切片,不会创建新的底层数组,可能会导致原切片得不到释放,此时可以使用copy替代re-slice
- map 采用预分配内存
- 字符串处理建议使用
strings.Builder - 使用空结构体来节省内存。
- 使用atmoic包,其操作通过硬件来实现,效率比锁高。
3. 性能调优原则
Go语言提供了pprof来用于可视化和分析性能分析数据。 业务服务优化的流程:
- 建立服务性能评估手段
- 服务性能评估方式
- 请求流量构造
- 压测范围
- 性能数据采集
- 分析性能数据,定位性能瓶颈
- 使用库不规范
- 高并发场景优化不足
- 重点优化项改造
- 优化效果验证