Go 八股题库

这份题库重点不是让你背底层源码,而是让你在面试里能把 Go 讲成:

我知道它的核心原理,也知道它为什么适合我项目里的实时链路、高并发服务和消费者。


一、Go 面试里你的最佳定位

你最稳的说法是:

我很多复杂业务经验是在 PHP 上沉淀的,但 Go 在我项目里不是点缀,而是主要承接实时链路、高并发处理、消费者和长生命周期服务。

这句话很重要,因为它诚实,也不会把你讲弱。


二、高频题

1. goroutine 和线程的区别

标准回答

goroutine 是 Go 运行时调度的轻量级执行单元,不等同于操作系统线程。线程是 OS 级别资源,切换和内存开销更大;goroutine 初始栈更小,由 Go runtime 调度到线程上执行,因此在高并发场景下成本更低。

项目里怎么讲

像消费者、批量同步、行为回传这类场景,用 goroutine 更适合做大量并发任务处理,但前提还是要做并发控制,不能无脑起。


2. Go 的 GMP 模型是什么

标准回答

  • G:goroutine
  • M:机器线程
  • P:处理器,上下文调度资源

Go runtime 通过 GMP 模型把大量 goroutine 调度到少量线程上执行,从而兼顾并发能力和资源成本。

面试更稳的说法

我不需要把 runtime 源码背下来,但要理解它为什么能支撑大量并发 goroutine。


3. channel 是什么,有缓冲和无缓冲有什么区别

标准回答

channel 是 goroutine 之间通信和同步的一种机制。

  • 无缓冲 channel:发送和接收必须同步配对
  • 有缓冲 channel:在缓冲区未满前发送不会阻塞,在缓冲区未空前接收不会阻塞

项目里怎么讲

我更关注 channel 的同步语义和限流作用,不会为了用 channel 而用。像 worker pool、任务分发、结果汇总这类场景比较适合。


4. select 是什么

标准回答

select 用于同时监听多个 channel 的收发操作,哪个 case 先就绪就执行哪个。如果多个同时就绪,会随机选择一个;如果都没就绪,可以配合 default

项目里怎么讲

在处理多个异步结果、超时控制和取消机制时,select 很常用。


5. channel close 后会怎样

标准回答

  • 关闭后的 channel 不能再发送数据,发送会 panic
  • 关闭后的 channel 仍然可以接收,直到缓冲区读完
  • 接收完后继续读会得到零值和 ok=false

6. context 是什么,为什么重要

标准回答

context 用于在请求链路中传递超时、取消信号和少量上下文数据。尤其在微服务、HTTP 调用、数据库调用、Go 并发任务里,context 是控制请求生命周期的重要工具。

项目里怎么讲

Go 在实时链路和消费者场景里,如果没有 context 做超时和取消,长链路任务很容易失控。


7. mutex、rwmutex、atomic 分别适合什么场景

标准回答

  • mutex:简单互斥保护
  • rwmutex:读多写少场景下允许并发读
  • atomic:适合简单数值或状态位的原子操作

面试更稳的说法

不是 atomic 越底层越高级,而是要看场景。复杂共享结构还是锁更清晰。


8. 为什么 map 并发不安全

标准回答

Go 原生 map 在并发读写时没有内部同步保护,并发写或者并发读写可能导致 panic 或数据不一致,因此需要自己加锁或使用 sync.Map

追问:sync.Map 适合什么场景

适合读多写少、key 相对稳定的场景,不适合所有业务 map 一律替换。


9. slice 和 array 的区别

标准回答

  • array 长度固定,是值类型
  • slice 是对底层数组的轻量抽象,包含指针、长度、容量,更灵活

追问:slice 扩容原理

扩容时会分配更大的底层数组并拷贝数据。不同版本 Go 的扩容策略细节不完全一样,但总体是小容量时倍增,大容量时增长比例变缓。


10. defer、panic、recover 分别做什么

标准回答

  • defer:延迟执行,常用于资源释放、解锁、日志
  • panic:程序异常中断
  • recover:在 defer 中捕获 panic,避免程序直接崩溃

面试更稳的说法

业务代码里不应该滥用 panic,把 panic 当普通错误处理;panic 更适合不可恢复的严重异常。


11. Go 的 interface 底层大概怎么理解

标准回答

interface 本质上保存两部分:

  • 类型信息
  • 数据指针

空接口和非空接口的内部结构略有差异,但核心都是通过运行时类型信息决定如何调用具体实现。

常见追问:为什么会有 nil interface 坑

因为“接口本身为 nil”和“接口里装的是一个 typed nil”不是一回事。


12. Go GC 你怎么理解

标准回答

Go GC 是并发标记清扫为主的垃圾回收机制,目标是在尽量控制停顿时间的同时回收不再使用的对象。面试里不用背太深源码,但要知道:

  • 会有 GC 开销
  • 高分配场景要关注对象创建和逃逸
  • 长生命周期服务更要关心内存行为

13. 什么是逃逸分析

标准回答

编译器会分析变量是否可以分配在栈上,如果变量在函数外部还会被引用,就可能逃逸到堆上。堆分配更多,GC 压力也更大。

项目里怎么讲

高并发服务里,我会注意不要频繁创建大对象、避免不必要的堆分配。


14. worker pool 为什么常见

标准回答

worker pool 的核心价值是控制并发度,避免无上限创建 goroutine,把任务放进队列,由固定数量的 worker 消费。

项目里怎么讲

像 Kafka 消费、批量回传、并发请求外部接口这类场景,用 worker pool 比无脑起 goroutine 更稳。


15. Go 里怎么做超时、重试和限流

标准回答

  • 超时:context.WithTimeout
  • 重试:控制次数、间隔、幂等前提
  • 限流:令牌桶、漏桶、并发控制、队列控制

面试更稳的说法

真正重要的不是“有重试”,而是重试是否幂等、是否会放大故障、是否配合超时与熔断。


16. 你项目里 Go 主要用在哪里

这是你很可能会被问到的。

推荐回答

我项目里 Go 主要不是做普通后台 CRUD,而是承接更适合服务化和高并发的部分。比较典型的是推广 ROI 这条线,Go 主要用在点击和行为数据处理、Kafka 消费者、实时回传、批量任务和部分长链路服务;另外像一些高并发、脚本耗时重的能力,也会从 PHP 侧迁到 Go。


三、Go 面试里你最该主动讲的点

1. 为什么这块要用 Go,不继续用 PHP

你可以说:

不是为了换语言,而是因为实时链路、高并发处理、消费者和长生命周期服务更适合 Go。PHP 更适合复杂业务规则和后台系统,两边在系统里是分工关系。

2. 你不是“只会背原理”

你可以说:

我对 Go 的理解更偏工程落地,比如并发怎么控、任务怎么拆、消费者怎么稳、服务怎么治理。


四、Go 继续追问时的答法

追问 1:Go 怎么保证高并发一定更好

可以答:

Go 不是天然就比别的快,关键还是看场景。它在 goroutine、channel、runtime 调度、常驻服务和资源利用率上更适合做消费者、实时链路和高并发任务。

追问 2:Go 服务如果积压了怎么办

可以答:

先看积压发生在哪一层,是消费速度不够、下游慢、重试过多,还是分区不合理。再决定是扩 consumer、优化处理逻辑、增加限流还是拆分链路。

追问 3:你在 Go 项目里怎么做可观测性

可以答:

我比较关注 traceId、关键日志、消费延迟、失败数、重试数和外部依赖超时。高并发系统如果没这些,排查会很痛苦。


五、你复习 Go 最该背的 12 个点

  1. goroutine 和线程区别
  2. GMP 模型
  3. channel
  4. select
  5. close 后行为
  6. context
  7. mutex / rwmutex / atomic
  8. map 并发问题
  9. slice 扩容
  10. defer / panic / recover
  11. interface / nil 坑
  12. worker pool / 超时 / 重试 / 限流