一、语言进阶

并发与并行

并发:多线程在单核CPU上运行

并行:多线程程序在多核程序上运行

1、Goroutine

协程:用户态,轻量级线程,栈MB级别

线程:内核态,线程跑多个协程,栈KB级别

创建协程代码:

1
2
3
4
5
6
7
8
9
10
11
12
func hello(i int) {
println("hello goroutine : " + fmt.Sprint(i))
}

func main() {
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
time.Sleep(time.Second)
}

2、CSP(Communicating Sequential Processes)

提倡通过通信共享内存而不是通过共享内存实现通信

3、Channel

通过make(chan 元素类型,, [缓冲大小])

  • 有缓冲通道
  • 无缓冲通道

代码示例:

A协程发送0~9数字;B协程计算输入数字的平方;主协程输出最后的平方数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func CalSquare() {
src := make(chan int)
dest := make(chan int, 3)
go func() {
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}()
go func() {
defer close(dest)
for i := range src {
dest <- i * i
}
}()
for i := range dest {
println(i)
}
}

4、并发安全Lock

5、WaitGroup

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

6、小结

  • Goroutine
  • Channel
  • Sync

二、依赖管理

1、Go依赖管理演进

GOPATH -> Go Vender -> Go Module

(1)GOPATH

  • 项目代码直接依赖src下的代码
  • go get下载最新的代码到src目录下

无法实现package的多版本控制

(2)Go Vender

  • 增加vender文件,存放所有的依赖包副本
  • 为每一个项目引入一份依赖副本

无法控制依赖版本

(3)Go Module

  • 通过go.mod文件管理依赖包版本
  • 通过go get/go mod指令工具管理依赖包

定义版本规则和管理项目依赖关系

2、依赖管理

  • 配置文件:go.mod
  • 中心仓库管理依赖库:Proxy
  • 本地工具:go get/mod

(1)依赖配置-go.mod

也就是编写go.mod

1
2
3
4
5
6
7
8
9
10
11
// 依赖管理基本单元
module github.com/Moonlight-Zhao/go-project-example

// 原生库
go 1.16

// 描述单元依赖
require (
// 依赖标识:[Module Path][Version / Pseudo-version]
github.com/gin-contrib/sse v0.1.0
)

(2)依赖配置-version

  • 语义化版本
  • 基于commit伪版本

(3)依赖配置-indirect

直接依赖和间接依赖

(4)依赖配置-incompatible

主版本2+模块会在模块路径增加/vN后缀

对于没有go.mod文件并且主版本2+的依赖,会加上该关键字

(5)工具

go get

go mod (init / download / tidy)

3、小结

  • Go依赖管理演进
  • Go Module依赖管理方案

三、测试

回归测试 -> 集成测试 -> 单元测试(测试成本逐渐降低)

1、单元测试

(1)规则

  • 所有测试文件以_test.go结尾
  • func TestXxx(*testing.T)
  • 初始化逻辑放到TestMain中

(2)单元测试-assert

待测试函数:

1
2
3
func HelloTom() string {
return "Susan"
}

测试代码:

1
2
3
4
5
func TestHelloTom(t *testing.T) {
output := HelloTom()
expectOutput := "Tom"
assert.Equal(t, expectOutput, output)
}

2、单元测试-依赖

外部依赖 => 稳定&幂等

3、单元测试-Mock

monkey:https://github.com/bouk/monkey

  • 为一个函数打桩
  • 为一个方法打桩

不依赖于本地文件

4、基准测试

  • 优化代码
  • 内置的测试框架提供了基准测试能力

5、小结

  • 单元测试
  • Mock测试
  • 基准测试

四、项目实战

1、分层结构

  • 数据层

    数据Model,外部数据的增删改查

  • 逻辑层

    业务Entity,处理核心业务逻辑的输出

  • 视图层

    视图View,处理和外部交互逻辑

2、组件工具