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

108 阅读3分钟

前言

深入学习Go语言,进行Go语言的进阶和项目实战

目录

  1. 语言进阶
    • 从并发编程的视角待大家了解Go高性能的本质。
  2. 依赖管理
    • 了解GO语言依赖管理的演进路线。
  3. 测试
    • 从单元测试实践出发。提升大家的质量意识。
  4. 项目实战
    • 通过项目需求、需求拆解、逻辑设计、代码实现带领大家感受下真实的项目开发。

1.Go语言进阶

1.1 并发编程

image.png

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

image.png

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

  • Go可以发挥多核优势,高效运行

【协程Goroutine】

image.png
  • 协程:用户态,轻量级线程, KB级别\color{red}{栈KB级别}
  • 线程:内核态,线程跑多个协程, MB级别\color{red}{栈MB级别}

Go可以并发去跑多个协程

【快速打印】

乱序的输出

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

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

1.2 CSP

image.png
  • 提倡通过通信共享内存而不是通过共享内存而实现通信

1.3 Channel

image.png

make(chan元素类型,[缓冲大小])

  • 无缓冲通道 ---> make(chan int)
  • 有缓冲通道 ---> make(chan int,2)

A子协程发送O~9数字 B子协程计算输入数字的平方 主协程输出最后的平方数

func CalSquareo {
    src :=make(chan int)
    dest := make(chan int3)
    go funcO {
        defer close(src)
        for i :=0; i< 10;i++ {
            src <- i
        }
    }()
    go func() {
        defer close(dest)
        for i := range src {
            dest <- i * i
    }()
    for i := range dest {
        //复杂操作
        println(i)
    }
}

1.4 并发安全 Lock

image.png

1.5 WaitGroup

image.png
  • 计数器

开启协程+1;执行结束-1;主协程阻塞直到计数器为0。

2. 依赖管理

2.1 背景

image.png
  • 工程项目不可能基于标准库0~1编码搭建
  • 管理依赖库

2.2 Go依赖管理演进

GOPATH ---> Go Vendor ---> Go Module

  • 不同环境(项目)依赖的版本不同
  • 控制依赖库的版本

[GoPath]

image.png
  • 环境变量$GOPATH
  • 项目代码直接依赖src下的代码
  • go get下载最新版本的包到src目录下

弊端:

image.png
  • 场景: A和B依赖于某一package的不同版本。
  • 问题: 无法实现package的多版本控制

[Go Vendor]

  • 项目目录下增加vendor文件,所有依赖包副本形式放在$ProjectRoot/vendor
  • 依赖寻址方式:vendor => GOPATH
image.png

通过每个项目引入一份依赖的副本, 解决了多个项目需要同一个 package 依赖的冲突问题。

image.png

问题:

  • 无法控制依赖的版本。
  • 更新项目又可能出现依赖冲突,导致编译出错。

[GO Module]

  • 通过go.mod文件管理依赖包版本
  • 通过go get/go mod指令工具管理依赖包

终极目标:定义版本规则和管理项目依赖关系

2.3 管理依赖三要素

  1. 配置文件,描述依赖 ---> go.mod
  2. 中心仓库管理依赖库 ---> Proxy
  3. 本地工具 ---> go get/mod

【依赖配置——go mod】

image.png

依赖标识:[Module Path][Version/Pseudo-version]

【依赖配置——version】

image.png

【依赖配置——indirect】

image.png

A->B->C

  • A->B 直接依赖
  • A->C 简介依赖

【依赖配置——incompatible】

image.png
  • 主版本2+模块会在模块路径增加/vN后缀。
  • 对于没有go.mod文件并且主版本2+的依赖,会+incompatible

【依赖图】

image.png

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

A. v1.3

B. v1.4(正确)

C。A用到c时用v1.3编译,B用到c时用v1.4编译

【依赖分发——回源】

image.png
  • 无法保证构建稳定性
    • 增加/修改/删除软件版本
  • 无法保证依赖可用性
    • 删除软件
  • 增加第三方压力
    • 代码托管平台负载问题

【依赖分发——Proxy】

image.png

Proxy会缓存原栈的内容

【依赖分发——变量 GOPROXY】

GOPROXY="proxy1.cn, https:[/proxy2.cn ,direct”

服务站点URL列表,“direct”表示源站

Proxy1 ---> Proxy2 ---> Direct

【工具——go get】

image.png

【工具——go mod】

image.png