Go select 详解
一句话结论 select 是 Go 的多路复用语句——同时监听多个 Channel 操作,哪个先就绪执行哪个。多个同时就绪则伪随机选择一个,避免饿死。配合 default 可实现非阻塞操作。 核心原理 执行机制 1. 对所有 case 的 Channel 上锁(按地址排序防死锁) 2. 检查是否有
一句话结论 select 是 Go 的多路复用语句——同时监听多个 Channel 操作,哪个先就绪执行哪个。多个同时就绪则伪随机选择一个,避免饿死。配合 default 可实现非阻塞操作。 核心原理 执行机制 1. 对所有 case 的 Channel 上锁(按地址排序防死锁) 2. 检查是否有
一句话结论 panic 中断当前 Goroutine 的正常执行,沿调用栈向上传播并执行沿途的 defer。recover 只能在 defer 中捕获 panic,阻止程序崩溃。 核心原理 panic 传播 func C() { panic("error in C") } func B() { C(
一句话结论 Go sync.Mutex 是CAS + 信号量实现的互斥锁,有正常模式和饥饿模式两种状态。正常模式下等待者自旋+排队,饥饿模式下按 FIFO 直接交接,防止尾端 Goroutine 饿死。 核心原理 底层结构 type Mutex struct { state int32 /
一句话结论 Go Map 是拉链法的哈希表,由一个 hmap 结构体 + 多个 bmap(bucket)组成。每个 bucket 存 8 个键值对,冲突通过溢出桶解决,扩容采用渐进式搬迁避免一次性停顿。 核心原理 底层结构 hmap { count int // 元素个数
一句话结论 Go 原生 Map 不支持并发读写——并发读写会触发 fatal error 直接崩溃。并发场景有三种方案:Mutex + map(通用)、sync.Map(读多写少)、分片加锁 Map(高并发写入)。 核心原理 为什么原生 Map 不并发安全 Go 设计者刻意不在 Map 内部加锁——
一句话结论 Go 的 interface 是一个双指针结构(类型指针 + 数据指针),分为 eface(空接口 interface{})和 iface(有方法的接口)。接口的 nil 判断需要动态类型和动态值都为 nil。 核心原理 底层结构 eface(空接口 interface{}): ┌─
一句话结论 GMP 是 Go 运行时调度器的核心——G(Goroutine)是执行单元,M(OS 线程)是执行者,P(逻辑处理器)是执行所需的资源上下文。P 的数量由 GOMAXPROCS 决定,M 的数量由 Go Runtime 动态管理。 核心原理 G、M、P 分别是什么
一句话结论 defer 在函数返回前执行,遵循后进先出(LIFO)栈序。defer 的参数在声明时求值(不是执行时),与 return 的交互由命名返回值决定。 核心原理 执行顺序:LIFO func demo() { defer fmt.Println("1") defer fmt
一句话结论 Context 用于在 Goroutine 之间传递取消信号、截止时间和请求范围元数据。不是用来传普通业务参数的。取消是协作式的——Context 只发信号,不能强制终止 Goroutine。 核心原理 Context 接口 type Context interface { De
一句话结论 Channel 的阻塞取决于是否有缓冲和对方是否就绪。nil Channel 永久阻塞,已关闭 Channel 写入 panic、读取返回零值。谁写谁关——接收方关闭 Channel 极易 panic。 核心原理 阻塞条件全表