/images/hugo/avatar.png

Delve 调试Go代码

1. 专业调试工具

bug是表象,要发现内部原因需要利用更多的表象数据去推理,需要收集足够多的“现场数据”。我们可以通过编程语言内置的输出语句(如Go的print、fmt.Printf等)输出我们需要的信息,而更为专业的方法是通过编程语言提供的专业调试工具(如GDB)设置断点来采集现场数据或重现bug。

expvar

1. expvar

应用运行状态一般以度量数据的形式呈现。通过了解应用关键路径上的度量数据,我们可以确定在某个度量点上应用的性能是符合预期性能指标还是较大偏离预期,这样就可以最大限度地缩小性能瓶颈点的搜索范围,从而快速定位应用中的瓶颈点并进行优化。这些可以反映应用运行状态的数据也被称为应用的内省(introspection)数据。相比于通过查询应用外部特征而获取的探针类(probing)数据(比如查看应用某端口是否有响应并返回正确的数据或状态码),内省数据可以传达更为丰富、更多的有关应用程序状态的上下文信息。这些上下文信息可以是应用对各类资源的占用信息,比如应用运行占用了多少内存空间,也可以是自定义的性能指标信息,比如单位时间处理的外部请求数量、应答延迟、队列积压量等。我们可以轻松地使用Go标准库提供的expvar包按统一接口、统一数据格式、一致的指标定义方法输出自定义的度量数据。

Go 性能优化

1. 性能基准测试

性能基准测试在Go语言中是和普通的单元测试一样被原生支持的。我们可以像对普通单元测试那样在*_test.go文件中创建性能基准测试,每个以Benchmark前缀开头的函数都会被当作一个独立的性能基准测试:

Go 测试

本部分将详细介绍Go在单元测试、性能测试的最佳实践方案。

1. 单元测试

Go语言在工具链和标准库中提供对测试的原生支持。在Go中测试代码与包代码放在同一个包目录下,并且Go要求所有测试代码都存放在以*_test.go结尾的文件中。go test将所有包目录下的*_test.go文件编译成一个临时二进制文件(可以通过go test -c显式编译出该文件),并执行该文件,后者将执行各个测试源文件中名字格式为TestXxx的函数所代表的测试用例并输出测试执行结果。

并发编程

今天我们开始深入学习,Go 语言的并发编程,将详细介绍Go基本执行单元——goroutine的调度原理、Go并发模型以及常见并发模式、Go支持并发的原生类型——channel的惯用使用模式等内容。

Go 函数、方法和接口

今天我们开始深入学习,Go 语言的函数、方法和接口

1. 函数

Go 语言里函数是"一等公民",简单来讲函数可以像变量值那样被赋值给变量、作为参数传递、作为返回值返回和在函数内部创建等。概念我们就不过介绍,我们把关注在放在 Go 语言函数的一些典型应用上。