Go语言进阶 | 青训营笔记

64 阅读2分钟

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

一. 重点内容

  • Go语言进阶

  • Go语言依赖管理

二. 知识点介绍

1. Go语言进阶

  • 并发 vs 并行:Go语言可以充分发挥多核优势,高效运行。
并发: 多线程程序在一个核的CPU上运行,在同一时间点,任务不会同时运行
并行:多线程程序在多个核的CPU上运行,在统一时间点,任务同时运行
  • 协程:用户态,轻量级线程,栈MB级别
// 快速打印hello: 0-4
for i := 1; i < 5; i++ {
    go func(j int) {
        // 字符串和数字不能直接相加
        // 需要fmt.Sprint()函数return回字符串再相加
        println("hello" + fmt.Sprint(j))
    }(i)
    time.Sleep(time.Second)
}
  • CSP:提倡通过通信共享内存而不是通过共享内存实现通信

CSP.png

  • 创建Channel
// 无缓冲
make(chan int)
// 有缓冲
make(chan int, 2)

Channel.png

  • 并发安全:多个线程操作同一个变量时,需要加锁,防止race condition
// 定义锁
var lock sync.Mutex

lock.lock()
xxxxxxxxxxx
lock.unlock()
  • WaitGroup:由于不同进程的不同效率,用time.Sleep()无法确切地掌握睡眠时间。而WaitGroup可以更加优雅的控制并发任务的同步,实际上是内置了计数器,阻塞进程直到计数器为0,即所有并发任务都已经Done。
// 定义WaitGroup
var wg sync.WaitGroup
// 添加计数器
wg.Add(delta: 5)
// 快速打印hello: 0-4
for i := 1; i < 5; i++ {
    go func(j int) {
        // 计数器减一
        defer wg.Done()
        println("hello" + fmt.Sprint(j))
    }(i)
}
// 阻塞直到计数器为0
wg.Wait()

2. Go依赖管理

  • GOPATH:项目代码依赖GOPATH下的src源码
  • GOPATH的弊端:无法实现package的多版本控制
  • Go Vendor:通过每个项目引入依赖的副本,解决了多个Project需要多一个package依赖冲突的问题
  • Go Vendor的弊端:无法控制依赖的版本,出现不兼容的问题。
  • Go Module:定义版本规则和管理项目依赖关系
  • 依赖管理三要素
// go.mod
配置文件,管理依赖
// Proxy
中心仓库管理依赖库
// go get/mod
本地工具