卡码笔记-最强八股文
首页
计算机基础
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
简历专栏
代码随想录 (opens new window)
首页
计算机基础
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
简历专栏
代码随想录 (opens new window)
  • 本栏必读

    • Go语言面试题专栏介绍
  • 语言基础

  • 内存管理

  • 并发编程

    • 什么是Goroutine
      • 简要回答
      • 详细回答
      • 知识图解
      • 知识扩展
    • 协程、线程、进程的区别
    • 协程如何通信
    • 怎么实现协程池
    • Goroutine创建数量有限制吗
    • Goroutine阻塞场景与调度器行为
    • 等待多个goroutine执行结果
    • 无缓冲和有缓冲channel区别
    • 关闭channel的行为与安全关闭
    • nil channel读取会发生什么
    • channel死锁场景与避免策略
    • select语句的执行机制
    • sync.Mutex正常模式与饥饿模式
    • sync.Mutex底层锁状态实现
    • sync.Map并发安全与优缺点
    • context实现超时取消控制
    • Context.Value使用场景与注意事项
  • 底层原理

# 什么是Goroutine?协程的上下文切换保存在哪?

什么是协程?

# 简要回答

协程是 Go 语言实现并发的核心机制,是用户态的轻量级线程。

与操作系统线程相比,协程启动快、内存占用低,切换开销小。

Go 运行时通过 M:N 调度模型,将多个协程映射到少量操作系统线程上,大大提高了并发效率。

协程之间通过 channel 进行通信,实现安全的数据共享。

# 详细回答

协程是 Go 语言中实现并发的基本单元,是用户态的轻量级线程。它的主要特点是轻量、高效和易于使用。与操作系统线程相比,协程的创建和切换成本极低,这使得 Go 程序可以轻松创建大量协程。

Go 语言的协程调度器采用 GPM 模型:G 代表 goroutine(协程),P 代表处理器(逻辑处理器),M 代表操作系统线程。每个 P 维护一个协程队列,M 负责执行 P 队列中的协程。当一个协程阻塞时,调度器会将其挂起,并从队列中取出另一个协程继续执行,实现高效的并发。

协程的栈空间是动态调整的,初始为 2KB,随着需要自动增长,最大可达 1GB。这种设计既节省了内存,又避免了栈溢出问题。

协程之间通过 channel 进行通信,channel 提供了一种安全的方式在协程之间传递数据,避免了传统多线程编程中的锁竞争和数据竞争问题。

# 知识图解

image

协程VS线程

image

# 知识扩展

Go 语言的协程调度器采用 GPM 模型,这是理解协程工作原理的关键。

G 代表 goroutine(协程),P 代表处理器(逻辑处理器),M 代表操作系统线程。每个 P 维护一个协程队列,M 负责执行 P 队列中的协程。

当一个协程阻塞时,调度器会将其从当前 M 上移除,并将 P 与另一个 M 关联,继续执行队列中的其他协程。当阻塞的协程恢复后,它会被放入全局队列或其他 P 的本地队列中等待执行。

这种设计使得 Go 程序能够高效地利用多核 CPU 资源,同时避免了操作系统线程的频繁切换开销。

GPM 模型是 Go 语言实现高并发的关键所在。

# 面试官可能会追问

Q1:协程和线程的区别是什么?

A1:协程与线程的主要区别在于管理方式和资源消耗。

  • 协程由 Go 运行时调度,线程由操作系统调度。

  • 协程的创建和切换开销小,内存占用低,适合高并发场景。线程的创建和切换开销大,内存占用高。

Go 的协程调度器通过 M:N 模型,实现了高效的协程管理。

Q2:Go 语言的协程调度器是如何工作的?

A2:Go 的协程调度器采用 GPM 模型。

G 是协程,P 是逻辑处理器,M 是操作系统线程。

每个 P 维护一个协程队列,M 负责执行 P 队列中的协程。

当协程阻塞时,调度器会将其挂起,并从队列中取出另一个协程执行。这种设计实现了高效的并发调度。

Q3:如何在 Go 中创建协程?

A3:Go 语言通过 "go" 关键字创建协程。

语法格式为:go 函数名 (参数)。例如:go processData (data)。

创建协程后,程序会继续执行后续代码,而新协程会在后台运行。协程的创建是异步的,不会阻塞当前执行流程。

Q4:协程之间如何通信?

A4:协程之间的通信主要通过 channel 实现。channel 是 Go 语言的核心特性之一,提供了安全的并发通信机制。

使用 channel 可以避免传统多线程编程中的锁竞争问题。

除了基本的 channel 操作,还可以使用 select 语句在多个 channel 上进行非阻塞操作,实现更复杂的协程通信模式。

Last Updated: 4/29/2026, 3:26:47 PM

← 什么情况会导致内存泄漏 协程、线程、进程的区别 →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪