我非常了解JavaScript,但是我炸毁了编码面试[关闭]


33

因此,我目前正在寻找担任前端开发人员的新职位。我非常了解JavaScript,并且可以在闭包,库里开发,原型继承,设计模式,应用程序性能和总体前端体系结构方面颇具诗意。但是,我仍然最终轰炸了求职面试。(仅供参考,我面试的大部分工作都是使用某种MVC框架构建SPA)

通常,编码测试只是我从未专业接触过的小代码片段。喜欢写一个函数来解决某种数学问题。除了一手握住手机试图让一个陌生人看到您的屏幕并看着您键入的每个字符的继承笨拙之外,我只是通常在现实世界中看不到这种东西。

这是我所缺乏的一套严肃技能吗?还是面试官在问我无关的问题。我想我应该进行函数式编程和算法印章工作,但是我没有在网络上(或印刷版中)找到许多好的资源有任何建议吗?


4
尝试一些项目的欧拉计划
Peter K.

11
并为您的手机获得免提套件?
AakashM 2014年

为什么要在手机上进行编码测试?当您获得工作时,是否期望您以这种方式工作?
Burhan Ali 2014年

2
@BurhanAli,电话用于交谈,这是面试第一阶段的标准操作。
greenoldman 2014年

3
是的,我认为当今的一些严峻考验完全是胡说八道。我特别鄙视“带回家”的测试,在测试中他们告诉您一个小时内可以完成某件事,但是实际上,需要花费半天或更长时间才能正确完成。我拒绝直接这样做。你真的是面试官的想法。他们中的一些人认为可以评估真实技能的良好测试。其他面试官不知道自己在做什么,他们有自己的个人议程和不安全感。
林戈2015年

Answers:


52

编写代码只是面试过程的一部分。

实际解决逻辑问题只是代码编写任务的一部分。

采访者希望确保:

  • 您可以编写代码。许多在语言方面具有十年专业经验的应聘者根本不会编写任何代码,而该测试旨在拒绝这些应聘者。

  • 在编写代码之前,请先考虑问题。许多人会跳到键盘上,写几十行代码,然后发现他们误解了最初的问题,因为他们没有花时间去思考它。

  • 您可以在编写代码时适应自己。假设您找到了解决方案,但是当您开始实施它时,似乎您的第一个想法并不是最好的想法。您可以快速切换到更好的代码,最终重构您编写的代码吗?

这也意味着这种采访应该更具互动性。不用单手打字,而是购买免提工具包或通过Skype打电话并使用耳机。在工作中输入内容时输入内容,同时评论和解释您的工作:这会突然变得不那么尴尬。

您完成结对编程了吗?如果是,则采访情况非常相似,不同之处在于采访者可能不会给您他的意见,并且在结束后您也不会要求他与您切换键盘。

以下是一些纯数学问题的示例,以及它如何显示开发人员的非数学技能。

示例1:简单的编码练习

您需要在JavaScript中实现斐波那契数计算器。您应该能够更改索引。斐波那契数列遵循以下规则:

  1. 序列的前两个数字是0和1
  2. 每个后续数字是前两个数字的和。

示例:F 0 = 0,F 1 = 1,F 2 = 1,F 3 = 2,F 10 = 55。

你三分钟

在这里,面试官希望您尽快思考,找到解决方案并快速实施。这样的练习与实际开发人员的工作无关,并且与您获得CS学位时所能找到的东西更接近,但是面试官喜欢这种事情,所以让我们开始吧。而且,由于时间限制,不可能进行任何自动化测试,因此面试官可能不会期望您这样做。

“算法的描述使我想到了递归。第二条规则导致以下递归函数。”

var fibonacci = function (n) {
    return fibonacci(n - 2) + fibonacci(n - 1);
};

console.log(fibonacci(10));

“为了结束递归,我们将通过替换fibonacci函数主体来添加特殊情况。”

switch (n) {
    case 0: return 0;
    case 1: return 1;
    default: return fibonacci(n - 2) + fibonacci(n - 1);
}

“完成。”

结论

正如我所说,这种练习与开发人员的实际工作完全无关。它使它变得毫无意义吗?并非如此,至少因为它表明此人:

  • 能够思考问题。一些候选人将完全迷失方向,在压力下,他们将花费比分配的时间更多的时间来思考解决问题的可能方法。

  • 知道递归或能够通过普通循环规避递归。稍后,访调员可能会问是否有使用/不使用递归的方法,以及递归的好处/缺点是什么。

  • 了解编程语言的基础知识。使用人员switch,保护子句,条件语句还是字典都没有关系:根据背景,不同的候选人将选择不同的工具来完成同一件事。

  • 始终专注于问题,而不会带来单元测试,可伸缩性或性能等问题。然后,面试官可能会问,为什么在绩效方面,上述职能很糟糕,希望候选人解释应该采取什么措施才能使绩效达到合理水平。

示例2:棘手的问题

您需要在JavaScript中实现斐波那契数计算器。它应该尽可能快。您应该能够将索引的范围从0更改为100。斐波那契数列遵循以下规则:

  1. 序列的前两个数字是0和1
  2. 每个后续数字是前两个数字的和。

示例:F 0 = 0,F 1 = 1,F 2 = 1,F 3 = 2,F 10 = 55。

你三分钟

现在,我们有一个有趣的约束条件,它表明面试官并不真正在乎候选人解决​​问题的能力,而是在乎他猜测哪些方法比其他方法更快的能力。

这些棘手的问题通常会邀请棘手的答案。在给定时间限制的情况下,无法进行多种实现,对其进行基准测试,剖析最快的实现并提供最佳解决方案。

相反,该怎么办:

“让我Google“第一个斐波那契数字” ... 看起来很有希望。使用一个简单的(可能是oxymoron)正则表达式,我们可以构建一个用逗号分隔的值列表。”

sed -e "s;\([0-9]*\) \([0-9]*\);'\2',;g" fbncc10.txt | tr '\n' ' '

“最后,程序本身。”

var map = ['0', '1', '1', '2', '3', '5', '8', '13', '21', '34', '55', '89', '144', '233', '377', '610', '987', '1597', '2584', '4181', '6765', '10946', '17711', '28657', '46368', '75025', '121393', '196418', '317811', '514229', '832040', '1346269', '2178309', '3524578', '5702887', '9227465', '14930352', '24157817', '39088169', '63245986', '102334155', '165580141', '267914296', '433494437', '701408733', '1134903170', '1836311903', '2971215073', '4807526976', '7778742049', '12586269025', '20365011074', '32951280099', '53316291173', '86267571272', '139583862445', '225851433717', '365435296162', '591286729879', '956722026041', '1548008755920', '2504730781961', '4052739537881', '6557470319842', '10610209857723', '17167680177565', '27777890035288', '44945570212853', '72723460248141', '117669030460994', '190392490709135', '308061521170129', '498454011879264', '806515533049393', '1304969544928657', '2111485077978050', '3416454622906707', '5527939700884757', '8944394323791464', '14472334024676221', '23416728348467685', '37889062373143906', '61305790721611591', '99194853094755497', '160500643816367088', '259695496911122585', '420196140727489673', '679891637638612258', '1100087778366101931', '1779979416004714189', '2880067194370816120', '4660046610375530309', '7540113804746346429', '12200160415121876738', '19740274219868223167', '31940434634990099905', '51680708854858323072', '83621143489848422977', '135301852344706746049', '218922995834555169026', '354224848179261915075'];

var fibonacci = function (n) {
    return map[n];
};

console.log(fibonacci(10));

结论

棘手的问题邀请棘手的答案。不要太英勇,只有三分钟的时间也不要开始进行基准测试和性能分析。考虑使用您的经验来解决问题的聪明方法。我的经验告诉我,使用地图可能比计算数字更快。可能是错误的,但是鉴于时间的限制,应该尝试这种尝试。

了解您的工具也有帮助,并且是开发人员技能的重要组成部分:不了解正则表达式,我要么花分配的三分钟时间搜索一个逗号分隔的列表,要么开始编写解析器来构建所需的数组。

记住,一个好的开发人员不是立即开始编码的人,而是知道在有更好的机会时如何避免编码的人。一些面试官会毫不犹豫地给您看似编码的作业,但几乎不需要任何编码。

示例3:完成应用程序开发

您需要在JavaScript中实现斐波那契序列。序列的长度在程序执行期间确定。该顺序遵循以下规则:

  1. 序列的前两个数字是0和1
  2. 每个后续数字是前两个数字的和。

例如:0、1、1、2、3、5、8、13、21、34、55、89。

该应用程序应显示为网页,允许用户通过输入字段指定序列的长度。

你有一个小时。

开始吧。

“示例序列非常有帮助,因为它可以让我进行大量的单元测试,以确保我的实现看起来不会完全错误。通常,我将Mocha用于node.js或将QUnit用于客户端JavaScript,但是在这里,为了简单起见,我将仅抛出一堆测试函数。

“我首先创建index.htmfib.js归档。然后,我填写index.htm了真正的简约代码,而不是与W3C兼容的代码(如果您也对我的HTML技能也感兴趣,我们可以稍后再讲)。”

<label>Length</label> <input id="length" value="15" />
<input id="compute" type="button" value="Compute" />
<div id="result" style="font-weight:bold;"></div>
<div id="tests"></div>
<script src="fib.js"></script>

“现在让我们编写一些代码,这些代码将调用斐波那契生成器函数并显示结果。”

fibonacci = (function () {
    var compute,
        init;

    compute = function (length) {
        // TODO: Implement Fibonacci sequence.
        return [1, 2, 3];
    };

    init = function () {
        var button = document.getElementById('compute');
        button.addEventListener('onclick', function () {
            var length = parseInt(document.getElementById('length').value, 10),
                result;

            console.log(
                'Computing Fibonacci sequence of length ' + length + '.'
            );

            result = compute(length);
            document.getElementById('result').innerText = result.join(', ');
        });
    };

    return {
        compute: compute,
        init: init
    };
}());

“是时候第一次运行代码了,……不起作用。没发生什么事。为什么?”

“好的,我忘fibonacci.init();了最后。我添加了它,但是仍然没有任何反应,尽管它至少应该在控制台中显示消息。等待,对,不是onclick,而是click;我经常使用JQuery,以至于开始忘了纯JavaScript中事件的名称。”

“让我们添加一些测试。”

ensureAreEqual = function (expected, actual) {
    var testResultsContainer = document.getElementById('tests');
    testResultsContainer.innerText += (expected.equals(actual) ?
            '.' :
            ('Actual [' + actual.join(', ') + '] is different from ' +
             'expected [' + expected.join(', ') + '].'));
};

test = function () {
    ensureAreEqual([0], compute(1));
};

“比较数组可能很棘手,所以我只是Array.prototype.equals从此答案中复制粘贴 代码。”

“现在我们运行该应用程序,它将显示:”

实际[1、2、3]与预期[0]不同。

“鉴于我们return [1, 2, 3];的斐波那契数列的实际实现(),该测试失败了,这是人们高度期望的。是时候改变这一点了。”

“从原始语句开始,斐波那契数列以开头[0, 1],因此compute变为:”

compute = function (length) {
    var fib = [0];
    return fib;
};

“这使通过第一个测试成为可能,我们现在可以编写第二个测试。”

ensureAreEqual([0, 1], compute(2));

“它失败了,所以我们回到compute并修改它。”

compute = function (length) {
    var fib = [0, 1];
    return length === 1 ? [0] : fib;
};

“现在,两项测试都通过了,现在该转向非边缘案例了。”

compute = function (length) {
    var fib = [0, 1],
        i,
        next,
        current = 1,
        previous = 0;

    for (i = 2; i < length; i += 1) {
        next = current + previous;
        previous = current;
        current = next;
        fib.push(next);
    }

    return length === 1 ? [0] : fib;
};

“这三个测试现在都通过了,除了对于较大的长度(例如100)而言,结果看起来不正确。为了正确地获得这些结果,我们应该使用任意精度库。还有一些需要改进的地方。例如,命名约定有时太糟糕了(是什么fib?)。与HTML相关的JavaScript代码以及测试代码也应转到其他对象。另外,我还没有测试compute(0),也没有检查输入。”

结论

通过遍历示例,您可能会看到面试中期望的互动。并非一切都很顺利(一开始我犯了一些错误,这使我陷入了一个尴尬的境地,当我运行应用程序时什么也没有发生),并且如果我们必须支持较大的序列长度,最初的方法很la脚,但是我已经实现了证明:

  • 我可以处理不同的问题,
  • 我使用测试驱动的开发,斐波那契序列是一个极好的机会,
  • 当源值得信赖时,我会复制粘贴代码,并且从头开始编写代码似乎极其复杂且容易出错,
  • 我并不太依赖JQuery之类的库,
  • 我选择了合适的范围:由于面试官想检查我的JavaScript技能,因此我不会浪费时间来编写完美而干净的HTML:不在这里花费时间可以花更多时间在编写单元测试上,
  • 我知道何时完成并告诉我已完成,同时请记住,很多事情都不是完美的(例如compute(0)可能会失败,但对于演示来说并不重要)。

这正是面试官对您的期望。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.