这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
简介
- 语言进阶
- 依赖管理
- 测试
语言进阶
并发和并行
- 两个及以上的线程在同一个时间段内运行
- 两个及以上的线程在同一时刻运行
协程
协程,英文名Coroutine。但在 Go 语言中,协程的英文名是:gorutine。它常常被用于进行多任务,即并发作业。没错,就是多线程作业的那个作业。
协程的特点
-
多个协程可由一个或多个线程管理,协程的调度发生在其所在的线程中。
-
可以被调度,调度策略由应用层代码定义,即可被高度自定义实现。
-
执行效率高。
-
占用内存少。
线程和协程的对比:
| 比较的点 | 线程 | 协程 |
| 数据存储 | 内核态的内存空间 | 一般是线程提供的用户态内存空间 |
| 切换操作 | 操作最终在内核层完成,应用层需要调用内核层提供的 syscall 底层函数 | 应用层使用代码进行简单的现场保存和恢复即可 |
| 任务调度 | 由内核实现,抢占方式,依赖各种锁 | 由用户态的实现的具体调度器进行。例如 go 协程的调度器 |
| 语音支持程度 | 绝大部分编程语言 | 部分语言:Lua,Go,Python … |
| 实现规范 | 按照现代操作系统规范实现 | 无统一规范。在应用层由开发者实现,高度自定义,比如只支持单线程的线程。不同的调度策略,等等 |
依赖管理
解决问题:
- 开发环境不同
- 依赖版本不同
Go Module
通过go.mod管理
通过go install/go mod管理依赖
module example/app
go 1.20
require(
dependencies v1.2.1
)
在依赖版本不同、互相不冲突时,会选择最低的兼容版本(1.1, 1.2会选择1.2)
在Go语言的早期版本中,我们编写Go项目代码时所依赖的所有第三方包都需要保存在GOPATH这个目录下面。这样的依赖管理方式存在一个致命的缺陷,那就是不支持版本管理,同一个依赖包只能存在一个版本的代码。可是我们本地的多个项目完全可能分别依赖同一个第三方包的不同版本。
go module介绍
Go module 是 Go1.11 版本发布的依赖管理方案,从 Go1.14 版本开始推荐在生产环境使用,于Go1.16版本默认开启。Go module 提供了以下命令供我们使用:
go module相关命令
| 命令 | 介绍 |
|---|---|
| go mod init | 初始化项目依赖,生成go.mod文件 |
| go mod download | 根据go.mod文件下载依赖 |
| go mod tidy | 比对项目文件中引入的依赖与go.mod进行比对 |
| go mod graph | 输出依赖关系图 |
| go mod edit | 编辑go.mod文件 |
| go mod vendor | 将项目的所有依赖导出至vendor目录 |
| go mod verify | 检验一个依赖包是否被篡改过 |
| go mod why | 解释为什么需要某个依赖 |
Go语言在 go module 的过渡阶段提供了 GO111MODULE 这个环境变量来作为是否启用 go module 功能的开关,考虑到 Go1.16 之后 go module 已经默认开启,所以本书不再介绍该配置,对于刚接触Go语言的读者而言完全没有必要了解这个历史包袱。