这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天,今天第一课主要学习了并发和依赖管理的知识,了解了协程、channel等知识;第二节课主要学习了测试,单元测试、mock测试和基准测试。最后对一个Gin项目进行了学习和功能扩展。
课程一
并发
并发与并行
并发:单核多程序,时间片
并行:多核多程序
Goroutine
| 协程 | 线程 |
|---|---|
| 用户态,靠Go调度器调度 | 内核态的,内核调度 |
| 上下文切换快,不经过os的用户态和内核态切换 | |
| 协程栈默认2KB | 线程栈默认2MB |
CSP
用通信共享内存,而不是共享内存通信
channle
1 无缓冲区:接收和发送端同步
2 有缓冲区:缓冲区未满,发送不阻塞;缓冲区未空,接收不阻塞。
例子:由于消费者和生产者的消费或者生产速度不匹配,可以用带缓冲的channel减少阻塞,提高二者执行效率
waitgroup
并发任务同步。
var wg sync.WaitGroup
wg.Add(5)
go fun() {
defer wg.Done()
XXX
}
wg.Wait()
依赖管理
- gopath: 不能实现package的多版本控制
- govender:无法控制依赖的版本
- gomodule:定义了版本规则和依赖关系
三要素
- 配置文件 go.mod
- 中心仓库 goproxy
- 本地工具 go get
go.mod
一般是 [module_path][version]形式
version一般有两种${MAJOR}.${MINOR}.${PATCH}或是vX.Y.Z-yyyymmddhhmmss-comit
依赖分发
比较像常见的缓存,也是一级一级的
graph LR
proxy1 --> proxy2 --> direct
使用
- go get参数 @none 删除, @v1.1.2 下载特定版本
- go mod参数 init 初始化, download 下载, tidy 删除不需要的依赖
课程二
单元测试
方法:
go test hellowithassert_test.go hello.go
规则
- 测试文件以
_test.go结尾 - 函数名称
func TestXxxx(t *testing.T) - 初始化逻辑放在
TestMain(t *testing.M)
评估测试
代码覆盖率go test加上--cover
mock测试
例子:通过mock实现不对本地文件的强依赖
基准测试
测试cpu损耗之类
函数名称func BenchmarkXxxx(b *testing.b)
项目
我的作业实现见RepoGithub,最后发现老师已经写好了一个版本v0.1,可以对照原本V0的看下Github对比查看
配置
注意:视频里的源码在V0分支(文件),默认只forkmain分支,fork的时候main branch only 前边的对勾去了
先设置下proxy,参考goproxy.cn
cd go-project-example
go mod download
运行后测试
curl --location --request GET 'http://0.0.0.0:8080/community/page/get/2'
1 发布帖子接口 思考
参考go-tutorial-gin 增加一个POST接口,
- post信息传递流程
graph LR
A[server.go<br>系统获取post请求] --> B[cotroller<br>返回客户PageData] --> C[service<br>系统加入失败或成功] -->D[repository<br>map插入&&文本插入]
- 本地id唯一: 加字段,记录post的个数
- 并发读写问题 原先的系统其实只支持读操作,加了发布接口后,加了写操作,暂时考虑使用读写锁防止并发错误
TODO:
- 没有并发测试
- 老师给的版本,读写锁和我写的读写锁位置不同,还有些东西没有考虑到
总结
自己写的版本可读性不太好,还需要整理。