前端面经总结——字节跳动头条笔试一面+二面
前言
笔者此次面的是深圳字节跳动的前端岗位,一直听说头条注重算法,所以面试前已经花了不少时间准备,可是最后还是到了二面就止步了,算法基础还是不够扎实啊-.-|||||||||所以大家要面头条的话还是要好好准备一下算法,多做做题啥的~
笔试 + 一面
敲黑板!头条是一定会有笔试题的哦,css,js,算法都会考察噢。我尽量还原题目。。有的实在是忘了-.-
1. 实现css布局
一个div垂直居中
其距离屏幕左右两边各10px
其高度始终是宽度的50%
div中有文本'A'
其font—size:20px
文本水平垂直居中
我的回答:
<div class="wrap">
<div class="box">
<span class="text">A</span>
<div>
</div>
.wrap {
position: fixed;
left: 10px;
right: 10px;
top: 0;
bottom: 0;
}
.box {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
height: 50%;
background: red;
}
.text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 14px;
background: blue;
}
我的回答好像做不到“其高度始终是宽度的50%”这一点,网上参考了一下其他大神的,使用了calc和flex,大家可以看看:
<div class="box">
<div class="Abox">A</div>
</div>
*{
padding:0;
margin: 0;
}
html,body{
width: 100%;
height: 100%;
}
.box{
position: relative;
background: red;
width: 100%;
height: 100%;
}
.Abox{
margin-left:10px;
width: calc(100vw - 20px);
height: calc(50vw - 10px);
position: absolute;
background: yellow;
top:50%;
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
}
2. 函数中的arguments是数组吗?类数组转数组的方法了解一下?
答: arguments当然不是数组啦,转数组的方法有:
- [...arguments]
- Array.from(arguments)
3. 类型比较
if([]==false){console.log(1)};
if({}==false){console.log(2)};
if([]){console.log(3)}
if([1]==[1]){console.log(4)}
答:1 3
- == 是非严格比较操作符,false会转换为0,[]会转换成'',{}会转换为"[object Object]",所以会输出1,不输出2,具体的可以看看以下文章
参考文章
- []和{}是“空”的对象,不是“空”,所以会输出3
- 最后一个引用地址不一致,不是同一个对象,所以不会输出4
4. EventLoop
async function a1 () {
console.log('a1 start')
await a2()
console.log('a1 end')
}
async function a2 () {
console.log('a2')
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout')
}, 0)
Promise.resolve().then(() => {
console.log('promise1')
})
a1()
let promise2 = new Promise((resolve) => {
resolve('promise2.then')
console.log('promise2')
})
promise2.then((res) => {
console.log(res)
Promise.resolve().then(() => {
console.log('promise3')
})
})
console.log('script end')
正确答案:
script start
a1 start
a2
promise2
script end
// 此处开始执行异步队列
promise1
promise2.then
promise3
// 真的不知道 a1 end 为啥在这里才输出,还以为会在promise1 后面。。
// 大家知道的话可以评论区分享一下啊~在网上看到的答案都说得模凌两可的
a1 end
// 执行完所有微任务才执行宏任务
setTimeout
5. 改正代码,输出0123401234
function a () {
for (var i = 0; i < 5; i++) {
this.i = i
setTimeout(function () {
console.log(i)
}, 0)
console.log(this.i)
}
}
a()
答:首先留意var,可以改成let,再加个立即执行函数;然后留意this指向,可以改为箭头函数。(我当时的想法就是这么短浅。。。)
function a () {
for (let i = 0; i < 5; i++) {
(function (i) {
this.i = i
setTimeout(() => {
console.log(i)
}, 0)
console.log(this.i)
})(i)
}
}
a()
我的一个牛逼大神同事用了这个方法,实在佩服啊哈哈哈👇
var count = 0;
Object.defineProperty(window, 'i', {
get: function() {
return count++
},
set: function() {}
})
function a () {
for (let i = 0; i < 5; i++) {
(function (i) {
this.i = i
setTimeout(() => {
console.log(this.i)
}, 0)
})(i)
}
}
a()
5分钟后他又想出了一个新方法!我的膝盖啪一声跪下来👇
function a () {
for (var i = 0; i < 5; i++) {
this.i = i
setTimeout(function () {
console.log(this.i)
}.bind({i: i}), 0)
}
}
6. 按要求写出bind(题目我实在记不清楚,反正不是简单的写一个bind)
答:(以下是正常的bind手写实现)
Function.prototype.bind2 = function (context) {
if (typeof this !== "function") {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
var fNOP = function () {};
var fbound = function () {
self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
}
fNOP.prototype = this.prototype;
fbound.prototype = new fNOP();
return fbound;
}
7. 按要求写出一个throttle防抖函数
答:
先丢个正常的防抖函数出来
function throttle(callback, ms) {
var pending = false;
var _this;
return function () {
if (!pending) {
var args = arguments;
pending = true;
_this = this;
setTimeout(function () {
callback.apply(_this, args);
pending = false;
}, ms);
}
};
}
结果面试官不满意了,明明题目点第三次的时候虽然不执行,但是等第一次执行完后会马上执行第三次的。反正我最后还是做不出来,,
8. 从一个无序,不相等的数组中,选取N个数,使其和为M实现算法
哈哈哈哈哈做不出来,面试官很有耐心引导,假如选取2个数的话怎么实现呢,我就想到递归函数之类的,但是最后还是手写不出来。。。
一面的面试官主要是看着笔试题拓展问了相关的知识点,然后我也不知道怎么就过了一面了,,,
二面
二面几乎都是算法题,再加点js基础题这样。emmm算法题我就说说当时的做法吧,,感觉要误人子弟了,,改天研究透了再单独分享
1. 一个字典['I', 'have', 'a', 'book', 'good'],实现一个函数,判断一个字符串中是否都是出自字典中的,输出true/false
例如:
输入'I have a book' 输出 true
输入 'this is a good book' 输出 false
答: 我当时是想出了个很蠢的方法,就是将字符串的字典词都切了,切完后还有得剩就说明是false,哈哈哈哈啊哈哈哈好蠢啊,面试官不满意地问我这个做法的复杂度,我说好的我知错了。。。
2. 一个长阶梯有n级,可以一次走1级,一次走2级,一共有多少种走法?
答: 引导了一番后我写了个递归函数
function step (n) {
if (n === 1) return 1
if (n === 2) return 2
return step(n - 1) + step(n - 2)
}
面试官看完后不是很满意,说假如在浏览器上敲step(40000)会怎样,我说会爆掉吧。。他说为什么。。我说内存会溢出。。他问我为什么。。
blablabla一大堆后我还是没答好,回到家后我想想觉得应该是还存在尾递归的优化空间吧。。。
////////之后问的算法题我已经记不住了。。我再分享一些基础题题目吧,大部分答案都在之前的文章和面经都提过了,此处不再赘述
3. 说说http缓存
4. 用过typescript吗?它的作用是什么?
答: 用过,我真的只想到类型检查,提供缺省值诶,,后来想想还有引入了“类”“模块”的概念。
5. ts的用法用到了装饰器,你了解过吗?知道如何实现的嘛?
答:这个正好我写了一篇装饰器的文章,略知一二。。。实现大概就是使用object.defineProperty来拦截对象的属性进行“加工”
6. PWA使用过吗?serviceWorker的使用原理是啥?
最后
。。。有的题目真的想不起来了,最后二面面试官和我说他们是对算法有要求的,包括前端。这次面试真的被虐得很惨,但是收获真的很多很多,而且也让自己意识到算法真的(对找工作)很重要~!
完