第三节课:高质量编程和性能调优|青训营笔记

75 阅读3分钟
  • 高质量编程\

    • 编码规范\

      • 代码格式\

        • go fmt格式化代码\
        • 提升可读性,风格一致的代码更容易维护、需要更少的学习成本、团队合作成本,同时可以降低 Review 成本\
      • 注释\

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

        • 变量\

          • 简洁胜于冗长\
          • 缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写\
          • 变量距离其被使用的地方越远,则需要携带越多的上下文信息\
          • 全局变量在其名字中需要更多的上下文信息,使得在不同地方可以轻易辨认出其含义\
        • 函数\

          • 函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的\
          • 函数名尽量简短\
          • 当名为 foo 的包某个函数返回类型 Foo 时,可以省略类型信息而不导致歧义\
          • 当名为 foo 的包某个函数返回类型 T 时(T 并不是 Foo),可以在函数名中加入类型信息\
        • 包\

          • 只由小写字母组成。不包含大写字母和下划线等字符\
          • 简短并包含一定的上下文信息。例如 schema、task 等\
          • 不要与标准库同名。例如不要使用 sync 或者 strings\
      • 控制流程\

        • 避免嵌套\
        • 优先处理错误情况\
        • 如果两个分支中都包含 return 语句,则可以去除冗余的 else\
      • 错误和异常处理\

        • 简单错误\

          • 只出现一次,且在其他地方不需要捕获\
          • errors.New()\
          • 如果有格式化需求则使用fmt.Errorf()\
        • 错误的wrap和unwrap\

          • 提供了一个error嵌套另一个error的能力,形成一个error的跟踪链\
          • 在fmt.Errorf()中使用%w关键字将一个error关联至error链中\
        • panic\

          • 不推荐在业务中使用panic\
          • 建议使用error代替panic\
        • recover\

          • 只能在被derfer的函数中使用\
          • 嵌套无法生效\
          • 只在当前goroutine生效\
          • defer语句先进后出\
  • 性能调优实战\

    • 如何使用\

      • 基准性能测试的Benchmark工具\

        • 添加函数\

          • func fib(x int) int {}\
        • 生成fib函数test.go\

          • func BenchmarkFib(b *testing.B) {}\
        • go test -bench .\
    • 建议\

      • slice\

        • 尽可能在make初始化时指定容量信息\
        • 扩容时有性能消耗\
      • map\

        • 尽可能在make初始化时指定容量信息\
        • 扩容时有性能消耗\
      • 字符串处理\

        • 拼接\

          • +\

            • 性能最差\
          • strings.Builder\

            • 性能与buffer差不多\
          • bytes.Buffer\

            • 更快\
      • 使用空结构体节省内存\

        • 空结构体struct{}实例不占据内存空间\
        • 可作为各种场景下的占位符使用\
      • atomic包\

        • 性能比使用锁lock性能高\

          • 锁是通过操作系统实现\
          • atomic通过硬件实现\
    • 原则\

      • 要依靠数据不是猜测\
      • 要定位最大瓶颈而不是细枝末节\
      • 不要过早优化\
      • 不要过度优化\
    • 性能分析工具pprof\

      • 采样过程和原理\

        • cpu\

          • 采样对象\

            • 函数调用和它们占用的时间\
          • 采样率\

            • 100次/秒\
          • 采样时间\

            • 手动开始到手动结束\
        • heap 内存\
        • goroutine\
        • 阻塞和锁\