go语言进阶 | 青训营笔记
这是我参与「第五届青训营」笔记创作活动的第2天。
go 并发编程
go语言使用协程进行高并发操作,与线程(用户态,轻量化线程,栈 MB 级别)相比,协程有以下特点:
- 内核态,线程跑多个协程,栈 KB 级别
我们可以看到,协程是很轻量级的,所以甚至我们可以同时开上万个协程来并发操作。
一般在 java 中实现高并发一般都是通过加锁的操作来进行的,这实际是一种通过共享内存来实现通信的方式;而 go 则使用另一种方式,通过通信共享内存,通过 channel 来实现共享内存。
go 中 sync 并发包可以实现并发安全操作和协程间同步操作:
Lock 可以进行并发操作,通过 lock.Lock() 和 lock.Unlock() 操作实现防止并发访问内存出错的问题。
WaitGroup 可以做计数器, WaitGroup.Add(delta int) 可以使计数器加 delta,WaitGroup.Done() 使计数器减一,WaitGroup.Wait() 阻塞直到计数器为0。
依赖管理
go 中依赖管理主要经历了三个过程:GOPATH Go Vendor Go Module
现在主要通过 go.mod 文件管理依赖包版本,go get/mod 指令管理依赖包。
go.mod文件中:
// indirect后缀,表示当前模块没有直接导入该依赖的包,标识间接依赖+incompatible后缀,一般是由于 Module 为不规范的 Module,为了加以区分,go 会在go.mod中增加+incompatible标识。
项目测试
go 支持单元测试:
- 以 _test.go 结尾
- func TestXxx(t *testing T)
- 初始化逻辑放在TestMain里
go 支持基准测试:
- func BenchmarkXxx(b *testing.B)
Mock函数可以进行打桩,Mock Patch的作用域在 Runtime,在运行时通过通过 Go 的 unsafe 包,能够将内存中函数的地址替换为运行时函数的地址。
项目实战
项目是一个经典的 Web 项目,基于 MVC 架构,整体分为三层,repository数据层,service逻辑层,controller视图层。
- repository 层关联底层数据模型,数据存储在本地文件,通过文件操作获取数据,repository 层面向service 层,对service 层透明,不管底层数据是什么,对service 层的接口是不变的。
- service 层处理核心业务逻辑,计算打包业务实体 entity,并上传controller 层
- controller 层负责处理和外部的交互逻辑。
gin 是一个轻量级的 go web 框架,感觉用起来还是很方便的。
参考链接
ps:clone 时使用 git clone -b V0 xxx操作,跳转到对应分支。