面试题答案
一键面试- 内存管理:
- 当
outer
函数被调用时,会在栈上为其分配局部变量num
。 - 但是,当
outer
函数返回匿名函数时,由于匿名函数引用了num
,num
不能随着outer
函数调用结束而被销毁。Go语言的垃圾回收器(GC)会识别这种引用关系,将num
所在的内存块移动到堆上。 - 每次调用匿名函数时,都是在堆上操作这个
num
变量。
- 当
- 保持状态的原因:
- 匿名函数形成了闭包。闭包是一个函数和与其相关的引用环境组合而成的实体。在这里,匿名函数引用了
outer
函数中的num
变量,即使outer
函数执行完毕,由于闭包的存在,num
的状态依然被保存。 - 每次调用匿名函数时,都是对同一个堆上的
num
变量进行操作,所以num
的值能在多次调用中保持状态。
- 匿名函数形成了闭包。闭包是一个函数和与其相关的引用环境组合而成的实体。在这里,匿名函数引用了
- 潜在的内存问题:
- 内存泄漏:如果匿名函数被长期持有(例如,被存储在全局变量中且不会被释放),而
num
占用的内存空间不断增大(例如,如果num
是一个不断增长的复杂数据结构,而不是简单的int
),那么这部分内存就不能被垃圾回收器回收,从而导致内存泄漏。 - 并发问题:如果多个协程同时调用这个匿名函数,由于
num
的操作不是原子的,可能会出现竞态条件(race condition),导致num
的值出现错误。例如,在并发环境下,两个协程同时读取num
的值,然后分别加1,再写回,最终num
只增加了1而不是2。这种情况下,需要使用同步机制(如互斥锁sync.Mutex
)来保护对num
的操作。
- 内存泄漏:如果匿名函数被长期持有(例如,被存储在全局变量中且不会被释放),而