golang 高质量编程| 青训营笔记

95 阅读3分钟

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

高质量编程

判定标准

  • 各种边界条件是否考虑完备。
  • 对于异常情况处理是否完备(稳定性保证)。
  • 易读易维护。

编程规范

编程规范所要考虑的范围

  • 代码格式。可以通过gofmtgoimports自动格式化代码。gofmt能自动格式化GO语言代码为官方统一风格;goimports实质上是再gofmt基础上加上对依赖包的管理,自动增删依赖的包引用,将依赖包按字母序排序分类。

  • 注释。注释使用场景:

    • 公共符号使用注释。
    • 注释实现过程。
    • 注释代码实现原理。
    • 注释出错条件。
  • 命名规范。

    • 对于变量的命名规范:1.简洁;2.缩略词全大写,当其处于变量开头且不需要导出时,使用全小写(如XMLHTTPRequest/xmlHTTPRequest);3. 变量距离使用的地方越远,需要携带上下文信息越多。

    • 对于函数名的命名规范:1. 不携带包名的上下文信息。; 2. 简洁;

      3.当包名与返回值类型一致时,可以省略类型信息

  • 控制流程。 线性原理,尽量避免复杂嵌套。

  • 错误和异常处理。 GO处理错误/异常的方式不同于Java,Java会在异常处直接抛出异常产生的栈信息,而GO采用控制流的方式处理异常信息,通过函数的返回值返回error信息。当然,GO也可以通过异常嵌套的方式生成错误链,这样也可以在每一层异常中嵌套入当前的上下文信息,,error尽可能提供简洁的上下文信息链,方便定位问题。

性能调优

使用benchmark工具观察程序执行情况

下列以斐波那契函数为例进行分析

image-20220511195325228.png

image-20220511195210632.png 从左到右依次为:测试函数名 , b.N的值(即执行次数),每次执行花费的时间(ns/op),每次执行申请的内存空间(B/op) 每次执行申请内存次数(allocs/op)

性能调优建议

  • 使用slice预分配内存。 创建slice可以通过make(Type,length)make(Type,length,cap)创建,当slice增加的时候,由于slice本身结构的原因,会新分配一个大小为加入slice之的空间到原slice的后方,而如果创建时先预分配了内存空间,则会将加入的切片直接放在slice的后续空间当中。
  • 大内存未释放问题。 当从一个大的slice中切片出一个小内存时,由于小内存对原slice有引用,所以原先的大内存不会释放,在这种情况下需要用copy替代re-slice
  • 字符串处理。 使用“+”拼接性能最差,strings.Builder,bytes.Buffer相近,strings.Buffer更快.
  • 使用空结构体。 空结构体不占空间,仅作为占位符,如如果map[type]struct{}来实现set
  • 使用atomic包。 atomic包实现原子性的功能由操作系统提供,会降低自己实现原子性的开销。

性能调优工具

pprof

image-20220511203750711.png