當前位置: 妍妍網 > 碼農

2年經驗,面試字節跳動,感覺也不是很難

2024-04-01碼農

模擬面試、簡歷指導、入職指導、計畫指導、答疑解惑 可私信找我~已幫助100+名同學完成改造!

前言

大家好,我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心~

題目

一面

  • 1、['10', '10', '10', '10', '10'].map(parseInt) 的輸出值是什麽?

  • 2、你們現在的技術棧是什麽?為什麽要使用ts?

  • 3、setTimeout的執行過程(事件迴圈,同步、異步)?

  • 4、對Promise的理解,與async、await的區別,async、await是怎麽實作的?

  • 5、解釋 requestAnimationFrame/requestIdleCallback,分別有什麽用?

  • 6、react效能最佳化?

  • 7、說說對flex的理解?

  • 8、回流、重繪是什麽?如何減少回流和重繪?

  • 10、怎麽尋找react頁面卡頓的原因?

  • 11、編程題:實作一個物件的 flatten 方法,如下:

  • const obj = { a: { b1, c2, d: { e5 } }, b: [13, {a2b3}], c3 }

    flatten(obj){} 結果返回如下:

    // { // 'a.b': 1, // 'a.c': 2, // 'a.d.e': 5, // 'b[0]': 1, // 'b[1]': 3, // 'b[2].a': 2, // 'b[2].b': 3 // c: 3 // }

    二面

  • 1、說說對web worker的理解

  • 2、service worker和強緩存相比,有哪些優勢?

  • 3、說說對堆疊溢位的理解

  • 4、position中的sticky是什麽,還有哪些其他的?

  • 5、ts中,any和unknown分別是什麽意思?泛型怎麽使用?

  • 6、bind有什麽用?連續多個bind,最後this指向是什麽?

  • 7、webpack的plugin怎麽實作?

  • 8、編程題:現已知一個字串是由正整數和加減乘除四個運算子(+ - * /)組成。例如存在字串 const str = '11+2-3 4+5/2 4+10/5',現在需要將高優先級運算,用小括弧包裹起來,例如結果為 '11+2-(3 4)+(5/2 4)+(10/5)'。註意可能會出現連續的乘除運算,需要包裹到一起。請用 javascript 實作這一過程

  • 三面

  • 1、手寫體:使用TypeScript 實作一個 get 函式來獲取它的內容值

  • const data = { name'tom'age18address'xxx' }

  • 2、ts中的 any 、 unknown 的區別

  • 3、有用過ts中的 keyof 嗎?

  • 4、for in/for of的區別?

  • 5、Promise值穿透?

  • 解答

    一面

    1、['10', '10', '10', '10', '10'].map(parseInt) 的輸出值是什麽?

    可轉化為:

    ['10''10''10''10''10'].map((num, index) =>parseInt(num, index))
    // [10, NaN, 2, 3, 4]
    '10'0 -> 10: 進制為0,則預設10進制
    '10'1 -> NaN: 1進制不存在
    '10'2 -> 2: 2 * 1 + 2 * 0
    '10'3 -> 3: 3 * 1 + 3 * 0
    '10'4 -> 4: 4 * 1 + 4 * 0

    2、你們現在的技術棧是什麽?為什麽要使用ts?

    typescript JavaScript 的超集,它本質其實是是在 JavaScript 上添加了 可選靜態型別 基於類的物件導向編程

    typescript 的特點

  • 可以在編譯期間發現並糾正錯誤

  • 提高可維護性

  • 提高協同開發的效率

  • 支持強型別、介面、泛型、模組

  • 3、setTimeout的執行過程(事件迴圈,同步、異步)?

    事件迴圈

  • 1、執行同步程式碼

  • 2、 1 中生成的 微任務 先執行

  • 3、 1 中生產的 宏任務 再執行 同步

  • 簡單來說就是:排隊。程式碼有前後順序,必須按照順序去執行 異步

    異步任務可以不阻塞後面的程式碼執行,而是可以同時進行,並且執行完後會有一個異步的回呼。

    想起一個故事可以很好的解釋 同步 異步

  • 同步:你打電話去書店借書,老板接電話時讓你等著,他去找書,你只能守著電話幹等著

  • 異步:你打電話去書店借書,老板接電話後說等他找到書再打回給你,然後掛電話了,這段找書的時間你可以自由活動

  • 4、對Promise的理解,與async、await的區別,async、await是怎麽實作的?

    Promise的理解

    顧名思義, Promise 就是 承諾 的意思,表現在了Promise的狀態一旦改變則不會再變了,如果狀態為 fulfilled 則執行 then ,如果狀態為 rejected 則執行 catch ,Promise 也支持 鏈式呼叫 。我覺得Promise最大的用處就是 解決了回呼地獄,提高了程式碼的可讀性 。常用的方法有 resolve、reject、then、catch、race、all、allSettled、any、finally

    async await async/await 的作用是 用同步的方式執行異步的操作 ,它的實作原理,我個人理解就是利用了 Promise 的不斷巢狀,再加上 generator函式 的步驟控制,實作了按順序執行異步操作的效果

    補充:async函式返回的是一個Promise

    5、解釋 requestAnimationFrame/requestIdleCallback,分別有什麽用?

  • requestAnimationFrame:

  • 一般間隔是 16ms ,因為大部份電腦都是 每秒60幀 ,所以 1000 / 60 ≈ 16ms

  • 會把每一幀中的所有DOM操作集中起來,在一次重繪或回流中完成,且時間間隔緊緊跟隨瀏覽器的重新整理頻率

  • 如果有隱藏或不可見的元素,將不會進行重繪或回流,減少了cpu、gpu的記憶體使用量

  • 如需取消則使用 cancelAnimationFrame

  • requestIdleCallback:我的理解就是找瀏覽器空閑時間去執行傳入的回呼,具體也沒在計畫中使用過

  • 6、react效能最佳化?

    7、說說對flex的理解?

    彈性布局 ,設定了 display: flex 的盒子為 彈性盒子 ,子元素會自動變成 彈性計畫 ,盒子有一根主軸,預設是水平,並且有一個交叉軸(跟主軸垂直)。

    彈性盒子的樣式:

  • flex-direction:定義主軸方向

  • flex-wrap:是否允許換行

  • flex-flow:flex-direction 和 flex-wrap的簡寫

  • justify-content:主軸方向上的對齊方式

  • align-items:交叉軸方向的對齊方式

  • align-content:多根軸線的對齊方式

  • 彈性計畫的樣式:

  • order:定義計畫的排列順序,數值越小排列越靠前,預設0

  • flex-grow:定義計畫的放大比例,預設為 0

  • flex-shrink:定義計畫的縮小比例,預設為1

  • flex-basis:定義了在分配多余空間之前,計畫占據的主軸空間,預設auto

  • flex:flex-grow、flex-shrink、flex-basis的簡寫

  • align-self:允許單個計畫設定不同的交叉軸對齊方式

  • 8、回流、重繪是什麽?如何減少回流和重繪?

    重繪回流

  • 回流:尺寸、布局改變時,引起頁面重新構建

  • 重繪:元素外觀、風格改變時,不影響布局,則為重繪

  • 區別:回流一定引起重繪,重繪不一定引起回流

  • 瀏覽器幫忙:瀏覽器維護一個佇列,把所有引起回流、重繪的操作放入這個佇列,等佇列到了一定數量或者到了一定的時間間隔,瀏覽器就會清空佇列,進行批次處理。

  • 避免重繪、回流

  • 1、批次修改DOM或者樣式

  • 2、復雜動畫使用絕對定位讓它脫離文件流,不然會影響父元素或後續元素的頻繁回流

  • 3、GPU加速:transform、opacity、filters、will-change等樣式

  • 9、判斷一個物件是陣列的方法?

  • Object.prototype.toString.call(xxx)

  • Array.isArray(xxx)

  • xxx instaceOf Array

  • 10、怎麽尋找react頁面卡頓的原因?

    11、編程題:實作一個物件的 flatten 方法,如下:

    const obj = { a: { b1, c2, d: { e5 } }, b: [13, {a2b3}], c3 }

    flatten(obj){} 結果返回如下:

    // { // 'a.b': 1, // 'a.c': 2, // 'a.d.e': 5, // 'b[0]': 1, // 'b[1]': 3, // 'b[2].a': 2, // 'b[2].b': 3 // c: 3 // }

    解題

    const isObject = (target) => {
    returntypeof target === 'object' && target !== null
    }
    const flatten = (obj) => {
    if (!isObject) return
    const res = {}
    const dfs = (cur, prefix) => {
    if (isObject(cur)) {
    if (Array.isArray(cur)) {
    cur.forEach((item, index) => dfs(item, `${prefix}[${index}]`))
    else {
    for(let key in cur) {
    dfs(cur[key], `${prefix}${prefix ? '.' : ''}${key}`)
    }
    }
    else {
    res[prefix] = cur
    }
    }
    dfs(obj, '')
    return res
    }

    二面

    1、說說對web worker的理解

  • 1、開啟一個子執行緒,並在此子執行緒進行一些大數據處理或者耗時的操作

  • 2、使用 postMessage onmessage ,實作主執行緒和子執行緒之間的通訊

  • 3、使用 onerror 監聽子執行緒掛了沒

  • 4、 web worker 並沒有改變JavaScript單執行緒的事實

  • 2、service worker和強緩存相比,有哪些優勢?

    service緩存沒用過。。

    3、說說對堆疊溢位的理解?

    常見的情況發生在 大數量遞迴 死迴圈 時,就會造成 棧溢位 ,因為每次執行程式碼都需要分配一定空間的記憶體,以上兩種情況都會使執行空間超出最大限度,從而報錯

    4、position中的sticky是什麽,還有哪些其他的?

  • static:預設

  • relative:相對定位,相對於自身定位

  • absolute:絕對定位,相對於非static的第一個祖宗元素定位

  • fixed:相對於瀏覽器視窗進行定位

  • inherit:規定應該從父元素繼承 position 內容的值

  • sticky:吸頂定位

  • 5、ts中,any和unknown分別是什麽意思?泛型怎麽使用?

  • any:變量如果是 any 型別,繞過所有型別檢查,直接可使用

  • unknown:變量如果是 unknow 型別,需要判斷完是什麽型別之後才能使用

  • 6、bind有什麽用?連續多個bind,最後this指向是什麽?

    bind 的作用是改變函式執行的指向,且不會立即執行,而是返回一個新的函式,可以自主呼叫這個函式的執行(此函式不可當做建構函式)

    連續多個bind之後this指向始終指向第一個

    7、webpack的plugin怎麽實作?

    一個plugin就是一個類,類裏有一個 apply方法 ,每次打包時都會呼叫這個apply,而這個apply方法接受一個參數物件,其中有一個 plugin 方法,此方法中有許多 勾點函式 ,且可以決定靜態檔的生成,修改等等

    8、編程題:

    現已知一個字串是由正整數和加減乘除四個運算子(+ - * /)組成。例如存在字串 const str = '11+2-3 4+5/2 4+10/5',現在需要將高優先級運算,用小括弧包裹起來,例如結果為 '11+2-(3 4)+(5/2 4)+(10/5)'。註意可能會出現連續的乘除運算,需要包裹到一起。請用 javascript 實作這一過程

    解答 我比較菜,用的方法也是臨時想出來的,沒有最佳化,大家將就著看吧:

    const checkType = (str) => {
    if (['*''/'].includes(str)) return'high'
    if (['+''-'].includes(str)) return'low'
    return'number'
    }
    const addBrackets = (formula) => {
    const strs = formula.split('')
    let i = 0, j = 1, high = false, res = []
    while(j < strs.length) {
    const jType = checkType(strs[j])
    if (jType === 'low' && !high) {
    i = ++j
    j++
    }elseif (jType === 'low' && high) {
    res.push(j++)
    i = j++
    high = false
    }elseif (jType === 'high') {
    j++
    !high && res.push(i)
    high = true
    }else {
    j++
    }
    }
    if (high) res.push(strs.length)
    let add = 0
    for(let i = 0; i < res.length; i++) {
    const index = res[i]
    strs.splice(index + add, 0, add % 2 ? ')' : '(')
    add++
    }
    return strs.join('')
    }

    三面

    1、手寫體:使用TypeScript 實作一個 get 函式來獲取它的內容值

    const data = { name'tom'age18address'xxx' }

    解答:

    constget = <T extends object, K extends keyof T>(obj: T, key: K): T[K] => {
    return obj[key]
    }

    2、ts中的 any 、 unknown 的區別?

  • any:變量如果是 any 型別,繞過所有型別檢查,直接可使用

  • unknown:變量如果是 unknow 型別,需要判斷完是什麽型別之後才能使用

  • 3、有用過ts中的 keyof 嗎?

    將一個interface的所有key,匯聚成一個聯合型別,可以用來對傳入key的限制,比如:

    interface Target {
    name: string,
    age: number
    }
    const fn = (obj: Target, key: keyof Target) => {}
    const obj: Target = { name'sunshine'age18 }
    fn(obj, name) // 成功
    fn(obj, age) // 成功
    fn(obj, height) // 報錯

    4、for in/for of的區別?

  • for in:遍歷物件的key或者陣列的索引

  • for of:遍歷可叠代物件的值,如陣列、Set

  • 5、Promise值穿透

    then或catch沒有傳入函式的話,會發生值穿透,原理是Promise內部檢測如果傳入的是非函式,則會拿上一次的結果包裝成一個返回Promise的函式,達到穿透效果

    例如:

    Promise.resolve('foo')
    .then(Promise.resolve('bar'))
    .then(function(result){
    console.log(result) // foo
    })

    但是如果傳入的是函式的話:

    Promise.resolve('foo')
    .then(() =>Promise.resolve('bar'))
    .then(function(result){
    console.log(result) // bar
    })

    結語

    我是林三心

  • 一個待過 小型toG型外包公司、大型外包公司、小公司、潛力型創業公司、大公司 的作死型前端選手;

  • 一個偏前端的全幹工程師;

  • 一個不正經的金塊作者;

  • 逗比的B站up主;

  • 不帥的小紅書博主;

  • 喜歡打鐵的籃球菜鳥;

  • 喜歡歷史的乏味少年;

  • 喜歡rap的五音不全弱雞如果你想一起學習前端,一起摸魚,一起研究簡歷最佳化,一起研究面試進步,一起交流歷史音樂籃球rap,可以來俺的摸魚學習群哈哈,點這個,有7000多名前端小夥伴在等著一起學習哦 --> 摸魚沸點

  • 廣州的兄弟可以約飯哦,或者約球~我負責打鐵,你負責進球,謝謝~