Go语言进阶-工程进阶| 青训营笔记

92 阅读3分钟

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

课堂笔记(Go语言进阶与依赖管理&Go语言工程实践之测试)

本节课重点内容: 从工程实践角度了解Go在企业设计开发过程中涉及的基础知识点

1.并发编程

  • 并发:多线程程序在一个核的cpu上运行
  • 并行:多线程程序在多个核的cpu上运行

协程与线程程的分别

线程可以并发的运行多个协程

  • 协程:用户态、轻量级线程、栈MB级别
  • 线程:内核态、线程跑多个协程、栈KB级别

Go语言提倡通过通讯共享内存而不是通过共享内存而实现通讯

通过共享内存实现通讯需要使用互斥量加锁,不同的协程之间可能发生数据静态,在一定程度上影响程序的性能

通过通讯共享内存

通过通讯共享内存需要使用channel,channel需要使用make(chan 元素类型, [缓冲大小])这种方式申请空间,channel是引用类型,channel分为两种:

  • 无缓冲通道 make(chan int)

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

    无缓冲通道实现不同协程的同步执行,有缓冲通道实现不同协程的异步执行

共享内存实现通讯

共享内存实现通讯需要使用锁,相关函数在sync包中

并发安全Lock
  • 声明一个锁:lock sync.Mutex
  • 加锁:lock.Lock()
  • 解锁:lock.Unlock()
WaitGroup

Go语言也可以使用waitgroup实现并发任务的同步

  • 声明一个计数器:var wg sync.WaitGroup
  • 设置计数器:wg.Add(5)
  • 计数器减1:defer wg.Done()
  • 计数器为0:wg.Wait()

将计数器设置为协程数量,每个协程完成后计数器减1,当计数器不为0时wg.Wait()会阻塞,直到计数器为0也就是所有协程都结束

2.依赖管理

Go的依赖管理经历了三个阶段,不同环境的依赖的版本不同

  1. GOPATH
  2. Go Vender
  3. Go Module

目前新版本的Go语言使用Go Module对依赖进行管理

Go Module

  • 通过go.mod文件管理依赖包版本
  • 通过go install/go mod指令工具管理依赖包
依赖管理三要素
  1. 配置文件,描述依赖 go.mod
  2. 中心仓库管理依赖库 Proxy
  3. 本地工具 go install/mod

3.测试

  1. 回归测试
  2. 集成测试
  3. 单元测试

这三种测试从上到下,覆盖率逐层变大,成本却逐层降低

单元测试

单元测试规则:
  • 所有测试文件以_test.go结尾
  • func TestXxx(*testing.T)
  • 初始化逻辑放到TestMain中
单元测试运行指令:

go test [flags] [packages]

单元测试可以使用一个开源包方便的判断输出是否符合期望:github.com/stretchr/testify/assert assert.Equal(t, expectOutput, output)

单元测试覆盖率:go test judgment_test.go judgment.go --cover

  • 一般覆盖率:50%~60%,较高覆盖率80%+
  • 测试分支相互独立、全面覆盖
  • 测试单元粒度足够小,函数单一职责
单元测试-Mock

monkey:github.com/bouk/monkey

Mock函数可以快速为一个函数或方法打桩,使测试的函数或方法不依赖本地文件

基准测试

优化代码,对当前代码分析,测试代码的运行速度

项目实践

需求描述
  • 展示话题(标题、文字描述)和回帖列表
  • 不考虑前端页面实现,仅仅实现一个本地web服务
  • 话题和回帖数据用文件存储
需求用例

捕获.PNG 用户可以查看话题以及话题所对应的回帖的列表

ER图

捕获.PNG 话题和回帖的结构体属性如上

分层结构

捕获.PNG

  • 数据层:数据Model,外部数据的增删改查
  • 逻辑层:业务Entity,处理核心业务逻辑输出
  • 视图层:视图view,处理和外部的交互逻辑