開篇詞|想真正學會 Go 併發,建議這樣學
你好,我是晁嶽攀(鳥窩),曾在微博研發平台架構中心擔任資深架構師,也是微服務框架 rpcx 的作者。歡迎來到這份《Go 併發程式設計實戰》學習內容。
這份內容的目標,不只是教你「會用 goroutine / channel」,而是幫你建立一套可以在實務專案裡穩定解題的併發思維。
為什麼要學 Go 併發?
我過去長期使用 Java 做專案開發,後來投入 Go,原因很直接:Go 在併發場景的開發體驗和執行效率,真的很有優勢。
Go 的特點大致有幾個:
- 語法相對精簡,程式碼比較容易維護
- 工具鏈完整,建置與部署方便
goroutine建立成本低,適合處理大量併發任務channel讓 goroutine 之間的資料傳遞更直觀
你可以很快寫出一個會動的併發程式,但要寫得穩、寫得準、寫得不踩坑,就是另一回事了。
多數人學 Go 併發時,常卡住的地方
我把常見問題整理成 5 類:
- 不知道該選哪一種併發原語(例如
Mutex、channel、WaitGroup)。 - 好幾種做法都能解,卻不知道哪個才是比較好的解法。
- 不知道怎麼做任務編排,導致流程順序失控。
- 程式會
panic、死鎖(deadlock)或卡住,但很難除錯。 - 現成原語不夠用時,程式越寫越複雜、可讀性越差。
這些問題很正常,幾乎每個開始深入學 Go 的工程師都會遇到。
這份內容的學習方式:兩條主線
我建議用「兩條主線」來學,才不會變成零散記憶。
1) 知識主線(你要有哪些工具)
課程核心分成 5 個模組:
- 基本併發原語
Mutex、RWMutex、WaitGroup、Cond、Pool、Context等
- 原子操作(atomic)
- 併發原語的基礎能力,理解後更容易看懂底層設計
- Channel
- Go 特有的資料傳遞機制,也是任務編排的核心工具之一
- 擴充併發原語
- 例如信號量(Semaphore)、
singleflight、循環柵欄(CyclicBarrier)、errgroup
- 例如信號量(Semaphore)、
- 分散式併發原語
- 例如 Leader 選舉、分散式鎖、分散式佇列等
你可以把它想成「武器庫」:工具越完整,面對不同併發情境時越不容易硬解。
2) 學習主線(每個工具要學到什麼程度)
每個模組都建議用同一套節奏學習:
- 基本用法
- 實作原理
- 常見踩坑情境
- 真實專案中的錯誤案例(Bug)
這樣學的好處是:你不只知道 API 怎麼呼叫,也知道它為什麼會壞、壞在哪裡、怎麼避開。
學習地圖(先建立全局觀)
Go 併發程式設計學習地圖
+--------------------+ +--------------------+
| 知識主線 | | 學習主線 |
| (你要有的工具庫) | | (每個工具怎麼學) |
+--------------------+ +--------------------+
| |
v v
+--------------------------------+ +------------------+
| 基本原語 / atomic / channel / | | 用法 |
| 擴充原語 / 分散式原語 | | 原理 |
+--------------------------------+ | 易錯情境 |
| | 真實 Bug 案例 |
+----------+----------+------------------+
|
v
+---------------------------+
| 實務上能選對工具、避開坑洞 |
+---------------------------+
實務上怎麼選工具?先用這個原則
剛開始學時,可以先用這個簡化判斷:
- 任務編排:優先考慮
channel - 共享資源保護:優先考慮傳統同步原語(例如
Mutex)
但這只是入門準則,不是萬用答案。
同一個問題,常常有不只一種可行方案;真正的關鍵是:
- 原語的底層機制是什麼
- 成本在哪裡(效能、複雜度、可維護性)
- 哪些情境容易出錯
所以,不建議「什麼都用 channel」;能不能用是一回事,適不適合是另一回事。
為什麼要看原始碼與真實 Bug?
如果你只停在 API 用法,遇到邊界情況通常會很痛苦。
深入看 Go 併發原語的原始碼,你會學到很多實戰價值很高的設計,例如:
Mutex在公平性與效能上的取捨sync.Map為了提升效能做的資料結構設計- 各種異常狀況(panic、競態、死鎖)是怎麼被觸發的
而真實專案的 Bug 案例更重要,因為它能幫你建立「避坑清單」。
最後的目標:不只會用,還能組合與設計
學到後面,你的能力應該分成 3 個層次:
- 會用:知道常見併發原語的用途與基本寫法。
- 會選:面對情境能選出更合適的做法,避免誤用。
- 會設計:能組合既有原語,甚至設計新的併發解法。
能力進階示意
[會用 API] -> [看懂原理與限制] -> [選對工具] -> [組合/設計新原語]
初學 進階 實務穩定 高階
例如:
- 你可以把多個原語組合成新的控制流程(例如限制併發數量 + 等待全部完成)
- 也可以依照需求設計出標準庫沒有直接提供的解法
建議你怎麼讀這份內容
- 想補基礎:從「基本併發原語」開始
- 對
channel不熟:先讀Channel相關章節 - 已熟悉標準庫:可先看「擴充併發原語」與「分散式併發原語」
- 想快速提升實戰能力:優先看每章的「易錯情境」與「真實 Bug」
結語
Go 併發世界很大,工具也很多。真正的差別不在於你背了多少 API,而在於:
- 你是否能理解原理
- 你是否能選對工具
- 你是否能在複雜場景裡穩定解題
把這份內容當成你的練功地圖,循序建立工具庫、補齊原理、累積避坑經驗,你的 Go 併發能力會進步得很快。
如果你是和同事、朋友一起學,效果通常更好,因為很多併發問題非常適合透過 code review 和討論來釐清。