58同城大資料開發社招面經(附答案)

語言: CN / TW / HK
今天為大家分享一篇 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 模式下,客戶端都需要執行以下三步,即:

  1. 獲取作業所需的依賴項;

  2. 通過執行環境分析並取得邏輯計劃,即 StreamGraph→JobGraph;

  3. 將依賴項和 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 時主要涉及兩大階段:

  1. SQL 語句到 Operation 的轉換,即 Parse 階段;

  2. 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。

  1. Count 計數器統計一個指標的總量

  2. Gauge:反映一個指標的瞬時值。比如要看現在 TaskManager 的 JVM heap 記憶體用了多少,就可以每次實時的暴露一個 Gauge,Gauge 當前的值就是 heap 使用的量。

  3. Meter:平均值,用來記錄一個指標在某個時間段內的平均值。Flink 中的指標有 Task 運算元中的 numRecordsInPerSecond,記錄此 Task 或者運算元每秒接收的記錄數。

  4. 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 包含了 keyvaluetimestamp

(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)。步驟為:

  1. 從數列中挑出一個元素,稱為”基準”(pivot)。

  2. 重新排序數列,所有比基準值小的元素擺放在基準前面,所有比基準值大的元素擺在基準後面(相同的數可以到任一邊)。在這個分割槽結束之後,該基準就處於數列的中間位置。這個稱為分割槽(partition)操作。

  3. 遞迴地(recursively)把小於基準值元素的子數列和大於基準值元素的子數列排序。

遞迴到最底部時,數列的大小是零或一,也就是已經排序好了。這個演算法一定會結束,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。

時間複雜度:O(nlog2n)

27 面試官:好的,我這邊暫時就這麼多問題啦,你有什麼想問的嗎?

1 部門主要工作,2 近 1-2 年的規劃,3 多久會有下一面通知。

歡迎新增我的微信:拉你進大資料招聘求職群