
2023年小滿春招第三批筆試這四個字放在一起信息量其實不小。“2023”意味著春招徹底恢復了線下節奏崗位競爭烈度比前兩年明顯回暖“第三批”則更直白——前兩批已經篩過一輪人到第三批筆試時剩余的候選池基本面已經清楚了題目難度和考察深度往往會刻意再上一個臺階。HR流程越走越深筆試題的使命就從“過濾”變成了“分級”。這篇文章就拿這場筆試當引子把前端校招筆試里的考察邏輯、核心考點、答題節奏和容易翻車的細節從頭到尾拆一遍。內容同樣適用于準備暑期實習、秋招提前批或者想跳槽但基本功不牢的前端同學。我盡量只講實操層面的東西哪些題必考、怎么寫才不會被扣分、時間怎么分配、哪些坑是每年都有人踩的。1. 春招第三批筆試的定位與考察邏輯1.1 “第三批”背后的招聘節奏與心理博弈春招一般從3月持續到5月很多公司會把崗位按批次拆開第一批先撈簡歷最亮眼的一撥人第二批補充一些項目經歷扎實的到了第三批名額通常已經所剩不多但簡歷池里依然躺著大量備選。這種情況下筆試承擔的不再是單純的信息量測試更像一個公平的“雷達”——在面試官還沒見到你本人之前用一張卷子判斷你的基本功、思維習慣和工程意識。從候選人角度看第三批筆試有一種“末班車”心理前面有人已經拿了offer自己還在流程里難免焦慮。但我見過太多反例——有人第一批就筆試結果準備不足草草交卷有人第三批才進場反而因為前面積累了大量面經復習方向更精準最后拿下offer。批次靠后不等于機會更小筆試成績是硬指標誰分高誰進和批次沒有直接關系。需要留意的是第三批筆試因為崗位空余少通過線往往會比前兩批略高。這不一定體現在題目更難而是打分更嚴格同樣的代碼第一批可能看思路就給分第三批就會追問實現細節、邊界處理和代碼風格。說白了錄取名額少的時候容錯率就低。1.2 筆試的真正目的不是考倒你而是分級前端校招筆試覆蓋面很廣但單題難度其實并不會到競賽級別。我拆過不少校招真題第一感受是出題人并不是想讓你考零分而是想通過題目組合把候選人快速分成三檔——只會用、懂原理、能落地。“只會用”的候選人能把Vue/React的API背得滾瓜爛熟但要他手寫一個深拷貝寫到循環引用就卡住“懂原理”的候選人能在選擇題里準確判斷事件循環輸出順序卻寫不出一個健壯的并發控制函數“能落地”的候選人不一定每道題都完美但他對輸入輸出、邊界條件、異常情況都有意識代碼風格干凈注釋到位。筆試成績還會直接決定面試走向。一面面試官拿到的筆試卷面是他追問的技術地圖你錯在哪他就問哪你寫得粗糙的地方他會讓你現場重構。所以筆試不是考完就結束的關卡它的人影響會延續到整個面試周期。很多候選人以為筆試只是敲門磚其實它是后續面試的劇本。2. 核心考點全景解析從語言基礎到工程化能力2.1 JavaScript基礎筆試的絕對主體前端筆試里JavaScript從來不是“一個板塊”而是占據半張卷子的核心主線。選擇題、手寫題、開放題幾乎處處都能看到JS的身影。從歷年真題看常考的知識點集中在五個方向作用域與閉包、this指向、異步與事件循環、數組方法、原型與繼承。作用域與閉包的經典考法是一道for循環配合setTimeout的輸出順序。很多人第一次做都會錯for (var i 0; i 5; i) { setTimeout(() console.log(i), 100); } // 輸出5 5 5 5 5換成let之后輸出變成0 1 2 3 4原理在于var聲明提升到函數作用域、循環結束i已經變成5而let每次迭代都會創建一個新的詞法環境綁定。這個考點每隔幾年換層皮出現但它想考察的本質一直沒變你是否理解變量作用域與閉包捕獲時機。this指向是另一個送命題集中地。普通函數調用、對象方法調用、構造函數、箭頭函數四種場景下this的指向各不相同。筆試里最常見的組合是先用call/apply/bind改變this再疊加一層箭頭函數最后問輸出。能答對的人說明對this綁定規則不是死記硬背而是真正理解了調用點決定this的原則。事件循環與Promise幾乎是必考的。別再只記“宏任務微任務誰先執行”的結論要能一步步推導setTimeout(() console.log(timeout)); Promise.resolve().then(() console.log(promise)); console.log(sync); // 輸出sync - promise - timeout這里的關鍵在于JS執行同步代碼后先檢查微任務隊列再取出宏任務。微任務包括Promise回調、MutationObserver、queueMicrotask宏任務包括setTimeout、setInterval、I/O事件。兩個隊列各排各的微任務清空一次后才執行一個宏任務然后繼續循環。很多人把“微任務先于宏任務”背成了結論遇到嵌套Promise和多個setTimeout就推錯。2.2 HTML/CSS看似簡單失分最多前端筆試里最容易被輕視的就是HTML和CSS。原因是前端同學容易覺得“這倆我天天寫還會考倒我”但實際上CSS的失分率往往比JavaScript還高。盒模型是萬年常客標準盒模型的width指content寬度IE怪異盒模型的width包含contentpaddingborder。box-sizing: border-box的意義就在于我們日常布局時希望width就是你視覺上的總寬而不是一層層累加。筆試里常延伸出“給一個div設置width:200px; padding:20px; border:5px; content實際多寬”這樣的計算題看似簡單但真的有人算錯。BFC塊級格式化上下文是另一個高頻考點。題目通常這樣出父元素里有子元素設置了margin-top結果父子一起往下掉——這就是margin塌陷。解法是給父元素構建BFC比如加overflow: hidden或display: flow-root。BFC還能解決浮動高度塌陷、阻止元素被浮動元素覆蓋。我建議把BFC理解為一塊獨立的“布局小世界”它內部的元素跟外部互不干擾很多布局問題的解法本質都是建立隔離。flex和grid布局每年必有一道。考法要么是“寫出讓子元素垂直水平居中的代碼”要么是“實現一個兩欄布局左邊固定200px右邊自適應”。flex居中三行代碼就能寫完但要注意flex主軸和交叉軸的方向——justify-content作用在主軸align-items作用在交叉軸主軸方向會隨flex-direction變化很多人一改方向就搞混。CSS選擇器優先級也是一道常客!important 內聯style id class/屬性/偽類 元素/偽元素同級別看數量。筆試里常見組合題比如div#app .item:hover是什么優先級。規則不難但要寫對就得靜下心逐段數。2.3 框架與工程化從“會寫頁面”到“會寫應用”到了框架與工程化板塊筆試考察的就不再是單個API好不好用而是你有沒有“應用思維”——也就是把組件化、通信、構建這些都串起來的能力。Vue和React二選一或都考不同公司的側重點不一樣。但有一個規律只要考生命周期就一定不是單純背名字。常見問法是“在哪個生命周期發請求”“父子組件的生命周期執行順序”“Vue3的setup替代了哪些鉤子”。這類題目背后的潛臺詞是你寫頁面時是否清楚什么時候該做什么事。比如在created里拿數據和在mounted里拿數據的區別很多人說不清其實區別在于created階段組件實例已創建但DOM還未掛載數據請求與DOM無關時可以提前但依賴DOM尺寸的初始化就必須等到mounted。組件通信也是高頻props和事件、provide/inject、事件總線、vuex/pinia、Redux/Context每種方式適合什么場景筆試里常見的設計題是“封裝一個彈窗組件需要考慮哪些通信點”——打開關閉的狀態由誰控制、回調怎么傳、全局唯一還是局部實例。這道題沒有標準答案但答得好的人會提到“通過事件或狀態管理控制顯隱而不是讓彈窗自己管理”這就是組件設計的分水嶺。工程化方向的題Webpack是出題重災區loader和plugin有什么區別構建流程大概分幾步配置過哪些常見優化項很多人只會npm run build于是這類題直接懵。我給一個穩妥的回答思路loader本質是文件轉換器把非JS模塊處理成JS能識別的模塊比如babel-loader把ES6轉ES5、css-loader解析CSS里的import、style-loader把CSS注入到style標簽plugin則是在構建生命周期里掛鉤子做額外處理比如HtmlWebpackPlugin生成HTML、MiniCssExtractPlugin提取CSS文件。如果能把“編譯流程解析配置—初始化—編譯—構建—輸出”說清楚已經能贏過大部分人。2.4 算法與數據結構固定的“送分”與“拉分”區間前端筆試的算法題難度通常卡在“LeetCode中等偏下”很少出現難題怪題但考得很實用。這意味著算法主力準備期的投入產出比很高把高頻題做熟比盲目刷五百道更有效。常考的類型很集中數組去重、字符串反轉、深拷貝、防抖節流、排序、斐波那契、爬樓梯。這些題有共同特點——都能在真實業務里找到對應場景。數組去重對應數據處理防抖對應搜索框輸入爬樓梯對應動態規劃思維的入門。出題人的邏輯是我們不指望前端寫多復雜的算法但希望你具備把問題拆解成小步驟并寫清楚的能力。算法題在筆試里占的分值不一定最高但它決定了你的卷面上線。選擇題大家都靠記憶手寫題大多數人都能寫個大概真正拉開差距的是代碼的完整性和邊界感。舉個例子寫快速排序時你是否處理了空數組二分查找時left (right - left) / 2還是(left right) / 2后者在極端情況下可能整型溢出。這些細節才是閱卷人最關注的“工程素養”信號。3. 筆試實操復盤拿到卷子后的完整時間線3.1 開考前5分鐘先做戰略層決策很多候選人拿到卷子就開始悶頭做這是最大的浪費。一張校招筆試卷通常包含選擇題、填空題、手寫代碼題、開放問答題題型之間沒有回頭看的分值提示但每一類題目的用時差異很大。我的習慣是先用5分鐘通讀全卷明確題型、題量、分值然后把整場時間按比例切好。這里給一個可復用的時間分配參考假設筆試總時長為90分鐘選擇題和填空題控制在20分鐘內平均每題不超過1分半鐘手寫代碼題留50到60分鐘其中前10分鐘用來把每道題的思路在注釋里寫出來再動手最后10分鐘通查一遍代碼補邊界條件檢查有沒有低級語法錯誤。如果手寫題有三道寧可前兩道寫得完整也不要三道都只寫半截因為半截代碼很難給分完整的代碼即使思路樸素也能拿到大部分步驟分。通讀全卷還有一個額外收獲你會提前知道最后一道開放題問的是什么。答題過程中大腦其實會自動在后臺幫你檢索相關經驗等做到最后一道題的時候思路往往已經成型了。這就是“提前埋問題”的妙處。3.2 選擇題里的“語言陷阱”與排查思路選擇題不是靠背誦就能穩拿分的它考察的是精確記憶和快速排除的能力。前端筆試里有幾個“永恒的陷阱”幾乎每年換著角度出現。我先整理成一份速查供大家考前重點瀏覽題目陷阱正確認知易錯點typeof null返回object這是歷史遺留bug不是刻意設計[1,2] [3,4]返回1,23,4數組轉字符串后做字符串拼接[] ![]返回true兩邊都轉成數字后再比較5 - 3返回2減號會強制轉為數字加號則是字符串優先NaN NaN返回false判斷NaN應該用Number.isNaN0.1 0.2 0.3返回false浮點精度問題穩定比較用差值閾值遇到這類題千萬不要憑“好像見過”的記憶來選要現場推導一遍。比如[] ![]拆解步驟是![]先運算得false然后[] false兩邊都轉數字[]轉0false轉0所以為true。類似的題只要你肯動筆拆解錯誤率會大幅下降。排查選擇題還有一個技巧先排除掉明顯違背常識的選項再對剩余選項逐一構造反例。比如題目問“以下哪個數組方法會改變原數組”map和filter都是返回新數組forEach返回undefined不改變原數組splice和sort會改變。如果你不確定就在草稿紙上寫幾行代碼模擬const arr [3,1,2]; arr.sort(); console.log(arr)——輸出結果一看便知。3.3 手寫代碼題先寫思路注釋再寫實現手寫代碼題是整場筆試里最能展現工程素養的題型。閱卷人看的不只是最終結果還包括代碼結構、邊界處理和注釋質量。有一個特別實用的習慣動手前先在注釋里把輸入、輸出、邊界條件和算法思路寫清楚。這既是給自己理清邏輯也是在不會寫完整代碼時保住步驟分的關鍵。以高頻的防抖函數為例先寫思路注釋/** * 防抖函數 * 輸入func 需要防抖的函數, wait 等待時間(ms) * 輸出返回一個防抖后的新函數 * 邊界需保存 timer且要處理 this 指向和參數透傳 */ function debounce(func, wait) { let timer null; return function(...args) { const context this; if (timer) clearTimeout(timer); timer setTimeout(() { func.apply(context, args); }, wait); }; }這道題看似簡單但很多人會漏掉this綁定和args透傳。不加apply(context, args)的話函數內部的this在嚴格模式下會是undefined參數也會丟失。筆試里一道手寫題拿到完整分往往就是贏在這些細節。再看深拷貝的常見實現和它的問題const clone1 JSON.parse(JSON.stringify(obj));這個寫法在面試和筆試里長期被當作“簡便做法”出現但它的缺陷非常明顯遇到undefined、Symbol、函數會直接丟掉遇到循環引用會拋錯Date會變成字符串。稍微考深一點的題目就會要求實現一個能處理循環引用的深拷貝。合格版實現需要用到WeakMap記錄已拷貝對象function deepClone(obj, map new WeakMap()) { if (obj null || typeof obj ! object) return obj; if (map.has(obj)) return map.get(obj); const clone Array.isArray(obj) ? [] : {}; map.set(obj, clone); for (const key of Object.keys(obj)) { clone[key] deepClone(obj[key], map); } return clone; }這里用WeakMap而不是Map是為了避免在深拷貝大量數據時產生內存泄漏——WeakMap的鍵是弱引用外部對象不再被引用時它可以被垃圾回收。很多候選人能寫出循環引用處理但說不出為什么用WeakMap這層追問才是真正區分實力的地方。3.4 開放題的“結構化答題法”開放題不要求標準答案但閱卷人見過大量“口語化”的回答所以“結構化”恰恰是拉開差距的地方。比如“如何優化首屏加載速度”如果把腦海里想到的點子零零散散全倒出來就顯得沒條理。我的建議是分維度回答資源體積、請求數量、渲染路徑、緩存策略。資源體積路由懶加載、代碼分割、Tree Shaking、壓縮混淆、開啟gzip請求數量合并請求、雪碧圖/iconfont、小圖轉base64、合理使用CDN渲染路徑減少阻塞渲染的腳本、async/defer加載JS、CSS內聯關鍵路徑樣式緩存策略強緩存與協商緩存結合、配合hash指紋管理靜態資源版本這樣回答哪怕每一部分都只提到兩三個點整體結構也完整。更好的是你可以在末尾補充一句“具體方案需要結合項目的實際瓶頸比如通過Performance面板分析是網絡耗時還是渲染耗時”這會讓閱卷人覺得你有分析意識而不是單純背條目。4. 筆試后的技術復盤把試卷變成能力地圖4.1 從錯題反推知識盲區筆試卷子交上去最有價值的不是你估分多少而是它幫你暴露了哪些不會的知識點。我強烈建議每一位候選人做完筆試后趁記憶還熱把題目按“完全不會、半會不會、粗心做錯”三檔整理出來。完全不會的屬于系統性盲區需要投入整塊時間補半會不會說明原理沒吃透需要深挖一到兩層粗心做錯的則要針對性提醒自己在審題和邊界檢查上加強。我見過一個候選人筆試算法題用let在for循環里聲明變量但沒意識到var提升是另一回事于是選擇題里同類題也錯了。他整理錯題時發現自己所有和變量作用域相關的錯題本質都是同一個盲區。一次筆試能暴露這樣高價值的信息比多刷十道題還值得。4.2 筆試與面試的聯動卷面是面試官的追問地圖很多人不知道筆試結束后到面試之間的這段時間是你“定向復習”的黃金窗口。因為面試官大概率會從你的筆試作答里挑幾個點展開追問。你手寫防抖只寫了主邏輯但沒處理this指向——面試官就會問你“這里this指向誰有沒有問題”你選擇題選了typeof null是對象他可能接著問“為什么會出現這種情況”。所以筆試結束后除了整理錯題還要對每道答得不夠完整的題目準備一個延伸解釋。比如你只會寫JSON.parse(JSON.stringify(obj))那就去弄清楚它為什么不能拷貝函數和循環引用你只會用flex居中那就去理解flex: 1到底是什么意思它展開為flex-grow: 1; flex-shrink: 1; flex-basis: 0%每一個值的含義是什么。這種“舊題新問”的準備方式能讓你在面試里顯得特別扎實。4.3 建立自己的前端知識清單刷題、筆試、復盤、面試這一整條鏈路下來最終沉淀下來的東西應該是一份屬于自己的知識清單。這份清單不需要很長但每個知識點都應該能回答三個問題是什么、為什么需要它、它解決了什么痛點。舉例來說“閉包”這個詞背熟了不代表你會用。你需要能說閉包是在一個函數內部創建另一個函數內層函數可以訪問外層函數作用域中的變量即使外層函數已經執行完畢。它能實現數據私有化比如模塊模式里暴露公共API但隱藏內部變量它也會帶來內存占用問題因為閉包引用的變量不會被回收。能講到這個層次筆試里的閉包題基本不會再丟分。5. 高頻失分點與避坑指南5.1 只看API層面答不出原理追問前端筆試里“背API”是最容易暴露的短板。比如問“Vue3的響應式原理”背下來的答案是ProxyReflect但一到追問就崩。要答好這道題至少要知道三個層次Vue2用Object.defineProperty逐個劫持屬性所以新增屬性需要用Vue.setVue3用Proxy代理整個對象可以監聽新增和刪除Reflect用來保證this指針正確性還能讓后續默認操作與代理邏輯共存。背到第一層只能過選擇題答到第三層才是真正的理解。5.2 忽略了進制的“輸入輸出”邊界手寫代碼題得分不滿很多時候不是算法不會而是輸入輸出邊界處理不完整。比如寫數組去重有人用Set一行搞定但題目要求“不能使用Set”就丟分了寫字符串相關題沒處理空字符串寫深拷貝沒處理循環引用。這背后的核心問題是對邊界條件不敏感這種能力在真實開發中直接影響代碼質量所以閱卷人尤其看重。我的建議是寫完主邏輯后強制自己在代碼末尾補一段邊界注釋標注“空值處理”“重復值處理”“大數據量性能”這些要點。哪怕不寫代碼寫了注釋也會讓閱卷人覺得你有這個意識。5.3 時間分配失衡一道算法題卡死全局筆試里最容易讓人崩潰的是某道算法題卡了30分鐘解不出來回頭看時間不夠了后面的簡單題也沒寫。這是最虧的失分方式。正確做法是單道題最多卡15分鐘如果完全沒有思路先跳到下一題把能拿的分全部拿到最后再回來啃硬骨頭。一個實用的技巧遇到完全沒思路的題先在注釋里寫下你的第一反應和大概方向比如“這題看起來可以用雙指針但細節還沒理清”。在閱卷時這屬于有效試錯至少能讓你拿到思路分。比空白的答題區域好太多。5.4 筆試題經常出現的“隱藏約束”筆試題目里有一些容易被忽視的約束條件往往是得分關鍵。例如要求“不要修改原數組”你用了splice直接掛掉要求“盡量降低時間復雜度”你寫了個雙重for循環的O(n2)解法思路對但會被扣分要求“用ES5實現”你寫了箭頭函數和const直接違規。每次拿到題先用筆把題目中所有約束詞圈出來能不能用內置方法、輸入范圍、返回值要求、時間復雜度要求。這些都是踩分點也是失分重災區。最后說幾句實在話我在實際看簡歷和面試的過程中發現一個規律筆試分數高的候選人未必是項目經歷最漂亮的但一定是對基礎知識有“確定感”的人。他不慌因為面對任何一道題他都知道考察點是什么知道自己為什么這么寫。這種確定感不是天賦而是大量刷題、復盤、補盲區之后磨出來的。第三批筆試聽著像是搭末班車但它也意味著前面很多人已經放棄了或者拿到了更好的機會。而你還在牌桌上這本身就是好事。把基礎過一遍、把節奏調好、把邊界想全這場筆試就是一次值得的實戰演練。還有一個我自己的習慣每次筆試結束后不管結果如何我都會把試卷里的錯題整理成一篇學習筆記隔兩周再重做一遍。筆試里沒有一道題是白做的你踩過的每一個坑在后面的項目里都會以另一種方式再遇到。這就是前端這個行業最實在的公平。