58同城大資料開發社招面經(附答案)
今天為大家分享一篇 58 同城大資料開發(流計算方向)社招的面經,附上答案。
面試方式通過專案來引出提問的知識點,主要考察面試人員對專案的理解能力以及背後涉及的原理。
面試時間:50 分鐘
面試方向:大資料開發(流計算方向)
面試工具:微信影片面
面試難度 ::star::star::star:
面試環節
1 面試官:請簡短的做個自我介紹。
面試官,您好!我叫 xxx , xxxx 年 x 月畢業於 xxx 學校,xx 學歷,目前就職於 xxx 公司 xxx 部門,職位為:大資料開發工程師,主要從事於 Flink 流計算元件、平臺的開發工作。
工作以來,我先後參加了 xxx 專案、xxx 專案以及 xxx 專案,積累了豐富的專案經驗,同時,這 x 個專案都得到了領導的一致好評。
我對流計算元件有著濃厚的興趣,工作之餘經常鑽研技術、例如:Flink 四大基石、Flink 核心應用提交流程、Flink 排程策略等。
入職 x 年,曾榮獲優秀員工,以上是我的自我介紹,請面試官提問。
2 面試官:你做的這些專案主要是資料開發呢還是平臺性質的?
主要面向平臺,由於組內是研究 Flink 元件的,基於這個元件設計的平臺,供公司多個部門使用。
3 面試官:那你介紹一下這三個專案,哪個是你最拿手的,並解決了哪些問題?
那我重點描述一下第三個專案,該平臺對標阿里雲的實時計算 Flink 平臺。XXX 是一個 一站式、高效能的大資料處理平臺,底層基於 Flink 實現,平臺提供多種核心功能,支援多種 source、sink 外掛,內建統一的元資料管理,支援 一鍵提交、應用管理、斷掉除錯、監控告警、Ranger 鑑權等多個核心模組。
我主要負責對該平臺的 Flink 版本升級、從原先的 Flink 1.11.0 升級到 1.14.0,同時對平臺進行架構重構及程式碼優化,並參與核心模組 應用管理 、Ranger 鑑權模組的開發工作。
主要解決了多部門提交 Flink 任務需要大量開關配置問題, 版本升級後的 SQL 語法校驗、應用提交報錯問題,以及 Ranger 鑑權問題。
4 面試官:應用提交都支援哪些方式?
支援 Flink SQL、Jar 包、畫布 3 種方式。
5 面試官:使用 Jar 包提交支援哪些模式?
目前支援 Standalone、yarn 、K8s 三種方式,然後 通過 Yarn 提交時 支援 per job 模式,session 模式( 專門少說了一種方式 )
6 面試官:Flink on yarn 在新版本新增了一種模式,你知道嗎? (果不其然,發問了)
知道,新增了 flink on yarn application 模式。該模式的最大特點是 原本在客戶端需要做的事全部被提交到了 jobManager 中進行,也就是說 main()方法在叢集中執行(入口點位於 ApplicationClusterEntryPoint ),客 戶端只需要負責發起部署請求即可。
7 面試官:Flink on yarn application 設計的優點在哪?
首先 yarn-per-job 和 yarn-session 模式下,客戶端都需要執行以下三步,即:
-
獲取作業所需的依賴項;
-
通過執行環境分析並取得邏輯計劃,即 StreamGraph→JobGraph;
-
將依賴項和 JobGraph 上傳到叢集中。
如下圖簡易版:

只有在這些都完成之後,才會通過 env.execute()方法 觸發 Flink 執行時真正地開始執行作業。
如果所有使用者都在 同一個客戶端
上提交作業,較大的依賴會消耗更多的頻寬,而較複雜的作業邏輯翻譯成 JobGraph 也需要吃掉更多的 CPU 和記憶體,客戶端的資源反而會成為瓶頸。
Application 模式。將原本需要在客戶端做的三件事都被轉移到了 JobManager 裡,客戶端只需要負責發起部署請求。大大減小了 客戶端 CPU 和記憶體的使用資源。簡易版原理圖如下:

8 面試官:平臺進行架構重構及程式碼優化,這塊是如何設計的?
開發初期,使用人過少,且合作部門只有一個,只採用單介面設計、後期多部門合作時,之前設計的架構會導致每個部門都需要單獨維護一個版本。
經過問題分析後,對之前的程式碼進行解構,其核心思想在於獨立每個業務場景的 Web 上下文,通過 WebInstall 介面實現,讓其他多部門實現其介面。
WebInstaller 裡面定義了 3 個方法,分別為 inin(),run(),close().
init()負責初始化工作、如配置檔案載入,資料庫初始化等。run()負責啟動,例如 Metric、Watchdog 等;close()負責 Web 服務關閉,會被作為關閉鉤子函式(ShutdownHook)註冊起來。
xxx 作為主類,會在執行時根據配置引數反射生成不同的 WebInstaller,從而實現在不同業務場景下執行其對應的 Web 服務,從根本上去掉了大量開關配置。
9 面試官:看你解決了 SQL 校驗問題,Flink SQL 提交流程包含哪幾步?
Flink sql 在被提交到叢集之前都需要先被轉換成 Transformations,然後編譯成 StreamGraph,通過優化生成 JobGraph.
在被轉為 Transformations 時主要涉及兩大階段:
-
SQL 語句到 Operation 的轉換,即 Parse 階段;
-
Operation 到 Transformations 的轉換,即 Translate 階段。
在 Parse 階段一共包含 parse、validate、rel、convert 四個部分。
在 Translate 階段 一共包含 translateToRel、optimize、translateToExecNodeGraph 和 translateToPlan 四個階段。
原理圖如下:

10 面試官:在 SQL 校驗環節做了哪些操作?
SQL 校驗環節主要是對經過 parser 解析出的 AST 進行有效性驗證,驗證的方面主要包括兩方面: 1 表名、欄位名、函式名是否正確,如在某個查詢的欄位在當前SQL位置上是否存在或有歧義 2 特定型別操作自身的合法性.
11 面試官:Ranger 鑑權模組是幹什麼的?
我們的 xxx 作為一個流計算平臺,提供給第三方時,要保證資料的安全性。
所以需要對使用者提交的 SQL 基於 ranger 資訊進行鑑權,確定其許可權。
實現步驟:
鑑權主要有三大模組
1 邏輯計劃解析:解析 xxx sql ,攔截執行計劃.
2 flink-ranger 外掛自研:將 flink sql 庫、表、欄位等操作資訊,轉換成 ranger 鑑權所需資訊,完成鑑權。
3 ranger 策略同步:將 ranger 配置策略,同步到自研外掛中。
具體的實現流程:
鑑權在 xxx 中主要分為 3個步驟:
1 使用者在平臺上 執行 sql ,通過 flink-planner 模組進行 sql 解析,並執行。
2 攔截 flink 原始碼中#executeOperation,獲取 sql 操作的具體細節。
3 將 sql 按照 DDL\DML\DQL 等方式,分別包裝為 ranger 鑑權資訊,完成鑑權。
12 面試官:看你介紹時提到平臺包含監控告警模組,是通過什麼進行監控的,主要監控哪些指標?
通過 Flink Metrics 對指標進行監控。使用 Flink 提供的主動方式 PrometheusPushGatewayReporter 方式 通過 prometheus + pushgateway + grafana 元件搭建 Yarn 提交模式進行視覺化監控
主要監控 (JM、TM、Slot、作業、運算元)等相關指標。以及叢集 CPU、記憶體、執行緒、JVM、網路等執行元件的指標。
13 面試官:Flink Metrics 提供了幾種監控指標型別?分別是哪些?
Flink Metrics 一共提供了四種監控指標:分別為 Counter、Gauge、Histogram、Meter。

-
Count 計數器統計一個指標的總量
-
Gauge:反映一個指標的瞬時值。比如要看現在 TaskManager 的 JVM heap 記憶體用了多少,就可以每次實時的暴露一個 Gauge,Gauge 當前的值就是 heap 使用的量。
-
Meter:平均值,用來記錄一個指標在某個時間段內的平均值。Flink 中的指標有 Task 運算元中的 numRecordsInPerSecond,記錄此 Task 或者運算元每秒接收的記錄數。
-
Histogram:直方圖,用於統計一些資料的分佈,比如說 Quantile、Mean、StdDev、Max、Min 等,其中最重要一個是統計運算元的延遲。此項指標會記錄資料處理的延遲資訊,對任務監控起到很重要的作用。
14 面試官:我看你簡歷中寫了對 全鏈路吞吐
、 全鏈路時延
、 吞吐時延
指標進行監控和調優,全鏈路時延是怎麼計算的?
全鏈路時延指的是 一條資料
進入 source 運算元到 資料預處理運算元
直到最後 一個運算元
輸出結果的 耗時
,即處理一條資料需要多長時間。 包含運算元內處理邏輯時間,運算元間資料傳遞時間,緩衝區內等待時間
。
全鏈路時延要使用 latency Marker 計算。latency Marker 是由 source 運算元根據當前本地時間生成的一個 marker ,並不參與各個運算元的邏輯計算,僅僅跟著資料往下游運算元流動,每到達一個運算元則算出當前本地時間戳並與 source 生成的時間戳相減,得到 source 運算元到當前運算元的耗時,當到達 sink 運算元或者說最後一個運算元時,算出當前本地時間戳與 source 運算元生成的時間戳相減,即得到全鏈路時延。原理圖如下:

15 面試官:全鏈路時延計算公式怎麼計算的?( 重點
)
計算公式:
avg(flink_taskmanager_job_latency_source_id_
operator_id _operator_subtask_index_latency{
source_id="cbc357ccb763df2852fee8c4fc7d55f2",
operator_id="c9c0ca46716e76f6b700eddf4366d243",quantile="0.999"})
16 面試官:怎麼實現對吞吐的監控的?比如說怎麼知道 source 端的吞吐量?
通過 Flink Metrics 的 Count 計數器,以及 Gauge 可以實現對 source
端吞吐量的監控
17 面試官:我們聊聊 Flink 的一些知識點,說一下 WaterMarker 機制
WaterMark 是用來解決資料延遲、資料亂序等問題。
水印就是一個時間戳(timestamp),Flink 可以給資料流新增水印
-
水印並不會影響原有 Eventtime 事件時間
-
當資料流新增水印後,會按照水印時間來觸發視窗計算,也就是說
-
設定水印時間,會比事件時間小几秒鐘,表示最大允許資料延遲達到多久
Flink 提供了常規的 定期水位線 以及 定製化的標點水位線 兩種生成水位線的方式供使用者選擇。
(1) 定期水位線:週期性的生成 watermark,系統會週期性的將 watermark 插入到流中。預設週期是 200 毫秒。
(2) 標點水位線:沒有時間週期規律,可打斷的生成 watermark, 每一次分配 Timestamp 都會呼叫生成方法。
18 面試官:結合 kafka 說一下,flink 如何實現 exactly once 語義的?
Flink 使用兩階段提交協議 預提交(Pre-commit)階段和 提交(Commit)階段 保證端到端嚴格一次。

(1)預提交階段
1、當 Checkpoint 啟動時,進入預提交階段,JobManager 向 Source Task 注入檢查點分界線(CheckpointBarrier),Source Task 將 CheckpointBarrier 插入資料流,向下遊廣播開啟本次快照,如下圖所示:

預處理階段:Checkpoint 啟動
2、Source 端:Flink Data Source 負責儲存 KafkaTopic 的 offset 偏移量,當 Checkpoint 成功時 Flink 負責提交這些寫入,否則就終止取消掉它們,當 Checkpoint 完成位移儲存,它會將 checkpoint barrier(檢查點分界線) 傳給下一個 Operator,然後每個運算元會對當前的狀態做個快照,儲存到狀態後端(State Backend)。
對於 Source 任務而言,就會把當前的 offset 作為狀態儲存起來。下次從 Checkpoint 恢復時,Source 任務可以重新提交偏移量,從上次儲存的位置開始重新消費資料,如下圖所示:

預處理階段:checkpoint barrier 傳遞 及 offset 儲存
3、Sink 端:從 Source 端開始,每個內部的 transformation 任務遇到 checkpoint barrier(檢查點分界線)時,都會把狀態存到 Checkpoint 裡。資料處理完畢到 Sink 端時, Sink 任務首先把資料寫入外部 Kafka ,這些資料都屬於預提交的事務(還不能被消費),此時的 Pre-commit 預提交階段下 Data Sink 在儲存狀態到狀態後端的同時還必須預提交它的外部事務,如下圖所示:

預處理階段:預提交到外部系統
(2)提交階段
4、當所有運算元任務的快照完成(所有建立的快照都被視為是 Checkpoint 的一部分),也就是這次的 Checkpoint 完成時, JobManager 會向所有任務發通知 ,確認這次 Checkpoint 完成,此時 Pre-commit 預提交階段才算完成。才正式到兩階段提交協議的第二個階段:commit 階段。該階段中 JobManager 會為應用中每個 Operator 發起 Checkpoint 已完成的回撥邏輯。
所有運算元 收到確認通知,就會正式提交之前的事務,Kafka 中未確認的資料就改為“已確認”,資料就真正可以被消費了。如下圖所示:

提交階段:資料精準被消費
19 面試官:Flink HBase 支援 Exactly once 語義嗎?
使用 hbase 的冪等性結合 at least Once(flink 中 state 能恢復,在兩次 checkpoint 間可能會有重複讀取資料的情況)實現精確一次性語義。
20 面試官:Flink HDFS 支援 Exactly once 語義嗎?
支援,Flink 中 sink 資料到 HDFS 可以通過 BucketingSink 來完成。
21 面試官:好,我們問一些 kafka 方面的問題,先簡單介紹一下 kafka的架構
Kafak 總體架構圖中包含多個概念:如下圖所示:

(1)ZooKeeper: Zookeeper
負責儲存 broker
叢集元資料,並對控制器進行選舉等操作。
(2)Producer:生產者負責建立訊息,將訊息傳送到 Broker。
(3)Broker: 一個獨立的 Kafka
伺服器被稱作 broker
,broker 負責接收來自生產者的訊息, 為訊息設定偏移量
,並將訊息儲存在磁碟。broker 為消費者提供服務,對讀取分割槽的請求作出響應,返回已經提交到磁碟上的訊息。
(4)Consumer:消費者負責從 Broker
訂閱並消費訊息。
(5)Consumer Group: Consumer Group
為消費者組,一個消費者組可以包含一個或多個 Consumer
。
使用 多分割槽 + 多消費者
方式可以極大 提高資料下游的處理速度
, 同一消費者組中的消費者不會重複消費訊息
,同樣的,不同消費組中的消費者消費訊息時互不影響。Kafka 就是通過消費者組的方式來實現訊息 P2P 模式和廣播模式。
(6)Topic:Kafka 中的訊息 以 Topic 為單位進行劃分 ,生產者將訊息傳送到特定的 Topic,而消費者負責訂閱 Topic 的訊息並進行消費。
(7)Partition:一個 Topic 可以細分為多個分割槽, 每個分割槽只屬於單個主題 。同一個主題下不同分割槽包含的訊息是不同的,分割槽在儲存層面可以看作一個可追加的 日誌(Log)檔案 ,訊息在被追加到分割槽日誌檔案的時候都會分配一個特定的 偏移量(offset) 。
(8)Offset:offset 是訊息在分割槽中的唯一標識, Kafka 通過它來保證訊息在分割槽內的順序性 ,不過 offset 並不跨越分割槽,也就是說, Kafka保證的是分割槽有序性而不是主題有序性 。
(9)Replication: 副本 ,是 Kafka 保證資料高可用的方式,Kafka 同一 Partition 的資料可以在多 Broker 上存在多個副本 ,通常只有 主副本對外提供讀寫服務 ,當主副本所在 broker 崩潰或發生網路異常,Kafka 會在 Controller 的管理下會重新選擇新的 Leader 副本對外提供讀寫服務。
(10)Record:實際寫入 Kafka 中並可以被讀取的訊息記錄。每個 record 包含了 key
、 value
和 timestamp
。
(11)Leader: 每個分割槽多個副本的 "主" leader,生產者傳送資料的物件,以及消費者消費資料的物件都是 leader。
(12)follower: 每個分割槽多個副本中的"從" follower,實時從 Leader 中同步資料,保持和 leader 資料的同步。Leader 發生故障時,某個 follow 會成為新的 leader。
22 面試官:kafka 如何做到高吞吐量和效能的?
kafka 在寫方面通過頁快取技術、磁碟順序寫 實現寫資料的超高效能,在讀方面通過 零拷貝實現高吞吐和高效能的。
1、頁快取技術
Kafka
是基於 作業系統
的 頁快取
來實現檔案寫入的。
作業系統本身有一層快取,叫做 page cache ,是在 記憶體裡的快取 ,我們也可以稱之為 os cache ,意思就是作業系統自己管理的快取。
Kafka 在寫入磁碟檔案的時候,可以直接寫入這個 os cache 裡,也就是僅僅寫入記憶體中,接下來由作業系統自己決定什麼時候把 os cache 裡的資料真的刷入磁碟檔案中。通過這一個步驟,就可以將磁碟檔案 寫效能 提升很多了,因為其實這裡相當於是在寫記憶體,不是在寫磁碟,原理圖如下:

2、磁碟順序寫
另一個主要功能是 kafka 寫資料的時候,是以磁碟順序寫的方式來寫的。也就是說, 僅僅將資料追加到檔案的末尾
, 不是在檔案的隨機位置來修改資料
。
普通的機械磁碟如果你要是隨機寫的話,確實性能極差,也就是隨便找到檔案的某個位置來寫資料。
但是如果你是 追加檔案末尾 按照順序的方式來寫資料的話,那麼這種磁碟順序寫的效能基本上可以跟寫記憶體的效能相差無幾。
基於上面兩點,kafka 就實現了寫入資料的超高效能。
3、零拷貝
從 Kafka 裡消費資料的時候實際上就是要從 kafka 的 磁碟檔案 裡 讀取某條資料 然後傳送給下游的消費者,如下圖所示。

那麼這裡如果頻繁的從磁碟讀資料然後發給消費者,會增加兩次沒必要的拷貝,如下圖:

一次是從作業系統的 cache 裡拷貝到應用程序的快取裡,接著又從應用程式快取裡拷貝回作業系統的 Socket 快取裡。
而且為了進行這兩次拷貝,中間還發生了好幾次上下文切換,一會兒是應用程式在執行,一會兒上下文切換到作業系統來執行。所以這種方式來讀取資料是比較消耗效能的。
Kafka 為了解決這個問題,在讀資料的時候是引入零拷貝技術。
也就是說,直接讓作業系統的 cache 中的資料傳送到 網絡卡 後傳輸給下游的消費者, 中間跳過了兩次拷貝資料的步驟 ,Socket 快取中僅僅會拷貝一個描述符過去,不會拷貝資料到 Socket 快取,如下圖所示:

通過 零拷貝技術 ,就不需要把 os cache 裡的資料拷貝到應用快取,再從應用快取拷貝到 Socket 快取了,兩次拷貝都省略了,所以叫做零拷貝。
對 Socket 快取僅僅就是拷貝資料的描述符過去,然後資料就直接從 os cache 中傳送到網絡卡上去了, 這個過程大大的提升了資料消費時讀取檔案資料的效能 。
Kafka 從磁碟讀資料的時候,會先看看 os cache 記憶體中是否有,如果有的話,其實讀資料都是直接讀記憶體的。
kafka 叢集經過良好的調優,資料直接寫入 os cache 中,然後讀資料的時候也是從 os cache 中讀。相當於 Kafka 完全基於記憶體提供資料的寫和讀了,所以這個整體效能會極其的高。
23 面試官:說一下 kafka 的 ISR 機制?
在分割槽中,所有副本統稱為 AR ,Leader 維護了一個動態的 in-sync replica(ISR), ISR 是指與 leader 副本保持同步狀態的副本集合
。當然 leader 副本本身也是這個集合中的一員
。
當 ISR 中的 follower 完成資料同步之後, leader
就會給 follower 傳送 ack
,如果其中一個 follower 長時間未向 leader 同步資料,該 follower 將會被踢出 ISR 集合,該時間閾值由 replica.log.time.max.ms
引數設定。當 leader 發生故障後,就會從 ISR 集合中重新選舉出新的 leader。
24 面試官:如果資料量過大,kafka 會怎麼處理?
首先,資料量過大,會造成 1 broker 壓力大,2 磁碟壓力大,3 消費者壓力大,4 log 變大.
這時候需要做的就是,1.擴充 broker,2.掛載多個磁碟,3. 增加消費者,增大消費能力,4 擴分割槽提升並行能力,5 增大訊息批次大小,減少網路請求壓力
25 面試官:問一些 java 方面的知識點吧,JVM 記憶體劃分瞭解嗎?
Java 虛擬機器在執行 Java 程式的過程中會把它在主存中管理的記憶體部分劃分成5個區域:
1.程式計數器,2.Java 虛擬機器棧,3.本地方法棧、4.方法區、5.Java 堆。
其中 程式計數器,Java 虛擬機器棧,本地方法棧執行緒私有,方法區、Java 堆執行緒共享。物件一般在堆中生成,垃圾回收也在這裡發生。
26 說一個演算法的實現思路吧。快速排序的實現思路可以簡單說一下嗎?
快速排序的基本思想: 挖坑填數+分治法 。
它的基本思想是:通過一趟 排序將要排序的資料分割成獨立的兩部分 ,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。
快速排序使用分治策略來把一個序列(list)分為兩個子序列(sub-lists)。步驟為:
-
從數列中挑出一個元素,稱為”基準”(pivot)。
-
重新排序數列,所有比基準值小的元素擺放在基準前面,所有比基準值大的元素擺在基準後面(相同的數可以到任一邊)。在這個分割槽結束之後,該基準就處於數列的中間位置。這個稱為分割槽(partition)操作。
-
遞迴地(recursively)把小於基準值元素的子數列和大於基準值元素的子數列排序。
遞迴到最底部時,數列的大小是零或一,也就是已經排序好了。這個演算法一定會結束,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。
時間複雜度:O(nlog2n)
27 面試官:好的,我這邊暫時就這麼多問題啦,你有什麼想問的嗎?
1 部門主要工作,2 近 1-2 年的規劃,3 多久會有下一面通知。
歡迎新增我的微信:拉你進大資料招聘求職群
- 去位元組了 ...
- 58同城大資料開發社招面經(附答案)
- 2022年首發|大資料專家級技能模型與學習指南
- Apache Spark原始碼解析之Maven構建
- Redis 原理 知識點總結 面試必備
- 一文帶你掌握 ElasticSearch 原理和技術
- JDK ThreadPoolExecutor核心原理與實踐
- Hive 核心知識點靈魂 16 問
- 萬字長文帶你入門 Hadoop
- kafka用了兩年,踩了好多坑,總結一下
- 阿里開源的11個神級專案
- Flink面試乾貨總結(原始碼)
- 深入理解Flink Kafka source
- HBase 效能調優指南
- Spark面試八股文(上萬字面試必備寶典)
- Spark面試乾貨總結
- 大資料必須要學會的資源排程平臺:YARN!
- 3天,我把 Flink 叢集啟動、抽象提交原始碼擼乾淨了!
- Flink 1.14.0 全新的 Kafka Connector
- 一文了解 Data Lakehouse 的演變