Go语言进阶| 青训营笔记

133 阅读4分钟

Go语言进阶| 青训营笔记

这是我参与「第五届青训营」笔记创作活动的第2天。

一、本堂课重点内容

Go 语言进阶课程主要重点是并发编程、依赖管理和单元测试。在并发编程方面,学习 Go 语言提供的 goroutine 和 channel 来实现并发编程,使用 Go 的包管理工具来管理项目依赖以及使用 testing 包来编写单元测试。最后通过项目实践来运用和熟悉这些知识。

二、详细知识点介绍

并发编程

并发 image.png

并行 image.png

1.Goroutine

协程 VS 线程
协程:用户态,轻量级线程,栈KB级别
线程:内核态,线程跑多个协程,栈MB级别
只需在函数调用前加 go 关键字,可为函数创建协程运行
同一个程序中的所有 goroutine 共享同一个地址空间

2.Channel

通过通信共享内存
make(chan 元素类型,[缓冲大小])

make(chan int) //无缓冲通道
make(chan int,2) //有缓冲通道

默认情况下,通道是不带缓冲区的。发送端发送数据,同时必须有接收端相应的接收数据。
注意:

  • 如果通道不带缓冲,发送方会阻塞直到接收方从通道中接收了值;
  • 如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区内;
  • 如果缓冲区已满,则意味着需要等待直到某个接收方获取到一个值。接收方在有值可以接收之前会一直阻塞。

3.Sync

sync.Mutex 是一种互斥锁,可以用来保证在并发环境下访问共享资源时的安全性。我们可以在访问共享资源之前获取锁,在访问结束后释放锁,以保证在同一时刻只有一个 goroutine 能够访问该资源。

总结:并发安全Lock。

sync.WaitGroup 是一种等待组,可以用来等待一组 goroutine 执行完毕。我们可以在启动一个 goroutine 时调用 WaitGroup.Add 方法来增加计数器,在 goroutine 执行完毕时调用 WaitGroup.Done 方法来减少计数器,最后在主 goroutine 中调用 WaitGroup.Wait 方法来等待所有 goroutine 执行完毕。

总结:开启协程+1;执行结束-1;主协程阻塞直到计数器为0。

依赖管理

1.背景

工程项目不可能基于标准库0~1编码搭建,需要导入较多的依赖,从而也有了管理依赖库的需求。
依赖管理演进:GOPATH >> Go Vendor >> Go Module

  • GOPATH 无法实现package的多版本控制
  • Go Vendor 通过每个项目引入一份依赖的副本,解决了多个项目需要同一个依赖的冲突问题,但是其无法控制依赖的版本,在更新项目时可能会出现依赖冲突。
  • Go Module 允许开发者在项目中使用 go mod 命令来管理依赖包。Go Modules 支持版本管理,解决了依赖冲突和过时的问题,并且支持分享项目依赖信息。

2.Go依赖管理

三要素:配置文件,描述依赖(go.mod);中心仓库管理依赖库(Proxy);本地工具(go get/mod)\

测试

1.单元测试

规则:

  • 所有测试文件以 _test.go 结尾
  • func TestXxx(*testing.T)
  • 初始化逻辑放到 TestMain 中 评估标准:覆盖率
  • 一般覆盖率:50~60%,较高覆盖率80%+

2.Mock测试

使用第三方库monkey快速生成Mock函数

//安装monkey第三方库
go get -u github.com/bouk/monkey

使用 monkey 库来mock函数,首先需要使用 monkey.Patch() 方法来替换需要mock的函数。其次,需要使用 monkey.Unpatch() 方法来撤销mock操作。 image.png

3.基准测试

  • 优化代码,需要对当前代码分析
  • 内置的测试框架提供了基准测试的能力 使用 testing.Benchmark 函数来测试该函数的性能:在运行 go test -bench=. 命令后,系统会自动运行 BenchmarkTest 函数,并输出每次运行所消耗的时间。

项目实战

1.需求设计

  • 展示话题和回帖列表
  • 暂不考虑前端页面实现
  • 话题和回帖数据用文件存储 ER图 image.png 分层结构 image.png 组件工具:
  • Gin 高性能 go web 框架
  • Go Mod
go get gopkg.in/gin-gonic/gin.v1@v1.3.0 

出现下载模块提示连接失败问题: A connection attempt failed because the connected party did not properly respond after a period
of time, or established connection failed because connected host has failed to respond. 解决办法:

go env -w GOSUMDB=off //关闭GOSUMDB
go env -w GOPROXY=https://goproxy.cn,direct //设置新的代理

2.代码设计

3.测试运行

三、实践练习例子

  • 支持发布帖子
  • 本地 Id 生成需要保证不重复、唯一性
  • Append 文件,更新索引,注意 Map 的并发安全问题

四、课后个人总结

这门课程对于深入学习 Go 语言有很大的帮助。我深刻地意识到,在 Go 语言中,并发编程、依赖管理和单元测试是非常重要的。我会继续努力学习,深入探索 Go 语言的更多知识。项目的代码还需时间来进行消化,加油!

五、引用参考