这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
一.本次课程的重点内容
任何一个项目的完成,都离不开一个团队的共同合作,想要在项目中团队合作愉快就不得不提及,项目代码的规范书写,代码书写标准,简洁,高效,是对一个程序员的基本要求,一份合格的代码可以让团队之间调用,阅读,二次开发变的更加的便捷,同时也会少一些BUG的产出。在一份标准代码的基础上,还需要学习代码的调优及分析工具,要学会了解工程中性能优化的原则和流程。
二.课程整体内容
本次课程主要通过4个方向分别进行讲解:
1.如何编写更简洁清晰的代码
2.常用Go语言程序优化手段
3.熟悉Go程序性能分析工具
4.了解工程中性能优化的原则和流程
三.课程详细内容及实践
一.GO的代码规范
1.首先是注释部分: 公共符号始终要注释包中声明的每个公共的符号:变量、常量、函数以及结构都需要添加注释 任何既不明显也不简短的公共功能必须予以注释,无论长度或复杂程度如何,对库中的任何函数都必须进行注释
每个包都应该有一个包注释,一个位于 package 子句之前的块注释或行注释。包如果有多个 go 文件,只需
要出现在一个 go 文件中(一般是和包同名的文件)即可。
// @Title
// @Description
// @Author 创建人 创建时间
// @Update 创建人 修改时间
每个自定义的结构体或者接口都应该有注释说明,该注释对结构进行简要介绍,放在结构体定义的前一行,格
式为: 结构体名, 结构体说明。同时结构体内的每个成员变量都要有说明,该说明放在成员变量的后面(注
意对齐)
// User , 用户对象,定义了用户的基础信息
type User struct{
UserName string `description:"用户名称"`
Email string `description:"邮箱"`
}
函数 注释
// @Title 标题
// @Description 详细信息
// @Auth 创建时间 创建人
// @Param 参数类型 参数介绍
// @Return 返回类型 "错误信息"
2.一些变量,常量,函数的命名在程序开发中也尤其重要,主要需要遵循:
- 简洁胜于冗长
- 缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写
- 例如使用 ServeHTTP而不是ServeHttp
- 使用XMLHTTPRequest或者xmlHTTPRequest
- 变量距离其被使用的地方越远,则需要携带越多的上下文信息
- 全局变量在其名字中需要更多的上下文信息,使得在不同地方可以轻易辨认出其含义
3.在嵌套循环时要保持最短嵌套工作:
最常见的正常流程的路径被嵌套在两个if条件内 成功的退出条件是 return nil,必须仔细匹配大括号来发现函数最后一行返回一个错误,需要追溯到匹配的左括号,才能了解何时会触发错误 如果后续正常流程需要增加一步操作,调用新的函数,则又增加一层嵌套。
二.性能优化
性能优化的前提是: 保证项目代码规范,程序无异常。
-
使用 Benchmark 进行基准测试;
-
尽可能为 slice 和 map 预分配内存(通过在
make时指定容量信息); -
注意为切片创建切片不会创建新的底层数组,这可能会导致内存泄漏发生,此时可用
copy代替 re-slice; -
多个字符串拼接时,使用
strings.Builder比直接使用+或使用bytes.Buffer更快(这和 Java 倒是十分相似,Java 也推荐使用StringBuilder拼接多个字符串;其实他们的底层逻辑都是类似的); -
当需要占位符时,可使用空结构体(
struct{})代替,其不会占据镇和内存空间; -
使用
atomic包代替锁修改变量;
三.性能分析工具-pprof
pprof是golang内置的性能分析工具,在进行性能问题分析(入内存泄露,goroutine泄露,cpu资源占用较高等分析)时使用,其可成为我们进行golang开发时,调试应用性能的常用工具。
pprof主要模块介绍:
- CPU profile:当前程序的CPU使用情况,pprof按照一定频率去采集应用程序在CPU和寄存器上面的数据
- Memory Profile(Heap Profile):当前程序的内存使用情况,可查看heap和alloc的情况
- Block Profiling:程序当前goroutines不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈
- Goroutine Profiling:程序当前goroutines的使用情况,查看所有goroutine,产看调用关系,可发现未释放的go程
使用pprof我们可以项目中导入runtime/pprof
//再main包中加入
import _ "net/http/pprof"
//pprof.go
func init() {
http.HandleFunc("/debug/pprof/", Index)
http.HandleFunc("/debug/pprof/cmdline", Cmdline)
http.HandleFunc("/debug/pprof/profile", Profile)
http.HandleFunc("/debug/pprof/symbol", Symbol)
http.HandleFunc("/debug/pprof/trace", Trace)
}
四.课程的总结
本次课程受益颇深,了解成为一名合格的程序员路还有很久,项目编码的规范,调优,管理,每一步都需要细心做到。愿前途一片美好,让我们砥砺前行。
五.引用
掘金课程
文献