
1. 為什么工程數據崗的筆試要先搞明白考什么、怎么考2024年秋招我投了螞蟻集團的工程數據崗從簡歷篩選到筆試通知中間隔了大概一周。說實話收到筆試鏈接那一刻我是有點懵的——因為工程數據崗這個名字本身就有點模糊它既不像純后端開發崗那樣大家都能說出個大概也不像算法崗那樣有明確的刷題路徑。我身邊很多同學都以為這崗考的是數據分析結果進去一看Java并發、SQL窗口函數、Flink原理、算法題全都有。所以這篇復盤我想先聊一個很多人忽略的問題你到底在考什么。工程數據崗在螞蟻內部主要做的是數據管道、實時計算、數據治理、離線數倉這一類方向也就是把業務數據從源頭采集、清洗、加工成可用的數據資產。這個崗位的筆試不會只考數據分析它更看重的是你能不能寫對代碼、能不能處理大數據場景下的計算問題。換句話說它考察的是一個會寫代碼的數據工程師而不是會看報表的數據分析師。這一點直接從筆試題目分布就能感受到——算法題占了很大比重SQL也是偏復雜查詢而不是簡單select。還有一個很重要的點工程數據崗的筆試和純后端崗筆試的重合度大概有六成剩下四成是大數據組件和SQL的專屬考點。所以我后來復盤時有個很深的感受如果你只刷LeetCode不練SQL想靠運氣過筆試是很懸的反過來如果你只背組件原理不刷算法編程題大概率做不完。筆試的設計邏輯其實非常清晰就是篩掉那些偏科的人。另外要提醒一句螞蟻的筆試是在牛客網這種在線OJ系統上進行的全程攝像頭監控不能切屏切屏超過一定次數會被判作弊。所以考前一定要把網絡、瀏覽器、攝像頭都調試好。我筆試那場就有個同學因為電腦彈窗導致切屏被警告后面整個人心態都受影響了。這些細節看起來很碎但實際影響非常大。2. 考前信息戰從崗位JD倒推考點再定刷題計劃很多人準備筆試是看到什么刷什么今天做幾道數組題明天看兩個Flink原理視頻結果到考場上發現會的沒考、考的不會。我的經驗是準備筆試一定要從崗位JD倒推考點再倒推刷題計劃這樣才能把有限的時間用在刀刃上。2.1 JD里藏著筆試考察方向我當時把螞蟻工程數據崗的崗位描述翻來覆去看了好幾遍摘出幾個關鍵信息一是要求扎實的Java或C編程基礎二是熟悉Hadoop、Spark、Flink等大數據框架三是熟悉SQL和數據倉庫建模四是具備一定的算法與數據結構能力。如果你看到這樣的JD基本可以推斷出筆試的兩個大頭第一是編程題考察數據結構和算法第二是專業題考察Java基礎、SQL和大數據組件原理。我把JD里的每個要求對應到了具體的筆試考點列了一個表格照著這個表格復習效率和漫無目的刷題完全不一樣JD要求對應筆試考點復習優先級扎實的編程基礎數組、鏈表、棧、隊列、哈希、二叉樹、動態規劃高熟悉大數據框架Hadoop HDFS讀寫流程、Spark RDD/Shuffle、Flink 狀態與Checkpoint高熟悉SQL窗口函數、多表關聯、去重排序、行列轉換、連續問題高具備算法能力TopK、LRU、字符串處理、前綴和、雙指針高Java基礎集合源碼、并發編程、JVM內存模型、類加載中高數據倉庫建模星型模型、拉鏈表、緩慢變化維、事實表與維度表中2.2 題庫選擇和刷題優先級確定考點之后接下來就是選題庫。我個人的組合方案是LeetCode Hot 100 牛客SQL大廠真題 大數據組件原理題。LeetCode不用多說了Hot 100過兩遍基本能覆蓋筆試里大部分常規算法題。SQL部分牛客上有專門的大廠真題練習區里面有大量真實面試難度的SQL題比LeetCode的數據庫題更貼近國內大廠風格。大數據組件題在牛客、LeetCode上都沒有特別系統的題庫只能靠看面經總結我當時是把牛客上關于螞蟻工程數據崗的筆試面經翻了個遍把能收集到的題目類型都整理出來了。刷題優先級上我建議是SQL和算法題最優先JVM和并發其次大數據組件原理可以放在選擇題沖刺階段集中背。因為SQL和算法是編程題的主戰場占比高、拉分大值得投入最多時間。組件原理雖然也重要但更多出現在選擇題里背誦性價比高但理解深度要求沒那么高。2.3 四周復習計劃參考我實際用的復習計劃是四周周期比較適合時間適中、目標明確的情況分享出來給大家做參考第一周數據結構與算法強化。每天3道LeetCode中等題優先數組、鏈表、二叉樹、動態規劃周末做一次限時模擬。第二周SQL專項。每天5道SQL題覆蓋窗口函數、連續登錄、行列轉換、留存計算等高頻題型配合牛客SQL題庫。第三周Java基礎大數據組件。白天看Java并發和JVM晚上看Spark、Flink核心原理周末刷選擇題。第四周真題模擬與查漏補缺。每天按正式筆試的時間節點做一套模擬題重點訓練時間分配和抗壓能力。這個計劃最大的好處是把輸入和輸出結合起來了不是只看不練。第四周的限時模擬非常關鍵我第一次模擬的時候編程題根本做不完后來調整了答題順序才改善這個后面專門說。3. 筆試題型拆解從選擇題到編程題的實戰復盤螞蟻工程數據崗的筆試我當時參加的是約120分鐘的線上筆試題量不算小。整體風格偏向基礎扎實思維靈活沒有特別偏門的知識點但想拿高分也不容易。下面按題型來復盤。3.1 選擇題覆蓋Java、SQL、大數據組件選擇題大概有20到25道左右涵蓋的范圍很廣。Java基礎方面考了ArrayList和LinkedList的區別、HashMap的底層實現、并發編程里synchronized和ReentrantLock的區別、線程池的核心參數等。這些都是很典型的八股題難度不高但知識點細需要平時積累。SQL選擇題基本就是給一段SQL問你執行結果或者給個業務場景讓你選正確的SQL寫法。這類題目考察的是對SQL語義的理解是否準確尤其是JOIN的細節、GROUP BY與HAVING的關系、窗口函數的執行順序等。我有一個比較深刻的教訓是ON和WHERE的執行順序在LEFT JOIN里真的很容易混淆筆試就考了類似的題我當時差點選錯。大數據組件選擇題是大頭也是工程數據崗和其他技術崗最大的區別。Hadoop、Spark、Flink都有涉及比如HDFS的副本放置策略、Spark RDD的依賴關系、Flink的Checkpoint機制、Watermark和窗口的關系、數據傾斜的處理方式等。這些題目不會特別深只要你系統看過組件核心原理基本能答對。但如果只是知道組件名字、沒深入了解原理很容易被選項干擾。我復習時用了對比法把Hadoop、Spark、Flink的架構、計算模型、存儲方式、容錯機制放在一個表格里對比記憶效果很好。3.2 編程題常規算法題加一道SQL題編程題一般有兩到三道通常包括一道算法題和一道SQL題有時候會加一道大數據場景題。我這場的結構是兩道算法題加一道SQL題。算法題的方向比較常規一道是TopK問題的變體一道是字符串處理。難度大概在LeetCode中等不會到Hard但比Hot 100里的簡單題要難一些。這類題目刷過LeetCode的人應該都能下手關鍵是在有限時間內寫出正確且夠高效的解法。SQL題是典型的大廠業務題給了一張用戶登錄表要求計算每個用戶連續登錄的最大天數。這類問題在SQL面試里太常見了核心是用窗口函數row_number date_sub來做分組之前如果專門練過連續登錄類題目基本屬于送分題。但如果沒準備過考場上現場想可能要花不少時間。3.3 說說我印象最深的一道編程題有一道編程題我印象特別深題目大意是給一個很大的日志文件每行是一條用戶訪問記錄包含用戶ID、訪問時間和訪問頁面要求統計每個頁面獨立訪客數排名前10的頁面。這道題本質上就是經典TopK問題但是套了一個大數據場景的外殼。如果用Java寫核心思路就是先用HashMap統計每個頁面的獨立訪客數然后用小頂堆維護TopK。我在考場上很快想到了思路但因為要處理獨立訪客這個條件哈希表存的時候需要先去重當時在去重的實現上稍微猶豫了一下最后用了HashSet套在HashMap的value里。這道題給我的啟發是工程數據崗的算法題不會單純考數據結構和算法它會把實際業務場景包裝進去你需要快速把業務問題轉化成算法問題。4. 最拉開差距的算法題思路、代碼與現場心態算法題在整場筆試里的重要性不用多說它通常分值最高而且直接決定你能不能進下一輪。這里我想用一道TopK變體題作為例子完整還原我在考場的思考過程和解法。4.1 一道TopK變體的完整解題過程題目大致是給定一個字符串數組統計每個字符串出現的次數返回出現次數最多的前K個字符串如果出現次數相同則按字典序排序。這題在LeetCode上有原型就是前K個高頻單詞。我看到這題的時候心情是比較平靜的因為它屬于典型的哈希統計排序/TopK套路。我的解法思路分兩步第一步用HashMap統計每個單詞的出現次數key是單詞value是次數第二步構建一個小頂堆堆內按出現次數從小到大排序如果次數相同則按字典序從大到小排序這樣堆頂是最小的元素遍歷完所有單詞后堆里留下的就是出現次數最大且字典序靠前的K個。關鍵點在于利用優先隊列時要注意Comparator的寫法。我現場Java實現的核心代碼如下public ListString topKFrequent(String[] words, int k) { MapString, Integer countMap new HashMap(); for (String word : words) { countMap.put(word, countMap.getOrDefault(word, 0) 1); } PriorityQueueString minHeap new PriorityQueue((a, b) - { if (!countMap.get(a).equals(countMap.get(b))) { return countMap.get(a) - countMap.get(b); } else { return b.compareTo(a); } }); for (String word : countMap.keySet()) { minHeap.offer(word); if (minHeap.size() k) { minHeap.poll(); } } ListString res new ArrayList(minHeap); Collections.sort(res, (a, b) - { if (!countMap.get(a).equals(countMap.get(b))) { return countMap.get(b) - countMap.get(a); } else { return a.compareTo(b); } }); return res; }這里要注意幾個細節一是小頂堆的堆頂是當前最小的當堆大小超過K時彈出堆頂最終留下的就是最大的K個二是當次數相同時字典序小的應該留在堆里所以比較器里字典序那一項要反過來寫也就是b.compareTo(a)三是最后從堆里取出結果時順序是亂的需要二次排序恢復成題目要求的順序。這些細節如果平時沒寫熟考場上很容易翻車。4.2 遇到沒思路的題怎么辦先暴力再優化筆試現場最怕的就是碰到一道題完全沒有思路。我的策略是首先快速判斷這題的考點是什么如果5分鐘內想不出最優解就直接寫暴力解法。理由很簡單筆試OJ判題是按用例給分的暴力解至少能過一部分用例比交白卷強得多。寫暴力解的時候一定要把想法和注釋寫清楚方便后面有時間回來優化。很多牛客的筆試是支持多次提交的你可以先提交一個暴力解拿保底分然后繼續想優化方案。我筆試時第二道算法題就差點卡住題目涉及字符串的某種變換我當時第一反應是這題跟滑動窗口有關系但是窗口的左右邊界怎么移動想了好幾分鐘沒想清楚。后來我果斷放棄了一次寫對最優解的想法先寫了一個雙層循環的暴力解提交后大概過了30%的用例。拿到保底分之后我重新理了一下思路發現可以用前綴和數組把部分重復計算優化掉最后優化完過了全部用例。這段經歷讓我徹底明白筆試不是競賽得分才是硬道理不要在糾結中浪費時間。4.3 現場心態管理的幾個細節心態這件事聽起來虛但真的很影響發揮。我有幾點實際感受拿到題先深呼吸快速歸類考點不要一上來就寫代碼。腦子里的錨點很重要看到求前K個就想到堆看到連續子數組就想到前綴和看到字符串匹配就想到雙指針或KMP這些套路能幫你快速進入狀態。遇到卡殼超過10分鐘就跳過做后面會做的題回過頭來再看卡殼的題往往會有新的思路。我筆試時有一道算法題就是這樣先跳過做SQL題回頭再來看反而一下子想到了解法。不要盯著計時器看尤其是時間剩得不多的時候越看越焦慮。可以把剩余時間拆成幾個階段比如還剩60分鐘時應該做到哪還剩30分鐘時應該做到哪心里有個底就行。5. SQL與大數據組件題工程數據崗的專業分水嶺算法題大家都會刷真正把工程數據崗和其他崗位拉開差距的其實是SQL題和大數據組件題。這一塊如果你有數倉實習或者平時工作接觸過大數據組件會覺得很簡單但如果沒有實際經驗只能靠臨時背考場上很容易露餡。5.1 SQL高頻題型連續登錄、行列轉換、留存率SQL題在筆試里的地位非常高因為它直接對應了未來工作里最核心的能力——寫數據查詢和分析SQL。我整理過工程數據崗筆試SQL題的高頻題型主要集中在三類一是連續登錄問題。經典場景是給一張用戶登錄表計算每個用戶連續登錄的最大天數。核心解法是用窗口函數給每個用戶的登錄日期編號然后用登錄日期減去編號得到一個新的日期字段如果日期相同說明是同一段連續登錄。具體SQL如下select user_id, max(continue_days) as max_continue_days from ( select user_id, date_sub(login_date, row_number() over (partition by user_id order by login_date)) as grp_date, count(*) over (partition by user_id, date_sub(login_date, row_number() over (partition by user_id order by login_date))) as continue_days from user_login group by user_id, login_date ) t group by user_id;這個解法是分組求最大值的思路先給連續日期打上同一個標記再按標記分組統計數量最后取最大值。這種題沒有任何捷徑就是多練幾遍把套路刻在腦子里。二是行列轉換。比如把一張長表轉成寬表或者把寬表轉成長表。這類題考察的是CASE WHEN和UNION的靈活運用平時多寫幾遍就熟練了。三是留存率計算。給用戶活躍表計算某天新增用戶在之后第N天的留存率。核心是理解新增用戶和活躍用戶的區別然后通過JOIN和日期差計算。5.2 大數據組件題掌握原理比背八股重要大數據組件相關的選擇題和簡答題是工程數據崗筆試的個性題。我當時復習時重點看了幾個方向Hadoop的HDFS讀寫流程、MapReduce的Shuffle過程、Spark的RDD依賴和DAG、Spark和Flink的容錯機制區別、Flink的Watermark和窗口、數據傾斜的原因和解決方案。這里最常考的一個點是數據傾斜。題目通常會給你一個場景比如兩張表JOIN時某個key的數據量特別大導致reduce端負載不均問你該怎么解決。我建議至少要掌握以下幾個方案對傾斜key加隨機前綴打散、廣播小表避免Shuffle、調整并行度、兩階段聚合。這些方案筆試會考面試還會追問值得深入理解而不是死記硬背。還有一個高頻考點是Spark和Flink在容錯上的區別。Spark用Lineage血緣機制通過RDD的血緣關系重新計算恢復數據Flink用Checkpoint分布式快照通過周期性保存狀態快照實現精確一次語義。這兩個都是各自框架的核心機制一定要能說清楚它們的設計思路和適用場景。5.3 一道選擇題啟發我重新理解SQL執行順序筆試里有一道選擇題我印象很深問的是SQL語句中WHERE、GROUP BY、HAVING、SELECT、ORDER BY的執行順序。看起來很簡單但很多平時寫SQL的人根本說不清楚。正確答案是FROM是最先執行的然后WHERE再GROUP BY再HAVING再SELECT最后才是ORDER BY和LIMIT。這個執行順序決定了你在WHERE里不能使用SELECT里定義的別名但在ORDER BY里可以使用。我后來把這個知識點記到了自己的SQL筆記里因為很多業務SQL寫錯就是因為沒搞清楚執行順序。比如有人想對分組聚合后的結果過濾把條件寫在了WHERE里而不是HAVING里結果報錯或者結果不對。這種題考察的不是你會不會寫SQL而是你有沒有真正理解SQL的執行邏輯這也是工程數據崗需要具備的思維。6. 時間分配與答題策略別讓會做的題被時間拖死筆試時間有限做題順序和時間分配在很大程度上決定了你的成績。我第一套模擬題就是吃了順序的虧一上來死磕算法題結果后面簡單的選擇題都來不及做白白丟了很多分。6.1 我的答題順序先做選擇題再做SQL題最后做算法題我的實際策略是拿到試卷先快速瀏覽一遍全部題目對難度有個大致判斷然后按照選擇題 → SQL題 → 有思路的算法題 → 沒思路的算法題的順序來做。理由是選擇題雖然知識點碎但單個題耗時短、分值固定適合在頭腦最清醒的時候快速拿下SQL題只要會寫得分效率很高而且答案相對確定算法題費時最長不確定性最大放到后面做更合理。很多人的習慣是先做分值高的算法題我覺得這恰恰是誤區。大廠筆試的通過標準是總分過線而不是某一道題拿滿分。用更少的時間拿到更多的基礎分比花30分鐘死磕一道算法題要劃算得多。6.2 每類題目的時間預算參考我當時給自己定了一個時間預算大概是這樣題型建議時間策略說明選擇題25-30分鐘每題控制在1-1.5分鐘不會的果斷蒙一個并標記SQL題25-30分鐘先寫出正確版本再考慮優化不要一上來就寫復雜解法算法題第一題20-30分鐘這是最容易拿分的算法題全力以赴算法題第二題15-20分鐘10分鐘沒思路就寫暴力解拿保底分檢查和提交10-15分鐘重點檢查編譯錯誤、輸入輸出格式、邊界條件這個預算不一定適合所有人但有一個原則是通用的一定要給檢查留時間。我見過太多人寫完代碼就提交結果因為Scanner讀取格式不對或者沒有處理空輸入被扣分。這些不是不會做而是太虧了。6.3 編程題提交前的檢查清單說到提交檢查我總結了一個簡單的清單每次提交前都按這個過一遍輸入輸出格式是否正確題目要求多組輸入還是單組輸入用的是Scanner還是BufferedReader。有沒有處理邊界條件比如數組為空、k為0、字符串長度為1。數據類型是否溢出比如用int還是longTopK和累加計算很容易溢出。題目的方法簽名是否符合要求牛客筆試有時候要求你實現某個類方法類名和方法名都不能改。時間復雜度和空間復雜度是否會被卡如果題目給的數據量很大暴力解可能直接超時至少要先算一下復雜度。這些檢查項看起來基礎但每次筆試都有人在上面翻車。我建議平時刷題的時候就養成這個習慣不要只埋頭寫代碼要站在OJ的角度審題。7. 筆試之后復盤、面試銜接與抗遺忘安排筆試結束不代表這件事就完了。我身邊很多同學考完就徹底放飛自我等收到面試通知才開始慌。實際上從筆試到面試的間隔期是最重要的準備窗口能不能利用好這段時間決定了你在面試時是講得出深度還是只能聊表面。7.1 考后立刻做一次趁熱復盤筆試結束當晚趁記憶還新鮮我建議立刻做一次復盤。我當時是打開備忘錄把能回憶起來的題目類型、考察知識點、自己做錯的點、有疑慮的題全部記下來。不要只記題目要記我為什么做錯了和下一次遇到同類題應該怎么想。這個動作看起來簡單但非常有價值因為筆試考察的很多知識點在面試中會被問到考后復盤相當于提前做了面試梳理。比如我在SQL那道連續登錄題上雖然做對了但復盤時發現自己對date_sub和row_number配合的本質原理理解得不深。于是面試前我又專門搜了相關博客重新理解了一遍用日期減去編號把連續區間變成同一分組這個思路的數學原理結果面試時真的被追問了。如果不是考后復盤把這個薄弱點標記出來我面試很可能答不好。7.2 把筆試知識點延展成面試口語化表達筆試是選擇題和編程題面試是口頭交流和手撕代碼這中間有個轉換過程。筆試時你只要選出正確答案面試時面試官會追問為什么選這個和還有沒有其他方案。我的建議是趁著筆試后對知識點的印象還很深挑幾個核心內容做一次口述練習。比如Flink的Checkpoint機制你不能只說通過Checkpoint實現狀態恢復要能講清楚檢查點是怎么觸發的、Barrier對齊是怎么回事、精確一次和至少一次的區別、狀態后端有哪些。再比如數據傾斜不能只說加隨機前綴要能說明加前綴后如何進行兩階段聚合、性能代價有多大、什么場景下適合用廣播變量。這種把知識點從認識變成會講的過程是面試準備中最有價值的部分。7.3 個人的一點體會筆試是短板探測器這次筆試給我最大的收獲不是流程走完了而是讓我看清了自己在哪些方面還有短板。我在復習階段自我感覺SQL還不錯但實際筆試時發現自己在窗口函數的某些邊界場景下還是會猶豫我以為自己對Spark很熟但選擇題里考到RDD的窄依賴和寬依賴時有個選項讓我糾結了很久。這些自我感覺良好但實際還不夠扎實的地方如果不去筆試檢驗可能永遠不會暴露。所以我也想給正在準備秋招的人一個建議不要只盯著筆試通過與否看把它當成一次免費的壓力測試和短板探測器。每一道做錯的題、每一個卡殼的瞬間都是后續復習最明確的指引。2024年秋招競爭確實不小但工程數據崗的核心考察方向其實是清晰和穩定的把算法、SQL、大數據組件、Java基礎這四個方向扎扎實實準備好筆試這關沒有想象中那么可怕。