前端实习生-字节面试面经

前端实习生-字节面试面经

  这次字节的一面还是比较简单的,和一般公司的一面差不太多,基本大家只要多复习复习JS的基础和ES6,其实都差不多能够答出来。接下来记下具体这次的面试和流程,希望能对XDM有所帮助

  这次是在牛客网上的面试房间面试的,有的面试官会使用腾讯会议面试,有的面试官会使用电话面试,所以碰到在牛客网上面试的情况的话,可以尽量多准备准备算法相关的一些东西,因为经常会有题目需要你手打代码,然后面试官询问思路

CSS

  • 居中对齐
  • position

  首先是面试官让你自我介绍,介绍完之后开始问CSS方面的知识,这部分问的少,居中对齐有哪几个方案,position居中对齐的方案解释下原理,这两个问题回答完就直接JS部分了。CSS部分复习比较广泛繁琐,尽量还是在日常使用中累积经验

JS

  • 事件循环
  • Promise
  • call bind
  • 拍平方案
  • 状态码

  这部分首先是事件循环题,是一个老生常谈的题目了,我没记下原题,这里贴一个类似的题目,当时出的是只有五个打印的题目,这个题目只要注意在微任务中Promise、settimeout的执行顺序,遇到await会立即执行表达式,然后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行就行了

async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
    console.log('async2');
}
console.log('script start');
setTimeout(function() {
    console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
    console.log('promise1');
    resolve();
}).then(function() {
    console.log('promise2');
});
console.log('script end');

/**
 * script start
 * async1 start
 * async2
 * promise1
 * script end
 * async1 end
 * promise2
 * setTimeout
 */

  紧接着的是手写的题目,要求手写call函数和Promise函数(这个其实没有让我去写,只是说了下实现的思路,后面的Redux简单实现也是只要求说了思路),注意以下写的东西并不是当时写的代码

Function.prototype.myCall = function(context) {
    context = context || window;
    context.func = this;
    const params = [...arguments].slice(1);
    const result = context.func(...params);
    return result;
}

function MyPromise(executor) {
    var self = this;
    this.status = 'pending';
    this.value = undefined;
    this.reason = undefined;
    this.onResolvedCallbacks = [];
    this.onRejectedCallbacks = [];
    function resolve(value) {
        if (self.status === 'pending') {
            self.status = 'resolve';
            self.value = value;
            self.onResolvedCallbacks.map((fn) => {
                fn();
            })
        }
    }
    function reject(reason) {
        if (self.status === 'pending') {
            self.status = 'rejected';
            self.reason = reason;
            self.onRejectedCallbacks.map((fn) => {
                fn();
            })
        }
    }
    try {
        executor(resolve, reject);
    } catch (err) {
        reject(err)
    }
}

MyPromise.prototype.then = function (infulfilled, inrejected) {
    var self = this;
    if (this.status === 'resolve') {
        infulfilled(this.value)
    }
    if (this.status === 'rejected') {
        inrejected(this.reason)
    }
    if (this.status === 'pending') {
        this.onResolvedCallbacks.push(function () {
            infulfilled(self.value)
        });
        this.onRejectedCallbacks.push(function () {
            inrejected(self.reason)
        });
    }
};

  Promise部分完之后,面试官问知道拍平吗?拍平能说出有哪几种方案,我说了简单的比如toString+split的方案,递归的方案,还有Array.prototype.flat可以做到这一点,然后这里面试官说希望我能手写一个flat函数,要求传数组进去能够返回拍平后的数组

// 错误示范
// 这个是当时我写的,num并未起作用,然后面试官就让我回答后续的问题了
function flat(arr, num){
    let res = [];
    if(num > 0){
        arr.map(item => {
            if(Array.isArray(item)){
                res = [...res, flat(item, num - 1)]
            } else {
                res.push(item)
            }
        })
    }else {
        res = arr
    }
    return res;
}

console.log(flat([1,2,3,[1,2, [3,4], 5], 6], 1))

  紧接着面试官询问了我了解哪些状态码,我说完之后他取出304状态码问这个状态码是什么时候会看到的,这个地方其实就是问你对缓存的了解,问完后就进入了React的部分

React

  • diff算法
  • this.setState异步同步
  • 生命周期说一遍
  • this.setState为什么不能用在render里
  • 为什么hooks不能用在if-else里面
  • redux实现

  首先简单问了React中diff的原理,key的作用,然后问了生命周期都有哪些,让我按自己的记忆说一遍,因为后面我用的是hooks,所以生命周期我只说了六七个,然后问了我,this.setState是同步的还是异步的,这里是一个小陷阱,因为this.setState在一些时候是同步的,一些时候是异步的,这个大家可以自己去了解一下在监听事件、绑定事件、生命周期中的this.setState表现。然后问了我this.setState为什么不能用在render里,这里也是一点小陷阱,因为事实上不是不能用,而是尽量谨慎,this.setState会触发重新render,你可以为其设置限制条件等控制他的重新渲染。为什么hooks不能用在if-else里面,这个其实我没有太清楚,所以说了不好意思不太清楚。值得一提的是,大厂的面试官不会因为你不懂而改变对你的态度,始终都会是比较温和的面试态度,所以这点对于面试者还是比较舒服的,不会出现面完心态大崩的情况啦。然后问了我懂不懂redux的简单的实现,正好这个我有写过一个简单的实现,然后就边地打了几行,边讲具体的代码和设计思路,具体代码在下方

export default function createStore(reducer){
    let state = null;
    const listeners = [];
    const getState = () => state
    
    const dispatch = (action) => {
        state = reducer(state, action)
        listeners.forEach(listener => listener())
    }
    
    const subscribe = (listener) => listeners.push(listener)
    
    // 这里初始化dispatch的原因是在这之前,state是为null的
    dispatch({});
    return {
        dispatch,
        subscribe,
        getState,
    }
}

其他

  • graphql的意义

  最后面试官还问了我graphql的意义是什么,这个是因为我的简历上是有说用过graphql的,所以问了用这个的原因,这里我答得是和Restful的一些差别,这个的话大家可以没用过的话就可以不用复习,不用担心面试官会问出除你简历所写之外的技术(昂除非是很基础的比如CSS、html),最后是让我问问题,我询问了该前端团队所选用的技术栈是怎样的,也是gql + apollo那一套加中间层,具体的没有详细问,希望我的面经能够对大家的面试有所帮助

posted @ 2021-02-26 17:53  JobsOfferings  阅读(413)  评论(0编辑  收藏  举报