*这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天
其实是把第二天的文章重新发了一遍,因为拖到了次日0点发文,没有统计上
今天主要学习了Go 语言进阶与依赖管理以及测试的相关知识,第一节课主要是学习了依赖管理,顺带着了解了下了解了协程、channel的相关知识。第二节课则主要学习了单元测试、mock测试和基准测试,最后学习了我了解go语言之后的第一个框架 gin 并对其进行了扩展。
一 、依赖管理、协程、channel的相关知识
说到协程就不得不从并行和并发开始说起
- 并发(concurrency):把任务在不同的时间点交给处理器进行处理。在同一时间点,任务并不会同时运行。
- 并行(parallelism):把每一个任务分配给每一个处理器独立完成。在同一时间点,任务一定是同时运行
go语言中有一个东西叫做goroutine是其对于轻量级线程的实现
下表列出了协程线程的区别
| 区别 | 协程 | 线程 |
|---|---|---|
| 存在形态和调度方式 | 用户态,靠Go调度器调度 | 内核态的,内核调度 |
| 上下文切换 | 上下文切换快,不经过os的用户态和内核态切换 | |
| 栈大小 | 协程栈默认2KB | 线程栈默认2MB |
go语言的CSP(协程间通信)
channel
channel是一种引用类型,分为了有缓冲通道和无缓冲通道
最后是写了一个A协程发送0-9数字 b协程计算其平方的一个生产消费模型的程序(梦回操作系统课)
而对于这种并发类型的程序我们首先想到的是如何让线程更安全,则我们引入lock但是这种方法不是特别优雅,我们始终不知道什么时候sleep,go语言则给了一个waitgroup方法来暴露出这些细节。
然后就是依赖管理的一些内容
三要素
- 配置文件 go.mod
- 中心仓库 goproxy
- 本地工具 go get go.mod:首先模块路径用来标识一个模块,从模块路径可以看出从哪里找到该模块,如果是gitub前缀则表示可以从github仓库找到该模块,依赖包的源代码由github托管,如果项目的子包想被单独引用,则需要通过单独的 init go,mod文件进行管理。下面是依赖的原生sdk版本。
最下面是单元依赖,每个依赖单元用模块路径+版本来唯—标示。
依赖单元中的特殊标识符:首先是indirect后缀,表示go,mod对应的当前模块,没有直接导入该依赖模块的包,也就是非直接依赖。标示为间接依赖。
下一个常见的是incompatible,主版本2+模块会在模块路径增加/vN后缀,这能让go module按照不同的模块处理同一个项目不同主版本依赖。因为在这项规则提出之前已经又一些仓库打上2或更高版本的tag了,为了兼容这部分仓库,对于有go.mod文件并且主版本在2或者以上的依赖,会在版本号后加上+imcompatible后缀。
一个结论:在最终编译时会选择兼容子项目的最低兼容版本