
字節跳動2017秋招的這套開發工程師筆試卷在校招圈里流傳了很久。倒不是因為題目多么偏門恰恰相反它考察的內容非常“正”——全是計算機基礎里的核心地帶數據結構、算法、操作系統、網絡協議。但它的難度在于題目設計得很靈活不是死記硬背就能應付的每一道題都在逼你展示真正的工程思維和代碼功底。我當時刷完這套題最大的感受是它不考你“知不知道”而考你“會不會用”。很多基礎概念課本上背得滾瓜爛熟但放到字節的題目里就變成了需要現場推導、現場設計算法的實際場景。這份試卷的價值不在于“押題”或者“刷真題”而在于它代表了一類頭部互聯網公司的篩選標準。哪怕放到今天來看它的考察方向依然沒有過時扎實的編碼能力、對算法復雜度的敏感度、對系統底層原理的理解。這篇文章我想以這套試卷為藍本把它的考察邏輯、典型題型、以及我當時備戰和復盤時的思路完整拆開來講。不論你是正在準備秋招的應屆生還是打算跳槽的工程師這份拆解應該能幫你理清復習的優先級。1. 試卷的整體結構與考察邏輯1.1 一份筆試背后的篩選思路當年字節跳動的筆試考察的不僅是解題能力更是評估你作為開發者的“下限”在哪里。一套題通常由兩部分構成一部分是客觀題選擇題、填空題覆蓋計算機基礎知識另一部分是編程題需要在線手寫完整代碼并處理輸入輸出。這種結構直接決定了篩人的邏輯第一基礎知識要廣而扎實。選擇題覆蓋范圍很廣從數據結構的時間復雜度分析到操作系統的進程調度算法再到網絡層的擁塞控制機制都有可能出現。這考察的是大學四年基本功是否牢固。第二編碼能力要真刀真槍。編程題是拉開差距的核心。在線編程環境沒有IDE的代碼提示沒有編譯錯誤的高亮輔助你需要在有限時間內從理解題意到設計算法再到寫出無bug的代碼。這非常考驗平時的代碼積累。第三工程思維要落地。部分題目特別是分值較大的編程題不是單純的算法題它會在題目中嵌入一個實際業務場景比如處理海量日志、設計限流策略、優化接口響應時間。你需要在解題過程中展示出對工程問題的分析與取舍能力。1.2 試卷內容的模塊劃分根據我的復盤這套2017秋招的筆試卷大體上可以劃分為四個核心模塊計算機基礎知識模塊覆蓋數據結構棧、隊列、二叉樹、圖、堆、操作系統進程管理、內存管理、死鎖、計算機網絡TCP/IP、HTTP協議。這部分難度中等但考察范圍很細有些題特別容易答錯考驗對細節的把握。編程語言與代碼理解模塊通常會給出一段代碼C或Java居多讓你分析輸出結果、指出錯誤或者補全代碼。這部分考察實際編碼的基本功以及代碼的閱讀能力。算法設計與實現模塊這是筆試的重頭戲分值占比最高。常考的題型包括字符串處理、數組操作、動態規劃、貪心算法、二叉樹遍歷與深搜廣搜。難點在于題目不會直接告訴你“用動態規劃”而需要你從問題描述中抽象出數學模型。綜合分析與設計模塊可能以簡答題形式出現比如“請設計一個短鏈接系統”“如果線上服務的CPU持續飆升你如何排查”。這考察的不是背誦能力而是你面對真實問題時的分析框架和表達能力。1.3 為什么這套卷子“值得反復研究”市面上有很多筆試真題但字節2017秋招這套題我覺得非常典型原因有三第一題目設計有梯度。由淺入深一開始是基礎題讓大多數人能動手后續題目難度逐漸拔高把區分度做出來。這種梯度設計對篩選人才非常有效也能讓考生快速進入狀態。第二知識點考察不偏怪。基本沒有偏題、怪題所有知識點都在“合格計算機專業學生”的知識射程內。不考冷門的、文檔里都難查到的細節考的是核心主干知識。第三與工程實踐結合緊密。算法題不是純粹的數學游戲而是帶業務背景的場景題。這使得平時注重工程實踐、有項目經驗的同學更容易脫穎而出。2. 算法與數據結構題型的深度拆解2.1 字符串處理與雙指針技巧在筆試中字符串處理類題目出現頻率極高。這類題看似簡單但實際編碼時很容易因為邊界條件處理不當而出錯。常見的考法有以下幾種字符串反轉、單詞反轉涉及空格處理、標點符號處理需要借助快慢指針或雙端操作。字符串匹配與子串查找通常考察KMP算法思想或者更簡單的滑動窗口思想。字符串去重與壓縮比如“給定一個字符串統計每個字符出現的次數并按出現次數排序輸出”。我印象里特別容易出錯的地方是對字符數組與字符串結束符的處理。在C/C中字符串沒有長度屬性只能依靠結尾的\0判斷循環結束一旦越界就會導致未定義行為。在筆試環境中很多人會遇到“本地運行對一提交就崩潰”的情況多半就是這里出了問題。針對這類題目我的建議是在動手寫代碼前先在草稿紙上寫下幾個典型的測試用例尤其是空字符串、只有單個字符的字符串、全部字符都相同的極端情況。這些邊界用例往往是算法是否完整的關鍵。2.2 數組操作與排序算法的變形數組題在筆試中的占比同樣很大通常來考察時間復雜度的優化能力。例如給定一個整型數組找出其中出現次數超過一半的數字給定兩個有序數組找出兩個數組的中位數給定一個數組將數組中的0移動到末尾并保持非零元素相對順序。這些題目的共同特點是基礎版本的解法并不難但想要達到最優時間復雜度需要一點巧思。以“找出數組中出現次數超過一半的數字”為例最容易想到的解法是使用哈希表統計每個數字出現的次數時間復雜度O(n)空間復雜度O(n)。但更進一步可以使用“摩爾投票法”將空間復雜度降低到O(1)并且編碼起來非常簡潔。這類“從O(n)空間到O(1)局部”的優化正是面試官想看到的算法思維過程。在實際筆試時我建議盡量在代碼注釋里寫下思路比如“本解法采用摩爾投票法時間復雜度O(n)空間復雜度O(1)”。這既能幫助自己理清思路也能讓閱卷人快速看見你的思考過程。2.3 動態規劃從狀態定義到轉移方程動態規劃是筆試中的“分水嶺”題型通常以壓軸題或高分題出現。它考察的不僅是算法熟練度還有問題抽象能力。常見的動態規劃類型包括一維DP斐波那契數列、爬樓梯、最大子數組和、打家劫舍問題。二維DP編輯距離、最大正方形、不同路徑問題。區間DP回文串分割、石子合并問題。背包類DP0-1背包、完全背包及其變種。以“編輯距離”為例題目描述通常是這樣給定兩個單詞word1和word2計算將word1轉換成word2所需的最少操作數操作包括插入、刪除、替換一個字符。初看是個字符串處理問題但如果不套用DP框架很難高效解決。這類DP題的核心步驟可以歸納為三步定義狀態首先定義dp[i][j]的含義比如“word1的前i個字符轉換成word2的前j個字符所需的最小操作數”。找到狀態轉移方程分析dp[i][j]可以從哪些狀態轉移而來。對于編輯距離可以分兩種情況word1[i-1] word2[j-1]時dp[i][j] dp[i-1][j-1]否則dp[i][j] min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) 1分別對應刪除、插入和替換三種操作。初始化與邊界條件dp[0][j] j表示從空字符串插入j個字符dp[i][0] i表示從i個字符刪除到空字符串。這塊有一個實用經驗在筆試中如果你能寫出正確的DP解法哪怕不是最優解也能拿到大部分分值。很多人在考場上試圖追求最優解而浪費了太多時間最后連基礎解法都沒寫完這是得不償失的。2.4 二叉樹、圖論與深搜廣搜二叉樹相關的題目重點在遍歷方式上前序、中序、后序、層序遍歷。筆試中經常考的有根據前序和中序遍歷重建二叉樹、二叉樹的最近公共祖先、二叉樹的序列化與反序列化等。這些題目的難點在于遞歸邏輯的清晰性和邊界條件的判斷。特別是“重建二叉樹”這道題很多人在遞歸參數上容易搞混因為需要考慮子樹區間邊界是開區間還是閉區間。我建議在考前把這類題統一訓練一遍并固定下來一套自己的寫法比如統一使用“左閉右開”的區間表示法可以避免不少邊界錯誤。而圖論題目最常考的是深搜DFS和廣搜BFS。常見場景包括島嶼數量問題、課程表拓撲排序、單詞接龍最短路徑。其中BFS常用于求解無權圖的最短路徑DFS常用于求解可達性問題或枚舉所有可能性。在筆試中圖的表示方式鄰接矩陣還是鄰接表也需要根據題目要求靈活選擇。鄰接矩陣適合稠密圖查詢兩個節點間是否有邊時間復雜度為O(1)鄰接表適合稀疏圖遍歷所有鄰居節點時更節省空間和時間。3. 計算機基礎知識的考點分布3.1 操作系統并發與內存管理的考察重點操作系統是校招筆試中的“重頭戲”考核內容集中在這幾個方面進程與線程的區別與聯系為什么線程切換比進程切換開銷小哪些資源是線程共享的哪些是獨享的。進程同步與互斥信號量機制、生產者消費者問題、讀者寫者問題、哲學家就餐問題。死鎖產生的四個必要條件互斥、占有并等待、不可剝奪、循環等待以及死鎖避免的銀行家算法。內存管理分頁、分段、虛擬內存、頁面置換算法LRU、FIFO、Clock。對于選擇題最容易出錯的是“進程與線程的對比”。很多人下意識認為“同一進程的多個線程共享進程的地址空間”這個說法沒錯但更準確地說線程之間共享的是進程的堆內存、全局變量和打開的文件描述符而每個線程擁有獨立的棧空間和寄存器狀態。判斷題如果問“線程共享進程的所有資源”這就是錯誤的表述。在準備這部分時我推薦把知識框架整理成對比表格來記憶。比如進程與線程的對比、分頁與分段的對比、各種頁面置換算法的優劣對比。表格比純文字更直觀考前翻一遍效果很好。3.2 計算機網絡協議理解不能停留在背誦網絡部分的考法比較集中在這幾個知識點TCP三次握手與四次揮手為什么握手是三次而不是兩次為什么揮手需要四次TIME_WAIT狀態存在的意義是什么。TCP與UDP的區別各自的適用場景可靠傳輸是如何實現的通過序列號、確認應答、超時重傳。HTTP協議常見狀態碼含義200、301、302、403、404、500、502、503HTTP/1.0與HTTP/1.1的區別以及Cookie與Session的機制。DNS解析的過程從瀏覽器輸入域名到獲取IP地址經過了哪些步驟。這些知識點選擇填空幾乎逢考必有。而稍微靈活一點的題目會要求你“分析某個網絡故障”。比如客戶端訪問某網站時非常慢可能是什么原因這類題目考察的是對TCP連接建立過程、DNS解析耗時、HTTP連接復用等知識點的綜合理解。我當時復習時的一個關鍵操作是親手抓包看三次握手和四次揮手的全過程。用Wireshark或tcpdump實際上清晰地看到SYN、SYN-ACK、ACK三個報文段的序列號和標志位變化。這個經歷讓我對TCP狀態轉換圖的理解從一個死記硬背的流程變成了一個活生生的過程。強烈建議時間充裕的同學也這樣試一次。3.3 編程語言細節C與Java的高頻考點筆試試卷中對編程語言的考察通常以“給定小代碼段讓你判斷輸出”或“找出代碼中的錯誤”的形式出現。對于C高頻考點集中在指針與引用的區別引用必須初始化且不能改變指向指針可以不初始化且能改變指向。內存管理棧區與堆區的區別new/delete與malloc/free的對比。構造函數與析構函數拷貝構造函數、深拷貝與淺拷貝、虛析構函數的作用。虛函數與多態虛函數表的原理以及靜態聯編和動態聯編的區別。對于Java高頻考點集中在JVM內存區域劃分程序計數器、虛擬機棧、堆、方法區。垃圾回收機制可達性分析、引用計數法以及它的缺點、Java中常見的垃圾收集器。集合框架源碼細節HashMap底層是數組鏈表紅黑樹擴容機制以及ConcurrentHashMap的鎖分段與CAS操作。多線程與并發synchronized與ReentrantLock的區別volatile關鍵字的內存語義。這部分死記硬背是效率最低的方式因為考法很靈活。最好的復習方式是“以題帶點”拿各種校招真題、模擬題來做遇到一個考點就回去翻書或源碼把相關的底層原理串起來。比如遇到一個考HashMap的題就順手把紅黑樹的性質、哈希沖突的處理方式、擴容時為什么是2的冪次、在高并發下HashMap會出現什么問題一口氣都復習一遍效率會高出很多。4. 綜合分析與系統設計題的答題思路4.1 面試官到底在考什么不止是知識儲備這類題目分值占比可能不是最高但非常影響整體印象分。簡單題的開創性在于它的答案沒有標準對錯只有分析是否合理、方案是否可行、表達是否有邏輯這就考察了候選人真實的問題分析和解決框架。比如題目問“如何設計一個短鏈接系統”。絕大多數人看到這道題第一反應是“生成一個短碼存儲到數據庫里”。但這只是最基礎的想法離一個可落地的系統設計還差得很遠。一個完整的分析框架應該包含以下部分需求分析量化系統有多少QPS總數據量預估多大是讀多還是寫多這些決定了技術選型的走向。方案設計思路描述短碼生成的方案可以采用發號器自增ID轉62進制或者隨機字符串方案并說明各自的優缺點。存儲設計底層用什么數據庫是否需要引入緩存層如Redis來抗住高頻讀取。重定向邏輯301還是302以及為什么。容災與擴展性如果單機扛不住如何通過分庫分表或集群方案解決。你看哪怕是一個簡短的回答也能充分展示你的全局視野。答題時可以適當使用“首先”“其次”“最后”這么的邏輯詞讓思路更清晰。4.2 線上故障排查題的答題框架另一類常考的綜合題是“線上故障排查”。比如“服務器CPU占用率持續100%你如何排查”。這類題目的回答要點在于建立一套系統化的排查流程。我當時總結的通用框架是“由表及里、先資源后代碼”。可以按照以下順序展開確認現象先通過top命令查看CPU占用率最高的進程是哪個確認是用戶態CPU高還是內核態CPU高。定位線程通過ps -Lf pid查看進程內的線程再用jstackJava或gdbC/C查看線程棧定位到具體代碼行。分析原因是鎖競爭激烈是死循環還是頻繁的GC導致CPU飆升解決方案針對不同的根因給出相應的解決方案比如優化鎖粒度、修復死循環代碼、調整JVM參數等。這個回答本身不需要特別深的技術含量但體現了你面對未知問題時的冷靜程度和排查邏輯。面試官可以通過這種回答判斷你在真實工作中的實戰能力。4.3 準備方式刻意練習框架化表達這類題目對于平時只刷算法題的同學來說可能會有點懵。我的建議是在復習時不要只看題解要有意識地練習“把答案結構說出來”的能力。具體操作是這樣找10道經典的系統設計題包括短鏈接、秒殺系統、消息隊列、限流系統、爬蟲系統等把每種題型的標準回答框架寫下來然后按1分鐘、3分鐘、5分鐘三種時間長度分別口頭復述一遍。這個練習看似簡單但能有效訓練你在壓力下組織答案的能力讓表達邏輯更清晰。在筆試中遇到這種題時可以先用一句話總結方案再展開細節。比如“我的方案是采用發號器生成短碼配合Redis緩存和兩級存儲”。這種總分結構能讓閱卷人快速抓住重點避免因為大段描述而失分。5. 實戰模擬與備考過程中的經驗教訓5.1 時間分配的黃金策略一套筆試的時間通常在60分鐘到120分鐘之間。很多同學包括我當年都有一個通病在客觀題上糾結過久導致后面分值最高的編程題沒時間寫。我的建議是“先通讀整卷再按分值分配時間”。拿到試卷后花兩三分鐘通讀一遍所有題目大概標記出每道題的難度和預估耗時。然后給自己定一條“紅線”比如選擇題部分最多不超過總時間的30%編程題部分必須保留60%以上時間。如果一道選擇題思考了超過兩分鐘還沒有思路直接先憑第一感覺選一個然后跳到下一題。客觀題不會因為你是靠猜而扣分但多選可能會少選得部分分而編程題如果空著那就是零分這是最致命的。5.2 編程題的“最穩拿分三步法”編程題的評分通常不會只看最終結果是否正確運行通過很多筆試系統會要求你提交完整代碼后自動跑測試用例。但為了保險起見我建議大家把編程題當作小型工程來對待并采用這套“最穩三步法”第一步先讀懂題意提煉輸入輸出格式。很多編程題會給出非常長的題干但核心要求其實就是一句話。先把輸入是什么、輸出是什么搞清楚然后再動手。第二步設計算法寫下核心偽代碼。不要一上來就寫完整代碼。先用偽代碼或注釋把思路寫下來比如“需要先排序然后雙指針找目標值”。這一步能幫你避免在后半段代碼中迷失方向。第三步實現代碼并逐行檢查邊界。寫完代碼之后不要急著提交先用幾組自測用例在腦中模擬運行一遍特別是空輸入、超大輸入、重復數據這些邊界場景。這個檢查習慣能幫你攔截掉大部分低級錯誤。5.3 我踩過的一個典型“坑”我當年在真正參加筆試時犯過一個特別低級的錯誤編程題中輸入是一個包含空格的字符串我當時用cin str來讀取導致字符串讀到空格就截斷了。結果后面對字符串的所有處理邏輯全部跑偏調試了半天才發現問題所在。如果當時先用getline(cin, str)讀取就不會出現這個問題。這個經歷告訴我兩個重要教訓第一筆試前一定要熟悉在線評測系統常用的輸入輸出方式尤其是字符串讀取第二不要忽略基礎API的細節你自認為“用得滾瓜爛熟”的函數在邊界情況下可能完全不符合預期。另外還有一個非常實用的經驗如果筆試系統支持本地編譯器調試那就先在本地寫好代碼并運行測試用例再復制到在線編輯器。本地調試能打印中間變量直觀看到算法每一步的狀態在刷題練習時一定要養成這個習慣。5.4 高頻錯誤速查表錯誤類型典型場景規避方法數組越界遍歷數組時循環條件寫作 i n統一采用 i n 的寫法循環前先檢查邊界字符串讀取截斷輸入含空格的字符串時用了 cin使用 getline 或 fgets 讀取整行遞歸棧溢出深搜樹或圖時遞歸深度過大改用顯式棧模擬遞歸或檢查遞歸終止條件空指針/空對象對可能為空的鏈表、樹節點直接訪問屬性單步模板代碼先判空動態規劃數組初始化錯誤忘記了 dp[0] 或 dp[i][0] 行的初始化初始化三步法從邊界行和邊界列逐一驗證這張表是我在刷題過程中逐漸總結出來的每次筆試前我都會快速過一遍提醒自己避開這些最常見的低級錯誤。6. 備考規劃與筆試技巧6.1 刷題路線系統化比題海更重要在備考時間有限的情況下盲目刷題效率很低。我建議按照以下路線進行系統性復習第一周基礎數據結構與算法。重點刷數組、鏈表、棧、隊列、哈希表、二叉樹相關的基礎題恢復代碼手感。第二周算法思想專項。集中攻堅分治、二分查找、滑動窗口、雙指針、回溯算法并開始涉獵動態規劃的基礎題型。第三周動態規劃與圖論。這個階段要多做DP題每天保證至少3道DP題目的訓練量同時穿插圖論的BFS/DFS練習。第四周真題模擬與查漏補缺。按照筆試的時間和題量要求做2到3套完整的模擬卷提前適應考場節奏。這個過程看起來很常規但真正執行的人不多。很多人刷題是“隨緣刷”今天想起來做兩道明天忙就停了這樣很難形成體系化的知識網絡考試時容易“似曾相識但就是寫不出來”。6.2 每個考點復習到什么程度才算合格有一個自測標準我可以分享給大家數據結構能夠不看代碼在白紙上畫出二叉樹的前中后序遍歷結果能手動模擬哈希表插人沖突的解決過程。算法能夠用口頭語言講清楚二分查找的循環不變式能夠解釋為什么某些場景下貪心算法不適用。操作系統能在白板上畫出進程狀態轉換圖并說明每個轉換發生的條件。網絡能夠畫出TCP連接建立與釋放的時序圖并標注每一方的狀態變化。如果以上幾點你都能做到那筆試的基礎題和中等題基本穩了。如果還有說不清楚的地方說明這個知識點你是“死記硬背”的建議重新看書或者找視頻理解一遍。6.3 考前一周與考前一晚的實戰建議考前一周不要再去鉆研難題和偏題了。這個階段的首要任務是保持手感而不是提升能力。我的做法是每天做兩道中等難度的算法題保持編碼的熟練度并且把之前整理好的知識框架表、易錯點清單拿出來反復看。考前一晚尤其要注意睡眠時間。很多筆試是在線進行的對精神狀態的要求非常高。我見過太多同學因為熬夜復習結果筆試時頭腦發脹連簡單的二分查找都寫錯。與其多復習一晚上不如好好睡一覺保持清醒的頭腦上考場。另外考前一天一定要檢查好設備和網絡。提前測試編輯器能否正常使用編譯器版本是否匹配網絡是否穩定。這些看起來瑣碎的事情一旦出了問題會成為整場考試中最致命的干擾因素。7. 筆試之外這套試卷帶來的長遠思考當我復盤完這份2017年秋招筆試卷的全部考點后我發現一個很有意思的現象整張試卷很少有純粹的“記憶題”每一道題都在考察某種能力而不僅僅是一段知識。客觀題考察的是你“知識的組織方式”是否形成體系。編程題考察的是你“將抽象問題轉化為代碼”的能力。綜合題考察的是你“面對開放性問題時的思考路徑”。這種考察邏輯和大學的期末考試有著本質區別它更接近真實工作中你解決一個未知問題的過程。哪怕是現在我已經工作好幾年了回看這些考點發現它們依然是日常開發中天天要用的底層能力。所以我真心建議正在準備筆試的同學不要只把這套試卷當成“敲門磚”來對待。把它當成一個檢測自身能力短板的機會針對弱項進行系統性提升。筆試只是第一關即使僥幸通過后續的面試也會問到類似的問題甚至考察得更深。如果你能從筆試備考中真正建立起一套完整的知識體系那收獲的遠遠不止是一份offer。最后再分享一個我個人的操作習慣每次筆試或面試結束后我都會在當天晚上立刻寫下復盤筆記記錄哪些題答得順暢、哪些題卡住了、卡住的根本原因是什么。半個月后我會重新做一遍卡住過的題目直到能順暢寫出最優解為止。這個習慣讓我在連續多場面試中狀態越來越穩定因為我知道自己每次都在補漏而不是原地打轉。希望這個經驗對你也有用。