这个并不是我参与的面试,是朋友参加的一个面试,所以不会有较多的面试细节和面试感受,更多的是对面试题的解析。
一面
面试题1: 说出下面的打印顺序和结果
console.log('begin');
for(var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
console.log('end');
输出结果是: begin end 5 5 5 5 5
解析:setTimeout是宏任务,肯定是在最后上面代码中最后执行的,在执行回调函数的时候,i的值已经是5了,且5个5是同时输出的
在这个时候肯定会被追问
怎么修改才能让这段代码输出 0 1 2 3 4。
1. 立即执行函数
for(var i = 0; i < 5; i++) {
(function(params) {
setTimeout(function() {
console.log(params);
}, 1000);
})(i)
}
2.利用setTimeout的第三个参数
for(var i = 0; i < 5; i++) {
setTimeout(function(params) {
console.log(params);
}, 1000, i);
}
3. 利用Es6的let
for(let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000)
}
面试题2:代码执行
var a = 1;
function Fn1() {
var a = 2;
alert(this.a + a); // 这儿会执行几次,分别是多少
}
function Fn2() {
var a = 10;
Fn1(); // 3
}
Fn2();
var Fn3 = function() {
this.a = 3;
}
Fn3.prototype = {
a: 4
}
var fn3 = new Fn3();
Fn1.call(fn3); // 5
结果:alert会执行2两次,结果分别是 3 5;
解析:
- 第一次执行的时候是在
Fn2函数中被调用,此时 Fn1中的this指向全局,所以 答案为1 + 2 = 3 - 第二次执行是上上面的最后一样,fn3对象的a属性的值是
3,因为使用了call函数,所以Fn2中的this指向fn3,所以结果是3 + 2 = 5
考点:
- 作用域在函数声明的时候就决定了,所以 alert 中的第二个a的值一直是 2
- 原型和原型链,new函数的执行
- call、apply、bind
面试题4: 自定义数组方法
给数组原型上添加一个方法返回数组的深度 测试示例:
[].getDepth(); // 1
[1, 2, 3].getDepth(); // 1
[1, 2, [3, 4]].getDepeth(); // 2
[1, 2, [3, 4],[6, [7, 8]]].getDepeth(); // 3
答案:
Array.prototype.getDepth = function() {
if(!Array.isArray(this)) {
throw new Error(`typeof ${this} is Error`);
}
const maxDepth = (arr) => {
const dep = [1];
for(let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i])) {
dep.push(maxDepth(arr[i]));
}
else {
dep.push(1);
}
}
return Math.max(...dep) + 1;
}
return maxDepth(this) - 1;
};
面试题4: 算法
假设100人,分编号1~100,从1号开始报数,报数到3号时,3号淘汰,然后有下一任从1报数,以此类推,最后谁会活下来?
比如100报的是1,再从第一个报2,最后只剩一个编号
方法一
let start = 0;
let i = 0;
while(arr.length > 1) {
if(start === 3) {
arr.splice(i, 1);
start = 1;
}
else {
i++;
start++;
}
if(i >= arr.length) {
i = 0;
}
}
方法二
let arr = [...new Array(100).keys()];
let start = 0;
while(arr.length > 1) {
if(start === 3) {
arr.shift();
start = 1;
}
else {
arr.push(arr.shift());
start++;
}
}
二面
1、自我介绍
2、自己觉得比较有挑战的和有成就的项目
3、算法题一
有两个请求,按照优先有序打印顺序打印; 例如: req1: 10ms、req2: 5ms; 10ms后打印出 req1、req2的结果 req1: 5ms、req2: 10ms; 5ms后打印出req1、再过5ms后打印出req2
function req(time) {
return new Promise(resolve => {
setTimeout(() => {
resolve(time);
}, time);
});
}
function sequence(reqs) {
let res = [];
let resIndex = 0;
for(let i = 0, l = reqs.length; i < l ; i++){
let time = reqs[i];
req(time).then(r => {
res[i] = r;
getRes(i);
});
}
function getRes(index) {
if(index === resIndex && res.hasOwnProperty(index)) {
console.log(res[index]);
resIndex++;
getRes(resIndex);
}
}
}
4. 算法二 数组[1,2,3]的全排列方法
function rank (arr) {
let len = arr.length;
let res = [];
function getArr(left, curItem) {
if(left.length === 0) {
res.push(curItem);
console.log(curItem);
return;
}
for(let i = 0, l = left.length; i < l; i++) {
const item = left[i];
const next = [...curItem];
next.push(item);
const newLeft = [...left];
newLeft.splice(i, 1);
getArr(newLeft, next);
}
}
getArr(arr, []);
return res;
}
5、你有什么需要了解的问题?
答题技巧:首先要问的是技术栈,其次要问团队小组规模,最后问下我如果有幸入职负责哪个方向的业务(可问可不问);其次是看个人发挥,跟技术官最好没必要问福利方面的; 欢迎大佬们点赞推上热门