我们都讨厌面试,然而,它却是我们职业生活中无法回避的事。
当我第一次天真地冒险地进入软件工程面试这个世界时,没过多久,我觉得我在 2~3 个小时内识别软件工程师的能力就像法医一样精准。然而,我总想知道坐在桌子另一边的人是什么样的人,需要什么才能知道一个工程师是否适合这个角色。
在过去几年,我进行了 100 多次软件工程技术面试。尽管每家公司都有自己独特的面试流程,但还是有一些人们容易犯的常见错误。下面是我关于如何避免犯下这些错误的忠告。
1. 优秀的软件工程师
成功之路和失败之路几乎一样。(The road to success and the road to failure are almost exactly the same.)
——科林・雷克斯・戴维斯(Colin R. Davis,英国指挥家)
什么是优秀的软件工程师?没有唯一定义。它关系到公司对角色的需要以及公司的多样性和成熟度。一家刚刚起步的初创公司无疑需要很短的上市时间,而如果一家成熟公司已经拥有庞大的客户群,那么有可能会面临规模和架构方面带来的挑战。
在理解对业务有何意义的同时,构建产品与解决复杂的技术难题是不同的。
细致的完美主义工程师不同于快速迭代的工程师。你需要了解公司想要的是什么,然后将你的行为和言论框定在这种思维中。不要去写一份适合所有人的简历,而是要根据实际情况改写简历。如果你不得不推销自我(以某种方式,你总是要以正式的或其他方式进行推销),你要用一种你将如何成为特定公司的资产的方式进行推销。你应该理解这个角色所要满足的需求,并扪心自问,这个角色是否能够激励你,如果确实如此,那么就接受它吧。
你应该弄清楚“优秀”的定义在公司的背景下是什么样子的,并表明你的知识、经验和态度是如何符合这个定义的。
2. 做好准备
没有准备的人,就是在准备失败。(By failing to prepare, you are preparing to fail.)
——本杰明·富兰克林(Benjamin Franklin,美国政治家及科学家)
在对公司一无所知的情况下参加面试,就像约会只谈论自己一样,这并不意味着不会有第二次约会,但也不会给人留下好印象。要努力去了解企业,它的目标、它的使命、战略和成果。我绝不会因为一个人对此一无所知而让他失望,但这也暗示了他的动机。同时,这也是 HR 倾向于评估的标准。
除了企业目标之外,如果他们有技术博客的话,一定要查看他们的博客,并了解他们的技术栈。应聘者通常不会对公司表现出应有的兴趣,但一旦他们表现出来,这就是脱颖而出的绝佳方式。
3. 要有批判性的意识
受教育的标志是你可以不接受一种观点,但你能够容纳它。(It is the mark of an educated mind to be able to entertain a thought without accepting it.)——亚里士多德(Aristotle,古希腊大哲学家及科学家、柏拉图的学生、亚历山大大帝的老师)
在职业生涯中,我遇见过很多杰出的技术专家,他们都是各种各样的人。尽管如此,他们至少都有一个共同点:都是那些挑战现状,使流程和技术都得到改进的人。很多求职者在被问到是否有问题提问时,却没有什么可补充的。回避提问就是在浪费机会,要抓住这个机会,询问公司的技术决策和他们面临的挑战,并讨论每种技术的利弊。
例如:
- 他们是否正在考虑迁移到 HTTP/3?
- 他们是否正在转向事件驱动的微服务架构?
- 他们使用什么类型的消息代理?为什么不用 Kafka 来代替 RabbitMQ?
- 他们使用什么样的数据库技术?用例是什么?在这个用例中,ElasticSearch 是 SQL 很好的替代方案吗?
诸如此类。对技术决策的质疑将会表明,你不仅了解这些技术,并且可以争论何时应该使用它们,而且,你还可以进行批判性思考,并最终关心如何改进你所使用的任何应用程序。
4. 技术挑战
理论的正确永远无法用足够的验证性实验来证明,然而理论的错误仅仅需要一个证伪性实验就够了。(No amount of experimentation can ever prove me right; a single experiment can prove me wrong.)
——阿尔伯特·爱因斯坦(Albert Einstein,犹太裔理论物理学家,创立了现代物理学的两大支柱之一的相对论。)
当前技术面试状态的“忘恩负义”和直截了当的不公平现象令人震惊。大多数过程都涉及到解决与计算机科学基础相关的某种问题,比如图搜索或排序算法。我发现一件轶事,求职者必须用最少的资源占用实现一个树遍历算法,这样当他得到这份工作时,首先要做的调试是一个十年前的庞然大物。作为一名应聘者和面试官,我觉得这种自命不凡的企图美化我们工作的复杂性令人沮丧。这些类型的挑战很可能会让那些头脑中没有这些新概念的高级开发人员不屑一顾,即使他们在这个角色中可能有非常丰富的经验。
我同意这些类型的练习并非完全无用;快速解决小问题的能力与解决复杂问题的能力有关,这些复杂问题需要几天的时间才能解决,但它们从根本上是不同的。面试过程应该尽可能地反映日常工作的实际情况。一些过程包括在真实应用程序上寻找和修补 Bug、结对编程,或者实现自动化测试,我觉得这些都比深奥的算法问题要充分得多。对于这种类型的情况,一定要适应公司的语言选择,不要害怕提问,这样你才能了解挑战的全貌。
不过,对大多数过程来说,你都会面临某种算法或数据结构的问题,除非你具备良好的计算机科学基础知识,否则无法绕过这些问题。像《程序员面试金典》(Cracking the coding interview)这本书、Leetcode 网站、Pramp 网站等这样的资源都是很好的参考资料。
不管怎样,一定要大声解释你的理由。通常,问题是相互叠加的,如果你在其中一个问题失败了,也没有关系,只要你能解决其余的问题。如果你陷入困境,面试官会帮助你的,关键是要看到应聘者能不能从一个不太为人所知的问题中恢复过来,并在其他方面做得很好,这才是至关重要的。另外,当你遇到困难时,经验丰富的面试官可能会从提问转变为教学,所以不要将这种转变解读为失败;环境的变化有助于疏通大多数人的障碍。
记住,面试官既是来帮助你的,也是来评价你的,而不是评判你。你要把面试官看成一个在问题上指导你的老同事。一定要跟他讨论各种解决方案和折衷方案;这将显示出你对这一问题的了解程度。
5. 不要灰心丧气
成功就是你比失败多爬起来一次。(Success consists of getting up just one more time than you fall.)
——奥立佛・高德史密斯(Oliver Goldsmith,爱尔兰诗人、作家与医生。)
我曾经遇到过一名这样的求职者,他在面试中表现得特别不自信,没有把握的样子。尽管他缺乏安全感,也很怀疑自己,但由于他做得很好,所以他还是被录用了。但是,在安顿下来后,在日常工作中,他信心十足,能够领导讨论,并在技术课题上指导团队。后来有一次,我问他为什么在面试的时候他看上去如此不自信。他跟我解释说,在那次面试之前,他经历了一连串惨败的面试,当时他还不能很好地应对面试被拒绝的情况。遭到拒绝是求职过程的一部分,你不能让它影响到你。
要在几个小时内评估与软件工程师相关的每一项能力是不可能的。每个过程都会为公司选择相关的流程,并尽可能以最好的方式对其进行评估。这些可以是你所擅长的,也可以不是。糟糕的招聘对公司来说很难,特别是在士气方面来说,他们加入的团队更是如此。他们也付出了巨大的代价。再加上许多公司没有一个标准化的流程(重点是比较候选人,因此每个面试官都应该处理相同的问题,而且应该有一个明确的流程,对每个面试官都是一样的),这样你就会留下相当比例的错误否定。在面试中表现糟糕并意味着你就是糟糕的人。而意味着你所表现出来的能力在那个特定时间里并不是那个过程中最好的。
我知道,当我失败了,看到或听到类似这样的东西时,我总觉得那都是胡说八道。我一生都在努力成为一名斗士。然而,有时候我也会输掉太多的战斗。总是输的斗士只不过是一个出气筒。但是有时候,你必须找到内心的力量,才能将自己从屈服的残骸中拉出来。站起来,举起你的手,再战斗一次,不要让失败影响到你。
6. 这一切都与激情有关
你的工作将会占据你人生中的一大部分,同时能够让你真正满意的只有做你认为是好的工作,而且要想做伟大的工作只有你喜欢你所做的工作。如果你还没有找到,继续寻找。不要安定下来。事实上,当你找到你心中就会知道。并且,就像任何好的关系也会随着一年一年地过去而变得越来越好。所以要一直寻找直到你找到。不要安定下来。(Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven’t found it yet, keep looking. Don’t settle. As with all matters of the heart, you’ll know when you find it.)
——史蒂夫·乔布斯(Steve Jobs,美国企业家、营销家和发明家,苹果公司的联合创始人之一)
当在日常生活中的困惑和混乱中前行时,我们渴望那些清晰的时刻,当我们在挑战或任务中迷失自己时,时间会弯曲,现实会消失。在那些超越的时刻,你的一生都会在你不经意间流逝。这就是编程对于我和我们中的许多人来说的意义。那就是刻在我们内心深处的永恒而坚定的激情。而同样的激情也是成功的秘诀。
我看到应聘者在我们的面试过程中表现出色,但他们在应聘职位上表现一般。他们并不差,才华横溢,知识渊博,但他们只是表现平平。有时候,你擅长那些你并不真正关心的事情,但正是这种激情会驱使你走向成功。要评价一名软件工程师的热情并不容易。但是,如果我问你有什么副业项目,或者你曾经做过的最好的项目是什么,你可能会在整个下午热切地讨论几个项目。不管它是一个坐拥数百万用户的平台,还是一个几乎不起作用的副业项目,都无关紧要。一个充满激情的程序员会满怀热情地描述他应用的每一种模式、他征服的每一个挑战,甚至每一次破解和失败。这样,任何面试官都会知道,坐在他桌子对面的那个家伙跟他一样,也是一个对编码充满无限热情的程序员同事。
这是一个非常真实的反应,你几乎可以从他们的眼神和肢体语言中看出。要么你对它充满热情,要么你对它一点热情都没有。如果你有激情的话,一定要谈论那些能打动你的项目,这可能是一次普通面试和一次优秀面试之间的区别。
7. 结语
我一直觉得,作为一名应聘者,压力最大的部分是知道我需要得到这份工作,并证明自己是足够优秀的。而面试官的角色也并非完全没有压力,他们需要确保有充分的理由批准或否决某人,这样做出来的结果经得起审查,就我的情况而言,总是如此,尤其是凭良心。
大多数面试官都会不得不在某些时候接受面试,所以他们很有可能是有同情心的。我希望我这篇文章能够帮助你从另一个角度看待问题,我真诚希望,我的建议能够帮你谋得你真正想要的工作。