網(wǎng)校招筆試題型全拆解:測試開發(fā)與后端核心考點(diǎn)與實(shí)戰(zhàn)策略)
我一直覺得互聯(lián)網(wǎng)大廠的校招筆試題是最有復(fù)習(xí)價值的材料。尤其是“小紅書2020校招測試開發(fā)后端筆試題卷一”這套卷子雖然過去幾年了但考點(diǎn)覆蓋得相當(dāng)全測試開發(fā)和后端兩個方向的核心知識都踩到了拿來做模擬訓(xùn)練非常合適。如果你正在準(zhǔn)備測試開發(fā)或后端的校招這套題值得認(rèn)真刷一遍而不是只看一眼標(biāo)題就劃走。筆試不直接決定offer但它是你進(jìn)入面試環(huán)節(jié)的入場券很多人在這一關(guān)折了不是因?yàn)椴粫且驗(yàn)闆]見過這種題型組合時間沒分配好。我自己工作這些年陸續(xù)幫不少人復(fù)盤過這套卷子也拿它當(dāng)過模擬題來練手。它身上有明顯的互聯(lián)網(wǎng)公司校招風(fēng)格選擇題打底簡答考思維算法題驗(yàn)代碼能力開放題看工程素養(yǎng)。這四板斧下來一個人基礎(chǔ)扎不扎實(shí)、有沒有做過真實(shí)項(xiàng)目基本就摸清了。這篇就把整套卷子的題型結(jié)構(gòu)、每類題目的答題思路、以及我當(dāng)時幫人復(fù)盤時總結(jié)的經(jīng)驗(yàn)教訓(xùn)一次性講透。1. 整份卷子的框架與出題邏輯1.1 卷面結(jié)構(gòu)與崗位差異先說卷面。小紅書這套筆試題雖然在2020年但它的結(jié)構(gòu)基本代表了互聯(lián)網(wǎng)公司校招筆試題的主流形態(tài)選擇題單選多選 簡答題 編程題 開放設(shè)計題。我當(dāng)時拿到的信息是測試開發(fā)和后端共用一套基礎(chǔ)卷兩個方向的差異體現(xiàn)在簡答題和開放題的選做部分。基礎(chǔ)卷部分的選題重點(diǎn)集中在幾塊計算機(jī)網(wǎng)絡(luò)TCP三次握手、HTTP/HTTPS區(qū)別、HTTP狀態(tài)碼語義、TCP與UDP的適用場景操作系統(tǒng)進(jìn)程與線程區(qū)別、死鎖四條件、線程池核心參數(shù)數(shù)據(jù)庫SQL基礎(chǔ)語法、索引失效場景、事務(wù)隔離級別Java基礎(chǔ)集合類源碼、并發(fā)容器、異常處理Linux常見命令grep、awk、top、netstat 的使用場景這部分的題量通常在20到30題之間難度不大但勝在覆蓋面廣。很多人在選擇題上失分的原因不是不會而是概念記混了。比如“進(jìn)程和線程哪一個擁有獨(dú)立的地址空間”“TCP和UDP哪一個支持廣播”這種看起來簡單考場上緊張起來很容易選反。簡答題部分則分方向出題。測試開發(fā)方向偏用例設(shè)計、自動化框架原理、性能測試思路后端方向偏Spring原理、MySQL索引、緩存一致性、消息隊(duì)列選型。這部分是拉開差距的核心因?yàn)樗侵饔^題答得好不好看的不只是知識點(diǎn)記沒記住更重要的是能不能用結(jié)構(gòu)化方式把思路講清楚。編程題一般是兩到三道力扣中等難度為主。常見的有最長無重復(fù)子串、反轉(zhuǎn)鏈表、二叉樹的層序遍歷、動態(tài)規(guī)劃類的背包或爬樓梯變體。這套題里編程題占的分值比例不小而且最后的開放題往往緊跟在編程題后面需要合理分配時間。1.2 校招筆試到底在篩什么人很多同學(xué)準(zhǔn)備筆試題時有個誤區(qū)覺得校招筆試就是考“背題”把網(wǎng)上的八股文刷一遍就能過。實(shí)際上像這套卷子的設(shè)計邏輯從頭到尾都在篩三種能力計算機(jī)基礎(chǔ)是否扎實(shí)、邏輯思維是否清晰、有沒有工程落地的意識。先說基礎(chǔ)。選擇題里大量概念題比如HashMap的負(fù)載因子為什么是0.75、ConcurrentHashMap在JDK1.7和1.8之間有什么區(qū)別、TCP的TIME_WAIT為什么存在這種題就是硬功底背題能解決一部分但真正理解原理的人面對變形問法也不會慌。我在復(fù)盤時發(fā)現(xiàn)一個規(guī)律凡是能把這些概念題的“為什么”講清楚的人編程題和簡答題得分也普遍高因?yàn)榈讓舆壿嬍峭ǖ?。再說邏輯思維。簡答題里的用例設(shè)計、狀態(tài)流轉(zhuǎn)、異常分支分析考的不只是測試?yán)碚摳悄忝鎸?fù)雜系統(tǒng)時能不能拆解問題、覆蓋邊界。舉個例子讓設(shè)計“發(fā)布一條小紅書筆記”的測試用例大多數(shù)人只會寫“上傳圖片、填寫文案、點(diǎn)擊發(fā)布”這就是沒進(jìn)入狀態(tài)。面試官真正想看的是你會不會考慮圖片格式兼容性、文字長度邊界、弱網(wǎng)重試、重復(fù)點(diǎn)擊防抖、敏感詞審核、發(fā)布失敗后的狀態(tài)回滾。最后說工程意識。開放題就是干這個的。設(shè)計一個短鏈系統(tǒng)、設(shè)計一個Feed流緩存方案這種題沒有標(biāo)準(zhǔn)答案但能看出你有沒有真實(shí)項(xiàng)目的經(jīng)驗(yàn)。做過系統(tǒng)的人會本能地考慮數(shù)據(jù)量級、緩存策略、可用性保障、監(jiān)控告警沒做過的人就算背了一堆理論寫出來的方案也是空中樓閣。一句話總結(jié)這份卷子的篩選邏輯不追求你把所有源碼都背下來但要求你在提到任何一個知識點(diǎn)時能說出它對工程的價值。2. 測試開發(fā)崗核心題型拆解用例設(shè)計、自動化、性能三件套2.1 用例設(shè)計題怎么答才能拿到高分這套卷子給測試開發(fā)方向設(shè)計的簡答題幾乎繞不開用例設(shè)計。經(jīng)典的考法有兩種一種是給定一個明確功能讓你寫用例比如“請設(shè)計登錄功能的測試用例”另一種是給一個業(yè)務(wù)場景讓你自己拆解比如“現(xiàn)在小紅書要上線一個筆記編輯功能請設(shè)計完整測試方案”。我見過很多人在第一類題上栽跟頭原因不是不會而是答得太散。寫出來十幾條用例但全都停留在“輸入正確的賬號密碼能登錄成功”這種層面缺乏結(jié)構(gòu)。正確思路應(yīng)該是按測試設(shè)計的標(biāo)準(zhǔn)方法分層來答需求分析先明確登錄功能的隱含需求。超級App里登錄往往不是獨(dú)立功能還涉及設(shè)備管理、多端同步、異常鎖定。這些都要在開頭點(diǎn)出來讓面試官知道你有全局視角。正常場景主路徑用例手機(jī)號驗(yàn)證碼登錄、密碼登錄、第三方授權(quán)登錄異常場景輸入錯誤、密碼錯誤次數(shù)過多觸發(fā)鎖定、驗(yàn)證碼失效、網(wǎng)絡(luò)超時、并發(fā)登錄互踢安全與合規(guī)密碼傳輸是否加密、驗(yàn)證碼是否防刷、日志是否脫敏兼容與體驗(yàn)不同機(jī)型、不同系統(tǒng)版本、弱網(wǎng)環(huán)境、深色模式光有分層還不夠每一層里要能看出你掌握了具體測試方法。比如針對輸入框你要主動提“等價類劃分”和“邊界值分析”空字符串、超長字符串、包含emoji、全角半角混輸、SQL注入和非注入的輸入針對登錄驗(yàn)證碼要提“驗(yàn)證碼60秒內(nèi)有效、超過60秒失效、連續(xù)獲取限制”這類時間邊界用例。我給的建議是用例設(shè)計題不要只寫測試點(diǎn)要寫出測試數(shù)據(jù)。面試官想在幾分鐘內(nèi)看到的不是你列了一百條“能不能”而是你選了哪些有代表性的數(shù)據(jù)來做等價類覆蓋。每條用例后面順手寫上預(yù)期結(jié)果這樣答題結(jié)構(gòu)化也方便后續(xù)互評追問。另外我在復(fù)盤時特別注意了優(yōu)先級的概念。這套卷子的參考答案通常會問“你最關(guān)注哪幾條用例”其實(shí)就是在考察優(yōu)先級意識。回復(fù)時要說清楚P0級是直接決定功能能否上線的用例比如登錄成功、登錄失敗攔截P1級是核心流程的異常分支P2級才是體驗(yàn)類、兼容類細(xì)節(jié)。先保主流程再談錦上添花。2.2 自動化測試框架從寫腳本到設(shè)計框架另一類高頻簡答題是自動化測試。常見考法有你做過哪些自動化測試接口自動化測試框架有哪些核心組件UI自動化測試為什么不穩(wěn)定怎么解決筆試時如果只寫“用過Selenium”“寫過Pytest腳本”基本就是送分題的行為。面試官真正想聽的是你對“框架”的理解而不是“腳本”。接口自動化測試框架的核心組件至少要說出這五塊用例管理用例的編寫方式、分類和組織方式按模塊、按接口、按業(yè)務(wù)場景數(shù)據(jù)驅(qū)動測試數(shù)據(jù)與用例邏輯分離支持Excel、YAML、JSON、數(shù)據(jù)庫等數(shù)據(jù)源請求封裝對底層HTTP請求做二次封裝統(tǒng)一處理鑒權(quán)、Header拼裝、日志打印斷言校驗(yàn)狀態(tài)碼斷言、業(yè)務(wù)碼斷言、數(shù)據(jù)庫斷言、字段級斷言報告與通知HTML報告、Allure報告、失敗自動截圖、企業(yè)微信/釘釘/郵件通知如果筆試時允許寫代碼可以給一個簡單的接口自動化示例。比如用 Pytest Requests Allure 寫一個登錄接口的測試用例import requests import allure allure.title(登錄接口-正常登錄) def test_login_success(): url https://api.example.com/login payload {username: test_user, password: 123456} resp requests.post(url, jsonpayload) assert resp.status_code 200 data resp.json() assert data[code] 0 assert data[data][token] ! 這個示例雖然短但你能借它展開講為什么用Pytestfixture管理、參數(shù)化、插件生態(tài)豐富、為什么用Requests輕量、易封裝、為什么不直接斷言整個響應(yīng)體接口迭代時字段變化會導(dǎo)致用例大面積失效。UI自動化穩(wěn)定性這塊我個人的經(jīng)驗(yàn)是盡量不要只答“用顯式等待”要答出UI自動化不穩(wěn)定的根源是環(huán)境隔離和測試數(shù)據(jù)污染。比如測試賬號被風(fēng)控攔截、測試數(shù)據(jù)被其他用例修改、彈窗廣告遮擋導(dǎo)致元素定位失敗。解決辦法是在用例設(shè)計時引入獨(dú)立的測試環(huán)境、干凈的測試數(shù)據(jù)、以及用例執(zhí)行前的數(shù)據(jù)初始化邏輯。順帶提一個心得自動化測試題里你寫不寫得出框架不重要重要的是你能不能用“分層”思維來組織答案。數(shù)據(jù)層、用例層、執(zhí)行層、報告層這四層說出來給面試官的印象是你搭過真正能用的框架而不是只在教程里敲過兩行代碼。2.3 性能測試和穩(wěn)定性不只會用工具還要會看指標(biāo)這套卷子里測試方向還經(jīng)常出性能測試相關(guān)的簡答題比如“如何對一個接口做性能測試”“線上出現(xiàn)接口響應(yīng)慢你怎么排查”。這道題其實(shí)有兩個考察點(diǎn)一是你會不會設(shè)計性能測試方案二是你會不會處理線上性能問題。性能測試方案的答題框架我建議分四步確定測試目標(biāo)先問清楚接口的線上調(diào)用量級再定性能指標(biāo)。核心指標(biāo)包括QPS、響應(yīng)時間RT、TP99、錯誤率。場景設(shè)計一般壓三個場景?;鶞?zhǔn)測試單線程壓測拿到接口基線、負(fù)載測試逐步增加并發(fā)看拐點(diǎn)在哪里、壓力測試持續(xù)加壓找服務(wù)崩潰點(diǎn)。工具選型JMeter、wrk、locust、LoadRunner。筆試時如果問選型理由就說JMeter適合復(fù)雜業(yè)務(wù)場景wrk適合簡單HTTP接口的高并發(fā)壓測locust適合python技術(shù)棧且需要腳本靈活性的場景。監(jiān)控與瓶頸定位壓測過程中不只盯吞吐量還要盯服務(wù)器CPU、內(nèi)存、磁盤IO、GC頻率、數(shù)據(jù)庫慢查詢。線上接口慢的排查思路按時間線來答最清晰先確認(rèn)是不是大范圍故障看監(jiān)控大盤再縮小范圍看是單機(jī)問題還是全鏈路問題然后分層排查網(wǎng)絡(luò)層、應(yīng)用層、數(shù)據(jù)層。應(yīng)用層的常見原因有線程池耗盡、內(nèi)存泄漏導(dǎo)致頻繁GC、調(diào)用下游接口超時重試拖垮線程數(shù)據(jù)層的常見原因有慢SQL、緩存穿透、鎖競爭。每說一個原因就補(bǔ)一句對應(yīng)的排查手段比如查慢SQL用EXPLAIN看執(zhí)行計劃查GC狀況用jstat或者Arthas。這種答案才是工程化的而不是教科書式的“看日志、找bug”。3. 后端崗高頻考點(diǎn)與解題思路3.1 Java基礎(chǔ)與JVMHashMap、并發(fā)與內(nèi)存模型后端崗位的筆試題里Java基礎(chǔ)是繞不開的大頭尤其是集合和并發(fā)。這套卷子里選擇題和簡答題都愛考這幾個經(jīng)典問題HashMap的底層實(shí)現(xiàn)數(shù)組鏈表紅黑樹為什么當(dāng)鏈表長度大于8且數(shù)組長度大于64時才轉(zhuǎn)紅黑樹鏈表查詢是O(n)紅黑樹是O(log n)但紅黑樹的節(jié)點(diǎn)體積比鏈表節(jié)點(diǎn)大得多所以用8這個閾值做空間和時間的折中。這個“為什么”才是拿分關(guān)鍵。HashMap為什么線程不安全JDK1.7時擴(kuò)容可能形成環(huán)形鏈表導(dǎo)致死循環(huán)JDK1.8后改為尾插法解決死循環(huán)問題但put時仍可能丟數(shù)據(jù)。這個演進(jìn)過程要能說出來。ConcurrentHashMap的鎖機(jī)制JDK1.7采用分段鎖JDK1.8改成了CASsynchronized鎖頭節(jié)點(diǎn)鎖粒度更細(xì)并發(fā)度更高。volatile和synchronized的區(qū)別volatile保證可見性和有序性但不保證原子性synchronized保證原子性和可見性。JVM這塊的簡答題頻率也很高尤其是內(nèi)存區(qū)域劃分、垃圾回收算法、類加載過程。筆試答題時我建議畫一張簡易的內(nèi)存圖用文字說明把堆、棧、方法區(qū)、程序計數(shù)器、本地方法棧都列出來接著強(qiáng)調(diào)“所有線程共享堆和方法區(qū)”“線程私有的是虛擬機(jī)棧、本地方法棧和程序計數(shù)器”。這樣答題結(jié)構(gòu)清晰面試官一眼就知道你掌握了。GC算法這道題別只答“標(biāo)記-清除”“復(fù)制”“標(biāo)記-整理”的名字要說出每種算法的適用區(qū)域和問題。新生代對象死亡率高所以用復(fù)制算法老年代對象存活率高所以用標(biāo)記-整理或標(biāo)記-清除。再加上當(dāng)前主流收集器G1的特點(diǎn)把堆劃分成Region通過維護(hù)可預(yù)測的停頓時間模型來實(shí)現(xiàn)“在不犧牲吞吐量的前提下盡量縮短停頓”。一句話點(diǎn)出G1和CMS的核心區(qū)別這就是加分項(xiàng)。3.2 Spring核心原理IOC、AOP、Bean生命周期Spring是后端崗位筆試的??瓦x擇題和簡答題都愛考。這套卷子里我見過的高頻問法有IOC控制反轉(zhuǎn)到底反轉(zhuǎn)了什么很多人的答案是“把對象的創(chuàng)建交給Spring容器管理”這只說了現(xiàn)象。更準(zhǔn)確的答法是反轉(zhuǎn)了對象的控制權(quán)原來需要自己new對象、自己管理依賴關(guān)系現(xiàn)在變成從容器中獲取依賴關(guān)系由容器注入。重點(diǎn)是“對象之間的耦合關(guān)系轉(zhuǎn)移到容器中”。AOP的底層實(shí)現(xiàn)是什么Spring AOP基于動態(tài)代理。目標(biāo)類有接口時使用JDK動態(tài)代理基于反射生成代理類沒有接口時使用CGLIB代理通過字節(jié)碼技術(shù)生成子類。新版SpringBoot里已經(jīng)默認(rèn)使用CGLIB不區(qū)分有沒有接口。Bean的生命周期分幾個階段答的時候按順序來實(shí)例化、屬性填充、初始化前、初始化、初始化后AOP代理、使用、銷毀。補(bǔ)充幾個會觸發(fā)回調(diào)的接口和注解PostConstruct、InitializingBean、BeanPostProcessor會讓答案專業(yè)很多。筆試?yán)镞€常出現(xiàn)一個讓很多人卡殼的問題Spring如何解決循環(huán)依賴底層用的是三級緩存。一級緩存存成品Bean二級緩存存早期暴露的Bean未完成屬性填充三級緩存存ObjectFactory工廠對象?;卮饡r最好指出Spring只解決了單例模式下setter注入的循環(huán)依賴構(gòu)造器注入無法解決。這個邊界意識是面試官在意的地方。Spring的事務(wù)傳播行為也容易被考到??谠E是“七種傳播行為默認(rèn)REQUIRED”。最常問的是REQUIRED和REQUIRES_NEW的區(qū)別前者加入當(dāng)前事務(wù)沒有就新建后者無論如何都新建一個獨(dú)立事務(wù)外層事務(wù)回滾不會影響內(nèi)層事務(wù)。“事務(wù)失效”的幾種場景也要能答私有方法調(diào)用、同類內(nèi)部調(diào)用、異常被try-catch吃掉、方法不是public。3.3 MySQL索引、事務(wù)與鎖數(shù)據(jù)庫這塊筆試題基本都圍繞索引、事務(wù)、鎖三個方向展開。索引那幾道經(jīng)典題我在不同公司的筆試題里已經(jīng)見到過無數(shù)遍為什么InnoDB用B樹而不是B樹兩個角度答一是B樹只有葉子節(jié)點(diǎn)存數(shù)據(jù)非葉子節(jié)點(diǎn)能存放更多索引項(xiàng)樹更矮、IO更少而是B樹的葉子節(jié)點(diǎn)通過雙向鏈表串聯(lián)范圍查詢和排序效率遠(yuǎn)高于B樹。聚簇索引和非聚簇索引的區(qū)別聚簇索引的葉子節(jié)點(diǎn)直接存整行數(shù)據(jù)一張表只能有一個非聚簇索引的葉子節(jié)點(diǎn)存主鍵值所以回表查詢需要二次索引。覆蓋索引就是讓查詢的列都在索引里避免回表。聯(lián)合索引最左前綴原則比如建立了(a,b,c)聯(lián)合索引查詢時可以用到(a)、(a,b)、(a,b,c)但跳過a直接查b或c就不走索引。能走到哪個索引取決于查詢條件的順序和順序性。答完這句再補(bǔ)一句MySQL優(yōu)化器會自己調(diào)整條件順序但最左前綴仍然要求查詢條件中有a列這句話能防止面試官覺得你只會背口訣。事務(wù)這部分的必考題是隔離級別和MVCC。四個隔離級別讀未提交、讀已提交、可重復(fù)讀、串行化。MySQL默認(rèn)是可重復(fù)讀。重點(diǎn)放在MVCC上多版本并發(fā)控制通過undo log生成版本鏈配合ReadView實(shí)現(xiàn)不同隔離級別下的快照讀。可重復(fù)讀和讀已提交的區(qū)別在于生成ReadView的時機(jī)前者在事務(wù)第一次select時生成后者在每次select都生成新的。鎖這塊要區(qū)分樂觀鎖和悲觀鎖。悲觀鎖通過數(shù)據(jù)庫的SELECT ... FOR UPDATE實(shí)現(xiàn)但要注意鎖必須加在事務(wù)里否則直接釋放。樂觀鎖通常用版本號或時間戳實(shí)現(xiàn)UPDATE t_order SET status 2, version version 1 WHERE id #{id} AND version #{version};回答時我習(xí)慣補(bǔ)一句樂觀鎖適合并發(fā)沖突少的場景悲觀鎖適合寫沖突多的場景。線上用樂觀鎖時要注意版本號字段一定要上索引否則更新時鎖范圍會擴(kuò)大這是我從生產(chǎn)環(huán)境踩過的坑。3.4 Redis緩存三兄弟與分布式鎖Redis在筆試題里的地位和MySQL不相上下。選擇題經(jīng)常考數(shù)據(jù)類型、過期策略、持久化方式簡答題必考緩存和分布式鎖。緩存穿透、擊穿、雪崩這三兄弟幾乎是每年必問穿透查詢一個不存在的key每次請求都會打到數(shù)據(jù)庫。解決思路緩存空值設(shè)置較短過期時間、布隆過濾器攔截。擊穿某個熱點(diǎn)key過期瞬間大量請求同時打到數(shù)據(jù)庫。解決思路互斥鎖重建緩存、設(shè)置邏輯過期、熱點(diǎn)key永不過期主動更新。雪崩大量key同時過期或Redis宕機(jī)導(dǎo)致數(shù)據(jù)庫被壓垮。解決思路過期時間加隨機(jī)數(shù)打散、多級緩存、Redis高可用集群。這幾個解決方案不是背下來就行要能說清楚每種方案的取舍。比如布隆過濾器有誤判率會增加系統(tǒng)復(fù)雜度互斥鎖在并發(fā)極高時會阻塞大量請求所以實(shí)際業(yè)務(wù)中經(jīng)常把“互斥鎖”和“邏輯過期”配合用。Redis持久化這道簡答題要答RDB和AOF的本質(zhì)區(qū)別。RDB是某個時間點(diǎn)的快照恢復(fù)速度快但可能丟數(shù)據(jù)AOF記錄每一條寫命令數(shù)據(jù)安全性高但文件大、恢復(fù)慢。生產(chǎn)環(huán)境常用AOFRDB混合持久化以RDB作為全量備份在兩份RDB之間用AOF記錄增量命令兼顧恢復(fù)速度和數(shù)據(jù)安全。這套方案在Redis 4.0之后已經(jīng)原生支持。分布式鎖的考法通常是“用Redis怎么實(shí)現(xiàn)分布式鎖”。最基礎(chǔ)的答案是SET key value NX EX seconds但要拿高分必須補(bǔ)充三個細(xì)節(jié)value要設(shè)置唯一標(biāo)識比如UUID釋放鎖時用Lua腳本校驗(yàn)防止誤刪別人的鎖鎖要設(shè)置過期時間但過期時間過短業(yè)務(wù)沒執(zhí)行完怎么辦答案是引入看門狗機(jī)制自動續(xù)期Redis主從切換場景下鎖可能丟失嚴(yán)格場景要用Redlock但Redlock本身也有爭議我建議答題時把Redisson提一句生產(chǎn)環(huán)境直接使用Redisson的分布式鎖它自帶看門狗和Lua腳本釋放邏輯是工程化的標(biāo)準(zhǔn)方案。4. 開放性設(shè)計題筆試?yán)镎嬲睦猪?xiàng)4.1 設(shè)計一個短鏈系統(tǒng)經(jīng)典的“看似簡單實(shí)則深淵”這套卷子的開放式題最常見的是設(shè)計類問題。我在復(fù)盤時發(fā)現(xiàn)很多算法刷得不錯的同學(xué)反而在開放題上丟分原因就是沒有形成“先把需求問清楚再給方案”的習(xí)慣。拿“設(shè)計一個短鏈系統(tǒng)”舉例它考察的點(diǎn)非常多。先別急著給方案列出需要確認(rèn)的需求點(diǎn)預(yù)計日新增短鏈數(shù)量級是多少短鏈有效期多長需不需要自定義短鏈跳轉(zhuǎn)是302還是301需不需要統(tǒng)計點(diǎn)擊數(shù)據(jù)。需求不清楚就給方案大概率會漏掉一個關(guān)鍵考慮。然后分兩步設(shè)計第一步是發(fā)號策略。兩種路線哈希取模MD5或CRC32取前幾位和發(fā)號器Redis INCR或數(shù)據(jù)庫自增ID轉(zhuǎn)62進(jìn)制。筆試時推薦答發(fā)號器方案因?yàn)楣H∧4嬖谂鲎诧L(fēng)險需要維護(hù)一個去重表復(fù)雜度高。發(fā)號器用62進(jìn)制26個小寫字母26個大寫字母10個數(shù)字壓縮10億級別的ID也只要6位字符這個計算過程要能寫出來。第二步是存儲設(shè)計。短鏈映射關(guān)系放在Redis里加速訪問DB里存全量數(shù)據(jù)。訪問短鏈時先查Redis命不中再查DB并回填緩存。跳轉(zhuǎn)狀態(tài)碼建議用302因?yàn)?01會被瀏覽器緩存后續(xù)修改目標(biāo)URL不生效。如果問到數(shù)據(jù)量級直接給出一個容量估算一個字符串類型的短鏈映射大概占200字節(jié)千萬級別數(shù)據(jù)量約2GB完全可以放Redis如果數(shù)據(jù)更多就分片存儲。這道題的高分答案往往不是方案本身多華麗而是能不能主動說出“如果熱點(diǎn)短鏈被刷怎么辦”這類細(xì)節(jié)。比如熱門短鏈加一層本地緩存、對可疑的重復(fù)請求做限流。4.2 設(shè)計筆記發(fā)布狀態(tài)機(jī)后端工程化的代表題小紅書這類內(nèi)容平臺后端開放的簡答題很愛考業(yè)務(wù)狀態(tài)流轉(zhuǎn)。比如“設(shè)計一個筆記發(fā)布審核流程你會怎么實(shí)現(xiàn)”。這種題的核心是狀態(tài)機(jī)設(shè)計?;卮饡r先把狀態(tài)畫出來用文字描述草稿、待審核、審核通過已發(fā)布、審核駁回、用戶刪除。然后把狀態(tài)轉(zhuǎn)移的條件列清楚草稿 - 待審核用戶點(diǎn)擊發(fā)布待審核 - 審核通過機(jī)器審核人工抽審?fù)ㄟ^待審核 - 審核駁回風(fēng)控策略命中或?qū)徍瞬煌ㄟ^審核通過 - 用戶刪除用戶主動刪除審核駁回 - 草稿用戶編輯后重新提交狀態(tài)轉(zhuǎn)移列完再補(bǔ)狀態(tài)機(jī)的實(shí)現(xiàn)方案。我建議用數(shù)據(jù)庫字段存儲當(dāng)前狀態(tài)代碼里用狀態(tài)模式或策略模式來管理轉(zhuǎn)移邏輯。用一張狀態(tài)轉(zhuǎn)移表來校驗(yàn)非法操作比如已刪除的筆記不允許直接再發(fā)。并發(fā)問題上一個用戶重復(fù)點(diǎn)擊發(fā)布按鈕后端要防止生成多條待審核記錄方案是對用戶筆記ID加唯一約束或者用INSERT ... ON DUPLICATE KEY UPDATE實(shí)現(xiàn)冪等。答到這里還可以再往深走一層審核駁回后用戶修改重新發(fā)布要不要重新走人工審核大概率要因?yàn)閮?nèi)容已經(jīng)變化不能用老的審核結(jié)論。如果有這種思考面試官會認(rèn)定你真實(shí)考慮過業(yè)務(wù)邏輯而不是在背模板。4.3 場景設(shè)計題如何設(shè)計小紅書信息流Feed流社交內(nèi)容平臺的校招筆試?yán)锪硪粋€高頻開放題是請設(shè)計一個關(guān)注頁信息流Feed流。這道題幾乎是專門給小紅書這類產(chǎn)品出的。從大的架構(gòu)選型來看主流的Feed流設(shè)計有三種拉模式粉絲主動拉取、推模式發(fā)布時寫入粉絲收件箱、推拉結(jié)合。筆試時建議這樣答拉模式發(fā)布者發(fā)布筆記后粉絲刷Feed時實(shí)時拉取自己關(guān)注的博主發(fā)布的筆記。優(yōu)點(diǎn)是存儲成本低、代碼邏輯簡單缺點(diǎn)是每個粉絲的Feed都需要實(shí)時聚合讀放大嚴(yán)重?zé)狳c(diǎn)用戶刷Feed時可能把服務(wù)打垮。推模式博主發(fā)布筆記后主動把筆記寫入所有粉絲的收件箱Feed列表。粉絲刷Feed時直接讀自己的收件箱讀路徑快。缺點(diǎn)是明星大V有千萬級粉絲一條筆記要寫千萬份寫放大嚴(yán)重額外需要“大V粉絲列表”來處理。推拉結(jié)合普通用戶用推模式大V用戶用拉模式粉絲刷Feed時實(shí)時去拉大V的筆記再合并。既能保證普通用戶的讀性能又能避免大V發(fā)布時的寫放大。選型說完就進(jìn)入緩存層設(shè)計。Feed流是典型的讀多寫少場景收件箱用Redis的List或ZSet存儲按時間倒序排列。ZSet的score用發(fā)布時間戳可以方便地做分頁ZREVRANGEBYSCORE按時間范圍取這是推薦答案。再往下可以加一層本地緩存對當(dāng)前在線用戶最常刷的Feed列表做內(nèi)存緩存降低Redis壓力。同時數(shù)據(jù)要落一份到DB用于用戶刪筆記時聯(lián)動清理粉絲收件箱。答開放題時記住一個原則不要執(zhí)著于給出一個唯一標(biāo)準(zhǔn)答案要展示思考過程。每提出一個方案就主動說清楚它的優(yōu)點(diǎn)和缺點(diǎn)以及你在什么約束條件下做這個取舍。面試官選的是會做技術(shù)權(quán)衡的人不是背書機(jī)器。5. 考場實(shí)戰(zhàn)時間分配與答題順序5.1 90分鐘的時間切片方案刷這套題之前先問一個問題你打算花多長時間做完一份完整卷子我個人的建議是把時間控制在90分鐘以內(nèi)并且按下面的方案切成四塊。選擇題和填空題是基礎(chǔ)題范圍廣但難度低按30分鐘來安排。每題控制在一分鐘內(nèi)卡住就跳過做完再回來?;A(chǔ)題忌諱的就是糾結(jié)一道概念題花五分鐘后面編程題就廢了。簡答題給它20分鐘。用例設(shè)計和原理題的關(guān)鍵是“結(jié)構(gòu)化”不需要寫論文但每道題要寫出清晰的編號。準(zhǔn)備一支草稿紙先在草稿上列大綱再往答題框里寫能明顯提高條理性。編程題是重頭戲留25分鐘。做題順序上先挑自己最有把握的題做保底分先拿到。讀題時先圈出輸入范圍和數(shù)據(jù)規(guī)模因?yàn)檫@兩個信息直接決定用哪種算法復(fù)雜度。剩下的15分鐘給開放設(shè)計題。這類題沒有標(biāo)準(zhǔn)答案寫一個完整的方案骨架就行不要在小細(xì)節(jié)上死磕。比如設(shè)計短鏈系統(tǒng)你先寫出發(fā)號器方案和302跳轉(zhuǎn)再寫RedisDB的存儲結(jié)構(gòu)拿分效率比苦想緩存一致性高得多。如果某些試卷的開放題分值較低可以直接壓縮到10分鐘多留時間檢查選擇題的選項(xiàng)和編程題邊界條件。記住一個原則任何一道題都不要空著。主觀題只要寫了就有步驟分尤其是測試用例題寫十條完整用例哪怕優(yōu)先級排得不太好也比空著強(qiáng)。5.2 各題型答題的細(xì)節(jié)技巧先說選擇題。“說法錯誤的是”“正確的是”這種詞圈出來。很多丟分都是因?yàn)轭}目問的是“錯誤的是”你按“正確”來選了。多選題少選能拿部分分的就寧可少選也不要亂選。拿不準(zhǔn)的選項(xiàng)回看題目里有沒有“一定”“必須”“都”這種絕對化表述通常這些是錯誤選項(xiàng)。簡答題要遵循“先總后分再補(bǔ)充”的結(jié)構(gòu)。第一段一句話給結(jié)論比如“Spring的循環(huán)依賴通過三級緩存解決但只適用于單例setter注入場景”然后分點(diǎn)展開最后補(bǔ)一個邊界情況或使用陷阱。這種結(jié)構(gòu)的好處是即使你后面細(xì)節(jié)寫錯前面的結(jié)論已經(jīng)給面試官留了正確印象。編程題寫代碼時先寫邊界判斷再寫主邏輯。比如反轉(zhuǎn)鏈表函數(shù)開頭先判斷head和head.next是否為空最長回文子串先處理空字符串和長度1的情況。寫完之后跑一遍自己構(gòu)造的用例空輸入、單元素、全相同元素、倒序輸入這四個用例過了基本不會被邊界問題卡死。開放題如果時間不夠也要把方案的框架列出來包括涉及的核心組件和關(guān)鍵流程后續(xù)的細(xì)節(jié)讓面試官找機(jī)會問。這是一種聰明的答題策略讓面試官覺得你思路完整只是時間受限。6. 復(fù)盤方法這套卷子做完之后該怎么辦6.1 錯題不能只記答案要按知識點(diǎn)歸檔刷這套卷子最有價值的環(huán)節(jié)其實(shí)是復(fù)盤。很多人刷題只看對錯對的選擇跳過錯的改個答案就完事實(shí)際上什么也沒學(xué)到。我的建議是建一個“錯題知識樹”。每道錯題不要只記正確答案要把這道題對應(yīng)的知識點(diǎn)往上追溯。比如HashMap擴(kuò)容的題錯了對應(yīng)知識點(diǎn)是哈希表和紅黑樹再往上追溯是Java集合框架的設(shè)計權(quán)衡。在錯題本里寫三個欄目題目與錯誤答案、正確解析、涉及的核心原理。順手再寫一道同類的變體題第二天遮住答案重做一遍。復(fù)盤的時間節(jié)點(diǎn)也重要。當(dāng)天復(fù)盤一遍三天后再重做一遍錯題一周后再用這套卷子做一次完整限時模擬。三輪下來知識點(diǎn)的記憶深度比刷新題強(qiáng)得多。6.2 筆試到面試的銜接準(zhǔn)備筆試不是終點(diǎn)通過筆試后一個周內(nèi)大概率會收到面試邀請面試?yán)镒類鄣木褪亲穯柟P試題的擴(kuò)展版本。比如筆試?yán)锟剂恕癕ySQL事務(wù)隔離級別”面試時可能問“可重復(fù)讀怎么解決幻讀”“RR級別存在什么坑”筆試?yán)锟剂恕熬彺嫜┍馈泵嬖嚂r可能讓你結(jié)合業(yè)務(wù)講具體的緩存更新策略。所以復(fù)盤時每道錯題后順手寫兩個可能的追問方向自己試著答一遍。我當(dāng)時帶人準(zhǔn)備時就常用這套方法筆試后不是休息而是黃金準(zhǔn)備期把卷子里涉及的每個知識點(diǎn)都往深挖一層。除此之外面試時經(jīng)常被要求介紹一個你最熟悉的系統(tǒng)或項(xiàng)目。如果復(fù)盤時能把這套卷子里的短鏈設(shè)計方案、Feed流設(shè)計方案整理成自己的項(xiàng)目經(jīng)歷面試時就能直接拿出來講??梢哉f“我之前做過一個類似的需求用了發(fā)號器和兩級緩存壓測下來QPS到XX主要瓶頸在數(shù)據(jù)庫連接數(shù)”一段完整的項(xiàng)目介紹就從一道筆試題延展出來了這是很實(shí)用的思路。6.3 長期來看校招筆試準(zhǔn)備的正確姿勢如果距離筆試還有兩三個月我的建議是不要急著刷題先把基礎(chǔ)課結(jié)構(gòu)搭建好。數(shù)據(jù)結(jié)構(gòu)與算法、計算機(jī)網(wǎng)絡(luò)、操作系統(tǒng)、數(shù)據(jù)庫、一門主力語言這五門課是筆試的根基。根基不牢刷題數(shù)量再多題目一變樣式就抓瞎。系統(tǒng)刷題的方法可以按專題來鏈表、二叉樹、動態(tài)規(guī)劃、雙指針、字符串、二分搜索每個專題刷透30題再換下一個。算法題不是比誰會解而是比誰能在短時間內(nèi)識別題型、想清楚復(fù)雜度、寫出無bug代碼。關(guān)于技術(shù)棧測試開發(fā)方向建議掌握Python或Java任選一門加上Pytest或JUnit、Requests或HttpClient、Selenium或Playwright后端方向建議JavaSpringBootMySQLRedis為主基本覆蓋90%以上公司的筆試題范圍。技術(shù)棧在精不在多把一套棧吃透了比什么都學(xué)個皮毛強(qiáng)得多。我個人在實(shí)際操作中最深的一個體會是筆試資料的價值不在于“押中題”而在于幫你建立一套應(yīng)對不確定題目的思考框架。這套卷子是很好的訓(xùn)練素材但更重要的是你自己去總結(jié)每類題的答題套路并對每個??贾R點(diǎn)養(yǎng)成“多問一句為什么”的習(xí)慣。準(zhǔn)備校招的過程本身就是一次把大學(xué)幾年學(xué)的東西系統(tǒng)性重新串起來的機(jī)會這比最終拿到哪家offer都有用。