百度:從八股文到項(xiàng)目深挖的面試復(fù)盤)
事情是這樣的。我在上一家公司待了快兩年屬于那種“文檔在手、天下我有文檔一關(guān)、直接抓瞎”的前端。圈里人管這個(gè)叫混子我認(rèn)。手上負(fù)責(zé)的頁(yè)面不算少但論深度也就是能跑、能上線、不出大事故的水平。某天關(guān)系不錯(cuò)的同事發(fā)來一條消息說百度某個(gè)前端組在招人崗位要求寫著“三年以上經(jīng)驗(yàn)、有大型項(xiàng)目?jī)?yōu)先”我掰手指一算年限剛好卡線。他問我投不投我說投唄面掛了又不扣工資萬一過了呢。結(jié)果從簡(jiǎn)歷篩選到 HR 面前后折騰了大半個(gè)月我居然一路走到了最后。先說結(jié)論這輪面試讓我最大的感觸是基礎(chǔ)前端八股文真的有用但只靠背八股文絕對(duì)過不了。整個(gè)過程里面試官問的東西大部分是網(wǎng)上能搜到的前端面試題但追問的深度和我平時(shí)刷題時(shí)想的完全不是一個(gè)量級(jí)。這篇文章我不打算寫那種“標(biāo)準(zhǔn)答案匯總”而是按照我真實(shí)的面試輪次把每一輪問了什么、我當(dāng)時(shí)怎么答的、哪些答崩了、哪些其實(shí)踩到了得分點(diǎn)原原本本捋一遍。適合正在準(zhǔn)備前端面試、尤其是打算沖大廠的朋友參考也適合那些覺得自己技術(shù)一般但想試試水的“混子型選手”——?jiǎng)e怕混子也有混子的打法。1. 開篇定調(diào)我這個(gè)「混子」是怎么混進(jìn)百度面試間的1.1 我的技術(shù)自畫像混在哪、不混在哪既然叫混子我得先老實(shí)交代一下自己的技術(shù)水平不然大家以為我在凡爾賽。我在上一家公司做的是偏業(yè)務(wù)型的前端Vue 2 為主后來項(xiàng)目局部升級(jí)過 Vue 3但組合式 API 用得不算深。UI 庫(kù)主要用 Element UI 和 Ant Design Vue日常開發(fā)就是寫頁(yè)面、調(diào)接口、改 bug偶爾涉及一點(diǎn)前端工程化配置比如改 webpack 的 loader、調(diào)一下 babel 插件但你說讓我從零搭一套完整工程我真不行?;斓牡胤胶苊黠@原理層面一知半解。我用過 Vuex但說不清它的響應(yīng)式在插件層面是怎么注入的我用過 webpack但只能說出 entry、output、loader、plugin 這些名詞我也寫過性能優(yōu)化無非就是懶加載、壓縮圖片、加緩存再深一點(diǎn)就露怯。不混的地方是業(yè)務(wù)理解力和排查問題的能力還湊合。因?yàn)槌D旮a(chǎn)品、后端、測(cè)試battle我養(yǎng)成了一個(gè)習(xí)慣遇到問題先自己復(fù)現(xiàn)、再二分定位、最后看源碼或者文檔確認(rèn)這個(gè)能力在面試?yán)镆馔獬闪思臃猪?xiàng)。1.2 簡(jiǎn)歷與面試機(jī)會(huì)混子的簡(jiǎn)歷怎么包裝很多混子同學(xué)最頭疼的就是簡(jiǎn)歷沒東西寫。我也是。項(xiàng)目經(jīng)驗(yàn)就那么幾個(gè)后臺(tái)管理系統(tǒng)總不能寫“我寫了一個(gè)商城后臺(tái)”吧。我當(dāng)時(shí)的策略是不寫功能寫問題和方案。比如有一個(gè)項(xiàng)目表格渲染一萬條數(shù)據(jù)卡到爆我優(yōu)化成了虛擬滾動(dòng)那這個(gè)項(xiàng)目就是“基于虛擬滾動(dòng)的海量數(shù)據(jù)展示方案設(shè)計(jì)”還有一個(gè)項(xiàng)目客戶要求上傳大文件我用 web worker 在瀏覽器端做了文件分片和哈希計(jì)算那這個(gè)項(xiàng)目就是“基于 Web Worker 的大文件分片上傳實(shí)踐”。面試官看到這樣的表述第一反應(yīng)不是“這人在寫業(yè)務(wù)”而是“這人解決過具體問題”約面的概率會(huì)大很多。簡(jiǎn)歷上不要撒謊但可以把做過的事用一種更有技術(shù)含量的方式表述出來。我后來復(fù)盤發(fā)現(xiàn)正是這兩個(gè)項(xiàng)目點(diǎn)成了二面面試官深挖的主線。1.3 面試前的突擊計(jì)劃一周時(shí)間我是怎么安排的從投出簡(jiǎn)歷到收到一面通知中間大概有一周多。我沒法辭職全職復(fù)習(xí)只能每天晚上抽兩三個(gè)小時(shí)突擊。我的復(fù)習(xí)順序是先看高頻前端面試題和前端八股文再對(duì)著自己簡(jiǎn)歷上的項(xiàng)目寫故事。八股文主要過了一遍 JavaScript 基礎(chǔ)閉包、原型鏈、this、事件循環(huán)、瀏覽器原理緩存、渲染、跨域、Vue 響應(yīng)式原理和組件通信方式還有手寫代碼題防抖節(jié)流、深拷貝、Promise 相關(guān)。背誦部分其實(shí)網(wǎng)上資料很多我用的就是一個(gè)語雀文檔配合 debugger 實(shí)際跑一遍效果更好。復(fù)習(xí)到后面我發(fā)現(xiàn)一個(gè)規(guī)律面試官問八股文不是為了考你背得熟不熟而是想看你能不能把知識(shí)點(diǎn)跟實(shí)際場(chǎng)景聯(lián)系起來。所以我把每個(gè)八股文知識(shí)點(diǎn)都強(qiáng)行造了一個(gè)業(yè)務(wù)場(chǎng)景比如“節(jié)流用在滾動(dòng)加載”“閉包用在防抖和柯里化”后面面試的時(shí)候確實(shí)用上了。2. 一面基礎(chǔ)題轟炸混子差點(diǎn)當(dāng)場(chǎng)現(xiàn)原形2.1 面試節(jié)奏40分鐘從閉包問到事件循環(huán)一面約在下午兩點(diǎn)視頻面面試官看著挺年輕應(yīng)該是組里比較核心的開發(fā)。開場(chǎng)沒有太多自我介紹環(huán)節(jié)簡(jiǎn)單問了一下項(xiàng)目就直奔主題大概 40 分鐘整體節(jié)奏很快。前半段是一些常規(guī)八股文比如“說說閉包是什么有哪些應(yīng)用場(chǎng)景”“原型鏈怎么理解”“this 指向問題”“數(shù)組去重有哪些方法”。這些我背過答得還算順但后來我才發(fā)現(xiàn)面試官真正想聽的不是定義而是“你什么時(shí)候用過”。問到閉包的時(shí)候我舉了防抖和節(jié)流的例子面試官明顯來了興趣順勢(shì)讓我手寫一個(gè)防抖——這就是背題和實(shí)際動(dòng)手的區(qū)別了我那會(huì)兒手一抖差點(diǎn)把防抖和節(jié)流的觸發(fā)條件搞反。后半段上了兩道代碼輸出題都是事件循環(huán)相關(guān)。第一道大概是console.log(script start); setTimeout(() { console.log(setTimeout); }, 0); Promise.resolve() .then(() { console.log(promise1); }) .then(() { console.log(promise2); }); console.log(script end);這個(gè)我背過很多遍知道輸出順序是 script start、script end、promise1、promise2、setTimeout解釋的時(shí)候把微任務(wù)和宏任務(wù)的優(yōu)先級(jí)說了出來。但接下來他變了個(gè)花樣問“如果 setTimeout 的延時(shí)改成 1 毫秒輸出順序會(huì)不會(huì)變”我當(dāng)時(shí)就有點(diǎn)懵。后來想想他的意思是要講清楚宏任務(wù)隊(duì)列的執(zhí)行時(shí)機(jī)和定時(shí)器的最小延時(shí)這其實(shí)前端面試八股文里??嫉耶?dāng)時(shí)沒答到點(diǎn)子上只說了“不一定要看執(zhí)行順序”。2.2 讓混子翻車的三道手寫題防抖、深拷貝、Promise.all一面最刺激的環(huán)節(jié)是手寫代碼。面試官直接在共享文檔里出了三道題前兩道我磕磕絆絆寫出了個(gè)大概第三道直接卡住這里詳細(xì)說說。第一道是手寫防抖函數(shù)要求支持立即執(zhí)行選項(xiàng)。我一開始寫成了節(jié)流的樣子被面試官點(diǎn)了一下“你再想想你這段代碼是防抖嗎”我趕緊改回來。最終版本大概是function debounce(fn, wait 300, immediate false) { let timer null; return function (...args) { const callNow immediate !timer; if (timer) clearTimeout(timer); timer setTimeout(() { timer null; if (!immediate) fn.apply(this, args); }, wait); if (callNow) fn.apply(this, args); }; }寫完之后面試官追問了兩個(gè)問題為什么要用apply為什么用timer null而不是clearTimeout之后直接賦初值。這兩個(gè)都是我平時(shí)沒細(xì)想的點(diǎn)第一問還好知道要綁定 this 和傳參第二問我支支吾吾他就直接解釋了置空 timer 是為了讓下一次 immediate 判斷生效不然 callNow 永遠(yuǎn)都是 false。這個(gè)細(xì)節(jié)后來我記下來了確實(shí)是防抖實(shí)現(xiàn)里容易漏的點(diǎn)。第二道是深拷貝要求考慮循環(huán)引用、Symbol 和 Date。我平時(shí)背過很多版深拷貝但現(xiàn)場(chǎng)寫的時(shí)候還是只能寫出JSON.parse(JSON.stringify(obj))然后在面試官的引導(dǎo)下補(bǔ)了遞歸。注意深拷貝的遞歸版本判斷對(duì)象類型時(shí)不要只寫typeof obj object還要排除 null并且要用 WeakMap 來保存已經(jīng)拷貝過的引用否則對(duì)象里面有循環(huán)引用會(huì)直接爆棧。后來我寫出了一個(gè)支持基礎(chǔ)循環(huán)引用的版本但對(duì) Symbol 和 Date 的處理是在提示下才寫出來的。這道題我只能算拿了三分。第三道是手寫Promise.all要求支持?jǐn)?shù)組項(xiàng)不是 Promise 的情況并且錯(cuò)誤要 reject。我現(xiàn)場(chǎng)寫了基礎(chǔ)版但忘了一個(gè)關(guān)鍵點(diǎn)結(jié)果的順序要和輸入的順序一致不能用 Promise 完成的先后順序來 push。面試官說“你的代碼能跑但結(jié)果順序是亂的”我這下才反應(yīng)過來?;乜催@段自己確實(shí)太混了平時(shí)用Promise.all用得飛起但從來沒想過它的內(nèi)部實(shí)現(xiàn)要保證順序。2.3 CSS 與瀏覽器問題真不是背個(gè)八股就行一面中間還穿插了一些 CSS 和瀏覽器的基礎(chǔ)題。CSS 問了“flex: 1 是什么含義”和“實(shí)現(xiàn)一個(gè)左側(cè)固定、右側(cè)自適應(yīng)的兩欄布局”。flex 那個(gè)我答得還行說了flex-grow: 1; flex-shrink: 1; flex-basis: 0%但面試官追問“flex-basis 默認(rèn)值是什么”我答錯(cuò)了默認(rèn)應(yīng)該是 auto。這個(gè)知識(shí)點(diǎn)不偏但屬于容易忽略的細(xì)節(jié)。兩欄布局我提供了一個(gè) float 加 margin 的方案面試官又問“還有什么方案”我說 flex他說“還有嗎”我一時(shí)沒想起來 grid。其實(shí)這些都是前端面試??臀业膯栴}在于只準(zhǔn)備了答案沒有準(zhǔn)備“多個(gè)方案橫向?qū)Ρ取彼悦康李}只能說出一種解法給面試官一種“知其然不知其所以然”的感覺。瀏覽器部分問了強(qiáng)緩存和協(xié)商緩存的區(qū)別還問了Cache-Control有哪些常見字段。這個(gè)我工作中常跟后端對(duì)接口時(shí)研究過答得比較細(xì)包括max-age、no-cache、no-store、must-revalidate以及ETag和Last-Modified的優(yōu)先級(jí)。我覺得就是這部分拉回了一點(diǎn)印象分讓面試官覺得這個(gè)人雖然手寫代碼拉胯但工程常識(shí)還是有的。一面結(jié)束后我的感受是大概率掛了。因?yàn)槭謱戭}太拉胯而且有些基礎(chǔ)細(xì)節(jié)答得很虛。結(jié)果第二天 HR 告訴我一面通過了我后來分析可能是因?yàn)轫?xiàng)目經(jīng)驗(yàn)描述比較貼合崗位需求加上網(wǎng)絡(luò)和緩存那塊答得不錯(cuò)面試官給了個(gè) borderline。3. 二面項(xiàng)目深挖與原理拷問沒有項(xiàng)目就只能挨打3.1 項(xiàng)目復(fù)盤混子項(xiàng)目里唯一能拿得出手的模塊二面約在一面后第三天這次面試官明顯資歷更老問的問題完全圍繞著簡(jiǎn)歷上的項(xiàng)目。我已經(jīng)反復(fù)準(zhǔn)備了兩個(gè)主線項(xiàng)目大文件分片上傳和表格虛擬滾動(dòng)。先說大文件分片上傳。這個(gè)項(xiàng)目我做的時(shí)候主要用的是 web worker 來計(jì)算文件的md5哈希然后把大文件切成固定大小的分片逐個(gè)上傳全部上傳成功后后端合并。面試官聽完我的介紹連珠炮似的問了幾個(gè)問題為什么要在 worker 里計(jì)算哈希直接在主線程算不行嗎分片大小是怎么確定的為什么選 5MB 而不是 10MB 或 1MB如果一個(gè)分片上傳失敗怎么處理要不要重試文件的唯一標(biāo)識(shí)怎么生成如果兩個(gè)文件內(nèi)容一樣但文件名不同算一個(gè)文件還是兩個(gè)文件第一個(gè)問題我答得還行說計(jì)算大文件哈希會(huì)阻塞主線程導(dǎo)致頁(yè)面卡頓和滾動(dòng)掉幀所以放到 worker 里。第二個(gè)問題我其實(shí)沒仔細(xì)想過當(dāng)時(shí)就是拍腦袋定的 5MB面試官追問后我硬編了一個(gè)理由網(wǎng)絡(luò)波動(dòng)大太小會(huì)頻繁請(qǐng)求太大會(huì)導(dǎo)致單次失敗重試成本高。這個(gè)回答勉強(qiáng)算合理但被面試官聽出了我沒有做過實(shí)際壓測(cè)。他補(bǔ)了一句一般會(huì)根據(jù)網(wǎng)絡(luò)環(huán)境和文件大小動(dòng)態(tài)調(diào)整分片大小有些方案會(huì)在秒傳時(shí)先用 HEAD 請(qǐng)求咨詢后端已存在的分片。這句話被我記到了筆記里。第三個(gè)問題我答了失敗重試 重新上傳該分片的方案面試官追問“并發(fā)上傳分片的話怎么控制最大并發(fā)數(shù)”我說可以用 p-limit 之類的庫(kù)或者自己維護(hù)一個(gè)并發(fā)池他就沒繼續(xù)追。第四個(gè)問題我答的是用內(nèi)容哈希作為文件唯一標(biāo)識(shí)所以兩個(gè)文件內(nèi)容相同但文件名不同會(huì)被識(shí)別成同一個(gè)文件秒傳直接返回結(jié)果。這塊我比較熟因?yàn)樗麊柕恼檬俏易鲞^的核心邏輯。3.2 性能優(yōu)化從 Network 面板到 Lighthouse 的實(shí)戰(zhàn)回答項(xiàng)目深挖之后面試官很自然地把話題引到了性能優(yōu)化上“你在這個(gè)表格虛擬滾動(dòng)里除了虛擬列表還做了哪些前端性能優(yōu)化”我當(dāng)時(shí)心里一緊因?yàn)楹?jiǎn)歷里寫了“首屏加載優(yōu)化”但實(shí)際做的比較淺。我回答了幾個(gè)點(diǎn)路由懶加載、組件異步加載、圖片懶加載、打包時(shí)關(guān)閉 sourcemap、公共依賴抽成 CDN。面試官表示認(rèn)可但接著問了一句讓我有點(diǎn)慌的話“那你有沒有真正研究過首屏性能指標(biāo)比如 FCP、LCP 這些你知道它們分別代表什么嗎”好在我在面試前一周刷到了一個(gè)關(guān)于 Core Web Vitals 的文章勉強(qiáng)能說出來FCP 是首次內(nèi)容繪制LCP 是最大內(nèi)容繪制LCP 通常比 FCP 更能反映用戶感知的加載速度。面試官還追問了怎么優(yōu)化 LCP我說了三個(gè)方向優(yōu)化圖片體積和格式、預(yù)加載關(guān)鍵資源、減少首屏 JavaScript 體積。他點(diǎn)點(diǎn)頭沒有再深挖。這輪的小心得是面試官并不指望你把所有性能指標(biāo)說得倒背如流但作為一個(gè)有項(xiàng)目經(jīng)驗(yàn)的前端你需要對(duì)自己項(xiàng)目里做了哪些性能優(yōu)化有清晰的量化認(rèn)知比如圖片減少了多少字節(jié)、LCP 降低了多少毫秒哪怕只是估算也比只說“我做了懶加載”強(qiáng)得多。提個(gè)醒如果簡(jiǎn)歷上寫了“性能優(yōu)化”四個(gè)字一定要準(zhǔn)備一個(gè)可以量化的case不然面試官只要追一句“優(yōu)化前多少、優(yōu)化后多少”就很容易暴露出你只是嘴上說說。3.3 Vue 原理與響應(yīng)式背了那么久終于用到了一次二面后半段基本是 Vue 原理的天下。面試官看了我的項(xiàng)目是用 Vue 2 寫的但 JD 要求里有 Vue 3于是從 Vue 2 一直問到 Vue 3。他先問 Vue 2 響應(yīng)式原理。這個(gè)我熟Object.defineProperty 對(duì)每個(gè)屬性做 getter/setter 劫持實(shí)現(xiàn)依賴收集和派發(fā)更新。他接著問“數(shù)組的響應(yīng)式是怎么處理的”我說 Vue 2 重寫了數(shù)組的七個(gè)方法push、pop、shift、unshift、splice、sort、reverse然后他問“為什么直接通過下標(biāo)修改數(shù)組不能觸發(fā)視圖更新”我回答是因?yàn)?defineProperty 只能劫持對(duì)象屬性而下標(biāo)修改沒法觸發(fā)。這個(gè)答得還算順。然后他問 Vue 3 和 Vue 2 的響應(yīng)式有什么區(qū)別。我答了 Proxy 和 defineProperty 的區(qū)別Proxy 可以攔截對(duì)象的增刪和屬性修改不需要像 Vue 2 那樣遍歷對(duì)象屬性還可以攔截?cái)?shù)組索引賦值所以不需要 hack 數(shù)組方法。面試官追問“Proxy 的兼容性怎么看”我說 es6 之后現(xiàn)代瀏覽器基本都支持但老瀏覽器需要 polyfill 或者降級(jí) —— 正好這也是項(xiàng)目選型時(shí)需要考慮的點(diǎn)。最后他問了一個(gè)我完全沒想到的問題“Vue 的 nextTick 原理是什么如果讓你實(shí)現(xiàn)一個(gè)簡(jiǎn)易版你會(huì)怎么做”我在項(xiàng)目中用過 nextTick也知道它跟 DOM 更新后的回調(diào)有關(guān)但真正要我說原理就垮了。我只能說跟微任務(wù)有關(guān)然后就卡住了。面試官?zèng)]太難為我告訴我核心是利用 Promise.then 或者 MutationObserver 把回調(diào)放進(jìn)微任務(wù)隊(duì)列等 DOM 更新后執(zhí)行。這道題我后來認(rèn)真補(bǔ)了絕對(duì)是 Vue 源碼里最值得深入的一塊因?yàn)樗鼱砍兜绞录h(huán)、異步更新、組件渲染機(jī)制。4. 三面leader 面的終極問題不是技術(shù)是「思考」4.1 業(yè)務(wù)與技術(shù)的關(guān)系混子如何急中生智二面過后的第三面面試官已經(jīng)明顯是技術(shù) leader 級(jí)別開場(chǎng)完全不問代碼先問我“你在這個(gè)項(xiàng)目里有沒有過跟產(chǎn)品經(jīng)理或者后端發(fā)生分歧的時(shí)候你最后怎么處理的”這種問題對(duì)于混子來說是最容易翻車的因?yàn)槠綍r(shí)我就是那個(gè)“行行行你說啥我做啥”的人。但這次我急中生智講了一個(gè)真實(shí)但稍微潤(rùn)色過的故事之前有一次產(chǎn)品提了一個(gè)需求要求前端做大量數(shù)據(jù)的即時(shí)篩選和排序我預(yù)估了一下如果按需求直接實(shí)現(xiàn)頁(yè)面會(huì)有明顯卡頓于是我沒有直接拒絕而是先做了一版 demo用一萬條數(shù)據(jù)實(shí)測(cè)截了性能面板的圖給產(chǎn)品看然后提出了虛擬滾動(dòng) 服務(wù)端篩選的替代方案最終產(chǎn)品接受了。面試官接著問了一句特別有價(jià)值的話“你覺得自己在這個(gè)過程中除了開發(fā)還承擔(dān)了什么角色”我說其實(shí)前端不只是把設(shè)計(jì)稿變成頁(yè)面還需要充當(dāng)技術(shù)方案和業(yè)務(wù)訴求之間的翻譯官。這句話后來想想有點(diǎn)裝但在當(dāng)時(shí)居然贏得了面試官的點(diǎn)頭。4.2 成長(zhǎng)性問題你怎么學(xué)習(xí)、怎么復(fù)盤leader 面后半段偏“軟素質(zhì)”了。問題包括平時(shí)怎么學(xué)習(xí)前端的未來三年的規(guī)劃是什么最近有沒有關(guān)注什么前端新技術(shù)學(xué)習(xí)路線我是這么說的日常以項(xiàng)目為主遇到問題先查文檔、再查 issue、最后翻源碼業(yè)余會(huì)看一些前端社區(qū)的高質(zhì)量文章重點(diǎn)關(guān)注工程化和性能優(yōu)化方向偶爾會(huì)動(dòng)手寫點(diǎn)小 demo 來驗(yàn)證想法。面試官追問“那你最近看過印象最深的一篇文章是什么”我愣了一下臨時(shí)想到前端工程化里的微前端方案說最近在研究微前端的沙箱機(jī)制。其實(shí)那篇文章我只看了半篇但為了圓場(chǎng)我硬是把 main 應(yīng)用和子應(yīng)用之間的樣式隔離、js 沙箱概念講了個(gè)大概。這輪的心得是不要給自己挖坑。面試官問你看過什么一定要挑一個(gè)你真的熟悉的技術(shù)不然他順著你的回答連續(xù)追問下去你就會(huì)像我一樣啞火。后來面試官真的追問了“沙箱是怎么實(shí)現(xiàn) js 隔離的”我答得很虛只能說出 with Proxy 的 eval 方式因?yàn)樗崃宋揖晚樚倜险f了兩句屬于運(yùn)氣比較好。4.3 反問環(huán)節(jié)別問沒營(yíng)養(yǎng)的問題三面最后留了幾分鐘反問面試官很客氣地說“你有什么想問我的”。我之前看過不少面經(jīng)知道反問環(huán)節(jié)不能回答“沒有”但也不能問太淺的問題。我問了兩個(gè)問題一個(gè)是“團(tuán)隊(duì)目前的前端技術(shù)棧和工程化建設(shè)到什么程度”另一個(gè)是“如果我有幸加入您覺得我當(dāng)前最需要補(bǔ)足的能力是什么”。這兩個(gè)問題的好處是第一表現(xiàn)出你對(duì)團(tuán)隊(duì)感興趣第二能通過面試官的回答反推自己哪些方面弱即便沒拿到 offer也是很有價(jià)值的反饋。面試官回答第二個(gè)問題時(shí)說了一句我印象很深的話“你基礎(chǔ)不算差但學(xué)習(xí)方式偏零散如果你能把一個(gè)知識(shí)點(diǎn)吃透到能主動(dòng)教會(huì)別人的程度會(huì)好很多?!边@句話后來被我當(dāng)成很長(zhǎng)一段時(shí)間的座右銘也徹底改變了我刷前端面試題的方式。5. HR 面聊薪資與 offer 的博弈5.1 HR 面的套路不是聊天是談判HR 面放在三輪技術(shù)面之后大概 30 分鐘。很多人以為 HR 面就是聊聊天其實(shí)不是HR 面是有明確目的的她要知道你的期望薪資、最快到崗時(shí)間、手里的其他 offer、離職原因、穩(wěn)定性、學(xué)歷背景等每一項(xiàng)都可能影響定級(jí)和薪資。HR 第一個(gè)問題就是“為什么從上家公司離職”。我提前準(zhǔn)備過沒抱怨加班多、沒說領(lǐng)導(dǎo)不好而是說“做了兩年業(yè)務(wù)型前端覺得技術(shù)成長(zhǎng)變慢了想換一個(gè)技術(shù)氛圍更濃的平臺(tái)”。這個(gè)答案既真實(shí)又不招黑。她接著問“目前手里有其他 offer 嗎”。我當(dāng)時(shí)其實(shí)手里只有一個(gè)中小廠的 offer薪資還沒談但我沒有撒謊也沒有把話說死就說“有一個(gè)在流程中的機(jī)會(huì)但更傾向于這邊因?yàn)楦胱黾夹g(shù)深耕”。后來我復(fù)盤覺得這個(gè)回答還行既表明了競(jìng)爭(zhēng)力也給對(duì)方留了空間。5.2 談薪話術(shù)混子的不算技巧的技巧薪資環(huán)節(jié)是 HR 面最核心的部分。我因?yàn)樯弦患倚劫Y不高所以在定期望值之前做了一點(diǎn)功課查了市場(chǎng)行情、問了一圈朋友最后報(bào)了一個(gè)比當(dāng)前薪資高大概 25% 的數(shù)字留了 5% 的還價(jià)空間。HR 問“你期望薪資為什么是這個(gè)數(shù)”我說了三層邏輯第一基于當(dāng)前市場(chǎng)行情和崗位要求這個(gè)區(qū)間在合理范圍第二對(duì)比我現(xiàn)在的能力和項(xiàng)目經(jīng)驗(yàn)?zāi)塥?dú)立負(fù)責(zé)復(fù)雜模塊第三如果定級(jí)和期望有差距也可以考慮其他綜合福利和成長(zhǎng)空間。整個(gè)過程沒有硬剛但也沒有一上來就自降身價(jià)。這里有個(gè)細(xì)節(jié)HR 問“能不能接受定級(jí)低一些”我說“如果定級(jí)對(duì)應(yīng)的工作內(nèi)容是我感興趣的可以談但薪資上希望盡量靠到某個(gè)區(qū)間”。這種“定級(jí)可以讓步薪資不能太離譜”的回答方式既顯得務(wù)實(shí)也給 HR 留下了協(xié)商空間。最后 offer 給的薪資雖然比期望少了 2K但綜合下來比我上家漲了不少我接受了。6. 面后復(fù)盤混子進(jìn)場(chǎng)帶著什么離場(chǎng)6.1 面試中暴露的問題清單雖然最后拿到了口頭 offer但我清楚這輪面經(jīng)里我的表現(xiàn)不是“穩(wěn)”而是“懸”?;乜凑麄€(gè)流程我暴露的問題非常典型也很有參考價(jià)值。手寫代碼基本功不扎實(shí)防抖、深拷貝、Promise.all 都屬于高頻題但我寫得不快且不規(guī)范尤其 Promise.all 的實(shí)現(xiàn)順序問題暴露了我對(duì) Promise 內(nèi)部機(jī)制的淺層理解。知識(shí)點(diǎn)碎片化不成體系flex-basis 默認(rèn)值、nextTick 原理、宏任務(wù)微任務(wù)調(diào)度這些點(diǎn)單獨(dú)問都能聊幾句但一旦被追問“為什么”就卡殼。項(xiàng)目中的技術(shù)決策缺乏數(shù)據(jù)支撐分片大小為什么選 5MB、優(yōu)化效果具體是多少我說不出來這是面試官最敏感的部分。學(xué)習(xí)方式偏被動(dòng)leader 面問我看過什么文章我只記得大概是某個(gè)方向但沒有真正消化成自己的知識(shí)結(jié)構(gòu)。Vue 3 知識(shí)儲(chǔ)備不足JD 里明確寫了 Vue 3我只知道 Proxy 比 defineProperty 強(qiáng)但組合式 API 的底層設(shè)計(jì)邏輯、編譯優(yōu)化等內(nèi)容基本空白。這些問題不是面試失敗者的專屬反而是很多“能干活但說不出來”的前端共通的短板。我把它列出來是想讓大家明白混子不可怕可怕的是不知道自己混在哪。只要能定位到具體的能力缺口接下來補(bǔ)就是了。6.2 給下一批「混子」的4條實(shí)在建議結(jié)合我這次經(jīng)歷給同樣準(zhǔn)備大廠前端面試的同學(xué)幾條建議第一把簡(jiǎn)歷上的每一條項(xiàng)目經(jīng)歷都準(zhǔn)備成一個(gè) 5 分鐘的故事。故事要包含背景、難點(diǎn)、你的方案、踩過的坑、最終效果。這樣面試官問什么你都能往這個(gè)故事上引不會(huì)出現(xiàn)“你做過什么”和“你會(huì)什么”兩張皮的情況。第二手寫題必須脫離背誦真正動(dòng)筆跑一遍。我現(xiàn)在都記得 Promise.all 那道題給我?guī)淼那琛=ㄗh把防抖、節(jié)流、深拷貝、Promise.all、Promise.race、數(shù)組扁平化、柯里化、new、call/apply/bind、instanceof、EventEmitter 這類高頻手寫題全部在本地跑過三遍以上直到閉上眼睛能寫出來。第三建立一個(gè)“為什么”清單。每刷一道八股文就追問自己三次“為什么”。比如事件循環(huán)不僅要背宏任務(wù)微任務(wù)的順序還要知道為什么要區(qū)分宏任務(wù)和微任務(wù)比如 Vue 響應(yīng)式不僅要背 Proxy還要知道 Vue 2 為什么不用 Proxy。面試官最愛追問的點(diǎn)往往都在三次“為什么”之后。第四視頻面試一定要錄音。我面完之后回聽錄音才發(fā)現(xiàn)自己有大量的“嗯”“那個(gè)”“就是”這類停頓詞而且很多題明明答到了關(guān)鍵點(diǎn)但因?yàn)楸磉_(dá)不清晰聽起來像沒答到。錄音復(fù)盤是成本最低、提升最明顯的練習(xí)方式。6.3 復(fù)盤表格哪些題該拿分卻沒拿住我把整場(chǎng)面試的題目和自己的表現(xiàn)整理成了表格方便大家直觀感受大廠面試的考察密度面試輪次核心題目我的表現(xiàn)丟分點(diǎn)得分點(diǎn)一面閉包與防抖手寫中偏下防抖節(jié)流條件寫反this 綁定不清能給出防抖的應(yīng)用場(chǎng)景一面深拷貝手寫偏下循環(huán)引用和特殊類型處理不當(dāng)知道 JSON 方案的局限一面Promise.all 手寫偏下結(jié)果順序錯(cuò)誤邊界處理不全能寫出基本框架一面瀏覽器緩存良好無明顯丟分Cache-Control 字段和協(xié)商緩存優(yōu)先級(jí)二面大文件分片上傳中上分片大小的技術(shù)依據(jù)不足對(duì)哈希、秒傳、并發(fā)控制有實(shí)踐二面性能優(yōu)化指標(biāo)中缺少量化數(shù)據(jù)知道 LCP/FCP 的基本概念二面Vue 響應(yīng)式原理中上nextTick 原理不清晰Vue2/Vue3 對(duì)比答得較完整三面業(yè)務(wù)分歧處理良好無明顯丟分有實(shí)際案例表達(dá)清晰三面學(xué)習(xí)方式與技術(shù)趨勢(shì)中技術(shù)文章印象不深微前端細(xì)節(jié)經(jīng)不起追問能表達(dá)學(xué)習(xí)方向HR面期望薪資與穩(wěn)定性良好無明顯丟分談薪有策略表達(dá)務(wù)實(shí)表格里能看出來我的優(yōu)勢(shì)在“有真實(shí)項(xiàng)目經(jīng)歷支撐的實(shí)戰(zhàn)問題”劣勢(shì)在“純基礎(chǔ)概念的深度和手寫能力”。如果你也打算面大廠可以先自己模擬打一次分看自己到底屬于哪類選手然后針對(duì)短板集中突破?;乜凑麄€(gè)面試過程我最大的感受是混子不混、只是平時(shí)沒把知識(shí)形成體系。真正讓我通過這輪面試的不是面試前那兩周背了多少題而是過去兩年在項(xiàng)目里踩坑時(shí)留下的肌肉記憶以及對(duì)項(xiàng)目細(xì)節(jié)的認(rèn)真復(fù)盤。如果你也是一枚混子別慌把我踩過的坑避開把我僥幸過關(guān)的地方變成你的穩(wěn)定項(xiàng)大廠的門沒有想象中那么窄。最后再分享一個(gè)小技巧面試被問到不會(huì)的題別直接說“不會(huì)”試著說出你的思考路徑比如“我對(duì)這個(gè)問題不了解但我從另外一個(gè)角度推測(cè)可能是……”。面試官要的不是滿分答案而是看你遇到未知問題時(shí)的反應(yīng)。這個(gè)能力恰恰是混子最容易被低估的地方。