據(jù)開(kāi)發(fā)筆試題拆解:從日志處理到集群部署)
1. 一套校招大數(shù)據(jù)筆試題背后到底在篩什么人每年秋招季都能看到大量XX公司XX崗位筆試題在各種群里流傳。我見(jiàn)過(guò)太多人拿到題先問(wèn)答案是什么我卻想先問(wèn)一句出題人到底想通過(guò)這套題篩出什么樣的人拿iHandy2019校招大數(shù)據(jù)開(kāi)發(fā)工程師這套題來(lái)說(shuō)它不像社招那樣追著源碼問(wèn)也不會(huì)像ACM那樣硬摳算法但它很典型地反映了一類移動(dòng)互聯(lián)網(wǎng)公司對(duì)校招數(shù)據(jù)崗的真實(shí)期待——不是要你背出Flink源碼的細(xì)節(jié)而是要看你能不能在這個(gè)數(shù)據(jù)量級(jí)飛速膨脹的環(huán)境里用最穩(wěn)妥的技術(shù)棧把活干完、干對(duì)、干明白。iHandy是什么體量的公司做海外工具類、內(nèi)容類App起家用戶量以億計(jì)日活數(shù)據(jù)千萬(wàn)級(jí)甚至上億。這種業(yè)務(wù)形態(tài)決定了它的數(shù)據(jù)團(tuán)隊(duì)每天面對(duì)的不是幾百M(fèi)B的Excel而是源源不斷的埋點(diǎn)日志、業(yè)務(wù)庫(kù)Binlog、服務(wù)器監(jiān)控指標(biāo)。這些數(shù)據(jù)要經(jīng)過(guò)采集、清洗、入倉(cāng)、建模、報(bào)表、算法特征提取這一整條鏈路任何一個(gè)環(huán)節(jié)出錯(cuò)輕則報(bào)表對(duì)不上重則影響買量決策、廣告收入計(jì)算。所以筆試題目設(shè)計(jì)的核心邏輯就一句話用最小的成本判斷你有沒(méi)有生產(chǎn)環(huán)境的直覺(jué)。什么意思我給你拆開(kāi)講。比如一道題問(wèn)Spark任務(wù)的并行度怎么設(shè)置沒(méi)有生產(chǎn)經(jīng)驗(yàn)的人會(huì)默寫上跟核數(shù)一致但有經(jīng)驗(yàn)的人會(huì)反問(wèn)數(shù)據(jù)量多少數(shù)據(jù)傾斜有沒(méi)有Shuffle分區(qū)數(shù)跟下游文件的關(guān)聯(lián)是什么這套題不是考你背參數(shù)而是考你在真實(shí)場(chǎng)景里會(huì)不會(huì)做權(quán)衡。再比如說(shuō)日志處理。移動(dòng)互聯(lián)網(wǎng)公司最不缺的就是日志用戶點(diǎn)擊、啟動(dòng)、崩潰、購(gòu)買行為全部以日志形式落盤。誰(shuí)能在有限資源里把億級(jí)日志處理得又快又準(zhǔn)誰(shuí)就是數(shù)據(jù)團(tuán)隊(duì)想要的人。這套題里如果出現(xiàn)用Java編寫Spark處理日志這類題一點(diǎn)都不奇怪——它就是業(yè)務(wù)場(chǎng)景的微縮版。從熱搜詞也能看出來(lái)大數(shù)據(jù)開(kāi)發(fā)、大數(shù)據(jù)架構(gòu)、Spark日志處理、集群部署、數(shù)據(jù)質(zhì)量這些詞高頻出現(xiàn)說(shuō)明行業(yè)對(duì)這些方向的人才需求是持續(xù)且明確的。作為校招生你不需要在每一個(gè)方向都是專家但你需要對(duì)這些詞背后的工程問(wèn)題有完整的認(rèn)知框架。我在后面幾節(jié)里會(huì)結(jié)合這類題目常見(jiàn)的幾個(gè)考察方向逐一拆解題目背后的出題意圖、答題思路以及那些老師沒(méi)教過(guò)、但面試官默認(rèn)你會(huì)的行業(yè)常識(shí)。這樣你看完這篇再去做任何一家公司的大數(shù)據(jù)開(kāi)發(fā)筆試題至少能知道每道題在問(wèn)什么以及考官想聽(tīng)什么答案。2. 從Java寫Spark處理日志看這道常青題怎么答才不丟分2.1 為什么日志處理題年年出現(xiàn)大數(shù)據(jù)校招筆試?yán)锶罩咎幚砘臼潜爻鲱}。原因特別樸素日志是離數(shù)據(jù)工程師最近的數(shù)據(jù)形態(tài)。每天零點(diǎn)過(guò)后全公司的App用戶行為日志、業(yè)務(wù)服務(wù)日志、系統(tǒng)運(yùn)行日志都會(huì)匯聚到數(shù)據(jù)平臺(tái)。你早上一來(lái)打開(kāi)告警群看到的就是昨日日志處理任務(wù)運(yùn)行時(shí)長(zhǎng)超時(shí)數(shù)據(jù)產(chǎn)出延遲某個(gè)埋點(diǎn)字段解析失敗。日復(fù)一日你其實(shí)就是在跟日志較勁。所以筆試?yán)锍霈F(xiàn)用Java編寫Spark處理日志數(shù)據(jù)這類題本質(zhì)上是把日常工作抽象成了考試題。它考察的能力很明確你會(huì)不會(huì)用Java寫Spark作業(yè)你知不知道日志數(shù)據(jù)常見(jiàn)的格式和坑你有沒(méi)有處理過(guò)臟數(shù)據(jù)、字段缺失、類型異常這些問(wèn)題你寫的代碼有沒(méi)有生產(chǎn)意識(shí)比如設(shè)置合理的分區(qū)數(shù)、避免OOM、考慮增量還是全量我見(jiàn)過(guò)很多候選人代碼寫得挺漂亮但一跑真實(shí)數(shù)據(jù)就崩。問(wèn)題不在語(yǔ)法在于他從來(lái)沒(méi)見(jiàn)過(guò)真實(shí)日志長(zhǎng)什么樣。2.2 一道經(jīng)典真題的完整答題過(guò)程假設(shè)題目是這樣的有一批用戶行為日志每一行是JSON格式包含userId、action、timestamp、pageId、deviceType等字段請(qǐng)用Java編寫Spark程序統(tǒng)計(jì)每天每個(gè)頁(yè)面的獨(dú)立訪客數(shù)UV和訪問(wèn)次數(shù)PV結(jié)果輸出到HDFS并按PV倒序排列。很多人拿到這題直接開(kāi)寫。但我想先說(shuō)一句先別急著寫代碼先想清楚你會(huì)在生產(chǎn)環(huán)境怎么做這件事。第一步讀數(shù)據(jù)。日志放在HDFS上日期作為分區(qū)目錄比如/data/logs/dt20240601。你用Spark讀的時(shí)候是讀整個(gè)目錄還是讀具體日期生產(chǎn)上通常跑定時(shí)調(diào)度傳入日期參數(shù)只讀當(dāng)天的分區(qū)。第二步解析。日志是JSON格式你可以在Java里用Fastjson或Jackson解析也可以用Spark自帶的from_json函數(shù)。筆試手寫代碼的話用Fastjson最直觀。第三步指標(biāo)計(jì)算。PV好算每條日志count一下就行。UV要去重用approxCountDistinct還是countDistinct這里有個(gè)考點(diǎn)UV通常很大精確去重在數(shù)據(jù)量上來(lái)以后會(huì)非常耗時(shí)生產(chǎn)環(huán)境一般用HyperLogLog這類近似算法誤差在1%以內(nèi)性能卻快幾個(gè)數(shù)量級(jí)。答題時(shí)說(shuō)清楚這個(gè)選擇比代碼寫對(duì)更讓面試官眼前一亮。第四步結(jié)果寫出。分區(qū)數(shù)多少文件大小多少如果結(jié)果很小coalesce(1)減少小文件如果結(jié)果很大保持合理分區(qū)數(shù)。這些都是生產(chǎn)環(huán)境的真實(shí)考量。我給出一個(gè)可直接參考的Java版本實(shí)現(xiàn)import com.alibaba.fastjson.JSONObject; import org.apache.spark.api.java.JavaPairRDD; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.sql.SparkSession; import scala.Tuple2; import java.util.Arrays; public class LogAnalyzer { public static void main(String[] args) { String inputPath args[0]; String outputPath args[1]; SparkSession spark SparkSession.builder() .appName(UserActionLogAnalyzer) .enableHiveSupport() .getOrCreate(); JavaRDDString lines spark.read().textFile(inputPath).javaRDD(); // 解析JSON過(guò)濾臟數(shù)據(jù) JavaPairRDDString, String pageUserRDD lines.mapToPair(line - { try { JSONObject obj JSONObject.parseObject(line); String pageId obj.getString(pageId); String userId obj.getString(userId); if (pageId null || userId null) { return null; } return new Tuple2(pageId, userId); } catch (Exception e) { return null; // 臟數(shù)據(jù)跳過(guò) } }).filter(tuple - tuple ! null); // PV統(tǒng)計(jì) JavaPairRDDString, Long pvRDD pageUserRDD .mapToPair(tuple - new Tuple2(tuple._1, 1L)) .reduceByKey(Long::sum); // UV統(tǒng)計(jì)先按(pageId, userId)去重再統(tǒng)計(jì) JavaPairRDDString, Long uvRDD pageUserRDD .distinct() .mapToPair(tuple - new Tuple2(tuple._1, 1L)) .reduceByKey(Long::sum); // 按PV倒序排序 ListTuple2String, Long pvList pvRDD.collect(); // 實(shí)際生產(chǎn)用sortByKey或DataFrame API排序 // 這里簡(jiǎn)化為輸出到文件 pvRDD.mapToPair(Tuple2::swap) .sortByKey(false) .mapToPair(Tuple2::swap) .saveAsTextFile(outputPath /pv); uvRDD.saveAsTextFile(outputPath /uv); spark.stop(); } }這段代碼在考試?yán)飰蛴玫乙貏e說(shuō)明幾個(gè)生產(chǎn)環(huán)境里真正重要、也是面試官真正想聽(tīng)的細(xì)節(jié)一是臟數(shù)據(jù)處理。真實(shí)日志里總有幾行JSON解析失敗、userId為空、字段類型錯(cuò)亂。代碼里catch (Exception e) { return null; }就是干這個(gè)的。你要能主動(dòng)說(shuō)出解析失敗的數(shù)據(jù)我選擇丟棄并記錄告警如果丟棄率超過(guò)閾值就要排查埋點(diǎn)問(wèn)題這句話能體現(xiàn)你的工程思維。二是數(shù)據(jù)傾斜。熱門頁(yè)面的日志量可能是冷門頁(yè)面的成百上千倍reduceByKey時(shí)一個(gè)Key的數(shù)據(jù)量巨大會(huì)導(dǎo)致單個(gè)Task跑很久。生產(chǎn)上要預(yù)見(jiàn)這個(gè)問(wèn)題答題時(shí)主動(dòng)提到加鹽、兩階段聚合等手段會(huì)明顯加分。三是結(jié)果文件數(shù)量問(wèn)題。saveAsTextFile默認(rèn)分區(qū)數(shù)跟最后一個(gè)RDD的分區(qū)數(shù)一致如果最后分區(qū)數(shù)幾百個(gè)會(huì)產(chǎn)生幾百個(gè)小文件HDFS NameNode壓力很大下游Hive查詢也會(huì)變慢。按PV排序輸出前應(yīng)該coalesce(1)或repartition(合適的數(shù)量)。能主動(dòng)講出這一點(diǎn)的人真的不多。2.3 這類題目的延伸追問(wèn)預(yù)備筆試之后通常還有面試面試官大概率會(huì)順著日志題往下追問(wèn)如果日志量每天增加一倍你的作業(yè)怎么擴(kuò)容如果某個(gè)字段的解析邏輯變了老數(shù)據(jù)和新數(shù)據(jù)怎么兼容如果下游報(bào)表要求凌晨6點(diǎn)前產(chǎn)出你的作業(yè)運(yùn)行時(shí)間超過(guò)窗口怎么辦埋點(diǎn)上報(bào)的日志有延遲凌晨統(tǒng)計(jì)時(shí)還有一部分?jǐn)?shù)據(jù)沒(méi)到齊怎么辦這些問(wèn)題沒(méi)有標(biāo)準(zhǔn)答案但都在考察你有沒(méi)有真實(shí)面對(duì)過(guò)數(shù)據(jù)是臟的、系統(tǒng)是不完美的、時(shí)間是緊張的這三種狀態(tài)。準(zhǔn)備面試時(shí)把歷年真題里的日志題都拿出來(lái)順著這幾個(gè)方向想一想比多刷十道算法題有用得多。3. 大數(shù)據(jù)收集與質(zhì)量保證題目里最簡(jiǎn)單、卻最能拉開(kāi)差距的一塊熱搜詞里有一句很扎眼的話對(duì)于大數(shù)據(jù)而言最基本、最重要的要求就是減少錯(cuò)誤、保證質(zhì)量。那么大數(shù)據(jù)收集的...。這多半是某個(gè)知識(shí)平臺(tái)上的問(wèn)題標(biāo)題但正好戳中了校招筆試?yán)镒钊菀妆缓鲆?、也最能體現(xiàn)功底的考察方向。3.1 減少錯(cuò)誤、保證質(zhì)量在大數(shù)據(jù)場(chǎng)景下到底指什么很多校招生對(duì)數(shù)據(jù)質(zhì)量的理解停留在數(shù)據(jù)不能錯(cuò)。但到了生產(chǎn)環(huán)境錯(cuò)有好多種我隨便列幾個(gè)數(shù)據(jù)丟采集端網(wǎng)絡(luò)抖動(dòng)一批日志沒(méi)傳上來(lái)數(shù)據(jù)重重試機(jī)制導(dǎo)致同一條日志被上報(bào)了兩次數(shù)據(jù)臟客戶端版本太老埋點(diǎn)事件里混入了格式錯(cuò)誤的內(nèi)容數(shù)據(jù)晚本該昨天到的數(shù)據(jù)今天才到齊數(shù)據(jù)不一致兩個(gè)部門對(duì)同一個(gè)指標(biāo)的統(tǒng)計(jì)口徑不一樣報(bào)表打架數(shù)據(jù)模型錯(cuò)事實(shí)表和維度表的關(guān)聯(lián)鍵有重復(fù)導(dǎo)致數(shù)據(jù)膨脹筆試題如果考到數(shù)據(jù)收集大概率會(huì)從你怎么設(shè)計(jì)一套可靠的采集方案或者給你一批臟數(shù)據(jù)你怎么清洗這兩個(gè)角度切入。前者考察系統(tǒng)設(shè)計(jì)后者考察實(shí)操能力。3.2 從埋點(diǎn)數(shù)據(jù)看數(shù)據(jù)收集的核心鏈路移動(dòng)App的數(shù)據(jù)收集鏈路大概是這樣的App端埋點(diǎn) - 上報(bào)隊(duì)列 - 網(wǎng)關(guān)接收 - Kafka - 實(shí)時(shí)/離線清洗 - 數(shù)倉(cāng)入倉(cāng)筆試考這個(gè)鏈路時(shí)常見(jiàn)的考點(diǎn)包括傳輸層Kafka在鏈路里扮演什么角色Kafka的定位是削峰填谷。如果客戶端直接寫數(shù)據(jù)庫(kù)高峰期可能把庫(kù)打爆但有了Kafka這個(gè)緩沖層上游流量再大下游消費(fèi)者都可以按照自己的速度消費(fèi)。這道題的變體還會(huì)問(wèn)Kafka掛了一個(gè)broker消息會(huì)丟嗎答案取決于副本因子配置生產(chǎn)環(huán)境一般設(shè)3副本允許掛2臺(tái)broker不丟數(shù)據(jù)。采集層埋點(diǎn)丟失怎么發(fā)現(xiàn)業(yè)界常用的做法是數(shù)量對(duì)賬。客戶端每次上報(bào)日志時(shí)附帶一個(gè)event sequence number服務(wù)端可以校驗(yàn)序列號(hào)連續(xù)性。離線側(cè)還可以做產(chǎn)出監(jiān)控比如昨天PV是1億今天突然變成8000萬(wàn)監(jiān)控系統(tǒng)自動(dòng)告警。筆試?yán)锬隳艽鸪鰞蛇厡?duì)賬監(jiān)控告警兩層保障基本就過(guò)關(guān)了。清洗層臟數(shù)據(jù)怎么處理清洗規(guī)則應(yīng)該寫死在ETL里而不是靠人工。比如日期字段格式不合法就置空、行為類型不在枚舉范圍內(nèi)就丟棄、userId為空就歸入未知用戶桶。關(guān)鍵是清洗規(guī)則要可追溯每一類被清洗掉的數(shù)據(jù)都要有統(tǒng)計(jì)和抽樣日志否則出了問(wèn)題連鍋都找不到。3.3 數(shù)據(jù)質(zhì)量題的答題框架面試官如果要考數(shù)據(jù)質(zhì)量常見(jiàn)的出題方式是你們的報(bào)表數(shù)據(jù)跟業(yè)務(wù)方自己統(tǒng)計(jì)的對(duì)不上怎么排查這是一個(gè)典型的排查思路題答案可以套用一套固定鏈路先對(duì)齊統(tǒng)計(jì)口徑。是不是兩邊對(duì)活躍用戶的定義不同一邊算啟動(dòng)過(guò)App就算活躍另一邊算有過(guò)頁(yè)面瀏覽行為才算活躍再對(duì)齊時(shí)間口徑。一個(gè)按東八區(qū)算天另一個(gè)按UTC算天數(shù)據(jù)對(duì)不上太正常了。第三步查數(shù)據(jù)鏈路。一邊從實(shí)時(shí)數(shù)倉(cāng)讀一邊從離線數(shù)倉(cāng)讀兩邊底層數(shù)據(jù)不一致結(jié)果必然不一致。實(shí)時(shí)和離線的數(shù)據(jù)質(zhì)量本身就可能不同。第四步是真的查Bug??纯碋TL代碼有沒(méi)有更新后沒(méi)測(cè)出問(wèn)題、有沒(méi)有上游表結(jié)構(gòu)變更導(dǎo)致下游解析失敗。這個(gè)框架的價(jià)值在于它向面試官證明你不是上來(lái)就翻代碼而是有系統(tǒng)性的排查方法。我在實(shí)際工作中處理過(guò)太多數(shù)據(jù)對(duì)不上的問(wèn)題超過(guò)一半最后查出來(lái)是口徑問(wèn)題不是程序Bug。3.4 關(guān)于串口屏往數(shù)據(jù)記錄控件添加一條內(nèi)容添加不全的延伸思考熱搜詞里有個(gè)很特別的問(wèn)題廣州大彩串口屏往數(shù)據(jù)記錄控件添加一條內(nèi)容添加不全。乍一看這跟主流大數(shù)據(jù)八竿子打不著。但這類問(wèn)題恰恰反映了物聯(lián)網(wǎng)/嵌入式場(chǎng)景下小數(shù)據(jù)的常見(jiàn)故障——不是大數(shù)據(jù)量級(jí)是大數(shù)據(jù)鏈路最前端的采集環(huán)節(jié)。如果你有幸面試的是一家做IoT數(shù)據(jù)平臺(tái)的公司這類問(wèn)題就可能以場(chǎng)景題出現(xiàn)設(shè)備端上報(bào)的數(shù)據(jù)不完整你怎么定位是設(shè)備端問(wèn)題、網(wǎng)關(guān)問(wèn)題還是平臺(tái)解析問(wèn)題排查思路其實(shí)是相通的先在鏈路各節(jié)點(diǎn)加日志和數(shù)據(jù)快照然后做分段對(duì)比找到第一個(gè)數(shù)據(jù)變短的節(jié)點(diǎn)再針對(duì)該節(jié)點(diǎn)的處理邏輯做代碼審查。這個(gè)方法論跟處理幾億條日志數(shù)據(jù)質(zhì)量問(wèn)題的思路一模一樣。所以別小看熱搜詞里那些犄角旮旯的關(guān)聯(lián)問(wèn)題——它們反映的往往不是問(wèn)題本身而是大數(shù)據(jù)從采集到應(yīng)用的完整鏈條中某個(gè)環(huán)節(jié)的真實(shí)痛點(diǎn)。你在筆試答題時(shí)能體現(xiàn)出我理解全鏈路而不只是會(huì)寫SQL就已經(jīng)跑贏大部分候選人了。4. 大數(shù)據(jù)架構(gòu)和集群部署題從一套架構(gòu)設(shè)計(jì)題反推復(fù)習(xí)重點(diǎn)4.1 大數(shù)據(jù)架構(gòu)題到底在問(wèn)什么校招筆試出現(xiàn)大數(shù)據(jù)架構(gòu)相關(guān)的題通常不是讓你畫一張完整的Lambda架構(gòu)圖而是給你一個(gè)具體場(chǎng)景讓你選技術(shù)方案。常見(jiàn)問(wèn)法是這樣的業(yè)務(wù)方需要實(shí)時(shí)看到今天的銷售額又要支持昨天之前的歷史數(shù)據(jù)分析你怎么設(shè)計(jì)數(shù)據(jù)架構(gòu)數(shù)據(jù)中心每天產(chǎn)生10TB日志要求保留30天供分析查詢響應(yīng)時(shí)間要在秒級(jí)你怎么選型數(shù)據(jù)量增長(zhǎng)很快當(dāng)前Hadoop集群磁盤使用率已經(jīng)85%怎么擴(kuò)容在線擴(kuò)容還是冷熱分離這些題沒(méi)有唯一答案但能看出一個(gè)人有沒(méi)有完整的數(shù)據(jù)平臺(tái)認(rèn)知。拿熱搜詞里那條大數(shù)據(jù)集群部署策略來(lái)說(shuō)校招筆試可能會(huì)拆成幾道小題NameNode和DataNode分別部署在什么類型的機(jī)器上ZooKeeper集群最少要幾臺(tái)為什么Kafka的broker和ZooKeeper部署在一起行不行這些問(wèn)題的核心只有一個(gè)——你是否理解不同組件對(duì)硬件資源的需求差異。我列一張表你在復(fù)習(xí)時(shí)可以對(duì)照著看組件主要消耗資源部署建議NameNode內(nèi)存存元數(shù)據(jù)大內(nèi)存機(jī)器如256GB內(nèi)存SSDDataNode磁盤、I/O大容量HDD即可追求吞吐ResourceManager內(nèi)存、CPU中等配置即可高可用要兩臺(tái)ZooKeeperCPU、網(wǎng)絡(luò)3臺(tái)或5臺(tái)小機(jī)器IO要求高Kafka Broker磁盤I/O、網(wǎng)絡(luò)多塊SSD做消息日志存儲(chǔ)HBase RegionServer內(nèi)存、I/O內(nèi)存要大最好配NVMe SSDFlink TaskManager內(nèi)存、CPU按內(nèi)存/CPU配比計(jì)算槽位數(shù)大部分校招生對(duì)這張表沒(méi)有概念或者說(shuō)只記住了NameNode要內(nèi)存大這句話但不知道為什么要大。NameNode把整個(gè)文件系統(tǒng)的目錄樹(shù)和文件塊位置信息都放在內(nèi)存里文件數(shù)越多內(nèi)存占用越大。一個(gè)文件塊默認(rèn)128MB的元數(shù)據(jù)大約150字節(jié)如果是1億個(gè)文件光元數(shù)據(jù)就要15GB內(nèi)存再加上堆內(nèi)其他開(kāi)銷和堆外內(nèi)存64GB的機(jī)器都不一定夠用。這就是為什么生產(chǎn)環(huán)境超大集群要引入NameNode聯(lián)邦或HDFS Router來(lái)橫向擴(kuò)展元數(shù)據(jù)能力。4.2 集群部署策略的考察點(diǎn)與答題重點(diǎn)集群部署題從實(shí)際操作角度來(lái)說(shuō)最常見(jiàn)的是在線擴(kuò)容和高可用配置兩個(gè)方向。在線擴(kuò)容考的是你對(duì)數(shù)據(jù)均衡的理解。新增DataNode節(jié)點(diǎn)后HDFS不會(huì)自動(dòng)把老節(jié)點(diǎn)數(shù)據(jù)搬到新節(jié)點(diǎn)需要手動(dòng)執(zhí)行hdfs balancer而且balancer默認(rèn)帶寬只有1MB/s需要調(diào)大參數(shù)。部署時(shí)如果不管磁盤數(shù)據(jù)平衡老節(jié)點(diǎn)磁盤很快被打滿新節(jié)點(diǎn)閑著集群整體可用容量反而下降。答題時(shí)能主動(dòng)說(shuō)出擴(kuò)容后要關(guān)注balance這個(gè)操作細(xì)節(jié)就會(huì)顯得很有實(shí)戰(zhàn)經(jīng)驗(yàn)。高可用配置考的是腦裂問(wèn)題的理解。Hadoop NameNode高可用依賴ZooKeeper和JournalNodeActive NameNode和Standby NameNode之間通過(guò)JournalNode同步元數(shù)據(jù)編輯日志。實(shí)際生產(chǎn)中可能出現(xiàn)Active節(jié)點(diǎn)假死網(wǎng)絡(luò)抖動(dòng)、JVM長(zhǎng)時(shí)間GCZooKeeper這邊判定它掛了讓Standby切換成Active但老Active其實(shí)還活著于是出現(xiàn)兩個(gè)Active——這就是腦裂。答案是靠Fencing機(jī)制舊的Active會(huì)被強(qiáng)制隔離SSH殺進(jìn)程、或者調(diào)用隔離腳本只有確保舊Active不再使用共享資源新Active才能安全接管。校招題如果問(wèn)到HA你能答出腦裂要靠Fencing機(jī)制解決這一層已經(jīng)比很多工作一兩年的人強(qiáng)了。4.3 基于大語(yǔ)言模型的非結(jié)構(gòu)化數(shù)據(jù)理解這類新考點(diǎn)最近的熱搜詞里還出現(xiàn)了一條很有意思的基于大語(yǔ)言模型的云盤非結(jié)構(gòu)化數(shù)據(jù)理解與內(nèi)容生成方法。這類技術(shù)方向放在2019年還是科幻小說(shuō)但放到現(xiàn)在它已經(jīng)變成了真實(shí)的數(shù)據(jù)架構(gòu)考題方向。校招筆試題如果往這個(gè)方向延伸很可能不是考模型本身而是考數(shù)據(jù)架構(gòu)怎么配合非結(jié)構(gòu)化數(shù)據(jù)文檔、圖片、視頻怎么統(tǒng)一接入數(shù)倉(cāng)對(duì)象的元數(shù)據(jù)文件類型、大小、存儲(chǔ)位置、所屬用戶放哪里大模型推理結(jié)果怎么回流是寫回源數(shù)據(jù)系統(tǒng)還是單獨(dú)建特征庫(kù)內(nèi)容生成的結(jié)果怎么評(píng)估質(zhì)量這四個(gè)問(wèn)題本質(zhì)上還是在考數(shù)據(jù)鏈路設(shè)計(jì)能力。你不需要真的訓(xùn)過(guò)大模型但你要能說(shuō)出非結(jié)構(gòu)化數(shù)據(jù)要先做元數(shù)據(jù)抽取再做內(nèi)容理解最后把結(jié)果回流到檢索系統(tǒng)或推薦系統(tǒng)這個(gè)閉環(huán)。面試官聽(tīng)到你講出這個(gè)閉環(huán)就會(huì)知道你對(duì)技術(shù)趨勢(shì)有敏感度而且對(duì)數(shù)據(jù)架構(gòu)有整體認(rèn)知。4.4 Avue-Data數(shù)據(jù)大屏這類前端部署題怎么應(yīng)對(duì)熱搜詞里avue-data數(shù)據(jù)大屏前端是怎么部署的也是個(gè)有意思的問(wèn)題。很多人會(huì)問(wèn)這是前端題關(guān)大數(shù)據(jù)什么事其實(shí)它考的是數(shù)據(jù)產(chǎn)品化的最后一公里。數(shù)據(jù)大屏就是把數(shù)倉(cāng)里的指標(biāo)通過(guò)可視化方式展示出來(lái)。筆試?yán)锶绻鲞@類題核心考點(diǎn)通常是大屏數(shù)據(jù)從哪來(lái)直接查數(shù)據(jù)庫(kù)還是查預(yù)聚合的API實(shí)時(shí)大屏用WebSocket還是輪詢大屏數(shù)據(jù)量很大時(shí)前端會(huì)不會(huì)卡死要不要服務(wù)端做聚合有一次我面一個(gè)候選人他說(shuō)他做過(guò)數(shù)據(jù)大屏被問(wèn)到數(shù)據(jù)量到10萬(wàn)條以上圖表卡頓怎么辦他沒(méi)答上來(lái)。其實(shí)答案不復(fù)雜大屏展示的是趨勢(shì)和概覽沒(méi)必要把每條明細(xì)都推到前端服務(wù)端按分鐘聚合出幾百個(gè)點(diǎn)就夠了。真正需要明細(xì)下鉆的再按需加載。能答到這層的人說(shuō)明他考慮的不只是怎么把組件跑起來(lái)而是這個(gè)系統(tǒng)在真實(shí)量級(jí)下能不能扛住。5. 從DataX到Dinky數(shù)據(jù)集成與開(kāi)發(fā)工具類題目的復(fù)習(xí)方向5.1 為什么筆試會(huì)考工具組件有熱搜詞問(wèn)大數(shù)據(jù)組件dinky下載大數(shù)據(jù)集群部署策略這一類關(guān)鍵詞直指筆試中的工具題。校招筆試考工具不是為了讓你報(bào)出版本號(hào)而是考察兩件事你知道這個(gè)工具解決什么問(wèn)題、在鏈路里處于什么位置你上手用過(guò)沒(méi)有遇到報(bào)錯(cuò)時(shí)能不能定位大數(shù)據(jù)開(kāi)發(fā)崗位日常接觸的工具有一大把數(shù)據(jù)集成有DataX、Flink CDC、Canal調(diào)度有Azkaban、DolphinScheduler、Airflow數(shù)倉(cāng)建模有Hive、Spark SQL查詢引擎有Presto、Doris、ClickHouse開(kāi)發(fā)輔助有Dinky這種Flink SQL開(kāi)發(fā)平臺(tái)。任何一個(gè)工具拿出來(lái)都能出一套面試題但校招筆試通常只考兩類選型類和應(yīng)用類。5.2 工具選型題的通用答題框架MySQL數(shù)據(jù)實(shí)時(shí)同步到數(shù)據(jù)倉(cāng)庫(kù)你會(huì)用什么工具——這是典型的數(shù)據(jù)集成選型題。筆試題答這題建議按這個(gè)框架展開(kāi)第一步確認(rèn)需求邊界。同步是全量還是增量實(shí)時(shí)還是離線數(shù)據(jù)量多大目標(biāo)庫(kù)是什么第二步列舉可選方案。全量離線可以用DataX增量實(shí)時(shí)且有主鍵變更捕獲需求用Flink CDC或Canal監(jiān)聽(tīng)Binlog如果只是分鐘級(jí)延遲的準(zhǔn)實(shí)時(shí)也可以用DataX配周期調(diào)度。第三步給出理由。比如選Flink CDC可以說(shuō)它能精確讀取Binlog支持?jǐn)帱c(diǎn)續(xù)傳配合Flink的實(shí)時(shí)計(jì)算能力可以直接做清洗和寬表加工選Canal則更輕量適合單純把Binlog轉(zhuǎn)發(fā)到Kafka的場(chǎng)景。第四步指出風(fēng)險(xiǎn)。Binlog開(kāi)啟會(huì)增加數(shù)據(jù)庫(kù)主庫(kù)的壓力大事務(wù)會(huì)導(dǎo)致Binlog膨脹源庫(kù)表結(jié)構(gòu)變更會(huì)導(dǎo)致同步任務(wù)報(bào)錯(cuò)這些都需要有應(yīng)對(duì)預(yù)案。哪怕你沒(méi)實(shí)際配過(guò)這些工具能按這個(gè)邏輯把答案組織完整筆試這題也能拿到大部分分?jǐn)?shù)。5.3 工具的坑面試官真正想問(wèn)的工具題的高級(jí)考法是直接給你一個(gè)報(bào)錯(cuò)場(chǎng)景問(wèn)你怎么排查。比如DataX同步任務(wù)一直報(bào)java.sql.SQLException: Data too long for column怎么處理這個(gè)問(wèn)題我在工作里真的遇到過(guò)。原因通常是源庫(kù)字符集和目標(biāo)庫(kù)字符集不一致或者目標(biāo)表字段長(zhǎng)度定義比源庫(kù)小。排查思路是打開(kāi)DataX日志找到具體是哪一列、哪一行的數(shù)據(jù)然后對(duì)比源表和目標(biāo)表的字段定義。再比如Dinky上提交Flink SQL作業(yè)狀態(tài)一直顯示RUNNING但數(shù)據(jù)不更新這個(gè)問(wèn)題的排查鏈路是先看TaskManager日志有沒(méi)有輸出再看Kafka消費(fèi)組的Lag是不是為0最后看Watermark有沒(méi)有推進(jìn)。如果Watermark不推進(jìn)說(shuō)明上游事件時(shí)間停滯要么是數(shù)據(jù)源本身沒(méi)有新數(shù)據(jù)要么是空閑數(shù)據(jù)源沒(méi)設(shè)withIdleness。能答出這個(gè)排查順序說(shuō)明你對(duì)實(shí)時(shí)計(jì)算是有實(shí)操經(jīng)驗(yàn)的。5.4 學(xué)習(xí)工具組件的高效路徑我的建議是不要一個(gè)個(gè)工具孤立地去學(xué)按一條主鏈路串起來(lái)學(xué)。我整理了一條復(fù)習(xí)主線校招生照著走覆蓋面會(huì)比零散刷題好得多數(shù)據(jù)采集Canal/Flink CDC、DataX、Flume 消息隊(duì)列Kafka重點(diǎn)分區(qū)、副本、消費(fèi)組、消息不丟不重 實(shí)時(shí)計(jì)算Flink重點(diǎn)窗口、狀態(tài)、檢查點(diǎn)、Watermark 離線計(jì)算Spark重點(diǎn)RDD/DataFrame、Shuffle、調(diào)優(yōu) 數(shù)倉(cāng)存儲(chǔ)Hive重點(diǎn)分區(qū)、分桶、ORC/Parquet、小文件 查詢引擎Presto/ClickHouse/Doris重點(diǎn)適用場(chǎng)景區(qū)別 調(diào)度DolphinScheduler/Azkaban重點(diǎn)任務(wù)依賴、失敗重試 開(kāi)發(fā)平臺(tái)Dinky重點(diǎn)Flink SQL開(kāi)發(fā)、作業(yè)提交每一個(gè)組件先搞清楚三件事它解決什么問(wèn)題、它上下游是什么、它最容易出問(wèn)題的點(diǎn)是什么。這三個(gè)問(wèn)題搞清楚了不管是筆試客觀題還是面試主觀題你都能有自己的判斷而不是死記硬背。6. 做題時(shí)的通用提分策略從會(huì)做到答得出彩6.1 大數(shù)據(jù)的題答案在權(quán)衡不在正確很多校招生做題有個(gè)習(xí)慣非黑即白必須選一個(gè)對(duì)的。但大數(shù)據(jù)開(kāi)發(fā)的筆試題幾乎沒(méi)有標(biāo)準(zhǔn)答案只有更合適的方案。我給你舉一個(gè)經(jīng)典例子。題目問(wèn)實(shí)時(shí)計(jì)算你選Flink還是Spark Streaming很多人的回答是Flink更先進(jìn)所以選Flink。但換個(gè)場(chǎng)景公司已有的技術(shù)棧是Spark團(tuán)隊(duì)對(duì)Spark更熟實(shí)時(shí)性要求是分鐘級(jí)而不是秒級(jí)數(shù)據(jù)量也沒(méi)有大到Flink才能扛住的水平。這時(shí)候Spark Streaming就是更務(wù)實(shí)的選擇。Flink和Spark Streaming的區(qū)別維度FlinkSpark Streaming計(jì)算模型真正的流式計(jì)算微批處理延遲毫秒級(jí)秒級(jí)狀態(tài)管理原生支持狀態(tài)大依賴外部存儲(chǔ)狀態(tài)能力弱精確一次語(yǔ)義內(nèi)置支持需要配合業(yè)務(wù)邏輯實(shí)現(xiàn)學(xué)習(xí)成本較高基于Spark生態(tài)熟悉你答題時(shí)應(yīng)該先說(shuō)我會(huì)根據(jù)場(chǎng)景選再把場(chǎng)景拆開(kāi)講延遲要求、狀態(tài)規(guī)模、團(tuán)隊(duì)技術(shù)棧、上下游生態(tài)。而不是一上來(lái)就宣布哪個(gè)好。能體現(xiàn)權(quán)衡思維的人分?jǐn)?shù)一定高。6.2 關(guān)鍵詞敏感度訓(xùn)練從題目里抓真實(shí)需求我這些年帶過(guò)不少新人發(fā)現(xiàn)一個(gè)共性做題時(shí)只看到題面看不到題面背后的業(yè)務(wù)需求。比如有一道題問(wèn)有一個(gè)訪問(wèn)日志表每天有幾十億條記錄需要查詢某個(gè)用戶在某個(gè)時(shí)間段內(nèi)的訪問(wèn)明細(xì)怎么優(yōu)化如果只看到JSON解析SQL查詢這些技術(shù)詞你就只會(huì)給出最簡(jiǎn)單的方案。但你把關(guān)鍵詞拆開(kāi)看幾十億條意味著要分區(qū)、分桶某個(gè)用戶意味著查詢條件高度選擇性強(qiáng)適合用分區(qū)裁剪謂詞下推某個(gè)時(shí)間段意味著時(shí)間字段應(yīng)該作為分區(qū)鍵明細(xì)查詢意味著需要支持點(diǎn)查和范圍查可以考慮用HBase或Druid或者用ClickHouse的跳數(shù)索引。你如果平時(shí)有意識(shí)地訓(xùn)練自己從題面關(guān)鍵詞反推業(yè)務(wù)場(chǎng)景這個(gè)能力碰到偏題怪題就不會(huì)慌。你還可以反向思考如果你是出題人你會(huì)在哪個(gè)環(huán)節(jié)埋業(yè)務(wù)陷阱6.3 答題的書面表達(dá)讓面試官一眼看到關(guān)鍵詞筆試通常有時(shí)間限制尤其是客觀題主觀題混合的卷子。主觀題答的時(shí)候我建議你用關(guān)鍵詞前置的寫法。比如題目問(wèn)請(qǐng)簡(jiǎn)述Flink的CheckPoint機(jī)制你不要上來(lái)就長(zhǎng)篇大論地講原理而是先寫CheckPoint是Flink保證故障恢復(fù)后狀態(tài)一致性的核心機(jī)制核心要素包括Barrier對(duì)齊、狀態(tài)快照、State Backend、恢復(fù)流程、端到端精確一次。然后再展開(kāi)講每個(gè)要素。面試官閱卷時(shí)第一眼掃到的就是這些關(guān)鍵詞你的答案在大批量卷子里就會(huì)顯得很懂。用這種方式答題還有一個(gè)額外好處即使你展開(kāi)部分寫得不太完整關(guān)鍵詞已經(jīng)幫你把基本分拿到手了。我當(dāng)年自己校招時(shí)也是用這個(gè)方法主觀題部分從來(lái)沒(méi)低于過(guò)80%的得分率。6.4 考前必須準(zhǔn)備的幾類萬(wàn)能素材大數(shù)據(jù)開(kāi)發(fā)筆試有幾類問(wèn)題出現(xiàn)的概率極高我建議考前就把這幾類素材準(zhǔn)備好說(shuō)清楚你做過(guò)的一個(gè)數(shù)據(jù)項(xiàng)目包含數(shù)據(jù)量、技術(shù)棧、處理鏈路、遇到的最大問(wèn)題、你怎么解決的、最后效果如何。這個(gè)準(zhǔn)備充分了能應(yīng)對(duì)一半以上的主觀題。說(shuō)清楚Spark和Flink的區(qū)別不只是計(jì)算模型還有狀態(tài)管理、精確一次、容錯(cuò)機(jī)制、適用場(chǎng)景。說(shuō)清楚Hive和數(shù)倉(cāng)的分層思想ODS、DWD、DWS、ADS每一層干什么為什么要這樣分。說(shuō)清楚一條數(shù)據(jù)從產(chǎn)生到報(bào)表展示的全過(guò)程哪一步會(huì)發(fā)生數(shù)據(jù)問(wèn)題哪一步最耗時(shí)哪一步最容易出瓶頸這四個(gè)素材準(zhǔn)備完你會(huì)發(fā)現(xiàn)筆試主觀題基本就是素材的排列組合。與其臨時(shí)抱佛腳刷一百道題不如先把這幾個(gè)核心故事打磨成自己的標(biāo)準(zhǔn)答案。7. 寫在最后一套真題之外的備考建議回到iHandy2019校招這套題。說(shuō)實(shí)話這類公司出的筆試題難度不在于題目本身有多深而在于題面很業(yè)務(wù)跟學(xué)校里教的算法操作系統(tǒng)數(shù)據(jù)庫(kù)完全是兩套話語(yǔ)體系。如果你還在用刷LeetCode和背操作系統(tǒng)八股的方式準(zhǔn)備大數(shù)據(jù)崗大概率會(huì)吃大虧。我給校招生的建議是準(zhǔn)備大數(shù)據(jù)開(kāi)發(fā)崗筆試先建認(rèn)知框架再填充細(xì)節(jié)。認(rèn)知框架就是我在前幾節(jié)反復(fù)強(qiáng)調(diào)的那條鏈路——采集、傳輸、存儲(chǔ)、計(jì)算、調(diào)度、應(yīng)用你要能閉著眼把這條鏈路畫出來(lái)并且標(biāo)出每一環(huán)的主流組件和核心問(wèn)題。細(xì)節(jié)填充就是把每個(gè)組件的關(guān)鍵原理、典型場(chǎng)景、常見(jiàn)故障想清楚。我自己當(dāng)年面試時(shí)吃過(guò)一個(gè)虧問(wèn)Kafka為什么快我只答了順序?qū)懘疟P但面試官緊接著問(wèn)順序?qū)憺槭裁幢入S機(jī)寫快那么多我楞住了。其實(shí)是機(jī)械硬盤尋道時(shí)間和操作系統(tǒng)頁(yè)緩存的問(wèn)題這個(gè)知識(shí)點(diǎn)我明明學(xué)過(guò)但在面試的壓力下沒(méi)串起來(lái)。從那以后我養(yǎng)成一個(gè)習(xí)慣**學(xué)每一個(gè)技術(shù)點(diǎn)都問(wèn)自己三個(gè)問(wèn)題——它在全鏈路里的位置是什么它的核心設(shè)計(jì)解決什么問(wèn)題如果它壞了會(huì)怎樣**這三個(gè)問(wèn)題串起來(lái)知識(shí)就不是孤島。最后再分享一個(gè)實(shí)戰(zhàn)小技巧。如果你拿到一套歷年真題先別急著做花半小時(shí)把每道題考察的知識(shí)點(diǎn)標(biāo)出來(lái)然后統(tǒng)計(jì)頻率。你會(huì)發(fā)現(xiàn)80%的分?jǐn)?shù)集中在20%的知識(shí)點(diǎn)上Spark算子與調(diào)優(yōu)、Flink狀態(tài)與容錯(cuò)、Kafka消息可靠性、Hive與數(shù)倉(cāng)建模、數(shù)據(jù)傾斜處理。把這20%知識(shí)點(diǎn)吃透剩下的20%即使答不全總分也不會(huì)差。這套方法不只在iHandy幾乎所有大數(shù)據(jù)開(kāi)發(fā)崗的筆試題都適用。希望這篇拆解能幫你少走一些彎路。數(shù)據(jù)開(kāi)發(fā)這一行入門靠基礎(chǔ)走得遠(yuǎn)靠的是對(duì)全鏈路的理解和解決問(wèn)題的能力。筆試只是第一關(guān)把每一次答題都當(dāng)成一次完整的工程思考你收獲的會(huì)遠(yuǎn)超一個(gè)offer。祝順利。