如何面试一个前端开发者?

Author : lovecicy

是的,招人很难!尤其要在短时间内判断一个人是否适合岗位更是一个高难度的工作。如何面试一个前端开发者,如何判断一个前端开发者的水平,这是对面试者的一个考验,曾就职于Twitter和Stripe这两家公司的Alex MacCaw和我们分享了他的面试过程和一些他设计的不同类型的面试问题,有兴趣看英文原本的请戳这里

Alex认为,理想情况下,应聘者应该有一份比较完整的GitHub‘简历’, 这样我们可以一起来回顾他们参与的开源项目。并且可以先浏览他们的代码,然后针对某一个具体的代码设计问他们一些问题。如果应聘者在这一部分表现非常优秀,就可以直接进入团队社交能力的考察部分。否则的话,他会让他们做一些编程题目。但是在国内公司,对GitHub简历可能还没有那么看中,当然如果面试者有一份好的GitHub简历,这肯定是很好的加分项。

Alex面试的时候是非常注重实践的,整个面试过程几乎全都是在写代码。他不会问一些比较抽象的或者算法相关的问题,因为他觉得这些知识未必是一个前端开发者所必需的。他问的问题看起来比较简单,但实际上每一类问题都可以让他洞悉应聘者在JavaScript的某一方面的知识。

通常面试时使用的是电脑而不是白板,应聘者可以使用任何适合自己的编辑器,但通常直接用Chrome的控制台来检查的应聘者的程序输出结果。

第一部分:对象原型

先从简单的来。实现一个spacify函数:接受一个字符串作为参数,然后把这个字符串的每个字符都用空格隔开后返回。例如:

spacify('hello world') // => 'h e l l o w o r l d'

虽然这个问题看起来非常容易,但结果却证明从这个问题问起是很合适的,尤其是对于一些电话面试者,他们声称了解JavaScript,却连一个完整的函数都不会写。下面是这个题目的正确答案,有的应聘者通过循环来实现也是可以的。

function spacify(str) {

  return str.split('').join(' ');

}

接下来这个问题是让应聘者直接为String对象增加spacify的函数,像这样:

'hello world'.spacify();

通过这个问题,可以了解到应聘者对于函数原型基础知识的掌握情况。另外这个问题经常会引发另外一个有趣的讨论:直接在prototype上尤其是在Object的prototypes上定义属性的风险。

最终的答案类似下面的代码:

String.prototype.spacify = function(){

  return this.split('').join(' ');

};

这时候还可以让应聘者解释函数表达式(expression)和函数声明(declaration)的区别。

第二部分:参数

接下来,会问一些简单的问题,这些问题可以了解到应聘者对参数对象的理解程度。

首先,调用一个尚未定义的log函数:

log('hello world')

然后让应聘者去实现log函数:接受一个string参数然后直接传给console.log(),正确答案就在下面,但有些比较优秀的应聘者会直接使用apply函数来实现。

function log(msg){

  console.log(msg);

}

完成上一步后可以修改调用log的方式:传递多个参数。告诉应聘者我希望log函数不止接收一个数字作为参数,它应该可以接受任意个数字作为参数。同时我也提醒他们cosole.log()本身就可以接收多个参数。

log('hello', 'world');

理想情况下应聘者应当直接使用apply来实现这个功能。但有时他们会混淆apply和call的二者的区别,这时你可以给他们一些提示。另外将console作为上下文参数这一点也很重要。

function log(){

  console.log.apply(console, arguments);

};

然后可以要求在每一条日志消息前加上“(app)”的前缀,例如:

'(app) hello world'

现在,问题就有点棘手了。能力强些的应聘者应当知道arguments是一个伪数组,在使用它之前得先把它转换成标准数组。通常我们用Array.prototype.slice就可以实现这一点,像下面这样:

function log(){

  var args = Array.prototype.slice.call(arguments);

  args.unshift('(app)');

  console.log.apply(console, args);

};

第三部分:上下文

下面的这一组面试题可以考察应聘者对于JavaScript中context和this的理解。先给出下面的定义,注意,count的属性是从当前的上下文中读取的。

var User = {

  count: 1,

  getCount: function() {

    return this.count;

  }

};

然后让应聘者写出下面代码的输出结果:

console.log(User.getCount());

var func = User.getCount;

console.log(func());

这个题目正确的答案是1和undefined。令人吃惊的是有很多人会在这种关于上下文的基础知识上犯错。func函数被调用时,它的上下文是windows,而windows是没有count属性的。当他把这些都和应聘者做了解释,然后问他如何才能保证func函数始终都能以User作为上下文被调用,这样它就能正确运行从而返回1。

正确的答案是使用Function.prototype.bind,例如:

var func = User.getCount.bind(User);

console.log(func());

通常他会告诉应聘者有一些老的浏览器是不支持bind函数的,然后让面试者自己来写一个函数来模拟。有一些基础差的应聘者并不认可这一点,但Alex认为每一个被雇佣的应聘者对apply和call都应该有比较深入的理解,这一点很重要!(同感)

Function.prototype.bind = Function.prototype.bind || function(context){

  var self = this;

  return function(){

    return self.apply(context, arguments);

  };

}

如果应聘者像上面那样实现了bind并且还判断了当前浏览器是否已经支持bind函数,那么应聘者可以得到额外的加分。
此时,如果应聘表现的很出色,他会让他们去实现currying参数。

第四部分:Overlay库

面试的最后这一部分里,Alex会让应聘者做一些更加实际的事情,通常是去实现一个‘overlay’的库。这很方式很管用,它涉及到了整个前端开发所用到的技术:HTML、CSS 和JavaScript。如果应聘者在前面几个环节表现优秀,他会尽早的开始这一部分的问题。

具体的实现因人而异,但是这里几个关键点需要注意!

对于overlay covers,最好使用 position: fixed 而不是 position: absolute,这样即使窗口滚动的时候也可以保证层铺满整个窗口。如果应聘者没有注意到这一点他会提示他们,然后问他们这两者的区别。

.overlay {

  position: fixed;

  left: 0;

  right: 0;

  bottom: 0;

  top: 0;

  background: rgba(0,0,0,.8);

}

从把内容放置到层的中心位置的方式也可以为面试官提供一些信息。有些应聘者可能会使用CSS和绝对位置,但这样的前提是内容必须是固定宽度和长度的。另外的应聘者也可能会选择用JavaScript来定位。

.overlay article {

  position: absolute;

  left: 50%;

  top: 50%;

  margin: -200px 0 0 -200px;

  width: 400px;

  height: 400px;

}

他还会要求他们实现单击关闭层的功能,然后就可以顺势讨论下几种不同类型的事件传播机制。大多数应聘者会直接为层设置一个事件监听器。

$('.overlay').click(closeOverlay);

看着是对的,但很快你就会发现在这个层的子元素上单击也会关闭层,这明显不是我们预期的效果。解决方法是先检查事件的targets来确保不是一个传播事件,像这样:

$('.overlay').click(function(e){

  if (e.target == e.currentTarget)

    closeOverlay();

});

其它

其实这些问题只覆盖了前端知识的很小一部分,面试的时候你可以问很多其他方面的问题,例如性能、HTML5 APIs, AMD vs CommonJS modules、 构造函数、数据类型以及盒模型等。可以根据应聘者的兴趣来搭配不同类型的问题。

此外Alex还推荐大家到前端开发者面试题集锦JavaScript花园去寻找一些灵感!

standard
  1. luckyGirl - 2014 年 4 月 30 日 11:38 上午

    不错不错 学习了,发现自己不合格呀

    回复

Have your say