-
Go语言的GMP调度模型由G(goroutine)、M(操作系统线程)、P(逻辑处理器)三部分组成,通过本地队列、全局队列以及工作窃取机制实现高效并发调度。G代表待执行的协程任务,M负责真正执行代码,P维护可运行G的队列并与M绑定。每个P优先执行本地队列中的G,当队列为空时会从全局队列或其他P中窃取任务实现负载均衡。调度器结合抢占式机制与netpoll网络轮询器,避免长时间占用CPU。GOMAXPROCS决定P的数量,从而控制并发度。相似问题及优化建议:GOMAXPROCS设置多少合适?一般建议
-
WaitGroup通过计数器和信号量实现协程同步。Add增加计数,Done减少计数,当计数为0时唤醒等待的goroutine。底层使用atomic操作保证线程安全。相似问题及优化建议:WaitGroup使用错误会导致什么问题?如何避免负数计数?协程同步有哪些方式?
-
select在多个case满足条件时通过伪随机顺序遍历case列表,避免饥饿问题。runtime会对case顺序进行打乱,并检测可执行分支。若无可执行case且无default,则当前goroutine进入等待队列。该机制保证并发公平性。相似问题及优化建议:select是否绝对公平?select如何避免阻塞?如何优化复杂select结构?
-
Once通过atomic标志位和Mutex结合实现。首次调用执行函数并设置标志位,后续调用直接返回,保证线程安全。相似问题及优化建议:Once是否可以重置?如何实现可重置的Once?单例模式如何实现?
-
goroutine泄漏通常由channel未关闭或阻塞操作未退出导致。可以通过pprof查看goroutine数量,分析堆栈信息定位未退出的协程。常见原因包括无限循环、阻塞IO未取消等。相似问题及优化建议:如何优雅关闭goroutine?context如何防止泄漏?高并发如何控制协程数量?
-
Go语言的垃圾回收采用并发三色标记清除算法,实现低延迟GC。GC过程包括标记、清除两个阶段,通过三色标记法区分对象状态,并使用write barrier保证并发安全。Go从1.5版本后实现并发GC,大幅降低STW时间。相似问题及优化建议:如何降低GC频率?如何查看GC日志?如何减少内存分配提升性能?使用对象复用或sync.Pool。
-
json.Unmarshal到interface{}时数字默认float64。核心结论符合JSON规范需手动转换类型可使用Decoder自定义解析详细分析JSON标准未区分整数与浮点。Go统一解析为float64以保证兼容性。常见问题如何优化?定义具体结构体避免interface解析。
-
atomic基于CPU原子指令实现无锁更新。核心结论使用CAS指令避免上下文切换适用于简单状态更新详细分析atomic通过Compare-And-Swap保证操作不可分割。适合计数器等轻量场景。常见问题如何优化?复杂逻辑仍应使用互斥锁。
-
strings.Builder可减少内存分配次数。核心结论避免频繁创建新字符串底层维护可扩展缓冲区性能优于+拼接详细分析字符串不可变,每次拼接都会产生新对象。Builder通过复用缓冲区提升效率。常见问题如何优化?高频拼接场景使用Builder或bytes.Buffer。
-
GOMAXPROCS决定同时运行Go代码的最大CPU核心数。核心结论默认等于CPU核心数影响并行而非并发数量设置过低会限制性能详细分析GOMAXPROCS控制P的数量,从而决定多少goroutine可真正并行执行。合理设置可提升CPU密集型任务效率。常见问题如何优化?一般保持默认值,特殊场景可压测调整。
-
逃逸到堆上的对象会增加GC压力。核心结论局部变量可能逃逸堆分配成本更高影响整体性能详细分析编译器通过静态分析决定变量分配位置。可使用go build -gcflags查看逃逸信息。常见问题如何优化?避免返回局部变量地址或接口转换导致逃逸。
-
Go语言中defer的执行顺序是如何保证的?Go中的defer采用栈结构(后进先出)。多个defer按照注册顺序入栈,在函数返回时按相反顺序执行。即最后声明的defer会最先执行,这种机制确保资源释放顺序可控。
-
访问未初始化指针或接口会触发nil pointer dereference。核心结论必须判空避免未初始化指针调用方法可使用防御式编程详细分析指针变量未指向实际对象时访问会触发运行时panic。常见于结构体指针未初始化或接口未赋值。常见问题如何优化?在使用前检查指针是否为nil,必要时初始化对象。
-
map遍历顺序在每次运行时都会随机化。核心结论防止依赖固定顺序提高安全性底层哈希结构决定详细分析Go在遍历map时会随机起始bucket。同一程序多次执行结果可能不同。常见问题如何优化?如需有序遍历,应先提取key并排序。
-
goroutine未退出会长期占用资源。核心结论阻塞在channel读写未监听context取消无限循环无退出条件详细分析泄漏的goroutine无法被GC回收。长期运行会导致内存与调度压力增加。常见问题如何优化?设计明确退出机制与超时控制。