­

2020前端春招經驗分享,從面試小白到老油條的蛻變

終於上岸了嗚嗚嗚…,終於又能愉快的寫程式碼了

tip:為方便閱讀部分內容細節使用摺疊

圖片

自我介紹

大三雙非本科,大一開始學前端,今年2月底開始投實習,不久前終於收到了美團的offer,心花怒放

初生牛犢不怕虎,前期沒好好準備,浪費了太多好機會,奉勸大家一定要好好複習和總結

→面試歷程(不含筆試時間)
  1. 2月25日:阿里淘系一面
  2. 2月26日:CVTE一面(涼)
  3. 3月13日:騰訊一面
  4. 3月23日:阿里淘系二面(涼)
  5. 3月24日:位元組一面(涼)
  6. 3月25日:騰訊二面
  7. 3月26日:騰訊三面(涼)
  8. 3月28日:美團一面
  9. 3月31日:美團二面
  10. 4月03日:美團hr面
  11. 4月03日:蘑菇街一面
  12. 4月09日:蘑菇街二面(拒)
  13. 4月10日:TW一面
  14. 4月10日:騰訊換部門撈起來一面(涼)
  15. 4月12日:百度一,二,三面技術
  16. 4月13日:美團OC(上岸)
  17. 4月16日:網易雲一面
  18. 4月16日:TW二面

當淘系前端二面涼了之後,周圍同學都陸續上岸了,我開始慌了,就海投了一波

圖片

→目前還在流程中
  1. 百度
  2. TW
  3. 網易雲
  4. 騰訊
  5. 快手

下面開始乾貨分享,請各位細細品,如有不足之處還請斧正

面試前應該做哪些準備?

1.一些知識儲備

這裡主要是根據我的面試經驗總結的一些面試高頻的知識點供大家參考,以樹形結構展開(避免貼圖勸退)

對前端的電腦基礎考查相比後端開發已經簡單了許多,大廠一二面也特別愛考查這部分內容

如果並沒有深入了解或使用Node,大家可以不用刻意去準備Node

電腦基礎知識
  • 演算法與數據結構
    1. 鏈表
    2. 堆/棧
    3. 哈希表
    4. 二叉樹
    5. 各種排序,尤其是快排
    6. BST
    7. KMP
    8. 二分
  • 作業系統
    1. 執行緒相關的問題
    2. 進程相關的問題
    3. 進程與執行緒進行對比所產生的問題
  • 電腦網路
    1. TCP相關
    2. UDP相關
    3. HTTP相關
    4. DNS相關
  • 設計模式
    1. 工廠模式
    2. 抽象工廠模式
    3. 單例模式
大前端
  • JS(包含ES6)
    1. DOM事件觸發的幾個階段(捕獲,目標,冒泡)相關問題
    2. 值類型與引用類型相關問題
    3. 函數柯里化
    4. 閉包
    5. this指向判斷
    6. apply,call,bind
    7. event loop
    8. promise
    9. 定時器
    10. 原型與原型鏈
    11. 箭頭函數
    12. 類型轉換
    13. async與await
    14. 類數組
    15. 節流防抖
    16. 垃圾回收機制
    17. typeof與instanceof
    18. ==與===
    19. JS中的繼承實現
    20. let,const,var區別
    21. 各種遍曆數組的方式比較(for,forof,forin,forEach)
  • CSS
    1. 迴流與重繪
    2. 盒模型
    3. 彈性布局(flex)
    4. 柵欄布局(grid)
    5. display各種值及其作業
    6. position各種值及其作用
    7. BFC(概念,如何觸發,特點)
    8. display:none,visibility:hidden,opacity:0區別
    9. CSS層級關係,樣式權重計算
    10. CSS偽類
    11. CSS偽元素
    12. 斑馬紋實現
    13. 簡單動畫的實現
    14. 小球從螢幕左滾動到右xxxpx
    15. 子元素相對於父元素水平居中的方法
    16. 子元素相對於父元素水平垂直居中的方法
    17. 如何做頁面主題(皮膚)切換
  • VUE(針對沒看源碼)
    1. 數據雙向綁定,數據響應式實現的原理
    2. 生命周期
    3. 組件之間通訊方法(父子,兄弟,祖孫,任意)
    4. v-if,v-show異同
    5. 路由原理,為什麼地址發生改變,瀏覽器不會刷新
    6. 許可權管理
  • 瀏覽器
    1. 快取機制
    2. 頁面渲染原理(過程)
    3. 本地存儲
    4. 瀏覽器安全相關問題(SQL注入,XSS,CSRF,DNS劫持,點擊劫持)
    5. 跨域相關問題(原因,解決方式)
    6. 同源策略
    7. 預檢請求
  • 性能優化
    1. Webpack程式碼打包優化
    2. 網路層面優化
    3. 首屏載入優化
  • 小程式
    1. 小程式的特點
    2. 你對小程式的發展看法
    3. 小程式的原理
    4. 小程式與傳統移動端Web的區別
  • Node
    1. node中的Event loop
    2. node中的進程與執行緒相關問題
  • 正則表達式簡單使用

圖片

圖片

2.總結自己的項目

如果你的項目非常有意思的話,不妨多多總結一下其閃光點,如果你的項目非常有意思,很容易與面試官產生共鳴,妥妥的面試+分,也能讓他留下一個印象

主要從:

  • 項目背景
  • 對於多人協作項目在項目中所擔任的職責,以及對項目的貢獻
  • 遇到了什麼難題,如何解決的
  • 項目的創新點
  • 你有什麼收穫
  • 項目所用技術棧,項目產出(web(PC/Mobile),app,小程式?)

這幾個方面,更加細節之處可以參考面試被問項目經驗不用慌,按這個步驟回答絕對驚艷

3.根據當前面試的進度做相應的複習

部分公司的職位可能需要4+1 甚至 5+1 ,小生太菜雞,尚未觸及

對於2+1的面試

  • 一面:電腦基礎+前端相關
  • 二面:項目+電腦基礎+前端相關
  • hr面:非技術的開放性問題

對於3+1的面試

  • 一,二面:電腦基礎+前端相關
  • 三面:項目+非技術開放性問題+一點點大前端相關
  • hr面:非技術的開放性問題

4.面試中自我介紹打草稿

大多數面試開場就是叫你介紹一下自己,這個環節還是非常重要的,說得好,能夠面試官留下深刻印象

但需要注意在自我介紹的時候,不要給自己挖坑,面試官一般會根據你自我介紹中的項目經歷,或者個人技術棧展開提問,如果對某一門技術棧只停留在使用/了解階段(Hello World),盡量不要提

  1. 個人基本資訊:姓名,目前狀況(大三,應屆),興趣愛好
  2. 前端的學習經歷
  3. 實習經歷
  4. 項目經歷可以簡單介紹一下
    1. 你收貨最大的項目
    2. 最近做的一個項目
    3. 自己最自豪的個人作品

5.面試中常常問的非技術問題準備

一定要自己下來打打草稿,臨場發揮難免不完美

展開查看
  1. 除開發外有什麼其他興趣愛好嗎
  2. 畢業後直接工作還是考研,為什麼不考研
  3. 未來/近5年的職業規劃
  4. 你認為自己的優勢/長處是什麼
  5. 你認為自己有什麼不足之處
  6. 為什麼選擇前端
  7. 平時是如何學習的,最近在看什麼
  8. 如何平衡學校的課程學習與前端的自學與開發
  9. 你覺得自己最成功的一次分享或者成果是什麼
  10. 有投其它公司嗎?有結果了沒?為什麼沒過,你知道原因嗎
  11. 為什麼選擇我們

面試中

  1. 如果是初次面試難免會緊張,這個不可避免,隨著面試次數增加應增加自己的自信心,減少緊張時間
  2. 語速不能過快
  3. 面試官提問後,不要急於回答,可以在大腦中思考幾秒中整理回答的思路,再脫口而出,出口成章,減少回答時卡頓
  4. 當遇到手撕程式碼的時候,如果思考了一段時間,一點思路都沒有,就直接給面試官說,避免長時間耗著(面試時長是有限的一般技術面再1小時左右短的30-40分鐘)
  5. 手撕程式碼,如果你有解決方案即便不是最優的也可以寫上,然後面試官會問你有不有更優的解法(或者優化空間),你可以藉此再思考一小會兒,沒有的話直接告知面試官(部分面試官在當你結束這題作答的時候,會告訴你一個解法的思路)
  6. 一般在面試快結束時,面試官會問你有什麼問題需要問他,不要說沒有問題,可以問問部門的一些情況,面試官職級,負責的產品,前端部門有開源項目沒,當前面試的什麼部門,未來工作Base在哪裡等等,也可以聊聊與工作無關的,暢所欲言,交流得愉快的話也能給面試加分

面試後

及時整理面試內容,大多數情況下面試都會遇到知識盲點,一定要下來去查資料了解,填上這個點,為下次面試做足準備

如果面完了HR面切忌不要放鬆(除非有100%的把握通過),身邊不少HR面掛掉的例子,不然還是繼續投,該筆試的筆試,該面就面

面試中所遇問題整理(附部分自我回答)

以面試題類型分類整理,為什麼不按公司分?在我看來同一個公司不同的人面難有太多相同的面試題,只有綜合多家的經驗才能百戰不殆

0.在瀏覽器中輸入URL到頁面渲染的整個過程(詳解,非常高頻的考點)


構建請求行

GET   /     HTTP/1.1
方法  請求路徑 請求的協議/版本

查找強快取

檢查資源是否存在強快取,存在的話直接進行資源解析

讀取DNS快取

  1. 瀏覽器先檢查自身快取中有沒有被解析過的這個域名對應的ip地址,如果有,解析結束
  2. 檢查作業系統快取中有沒有對應的已解析過的結果(win中的hosts文件)
  3. 都沒有則進行下一步

DNS解析

  1. 請求本地域名伺服器(LDNS)來解析這個域名,沒有則進行下一步
  2. DNS 根伺服器查詢

建立TCP連接

可以在此簡述建立TCP鏈接的3次握手的過程

  1. 客戶端服務端發送請求報文
  2. 服務端收到請求報文,同意連接則向客戶端發送一個應答
  3. 客戶端收到服務端的應答,並告知服務端我準備好了

TCP 的一些特性

  • 建立連接需要進行三次握手
  • 斷開連接都需要四次握手
  • 在傳輸數據的過程中,通過各種演算法保證數據的可靠性
  • 相比 UDP 來說不那麼的高效。

判斷是否是Https請求

是:進行TLS握手

基本過程

  1. 客戶端向伺服器端索要並驗證公鑰
  2. 雙方協商生成」對話密鑰」
  3. 雙方採用」對話密鑰」進行加密通訊

在 TLS 握手階段,兩端使用非對稱加密的方式來通訊,但是因為非對稱加密損耗的性能比對稱加密大,所以在正式傳輸數據時,兩端使用對稱加密的方式通訊

否:發起Http請求

發送HTTP請求

向服務端正式發送http請求

返回HTTP報文

伺服器處理請求響應結果,並返回Http報文

判斷狀態碼是什麼?

200:繼續解析,如果 4xx 或 5xx 的話就會報錯,如果 3xx 進行重定向

如果是gzip格式的話會先解壓一下,然後通過文件的編碼格式去解碼文件

瀏覽器解析渲染頁面

  1. 針對下載完成後的HTML文件
    • 詞法分析:標記化
    • 語法分析:構建DOM樹
  2. 解析HTML(超文本標記語言)–>DOM(文檔對象模型)樹
    • 遇到 script 標籤的話,會判斷是否存在 async 或者 defer屬性
      • async:並行進行下載,下載完成後並執行js
      • defer:先並行下載文件,然後等待 HTML 解析完成後順序執行。
      • 如果都沒有:就會阻塞住渲染流程直到 JS 下載並執行完畢
    • 遇到link下載並解析CSS(層疊樣式表)–>CSSOM(CSS對象模型)樹
      • link標籤引用
      • style標籤中的樣式
      • 元素的內嵌style屬性
  3. DOM樹 + CSSOM樹 –> Render Tree(渲染樹):CSSOM 樹和 DOM 樹構建完成後開始生成渲染樹
  4. 迴流(Layout):根據生成的渲染樹,迴流得到節點的幾何資訊(位置,尺寸)
    • 計算可見的Dom節點在設備視口的位置和尺寸,這個計算階段就是迴流
    • 為了知道每個可見節點在視口的確切大小和位置,瀏覽器從渲染樹的根節點進行遍歷
  5. 重繪(Painting):根據渲染樹與迴流得到的節點幾何資訊,得到節點的絕對像素
    • 經過生成的渲染樹和迴流階段,得到了所有可見節點具體的幾何資訊與樣式,然後將渲染樹的每個節點轉換成螢幕上的實際像素,這個階段就叫重繪節點
  6. 將像素髮送給GPU繪製,合成圖層,然後展示在頁面上

斷開TCP連接

簡述斷開進行4次數握手過程

  1. 客戶端服務端發送釋放連接的請求
  2. 服務端收到客戶端的請求後,告知應用層釋放連接
  3. 服務端將數據發送完畢後,再向客戶端發送釋放連接請求
  4. 客戶端收到釋放請求後,並向服務端發送確認釋放的應答,同意釋放

1.演算法與數據結構


  1. 查找一個字元串是否在另一個字元串中存在,考查KMP
  2. 鏈錶轉置,迭代/遞歸
  3. 合併兩個有序鏈表
  4. 合併兩棵BST
  5. 構建BST
  6. 二叉樹前/中/後序遍歷
  7. TopK問題
  8. 二叉樹深度優先/DFS,廣度優先(層序遍歷)/BFS
    // DFS藉助棧
    function dfs(root){
        let stack = []
        if(!root){
            stack.push(root)
        }
        while(stack.length!==0){
            let node = stack.pop()
            console.log(node.value)
            if(node.right){
                stack.push(node.right)
            }
            if(node.left){
                stack.push(node.left)
            }
        }
    }
    
    // BFS藉助隊列
    function bfs(root){
        let queue = []
        if(!root){
            queue.push(root)
        }
        while(queue.length!==0){
            let node = queue.shift()
            console.log(node.value)
            if(node.left){
                stack.push(node.left)
            }
            if(node.right){
                stack.push(node.right)
            }
        }
    }
    
  9. 快速排序
    function quickSort(array) {
        const _quickSort = (arr, left, right) => {
            if (left >= right) {
                return
            }
            let o = left
            let start = left
            let end = right
            while (left < right) {
                while (arr[right] >= arr[o] && right > left) {
                    right--
                }
                while (arr[left] <= arr[o] && left < right) {
                    left++
                }
                if (left !== right) {
                    swap(arr, left, right)
                }
            }
            [arr[o],arr[left]] = [arr[left],arr[o]]
            _quickSort(arr, start, left - 1)
            _quickSort(arr, left + 1, end)
        }
        _quickSort(array, 0, array.length - 1)
    }
    

2.電腦網路


  1. TCP與UDP的區別
  2. 簡述HTTP(把你知道的與HTTP相關的都吐露出來)
  3. HTTP中常用首部欄位有哪些?你了解哪些HTTP首部
  4. HTTP狀態碼有哪些,各代表什麼
  5. HTTP常用方法有哪些
  6. 簡述UDP
    • 面向無連接:不需要在正式傳遞數據之前先連接起雙方
    • 數據報文的搬運工:不保證有序且不丟失的傳遞到對端
    • 沒有任何控制流量的演算法,以恆定速率傳輸
    • 適用於對網路通訊品質要求不高但實時性要求高的地方
      • 直播,語音,視屏等場景
  7. 簡述TCP
    • 面向有連接:建立鏈接三次握手,斷開四次握手
    • 在傳輸數據的過程中,通過各種演算法保證數據的可靠性
    • 應用場景
      • HTTP
      • FTP
      • 網遊
  8. 為什麼TCP要經歷三次握手,不是一次或者兩次
    • 防止出現失效的連接請求報文段被服務端接收的情況,從而產生錯誤
    • 如果一次:客戶端發送連接請求後,沒有收到服務端的應答,是沒法判斷連接是否成功的
    • 如果兩次:客戶端發送連接請求後,等待伺服器端的應答。如過客戶端的SYN過了一段時間沒有到達伺服器端,客戶端鏈接超時,會重新發送一次連接,如果重發的這次伺服器端收到了,且應答了客戶端,連接就建立了。但是建立後,第一個SYN也到達服務端了,這時服務端會認為這是一個新連接,會再給客戶端發送一個ACK,這個ACK當然會被客戶端丟棄。但是此時伺服器端已經為這個連接分配資源了,而且伺服器端會一直維持著這個資源,會造成浪費
  9. HTTP與HTTPS的區別
    • HTTP是明文傳輸的
    • HTTP(80) 和 HTTPS(443) 使用不同的埠
    • HTTP 頁面響應速度比 HTTPS 快
    • HTTPS 是建構在 SSL/TLS 之上的 HTTP 協議,HTTPS 比 HTTP 要更耗費伺服器資源
    • HTTPS是在HTTP上建立SSL/TLS加密層,並對傳輸數據進行加密
  10. HTTP2的特點
    • 多路復用
    • Header壓縮
    • 服務端主動 Push資源
    • HTTP/2 中引入了新的編碼機制,所有傳輸的數據都會被分割,並採用二進位格式編碼
  11. HTTP2使用條件
    • 支援Http2的服務端與客戶端
    • 域名就必須是https(基於TLS/1.2或以上版本的加密連接)
  12. 簡述TLS協議工作過程

    利用非對稱加密實現身份認證和密鑰協商,對稱加密演算法採用協商的密鑰對數據加密,基於散列函數驗證資訊的完整性

3.作業系統


  1. 執行緒與進程的概念/區別/如何工作
  2. 進程|執行緒之間如何通訊的
  3. 進程如何切換

4.JS


  1. 為什麼typeof null == ‘object’|null是對象嗎

    null不是對象

    雖然 typeof null 會輸出 object,但是這只是 JS 存在的一個悠久 Bug。在 JS 的最初版本中使用的是 32 位系統,為了性能考慮使用低位存儲變數的類型資訊,000 開頭代表是對象,然而 null 表示為全零,所以將它錯誤的判斷為 object

  2. 什麼是函數柯里化

    把一個接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,並且返回(接受剩下的參數而且返回結果的)新函數的技術

  3. 對象類型和原始值類型的不同之處

    對象

    • 對象類型存儲的是(地址)指針:聲明一個對象會在記憶體中開闢一塊空間存放值
    • 變數賦值的時候是賦值的地址:新變數修改會影響原變數
    • 存在深淺拷貝問題

    值類型

    • 賦值的時候拷貝的一個新的值,不會影響原來的
  4. typeof能否正確判斷類型

    能夠判斷

    • number
    • string
    • boolean
    • undefined
    • symbol
    • function
  5. instanceof能正確判斷類型的原因是什麼
    • 通過原型鏈進行判斷
    • 每個對象都有一個原型,instanceof會沿著原型鏈進行判斷,直到最頂層原型為止
    • 可以通過Symbol.hasInstance重定義instanceof的行為,所以instanceof的結果不一定絕對正確
  6. 什麼是原型,原型鏈
    • 每一個js對象在創建的時候就會自動關聯另一個對象,這個對象就是原型,每一個對象都會從原型”繼承”屬性
    • 相互關聯的原型組成的鏈狀結構就是原型鏈
  7. this指向如何判斷,箭頭函數的 this 是什麼
    • 對於普通函數來說,this->window
    • 對於對象來說,誰調用函數誰就是this
    • new 的方式,this永遠被綁定在實例上
    • bind/call/apply對於這些函數來說,this 取決於第一個參數,如果第一個參數為空,那麼就是 window
    • 不管給函數 bind 幾次,function中的 this 永遠由第一次 bind 決定
    • 箭頭函數本身是沒有this
    • 箭頭函數中的this取決於包裹箭頭函數的第一個普通函數的this
    • 箭頭函數使用bind,call,this無效

    一個筆試題

    let obj2 = {
        name: 'obj2'
    }
    
    const obj = {
        name: 'obj',
        say1() {
            console.log(this.name)
        },
        obj1: {
            name: 'obj1',
            say2() {
                console.log(this.name);
            }
        },
        say3() {
            const fn = () => {
                console.log(this.name);
            }
            fn()
        },
        say4() {
            const fn = function () {
                console.log(this.name);
            }
            fn()
        },
        say5() {
            const fn = () => {
                console.log(this.name);
            }
            fn.call(obj2)
        },
        say6() {
            const fn = function () {
                console.log(this.name);
            }
            fn.call(obj2)
        }
    }
    
    let a = obj.say1
    let b = obj.obj1.say2
    a() 
    b()
    obj.say1()
    obj.obj1.say2()
    obj.say3()
    obj.say4()
    obj.say5()
    obj.say6()
    

    結果

    undefined
    undefined
    obj
    obj1
    obj
    undefined
    obj
    obj2
    
  8. == 和 === 有什麼區別

    ==

    • 首先會判斷兩者類型是否相同。相同的話就直接進行比較
    • 如果對比雙方的類型不一樣的話,就會進行類型轉換
    • null 與 undefined : true
    • string 與 number : string->number
    • 其中一方為 boolean:boolean -> number
    • object 與 string、number、symbol : object -> 原始值類型

    ===

    • 判斷兩者類型和值是否相同,都相同則true
  9. 什麼是閉包,其特點與缺點

    1.簡單定義

    閉包就是能夠讀取其它函數內部變數的函數

    2.使用場景

    • 需要重用一個變數,又要保護變數不會被污染
    • 將一個變數長期駐紮在記憶體當中可用於循環取值
    • 私有變數計數器,外部無法訪問,避免全局變數額污染

    3.特點

    參數與變數不會被垃圾回收機制回收

    4.與作用域相比較

    • 全局變數
      • 優:可重用
      • 缺:容易污染
    • 局部變數
      • 優:不會被污染,僅函數內部可用
      • 缺:不可重用

    5.缺點

    • 比普通函數佔用更多的記憶體。
    • 記憶體泄漏的影響,當記憶體泄漏到一定程度會影響你的項目運行變得卡頓等等問題
    • 釋放方法:將引用內層函數對象的變數賦值為null
  10. 淺拷貝/深拷貝是什麼,如何實現?

    淺拷貝

    • 只拷貝一層,深層次的對象只能拷貝對象的引用

    淺拷貝實現

    • Object.assign
    • 展開運算符...

    深拷貝

    • 完整的拷貝一個深層次的對象

    深拷貝實現

    面試中一般不會考慮過多的邊界問題,一般考查遞歸實現一個能夠拷貝對象與數組混合的對象

    • JSON.parse(JSON.stringify(object))
      • 忽略undefined
      • 忽略symbol
      • 不能序列化函數
      • 不能解決循環引用的對象
    • 遞歸實現deepClone
  11. Promise 有幾種狀態,分別是什麼

    三種狀態

    • pending:等待
    • resolved:完成
    • rejectde:拒絕

    一旦從等待狀態變成為其他狀態就永遠不能更改狀態

  12. 你了解async/await嗎,簡單描述一下
    • 特點
      • 一個函數如果加上async 那麼其返回值是Promise,async 就是將函數返回值使用 Promise.resolve() 進行包裹
      • await只能配合async使用 不能單獨使用
    • 優點
      • 相比於Promise來說優勢在於能夠寫出更加清晰的調用鏈
    • 缺點
      • 因為await將非同步程式碼變成了同步程式碼,如果多個非同步之間沒有關係,會導致性能降低
    • 原理
      • await 就是 generator 加上 Promise 的語法糖,且內部實現了自動執行 generator
  13. 事件的觸發過程是怎麼樣的

    事件觸發有三個階段:

    • 捕獲階段
    • 目標階段
    • 冒泡階段
  14. 什麼是事件代理

    如果一個節點中的子節點是動態生成的,那麼子節點需要註冊事件的話應該註冊在父節點上

    • 節省記憶體,不需要給每個子節點註冊一次
    • 不需要給子節點註銷事件
  15. 什麼是同源策略,什麼是跨域,如何解決

    瀏覽器有同源策略,如果:協議,,域名有一個不同就是跨域

    解決方法

    • jsonp
    • 服務端開啟CROS支援
    • Nginx反向代理
  16. 你知道什麼是預檢請求嗎

    使用後端開啟CROS解決跨域的方式,會把請求分成兩種類型:

    • 簡單請求
    • 複雜請求

    對於複雜請求,首先會發起一個預檢請求,請求方法為options,通過該請求來判斷伺服器是否允許跨域

  17. 你知道什麼是event loop,簡單描述一下

    執行 JS 程式碼的時候其實就是往執行棧中放入函數,當遇到非同步的程式碼時,會被掛起並在需要執行的時候加入到 Task(有多種 Task) 隊列中,一旦執行棧為空,Event Loop 就會從 Task 隊列中拿出需要執行的程式碼並放入執行棧中執行

    Event Loop執行順序

    • 同步程式碼
    • 執行完所有同步程式碼後,執行棧為空,查詢是否有非同步程式碼需要執行
    • 執行 微任務,如果在執行microtask的過程中,又產生了microtask,那麼會加入到隊列的末尾,也會在這個周期被調用執行
    • 執行完所有微任務後,如有必要會渲染頁面:
      • 判斷document是否需要更新:瀏覽器是 60Hz 的刷新率,每 16.6ms 才會更新一次。
      • 判斷是否有 resize 或者 scroll 事件,有的話會去觸發事件:所以 resize 和 scroll 事件也是至少 16ms 才會觸發一次,並且自帶節流功能。
      • 判斷是否觸發了 media query
      • 更新動畫並且發送事件
      • 判斷是否有全螢幕操作事件
      • 執行 requestAnimationFrame 回調
      • 更新介面
    • 然後開始下一輪 Event Loop,執行宏任務中的非同步程式碼,也就是 setTimeout 中的回調函數

    總結

    • 宏隊列macrotask一次只從隊列中取一個任務執行,執行完後就去執行微任務隊列中的任務
    • 微任務隊列中所有的任務都會被依次取出來執行,直到microtask queue為空
    • 只要執行UI rendering,它的節點是在執行完所有的microtask之後,下一個macrotask之前,緊跟著執行UI render

    微任務

    • promise
    • MutationObserver
    • process.nextTick(node)

    宏任務

    • script
    • xhr
    • setTimeout
    • setInterval
    • setImmediate(node)
    • requestAnimationFrame(瀏覽器)
    • I/O
    • UI rendering(瀏覽器)
  18. var、let 及 const 區別

    全局作用域下:

    • 使用 var 聲明的變數會被掛載到window上
    • 使用 let 和 const 聲明的變數,不會被掛載到 window 上
    • 使用 var 聲明的變數會被提升到作用域的頂部,函數也會被提升,並且優先於變數提升

    let 與 const 不能在聲明前就使用,作用基本一致,後者聲明的變數不能再次賦值

  19. ES6有哪些新特性,你了解到的

5.CSS



  1. 什麼是迴流與重繪

    迴流

    計算可見的Dom節點在設備視口的位置和尺寸,這個計算階段就是迴流

    為了知道每個可見節點在視口的確切大小和位置,瀏覽器從渲染樹的根節點進行遍歷

    重繪

    經過生成的渲染樹和迴流階段,得到了所有可見節點具體的幾何資訊與樣式,然後將渲染樹的每個節點轉換成螢幕上的實際像素,這個階段就叫重繪節點


  2. CSS層級關係