GO语言入门之高质量编程&性能调优 | 青训营笔记

147 阅读4分钟

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

高质量编程

编程,实现功能是第一目的。在实现功能之余,需要考虑高质量编程,一些编码的规范和性能的优化

简介

编写的代码能够达到正确可靠,简洁清晰的目标可称之为高质量代码。

考虑各种边界情况是否考虑完备;异常情况是否考虑到,是否能保持稳定;是否易读易维护;能简单实现就不复杂地实现

编程原则

简单性;可读性;生产力(关注团队整体工作效率)

编码规范

代码格式

gofmt,goimports

注释

注释应该做的:解释代码作用,解释代码如何做的,解释代码实现的原因,解释代码什么情况会出错

公共符号始终要注释;库中的任何函数必须注释;例外,不需要注释实现接口的方法

代码是最好的注释,注释应该提供的是代码不能提供的上下文信息

命名规范

  1. 变量名:简洁胜于冗长;缩略词全大写,如HTTP而不是Http;变量距其被使用的地方越远,则需要携带越多的上下文信息,便于任何地方都可以清晰辨认出含义
  2. 函数名:不携带包名的上下文信息,因为包名和函数名是成对出现的 (包名.函数名);尽量简短;当名为 foo 的包中某个函数返回类型 Foo 时,可以省略类型信息而不致出现歧义;而返回的不是 Foo 类型时,可以在函数名中加入类信息
  3. 包名:只有小写字母;简短并含有一定的上下文信息;不要与标准库同名;不使用常用变量名作为包名,如标准库中的 bufio 而不是 buf;使用单数而不是复数;谨慎地使用缩写,如 fmt 在不破坏上下文的情况下比 format 更简短

控制流程

错误和异常处理

  1. 简单错误:简单错误是指仅出现一次的错误,且在其他地方不需要捕获该错误;优先使用 error.New 来创建匿名变量来直接表示简单错误;如果有格式化的需求,使用 fmt.Errorf
  2. 错误的 Wrap 和 Unwrap:错误的 Wrap 实际上是提供了一个 error 嵌套另一个 error 的能力,从而生成一个 error 的跟踪链;在 fmt.Errorf 中使用 %w 关键字来将一个错误关联至错误链中
  3. errors.Is,errors.As
  4. panic。在程序出现无法继续执行下去的情况时尽早抛出 panic 结束无意义的运行
  5. recover

性能优化建议

性能优化的前提是满足正确可靠,简洁清晰等质量因素;性能优化是综合评估,有时候时间效率跟空间效率可能是对立的

性能测试工具:benchmark

  1. 预分配:Slice 尽可能在使用 make() 初始化切片时提供容量信息;Map 也提倡尽可能与分配内存,提前分配好空间可以减少内存拷贝和rehash的消耗,建议根据实际需求提前预估好需要的空间
  2. 字符串拼接,三种方式:"+",strings.Builder,bytes.Buffer,第二种较优
  3. 使用空结构体本身不占据内存
  4. atomic包

性能调优

做算法题时会想优化算法,使其执行耗时减少。而实际开发中的优化与算法题有一定区别,它并不一定有明确的边界,限制,需要我们对整条链的理解和我们实际生活适配的场景进行分析。需要定位到应用中性能瓶颈的地方,然后进行相关的优化流程,工具

性能调优原则

要依靠数据不是猜测

要定位最大瓶颈而不是细枝末节

不要过早优化

不要过度优化

性能分析工具 pprof

性能调优案例

业务服务优化

建立服务性能评估手段

分析性能数据定位性能瓶颈

重点优化项改造

优化效果验证

基础库优化

AB实验SDK的优化

分析基础库核心逻辑和性能瓶颈,优化后压测验证,推广业务服务落地验证。验证的步骤通常是所有优化都应经过的

Go 语言优化

编译器&运行时优化:优化内存分配策略;优化编译流程;验证 这种优化的优点是接入简单,任何一个 GO 应用程序都可以使用到,只需调整编译配置,通用性强