GO--高质量编程与调优|青训营笔记

113 阅读4分钟

GO--高质量编程与调优|青训营笔记

这是我参与「第五届青训营」伴学笔记创作活动的第10天

在后面会依次倒叙回顾之前的学习课程,便于复习~

一、课程重点内容

  • 高质量编程
  • 性能调优

下面是对课程重点内容的思考与总结,有问题或者错误,可以批评指正呐~

二、高质量编程

定义:编写的代码能够达到正确可靠、简洁清晰的目标。

  • 特点分析

    • 正确性:是否考虑各种边界条件,错误的调用是否能够处理
    • 可靠性:异常情况或者错误的处理策略是否明确,依赖的服务出现异常是否能够处理
    • 简洁:逻辑是否简单,后续调整功能或新增功能是否能够快速支持
    • 清晰:其他人在阅读代码的时候是否能清楚明白,重构或修改功能是否不用担心出现无法预料的问题
  • Go的高质量编程

    • 代码格式:使用gofmt自动格式化代码

    • 代码的注释:

      • 解释代码作用
      • 解释代码如何做的
      • 解释代码实现的原因
      • 解释代码什么情况会出错
      • 公共符号始终要注释
    • 代码的命名规范:

      • 简洁胜于冗长
      • 缩略词全大写,但当期位于变量开头且不需要导出时,使用全小写
      • 变量距离其被使用的地方越远,则需要携带越多的上下文信息
      • 函数名不携带包名的上下文信息且尽量简短
      • package名只由小写字母组成
    • 控制流程

      • 避免嵌套,保持正常流程清晰,例如去掉不必要的else
      • 尽量保持正常代码路径为最小缩进,能对称就对称
      • 故障问题的大多出现在复杂的条件语句和循环语句中,尽量化简为单个函数进行测试
    • 异常处理

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

三、性能优化

  • 概念:

    • 从资源视角出发来对一台服务器进行审视的话,CPU、内存、磁盘与网络是后端服务最需要关注的四种资源类型。
    • 对于计算密集型的程序来说,优化的主要精力会放在 CPU 上,要知道 CPU 基本的流水线概念,知道怎么样在使用少的 CPU 资源的情况下,达到相同的计算目标。
    • 对于 IO 密集型的程序(后端服务一般都是 IO 密集型)来说,优化可以是降低程序的服务延迟,也可以是提升系统整体的吞吐量。
  • GO的检测方法

CPU profile:报告程序的 CPU 使用情况,按照一定频率去采集应用程序在 CPU 和寄存器上面的数据

Memory Profile(Heap Profile):报告程序的内存使用情况

Block Profiling:报告 goroutines 不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈

Goroutine Profiling:报告 goroutines 的使用情况,有哪些 goroutine,它们的调用关系是怎样的

  • Go的优化手段

    • 协程池

      • 绝大部分应用场景,go是不需要协程池的。当然,协程池还是有一些自己的优势:

        1. 可以限制goroutine数量,避免无限制的增长。
        2. 减少栈扩容的次数。
        3. 频繁创建goroutine的场景下,资源复用,节省内存。(需要一定规模。一般场景下,效果不太明显)

    avatar

    • 反射

      go里面的反射代码可读性本来就差,常见的优化手段进一步牺牲可读性。而且后续马上就有范型的支持,所以若非必要,建议不要优化反射部分的代码

      • 缓存反射结果,减少不必要的反射次数。例如json-iterator
      • 直接使用unsafe.Pointer根据各个字段偏移赋值
      • 消除一般的struct反射内存消耗go-reflect
      • 避免一些类型转换,如interface->[]byte。可以参考zerolog
    • 并发场景下,对临界区加锁比较常见。带来的性能隐患也必须重视。

      • 减小锁力度
      • 原子操作atomic

avatar

五、课程总结

了解到Go的编程技巧与代码规范,同时如何进行代码性能分析与测试,以后一定好好用这些工具