让前端飞JavaScript 进阶营前端开发笔记

前端面经总结——字节跳动头条笔试一面+二面

2018-11-13  本文已影响92人  Rocky_Wong

前言

笔者此次面的是深圳字节跳动的前端岗位,一直听说头条注重算法,所以面试前已经花了不少时间准备,可是最后还是到了二面就止步了,算法基础还是不够扎实啊-.-|||||||||所以大家要面头条的话还是要好好准备一下算法,多做做题啥的~

笔试 + 一面

敲黑板!头条是一定会有笔试题的哦,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当然不是数组啦,转数组的方法有:

3. 类型比较

if([]==false){console.log(1)};
if({}==false){console.log(2)};
if([]){console.log(3)}
if([1]==[1]){console.log(4)}

答:1 3

参考文章

为什么[] 是 false

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的使用原理是啥?

最后

。。。有的题目真的想不起来了,最后二面面试官和我说他们是对算法有要求的,包括前端。这次面试真的被虐得很惨,但是收获真的很多很多,而且也让自己意识到算法真的(对找工作)很重要~!

上一篇下一篇

猜你喜欢

热点阅读