我们知道,Go 语言部署简单,自带完善的工具链,不仅容易上手,而且执行性能非常好,已经被越来越多的人当成主要的编程语言。
而我当初也算被 Go 的简单高效所打动。它不仅部署方便,自带完善的工具链,特别是 Go 在处理并发场景上表现出的独特性能,更是让我着迷。
相对于 Java 语言的繁琐编码,和为了应用设计模式而做的大量冗长设计, Go 提供了便利的并发编程方式 -- 简简单单的语句,就可以创建多个 goroutine 执行并发任务。此外,Go 还提供了独特的 Channel 类型,很容易实现 goroutine 之间的数据交流。
所以,入门 Go 并发编程很容易,即使是初学者,要写一个用 goroutine 异步输出 “Hello World” 的例子,也能不费吹灰之力。可以说,只要是用 Go 开发的大型应用程序,并发是必然要采用的技术。虽然上手简单,但想真正学好、用好 Go,就没那么容易了,比如:用并发方式实现的程序,有时候莫名 panic 或者死锁了,排查起来非常困难,等等。
这里,分享给你一张 Go 并发编程知识地图,里面涵盖了两条知识主线,按图索骥的学习,可以更高效地上手。首先,你要了解各种并发编程的技术,建立起丰富的并发原语库。其次,在学习层面,通过“基础用法、实现原理、易错场景、知名项目中的 Bug” 4 步法,掌握每种并发原语的实现机制和适用场景。Go 中有个大方向,就是任务编排用 Channel,共享资源保护使用传统并发原语。但实际上,同一场景可能会有多个适用的并发原语,想要选出其中最合适的,就要弄清每种并发原语的适用场景,千万不要被网上的一些文章误导,万事皆用 Channel。当你深入 Go 并发原语的源代码,会发现很多独到的设计,比如 Mutex 为了公平性考量的设计、sync.Map 为提升性能的设计,以及很多并发原语的异常状况处理方式。这些异常状况,常常是并发编程中程序 panic 的原因。上面这些经验和方法,是我从晁岳攀(鸟窝)的专栏《Go 并发编程实战课》中学到的,之前就一直默默关注他的博客,还在 Go 语言线下大会上听过他的分享。所以,那会儿得知他出了个专栏,我第一时间就订阅了。在专栏中,他深入讲解了 Go 并发编程的知识点,和并发原语的实现原理及使用技巧,通过 20 个大型项目的真实踩坑案例和解决方案,带你掌握分布式场景中并发问题的应对策略,彻底攻克并发编程各类难题。现在专栏已经 1.5W 人学过了,口碑和流量就是内容最好的证明:
我学了两遍,收获很大。
在知识主线层面,这门课程的核心内容设计了 5 个模块:
基本并发原语:在这部分,主要介绍 Mutex、RWMutex、Waitgroup、Cond、Pool、Context 等标准库中的并发原语,这些都是传统的并发原语,在其它语言中也很常见,是我们在并发编程中常用的类型。
原子操作:在这部分,介绍了 Go 标准库中提供的原子操作。原子操作是其它并发原语的基础,学会了你就可以自己创造新的并发原语。Channel:Channel 类型是 Go 语言独特的类型,因为比较新,所以难以掌握。但是别怕,我会带你全方位地学习 Channel 类型,你不仅能掌握它的基本用法,而且还能掌握它的处理场景和应用模式,避免踩坑。扩展并发原语:目前来看,Go 开发组不准备在标准库中扩充并发原语了,但是还有一些并发原语应用广泛,比如信号量、SingleFlight、循环栅栏、ErrGroup 等。掌握了它们,就可以在处理一些并发问题时,取得事半功倍的效果。分布式并发原语:分布式并发原语是应对大规模的应用程序中并发问题的并发类型。这里主要介绍了使用 etcd 实现的一些分布式并发原语,比如 Leader 选举、分布式互斥锁、分布式读写锁、分布式队列等,在处理分布式场景的并发问题时,特别有用。要知道,在面对一些复杂场景时,现有的并发原语远远并不足以应对。只有当你具备了独立创造自己需要的并发原语的能力,才能真正得心应手。而这个专栏,就是你的不二之选,口碑也不错,截了些评价供你参考:
Go 并发编程的世界确实纷繁复杂,涉及到的内容非常多。你可以把它看作是一个江湖,如果你想拥有极强的作战力,就要拥有足够多的武器,并且修炼内功。这门课,就是你的修炼山洞,鸟窝大佬准备了应有尽有的宝藏,等待着你来挖掘。感兴趣的朋友也可以点击「阅读原文」,开启并发编程功力提升之旅!