这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
今天也是青训营开始的第二天,在观看完学习视频并跟着做了一些练习之后,我感到收获颇丰,下面就来总结一下。
一、本堂课重点内容
本节课的重点内容主要有四个方面:
- 并发编程 重点主要在协程、通道、线程同步等部分,实践中使用频繁
- 依赖管理 主要在于Go Module的学习应用
- 单元测试 主要在于了解单元测试、基准测试的概念和规则,进行完整测试。
- 项目实战 完成青训营话题页的开发工作,充分运用以上知识点。
二、详细知识点介绍
1.并发编程
Goroutine
线程在内核态,较为消耗资源;协程在用户态,是轻量级线程,资源消耗较小。
在调用函数前加上关键词go即可使用协程。
CSP
提倡通过通信共享内存而不是通过共享内存实现通信。
通道
通过make(chan 元素类型,缓冲大小)来建立通道,没有缓冲大小参数则建立无缓冲通道。
带缓冲的channel可以解决生产消费不均衡(生产快消费慢)带来的执行效率问题。
并发安全Lock
lock sync.Mutex创建互斥量关键字lock,通过lock.Lock(),lcok.Unlock()来加减锁。
WaitGroup
开启协程用Add()将计数器增加若干,协程执行结束用Done()将计数器-1,Wait()阻塞等待计数器为0。
2.依赖管理
Go依赖管理演进
- GoPath 无法实现package的多版本控制
- GoVender 无法控制依赖的版本。更新项目又可能出现依赖冲突,导致编译出错。
- GoModule 可以定义规则管理关系。
依赖管理三要素
- 配置文件,描述依赖 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
依赖配置
go.mod
version:
- 语义化版本
${MAJOR}.${MINOR}.${PATCH} - 基于commit伪版本
vX.0.O-yyyymmddhhmmss-abcdefgh1234(时间戳+哈希码)
关键词:
- indirect表示非直接依赖
- 对于没有go.mod且住主版本在2以上的添加+incompatible
编译时选择最低兼容版本。
本地工具
go get:
- @update 默认
- @none 删除依赖
- @v1.1.2 tag版本,语义版本
- @23dfdd5 特定的commit
- @master 分支的最新commit
go mod:
- init 初始化,创建go.mod文件
- download 下载模块到本地缓存
- tidy 增加需要的依赖,删除不需要的依赖
3.测试
单元测试
规则:
- 所有测试文件以_test.go 结尾
- func TestXxx(*testing.T)
- 初始化逻辑放到TestMain中
可以增加--cover参数来显示覆盖率
Mock
常用 monkey : github.com/bouk/monkey
打桩是为了摆脱外部依赖的影响,可以为函数打桩,也可以为方法打桩,patch打桩,unpatch卸桩。
基准测试
基准测试用于对代码进行性能分析。
如图所示,基准测试函数以Benchmark开头,Resttimer重置计时器,runparallel是多协程并发测试。
在并发情况下rand为了保证并发安全和随机性有了全局锁,性能下降,可以使用fastrand提升性能。
三、实践练习例子
青训营话题页开发
开发顺序
- 进行需求分析,画出需求用例和ER图
- 选择分层结构,这里选择数据-逻辑-视图的的结构
- 选择组件工具,使用go mod进行依赖管理,导入gin框架
- 设计Repository,主要有Topic结构和Post结构,使用map来进行索引
- 构建初始化数据索引函数
- 构建数据查询函数
- 设计构建Service实体
- 进行具体Service处理代码流程编排
- 构建View对象,返回最终信息
四、课后个人总结
依赖管理和测试还需要进一步学习,本节课项目难度较大,有很多知识点需要进一步吸收消化,比如业务逻辑的设计实现、gin的使用细节等。