关于面试题
今天要聊的主题是关于面试题这个话题的讨论。 大家就免不了遇到各种面试题,对于开发职位来说,笔试题就是经常会遇到的,特别是那些一次会面试很多人的大团队。
事情还要从我的交流群中一个伙伴的分享开始,他遇到了这样一个面试题:
#define SQUAKE(a) ((a) * (a))
- (void)viewDidLoad {
[super viewDidLoad];
int a = 5;
int b = SQUAKE(a++);
NSLog(@"%d",b);
}
上面这段代码的输出结果是什么? 大家可以不必深究。我先把我的分析过程和大家分享:
首先, a 的初始值是 5, 然后我们调用 SQUAKE(a++) 并把结果给 b。
SQUAKE(a++) 调用展开后,就变成了这样 ((a++) * (a++)),至于为什么会变成这样,可以看一下第一行的 #define 语句。
如果你不了解宏定义,我简单讲解一下。第一行 #define SQUAKE(a) ((a) * (a))
是一个宏定义,编译器会在你的代码实际编译成机器码之前,将宏定义先展开,我们前面代码中的 int b = SQUAKE(a++)
展开之后就变成了int b = ((a++) * (a++))
。 实际被编译的是展开后的代码。
对于自增运算,如果你之前有过了解的话就会明白, a++ 这个运算,首先会将变量 a 当前的值作为表达式的值返回, 然后再将变量 a 自身的值加 1。 对于我们程序中的表达式,a 的初始值是 5,那么实际执行的代码就是这样:int b = ((5) * (6))
也就是说,经过这样推演,程序的输出结果应该是 30。
虽然我有比较大的把握,但我依然不敢保证程序运行的结果一定是 30(稍后我会把原因告诉你)。随后我打开 XCode 在实际的环境中跑了一下,证明了我的推导没有错。最终的输出结果就是 30 。
意义何在
之所以举这个面试题的例子,目的并不是为了在这里聊如何解这个题。 而是通过这种面试题,我发现了一个有趣的现象。虽然我知道这个题背后的代码原理,但我不认为这是一个很有意义的笔试题。
这点我当时在群里也和大家讨论了不少,虽然我知道这个题目中,宏展开和自增运算的完整规则,这个题目的目的大致也是要考验答题者对这方面的理解。 但我还是不敢保证机器的输出一定是我所计算出来的 30。
而且我想即便是各路技术大牛,看到这类题目也不敢保证百分百都能答对。反而是知识越深入的人,面对这类问题就越拿不准。打个比方,如果对一个只学过大学 C 语言的学生,那么他基本上就会断定 a++
这个运算,一定是先返回 a 当期的值,然后在对 a 自身做自增。
但对一个有很多开发经验的人来说,他反倒会对这样的运算持一个怀疑的态度。到底是先返回 a,再自增, 还是先自增再返回 a 呢?虽然说绝大多数情况下,会是我们常见的先返回后自增,但某些编译器下,确实会有不一样的结果。
比如知乎上的这个问题,就是一个真实的例子:https://www.zhihu.com/question/264902912, 题主在 win-tc
和 dev-c++5.7.1
上面编译同样的代码,却得出两个不同的运行结果。
对于这种高度依赖于运行环境的代码,用笔试的方式来提问,并不称得上是一个好方案。也许有人会说,题目中已经明确给出了 ObjC
代码,肯定点明了是在 XCode 开发环境中编译的情况。 但即便是这样,又有多少人会在平常开发中特意观察过,自增运算的优先级,并且能牢记在心呢? 更重要的是,自增运算本身在现代的开发语言中就是不推荐的。 因为它很容易产生歧义,在很多现代开发语言中,比如 Swift,已经明确禁止使用自增运算了。
如果从工程角度上看,这类的代码,我们平时工作中更是基本不会写,也不会遇到。 如果真的想考察开发人员的技术深度,倒不如问一些原理性的东西,比如 HTTPS 协议如何通信,多线程之前如何处理资源共享问题等,可以让应试者把自己对这些原理的理解表达出来。
而且我个人更认为开放性的问题更能接近的了解一个人的真实能力,可能是我们从小被应试教育影响的太多,我们更注重答案的正确与否,而对人的思维过程可能不是特别看重。即便是刚才提到的自增运算那个面试题,如果能让应试者把思维过程写下来,也会比直接看答案的对错来的更好一些。毕竟,我们在现实中处理各种问题的时候从来也没有标准答案,只有最适合当前情况的方案。
当然,实际情况还有另外一个维度,就是面试成本的考虑,如果一个大团队在同时面试几十甚至上百人,那么面试官在评价能力上给与每个人的精力肯定会变小。也许这样机械的筛选,在这个维度上,可能反倒成为合适的方案了。所以在如何面试人这件事上,也没有完全标准的答案,同样要看团队当时所处的情境。
总结
说了这么多,只想给最近遇到很多类似问题的朋友一点建议,如果你在面试中遇到这种类型的问题,并且没有答上来,不要全盘怀疑自己的能力。如果不幸被这些机械题目筛掉,其实也并没有什么,很大概率下是运气问题(当然,有时候也存在实力问题的情况)。其实不可否认,即便在面试工作的时候,也是有运气成分的。比如恰好这个团队正大量需要人,那么标准就会适当放低等等。尤其是很多大团队在面试技术人员的时候,通常都是同时在面试很多人。 很难做到完全精准的评估每个人的能力并分出高下来,并且在很多时候,团队的文化和面试者性格之间是否合适,也会影响最终的决策。
对于职场老鸟们来说,以上建议恐怕早已心知肚明了,甚至比我了解的更多。总之,希望上面分享的这些思维方式,能够给大家提供一个新的参考,至于有没有用,就看你自己了。
文章参考来源于网络,如有侵权,请联系小编删除。
网友评论