1. 程式人生 > >2020前端春招經驗分享,從面試小白到老油條的蛻變

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層級關係

    權重

    • tag(標籤選擇器):1
    • class(類選擇器):10
    • id(id選擇器):100
    • tag行內樣式:1000
    • !important最大

    權重一樣的情況下,後宣告的覆蓋前面的







  3. 你瞭解BFC嗎,如何觸發


    BFC規範(塊級格式化上下文:block formatting context)

    • 規定了內部的Block Box如何佈局:內部的Box會在垂直方向上一個接一個放置
    • Box垂直方向的距離由margin決定
    • 每個元素的margin box 的左邊,與包含塊border box的左邊相接觸
    • BFC的區域不會與float box重疊
    • 屬於同一個BFC的兩個相鄰Box的margin會發生重疊
    • 計算BFC的高度時,浮動元素也會參與計算
    • 隔離的獨立容器,容器裡面的子元素不會影響到外面的元素

    如何觸發

    • float值不為none
    • overflow不為visible
    • display的值為inline-block、table-cell、table-caption
    • position的值為absolute或fixed


  4. 彈性佈局flex

  5. 柵欄佈局grid

  6. display屬性值有哪些,分別是什麼作用

  7. position屬性值有哪些,分別有什麼作用

  8. display:none,opactiy:0,visibility:hidden區別

6.VUE

  1. 資料雙向繫結,資料響應式實現的原理
  2. 生命週期
  3. 元件之間通訊方法(父子,兄弟,祖孫,任意)
  4. v-if,v-show異同
  5. 路由原理,為什麼地址發生改變,瀏覽器不會重新整理
  6. 許可權管理

7.瀏覽器相關問題

  1. 快取機制
  2. 頁面渲染原理(過程)
  3. 本地儲存
  4. 瀏覽器安全相關問題(SQL注入,XSS,CSRF,DNS劫持,點選劫持)

8.效能優化

  1. Webpack程式碼打包優化
  2. 網路層面優化
  3. 首屏載入優化

9.小程式

  1. 小程式的特點
  2. 你對小程式的發展看法
  3. 小程式的原理
  4. 小程式與傳統移動端Web的區別

因篇幅有限,內容太多,部分未回答的內容與6-9部分的題目回答,都整理在了我的→部落格←中,歡迎大家戳連結檢視

下面分享(水貨)一下個人是如何跳進前端這個"坑"

在校經歷

專業是"電腦科學與技術",學院的培養方向為嵌入式開發工程師,在上大學前,想的學計算機學做遊戲,大一開學後的新生研討課就直接來了當頭一棒,專業只教嵌入式相關知識

我想嵌入式就嵌入式嘛,哪曉得培養計劃也太落後了,全是理論課,實驗課也是給個試驗箱,比著實驗報告一步步做,啥東西都學不到.跟我想象中的(智慧電子裝置開發)差太遠了,然後就自學U3D去了,學了幾個月聽說獨立遊戲開發沒有"錢途",就剎車了,剛好學校有個軟體開發的比賽,跟同學組了個隊就參加了,三個人(1划水,1JAVA,我就只好搞前端了),這一搞就覆水難收了,從此踏上前端不歸路

最開始學的東西非常雜,周圍也沒有前端大佬,自己摸索著學習,走了不少彎路,接了不少商業外包和學校的比賽專案,導致後端技術也蹭蹭蹭的學了不少,但還沒有一個深入的點,大二的時候就在考慮到底做後端還是前端亦或是"偽全棧(會寫頁面+CRUD)",後來思考了一段時間選擇了前端,覺得前端更容易出成果,更容易實現自己的想法,然後開始系統性的學習前端

在大三的時候開始準備複習春招找工作,看了看牛客上的面經,發現好多技術名詞都不知道,很多點自己都還不會,被做專案的能力迷惑了,心想涼了,自己開始慌了,然後把手裡的專案加急趕完,然後杜絕一切外包和學校的專案,開始緊張的複習

比較喜歡的一句雞湯

你的指尖,擁有改變世界的力量

當沒有學習動力的時候,默唸幾遍雞湯,想想未來的規劃,然後就又充滿學習的激情了

最後

感謝掘金的各位大佬,是大佬們分享的經驗把我抬進大廠的,
非常感謝阿里淘系的面試官提的建議,及時指出了我面試中的一些問題,最終雖然沒有通過阿里的面試,但受益匪淺,依舊感到非常幸運

掘金原文
個人站點

  • Github
  • 部落格
  • 部落格園