软件工程师如何应对面试的可怕“反乌托邦世界”?

  1. 云栖社区>
  2. 云栖号资讯>
  3. 博客>
  4. 正文

软件工程师如何应对面试的可怕“反乌托邦世界”?

云栖号资讯小编 2020-05-14 12:46:09 浏览474
展开阅读全文

那些尝试

我的电话响了。

“你好,我是Jared。”

“嗨,你好,我是“某搜索和广告行业巨头”的人,来对你进行电话面试。”

“是的!我一直在等你们的电话!”

“好的。你可以写出在二叉树中找到第K个最大值的算法吗?”

我顿了一下。大脑完全空白。我从来没有经历过这样的情况。空白的Google doc仿佛在盯着我一样,光标的闪烁就像被放慢了。我东拼西凑了个东西出来,作为第一次的尝试。

“你能为这个算法写个测试用例(test case)吗?”

当然。如果我的思维没有完全被迷雾环绕,且我的自尊心没有在因为看着梦想消失在自己眼前而引发的无能狂怒下消弭,我是可以写出那个测试的。过去几个月以来所有的辛勤付出就得到了这样的结果?19年1月左右我就决定要找一份新工作了,然后就仿佛是云端之上的软件工程之神对我赐福了一样,一位来自“某搜索和广告行业巨头”的招聘人员在LinkedIn上联系了我,希望对我电话采访。这太完美了!

这种情况不是第一次发生了。作为一名刚毕业,稚气未退的天真的年轻工程师,我最近开始了自己的第一份工作,并且做得很好。但是后来我的世界天翻地覆。我遇到了一个非常磨人的bug,然后做了任何有自尊心的软件工程师在尝试自己动手解决问题之前都会先去做的事情:Google搜索。当我在搜索框中键入了圆润的问号并按下Enter键后,屏渐渐黑了下去,然后我掉进了一个shell中。

您刚才用的是我们的语言......想接受一个挑战吗?

1.好的
2.不了,谢谢

温热的Costco咖啡刚入口,我差点一口喷出来。我几乎就快要跳起来,尖叫着让我的同事们来看看了。但是后来又突然担心起来,是不是自己出现了幻觉,并意识到如果真的是幻觉那会很尴尬。我一边担心着自己即将经历一次灵魂出鞘的体验,一边按下了1。

给定一个包含n + 1个整数的数组nums,其中每个整数都在1到n之间(包括1和n),你需要证明数组中至少存在一个重复的数字。如果只有一个重复的数字,请找出该数字。

您有24小时的时间!

我心脏病都快被吓出来了。又一杯Costco咖啡下肚,我终于使自己稍稍振作,然后才意识到自己完全有能力解决这个问题。我脑子里已经有了解决问题的计划。然后我照计划做了。当我点击提交按钮时,另一个需要解决的问题马上又出现了。就这样继续了五个来回,每次的问题都变得越来越难。在提交终极问题后,我收到了另一条消息:

恭喜您!这段代码很强大!现在有一个“某巨头搜索和广告公司”的面试机会,您想要吗?

事情的经过就是这样。就像这样,我的整个职业生涯发生了变化。世界上最强大的组织之一进入了我22岁的大脑,并改写了一个寄存器的内容。我从前所有的职业规划都不做数了。在此之前,我很无知但也很幸福地认为这样的顶级公司并不在我的选择范围之内。但是显然,不知怎么的,事实已经证明我是他们值得考虑的人选了。

电话采访的过程很像我做的这个噩梦。我被要求在45分钟内写出Conway’s Game of Life。我其实发挥得很好。我写出了整个程序并进行了测试,以证明它可以正常运行。但第二天我收到了拒绝的信息。我的内心既崩溃又困惑,自己到底做错了什么?我所做的所有算法题都没用吗?这家公司为什么会要求我在这么短的时间内写出这么难的算法?

鉴于我在这个级别的难度的面试中的初次经验,我决定下次要加大自己的努力程度。下一次的面试在19年4月。我为自己建立了一个为期3个月的学习计划,并尽力追赶。早上我起床以后做三道练习题,然后去上一整天的班,然后回家跑会儿步,吃点东西,再回到我的办公室里,为的是能在一个安静的工作环境中做更多的练习。在三个月的时间里,我总共做了114道练习题。涉及的主题包括数组,回溯,二叉搜索,二叉树,广度优先搜索,深度优先搜索,动态编程,图,贪心算法,散列表,链表,概率,排序,栈和字典树(trie, pl.tries)等等。做了这么多准备工作,我没理由不成功了吧?

苦难

在“某搜索和广告巨头”的面试化为灰烬了。我无法解决那个问题。但这仅仅是一整年里疯狂的起点。起初,我对于申请哪些公司很有策略性。我不仅仅是想要“一份工作”而已,我想要的是“对的那份工作”。

接下来面了一家自动驾驶公司。提交申请后我很快就得到了回复,并被安排了代码面试。面试时,面试官怒气冲冲地用很重的口音告诉我,让我编写一个非常复杂的图像过滤算法。我写完了,并要求对方给予反馈。他说:“看起来非常好!”结果第二天,我收到了一封官话版本的拒绝电子邮件。

然后是一家分析公司,让我把一道题带回家去做。题目只有三句话。我尽了最大的努力,并写出了一个非常复杂的多线程图像处理系统。后来招聘人员礼貌地拒绝了我,当我要求反馈时,对方告诉我代码“效率太低”。

在那之后是一家付款处理公司。我与一个招聘人员有了一段很顺利的电话交流,她称赞我的简历与职位描述很相符。第二天,我收到了她的一封电子邮件,说公司里找不到适合我技能的职位。

另一个例子是在“某社交媒体平台巨头”的面试。“Jared!感谢您的申请!我认为您将成为本司的重要成员!我已将您的申请直接发送给了您所在地区的招聘经理!”正在收到此电子邮件的八分钟之后,我又收到了一封自动发送的拒绝邮件,说我的技能不适合该职位。

与我联系过的第三方招聘人员不计其数。但所有这些机会最后都没有什么结果。这里面我最喜欢的大概是一个音频处理公司。招聘人员联系了我,说团队在看过我的简历后非常希望能与我谈谈,她将联系招聘经理安排电话面试的事宜。一个星期以后,我联系对方问问是什么情况。招聘人员说,她已经与招聘经理取得了联系,经理认为我的技能与他们团队不匹配。这对我来说是完全讲得通,因此我就继续去做自己的事情了……但是后来,抱着尝试的心态,我向他们的另一个职位提交了简历,立即有另一名招聘人员联系我了。当他们马上安排了电话面试时,我很惊讶。但是不得不承认,这场面试我只能说是表现平平。第二天我收到了官方的拒绝电子邮件。

然后,我终于得到了一个“某社交媒体巨头公司”的现场面试机会。我在四场不同的面试中与许多人一起群面,历经了一系列编程问题,并对所有问题都给出了正确且令人信服的回答。

一路上,我被问到一系列复杂而困难的“跟我聊聊……那时候的事情吧”这样的问题。这令人耳目一新,因为这是我在找工作的过程中第一次遇到考察我作为一名工程师的经验和聪明才智的情境。接着就是最后的系统设计面试。面试官及时地给了一个小的系统让我设计。我开始谈论自己的解决思路,面试官在每一步上相应地提出问题。最后,我们终于到了最后关头,面试官说:“好吧,现在我们有个微服务架构……所以说您有能力设计吗?”我马上回答说,我在微服务方面没有任何经验。他不解地看着我,问道:“你没有吗?”我回答说,“是的,我没有。我在简历中已经尽量说清楚了我在桌面,嵌入式系统和移动开发中的技能和背景。”他顿了一下,看起来就像意识到自己犯了一个错误一样。呵呵,可真是棒棒哒!所以这个人传达给我的信息就是,我花了整整4个月的时间为这个面试准备,工作之余的每个醒着的时间段都花在了做练习题,以及排练如何在软技能问题中表现我的技术背景上,但他连花10来分钟浏览一遍我简历的耐心都没有。

分析

对于在求职的艰辛过程中的那些令人失望透顶的经历,我能说上一年。这种事情太多了。一直以来,我无论是在面对自己还是他人时都力求对自己的技术实力保持诚实和谦逊的态度。那种需要多年经验(我不具备的),以及需要某种我不会的技能的工作,我都不会去申请。当然,我打算从嵌入式领域回到Web领域,但我是有两年的Web工程师经验的,更不用说我还有作为移动应用程序开发人员和机器学习算法研究人员的经验呢。我完全承认,我在很多很多方面都还有成长空间,在职位上需要学习的东西也很多。但另一方面,我也非常有信心,我是有能力快速地开始从事一份新工作的。在我看来,软件工程是一种由学习和新经验提炼出来的一种艺术形式。没有哪个软件工程师会只追求在某方面达到“还算精通”,并在他或她职业生涯的全过程中一直都在那个水平上止步不前。至少我是不希望有这样的软件工程师的:这样的人很快就会被别人落下,败者食尘。那么,我的面试到底是怎么回事呢?在长时间经历这种反乌托邦过程之后,我觉得有必要把各过程分开来分析一下我的观察结果,然后再复盘,以获得一个更清晰的全局观。

1、我们被自己造的神话迷惑了——软件工程师们往往都崇尚一种认知,尤其是在当今这个技术爆炸的世界中,大家都认为会有那么一类独来独往,特立独行的程序员,任何需求他们都可以轻松地用算法解决。这类原型软件工程师们的人设是不参加任何社交,反对结构,且极度理想主义。他或她的人格是极度独立的,不需要与任何人交流就能把工作搞定。因此,由于我们无意识地相信这种人设,我作为工程师必须先通过一个可以测试这些特征的筛选,才有资格跟对这个职位有所了解的人进行交谈。但是,其实用常识思考一下,就能明白这些特征实际上并不能表明候选人的能力有多强。软件公司是一个或多个软件团队的集合,而团队又是多名个体的集合。

要在一个有着共同目标的团队中取得成功,作为个人必须:

与他人交流——团队中只要有一位成员不了解目标,就会给整个团队拖后腿。

与其他工程师(非软件方面的工程师)交流——不管有多少软件工程师不喜欢这件事情,事实就是,要运营一个软件公司不仅仅需要软件方面的工程师。

服从指令——关于产品的指令通常来自软件团队之外。这大概就是为组织工作的要点:你要去实现的并不是你自己的愿景。

相互学习——团队中成员之间的知识面肯定是不平衡的,在产品和技术方面的知识都是如此。集体团队的集体技术技能之间存在有权重的平衡。这就是为什么公司内部会有按经验划分的等级制度和职责分配。这种平衡永远不是,也永远不该是静态的。应该永远都有人在学习,而且永远都有人在教别人。

到目前为止,总结一下就是:似乎促成了招聘流程结构的是“怎样才算一名软件工程师”的流行观念,而不是软件工程师身上真的能让他们在工作中取得成功的特质。

2、我们都知道算法题只是人为设计出来的游戏而已——由于多方面的原因,要阐明这一点比较难。

说到底,这些算法到底有多少价值?——这个问题众说纷纭。不论我怎么反驳,总是会有一些团体相信你无需了解算法的工作原理,甚至不需要知道数字计算机就可以成为一名非常优秀的软件工程师了。我的相反意见是,飞机维修工和航空工程师之间是有差异的。哪一个更有价值,你又更愿意成为哪一个呢?这个问题留给你自己思考吧。更好的问法是对于算法相关性的询问。

那么算法又究竟有多相关呢?——尽管我十分相信,算法知识以及计算机内部的工作原理对于成为一名成功且有价值的软件工程师来说非常重要,同时我也明白,而且所有其他人也都明白,这些知识很少能在工作中用到。“非我发明”(Not Invented Here,表示一种对外界解决方案的抵触风气)的思想无处不在,并被强加给团队。对于大多数应用程序来说,这是一个好策略。如果已经有一个经过充分测试并能够稳操胜券地满足需求的库了,那么显然用它来整合会比重新造轮子要更安全且更合适。就好比说,圆形的轮子已经很好了,为什么非要用其他形状的呢?因此,如果要考虑与此问题相关的算法题目,那就令人觉得奇怪,我们干嘛非要问这些问题。如果行业中有那么多人都认为算法题在软件工程师的日常工作中没有什么价值,那么为什么我们要用这些题目来衡量软件工程师的水平呢?

算法题的阴暗面——对于生命中的许多哲学问题,这些有毒的算法题是有阴暗面的。事实是,有大量的人都在试图涌入科技行业。在LinkedIn上发布了一个职位后,不到一天的时间,就会收到一百多名求职者的申请。几乎没有哪个公司有能力来面试他们所有人。真实情况是,这些算法题目是作为一种机制来筛掉那些不适合该职位的或没有“基本”编程技能的应聘者的。问题在于,在这种情境下,大家似乎对“基本”一词含义的理解都有所不同。

我们不知道算法题的合适难度是什么样的——在过去7个月的面试过程中,我在面对算法题时遇到了各种各样的困难。简单的遇到过要求写一个函数来倒置字符串,难的遇到过要求模仿一个社交网络以及写一个图像过滤算法。曾经有一家公司要我进行了两次单独的代码面试。第一场中我被要求写一个简单的排序算法,我轻松搞定了。第二场我被要求使用动态编程编写一个递归置换生成器,这可不简单。当时我完全被难住了。在面试结束时,我问面试官:“这个问题对于电话面试来说似乎有点难了。贵司的业务代码经常用到递归算法吗?”他回答道:“不是的,我们不用递归。”“那么置换呢?你们用到过吗?”他回答说:“我们的算法不需要用到置换。公司大多数工程师们的工作重心都在用户界面和基础架构上。”其实这一点我能理解。举这两个例子是想展示不同公司中对相似的技能水平职位的要求。那么,为什么这两家公司选择的面试题目难度不同呢?

这种衡量方式比俄罗斯转盘好点有限——假设你是一名面试者。在过去的几个月中你一直在研究所有可能的与编程面试有关的问题。然后假如说你申请了A公司。A公司要求你写一个二叉树搜索算法。太棒了!上周你刚刚复习完了二叉树!你顺利通过了面试。然后再假设你申请了B公司。B公司要求你实现一个字典树(trie树)。啊啊啊不要啊!你忘了复习字典树!因为你没有复习到这个问题,所以最后没能通过面试。现在颠倒顺序,假如说B公司问你二叉树算法,A公司问你字典树算法:那么显然,能否被某家公司雇用纯粹取决于你被问到哪个问题。

时间限制是有害且带歧视性的——通常在电话筛选中,对方给你解决代码问题的时限是45分钟。用这些时间来解决一个简单问题绰绰有余。但是,当对方要求你编写一个复杂的算法时,45分钟就显然很荒谬了。当我被要求写出Conway’s Game of Life时,我花了50分钟才写出能够运行的代码,然后我就几乎没有时间来进行测试了。当我被要求编写图像过滤算法时,光是理解题目我就花了15分钟。最后我时间不够了。如果是在现实世界中,编写这样一个复杂的算法,可能需要一周的实施时间以及一个月,甚至更长时间的实际测试才行。这是最起码的。那么为什么我们会要求工程师们在面试中45分钟就搞定呢?

面试的过程催生了一种小作坊式的生意——所有这些算法题的乱象都始于像Google这样的知名公司。有一些在这些受欢迎的科技公司工作的工程师,他们发现可以通过为应试者们提供些面试准备材料来赚点外快。有两本这样的书很有影响力:《破解编码面试》(Cracking the Coding Interview)和《编程面试要素》(Elements of Programming Interviews)。这两本书都旨在提供指导性的面试准备材料。问题在于,行业也接触到了这些书籍,并根据书籍的内容制定面试计划。然而,随着越来越多的人都能够通过这些书中列出的基本面试问题了,这些公司就会觉得他们选出来的候选人的技能是最低档的。因此,他们就编写了新的,更具挑战性的算法问题,以与其他公司区分,并筛选出“所有看似合格的候选人中间那些更为合格的候选人”。有关某些公司现在的和以前的最高级工程师的轶事有很多,他们说现在的面试过程越来越难了,要让他们现在去面试,肯定会被刷。我看过一个演讲,里面的故事很棒。在某“顶级”科技公司中,流程是当候选人进行面试时,他或她会产生一份包含面试表现的数据包。然后,数据包由一个委员会接手,这个委员会的工作就是公正地审查数据包,以决定是否雇用。直到有一天,委员会变得过于挑剔,以至于在连续的数月里他们连一个候选人都没接受。HR们听说以后,决定进行一项实验。他们向委员会发送了新一轮的数据包,而委员会也再次拒绝了所有候选人。HR们随后召集他们参加会议,并解释说,他们刚刚查看的数据包实际上就是委员会成员们在面试进入公司时所产生的。也就是说他们不知不觉中自己拒绝了自己!在这样的标准下还有谁能通过面试呢?

3、既然要衡量候选人的能力,那为什么不花点时间了解一下他们呢?——几周前,我看了一个某位在“顶级”公司进行过大量面试的面试官的演讲。用他的话说,他的演讲的目的就是精炼出一个能“在面试中提取信号”的策略。啥?!现在的人就不能好好了解一下他人吗?这种态度完全就像是冷漠的机器人,而且说实话,很反乌托邦。以后又会变成什么样子?是否要扫描候选人的大脑来寻找和已知的高水平候选人之间的相似之处了?这种态度散发着自我主义和组织男子气概恐怖地组合到一起之后的恶臭。在我看来,现在的公司更害怕招到糟糕的候选人,而不会为可能招到优秀的候选人而兴奋。在公司们能再次对招聘感到兴奋之前,对求职者来说,情况恐怕不会有改善了。最糟糕地方在于,现在求职者从招聘人员那里得到的第一条信息就是,你看上去是个很好的候选人,但是一旦进入面试,你只会发现对方只会怀疑你名不副实。我认为,应以谨慎的乐观态度而不是怀疑。

我很确定这个话题我还可以一直说下去。我的笔记中还有大约八点要写。但是到现在,这篇文章看起来更像是一篇抨击的长篇大论,而不像一篇博文了。我希望至少能够表达一下在过去七个月里自己遇到的一些困难。到了后来,我发现自己很矛盾。我现在的老板刚刚解雇了我所在的整个团队,然后我就失业了,只能独自写下自己这一肚子的苦水。我不确定是不是想要再次经历一遍求职的过程。我想了很多,从自己的经历里总结出了一些简单的结论:

我知道如何编写软件——两年来我已经写了大约85,000行Java生产代码了,这些代码对我正在开发的产品产生了非常积极且显著的影响。我用Python写过一些非常复杂的机器学习算法,同时也写了许多脚本。我还为嵌入式图形等等各种底层应用程序写过嵌入式C和C ++。我自学了Flutter,发布过一些应用程序。我自学了Clojure,这个过程极大地打开了我的眼界。我参与过一些C#项目。我知道如何建立一个静态网站。我拥有一个计算机科学学位。

我不知道为什么其他人不给我编写软件的机会——公众们号称的公司绝对渴望雇用软件工程师的说法,与一名软件工程求职者面对的残酷现实之间完全是不相符的。这些“要么做对要么死”的高压编程题似乎更像是一种模糊机制,而非有价值的评估工具。使用这种工具就像是在雇佣一名警察时,直接朝他开枪,却并没有先问他对法律有什么了解。

我不知道站在面试官的角度是什么样的——事实是,我所批评的流程可能是公司筛选好坏候选人的唯一方法。我从未参与过招聘流程,肯定有些事情是我所不知道的。

我的结论是:

适者生存原则是真实存在的——不管我觉得自己多么有资格得到一份知名科技公司的高薪职位,事实就是,还有很多其他人在与我竞争。就像生活中的其他一切事情一样,资源是有限的,但人们的需求是很高的。每个人以及他的哥哥/弟弟都希望通过写代码获得丰厚的报酬。我怀疑,业界之所以会设置如此凶残的筛查标准的原因是,客观地来说(不管这里的客观二字意味着什么)技能水平较低的人所占的比例要比那些有真才实学的人高得多。不幸的是,这意味着无论你经验多么丰富,都必须与大量的对手竞争。正如任何经历过编程学习过程的人都能理解的那样,即使只是最低限度地把基础技能掌握熟练,学习曲线都是非常陡峭的。除此之外,胜任一份工作所需的核心能力的知识体系是非常广泛的。而且,要熟练掌握一套特定的相关且可以市场化的技能是很难的,想做到游刃有余更是难上加难。无论一个人成为软件工程师时走的是哪条路,很显然的一点都是,竞争是生活中无可避免的事实,并且在这个行业中还相当激烈。

等级结构是真实存在的——我对招聘启事中软件工程师的分级感到困惑。似乎只分为两个等级:“非高级”以及“高级”。一般而言,招聘启事中的高级职位往往要求5年的工作经验。这种分级似乎不够细。我们要如何称呼拥有20年经验的人呢?他们真的和5年经验的人一样吗?就我自己而言,我们要如何称呼具有4年经验的人?我不算是刚毕业生的,我自己知道如何编写软件,我知道版本控制如何工作以及如何适应敏捷环境。根据不同的情况,我需要别人为我的工作设定方向。而问题的复杂性甚至不止如此,还存在着在具体的某项技术方面经验年限的问题。如果一个人有5年的Java编程经验,后来转到了一个使用Python的团队,并且团队内没有在Python方面超过两年以上经验的人,那么这个人应该被定为初级人员吗?这个问题令人困惑,光这一点就值得写一整篇文章来讨论,即使那样,甚至都可能讨论不出个所以然来。我想说的重点是,我是介于初级人员和高级人员之间的,而适合我经验水平的选择似乎很少。

抱怨并没有什么用——或早或晚,我都将不得不去另谋一份差事。即使我不喜欢这种面试方式,也将不得不再次陷入这个循环。但暂时来说我已经受够了。因为一遍又一遍地重复相同的过程似乎不可能有什么结果。终有一天,我还是会坐上旋转木马,但目前,我还是先选择让自己保持理智的唯一方法吧:

那就是先暂时退出这个循环。

原文链接:
https://www.jarednelsen.dev/posts/The-horrifically-dystopian-world-of-software-engineering-interviews

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-05-13
本文作者:Jared Nelsen
本文来自:“CSDN”,了解相关信息可以关注“CSDN

网友评论

登录后评论
0/500
评论
云栖号资讯小编
+ 关注
所属团队号: 云栖号资讯