「寒冬中」三年前端社招面試經驗

前言:16 年畢業的渣本程序員,畢業後一直在上海某公司工做,小組氛圍以及同事都很是 nice,可是業務線發展很差,年後回來後被砍了,不想內部轉崗到其餘部門,因此加入了找工做的大潮。此次的找工做經歷對我來講很重要,它讓我在準備的過程當中忽然對不少技術問題有所覺悟,想記錄一下此次的經驗。javascript

基本都是在 Boss 直聘加內推 ( 內推真的會比較靠譜,能夠提早知道消息而且避免去邊緣部門 ) 上投的,也沒投幾家,一開始就是奔着大廠去的,如今的公司不算大廠而且是按照業務線分組的,因此咱們小組幾我的開發一款產品,前端也一直只有我一我的在負責,因此一直想去大廠試試。css

大概面了 xxxxxxxxxxx(面試公司已刪,去哪家都是搬磚,差不了多少的),也是從一開始面試講話都有點不太自信,到後面有底氣去跟面試官扯皮子了,心態變化了不少。前端

忘了準備多久,目前的公司其實不加班,可是我都是晚上留到八九點,看書刷題,以前一直想看的劍指 offer 竟然也看完了,不懂的會跟着刷,從新開了 LeetCode 中國區的帳戶,刷了 10% 的題目,達到了一開始是對算法沒有思路到再也不懼怕算法知道能夠從哪裏入手的水平,不少公司面試算法其實沒要求那麼高特別是前端,不過也要對本身要求高一點。java

由於剛剛旅遊了一趟回來,對具體哪家公司的面試題目不太分得清了,如下都是個人面試內容,但願能對其餘人有所幫助:react

css

1. 三欄佈局

  • float
  • bfc (set middle area overflow is hidden)
  • position: absolute
  • 雙飛翼佈局
  • flex
  • table

2. 垂直居中

我的感受這個問不少,我通常就是答如下幾種:webpack

  • line-height: height 有被問到該值是否是等於高度設置的值,這個沒有答好,回來測試發現是跟盒模型相關的,須要是 computed height
  • absolute + transform 居中爲何要使用 transform(爲何不使用marginLeft / Top),這是一道重繪重排的問題。
  • flex + align-items: center 我會對 flex 容器以及 flex 項目的每一個 css 屬性都瞭解一遍,而且寫了一些小 demo。

3. 盒模型

4. BFC

  • 概念
  • 如何觸發
  • 怎麼應用

5. CSS 預處理器

通常回答 變量 / 嵌套 / 自動前綴 / 條件語句 / 循環語句git

我是一直很欣賞張鑫旭大神對 CSS 研究到很是透徹的境界,可是總結下來,對 CSS 通常不會考得很深,業界對 CSS 的專一度其實不夠,包括我我的也是沒投入不少時間精力在 CSS 上,若是有更深刻的理解固然是更好的。程序員

JS

1. 原型

其實以前剛畢業的時候就在啃高級程序設計,三年後仍是在考這個點。es6

  • 閉包 / 做用域 / this 指向
  • 實現 繼承
  • es5 實現 class
  • es5 實現 new

2. var let const

let/const 也存在變量聲明提高,只是沒有初始化分配內存。 一個變量有三個操做,聲明(提到做用域頂部),初始化(賦默認值),賦值(繼續賦值)。web

  • var 是一開始變量聲明提高,而後初始化成 undefined,代碼執行到那行的時候賦值。
  • let 是一開始變量聲明提高,而後沒有初始化分配內存,代碼執行到那行初始化,以後對變量繼續操做是賦值。由於沒有初始化分配內存,因此會報錯,這是暫時性死區。
  • const 是隻有聲明和初始化,沒有賦值操做,因此不可變。

const 只是保證了指向的內存地址不變,而不是內部數據結構不變。確保不會被其餘類型的值所替代。

3. 實現 promise

面 tx 的時候有讓我手寫實現 promise,由於有看過一點 bluebird 的源碼,因此對我來講還好。寫了一半就讓我停下來,我通常會邊寫邊講解,一上來先把框架搭好,例如

class Promise {
    constructor(executor) {
        // 設置屬性 status value resolveCbs rejectCbs
    }
    then(onResolved, onRejected) {}
    catch (cb) {
        return this.then(null, cb)
    }
}
複製代碼

而後再慢慢填充,這種作法會一上來讓人感受你是有思路的,並且瞭解 promise 的語法。

4. promise 鏈式

例如 promises = [],實現必須上一個異步完成後再去跑下一個任務。我是寫出兩種方案:

// 1.
const template = Promise.resolve();
promises.forEach((p) => {
    template = template.then(p)
})
// 2. 使用 await 
複製代碼

我的感受對 promise、async/await 都問比較多,包括比較火的問打印順序那種題還有捕獲異常的問題我也遇到過,只要對語法很是熟悉加上稍微瞭解實現細節都是沒問題。

5. 實現 bind

6. 實現事件系統 eventEmitter

跟 promise class 同樣,先搭建一個框架:

class EventEmitter {
    constructor() {
        this.events = {}
    }
    emit (eventName, args) {}
    on (eventName, callback) {}
    off (eventName, callback?) {}
}
複製代碼

以前有寫過事件系統,可是沒有考慮 once 之類的 method,也是面試官說了需求再一點點補充的。

7. 手寫 Proxy / Object.defineProperty

8. 事件委託

9. Event Loop

JS 執行是單線程的,它是基於事件循環的。事件循環大體分爲如下幾個步驟:

(1)全部同步任務都在主線程上執行,造成一個執行棧。

(2)主線程以外,還存在一個"任務隊列"。只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件。

(3)一旦"執行棧"中的全部同步任務執行完畢,系統就會讀取"任務隊列",看看裏面有哪些事件。那些對應的異步任務,因而結束等待狀態,進入執行棧,開始執行。

(4)主線程不斷重複上面的第三步。

event loop 基本每次都會被問到,通常就是說微任務、宏任務,怎麼樣的運行過程,以上是比較書面一點的回答,我本身也沒記得。

10. Webpack

  • loader plugin 的區別,一開始被問到還有點驚訝,不一樣做用的功能被問到一塊兒。
  • tree-shaking 的工做原理
  • code splitting用的是什麼插件
  • 如何提升 webpack 構件速度的
    • 利用 DllPlugin 預編譯資源模塊
    • 使用 Happypack 加速代碼構建

我寫過不少小項目,因此配過不少次 webpack,從 V2 到 V4,不過 webpack 通常沒有問不少。

11. 前端性能提高

通常我會分爲如下幾個方面來回答,通常會引伸到網絡、緩存方面的問題:

server:

  • 使用 cdn
  • 減小沒必要要的數據返回
  • 使用 gzip
  • 緩存 (etag / expires ...)

content:

  • 減小 http 請求 (css sprites / inline image)
  • 不一樣資源放在不一樣域下 (http1.1)
  • 延遲加載 / 延遲執行(當即下載,延遲執行[before DOMContentLoaded]defer) / 預加載(preload)
    • async,該布爾屬性指示瀏覽器是否在容許的狀況下異步執行該腳本。該屬性對於內聯腳本無做用 (即沒有 src 屬性的腳本)。
    • defer,這個布爾屬性被設定用來通知瀏覽器該腳本將在文檔完成解析後,觸發DOMContentLoaded事件前執行。
  • 精簡 HTML 結構
  • 壓縮資源

css:

  • in head
  • 較少的層級(以前被問到過是否有統計過層級多與少對性能的實質影響,實際上我是沒有作過此類研究,因此知道結論而不懂過程仍是欠缺的)

js:

  • before
  • 減小 dom 訪問(在 body 內放置的 JS 代碼是否能夠訪問到 body 標籤)

webpack:

  • tree shaking 去除沒有使用的代碼
  • 提取公共包,有被問到
  • 拆分模塊,按需加載
  • 優化圖片,使用 base64 代替小圖
  • file name with hash (etag)

12. Vue

由於我是寫 Vue 居多,因此簡歷上只寫了 Vue 而沒有 react 等其餘框架,通常都是被問到 Vue。

  • 父子組件通訊
  • 生命週期
  • 數據響應(數據劫持) 數據響應的實現由兩部分構成: 觀察者( watcher )依賴收集器( Dep ),其核心是 defineProperty這個方法,它重寫屬性的 getset 方法,從而完成監聽數據的改變。通常會要求從解析到收集依賴到通知一套工做原理比較熟悉。我是大概理解,跟着讀了一些源碼,可是仍是沒有講很清楚,遺憾沒有表現好。
  • 虛擬 dom、dom diff
  • nextTick

JS 確定是重點考察的部分,對象、繼承方面只要讀透高程再寫幾個 demo 掌握細節,es6 我是一直翻阮一峯寫的 ECMAScript 6 入門,Vue 的話首先把官網的內容掌握了,而後再去讀一些博客或者直接上源碼也是能夠的。

HTTP

1. 跨域

基本都被問同源策略以及引伸到跨域來,通常我會說 CORS 以及 jsonp,CORS 會從簡單請求跟非簡單請求區分開,再講 options 請求的意義。

2. HTTP 報文

請求行 + 頭部信息 + 空白行 + body 有被問到說空白行的意義,我一直覺得就是純粹來標識 headers 的結束,可是面試官說不止這個功能,我後面看了HTTP 權威指南 也沒有找到,Stack Overflow 也沒找到。。。但願有人知道能夠跟我說一下。不過有多是我聽錯了題目,畢竟是電話面試。

3. cookie session

通常會問二者的差異,以及引伸到 sessionStorage, localStorage, cookie 區別

4. 從輸入 URL 到頁面加載全過程

通常我會答連接的大部分步驟,按照理解來,這裏面我被問到的點有:

  • 緩存,分爲強緩存、協議緩存,通常會問到 304 的表現,以及再引伸到 301 302 的區別,我會再說 307 的區別。
  • 三次握手
  • HTTPS 的工做原理
  • CDN 的工做原理,以及刷新緩存的原理。
  • 瀏覽器渲染的步驟
  • 重繪重排的概念,以及最佳實踐。一直都知道應該用 transform 代替 margin,可是一被問原理,就不太清楚,查了資料是對 translate3d 的元素進行 GPU 加速。
  • 會由於 JS 是單線程而問到阻塞的問題,引伸到 async defer 等屬性。
  • status code 有哪些,咱們是嚴格按照 restful 的規範來設計接口,因此這個問題我一直以爲很簡單,可是被問到很多次。我記得趣頭條的筆試就有,我會把用過的按照 2xx(200, 201, 204, 206) 3xx(301, 302, 304, 307) 4xx(400, 401, 403, 405) 5xx(500, 502, 504) 來分類,我偶爾寫寫 rails,因此對對應的名詞都比較熟悉 貼一篇 list of rails status codes
  • DNS 解析過程

5. xss,csrf

  • xss 注入攻擊
    • 轉義
  • csrf (cross site request forgery)
    • Get 請求無反作用
    • cookie httponly
    • cors (origin not *)

我是經過看 這篇文章 對安全有更多瞭解的,推薦一下。

6. sse( server sent event)

由於寫過一個 sse 相關的插件,因此被問到過,是如何使用以及 EventSource 的 API。

感受前端對網絡、安全方面要求不是很高,沒被問過 HTTP2 或者長鏈接更多內容,以前看脈脈上一個後端被問從瀏覽器裏訪問一個地址,從網絡的 tcp/ip 協議、聊到操做系統 io、內存管理、進程管理和文件管理,再聊到負載均衡、限流算法、分佈式事務,相比之下前端真的簡單不少,不過知識儲備多確定是有用的。

算法

算法通常考得不難,不過基本每一次面試都會考到,我記得被考到算法題目有:

  • 層次遍歷一棵二叉樹 (這是惟一一道劍指 offer 上的題目了,最簡單的 😂 )
  • 字符串中找出最長最多重複的子串

想列舉發現不少已經忘了,感受不多會直接出現劍指 offer 的題目,也不會直接問某排序算法怎麼寫,這是我我的的體驗,僅供參考。刷題仍是頗有用的。

Git

  • 基本操做

  • git rebase vs git merge

    • git merge
      • 記錄下合併動做 不少時候這種合併動做是垃圾信息
      • 不會修改原 commit ID
      • 衝突只解決一次
      • 分支看着不大整潔,可是能看出合併的前後順序
      • 記錄了真實的 commit 狀況,包括每一個分支的詳情
    • git rebase
      • 改變當前分支 branch out 的位置
      • 獲得更簡潔的項目歷史
      • 每一個 commit 都須要解決衝突
      • 修改全部 commit ID

    回答時候沒有答出不少,這是後面總結,深入發現平常作總結的必要性,一直以爲本身是瞭解的,等到總結時候才發現有一些 point 仍是不清楚的。

  • 修改 commit message

沒有問很深,只是基礎操做多一點。若是平常是使用 git 開發,通常比較輕鬆應對。


總結:以上都是個人面試題目,並不是齊全的面試準備內容,我也遺忘了不少題目,再不寫下來估計忘更多了。通常都是問具體的技術問題加上項目經歷,由於我這邊作的事情是技術多於業務,目前只有我一我的負責所有的前端內容,因此對每一個項目都很是熟悉,建議對寫在簡歷上的項目都知根知底,避免出現被問到時候含糊不清的尷尬場景。

至於標題爲何「寒冬」加上雙引號,我以爲對寒冬的解釋在於我的而非徹底是大環境影響,感受每一個公司都挺缺人的,掛了鵝廠後 HR 給我看了面試評價以及又幫我投了其餘部門,不過是我在旅遊期間聯繫個人,已經接了 offer 就沒繼續面了。

我此次找工做的體會大體如此,沒有很糟糕沒有很愉快,過程當中壓力也是比較大的,可是換工做就是如此的啊,從溫馨區跳出來太難了,但願能經過個人經歷給人一點幫助吧。


這算是我寫的第一篇博客,有收到一些關注,只是由於在 juejin 看了一些面經因此想也寫一篇而已,實際上是沒有寫博客的習慣,因此關注的能夠取關。。。交流一些前端技術是歡迎的。

相關文章
相關標籤/搜索