前端實習生-字節面試面經一面

前端實習生-字節面試面經

  此次字節的一面仍是比較簡單的,和通常公司的一面差不太多,基本你們只要多複習複習JS的基礎和ES6,其實都差很少可以答出來。接下來記下具體此次的面試和流程,但願能對XDM有所幫助html

  此次是在牛客網上的面試房間面試的,有的面試官會使用騰訊會議面試,有的面試官會使用電話面試,因此碰到在牛客網上面試的狀況的話,能夠儘可能多準備準備算法相關的一些東西,由於常常會有題目須要你手打代碼,而後面試官詢問思路前端

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簡單實現也是隻要求說了思路),注意如下寫的東西並非當時寫的代碼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的部分promise

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那一套加中間層,具體的沒有詳細問,但願個人面經可以對你們的面試有所幫助markdown

相關文章
相關標籤/搜索