当前位置: 首页 > news >正文

Go语言面试遇到,面试官问什么是协程、什么是协程泄漏和数组跟切片是用该如何回答

什么是协程?

"协程,我把它理解为用户态的轻量级线程。它和线程最大的区别在于:线程的调度由操作系统内核负责,切换时涉及内核态和用户态的切换,开销比较大;而协程的调度完全在用户态完成,由程序自己控制什么时候挂起、什么时候恢复,因此切换成本极低。

从本质上讲,协程是一种可暂停、可恢复的函数。普通函数一旦执行就一路到底,中间没法停下来让给别人;但协程可以在执行到一半时主动让出执行权(比如遇到 I/O 等待),等条件满足了再回到刚才的断点继续往下跑。

什么是协程泄漏?

"协程泄漏,简单说就是:协程没有正常结束,但它的引用已经丢了,或者说它一直被阻塞在某个地方永远等不到结果,导致占用的内存和其他资源无法释放。

和内存泄漏类比:内存泄漏是’分配了内存忘了 free’,协程泄漏就是’创建了协程忘了(或者说没法)让它正常结束’。

举个例子,我启动了一个协程去等待一个网络请求的超时结果,但这个请求的 future 永远没有被 resolve 也没有被 cancel,那么这个协程就会一直挂在那里——它占着栈空间和闭包引用的变量,GC 也无法回收,随着时间推移越积越多,最终撑爆内存或端口耗尽。"

场景一:永不关闭的 channel
// ❌ 泄漏:ch 永远没人发也不关闭,这个 goroutine 永远阻塞 func leak() { ch := make(chan int) go func() { val := <-ch // 永远在这儿等着 fmt.Println(val) }() // 函数返回了,但上面的 goroutine 还活着 }
场景二:往没人读的 channel 发数据
// ❌ 泄漏:goroutine 想往 channel 发数据,但没人接 func leak() { ch := make(chan int) // 无缓冲! go func() { ch <- 42 // 永远阻塞,因为没人来读 }() }
场景三:for-range 未关闭的 channel
// ❌ 泄漏:channel 不 close,range 就永远不会结束 func leak() { ch := make(chan int) go func() { for val := range ch { // ch 一直开着,range 出不去 fmt.Println(val) } }() }
场景四:select 缺少退出通道
// ❌ 泄漏:select 没有 case 能退出 func leak(ctx context.Context) { ch := make(chan int) go func() { for { select { case v := <-ch: handle(v) // 少了 case <-ctx.Done(): return ! } } }() }
场景五:http.Client 不读 Body
// ❌ 经典泄漏:http.Get 之后没读也没关 Body,连接无法复用 func leak() { for { resp, _ := http.Get("https://example.com") // 忘了 resp.Body.Close() → goroutine 泄漏 + 连接泄漏 } }

什么是数组?

"Go 的数组是一块固定长度、类型确定的连续内存区域。长度是类型的一部分——[3]int[5]int在 Go 眼里是完全不同的类型,不能互相赋值。

核心特点就三点:

  • 长度固定,编译期就确定了,之后不能变
  • 值类型,赋值或传参会发生整体拷贝,不是传引用
  • 内存连续,所有元素紧挨着放在一起,CPU 缓存友好

举个例子:

var arr [3]int = [3]int{1, 2, 3} arr2 := arr // 整个数组拷贝了一份,arr 和 arr2 互不影响 arr2[0] = 99 // arr 还是 [1, 2, 3]

实际开发中,我几乎不会直接用[N]T这种数组。它更多出现在底层——比如[32]byte出现在 SHA256 的返回类型里,或者作为切片的底层存储。"

什么是切片?

"切片是对数组的一个动态视图。它本身不存数据,存的是三样东西:指向底层数组某个位置的指针、长度(len)、容量(cap)

type slice struct { ptr *Element // 指向底层数组的指针 len int // 当前有多少个元素 cap int // 从 ptr 开始到数组末尾还能装多少个 }

因为这个设计,切片有几个重要行为:

  • 它是引用语义——赋值或传参只拷贝 slice header(24 字节),不拷贝底层数据
  • append 扩容:当 len == cap 时,append 会分配一块更大的新底层数组,把旧数据拷过去,返回新切片
  • 通过make([]T, len, cap)可以预分配容量,避免频繁扩容

切片是我在 Go 里最常用的数据结构,基本取代了数组。函数传参、返回集合、处理子串,全是切片。"

区别是什么?

对比维度数组[N]T切片[]T
长度固定,是类型的一部分动态,len 可以变化
类型[3]int[5]int[]int就是[]int,不管 len 多少
值/引用值类型,赋值=全量拷贝引用语义,赋值只拷贝 header
内存位置自身就是数据自身只是 header,数据在底层数组
传参开销整个数组复制一份(大数组很贵)只拷贝 24 字节 header
可以用==比较吗可以(同类型)不能直接用==,只能和 nil 比
nil数组没有 nil切片零值是 nil

例子一:值拷贝 vs 引用语义

// 数组:值拷贝,互不影响 arr1 := [3]int{1, 2, 3} arr2 := arr1 arr2[0] = 999 fmt.Println(arr1[0]) // 1 ← 没变! // 切片:共享底层数组 s1 := []int{1, 2, 3} s2 := s1 s2[0] = 999 fmt.Println(s1[0]) // 999 ← 变了!

例子二:函数传参

// ❌ 数组传参:100万 int 全拷贝,4MB 复制! func sumArray(arr [1000000]int) int { ... } // ✅ 切片传参:只传 24 字节 func sumSlice(s []int) int { ... }

例子三:append 的陷阱

s1 := make([]int, 0, 3) s2 := s1 s2 = append(s2, 1, 2, 3) // 还在 cap 之内,s1 底层数组也变了 s2 = append(s2, 4) // 超 cap,扩容了!s2 换新底层数组,s1 不受影响
http://www.gsyq.cn/news/1611545.html

相关文章:

  • Agent Skill 学习笔记
  • 基于.NET AgentFramework开发OpenClaw智能体框架
  • GESP2026年6月认证C++三级( 第三部分编程题(1、加密))精讲
  • 深入浅出理解卷积的概念
  • 告别锁竞争:用C++11的concurrentqueue重构你的生产者消费者模型(附完整代码)
  • 一天一个Python库:tomlkit - 轻松解析和操作TOML配置
  • Python基础:三元表达式极简写法与高阶嵌套、场景避坑指南
  • 基于51/STM32单片机分贝仪检测 噪音等级声音采集(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)
  • 终极指南:如何安全备份微信聊天记录的技术方案解析
  • AKShare:金融数据接口的架构哲学与实践反思
  • SPT-AKI Profile Editor:逃离塔科夫离线服务器存档修改终极指南
  • 【VMware网络专家20年压箱底笔记】:多虚拟机通信必须绕开的4个致命陷阱(第3个连vCenter日志都不报错)
  • SSLsplit与OpenSSL深度集成:全面支持RSA、DSA、ECDSA密钥实战指南
  • 大数据相关专业哪个最适合普通家庭孩子:2026年选专业,别只盯“高大上”,要看能不能落地
  • 几句话概括,MySQL 半同步中,after_commit 与 after_sync 有什么区别
  • go: Fail-Fast Pattern
  • 万能遥控器app,各类家具都可用,推荐安装!
  • 【MES】自研MES采集设备数据的坑
  • 2026主流EPC项目协同平台横向选型与避坑评测
  • NET 安装 Aspose.Email for Python - Outlook SDK 安装
  • Qt阅读器-缩略图
  • 基于STM32单片机火灾报警系统 智能楼宇 烟雾温度火焰防盗无线2(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)
  • LLM喂文件神器-讲讲开源文件转换工具 file2md
  • 10 种 RAG 模式
  • 你的 Agent 架构选错了:越复杂的 Agent 系统,越可能走向失败
  • Spring AI + RAG
  • 告别Keil律师函!手把手教你用VSCode+GNU Arm+STM32CubeMX搭建免费单片机开发环境(Windows版)
  • 深智微:华润微官方授权代理商,如何让型号、库存交期与项目交付协同推进
  • 操作系统缓存机制深度解析:从页缓存到内存映射,超越Redis的性能优化之道
  • 行测申论试卷|公务员申论刷题|数量关系备考