面试题答案
一键面试Go语言中defer语句在内存管理方面的特点
- 延迟执行:defer语句后的函数或方法调用不会立即执行,而是在包含该defer语句的函数返回时才执行。这对于需要在函数结束时执行清理操作(如关闭文件、释放数据库连接等)非常有用,能确保这些资源在函数结束时被正确释放,避免内存泄漏。
- 栈式管理:defer语句的函数调用会被压入一个栈中。每次遇到defer语句,相应的函数调用就被压入栈,这使得defer函数的执行顺序与它们被声明的顺序相反。
多个defer语句对内存释放的顺序
在函数中有多个defer语句时,它们按照后进先出(LIFO,Last In First Out)的顺序执行,即最后声明的defer语句对应的函数先执行。例如:
func main() {
defer fmt.Println("defer 1")
defer fmt.Println("defer 2")
fmt.Println("main")
}
输出结果为:
main
defer 2
defer 1
这样设计的原因
- 符合资源管理逻辑:通常,资源的获取和释放顺序是相反的。例如,打开文件后最后要关闭文件,建立数据库连接后最后要断开连接。后进先出的顺序与这种资源管理的自然逻辑相匹配,使得代码在处理资源释放时更加直观和符合习惯。
- 保证资源正确释放:按照后进先出的顺序执行defer语句,可以确保依赖关系正确处理。如果先声明的defer函数先执行,可能会导致依赖的资源提前释放,后续的defer函数无法正确执行清理操作,从而引发错误或内存泄漏。例如,若有一个函数先获取锁,再打开文件,最后读取文件内容。按照正常逻辑,应该先关闭文件,再释放锁。后进先出的defer执行顺序可以自然地满足这种需求。