Golang进阶 | 青训营笔记

72 阅读2分钟

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


下面主要是我个人听课时的一些笔记

个人笔记

  • 使用WaitGroup优雅地实现协程同步

    主要是三个方法

    • Add(delta int)

      会使计数器加delta

    • Done()

      会使计数器减一

    • Wait()

      阻塞直到计数器为零

    实际使用:在开启n个协程的时候Add(n)

    在每个协程结束都defer Done()

    在主协程使用Wait()阻塞等待子协程结束

  • Golang中的互斥锁和原子操作

    互斥锁的实现主要是基于sync.Mutex和和sync.RWMutex

    原子操作的实现依赖于sync/atomic

    这里补充一下原子操作和互斥锁的区别:

    • 原子操作:

      所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (线程切换)。

      为了实现这样的严谨性,原子操作仅会由一个独立的CPU指令代表和完成。原子操作是无锁的,常常直接通过CPU指令直接实现。事实上,其它同步技术的实现常常依赖于原子操作。

    • 互斥锁:

      互斥锁用来保证临界区的安全性,确保在并发场景下,同一时刻,只会有一个线程持有锁,拥有访问临界区的权限。

  • Golang提倡通过通信来共享内存,而不是通过共享内存来通信

    前者就是channel

    尽管不提倡后者,但golang也支持后者,即通过sync.Mutex来实现对临界区的并发安全保证

  • Golang中的依赖管理

    GOPATH→Go Vendor→Go Module

    • GOPATH

      GOPATH是Go语言支持的一个环境变量,其value是Go项目的工作区

      弊端:无法实现package的多版本控制

    • Go Vendor

      Vendor 是当前项目中的一个目录,其中存放了当前项目依赖的副本(等于是给每个项目添加了其依赖的副本)

      弊端:

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

      最新的依赖管理方式

      新建项目后

      go mod init projectName

      go mod tidy

    在上述Golang的多种依赖管理方式的历史遗留背景下,体会到VSCode很难优雅地对Golang项目进行依赖管理,还得是Goland

参考