最近校招浪潮开始了,互联网公式开始扎堆面试,翻了翻Google Calendar,9月份和10月份没有一天是闲着,每天不是面试就是笔试,最夸张的是一个周六有6场,从东边的乐视到西二旗的百度,面试多了,收到offer的同时,另外比较有意思的是面试题。offer都是千篇一律,但是有趣的面试题很少。工作以后也帮着部门面试候选人,也在思考如何考察面试候选人真实的基础是不是扎实,而又不是那些枯燥、烂大街的、枯燥的问题,让面试过程变成一场与候选人愉快的交流“内功”的过程。
先聊一聊我接触到比较有“深度”的面试题。
C++中的析构函数是谁调用的?
问: 析构函数是干嘛的?
答: 释放类申请的空间,多是指类成员中指针所指的空间,另外,不排除其他的方式申请空间,并放在析构函数来显式析构。
问: 谁来调用析构函数?
答: 。。。操作系统
问: 操作系统怎么调用?
答: (思考几秒钟,被面试官打断)
问: 换个方式问这个问题,如果一个程序被使用Ctrl + C了,那么它申请的空间怎么办?
答: 这个问题没有仔细做过实验,但是根据我的学习的理论和经验,以及编译原理的知识,一个程序被编译器编程二进制代码,每个变量的声明周期,什么时候该销毁,什么时候该调用析构函数,编译器是完全能确定的,编译器会在恰当的时间点对这些没有显示调用delete的对象,生成一些调用析构函数的指令,完成对象的析构,比如,在函数中对象,会在函数执行结束后,添加析构函数指令,完成析构,程序结束时,会对全局变量进行析构,这些添加的析构指令,其实就是编译器把代码编译成二进制可执行文件时,不是一一翻译,而是有思想的解释程序,该调用析构的地方,实际上是隐式析构函数调用,只不过编译器完成了这部分工作。使用了Ctrl+C后,线程直接停止,很多二进制指令没有执行,也就造成了很多内存还没有来得及释放,造成内存泄露,这些内存会由操作系统最终来回收,但是不确定是什么时间回收。
面试官:很好。
这个面试官看重基础,算法问题只写了一个Middle级别的,由于写的漂亮,没有一点Bug,考虑了特殊Case,代码问题过关,所以剩下的时间完全考察基础,从编译原理,到CUDA编程的底层,从线性代数到概率论。
还有一个比较有意思的是,CUDA中的share memory与寄存器哪个快,慢的为什么慢?这如果没有做过CUDA程序优化,估计回答上来的可能很小,share memory会有冲突,寄存器没有,但是它们共享一块 Block 存储器。
这算是针对“内功”的一次小的交流,面试官觉得不错,我觉得这种交流很舒服。
二叉树的先序遍历、中序遍历、后续遍历,缺了哪一个不行?
这个答案不唯一,我在GitHub上给出了结果,还有部分源代码。