这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
高质量代码:
- 正确性: 是否考虑各种边界条件,错误的调用是否能够处理
- 可靠性: 异常情况或者错误的处理策略是否明确,依赖的服务出现异常是否能够处理
- 简洁: 逻辑是否简单,后续调整功能或新增功能是否能够快速支持
- 清晰: 其他人在阅读理解代码的时候是否能清楚明白,重构或者修改功能是否不会担心出现无法预料的问题
编程原则:
- 简单性消除“多余的复杂性”
- 可读性代码是给团队成员和自己看的,想要易维护的代码,第一步就是确保代码可读
- 生产力提高团队的工作效率
编码规范:
1. 代码格式
可以使用go fmt,进行代码的格式化。Go imports,对依赖包进行管理
2. 注释
解释代码的作用,如何实现,实现原因,可能会出的错误,尽量不要出现代码和注释不相关的内容,也容易造成误导,
尤其是在编写包的时候,公共符号都需要添加注释,无论长度和复杂度如何,库中的函数都要进行注释 既不明显,也不简短的公共功能,也需要注释
命名规范
变量命名
- 变量命名缩略词要大写、驼峰式命名
- 变量距离被使用的地方越远,需要携带更多的上下文信息,以便于在不同地方能够轻易识别出含义 函数命名 不携带包名的上下文信息,尽可能简短。
包命名
只由小写字母组成,不包含大写字母和下划线,主要与标准库同名
命名规范也可以参照标准库
控制流程
尽量少使用嵌套,尤其对于错误处理,会导致代码阅读难度增加,如图所示:(代码来自字节内部课)
// Bad
func OneFunc() error {
err := doSomething()
if err == nil {
err := doAnotherThing()
if err == nil {
return nil // normal case
}
return err
}
return err
}
//Good
func OneFunc() error {
if err := doSomething();err != nil {
return err
}
if err := doAnotherThing(); err != nil {
return err
}
return nil // normal case
}
错误和异常处理
可以使用错误跟踪链就是一个error,嵌套另一个error
考虑到错误链可能会很多,可以使用errors.is来判断错误链上的所有错误是否包含特定的错误,如图所示:
使用errors.as可以获取错误链上特定种类的错误。 如图所示:(代码来自字节内部课)
data ,err = lockedfile.Read( targ )
if errors.Is(err, fs.ErrNotExist) (
// Treat non-existent as empty, to bootstrap the "latest" file
// the first time we connect to a given database.
return []bytef{}, nil
}
return data, err
不要在业务代码中使用panic
调用的函数中不包含recover会造成程序崩溃
当程序启动阶段发生不可逆转的错误时,可以在init或者是main函数中使用panic
何时使用recover
当我们引用一些包或者是一些标准库的之后,运行程序会出现panic。在运行阶段,不想让这个panic影响我们的逻辑,可以调用recover(),只能在 defer 中使用。
注意:嵌套无法生效。只能在当前的goroutine内生效。在recover之后也可以把错误打印出来
性能优化
建议
Slice切片预分配内存,尽可能的预测需要分配的空间
以避免内存不够,发生拷贝。
map类似
字符串处理
有三种:
- 直接用加号
- 使用springs builder
- bytebuffer
Strength builder的性能是最好的,直接用加号性能最差。
字符串在go语言中是不可变类型,占用内存大小是固定的,所以每次使用加号都会重新分配内存
而另外两种形式,底层都是[ ]byte数组,会扩容,但不会重新分配
空间优化
可以使用空结构体来充当占位符。但是不会占用内存,尤其是对于实现set类型,可以用map进行底层实现,只使用key,Value利用空结构体
使用atomic包,来实现多线程编程,或者利用加锁
但是锁的实现是通过操作系统来实现,属于系统调用,Atomic操作是通过硬件实现效率要比锁高
在满足正确可靠,简洁清晰的质量的前提下,进行程序性能的提高。不能一味的追求程序的性能
性能调优实例
调优原则:
- 依靠数据而不是盲目猜测
- 定位最大的问题,而不是细枝末节
- 不要过早优化,也不要过度优化
性能分析工具pprof
希望知道应用在什么地方耗费了多少 CPU、Memorypprof 是用于可视化和分析性能分析数据的工具
net/http/pprof包的init函数中注册了以下路由到http服务中,用浏览器打开(http://localhost:8080/debug/pprof/)
即可使用pprof提供的功能。
功能简介
如图所示(来自字节内部课)