本篇文章基于 Golang 1.17.2
书接上回,胖虎前几天面试了一个“双休”的公司,但是他并不想去,他觉得他配不上这么优秀的公司,于是又开始了漫长的面试之路。
面试官:“看你简历上面写着精通 Golang, 那我问个简单的问题吧,什么defer”
胖虎:defer语句注册了一个函数调用,这个调用会延迟到defer语句所在的函数执行完毕后执行,所谓执行完毕是指该函数执行了return语句、函数体已执行完最后一条语句或函数所在的协程发生了panic。
胖虎回答问后,心想:“我厉害吧,把defer语句的官方解释都背下来了,作为优质的八股文选手,快给我发offer吧!!老板,走过路过,不要错过”
面试官看着胖虎自己在那演戏,笑而不语。继续问道:“那你说说为什么需要defer吧”
为什么需要defer
胖虎:在写代码的时候,经常会需要申请一些资源,比如数据库连接、mysql事务的提交等。
但是经常忘记释资源,并且释放的地方太多
导致很多重复代码,很容易出现事故。
defer关键字就可以解决此类问题,
在函数运行完毕后,释放响应的资源。
面试官:“那你说下defer常见的应用场景吧”
defer的执行顺序
多个defer出现的时候,它是一个“栈”的关系,也就是先进后出。一个函数中,写在前面的defer会比写在后面的defer调用得晚。
执行结果如下:
原因如下
defer与return
执行结果如下:
结论为:return之后的语句先执行,defer后的语句后执行
defer与panic
执行结果如下:
结论为:遇到panic时,遍历本协程的defer链表,并执行defer。在执行defer过程中:遇到recover则停止panic,返回recover处继续往下执行。
defer与os.Exit()
执行结果如下:
结论:当发生panic时,defer会被执行,但是当调用os.Exit()方法退出程序时,defer并不会被执行。
defer遇到返回值为命名变量
最终结果是:
原因:
- 11行res变量为"", 12行res值为"res"
- 执行return语句将"我是最终结果"赋值给变量res
- 执行defer方法,将res 修改为"我是defer"
- 最终结果就是“我是defer”
defer遇到返回值为匿名变量
执行结果是:
执行步骤:
- 11行res变量为"", 12行res值为"res"
- 执行return语句将"我是最终结果"赋值给匿名变量
- 执行defer方法,将res 修改为"我是defer", 但对匿名变量并没有影响
- 最终结果就是“我是最终结果”
总结如下:
胖虎一口气说了这么多,内心想:这次志在必得啊。我明天就能入职,快找我进来吧
面试官:小伙子不错啊,这样吧,在面试你最后一题,你要是能答上来,薪资大胆要,要多少,我们就给多少。
以下代码执行结果是什么?为什么?
胖虎:“……”,这题不会啊,眼看煮熟的鸭子飞跑了,胖虎流下没有技术的泪水。
面试官:不着急,看你的确挺厉害的,给你一次场外求助的机会,读者在评论区留言,在评论区选择出认为对的答案,也算面试成功。
胖虎:“有知道的大佬吗?在线等”
福利
我为大家整理了一些学习资料礼包,关注公众号回复指令:【Golang】、【操作系统】、【Linux】、【LeetCode】、【Golang电子书】即可获得相应学习资料!