大數(shù)據(jù)面經(jīng)吐血總結(jié)【阿里提問+答案解析】

1  自我介紹
控制在4分半以內(nèi),不超過5分鐘

(1)個人基本信息
(2)工作履歷
     工作時間、公司名稱、任職崗位、主要工作內(nèi)容、工作業(yè)績、離職原因
(3)深度溝通(也叫壓力面試)
     刨根問底下沉式追問(注意是下沉式,而不是發(fā)散式的)
     基本技巧:往自己熟悉的方向說
2  你自己搭過大數(shù)據(jù)集群嗎?那你說說搭建hadoop集群的3個xml文件
core-site.xml

hdfs-site.xml

mapred-site.xml
心想這簡單,趕緊將3個xml說出來,并簡單說了下里面都包括啥

3  正常的hadoop集群工作都會啟動哪些進(jìn)程?
NameNode

DataNode

Secondary NameNode

4  他們的作用分別是什么?
NameNode:主節(jié)點(diǎn),負(fù)責(zé)維護(hù)整個Hdfs文件系統(tǒng)的目錄樹,以及每個文件所對應(yīng)的block塊信息(元數(shù)據(jù))。

DataNode:從節(jié)點(diǎn),負(fù)責(zé)存儲具體的文件數(shù)據(jù),并且每個block可以在多個DataNode上存儲多個副本。

Secondary NameNode:相當(dāng)于一個備用的NameNode, 當(dāng)NameNode死機(jī)之后,可以將Secondary NameNode的數(shù)據(jù)備份到NameNode上面 ,但不能備份完整數(shù)據(jù),它有兩大功能,1 鏡像備份,2 日志與鏡像定期合并。

5  你能詳細(xì)介紹一下SecondaryNode 的具體作用嗎?
當(dāng)然可以,這個問題我可是仔細(xì)研究過,哈哈

Secondary NameNode會經(jīng)常向NameNode發(fā)送請求,是否滿足check。

當(dāng)條件滿足時,Secondary NameNode將進(jìn)行CheckPoint  。

這時NameNode 滾動當(dāng)前正在寫的edits,將剛剛滾動掉的和之前edits文件進(jìn)行合并。Secondary NameNode下載edis文件,然后將edits文件和自身保存的fsimage文件在內(nèi)存中進(jìn)行合并,然后寫入磁盤并上傳新的fsimage到nameNode,這時NameNode將舊的fsimage用新的替換掉。

6  看來你掌握的還不錯啊,HDFS的塊默認(rèn)是保存幾份?一個塊多大?
默認(rèn)保存是3份,一個塊是128M。

7  之前的64M 是從哪個版本變換的?
hadoop 1.0  默認(rèn)是64M, hadoop 2.0 由64M 改為128M

8  那假設(shè)現(xiàn)在是128M,那我在工作中想把它調(diào)為256M,那我需要調(diào)整什么,才能改變塊的大?。?br>主要是磁盤的存儲決定 塊的大小,塊組成的文件的大小取決于磁盤的傳輸速率,調(diào)整磁盤,可以改變塊的大小。

9  Hdfs的讀寫過程你了解嗎?簡單講講?
那我就說說寫過程吧(靈活發(fā)揮)

1、客戶端跟NameNode 通信,請求上傳文件,NameNode檢查文件,父目錄是否存在,并向客戶端返回是否可以上傳文件

2、客戶端請求第一個block塊該上傳到哪個DataNode服務(wù)器上,NameNode查詢從節(jié)點(diǎn)之后,返回對應(yīng)的DataNode 服務(wù)器A,B,C等。

3、客戶端請求NameNode服務(wù)器,采取就近原則,選擇A服務(wù)器上傳數(shù)據(jù)(本質(zhì)上是個RPC調(diào)用,建立PipeLine),A收到

請求后,A調(diào)B,B調(diào)C,將每個pipline建立連接,然后逐級返回給客戶端

4、客戶端開始往A上傳第一個block,以Package為單位,A收到一個Package,就會傳給B,B傳給C,A每傳一個package就會放入一個應(yīng)答隊列,等待應(yīng)答。

5、當(dāng)?shù)谝粋€block傳輸完成后,客戶端再次請求NameNode上傳第二個block。

10  挺好,那你說一下MapReduce的工作原理?
1、客戶端啟動一個job,然后向JobTracker請求一個jobID

2、 然后將運(yùn)行所需要的資源文件上傳到HDFS上,包括MapReduce程序打包的jar包,配置文件,以及計算的輸入劃分信息等

3、 這些文件全部存儲在JobTracker專門創(chuàng)建的JobID文件夾中(jar文件會有10個副本,輸入劃分信息對應(yīng)著JobTracker應(yīng)該啟動多少個Map任務(wù))

4、JobTracker將這些資源文件放入作業(yè)隊列中,調(diào)度器根據(jù)調(diào)度算法對作業(yè)文件進(jìn)行調(diào)度,根據(jù)輸入劃分信息劃分Map任務(wù)

并將map任務(wù)分配給TaskTracker執(zhí)行。

5、TaskTracker每隔一段時間發(fā)送給JobTracker一個心跳,告訴它自己的運(yùn)行情況,這個心跳中包含map任務(wù)完成的進(jìn)度等。

6、當(dāng)最后一個任務(wù)完成后,JobTracker會將該任務(wù)設(shè)為成功,返回給客戶端??蛻舳说玫浇Y(jié)果,得知任務(wù)完成便顯示消息給用戶。

11  你在具體講一下map中的一些步驟,例如partition,sort,combiner,shuffle等等。
好的,sort 主要是排序,combiner是合并,partition是分片等。

首先Mapper根據(jù)文件進(jìn)行分區(qū),sort將Mapper產(chǎn)生的結(jié)果按照key進(jìn)行排序,combiner將key相同的記錄進(jìn)行合并,partition是把數(shù)據(jù)均衡的分配個Reducer. shuffle是Mapper將結(jié)果傳給Reduce,在這期間容易發(fā)生數(shù)據(jù)傾斜等。

12  那這個數(shù)據(jù)傾斜一般是在Mapper端發(fā)生的還是Reduce中發(fā)生的?
Mapper將數(shù)據(jù)處理完傳給Reduce,當(dāng)Reduce進(jìn)行處理時,因為一部分key的數(shù)據(jù)量過大,導(dǎo)致其他分區(qū)已經(jīng)執(zhí)行完成而數(shù)據(jù)量過大的key執(zhí)行時間過長,所以數(shù)據(jù)傾斜是發(fā)生在Reduce端的。

13  對,那發(fā)生數(shù)據(jù)傾斜是因為這個key分布不均勻,那你會怎么優(yōu)化呢?
因為本科期間研究的課題就是關(guān)于Spark的并行大數(shù)據(jù)清洗,所以對MapReduce和Spark發(fā)生數(shù)據(jù)傾斜的過程和解決方法比較熟悉,

可以在Mapper期間將大數(shù)據(jù)量相同的key進(jìn)行分散,通過添加N以內(nèi)的隨機(jī)數(shù)前綴,對數(shù)據(jù)較多的Key進(jìn)行子擴(kuò)展,先進(jìn)行局部操作,再去除隨機(jī)數(shù)之后進(jìn)行聚合操作,避免在進(jìn)行Shuffle操作時出現(xiàn)數(shù)據(jù)傾斜問題。

14  那Mapper端進(jìn)行combiner之后,除了速度會提升,那從Mapper端到Reduce端的數(shù)據(jù)量會怎么變?
數(shù)據(jù)量會減少,因為combiner之后,會將相同的key進(jìn)行一次聚合,數(shù)據(jù)量會在這時候減少一部分

15  map 輸出的數(shù)據(jù)如何超出他的那個小文件內(nèi)存之后,那他是落地到磁盤還是落地到HDFS中?
落地到磁盤中,因為map,reduce操作,就是一次次的I/O請求

16  Map到Reduce默認(rèn)的分區(qū)機(jī)制是什么?
這個是根據(jù)那個hash進(jìn)行計算   對map中的key做hash,對reduce個數(shù)取模

17  hadoop的調(diào)優(yōu)主要針對配置文件的調(diào)優(yōu)你知道哪幾種?
思考了一下

1、因為MapReduce運(yùn)算時是在磁盤中進(jìn)行的,所以 通過修改磁盤I/O,也就是設(shè)置和的預(yù)讀緩沖區(qū)大小

來提高h(yuǎn)adoop里面大文件順序讀的性能。以此來提高I/O性能。

2、通過修改三個配置文件的參數(shù)如 core-site.xml,mapred-site.xml,hdfs-site.xml等

例如 修改core 文件里面的buffer.size,來修改讀寫緩沖區(qū)的大小,還有hdfs文件里面的block.size修改塊的大小等都可以進(jìn)行調(diào)優(yōu)

18  好的,給你出個題,現(xiàn)在有1G的數(shù)據(jù)文件,里面有四個字段,分別是id,name,age,class,然后要按照class來分組,
id來排序,口述一下MapReduce的過程是怎么實現(xiàn)的?這里面會有幾個map?思考了一下

1、首先1G文件,那默認(rèn)一個塊是128M,所以可以分為8個塊,對應(yīng)的就是8個Mapper

2、然后定義一個對象,將四個屬性封裝到對象中,實現(xiàn)序列化和反序列化

3、定義一個類繼承partitioner類,調(diào)用對象中的class屬性設(shè)置分組,

4、在map端對文件進(jìn)行讀取,然后通過Split來進(jìn)行分割,調(diào)用對象的id作為key,然后進(jìn)行局部sort排序,在combiner局部聚合后通過reduce來進(jìn)行整體聚合。

說完之后感覺對著吧,果然,聽見面試官說嗯嗯,好。覺得差不多對啦

19  嗯嗯,好,說說yarn吧,它有什么優(yōu)勢,能解決什么問題?
yarn集群主要分為主節(jié)點(diǎn)ResourceManage,從節(jié)點(diǎn) NodeManage  ResourceManage負(fù)責(zé)資源的分配,將集群的資源分配給各個應(yīng)用使用,資源分配的基本單元是Container,NodeManage則是一個計算節(jié)點(diǎn)的管理者,負(fù)責(zé)啟動應(yīng)用的所需的Conbiner,并對內(nèi)部資源進(jìn)行監(jiān)控等。yarn一般和mapreduce進(jìn)行結(jié)合,主要是對MapReduce中的資源計算進(jìn)行維護(hù)等。

答完之后,心想別問yarn吧,這塊看得不是很深,哈哈,果然,面試官問了一個問題后就跳過了

20  說說Spark吧,Spark為啥比Mapreduce運(yùn)行塊,原因都有哪些?
1、spark是基于內(nèi)存計算,mapreduce是基于磁盤運(yùn)算,所以速度快

2、spark擁有高效的調(diào)度算法,是基于DAG,形成一系列的有向無環(huán)圖

3、spark 是通過RDD算子來運(yùn)算的,它擁有兩種操作,一種轉(zhuǎn)換操作,一種動作操作,可以將先運(yùn)算的結(jié)果存儲在內(nèi)存中,隨后在計算出來

4、spark 還擁有容錯機(jī)制Linage

21  什么是RDD?
RDD就是彈性分布式數(shù)據(jù)集,可以理解為一種數(shù)據(jù)結(jié)構(gòu),擁有多種不同的RDD算子






22  你都知道哪些RDD算子?
比如轉(zhuǎn)換操作,有map().fliter() flatMap(),distinct()等  動作操作  有 collect ,reduce 等

23  你知道reduceBykey 和groupBykey有啥區(qū)別嗎?
reduceByKey會在結(jié)果發(fā)送至reducer之前會對每個mapper在本地進(jìn)行merge,

有點(diǎn)類似于在MapReduce中的combiner。這樣做的好處在于,在map端進(jìn)行一次reduce之后,數(shù)據(jù)量會大幅度減小, 從而減小傳輸,保證reduce端能夠更快的進(jìn)行結(jié)果計算。groupByKey會對每一個RDD中的value值進(jìn)行聚合形成一個序列(Iterator),此操作發(fā)生在reduce端, 所以勢必會將所有的數(shù)據(jù)通過網(wǎng)絡(luò)進(jìn)行傳輸,造成不必要的浪費(fèi)。同時如果數(shù)據(jù)量十分大, 可能還會造成OutOfMemoryError。

24  現(xiàn)在有一個業(yè)務(wù),當(dāng)SparkStreaming在消費(fèi)kafka里面的數(shù)據(jù),然后消費(fèi)了一段時間之后,程序掛了,當(dāng)下一次程序啟動時如何保證SparkStraming能繼續(xù)消費(fèi)kafka之前的位置?
聽到這個問題時,我就偷笑啦,幸虧上次科大訊飛問過我,我就好好看了一下可以依靠checkPoint機(jī)制來保證,每次SparkStreaming消費(fèi)kafka數(shù)據(jù)后,將消費(fèi)的kafka offsets更新到checkpoint,當(dāng)程序掛機(jī)或升級時,就可以用過讀取checkpoint 的記錄來接著上次的位置進(jìn)行讀取,實現(xiàn)數(shù)據(jù)的零丟失。

25  除了這種方式還有什么方式?
還可以在sparkStreaming中另外啟動一個預(yù)寫日志,這將同步保存所有收到的kafka數(shù)據(jù)導(dǎo)入hdfs中,以便發(fā)生故障時,恢復(fù)到上次的位置和之前的數(shù)據(jù)。

26  你說說Spark的廣播變量?
聽到這個問題后,一臉懵逼,不會拉。。我都猜想 面試官肯定在想,小樣,我還難不倒你拉。。。。然后我就讓面試官給我講了一下。。Spark中因為算子中的真正邏輯是發(fā)送到Executor中去運(yùn)行的,所以當(dāng)Executor中需要引用外部變量時,需要使用廣播變量。廣播變量只能在Driver端定義,不能在Executor端定義,在Driver端可以修改廣播變量的值,在Executor端無法修改廣播變量的值

27  那你知道累加器嗎?
之前看過一點(diǎn),累機(jī)器相當(dāng)于統(tǒng)籌大變量,常用于計數(shù),統(tǒng)計。累加器常常被作為rdd的map filter操作的副產(chǎn)品等。

28  你說說spark中 job,stage,task,分別代表什么?
Job簡單講就是提交給spark的任務(wù)。Stage是每一個job處理過程要分為的幾個階段。

Task是每一個job處理過程要分幾為幾次任務(wù)。Task是任務(wù)運(yùn)行的最小單位。最終是要以task為單位運(yùn)行在executor中。

29  嗯嗯 好,說說Spark的工作機(jī)制?
我去,咋問的都是大問題啊,幸虧之前復(fù)習(xí)過。。

用戶在客戶端提交job作業(yè)后,會由driver運(yùn)行main方法并創(chuàng)建SparkContext上下文。執(zhí)行RDD算子,形成DAG圖,然后將DAG圖交給DAGScheduler來處理。DAGScheduler按照RDD之間的依賴關(guān)系劃分stage,輸入task Scheduler,task Scheduler會將stage劃分為task set分發(fā)到各個節(jié)點(diǎn)的executer中執(zhí)行,executor以多線程的方式執(zhí)行,每個線程負(fù)責(zé)一個任務(wù),任務(wù)結(jié)束后,根據(jù)不同類型的任務(wù)返回不同的結(jié)果。

30  你了解zookeeper嗎?
zookeeper 是一個分布式協(xié)調(diào)服務(wù),zookeeper集群包括 leader 和 follow

31  說說zookeeper的選舉過程,比如現(xiàn)在有五臺機(jī)器,ABCDE依次啟動起來,那么哪臺是leader?
記得不太清楚了。。就大概說了一下

1.首先更新logicalclock并提議自己為leader并廣播出去

2.進(jìn)入本輪投票的循環(huán)

3.從recvqueue隊列中獲取一個投票信息,如果為空則檢查是否要重發(fā)自己的投票或者重連,否則

判斷投票信息中的選舉狀態(tài):就回答到這,后來下來百度了一下。。。

32  hive了解嗎?
Hive是基于Hadoop的一個數(shù)據(jù)倉庫工具,可以將結(jié)構(gòu)化的數(shù)據(jù)文件映射為一張數(shù)據(jù)庫表,并提供類SQL查詢功能

33  說說內(nèi)部表和外部表的區(qū)別?
內(nèi)部表的數(shù)據(jù)是由Hive自身管理的,外部表的數(shù)據(jù)是由HDFS管理的;

刪除內(nèi)部表會刪除元數(shù)據(jù)和存儲的數(shù)據(jù);刪除外部表只刪除元數(shù)據(jù)不刪除存儲的數(shù)據(jù)

34  你知道UDF嗎?
UDF就是Hive提供的內(nèi)置函數(shù)無法滿足業(yè)務(wù)處理需要時,可以考慮使用用戶自定義函數(shù)。

35  一張大表,一張小表,你寫join in時,哪個表放左邊,哪個表放右邊?
小表放前,大表放后,左查詢,根據(jù)小表為主進(jìn)行查詢。

36  問一下kafka的問題吧,kafka是怎么進(jìn)行數(shù)據(jù)備份的?
哇,面試官 你是要把大數(shù)據(jù)里面的每個組件分別問一下,。。。。深呼一口氣,思考了一下 然后巴拉巴拉

備份機(jī)制是Kafka0.8版本之后出的,一個備份數(shù)量為n的集群允許n-1個節(jié)點(diǎn)失敗。在所有備份節(jié)點(diǎn)中,

有一個節(jié)點(diǎn)作為lead節(jié)點(diǎn),這個節(jié)點(diǎn)保存了其它備份節(jié)點(diǎn)列表,并維持各個備份間的狀態(tài)同步。

37  消費(fèi)者是從leader中拿數(shù)據(jù),還是從follow中拿數(shù)據(jù)?
。。。不太會,備份機(jī)制這塊沒咋深入了解過。

kafka是由follower周期性或者嘗試去pull(拉)過來(其實這個過程與consumer消費(fèi)過程非常相似),

寫是都往leader上寫,但是讀并不是任意flower上讀都行,讀也只在leader上讀,flower只是數(shù)據(jù)的一個備份,

保證leader被掛掉后頂上來,并不往外提供服務(wù)。

38  那換個問題吧。說說kafka的ISR機(jī)制?
kafka 為了保證數(shù)據(jù)的一致性使用了isr 機(jī)制,

leader會維護(hù)一個與其基本保持同步的Replica列表,該列表稱為ISR(in-sync Replica),每個Partition都會有一個ISR,
而且是由leader動態(tài)維護(hù)

如果一個flower比一個leader落后太多,或者超過一定時間未發(fā)起數(shù)據(jù)復(fù)制請求,則leader將其從ISR中移除

當(dāng)ISR中所有Replica都向Leader發(fā)送ACK時,leader才commit

39  kafka如何保證數(shù)據(jù)的不重復(fù)和不丟失?
答案上面已經(jīng)回到了,面試官又問一遍。。可能是看我kafka這塊了解不是很深入。想再虐虐我。。。

40  kafka里面存的數(shù)據(jù)格式都是什么樣的?
topic主題,然后主題進(jìn)行分區(qū)  topic 分為partition , partition里面包含Message。

41  kafka中存的一個是數(shù)據(jù)文件,一個是索引文件,說說這個?
。。。。。不太會。。。哇,kafka被虐慘啦

42  kafka 是如何清理過期數(shù)據(jù)的?
kafka的日志實際上是以日志的方式默認(rèn)保存在/kafka-logs文件夾中的,默認(rèn)7天清理機(jī)制,

日志的真正清理時間。當(dāng)刪除的條件滿足以后,日志將被“刪除”,但是這里的刪除其實只是將 該日志進(jìn)行了“delete”標(biāo)注,文件只是無法被索引到了而已。但是文件本身,仍然是存在的,只有當(dāng)過了log.segment.delete.delay.ms 這個時間以后,文件才會被真正的從文件系統(tǒng)中刪除。

43  一條message中包含哪些信息?
包含 header,body

一個Kafka的Message由一個固定長度的header和一個變長的消息體body組成。

header部分由一個字節(jié)的magic(文件格式)和四個字節(jié)的CRC32(用于判斷body消息體是否正常)構(gòu)成。

當(dāng)magic的值為1的時候,會在magic和crc32之間多一個字節(jié)的數(shù)據(jù):attributes(保存一些相關(guān)屬性,比如是否壓縮、

壓縮格式等等);

如果magic的值為0,那么不存在attributes屬性body是由N個字節(jié)構(gòu)成的一個消息體,包含了具體的key/value消息

44  嗯,行,你知道m(xù)ysql的最左原則嗎?
終于把kafka過去啦。。心累

最左原則:顧名思義,就是最左優(yōu)先,比如現(xiàn)在有一張表,里面建了三個字段ABC,對A進(jìn)行主鍵,BC建立索引,就相當(dāng)于創(chuàng)建了多個索引,A索引,(A,B)組合索引,(A,B,C)組合索引,那查詢時,會根據(jù)查詢最頻繁的 放到最左邊。

嗯 好,我的問題問完了,讓我同事問問你。

已經(jīng)問了40分鐘純問題啦,,再換個面試官,好的,可以


作者:教你學(xué)懂大數(shù)據(jù)

歡迎關(guān)注微信公眾號 :教你學(xué)懂大數(shù)據(jù)