D
AI
学习工作台
8 周后端冲刺2026-05-222 分钟阅读

Goroutine 与 Channel

GMP 概览、无缓冲/有缓冲 channel、关闭语义

8周冲刺week2Gogoroutinechannel记笔记标记疑惑

为何需要 goroutine

Go 用 轻量级协程 简化并发:栈初始几 KB,调度在用户态。后端服务高并发连接、worker pool、pipeline 都建立在 goroutine + channel 之上。

go func() {
    fmt.Println("async")
}()

注意:循环里 go func 要传参,避免闭包捕获循环变量。

for i := 0; i < 3; i++ {
    go func(n int) { fmt.Println(n) }(i)
}

GMP 面试答法

  • G:用户态任务。
  • M:内核线程,真正执行代码。
  • P:本地 run queue、mcache;GOMAXPROCS 限制 P 数量。
阻塞 syscall 时 M 可能与 P 分离,G 迁移到其他 M。不必背源码细节,能说清 为何 goroutine 比 OS 线程便宜 即可。

channel 基础

ch := make(chan int)      // 无缓冲
buf := make(chan int, 10) // 有缓冲,满则 send 阻塞

select 多路复用 + default 非阻塞:

select {
case v := <-ch:
    fmt.Println(v)
case ch <- 1:
case <-time.After(time.Second):
}

关闭 channel

发送方 应 close;多个消费者可用 for v := range ch 直到关闭。

close(ch)
v, ok := <-ch
if !ok { / drained / }

用 channel 作 信号(struct{})通知退出:

done := make(chan struct{})
go worker(done)
// ...
close(done)

常见模式

  • Worker pool:jobs channel + results channel + 固定 N 个 worker。
  • Fan-out / Fan-in:多 goroutine 读同一 channel;merge 用 WaitGroup + 单输出 channel。
  • Pipeline:stage 间 channel 串联。
  • 反模式

    • 用 channel 当 mutex(应使用 sync.Mutex)。
    • 无缓冲 + 单 goroutine 自己 send recv 死锁。
    • 泄漏:goroutine 永久阻塞在 recv,无消费者。

    与 Week 2 衔接

    week02-go-mutex-context 讲共享内存 + 取消;channel 适合 传递所有权,mutex 适合 保护共享状态。选型口诀:用 channel 传递数据或事件,用 mutex 保护计数器/map。

    结合 /chapters/computer-network 可类比:channel 像带同步的消息队列,但更轻、进程内。

    实战巩固与面试表达

    本篇属于 8 周冲刺 week02-go-goroutine-channel 主题。复习时先闭卷回答 frontmatter 中三张 flashcard,再展开口述两个「为什么」:为什么这种方案能 work、边界失败时如何降级。与相邻章节对照:算法篇强调复杂度与模板,Go 篇强调工程默认写法,中间件篇强调线上故障案例。

    动手与自检清单

    用 25 分钟限时做 1 道相关练习题或画出一张架构/数据结构示意图;用 5 分钟写 STAR 片段说明你在项目里是否用过类似技术。记录 3 个面试追问及你的标准答法,存入 /zh/notebook/master-plan 笔记。若某点不熟,回到对应 /chapters 交互 Lab 重新走一遍流程,比死记卡片更有效。

    易错点提醒

    避免只背名词不会画图;避免只说优点不谈 trade-off(性能、一致性、运维成本至少提一项);避免把学习 Demo 说成百万 QPS 生产。回答时使用「场景 → 方案 → 结果 → 反思」四段式,体现工程成熟度。

    自检

    手写:N 个 worker 求 slice 平方和;用 context 取消(下一篇)。能解释 buffered size 对吞吐与延迟的影响。

    知识卡片

    问题

    GMP 模型各代表什么?

    点击翻转查看答案

    答案

    G goroutine、M OS 线程、P 逻辑处理器(调度上下文);P 绑定 M 执行 G 队列,实现 M:N 调度。

    问题

    无缓冲 channel 同步语义?

    点击翻转查看答案

    答案

    send 阻塞直到另一 goroutine recv,反之亦然;用于 handoff 同步,保证 happens-before。

    问题

    关闭 channel 后 recv 行为?

    点击翻转查看答案

    答案

    仍可 recv 已发送值;取完后得到零值且 ok=false;向已关闭 channel send 会 panic。