高质量编程与性能调优|青训营

116 阅读3分钟

高质量编程

1. 简介

1.1 什么是高质量

各种边界条件是否考虑完备

异常情况处理,稳定性保证

易读易维护

1.2 编程原则

简单性、可读性、生产力

我认为高质量编程就要用简单的语言实现应有的功能,代码逻辑简单清晰,让他人可以读懂,可以提高团队的工作效率。

2. 编程规范

2.1 代码格式

推荐使用gofmt自动格式化代码

2.2 注释

注释符号//

注释应该解释代码作用,解释代码来源,解释代码实现的原因。

例如用go语言打印出九九乘法表

package main 
import "fmt" 
func main() { 
    // 外层循环控制被乘数 i,从 19 
    for i := 1; i <= 9; i++ { 
       // 内层循环控制乘数 j,从 1i 
       for j := 1; j <= i; j++ { 
          // 打印乘法表达式,并使用 %2d 格式化保证对齐 
          fmt.Printf("%d * %d = %2d ", j, i, i*j) 
          } 
          // 换行符,打印下一行的乘法表达式 
          fmt.Println() 
    } 
}

结果:

QQ图片20230815111403.png

2.3 命名规范

  1. 包名:一般使用小写字母,不使用下划线或驼峰命名法。例如:"fmt", "net/http"。
  2. 变量和函数名:使用驼峰命名法,首个单词小写,后续单词首字母大写。例如:"myVariable", "calculateSum"。
  3. 常量名:使用全大写字母,单词间使用下划线分隔。例如:"PI", "MAX_VALUE"。
  4. 类型名:使用驼峰命名法,首字母大写。例如:"Person", "Employee"。
  5. 结构体字段:使用驼峰命名法,首字母小写。例如:"personName", "employeeAge"。
  6. 接口名:使用以 "er" 结尾的驼峰命名法,首字母大写。例如:"Reader", "Writer"。
  7. 文件名:使用全小写字母,可使用下划线分隔单词。例如:"my_file.go", "utils_test.go"。

此外,还有一些特殊的约定:

  • 不推荐使用单字符变量名,除非是临时变量。
  • 私有成员或私有函数使用以小写字母开头的驼峰命名法。例如:"privateField"。
  • 导出的成员或函数使用以大写字母开头的驼峰命名法。例如:"ExportedField"。

这些命名规范符合 Go 语言社区的约定,能提升代码的可读性和一致性。但是记住,最重要的是选择一个命名规范,并保持一致性。

2.4 控制流程

避免嵌套,保持正常流程清晰

尽量保持正常代码路径为最小缩进

2.5 错误和异常处理

error尽可能提供简明的上下文信息链,方便定位问题

panic用于真正异常情况

recover生效范围,在当前goroutine的被defer的函数中生效

性能优化

1.Benchmark

go语言提供了支持基准性能测试的benchmark工具

例如:

 import (
   "fmt"
   "testing"
 )
 func BenchmarkSprint(b *testing.B) {
   b.ResetTimer()
   for i := 0; i < b.N; i++ {
     fmt.Sprint(i)
   }
 }

2.Slice

slice预分配内存

另一个大陷阱:大内存未释放

3.Map

map中保存值,而不是指针,使用分段map。

4.空结构化

使用struct{}优化

性能调优

1.简介

要依靠数据

要定位最大瓶颈

不要过早优化

不要过度优化

2.性能优化工具pprof

2.1 pprof关注的模块

  • CPU profile:报告程序的 CPU 使用情况,按照一定频率去采集应用程序在 CPU 和寄存器上面的数据
  • Memory Profile(Heap Profile):报告程序的内存使用情况
  • Block Profiling:报告 goroutines 不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈
  • Goroutine Profiling:报告 goroutines 的使用情况,有哪些 goroutine,它们的调用关系是怎样的

2.2 引入方式

import "net/http/pprof"
import "runtime/pprof"

2.3 使用方式

如果使用了默认的 http.DefaultServeMux,只需要添加一行:

import _ "net/http/pprof"

如果应用使用了自定义的 Mux,则需要手动注册一些路由规则:

r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
//等等