go语言进阶 | 青训营笔记

215 阅读2分钟

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 \to Go Vendor \to Go Module

现在主要通过 go.mod 文件管理依赖包版本,go get/mod 指令管理依赖包。

go.mod文件中:

  • // indirect后缀,表示当前模块没有直接导入该依赖的包,标识间接依赖
  • +incompatible后缀,一般是由于 Module 为不规范的 Module,为了加以区分,go 会在 go.mod 中增加 +incompatible 标识。

image.png image.png

项目测试

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操作,跳转到对应分支。