我因为算法而面试失败了
照片由Siora Photography在Unsplash上拍摄
你好,开发人员。
过去几周,我一直在参与一家大公司的招聘流程。
这是一次非常好的经历,它让我对招聘、代码挑战以及如何(可能)为面试做好更多准备有了更多的了解。
正如你在标题中看到的,我没有通过,但我经历了所有阶段。所以,如果你正在努力寻找第一份工作,或者即使你正在考虑换工作但已经好几年没参加面试了,这篇文章对你来说可能也挺有意思的。
我将解释所有阶段,并提供一些细节和想法,但我在这里的主要重点是说明我在最后一部分失败的地方和原因。
希望你喜欢它,也希望我的经验能对你有所帮助!
目录
第一阶段:获得面试机会
一般来说,公司中一种非常常见的做法是激励人们(用钱)推荐专业人士来填补空缺职位(这就是为什么你应该尽可能与互联网内外的人们建立良好联系的一个很好的理由)。
我的一个朋友推荐我去他的公司工作。工资不错,福利待遇也很好,看起来是个很不错的工作环境,不妨试试看。
我只需要对我的在线简历做一些调整就可以了。
第二阶段:人力资源(又称HR)
公司的 HR 刚刚打电话给我,了解一些情况。
他们询问了我的所有经历、我一生中做过的事情、我是否具备一些特定的知识(例如 React、测试、Redux 等),还询问了我所在的公司。
说实话,这个电话似乎只是对那些在简历上撒谎的人的一个过滤器,因为一切都非常基础和琐碎。
我对我给她的所有答案都非常有信心,在通话结束时她给了我积极的反馈,然后她会与技术主管和团队经理安排下一阶段的安排。
第三阶段:管理者
接下来的一周,我与“经理们”进行了一小时的会议(现在有网络摄像头)。
他们的工作是了解我的软技能。很多问题都是这样的:
- 我职业生涯中最自豪的时刻是什么
- 我做过的最糟糕的技术决策是什么
- 我如何处理冲突
- 我如何处理自上而下的决策
- 我如何处理艰难的讨论
在这些问题之间,他们不断地要求我举例说明,我经历过的一些情况可以证明我以我的方式思考或解决问题。
这非常好,因为我可以回忆起职业生涯中的一些好与坏的时刻,这让我作为一个专业人士和一个人成长了很多。
当我挂断电话时,我仍然对最终结果非常有信心。
几天后,人力资源部打电话给我,说经理们很喜欢我以及我回答他们问题的方式(也许有一天我可以详细分享我经历过的一些情况以及我目前与人打交道和工作的方式)。
她给我的唯一反馈是:“我需要少一些跟随者的感觉”。
而且……当然,他们认为我更像是一个追随者而不是领导者,因为说实话,我快 30 岁了,我有点失去了精力去继续进行关于技术品味和个人编码方式的无意义的讨论。
我有我的观点,而且我总是可以争论为什么我有这些观点,但说实话,当讨论涉及到自我意识或个人喜好时,我只是放弃并让人们做他们想做的事。
我不关心:
- 最好的 JS 框架是什么;
- 最好的状态管理库是什么?
- 我们是否应该使用 reduce 或 map + filter
- 我们是否应该使用
it
或test
开玩笑的断言
我关心的是:
- 哪种解决方案最适合该问题;
- 好的命名;
- 测试代码;
- 尽可能提供简单的解决方案;
- 运送产品;
- 我月底的工资;
过去,我常常无休止地争论什么最好,什么最坏。现在我仍然会进行这样的讨论,但如果我发现我们不会取得任何进展,我就会接受,然后继续我的生活。
当然,别傻了。如果我确信有人做出了错误的决定,并且我能证明这一点,我愿意不惜一切代价来捍卫它。
从公司的角度来看,什么样的人格最有价值?我们可以就这个问题进行长时间的讨论。
第四阶段:HR(再次)
下一阶段是再次打电话给人力资源部,她问了我一些经理在前一周问我的问题。
她想亲自了解我的软技能。
嗯,我没有在任何问题上撒谎,我给出了相同的答案。
我还试图解释为什么经理们认为我更像追随者,看来她明白了。
她又一次给出了积极的反馈,然后告诉我下一步将有两名开发人员来测试我的硬技能,并且会有一名 QA 经理在场观察整个过程。
第 5 阶段(最新):开发者
这是最棘手的阶段,我想向大家详细介绍一下整个过程。如果你们还有不明白的地方,我想推荐一些文章,或许能解答这些问题。
我收到了一封电子邮件,其中有一些他们可以询问的主题,例如 JS、CSS、测试、状态管理、React 和 Http,但仍然不清楚他们将如何处理这些概念。
原计划缩短 1 小时 30 分钟,但实际开始时间晚了 10 分钟。
当我加入聊天室时,我们像往常一样做了一些演示,他们向我解释了它是如何工作的:
- 20 分钟了解我目前所做的事情;
- 30分钟回答并解释技术概念;
- 30 分钟完成代码挑战。
关于我
在这里,我必须再次解释我目前的工作内容,但要更加技术性一些。
嗯,只有我和另一个人负责整个网络生态系统,所以我知道产品是什么以及它的结构如何。
我向他们详细解释了这个平台是什么、我的职责是什么、我的日常任务是什么,以便让他们了解我们如何处理这些任务等等。
有时他们会要求我深入研究某些主题,但最后一切都很容易。
技术问题
这里开始有点棘手,因为他们开始了一个特定的测验。我尽量不深入解释和解答,而是简单介绍一下我的印象和想法,并分享一篇文章来详细解释这些问题和概念。
JavaScript 问题
你能解释一下 var、let 和 const 之间的区别吗?
这确实有点棘手,尤其是如果你最近才开始学习 JS。我相信人们总是说:总是更喜欢,const
但如果你需要重新赋值,那就用let
。
幸运的是我已经完成了从 var 到 let 和 const 的转变并且清楚地记得它是关于的scope
。
为了解释为什么即使我们使用时我也使用了对象突变const
,所以他们从这里得到了第二个问题:
如何冻结一个物体?
我之所以知道这个概念,是因为我在学习 ES6 时犯了一些 bug。在花了几个小时试图弄清楚我的对象为什么会发生变异之后,我找到了关于原生 API 的文档Object.freeze
。
这很简单。当我们冻结一个对象时,任何改变对象的操作都不会改变对象本身。请注意,这种冻结仅发生在浅层(深度为 1 个对象层级),并且不会冻结嵌套的对象和数组。

JS 中的 const 📦、seal 🤐、freeze ❄️ 和 immutability 🤓
本杰明·莫克 ・ 2020年1月11日
你能解释一下什么是 DOM 吗?
我认为那是最简单的一个,尽管我忘记了这个首字母缩略词的含义(D ocumment O bject M odel)。
你能解释一下事件如何在 DOM 中传播吗?
我知道这个问题是因为在我学习 React 之前,我创建了自己的 JS 框架(这是一个很好的实验),从中我学到了很多关于在不同级别捕获事件以及冒泡如何工作的知识。
使用单个事件来捕获事件有什么好处?
它仍然与这个问题有关,说实话,我不确定。
我记得以前用 Vanilla JS 实现的时候,我有一个表单,把 onChange 绑定到所有输入框上,我直接在关form
卡里做了,然后设置了某种开关来决定更新哪些信息或执行哪些操作……不过我忘了为什么这么做了。我当时的假设是性能问题。
开发人员告诉我就是这个原因,并给了我一个很好的例子。想象一下,一张表有成千上万条记录。如果我们给每一行都附加一个事件,肯定会出现性能问题,因为 DOM 中会有成千上万个事件需要调度。
我真的很喜欢这个例子。
您知道请求动画帧 API 是什么以及我们为什么要使用它吗?
我想我在 5 年内使用过一两次请求动画帧 (RAF) API,所以我不确定为什么存在这样的 API,然后我尝试猜测:“告诉浏览器我们要做一些动画并获得一些性能。”
他们告诉我这是正确的。
CSS 问题
您了解不同的显示器吗?
这个问题我没怎么理解。我不确定是否需要解释每个显示,还是直接说“是的,我知道”。
但我的回答是说我有几个显示器inline
,比如inline-block
,,,,,等等block
。grid
flex
令我惊讶的是,这正是他们想听到的。
display inline 和 display inline-block 有什么区别?
这一点我并不记得。
我知道 inline 和 block 之间的区别,因为这在 CSS 中很常见,但我记不住inline
和之间的区别inline-block
。
开发人员向我解释说,当我们inline-block
可以定义元素的边距和填充时,在显示内联时我们不能。
我怎样才能使某物垂直居中?
这也是另一个棘手的问题,也许是因为我们有几种方法可以做到这一点。
我记住的方法是display: flex
结合使用justify-content: center
和align-items: center
。
我的回答已经足够好了。
HTTP 问题
您能告诉我们 HTTP 中有哪些可用的方法吗?
这并不难,因为我有时会在 Node 中使用后端。
GET
POST
DELETE
PUT
PATCH
PUT
然后他们问我是否知道和之间的区别,PATCH
这很棘手。
我记得一个用新内容替换了整个数据,另一个只是更新了发送的信息,但我不知道哪一个做了什么。
他们告诉我这是正确的,但进行部分更新的是 PATCH,而进行完全替换的是 PUT。
除了这个问题之外,他们还问我是否知道其他方法,说OPTIONS
实话,我不知道。
我经常在网络选项卡中看到OPTIONS
请求,但我从未问过自己那到底是什么。
HTTP状态码是如何划分的?
基本的 HTTP 内容。
我只是记住了这一点,因为自从我开始构建使用 API 的应用程序以来,我一直很好奇这些代码是什么,我发现了这个https status dogs,这是一种理解每个代码的绝妙方法。😁
技术挑战
我感觉我已经掌握了测验题目,并且已经为技术挑战做好了充分的准备。
“30分钟也许足够解决一些问题。”我想
然后他们向我发送了一个带有单个 JS 文件的代码沙盒链接:
// index.js
/*
We have lots of deployment dashboards where we have drop-down UI to select an application version to deploy. We want to ensure that software version numbers delivered to our UI from the back-end API are always ordered with the newest (highest) available version at the top.
Eg:
const input = [0.1.0, 3.2.1, 2.2.3, 0.1.1];
sortVersions(input) should return [3.2.1, 2.2.3, 0.1.1, 0.1.0];
*/
const sortVersions = (unsortedVersions) => {
// code
};
export default sortVersions;
还有一个包含一些断言的测试文件来确保它是正确的
// index.test.js
import sortVersions from './index';
it('should sort correctly numbered versions', () => {
const versions = ['0.2.0', '3.1.2', '0.1.6', '5.0.0'];
const output = ['5.0.0', '3.1.2', '0.2.0', '0.1.6'];
expect(sortVersions(versions)).toEqual(output);
});
// Other assertions
解决该挑战的规则:
- 我可以使用 Google 搜索 JS API
- 我无法使用谷歌来具体搜索该问题。
第一个断言非常简单。我的解决方案很简单:
const sortVersions = (unsortedVersions) => {
// code
return unsortedVersions.sort().reverse();
};
并且它通过了!:)
然后我必须解决第二个断言:
// index.js
it('should sort correctly numbered versions with different lengths', () => {
const versions = [
'1.3.0.9',
'0.2.0',
'3.1.2',
'0.1.6',
'5.0.0',
'3.3.3.3',
'3.3.3.3.3',
'3.10',
'0.2.0',
];
const output = [
'5.0.0',
'3.10',
'3.3.3.3.3',
'3.3.3.3',
'3.1.2',
'1.3.0.9',
'0.2.0',
'0.2.0',
'0.1.6',
];
expect(sortVersions(versions)).toEqual(output);
});
而我却被困在这里了。
我之前的解决方案没有涵盖这种情况。它只是返回:
[
'5.0.0',
'3.3.3.3.3',
'3.3.3.3',
'3.10',
'3.1.2',
'1.3.0.9',
'0.2.0',
'0.2.0',
'0.1.6',
];
对于简单的字符串排序来说,原因显而易见。默认情况下,排序时会按照字母顺序进行,3.3
先排序在 之后的那个3.1
。但在语义版本控制中,我们知道3.10
大于3.3
。
在尝试了各种排序方法之后,我想到了一个想法,即根据最大的版本使所有版本的大小相同。
说实话,那一刻我已经很紧张了,因为我无法思考如何解决那个“简单”的问题,因此我开始变得焦虑。
他们给了我一些关于如何解决这个问题的建议,但还是有点难理解。不是因为他们解释得不够清楚,而是因为我当时同时在思考很多事情。
当我编写一些代码以使所有版本的长度相同时,时间就结束了。
开发人员问我,如果有更多时间我将如何解决这个问题,我解释说,我的想法是让所有版本的长度相同,以便我可以比较每个块。
我感谢他们的时间,然后我们就挂断了电话。
如果你想知道如何解决这个问题,我推荐你看看StackOverflow 上的这个答案。我刚刚测试过,它解决了所有问题。
测试后
老实说,接完电话后我感觉自己很失败。
在过去的5年里,我已经解决了太多比这更难的问题,但到最后,我却被一个排序问题打败了,我到底出了什么问题?
但我试图安慰自己:“好吧......我之前的所有步骤都进展顺利,即使他们问我技术问题......这应该不算太多”。
最后一次人力资源电话
经过一周的等待,看看我是否被批准,我是否会被录用,人力资源部的人打电话给我说:
“很遗憾,我们不会继续与您合作”
我只觉得非常沮丧。
然后我问她为什么,以及我是否可以得到关于我可以改进的地方的反馈,她告诉我:
开发人员非常欣赏你的沟通能力和面试时的活力。他们很高兴你正确地回答了大部分技术问题,但他们认为你在解决最后一个问题时表现得不太好。
嗯……好的,我说。
我可以从很多方面反对这个决定,但说实话,决定已经做出了。它不会改变任何事情。
我关掉电话,停下来5分钟来消化失败的感觉,并努力思考这一切的过程。
关于雇用 X 我们的技能的想法
我不知道你这辈子是否经历过面试官。我有过,而且我可以肯定地说:这绝非易事。因为招聘流程通常非常艰难。
我们需要以某种方式定义评估候选人的步骤和事项,尽管我们的目标是透明和分析,但这绝不是一个完美的方法。
人们的思考、学习、解决问题和交流方式各不相同,在招聘过程中,我们尝试创建一些我们对人们期望的指南和过滤器。
意思是,如果某人不符合你的期望,这或许是一个好兆头,表明这个人不适合这份工作。但是……这是否意味着这个人不会成为一位合格的专业人士?
我不这么认为。
我记得当我终于得到我的第一份开发人员工作时,我提出了类似的代码挑战,并且我做到了。
想知道三年前的我和现在的我有什么区别吗?那时候,我每天都在 FreecodeCamp 平台上不断练习算法。
得到这份工作后,我证明了自己是一名有价值的员工,我可以肯定地说,我在面试中所做的艰苦思考并不是让我推出产品的原因,因为很少有时候我不能使用谷歌来查看人们如何解决这个问题,并在其基础上创建另一个解决方案。
我遇到了一些有挑战性的问题需要解决,我花了很短或很长的时间解决了它们,有时是借助别人的帮助,有时是自己解决的。
为了得到我现在的工作,我必须创建一个使用公共 API 的 React APP,添加测试(E2E)、无限滚动、页面之间的动画并托管在某处,解释我的解决方案、我的困难,并进行结对编程来解决我遇到的一些问题。
这基本上就是我每天大部分时间所做的事情来赚钱。
无法解决算法是否意味着我不是一名优秀的开发人员?
我不这么认为。在我看来,这只是说明我在某些情况下没能解决问题。不过,这毕竟是他们评估专业人士的标准。
我在这里的目的不是抱怨为什么我没有被录用,而是要向你明确一点:面试失败并不意味着你作为一名专业人士的失败。
学习内容
总的来说,整个过程让我学到了很多东西。
在接下来的面试中,我会做好准备,轻松回答关于软技能的问题。我永远不会忘记inline
和之间的区别inline-block
,或者方法是什么,以及和HTTP OPTIONS
之间的区别。PUT
PATCH
但我最大的收获是:尽量为一切做好准备。
你可能会被要求使用 React、Vue、Angular 等来实现一些 APP,甚至解决 JS 中的一些棘手问题。
为此,我已经开始每天花几个小时尝试解决Codewars、FreeCodeCamp Learn和Codility等平台上的问题。
我仍在我的个人网站上实施新事物,并更加了解如何创建一个强大的前端应用程序。
结论
希望我的经历可以给你一些启发,让你了解如何才能获得第一份工作,或者至少为掌握招聘流程做好准备!
文章来源:https://dev.to/raulfdm/i-failed-an-interview-because-of-an-algorithm-3f9k