Go语言进阶、依赖管理以及工程实践 | 青训营笔记

91 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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 可以定义规则管理关系。

依赖管理三要素

  1. 配置文件,描述依赖 go.mod
  2. 中心仓库管理依赖库 Proxy
  3. 本地工具 go get/mod

依赖配置

go.mod

image.png 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卸桩。

基准测试

基准测试用于对代码进行性能分析。 image.png

如图所示,基准测试函数以Benchmark开头,Resttimer重置计时器,runparallel是多协程并发测试。

在并发情况下rand为了保证并发安全和随机性有了全局锁,性能下降,可以使用fastrand提升性能。

三、实践练习例子

青训营话题页开发

开发顺序

  1. 进行需求分析,画出需求用例和ER图
  2. 选择分层结构,这里选择数据-逻辑-视图的的结构
  3. 选择组件工具,使用go mod进行依赖管理,导入gin框架
  4. 设计Repository,主要有Topic结构和Post结构,使用map来进行索引
  5. 构建初始化数据索引函数
  6. 构建数据查询函数
  7. 设计构建Service实体
  8. 进行具体Service处理代码流程编排
  9. 构建View对象,返回最终信息

四、课后个人总结

依赖管理和测试还需要进一步学习,本节课项目难度较大,有很多知识点需要进一步吸收消化,比如业务逻辑的设计实现、gin的使用细节等。