Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理

Go 语言入门 – 工程实践进阶

1. Goroutine

1.1 Why Goroutine

线程属于内核态,栈内核态;

协程是轻量级线程, 栈kB级 属于用户态

如下代码: 直接使用关键词 go 可以直接创建一个协程

func hello(i int) {
	defer fmt.Println("hello, ", i)
}

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

1.2 CSP – goroutine communication

建议使用通信共享内存而不是通过共享内存实现通信,共享内存属于临界区,访问时需要加锁,会影响协程并发效率
Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第1张图片

1.3 Channel

如下图, 无缓冲通道和有缓冲通道,原理类似于操作系统的单缓冲区和双缓冲区

语法: make(chan 元素类型, [缓冲大小])
Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第2张图片

示例代码:

func CalSquare() {
	src := make(chan int)
	dest := make(chan int, 3)
	go func() {
    //defer 关键词的作用是 在同一作用域内代码执行完后执行该语句
		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)
	}
}

1.4 Lock 临界区

协程共享资源,互斥访问时,需要加锁

如图所示,如果对于共享资源 x 不加锁访问,下面例子会发生写后写的错误,导致最后结果与我们预期不相符。

1.5 waitGroup

sync.WaitGroup 计数器包括如下三个操作函数

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第3张图片

如下示例中 time.Sleep() 函数可以由waitGroup 代替
Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第4张图片
Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第5张图片

2. 如何管理依赖库: GOPATH --> GO Vendor --> Go Model

2.1 GOPATH:

​ 环境变量 GOPATH 是 go 项目的依赖库路径, 可通过 go env 查看或修改 $GOPATH 变量。

​ $GOPATH 下的三个目录作用如下所示:
Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第6张图片

弊端:

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第7张图片

2.2 GO Vendor:

  • 项目目录下增加 vendor 文件, 所有依赖包副本形式放在 ProjectRoot/vendor

  • 依赖寻址方式: vendor => GOPATH

    每个项目引入一份依赖的副本(vendor),解决了多个项目中需要同一个package依赖的冲突问题。

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第8张图片

弊端:

  • 无法控制依赖的版本
  • 更新项目又可能出现依赖冲突,导致编译错误

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第9张图片

2.3 Go Module

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

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

2.3.1 依赖管理三要素

  1. 配置文件,描述依赖 go.mod

  2. 中心仓库管理依赖库 Proxy – 远程代理库

  3. 本地工具 go get/mod 指令

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

  • 对于没有 go.mod 文件并且主版本2+的依赖,会 + incompatible

2.3.2 版本格式

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第10张图片

2.3.3 依赖分发

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第11张图片
Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第12张图片

2.3.4 工具

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第13张图片

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第14张图片

3.测试

  • 回归测试:抖音刷视频,点赞等测试

  • 集成测试: 自动化功能接口测试

  • 单元测试: 具体到每个函数模块

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第15张图片

3.1 单元测试

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第16张图片

assert & go test :

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第17张图片

在这里插入图片描述

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第18张图片

编码原则:

​ 编写函数应该尽量小,单一职责原则

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第19张图片

3.2 外部依赖测试

Go 语言入门(二) -- 工程实践进阶 协程Goroutine 通道Channel 互斥锁 mutex 计数器waitGroup GoPath包管理_第20张图片

3.2.1: 打桩 Mock

​ 打桩后,使得函数不再被外部依赖影响

三方依赖: github.com/bouk/monkey

3.3 基准测试

​ go test -bench=.

​ 测试性能,热点代码

图片均来自字节青训营课程,博客作为自己学习记录,如有侵权,麻烦联系删除。

你可能感兴趣的:(Go,golang,开发语言,go)