字节青训营笔记 | 青训营笔记

96 阅读4分钟
这是我参与「第六届青训营」伴学笔记创作活动的第 3 天

Go高质量编程

简介

首先介绍一下高质量:顾名思义质量很高,所以编写的代码能够达到正确可靠(尽可能的不出错误),简洁清晰(自己和别人都可以快速清楚的理解)的目标可称之为高质量代码。其次,go语言开发者普遍认为的编程原则:简单性 可读性 生产力

编码规范

代码格式

一定使用gofmt进行格式化,另一种是goimports也是go语言官方提供的工具,它实际上等于gofmt加上依赖包管理拥有自动增删以来的包引用将依赖包按字母序排序并分类的功能。

注释

注释是很有必要的,应该从下面几个方面进行注释

  • 解释代码的作用 (注释适合说明公共符号,函数功能简单而明显可以省略)
  • 解释代码的实现 ( 对代码中复杂、隐晦的逻辑进行说明)
  • 解释代码实现的原因 (解释代码的外部因素,使人可以理解脱离了上下文后的代码)
  • 解释代码可能出错的情况 (提醒使用者一些潜在的限制条件或者无法处理的情况)
  • 公共符号的注释 (Google Style指南有两条规则:任何既不明显也不简短的公共功能必须予以注释;无论长度或者复杂度如何,库中的任何函数都必须予以注释。)一个例外是,不要注释实现接口的方法!

命名规范

变量
  • 简洁胜于冗长
  • 缩略词使用全大写(如HTTP,XML等),但当其位于变量开头且不需要导出时,使用全小写(如使用ServeHTTP而不是ServeHttp, 使用XMLHTTPRequest或者xmlHTTPRequest)
  • 全局变量在名字中需要携带更多的上下文信息,使得不同地方都可以轻易辨认出其含义。
函数
  • 函数名不包含包名的上下文信息,因为包和函数总是成对出现的。
  • 尽量简短
  • 当名为foo的包中某个函数的返回类型是Foo时,可以省略类型信息而不产生歧义,当返回的是其余类型时,则可以在函数名中加入类型信息。
  • 只有小写字母组成。

  • 简短并包含一定的上下文信息

  • 不和标准库同名。

  • 尽量满足以下规则:

    • 不使用常用变量名作为包名
    • 使用单数而不是复数
    • 谨慎地使用缩写,利用使用fmt在不破坏上下文的情况下比format更加简短。

性能优化

建议-Benchmark

使用Go语言提供的基准性能测试工具Benchmark

Slice

尽可能在使用make初始化切片时提供容量信息,减少内存分配次数。另一个是Slice可能会出现大内存未释放的情况(原切片较大,代码在原切片 基础上新建小切片。原底层数组在内存中有引用,得不到释放),解决的办法是可以使用copy替代re-slice重切片。

Map

类似Slice,尽可能地在make时为Map提供容量信息,减少内存拷贝和重哈希的消耗。

字符串处理
str += ...
​
var builder strings.Builder
builder.WriteString(str)
​
buf := new(bytes.Buffer)
buf.WriteString(str)

代码中展示了三种不同的字符串拼接操作,使用+的拼接性能最差,而BuilderBuffer相近,Buffer最快。由于字符串在go中是不可变类型,内存大小占用固定,因而使用+每次都会重新分配内存。而另外两个结构的底层都是[]byte数组,通过内存扩容策略不需要每次都要重新分配内存。

空结构体

使用空结构体可以节省内存,也可以作为占位符使用。

atomic

锁的实现是通过操作系统来实现,属于系统调用,而atomic操作时同硬件实现效率比锁高。另外,sync.Mutex应该用来保护一段逻辑,不仅限于变量。