昨晚进行了字节前端的一面,我知道自己的技术还差不少,想看看有哪些不足,结果给打击的挺狠的0.0。不过有些知识点可以记一记,不让自己忘掉。
1.EVENT LOOP
我知道js是单线程语言,但是异步操作的话,会将这个事件,有结果了再放入一个事件队列,执行栈的代码都执行完了,主线程空闲的时候,才会去调出事件队列里的结果。然后就是一段代码:
setTimeout(function () {
console.log("1");
new Promise(function (resolve) {
resolve();
}).then(function () {
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("2");
});
console.log("3");
});
}, 0);
new Promise(function (resolve) {
console.log("4");
resolve();
}).then(function () {
console.log("5");
});
setTimeout(function () {
console.log("6");
}, 0);
console.log("7");
问我输出顺序:我思索了半天,给了个错误答案:4571326
正确答案:4751326
我知道promise是直接运行的,但是没去了解原理,4和7是同步的,因为4在前所有先出来,5是异步的,所以在7后面。后来查了,promise是微任务,比setimeout宏任务要快,所以5比其他的输出快,其他的没什么可谈的了。
2.原型和原型链
这个老生常谈,没什么好说的,然后给了代码:
var name = '李四';
function Foo(name){
this.name = name
}
Foo.prototype.printName = function () {
console.log(this.name)
}
Foo.printName = function () {
console.log(this.name)
}
//创建实例
var f = new Foo('张三')
var m = Foo.printName;
var n = f.printName;
//测试
f.printName();
m();
n();
答案: 张三,李四,李四。 写对了,过程大概说对了吧?第一个张三没啥好所的,this改的。
第二个李四也是,调用的是window.name,所以是李四。
第三个李四,我的理解是Foo给显示原型prototype一个属性printName,所以f.printName的隐式原型__proto__指向的就是这个prototype,所以调用的还是window.name。
大概是这样的?
3.Vdom和key
这个的话,单个的vdom和key还是有了解的,但是diff算法的那个patch函数后面的那个,新老虚拟节点的首尾交互比较我一直不是很明白,为啥变量相互比较后才用Key进行比较,还有比较过程中会往中间靠我也不是很明白,我知道有key可以用map索引,然后没有Key得遍历,所以这个可以更高效的利用dom。
但是问题又来, 简单模板下,使用key的速度反而慢的原因。是map映射时间加上key的增删节点的时间>遍历查找的时间吗?我感觉好无力0.0
4.编程题
Q:给定一个特殊的对象,要求根据它的key,生成一个新的对象:
var d = {
'a.b.c': 'c prop',
'a.d': 'd prop',
'fff': 'hh'
}
parse(d) => obj
obj = {
a: {
b: {
c: 'c prop'
},
d: 'd prop'
},
fff: 'hh'
}
编程老软肋了,这题没做出来,gg。
第二题题目忘了,没存,但是不难,还是能写出来的,就是代码有点冗杂。
5.TCP
问了我三次握手,我简单的说了说,后来问我SYN携带数据了吗,我说第一次发送不能携带数据,要不然服务器随便接收有数据的包会有问题的。然后他问我那啥时候会携带数据?
我:???
他问我知道TFO吗,我想了想,盲猜他一手cookie,结果给我猜对了好像0.0
6.闭包
面试官不讲武德,上来一手问我闭包的原理,阿这,闭包原理是啥啊。我就知道一个函数里面嵌套函数,然后作用是属性私有化,防止变量污染;坏处是容易内存泄漏,我知道可以设置为null解决,但是一直没考虑过原理,一时没头绪。然后面试官反手一道题目让我缓缓心情0.0
for (var i = 0; i < 6; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
这个很简单,叫我修改代码使得输出0,1,2,3,4,5(不使用let)
for (var i = 0; i < 6; i++) {
(function (i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i)
}
这样应该可以吧。
7.垂直水平居中
我说了固定宽高的:定位 + margin-top + margin-left;不固定的:transform;还有flex。
不过阿面好像不满意,问了我还有吗,阿这,地主家也没有余粮啊。
8.window.onload和DOMContentLoaded事件
这个我回答的也很表面,我对window.onload的理解只有一个图片懒加载,需要整个页面加载完成的之后,才声明这个函数,其他都一盖布吉岛。
DOMContentLoaded的话,当页面引用的所有js同步代码执行完毕,触发DOMContentLoaded 事件。就这了,隐隐约约阿面好像叹了一口气?
9.深浅拷贝
浅拷贝对话,数组有slice,concat,其他的有...。
深拷贝的话,JSON.parse(JSON.stringify()),然后提了下,如果是函数和undefined是会忽略的。
我说了下,我还用过lodash的_.clone和_.cloneDeep。这个感觉还阔以哈。
隐约好像看到了阿面的笑容,还好他没叫我递归方法实现深度克隆,吓死我了,我提都不敢提递归实现。
10.其他
其他还有一些问题,我忘了,反正回答都一般般,字节的阿面态度还是特别好的,虽然我回答的很烂,但是他还是能精准地从我一堆废话中挑出我不会的地方。继续努力吧。