这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记
并发编程
协程
在go语言中,并发是使用协程来实现的
协程与线程不同,协程是线程模型中1:n的实现,而线程是线程模型中1:1的实现
1:n也就是一个内核线程对应n个用户线程,用户线程的切换调度由用户自己实现
协程的实现
go语言中实现协程的方式很简单,只需要在函数前面加上go关键字就可以开启一个协程来运行
协程的通信
go语言是提倡通过通信来共享内存,而不是通过共享内存进行通信
左图是通过通道进行通信,通道相当于一个先入先出的队列,保证消息的有序性
右图是通过访问临界区来进行通信,访问临界区所需要的就是进程间的互斥也就是加锁
Channel
go语言中channel是一种消息队列
使用make来创建一个channel并返回指针,如make(chan int) make(chan int, 3)
如果使用无缓冲通道来进行通信,会使两个协程直接同步化,所以无缓冲通道又被称为同步通道
有缓冲通道相当于一个生产消费模型,当通道满的时候就会阻塞生产者,当通道空的时候就会阻塞消费者
协程A通过通道src向协程B发送数据,协程B从src中读取数据再写到dest中
从这里可以看出来,通道与共享内存不同,是线程安全的
带缓冲的通道可以解决生产者消费者模型中,资源生产消费不均衡的问题,消费者速度往往是小于生产者的速度,所以需要一个带缓冲的通道来缓冲过剩的资源
并发安全 LOCK
在go语言中的锁为 sync.Mutex
与java语言中的可重入锁很相似,获取锁是lock.Lock(),释放锁是lock.Unlock()
WaitGroup
go语言的同步器件为 WaitGroup
使用方法与Java中的CountDownLatch类似,但是CountDownLatch只能减少不能增加,使用过后就不能再次使用
go的并发组件使用简单
当wg.Add(5)时,表示同步组件可以获取5次
当wg.Done()时,表示同步组件被使用了一次
当wg.Wait()时,表示同步组件正在等待同步
依赖管理
依赖管理演进
GoPath时期,项目都会存放在src目录下,项目依赖的源码也都会存放在src目录下。但是GoPath在面对多个项目的时候,就无法很好的支持这些依赖了
比如当A项目依赖的源码与B项目依赖的源码不相同时,就会出现问题
Go Vendor是为了解决多版本的问题而出现的,其解决方案是每个项目都会有自己依赖的副本,一般会存放到vendor目录下,当vendor目录不存在的时候再回到GoPath目录寻找
但是当项目文件中依赖了一个源码的不同版本的时候,就又会出现版本依赖问题
Go Module是为了解决以上问题而出现的工具
Go Module
Go Module就相当于Java中的Maven一样,是一个管理版本依赖的软件
go.mod文件就相当于pom.xml文件一样,是配置项目依赖的文件,也跟CMakeLists一样,是管理编译的文件,管理了编译的版本
在go.mod文件中,依赖的version又两部分组成,一个是语义化版本,一个是基于commit伪版本
依赖分发
Go Proxy相当于一个中央仓库,这个中央仓库缓存了许多源码的版本
拉取请求就会转到Proxy中,当Proxy找不到源码时,就会将请求转到第三方的源上
go文件目录
GOROOT = C:\Go
GOPATH = D:\MyWorks
GOPROXY = https://mirrors.aliyun.com/goproxy,https://goproxy.cn,direct
C:\Go <<--- GOROOT 指向的位置
--src <<--- Go 语言自带的源代码
--pkg <<--- 编译的中间文件放在此文件夹
--bin <<--- 编译的目标文件放在此文件夹
D:\MyWorks <<--- GOPATH 指向的位置
--src <<--- 项目源代码放置在此文件夹。!!!警告:一个常犯的错误是把 GOPATH 指向此处!!!
--HelloWorld <<--- 我们项目源代码所在的文件夹。!!!警告:一个常犯的错误是把 GOPATH 指向此处!!!
--vendor <<--- 第三方开源代码文件夹
--github.com
--...
--pkg <<--- 编译的中间文件放在此文件夹,Go编译器自动生成此文件夹
--bin <<--- 编译的目标文件放在此文件夹,Go编译器自动生成此文件夹
go常用命令
go get命令为拉取一个项目
go mod为修改go.mod文件,有三种常用用法分别是
go mod init 初始化,创建go.mod文件
go mod download 仅下载模块到本地缓存
go mod tidy 增加需要的依赖,删除不需要的依赖
测试
单元测试
测试分支不重不漏
测试粒度足够小、单一职责
幂等:每次结果一样
稳定:对环境稳定性高
mock测试
不需要依赖特定文件就可以进行测试
基准测试
测试性能