Skip to content

四火的唠叨

一个纯正程序员的啰嗦

Menu
  • 所有文章
  • About Me
  • 关于四火
  • 旅行映像
  • 独立游戏
  • 资源链接
Menu

近期面试观摩的一些思考

Posted on 12/08/201907/04/2022 by 四火

作为软件工程师,工作有一些年头了,在不同的公司,也面试过不少人。以前没觉得这事儿多有意思,但是这几年想法改变了,我发现在一家公司,去面试不同的候选人,是一个非常有价值的增长阅历、经验,让自己成长的机会,还有机会见识到各种各样的人的,获知他们不同的思考问题的方式。特别是作为 bartender(在 Oracle,bartender 基本上就是面试的技术负责人,所有团队招人,都必须有一个来自别的团队的 bartender 来保证候选人的水准,具体的面试流程你可以参考一下我写过的这个专栏),这样的机会有很多,虽然会占用一些自己团队和项目的时间,但是和收获比起来,显然是很有价值的。

最近跟一些公司内一些经验特别丰富的 bartender 交流,并实际地 shadow(包括 reverse shadow)了一些他们的面试,学习了一些面试方法,包括其间的各种思路和套路,感觉有不少收获。有几个 bartender 是 IC-6 的级别,这个基本上就是 Oracle 的工程师技术上升通道上理论上能够达到的最高级别了,整个公司也没几个人;还有几个则是在 Oracle 有了几百次面试的经验,也可以说是阅人无数了。因此无论从哪个角度说,这样的学习机会都是很难得的。这里说的 shadow,就是 “观摩”,指的是这些经验丰富的工程师面试,我旁观,结束之后大家再切磋一下;而 reverse shadow,则是反过来,我面试,他们中的某一个旁观,结束之后再切磋一下。

这里面有几个思路、观点,我在这里记录和分享一下,有一些是来自别的同事,有一些则是自己的。当然,需要明确的是,面试没有什么 “最佳实践”,在这么短的时间内要对一个候选人定性,本来就是一件非常困难的事情。

采纳推荐人的意见

有时候候选人有公司内的员工推荐,大家都认为推荐人的意见往往非常有价值,因为面试官可能就花了一个小时和候选人接触,而推荐人则可能和候选人一起工作过很长时间,显然这样的评估更为全面。

在 debrief(相当于面试之后所有候选人聚到一起,评估候选人的的讨论会)的时候,我看到了一些不同的做法。而我的方法是,请推荐人进入这个会议,接受 “拷问”,但是询问清楚几个问题以后,就请他离开,以避免他知道任何 debrief 的进程和结果——因为这些既是对于候选人隐私的泄露,又可能造成他被候选人询问时而可能出现的为难。因此我们让他离开可以让这个状况变得简单,同时我们要让推荐人知道,这些内容是严格保密的。这几个问题是:

  • 你对候选人的推荐程度是什么,为什么?我们知道有些候选人的推荐 “只是认识而已”,有些对于候选人的推荐则 “愿意以我的名誉担保”。
  • 你觉得候选人有哪些优缺点?这些优缺点我们可以重点结合面试的反馈做出进一步的评估。
  • 你和候选人是否熟悉,你们是否一起工作过,什么时候工作过,有多长时间?
  • 你在公司、团队工作多长时间了,你的职位和角色是什么?这也是一个必要的问题,显然一个更熟悉本公司、本团队的员工,更熟悉文化,理解产品,这样的推荐往往更有价值。

对,就这些问题,其实这些问题基本上就是为了明确两个事情:(1)推荐人对候选人的评价本身,以及(2)到底这个评价到底在对候选人的整个评估体系中赋予多大的权重。当然,也可以询问其他问题,但是上面这几个问题是必须要覆盖到的。

分析问题的角度

对于一些有经验的程序员候选人,在得到一个粗略的、缺乏整理的问题的时候,他会一层一层地抽丝剥茧,把问题梳理清楚。在设计的时候也是如此,而不是很快地跳进问题解决的泥潭中。当然也有很多候选人,也许是大多数候选人,他们上来就开始动手,行动的意愿极其强烈,仿佛只有这样才算有了进展,心里才感到安心。

以往,当我遇到上述后者这样的候选人的时候,我可能会尝试中断候选人这样的做法,并问到,“你想清楚了吗?”,或者是,“你实现的思路是否已经明确?”,以希望候选人 “想清楚了再动手”。

但我现在觉得更好的做法,特别是对于一些经验相对较为缺乏的程序员来说,是顺其自然。尽管这意味着可能会出现设计上大量的反复,可能会出现实现上大量的涂改,候选人可能也将不得不磕磕绊绊,面对并解决一个一个的问题,并低效和曲折地逐步接近他的目标。这没有错,但是如果你强行改变候选人的思维方式,他可能将因此迷失。因为每个人的思维方式是不一样的,一般说来,比较理想的方式可能是自上而下的,更有统筹和规划性,可是自下而上却更为容易思考、更容易开始。

这让我想起了 TDD(测试驱动开发),它就鼓励(即便这种鼓励并非出于 TDD 的本意)问题没想清楚之前,就动手,然后逐步往上迭代进新的分支用例。不可否认这种方式有它的好处,但是我依然认为,还是 “想清楚了再动手” 更为理想,至少要把大致思路和重要的分支用例想清楚,在面试中其实也是如此,可是我们当然应当容许不同的思维方式。

另一方面,如果通过这种自下而上的相对低效的方式,候选人能够不断地发现问题,思考解决方案,并不需要面试官较多的指引,就可以独立不断地解决这一个一个的小困难,这就是一个很明确的闪光点了。但这大多是对于经验较少、级别较初级的程序员来说的,他们如果通过了面试,在团队中还需要得到进一步的引导,慢慢改进自己的问题分析和解决方法。相应地,对于一些已经是 “老司机” 的候选人,如果还使用这种自底向上方式来分析解决问题,而没有一个俯瞰的、纵览的视图,这显然就不是一件好事了。

问项目、挖简历的占比

我们的面试中,有一项内容就是挖掘简历和项目,就是说根据候选人的项目经验,找到一个点往深了挖,以了解他是怎样工作的,完成了怎样的成就,从中可以看出很多问题,特别是能够把那些实际做事的人和那些口若悬河的人给区分开。

这个方法其实很好,但是需要注意的是,针对不同的候选人,这种方式在整个面试过程中的占比应该有所不同。具体说,对于经验较少的候选人来说,这个过程可以短一些,因为经验较少,能问出的内容和价值也相对较低;而对于那些几十年经验的程序员,则要多问,不但容易发现闪光点,也容易发现问题。而且,有趣的一点是,对于特别有经验的程序员,你去仔细挖掘他的简历,还往往是一种 “尊重” 的体现,我听说有的面试官,面试一位工作了二十几年的程序员,上来就让写快排,这立马就把对方惹恼了。我们且不说这种面试方法对不对、好不好,也不说候选人的气量如何,但显然把对方惹恼这件事情是很容易理解的。面试过程毕竟是双向的,面试官有义务尽量保持候选人一个愉快的体验,这一点,下文我还会讲到。

主要问题的选择

对于面试过程中,时间占比比较大的那个 “主要问题”,我们都知道要选择一个模糊的、最好是实际的问题,面试官会和候选人花费几十分钟时间,一起来解决这个问题,期间会考察多个方面。但是除此之外,还有一些要点:

  • 不要一味避开那些常见问题,更重要的是要选择自己有着透彻思考的问题,可以是实际项目的问题;
  • 从算法和设计的角度来说,都要允许存在多个解,并且它们可以进行 trade-off;
  • 最好能够存在一些特殊的 case 以考察候选人思考问题的全面性;
  • 可以使用同一个问题问不同级别和经验的候选人,这样以便于把候选人放到一定纵深的实例集合中去比较考察。

快乐,不要沮丧

无论是成功还是失败,都不要让候选人觉得沮丧。最理想的面试,是能够通过一步一步引导,总让候选人觉得不断在进展,并且问题,或者是子问题的难度总是处于 “垫脚尖能够到” 的程度,难了容易灰心丧气,容易了又不能考察出候选人的能力边界。无论候选人能够通过面试,还是不能通过,希望这个过程对他来说,是快乐的,是一次正面的体验。

有人会质疑这一点,如果候选人觉得体验很好,但是最后却没能通过面试,这样的对比是不是更糟?有道理,但是,和留下糟糕的经历这样的印象比较起来,还是留下好的体验更值得。体验如何,毕竟和实际招不招人的决定,是两个相对独立的事情。我们希望,即便候选人没有通过面试,但是他依然可以去和他的朋友说,这家公司很好,很尊重候选人,整个流程我的感觉都不错,虽然我没有通过,还是推荐你去。当然,不要在面试的进程中放出任何通过、或是不通过面试的信号,因为通不通过的决定,是在面试之后的讨论会中才会做出的。

在面试讨论问题的进程中,需要尽量给候选人一定的自由度。有时候我们希望得到更多的候选人的数据,就会接连发问,可是,这样却可能适得其反,候选人会疲于应付接二连三抛出的问题,而失去靠自己独立去思考和发现问题的机会。

面试是双向的

你在面试候选人的时候,候选人也在面试你。基本上,对于那些优秀的候选人,根本就不愁 offer,因此,向候选人 “兜售” 加入团队的机会是很重要的。因为我也有 Amazon 的经验,因此我经常被问到 AWS 和 OCI 的区别,这一点可以说到好几个方面,比如:显然 AWS 更加成熟,工具、设施都比较丰富,而 OCI 的话,很多都需要自己干 ,但是相应地,我们能产生的影响力自然也大得多;再一个,我们每天遇到的问题和挑战,要丰富和模糊得多,这方面还是比较锻炼人的。

最后,我要说的是,在一个面试的 loop 中,除了 Hiring Manager(招聘经理),其它面试官一般都来自招聘经理自己的团队,唯有 bartender 是个例外,他必须来自其他团队,这是为了避免利益相关性上过度的集中,必须引入的一种分散机制(其实我认为这种机制的分散程度还是不足够的,我知道有一些其它的互联网公司有更好的办法)。因此,bartender 必须要有足够的 backbone,其肩上的担子也会尤其重,这个角色的重要性不言而喻。

过程比结果更重要

[Updated on 1/30/2020] “过程比结果更重要”,这可不是一个冠冕堂皇的说法,我想很多来 OCI 面试的人,对这一点都有不同的认识。我想更新一下这篇文章,主要就是来谈一谈我对于这一点的认识。

对于面试中最主要的那个问题,我比较喜欢问模糊的,来自于实际的问题(我认为,优秀的问题最好是一个模糊的实际问题,而不是翻转一个字符串或者找一个最大值这样具体的 “纯算法题”,因为这可以考察更多方面,也和工程师日常遇到的问题更为接近),这个问题可以扩展讨论的空间的非常大,里面最主要子问题的解法可能有很多,而其中比较好的解法也有好几种。

这样的问题我会拿来问不同级别、不同工作经验,和具备不同解决问题能力的工程师候选人。有的可能还没有毕业,而有的可能有十五年的工作经验。但是,这是一个可以不断伸展的,不断递进的问题,能够在面试的时间内深入到、并使用到最佳解法来解决的,基本就没有。但是,不能得到最优解,绝不代表这样的面试就是失败的,我希望候选人能够在这样一个多层次的问题中,找到自己能达到的,并且如前文提到的,是 “踮踮脚” 能够找到的位置,这样,问题既能够具备区分度,又能够让候选人完成一个完整的问题讨论和解答的过程,从而让面试具备一定完整角度的考察性(这样的问题设计其实很难,但是如果你感兴趣,你可以看看我在 “极客时间” 专栏中介绍的一个例子,这个例子我虽然现在很少用了,但是也足够清楚地说明问题)。对于同样的问题,通过不断积累面试的数据,可以让自己的对候选人的评估更加客观、理性和稳定。

在这个过程中,我希望考察候选人的沟通能力、对于需求的理解能力、对于问题的分析能力、挖掘问题的能力、思考的条理性和清晰程度、考虑情形的周密程度、将问题和数学能力结合的能力、解决方案工程化的能力、面对困难的态度(面对困难的时候,我们更容易看清自己,比如会轻易地丢掉自己原来思考的方向,比如会听不进建议和问题,比如会在一个局限的圈子里面兜兜转转,而忘掉了实际该解决的问题),等等等等,这太多太多了,这些都是在开始正式编码前后,和面试官一起来攻克问题的最有趣的一部分。

大多数时候,这些问题的考察都在编码前,但也有很多时候,这些发生在编码之后,比如分析怎样去测试代码,怎样取改进,既包括时间、空间复杂度上的改进,又包括代码设计和组织上的改进,分析代码在实际的工程化过程中,会有哪些隐患,等等。

因此,真正编码的部分,其实在其中占的比重,未必很大。我比较倾向于让候选人写一段核心代码,而不是完整的解答,这样可以节约时间。有些时候,候选人这些做得都不错,但是由于时间关系,或者编码生疏的关系,不能够抵达或基本完成编码的环节,在综合评估以后,我依然会给出一个 “incline” 的投票。一个典型的情况是,我的这一轮中,其它过程时间占比过大,但是做得比较不错,因而没有时间留给编码,那么我们在 debrief 的时候,如果其它几轮面试官普遍反映编码能力不错,那么编码这个方面,我们依然会认为已经考察到,并且通过了。

但是候选人可能会意识到自己没有完成编码,或者是完成编码了,但是意识到实现不是最优的,就会沮丧。事实就是,候选人把这个 “结果” 看得过于重要了,而忽略了面试的整个过程中所反映出来的种种能力。从面试官的角度来说,我们希望让候选人感觉这个面试过程是 “完整” 的,能够愉快地结束,因此有时候,在可能的情况下,即便候选人在前面的环节做得不好,我还是希望能给他/她完成一段代码的机会,即便是很短的一小段代码。这段代码,即是对候选人考察的一个方面 ,也是保持面试完整性的一个方面。有时实在没有时间编码,但是如果候选人其它方面做得不错,我可能会安慰他/她说,“虽然没有写代码,但是你我们在很多方面讨论得很深入,已经走得很远了”,这也希望候选人可以保持良好的心态,也保留一个好印象,毕竟,面试是双向的(如前文所述)。当然,也是由于类似这样的差异,有时候候选人觉得自己不是很顺利,却拿到了 offer;有的候选人则觉得自己表现得很好,“搞定了一切”,却挂掉了面试。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

×Scan to share with WeChat

你可能也喜欢看:

  1. 系统设计的典型分层和涉及的知识点
  2. 职业生涯下一站
  3. 写在 Oracle 入职一个月之时(兼招人帖)
  4. 技术面试中,什么样的问题才是好问题?
  5. 常用命令归纳:Linux/Oracle/JVM/Git

5 thoughts on “近期面试观摩的一些思考”

  1. xuruizhi says:
    02/18/2021 at 12:47 AM

    你对候选人的推荐程度是什么,为什么?我们知道有些候选人的推荐 “只是认识而已”,有些对于候选人的推荐则 “愿意赌上我的名义”。

    名义 -> 名誉?

    Reply
    1. 四火 says:
      02/18/2021 at 7:28 PM

      确实,修改了

      Reply
  2. lionelgeng says:
    12/15/2019 at 8:27 PM

    现在很多面试的问题都很开放,面试官挖掘候选人思考的能力,一步步推进的方法,确实是很重要的一方面。

    Reply
  3. CE.BB.CAT says:
    12/13/2019 at 3:19 AM

    读完以后很有收获,奇怪的是为什么点击量不高捏?怪哉怪哉

    Reply
  4. arch says:
    12/08/2019 at 4:38 PM

    一个严肃的问题摆在你的面前:请问这样是否道德?

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

订阅·联系

四火,啰嗦的程序员一枚,现居西雅图

Amazon Google Groovy Hadoop Haskell Java JavaScript LeetCode Oracle Python Spark 互联网 前端 华为 历史 同步 团队 图解笔记 基础设施 工作 工作流 工具 工程师 应用系统 异步 微博 思考 技术 数据库 曼联 测试 生活 程序员 管理 系统设计 缓存 编码 编程范型 英语 西雅图 设计 评审 问题 面试 项目

分类

  • Algorithm and Data Structure (30)
  • Concurrency and Asynchronization (6)
  • System Architecture and Design (43)
  • Distributed System (18)
  • Tools Frameworks and Libs (13)
  • Storage and Data Access (8)
  • Front-end Development (33)
  • Programming Languages and Paradigms (55)
  • Testing and Quality Assurance (4)
  • Network and Communication (6)
  • Authentication and Authorization (6)
  • Automation and Operation Excellence (13)
  • Big Data and Machine Learning (5)
  • Product Design (7)
  • Hiring and Interviews (14)
  • Project and Team Management (14)
  • Engineering Culture (17)
  • Critical Thinking (25)
  • Career Growth (57)
  • Life Experience and Thoughts (45)

推荐文章

  • 谈谈分布式锁
  • 常见分布式系统设计图解(汇总)
  • 系统设计中的快速估算技巧
  • 从链表存在环的问题说起
  • 技术面试中,什么样的问题才是好问题?
  • 从物理时钟到逻辑时钟
  • 近期面试观摩的一些思考
  • RSA 背后的算法
  • 谈谈 Ops(汇总 + 最终篇):工具和实践
  • 不要让业务牵着鼻子走
  • 倔强的程序员
  • 谈谈微信的信息流
  • 评审的艺术——谈谈现实中的代码评审
  • Blog 安全问题小记
  • 求第 K 个数的问题
  • 一些前端框架的比较(下)——Ember.js 和 React
  • 一些前端框架的比较(上)——GWT、AngularJS 和 Backbone.js
  • 工作流系统的设计
  • Spark 的性能调优
  • “残酷” 的事实
  • 七年工作,几个故事
  • 从 Java 和 JavaScript 来学习 Haskell 和 Groovy(汇总)
  • 一道随机数题目的求解
  • 层次
  • Dynamo 的实现技术和去中心化
  • 也谈谈全栈工程师
  • 多重继承的演变
  • 编程范型:工具的选择
  • GWT 初体验
  • java.util.concurrent 并发包诸类概览
  • 从 DCL 的对象安全发布谈起
  • 不同团队的困惑
  • 不适合 Hadoop 解决的问题
  • 留心那些潜在的系统设计问题
  • 再谈大楼扔鸡蛋的问题
  • 几种华丽无比的开发方式
  • 我眼中的工程师文化
  • 观点的碰撞
  • 谈谈盗版软件问题
  • 对几个软件开发传统观点的质疑和反驳
  • MVC 框架的映射和解耦
  • 编程的未来
  • DAO 的演进
  • 致那些自嘲码农的苦逼程序员
  • Java 多线程发展简史
  • 珍爱生命,远离微博
  • 网站性能优化的三重境界
  • OSCache 框架源码解析
  • “ 你不适合做程序员”
  • 画圆画方的故事

近期评论

  • + 1.943624 BTC.NEXT - https://graph.org/Ticket--58146-05-02?hs=9a9c6f8dfe3cdbe0074006e3e640b19b& on 所有文章
  • Anonymous on 闲聊投资:亲自体验和护城河
  • 四火 on 关于近期求职的近况和思考
  • YC on 关于近期求职的近况和思考
  • mafulong on 常见分布式基础设施系统设计图解(四):分布式工作流系统
  • 四火 on 常见分布式基础设施系统设计图解(八):分布式键值存储系统
  • Anonymous on 我裸辞了
  • https://umlcn.com on 资源链接
  • Anonymous on 我裸辞了
  • Dylan on 我裸辞了
© 2025 四火的唠叨 | Powered by Minimalist Blog WordPress Theme