这次的面试机会来的也很偶然,大概4月初的时候在 v2ex
论坛上看到了酷家乐的招聘信息,就照着邮箱发了自己的简历,当时也没有太在意。到了4月24号左右,收到了酷家乐的在线笔试邀约,在说这次面试前可以先聊聊这次在线笔试。
到现在为止,在线笔试也做了阿里、蘑菇街的,做个横向对比,酷家乐这次的笔试题目分配是20道选择题、3道编程题。很有趣的是在20道选择题中,大概前15道都是围绕数据结构、组成原理、操作系统、网络原理出的题,当初做的时候也是绞尽脑汁回想以前的知识点,我一度怀疑是不是投错了职位,因为像阿里、蘑菇街的笔试题目还都是围绕着前端这一边的,直到最后大概5题才是
js 的题目。3道编程题,一道是实现函数功能,一道是自己写一个 json.stringify() 函数,第3道是 canvas
的题目,大概题目好像是在页面中实现一个可以拖拽的方块。
选择题做的模模糊糊,编程题也只做出一个,当时已经不怎么抱希望。只是从笔试的网站和重视基础的题目,隐隐感受到这家公司的逼格。最后在上周四,接到了笔试通过的电话,并预约了周一的现场面试。
技术一面(35min)
话不多说,直接接入正题。在一面的时候,面试官先拿出了一张考卷让我做,上面6道js(闭包、原型链、this、类型判断、变量提升、函数提升都有)、1道css(
盒模型),说实话题目不是很难,只要准备过题目,都是可以答出来的。
这里列出几道我记得的题目,再附上面试官结合题目问的问题。
1、
console.log(foo()); var foo = function() { return 1; } console.log(foo());
function foo() { return 2; } console.log(foo());
答案:2 1 1
解析:很基础的变量提升、函数提升,详细可以移步 JavaScript中的变量提升和函数提升
<https://blog.csdn.net/zwkkkk1/article/details/79742263>。
2、
for(var i = 0; i < 6; i++) { setTimeout(function() { console.log(i); //位置1 },
1000 * i); } console.log(i); //位置2
问:1、 实现的效果;
2、 将 var i = 0; 改成 let i = 0; 效果如何;
3、除了上面的方法,还有什么方法可以达到上面的效果,并能规避上面的错误;
4、将 setTimeout 的时间 1000 * i 改成 0,效果如何;
答:1、 先打印一个6,再每隔一秒打印一个6;
2、 这里光注意 let 在 循环内的表现,疏忽了位置2的报错,正确答案是:首先报出一个 ReferenceError: i is not defined
,然后每隔一秒输出 0,1,2,3,4,5;
3、手写代码:
for(var i = 0; i < 6; i++) { (function(i) { setTimeout(function() {
console.log(i); }, 1000 * i); })(i) } console.log(i);
4、先打印位置2的1个6,然后打印出6个6
3、
function foo() { console.log(typeof kkk); console.log(typeof bar); var kkk;
function bar() {}; } console.log(typeof foo());
问:1、效果如何;
2、函数没有返回值,返回什么;
3、typeof 在判断类型时有什么弊端;
4、function 同样算是一种 object,为什么不像 Array 一样返回 object 而是返回 function?
答:1、undefined、function、undefined;
2、undefined;
3、在判断 Array、Date等对象都返回 object,不能确切判定出,typeof null = object;
4、这里面试的时候不清楚,回来之后查了好多的资料,然后我在一篇博文(ECMA-262-3 in detail. Chapter 7.2. OOP:
ECMAScript implementation.
<http://dmitrysoshnikov.com/ecmascript/chapter-7-2-oop-ecmascript-implementation/>
)上看到这样的一段话:
Thus [[Call]] besides the [[Class]] property (which equals to “Function”) is
the main in respect of objects distinguishing. Therefore the objects having
internal [[Call]] property are called as functions.
上面这段话大致翻译成这样:
因此[[Call]]是除了[[Class]]属性(相当于“Function”)object 识别的主要部分。
因此具有内部[[Call]]属性的对象被称为函数。
typeof 运算符结果(重点看最后4个)
4、
var bar = { foo: function() {return this.baz}, baz: 1 }; (function() {
console.log(typeof arguments[0]()); })(bar.foo)
答案:undefined(这里另有坑)
一开始我认为 arguments[0] () 可以转换为 bar.foo(),所以我的答案是
number。后来面试官提示这里匿名函数参数传递的是函数的地址,我连忙改口说因为这里的函数调用是 function 调用,故 this 指向
window,所以是 undefined。
后来回来之后,复盘的时候发现这里似乎被面试官挖了一个坑往里面跳,答案仍旧是 undefined,不过原理却完全不同。
这里的 this 指向的不是 window,而是 arguments 这个类数组对象,arguments[0] () 可以替换成是
arguments.0()(伪代码,实际不能这么写),可以把 arguments 看成这样:
arguments = { 0: bar.foo, //也就是 functon() {return (this.baz)} 1: 第二个参数, //没有
..., length: 1 //只有一个参数 }
那么此处这个函数是作为 arguments这个对象的 method 方式运行的,故this指向 arguments,返回 undefined。(对
this 的解释可以移步:this 的4条绑定规则及优先级
<https://blog.csdn.net/zwkkkk1/article/details/80008343>)。
卷纸上的题目只能记得上面的4个(没办法,老年人记性)。
问完卷纸上的题目,面试官开始拿着我的简历开始问问题,也是围绕着上面写的一些点,这里举几个例子:
* 为什么从上家公司离职?(因为我上面写了我大二的时候兼职实习);
* 简历上面写 PHP 做了挺多的东西,为什么选择前端;
* 你在工作经历写了使用过 AJAX,有没有遇到什么问题?有没有遇到跨域的问题?(实话实说没有碰到,现在想想是不是要问
AJAX重复提交的问题,解决方案移步:Ajax 重复提交解决方案
<https://blog.csdn.net/zwkkkk1/article/details/79919166>)
然后问了点我简历里写的项目问题,问完简历上面的问题后,面试官又提了一些其他的东西:
* 已知宽高的父元素div,让未知宽高 div 水平垂直居中
这题我答了运用 display:flex; 和 transform: translate(-50%, -50%); 两种办法(详情可参见 CSS
实现水平居中与垂直居中 <https://blog.csdn.net/zwkkkk1/article/details/79917835>)。
* 上题回答的 transform: translate(-50%, -50%);中的 -50%,是参照父元素的宽高偏移还是参照子元素的宽高偏移?
起初我没答上来,答案是 translate(-50%, -50%)作用是,往上(x轴),左(y轴)移动自身长宽的50%,以使其居于中心位置。
* 能想到的数组去重的方法
起初想到新建一个数组用来记录不重复的字符,后面一直在想有没有更好的方法,没想出来就答了一开始的想法。后面回来的时候,在网上进行了了一次总结,详情请移步:
JavaScript 9种数组去重及性能问题 <https://blog.csdn.net/zwkkkk1/article/details/80337451>。
一面总结
除了上面的问题,其实还问了挺多的,只是一时想不起来,只能列出一些印象深刻的。整体自我感觉一面还好,有一些自认为理解的问题,还有些欠缺,一些问题是之前写了博文总结过的,也想了好一会儿。看来,在日常学习之余,还要时常总结复习之前的学习内容。
技术二面(30min)
一面之后,直接就安排了二面。二面面试官一开始也没随便吧啦吧啦,直接切入正题。
* 算法题:有n个人,其中一个明星和n-1个群众,群众都认识明星,明星不认识任何群众,群众和群众之间的认识关系不知道,现有一个函数 foo(A, B)
,若A认识B返回true,若A不认识B返回false,试设计一种算法找出明星,并给出时间复杂度。
* 请用 array 模拟栈的 pop()、push() 方法,时间复杂度应为 O(1)。
二面总结
二面就问了两个算法题,二面回答的很糟糕,第一题一开始想到好几种时间复杂度都是O(n*n)的方法,好不容易在面试官的提示下才堪堪想出一个 O(n)
的方法。第二题则完全没想出来,gg。最后在两天后接到了被拒的邮件,我想大概率就是栽在了二面上,以后在学习前端知识的同时,还要注意算法等基础方面的能力。(二面题目的解析,后面我会单独发解析的文章)。
热门工具 换一换