Go 语言进阶学习 | 青训营笔记

74 阅读4分钟

这是我参与「第五届青训营」伴学笔记创作活动的第2天。

前言

第二天的课程总结下来主要围绕了三个方面:并发编程、模块管理、测试,简单整理下今日的学习笔记和收获。

知识点内容

1.并发编程

协程

Go有自己的高并发调度模型,从而可以充分发挥多核优势,高效运行。这里还需要提到一个对我来说较新的概念-协程,它是用户态,一种轻量级线程,栈KB级别。而平时Java中常用的线程属于内核态,比较重,栈MB级别。Golang开启协程只需要在调用的函数前加上go关键字就可以开启协程运行,实例如下:

func hello(i int) {
   println("hello goroutine :" + fmt.Sprint(i))
}

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

输出结果是乱序输出,说明程序是并行执行的。

Channel缓冲通道

Golang提倡通过通信共享内存,通过channel可以直接在进程/线程之间传递资源,这里又分为无缓冲通道和有缓冲通道。

⽆缓冲的channel: 1.jpg

第 1 步,两个 goroutine 都到达通道,但哪个都没有开始执⾏发送或者接收。

第 2 步,左侧的 goroutine 将它的⼿伸进了通道,这模拟了向通道发送数据的⾏为。这时,这个 goroutine 会在通道中被锁住,直到交换完成。

第 3 步,右侧的 goroutine 将它的⼿放⼊通道,这模拟了从通道⾥接收数据。这个 goroutine ⼀样也会在通道中被锁住,直到交换完成。

第 4 步和第 5 步,进⾏交换,并最终,在第 6 步,两个 goroutine 都将它们的⼿从通道⾥拿出来,这模拟了被锁住的 goroutine 得到释放。两个 goroutine 现在都可以去做其他事情了。

有缓冲的channel 2.jpg 第 1 步,右侧的 goroutine正在从通道接收⼀个值。

第 2 步,右侧的这个 goroutine独⽴完成了接收值的动作,⽽左侧的go routine 正在发送⼀个新值到通道⾥。

第 3 步,左侧的goroutine还在向通道发送新值,⽽右侧的 goroutine 正在从通道接收另外⼀个值。这个步骤⾥的两个操作既不是同步的,也不会互相阻塞。

最后,所有的发送和接收都完成,⽽通道⾥还有⼏个值,也有⼀些空间可以存更多的值。

Lock和WaitGroup

Lock即为锁,和Java中的锁类似,通过给协程加锁实现并发安全操作。

WaitGroup即为线程同步,它的内部维护了一个计数器,主要包含三个主要方法Add()、Done()、Wait()来维护协程之间的同步问题。

2.依赖管理

Go Modules

Go modules是Go的依赖解决⽅案,它解决了Go⻓久以来的依赖管理问题;“淘汰”现有的 GOPATH 的模式;统⼀了社区中的其它的依赖管理⼯具(提供迁移功能),是目前主流的go构建项目采用的模式。

GOPATH

而GOPATH工作模式的弊端则是⽆版本控制概念、⽆法同步⼀致第三⽅版本号、⽆法指定当前项⽬引⽤的第三⽅版本号。

go mod

通过go.mod文件管理依赖包版本,有些类似于Java中的Maven。首先,需要配置下环境:通过go env -w GO111MODULE=on来开启go modules模式;修改GOPROXY为国内下载地址,如阿里云、七牛云,这里类比于我们在安装Linxu虚拟机之后会配置下载源为国内。

思考:如果某个项目依赖了A、B两个项目,A和B又分别依赖了C的1.3和1.4版本,最终编译时使用的C版本为哪个?答案是1.4,go会选择最低的兼容版本。

3.测试

单元测试

规则:1.所有测试文件以_test.go结尾;2.func TestXxx(*testing.T);3.初始化逻辑放到TestMain中。没有Java做测试方便,Java只需要一个Junit注解就可以了,希望以后能有更简洁的测试方案。

mock测试

有很多优秀的mock测试包,今天的课程里用到的是monkey,通过mock打桩测试可以使得我们的测试不再依赖于本地文件,这个对我来说算是个新知识,以前只做过单元测试,这个是第一次接触。

基准测试

go内置的测试框架提供了基准测试,主要用于分析系统性能。

小结

今天最大的收获就是Gin框架的学习,通过官网的文档,我花了一小时快速入门了下,第一次切身感受到了go开发的好处-又轻又快。而且仅仅只是go和gin内置的方法就已经足够一个简单网站开发的所有需求,相比于Java工程需要大量的导包。目前在我看来,至少在服务端和后端开发上,我认为go就是未来! 01.jpg

参考文档

web框架 - Gin