Golang学习&高质量编程和性能调优 | 青训营笔记02

高质量编程和性能调优

1.高质量编程通用原则

  • 简单性
    消除”多余的复杂性”,以简单清晰的逻辑编写代码。
    在实际工程项目中,复杂的程序逻辑会让人害怕重构和优化,因为无法明确预知调整造成的影响范围难以理解的逻辑,排查问题时也难以定位,不知道如何修复。

  • 可读性
    可读性很重要,因为代码是写给人看的,而不是机器。
    在项目不断迭代的过程中,大部分工作是对已有功能的完善或扩展,很少会完全下线某个功能,对应的功能代码实际会生存很长时间。已上线的代码在其生命周期内会被不同的人阅读几十上百次。

    听课时老师经常说的在课堂上不遵守纪律影响全班同学的时间,难以理解的代码会占用后续每一个程序员的时间。

  • 生产力
    编程在当前更多是团队合作,因此团队整体的工作效率是非常重要的一方面。
    为了降低新成员上手项目代码的成本,Go语言甚至通过工具强制统一所有代码格式。
    编码在整个项目开发链路中的一个节点,遵循规范,避免常见缺陷的代码能够降低后续联调、测试、验证、上线等各个节点的出现问题的概率,就算出现问题也能快速排查定位。

2.go语言编码规范

  • gofmt工具

Go语言官方提供的工具,能自动格式化Go 语言代码为官方统─风格常见IDE都支持方便的配置

  • goimports工具

也是Go语言官方提供的工具
实际等于gofmt加上依赖包管理
自动增删依赖的包引用、将依赖包按字母序排序并分类

3.注释原则和Java大同小异!

  • 代码是最好的注释。
  • 注释应该提供代码未表达出的上下文信息。
  • 简洁清晰的代码对流程注释没有要求,但是对于为什么这么做,代码的相关背景,可以通过注释补充,提供有效信息,在以后工作学习中可以慢体会。

4.命名规范和Java有所不同

  • 变量

  • 方法

  • package

5.错误和异常处理

  • 简单错误
    • 简单的错误指的是仅出现一次的错误,且在其他地方不需要捕获该错误
    • 优先使用crrors.New来创建匿名变量来直接表示简单错误
    • 如果有格式化的需求,使用fmt.Errorf
  • 复杂错误

对于复杂的错误,有时候并不能简单描述,应该如何处理?
错误的包装提供了一个error嵌套另一个error的能力,生成一个error的跟踪链,同时结合错误的判定方法来确认调用链中是否有关注的错误出现。这个能力的好处是每一层调用方可以补充自己对应的上下文,方便跟踪排查问题,确定问题的根本原因在哪里。
在fmt.Errorf中使用: %w关键字来将—个错误wrap至其错误链中。

  • 错误判定
    • 判定一个错误是否为特定错误,使用errors.Is。
    • 不同于使用==,使用该方法可以判定错误链上的所有错误是否含有特定的错误。
    • 在错误链上获取特定种类的错误,使用crrors.As。
  • 在Go中,比错误更严重的就是panic,它的出现表示程序无法正常工作了,那么在使用时应该注意什么呢?
    不建议在业务代码中使用panic。因为panic发生后,会向上传播至调用栈顶,如果当前goroutine中所有deferred函数都不包含recover就会造成整个程序崩溃。

  • 若问题可以被屏蔽或解决,建议使用error代替panic。

  • 特殊地,当程序启动阶段发生不可逆转的错误时,可以在init或main函数中使用panic。因为在这种情况下,服务启动起来也不会有意义比如示例是启动消息队列监听器的逻辑,在创建消费组失败的时候会Panicf,实际打印日志,然后抛出panic。

  • recover
    • recover只能在被defer的函数中使用
    • 嵌套无法生效
    • 只在当前goroutine生效-
    • defer的语句是后进先出

6.性能优化

1
2
3
//基准测试命令
go test -bench=. // . 代表测试所有文件,可以单独一个go文件也可以
go test -bench=. -benchmem //-benchmem 表示也统计内存信息

7.性能优化工具pprof

注意:浏览器不能正常显示需要安装graphviz组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
浏览器中打开http://localhost:6060/debug/pprof

allocs:内存分配情况
blocks:阻塞操作情况
cmdline:程序启动命令及
goroutine:当前所有
goroutine的堆栈信息
heap:堆上内存使用情况(同alloc)
mutex:锁竞争操作情况
profile: CPU占用情况
threadcreate:当前所有创建的系统线程的堆栈信息
trace:程序运行跟踪信息

使用命令:go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10" 启动采样数据

使用 topN 命令查看资源占用最高的函数

例如,输入top5,查看CPU占用最高的5个函数这五列从左到右分别是:
Flat:当前函数的占用
Flat%:Flat占总量的比例
Sum%:上面所有行的Flat%总和
Cum (Cumulative):当前函数加上其调用函数的总占用
Cum%: Cum占总量的比例

输入list + 函数名称 查找这个函数,看看具体是哪里出了问题
List命令会根据后面给定的正则表达式查找代码,并按行展示出每一行的占用。

除了这两种视图之外,我们还可以输入web命令,生成一张调用关系图,默认会使用浏览器打开。

Golang学习&高质量编程和性能调优 | 青训营笔记02
https://zty-f.github.io/2022/05/16/Golang学习-高质量编程和性能调优-|-青训营笔记02/
作者
ZTY
发布于
2022年5月16日
更新于
2025年3月6日
许可协议