Go语言上手-工程实践
这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记
并发VS并行
并发,多个线程在一个核心上运行,通过时间片的快速切换使得在宏观上是同时运行的。
并行,多个线程在多个核心上运行,实际上是同时运行。
实际上我们可以理解并行是实现并发的一个手段。
Go可以发挥多核优势,高效运行。
Goroutine
Go里面有一个新的概念叫协程。
协程可以看作是一个轻量级的线程,处于操作系统的用户态中。
在一个线程里面可以创建多个协程。
线程处于内核态,实际上调用线程是非常消耗性能的
Go语言使用协程可以更好的提高效率。
Channel
Go语言提倡通过通信来共享内存,而不是通过共享内存来通信。
channel是go语言中进行协程通信的通道。
channel有两种:
- 同步通道
- 缓冲通道
Sync
这个一个包,在这个包下用实现并发安全的一些关键字和方法
比如lock和waitGroup。
Go Modules
Go path模式的弊端
- 无版本控制概念
- 无法同步一致第三方版本号
- 无法指定当前项目引用的第三方版本号
Go Modules模式
Go Modules 是Go语言解决版本依赖问题的解决方案。
Go modules 目前集成在 Go 的工具链中,只要安装了 Go,自然而然也就可以使用 Go modules 了。
Go proxy
这个环境变量主要是用于设置 Go 模块代理(Go module proxy),其作用是用于使 Go 在后续拉取模块版本时直接通过镜像站点来快速拉取。
我们需要去配置这个环境变量,以保证可以直接下载依赖,配置代理可以解决诸多问题例如项目构建的确定性,项目作者的修改等等。保证依赖的可用性。
依赖问题
如果一个项目中俩个模块用到了一个依赖库的俩个版本,go module会选择最低兼容版本
依赖问题3要素:
- go mod 配置文件,管理依赖
- go proxy 中心依赖库
- go get/mod 本地工具
//初始化指令,指定了导入模块github.com/dasgu/go
go mod init github.com/dasgu/go
//如果需要哪一个依赖直接go get,后面可以加上版本等信息
go get ....
测试
测试是避免事故的最后一道屏障
测试可以分成3类:
- 回归测试
- 集成测试
- 单元测试
从上到下,一般成本越来越低,代码覆盖率也越来越高
所以一般单元测试就决定了代码的质量
一般用代码覆盖率来评测测试的水准和完备性
单元测试的规则
- 所有的测试文件以_test.go结尾
- func TestXxx(*testing.T)
- 初始化逻辑放在TestMain中
Mock测试
一般我们的函数都会存在一些外部的依赖,这样我们测试起来很不方便。
我们可以mock一些数据来进行测试,这样就不需要导入外部依赖,提高测试效率。
基准测试
基准测试是指测试一段程序的运行性能及消耗cpu的资源,用于做性能分析。以便于我们来优化代码。
基准测试以Benchmark开头,入参是testing.B
补充:字节开源了一个高性能随机数方法fastrand。思路是牺牲了一定的数列一致性,在大多数场景下是适用的。