Go 语言进阶与依赖管理 | 青训营笔记

75 阅读3分钟

1、语言进阶--并发编程

1.1 Goroutine(协程)

并发与并行

并发:多线程程序在一个核的cpu上的运行

QQ图片20230513205426.png

并行:多线程程序在多个核的cpu上运行

QQ图片20230513205430.png

而go语言可以充分发挥多核性能,解决高并发问题

线程与协程

线程:内核态,线程跑多个协程,栈MB级

协程:用户态,轻量级线程,栈KB级

如何开启协程

实例:快速打印hello groroutine

go语言开启协程的方法就是在函数名前加一个go

package main

import (
   "fmt"
   "time"
)

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

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

func main() {
   closure()
}

time.Sleep(time.Second)的作用是暴力阻塞,保证子协程结束前主协程不退出,输出是乱序,可以知道,是并行打印的。

2、依赖管理

在开发时,我们不能所有东西都从0开始,而是更多的使用已经开发测试好,封装好的组件,专注于业务逻辑

GO的依赖管理经历了3个阶段GOPATH -> GO VENDER -> GO MODULE

GO MODULE

GO 1.16默认开启

通过go.mod文件管理依赖包版本

通过go get/go mod指令工具管理依赖包

依赖管理的三要素:

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

2.中心仓库管理依赖库 Proxy

3.本地工具 go get/mod

类似java中maven对依赖的管理,导入依赖

依赖配置-go.mod

QQ图片20230513210603.png

依赖管理基本单元:标识了模块路径

单元依赖由两部分组成:模块路径和版本号

依赖配置-version

1.语义化版本

${MAJOR}.${MINOR}.${PATCH}

MAJOR:大版本,不同MAJOR可以不兼容

MINOR:新增函数与功能,相同MAJOR下的不同MINOR要兼容

PATCH:代码bug修复

如:V1.3.0

2.基于commit伪版本

vx.0.0-yyyymmddhhmmss-abcdefgh1234

中间部分是一个提交的时间戳

后面是一个12位哈希码

依赖配置-indirect

QQ图片20230513210951.png

QQ图片20230513210954.png

对于没有直接依赖的用indirect标注

依赖配置-incompatible

QQ图片20230513211132.png

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

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

依赖最低兼容版本选择

QQ图片20230513211305.png

如果X项目依赖了A、B两个项目,且A、B分别依赖了C项目的v1.3、v1.4两个版本,最终编译时所使用的C项目的版本为哪个呢?

答案是v1.4,因为go对版本的选择使用最低兼容版本,因为1.3与1.4是兼容的所以会优先选择1.4

这就是依赖最低兼容版本选择

依赖分发-回源

可以直接从github上去下载依赖,但是这样会有几个问题

1.无法保证构建稳定性增加/修改/删除软件版本,作者可以随时修改代码,导致我们本地的代码出现问题

2.无法保证依赖可用性删除软件,作者可能会删除

3.增加第三方压力,代码托管平台负载问题

依赖分发-Proxy

QQ图片20230513211434.png

Proxy会缓存一些软件内容,缓存的版本不会改变,通过这个中间站点,保证了代码稳定性

我们可以直接去Proxy去选择一些依赖

依赖分发-变量GOPROXY

通过控制GOPROXY环境变量来控制Proxy配置

GOPROXY="proxy1.cn, proxy2.cn ,direct”

是url列表,direct表示,前两个地方都没有时,会回到源站去

以下是依赖查找路径示意图:

QQ图片20230513211603.png

工具1-go get

image.png

默认加@update,拉取最新版本

工具2-go mod

image.png

每个项目开始前init去初始化创建一个go.mod文件

经过代码的修改,可能有些依赖已经不需要了,可以每次上传代码时进行tidy操作,来更新依赖