1. 程式人生 > 其它 >大資料面試吹牛草稿V2.0

大資料面試吹牛草稿V2.0

面試吹牛之前先打個草稿!

各位面試官好!

  1. 我叫 xxx,畢業於 xxx,之前在 xxx 公司待了 1 年多,期間⼀直從事的是 IT 行業,剛開始的時候做的是 Java 開發後來轉崗到大資料方向做大資料開發; 剛轉行到大資料開發的時候開始比較困難的,大資料並不像 Java 那樣⼀套框架基本可以搞定所有的問題,而是不同的業務對於同⼀個問題有多種解決方案。
  1. 我叫 xxx,畢業至今就職於 xx 公司,職位是數倉開發。
    參加工作以來,我先後參與籌備大資料伺服器購買以及從 0 到 1 的搭建,離線數倉專案組,實時數倉專案組。這三個專案都得到了老闆們的一致好評,大大增加了業務方需要客戶資料的效率,能更快的做出實時決策。
    我對大資料各框架有濃厚的興趣,工作之餘經常鑽研技術,例如 flink 的水位線,雙流 join 等,對業務需求分析的比較透徹。
    工作三年,我已經連續兩年被評為優秀員工,我覺得這足以說明我技術紮實,對待工作嚴謹,好學,當然也離不開原公司幫助過我的師傅們。
  1. 我叫 xxx,畢業於 xxx,自己大學期間學了 C++就喜歡上了程式設計,然後大學期間利用業餘時間學習了 JAVA。大四的時候又接觸到了大資料,又對大資料產生興趣,學校也開了大資料相關的專業,於是就在晚上找各種相關資料,在 B 站上搜一些比較好的大資料視訊,把相關視訊學習鑽研了一遍。20 年畢業的時候,也從事的大資料行業的工作,參與了大資料架構的搭建,以及數倉的建模等相關的工作。又利用業餘時間,進行補充知識,不斷的提高自己。至於以後,還是會不斷的學習來提高自己對大資料的開發能力,提高自己的業務水準。
  1. 我叫 xxx,畢業於 xxx。之前 2 年多的時間裡一直從事大資料開發工作。
    剛開始是在平臺崗,主要負責資料平臺的搭建以及維持整個框架的正常執行,從購買伺服器,包括框架版本選型,以及伺服器臺數定製,這些都是從 0 到 1 搭建的;在平臺崗工作了差不多半年時間,由於這段期間表現比較突出,公司想成立數倉組,就讓我負責籌建搭建數倉的工作,我從數倉建模開始逐漸搭建元資料管理,資料質量監控,許可權管理,指標分析,之後就一直數倉崗的工作;直到一年前,公司老大決定要做實時這塊,要統計一個大屏的視覺化展示,可能覺得我的攻堅能力比較強,第一時間又想到了我,我就把這個活接過來了,我開始組建實時團隊,也比較好的完成了任務。

我離職前主要是做平臺的搭建以及各種指標的分析: 實現和離線的都做;

我最近做的⼀個專案是商城平臺,我們這個專案主要包含三個方⾯ :

  1. 資料倉庫的搭建;
  2. 實時計算系統;
  3. 離線計算系統;

剛開始主要是負責做平臺相關的工作,後來做了⼀段時間的實時指標,離職前主要負責離線 指標這塊的內容以及⼀些維護優化的⼯作;

公司大資料部門這邊剛開始有 5 個人,隨後因為業務的增加又招了⼀些人離職前有 8 個人;

一、簡要介紹專案

接下來我先介紹⼀下這個專案:

專案是⼀個高度定製化的商城平臺,最近主要做的是數倉和離線指標計算這⼀塊;

數倉初期

數倉搭建初期,由於公司資料量少,經驗不足,數倉沒有層級概念,過來的資料直接進行解析,每次計算一個指標的時候,都需要進行 ETL 操作,每次都需要進行 join,造成了大量的重複操作,效率十分低下,浪費大量人力。

數倉後期

數倉在搭建一段時間後,重複的計算操作困惱了我很久,後來我參考了阿里的離線數倉架構,我們對數倉進行了重新的架構搭建,對數倉進行了分層規劃。

主要分為:

  1. ods 層 : 資料緩衝層;
  2. dwd 層 : 基礎資料層;
  3. dws 層 : 資料彙總層;
  4. app 層 : 應用層;

分四層的原因主要是為了隔離資料然後還能複用上⼀層計算出來的資料,另一方面也是為了資料的備份;

二、介紹熟悉的框架

資料採集我們主要是採集業務系統的資料日誌資料兩部分,業務系統資料儲存在 Mysql 中,使用 Sqoop 將資料匯入大資料平臺。

Sqoop

Sqoop 是在 Hadoop 生態體系和 RDBMS 體系之間傳送資料的一種工具。它的工作機制是將匯入或匯出命令翻譯成 mapreduce 程式來實現。在翻譯出的 mapreduce 中主要是對 inputformat 和 outputformat 進行定製。

我們在使用 Sqoop 匯入匯出時出現了 Null 的儲存一致性問題,Hive 中的 Null 在底層是以“\N”來儲存,而 MySQL 中的 Null 在底層就是 Null。為了保證資料兩端的一致性,在匯出資料時採用--input-null-string 和--input-null-non-string 兩個引數。匯入資料時採用--null-string 和--null-non-string。

Flume

對於日誌採集我們當時選用的是 Flume,採集日誌框架也有很多,之所以選擇 Flume 主要是因為它採集資料的效果比較好,其次是對於 HDFS 和 Kafka ⽀持的也比較好;

Flume 主要包含三大元件:

Source、Channel、Sink

  1. Flume 在 1.7 以後提供了⼀個 TailDirSource 用來⽀持多目錄和斷點續傳功能;

    • 斷點續傳主要保證在伺服器掛掉的情況下,再次啟動服務資料不會丟失的問題;其原理就是在底層維護了⼀個 offset 偏移量(也就是每次讀取檔案的偏移量)Flume 會通過這個偏移量來找到上次檔案讀取的位置從⽽實現了斷點續傳的功能;

    • 在 1.6 以前這個實現斷點續傳是需要手工維護這個偏移量的會比較麻煩;

  2. Channel 的種類比較多主要有:

    • MemoryChannel : 資料放在記憶體中,會在 Flume 宕機的時候丟失資料,可以用在對資料安全性要求沒有那麼高的場景中比如日誌資料;

    • FileChannel : 不會丟失資料,因為資料是放在磁碟上邊的⽽且⽀持多目錄配置可以提高寫入的效能,同時因為有落盤的操作所以效率比較低,適合用在對資料安全性要求比較高的場景比如⾦融類的資料;

    • KafkaChannel : 主要是為了對接 Kafka,使用這個可以節省 Sink 元件也可以提升效率的,我們專案中使用的就是這個 Channel,因為下⼀層是使用 Kafka 來傳遞訊息的;

  3. 在 Flume 這⼀層我們還做了⼀個攔截器,主要是對收集到的日誌做了⼀層過濾,因為有的日誌沒有 id 或一些關鍵欄位,這些資料對我們資料分析來說是沒有任何用的,所以在攔截器裡邊對這些資料進行了簡單清洗;

  4. 還做了⼀個分型別的攔截器,在這個攔截器裡邊我們對資料進行型別的區分,主要是做了⼀個打標籤的功能對不同的日誌資料打上不同的標籤,然後通過後續的選擇器 Multiplexing 將不同標籤的資料放到不同的 topic 裡邊,⽅便下游對資料進行處理;

Kafka:

下游資料傳輸使用的是 Kafka 作為訊息佇列來傳輸訊息,使用 Kafka 的主要原因是因為 Kafka 的高吞吐量以及可以對資料進行分類也就是不同的 topic,⽅便下⼀層的使用,整體的架構是採用 Lamda 架構設計的,實時和離線都會從 Kafka 中獲取資料來進行處理,⽽且還有其他的業務線也是從 Kafka 中獲取資料的,這樣做以後可以有效的提高資料的複用減少資料的冗餘,離線這塊我們是在 Kafka 之後⼜做了⼀層 Flume 來作為消費者處理 Kafka 中的資料的, 將消費到的資料直接放入 HDFS 中,實時這塊使用的是 SparkStreaming 來消費 Kafka 中的資料;

為什麼選擇 Kafka 作為訊息佇列來處理資料

當時在做技術選型的時候我們也是做了大量的調研,因為訊息佇列的產品有很多比如 : ReactMQ Kafka 等;

我們當時調研考慮的主要指標就是吞吐量這⼀塊,因為大資料流式處理對資料的吞吐量要求是⾮常高的,在這⼀塊 ReactMQ 是比較厲害的,吞吐量可以達到 1 萬多每秒;通過後來的調研以後發現 Kafka 的吞吐量比 ReactMQ 更高,如果使用恰當的話吞吐量甚⾄可以達到 10 萬+每秒;

kafka 支援訊息持久化,消費端是主動拉取資料,消費狀態和訂閱關係由客戶端負責維護,訊息消費完後,不會立即刪除,會保留歷史訊息。因此支援多訂閱時,訊息只會儲存一份就可以。

  1. broker:kafka 叢集中包含一個或者多個服務例項(節點),這種服務例項被稱為 broker(一個 broker 就是一個節點/一個伺服器);
  2. topic:每條釋出到 kafka 叢集的訊息都屬於某個類別,這個類別就叫做 topic;
  3. partition:partition 是一個物理上的概念,每個 topic 包含一個或者多個 partition;
  4. producer:訊息的生產者,負責釋出訊息到 kafka 的 broker 中;
  5. consumer:訊息的消費者,向 kafka 的 broker 中讀取訊息的客戶端;
  6. consumer group:消費者組,每一個 consumer 屬於一個特定的 consumer group(可以為每個 consumer 指定 groupName);

Kafka 為什麼可以這麼快?

  1. 首先從生產者說起,生產者傳送資料是按照批進行傳送的並不是⼀條⼀條傳送的,從這裡就已經可以保證 Kafka ⼀個比較高的吞吐量了;

  2. 生產者來⼀條訊息以後會進入⼀個攔截器,在攔截器裡邊可以對資料進行⼀個整體的 修改操作⼀般這裡是不做特殊的處理的,資料從攔截器出來以後就會進入到序列化器, 在序列化器裡邊將資料轉換成⼀個⼆進位制流的形式放入 Broker 裡邊;

  3. 經過序列化器以後資料就會⾛到分割槽器,Kafka 使用的分割槽器是⼀個叫做 Hash 的分割槽器,Hasf 分割槽器我們可以對其進行重寫;

  4. 生產者將訊息傳送到 Broker 的過程可能會出現訊息的重複或者丟失的情況,這個主要是靠 ACK 的配置來決定的,ack 的響應有三個狀態值 0,1,-1

    • 0:生產者只負責傳送資料,不關心資料是否丟失,丟失的資料,需要再次傳送
    • 1:partition 的 leader 收到資料,不管 follow 是否同步完資料,響應的狀態碼為 1
    • -1:所有的從節點都收到資料,響應的狀態碼為-1
  5. 這裡還有⼀個很重要的概念就是 ISR 副本同步佇列,在這個佇列裡邊包含了 Leader 和 Follower,主要解決的問題就是 Leader 掛了以後誰來做 Leader 的問題:

    • 選舉機制就是通過這個 ISR 來進行的,預設是有⼀個排序排序的⼀般都是選取第⼀ 個,因為每⼀批的資料只有最快的那個才能達到第⼀個接收訊息,其中 ISR 佇列以及 Leader 的選舉是由 Controller 來控制的,Zookeeper 來進行儲存,關於 Controller 在 Kafka 中也是⾮常重要的 Controller 也有⼀個專門的選舉機制,它是相當於是用 Zookeeper 來做了⼀個分散式鎖,具體原理就是利用 Zookeeper 生成的臨時節點生成⼀個分散式鎖,誰先搶佔到誰就是 Leader;

三、介紹專案採用的架構

上面也說到,我們整體的架構是採用 Lamda 架構設計的。

資料從底層的資料來源開始,經過 Kafka、Flume 等資料元件進行收集,然後分成兩條線進行計算:

  • 一條線是進入流式計算平臺(例如 Storm、Flink 或者 SparkStreaming),去計算實時的一些指標;

  • 另一條線進入批量資料處理離線計算平臺(例如 Mapreduce、Hive,Spark SQL),去計算 T+1 的相關業務指標,這些指標需要隔日才能看見。

在 Lambda 架構中,每層都有自己所肩負的任務。

1. 批處理層儲存管理主資料集(不可變的資料集)和預先批處理計算好的檢視:

批處理層使用可處理大量資料的分散式處理系統預先計算結果。它通過處理所有的已有歷史資料來實現資料的準確性。這意味著它是基於完整的資料集來重新計算的,能夠修復任何錯誤,然後更新現有的資料檢視。輸出通常儲存在只讀資料庫中,更新則完全取代現有的預先計算好的檢視。

2. 流處理層會實時處理新來的大資料:

流處理層通過提供最新資料的實時檢視來最小化延遲。流處理層所生成的資料檢視可能不如批處理層最終生成的檢視那樣準確或完整,但它們幾乎在收到資料後立即可用。而當同樣的資料在批處理層處理完成後,在速度層的資料就可以被替代掉了。

四、詳細介紹數倉搭建

1. 資料各層作用

  1. ODS(原始資料層):日誌資料和業務進入數倉後,首先放入該層,建立分割槽表,防止後續的全表掃描,使用 ORC 列式儲存,同時對資料進行壓縮,壓縮格式採用 LZO,以減少儲存空間。

    • 日誌:商品列表、商品點選、商品詳情;廣告;故障;後臺活躍、通知;啟動表;點贊、評論、收藏等。
    • 業務資料:訂單表、使用者表、支付流水錶、訂單詳情表、商品表、三級、二級、一級,物流資訊(根據產品的來源,有兩種,香港特快直送,閃電保稅倉。一個從香港發貨,一個從內地的保稅倉發貨)等。
  2. DWD(明細資料層):對 ODS 層資料清洗(去除空值,髒資料,超過極限範圍的資料)。

    1. 使用者行為資料:自定義 UDF(extends UDF 實現 evaluate 方法),解析公共欄位;自定義 UDTF(extends Genertic UDTF->實現三個方法 init(指定返回值的名稱和型別)、process(處理欄位一進多出)、close 方法),自定義方法的好處在於更加靈活以及方便除錯 bug。在自定義函式解析欄位時,我們一般建立中間表,存放解析後的表,最後通過 get_json_object 獲的我們所需要的欄位,建立最終所需表。
    2. 業務資料:維度退化+資料清洗(where group by)
    3. 脫敏:利用 spark 對手機號、身份證號、銀行賬號等敏感資訊進行脫敏處理。
    4. ETL:通過 HQL、Kettle 對資料進行清洗。清洗標準是核心欄位滿足業務邏輯要求,去除重複、空值、超過時限等資料。一般清洗率為萬分之一,如果大於這個數,需要和前端、javaEE 人員進行溝通。
    5. 維度退化:商品表+三級分類、二級分類、一級分類=>商品表,省份+地區表=>省份表,其中我們用到的維度建模理論是星型模型,事實表周圍 1 級維度。
    6. LZO 壓縮:減少儲存空間
    7. 列式儲存:ORC,增加壓縮比
    8. 分割槽表:防止後續的全表掃描

重點重點:DWD 層我們使用的是標準的數倉建模理論

數倉建模怎麼建?

我們按照數倉工具箱中的維度建模四步走來建的:

  • 選擇業務過程:由於我們公司當時資料量較小,我把 javeEE 涉及的業務表全部匯入了,這些表包括實體表,維度表,事務型快照事實表,週期性快照事實表、累積型事實表。過來之後,將這些表作為矩陣的一個列。

  • 宣告粒度:粒度一般有:一行資訊代表一次、按天、按周、按月等,參考了很多架構之後,我們考慮到後期想要分析更多的指標,只能選擇最小的粒度,一行資訊代表一次消費。

  • 確認維度:採用標準數倉建模的思維,爭取事實表周圍都是 1 級維度。我們關係的就是什麼時間、什麼地點、什麼人、具體什麼活動、優惠券等主題的維度,同時將跟使用者、商品相關的表進行維度退化,儘量把他們降成一級維度。

  • 確認事實:這裡我們確定的不是事實表,而是事實表的度量值,我們用到的度量值有訂單的個數、訂單的金額、下單次數等可以累加的欄位。

  1. DWS、DWT(每天的使用者行為寬表):每天的使用者行為寬表、商品寬表,相當於一個週期型快照事實表。每天記錄使用者做了那些事情,商品被下單了多少。

    • DWS 寬表的欄位我們是站在維度的角度來取的,比如站在使用者的維度去看待周圍的對應事實表,取事實表對應的度量值,取出訂單的次數、訂單的金額、支付的次數、支付的金額、加入購物車的次數、加入購物車的金額、評論的次數、點讚的次數、收藏的次數等等,將他們組合成為 DWS 層每天發生的事情。

    • 後期我們為了統計的指標,加了一個 DWT 層,DWT 層還是站在維度的角度去看待對應事實表,但是它和 DWS 有略微的區別,現在關注的是這個使用者什麼時間開始建立的,最後一次登入是什麼時候,累計登入多少次,最近 30 天登入多少次等資訊。

  2. DWS、DWT 統稱為服務層:都是為後面的 ADS 層提供服務的,如果統計的是累積性指標,從 DWT 層拿取資料;如果統計的當天的指標,直接從 DWS 層取對應的資料。 DWS 層最大的行為寬表是使用者行為寬表,其欄位有互動日期、使用者 id、使用者暱稱、註冊日期、註冊來源、細分渠道、註冊省份、評論次數、打賞次數、新增收藏、取消收藏、關注商品、取消關注的商品、關注人、取消關注的人、點不值次數、點值次數、點贊次數、分享次數、爆料數、加購物車數、取消購物車次數等待。DWT 也是使用者行為寬表,其欄位有互動日期、使用者 id、使用者暱稱、註冊日期、註冊來源、細分渠道、註冊省份、最後一次登入日期、累計登入日期、最近 30 天登入日期等等。

  3. ADS 層:分析了 100 多個指標:包括 日活、月活、周活、留存、留存率、新增(日、周、年)、轉化率、流失、迴流、七天內連續 3 天登入(點贊、收藏、評價、購買、加購、下單、活動)、連續 3 周(月)登入、GMV、復購率、復購率排行、點贊、評論、收藏、領優惠價人數、使用優惠價、沉默、值不值得買、退款人數、退款率 topN 熱門商品、留轉 G 復活等。

五、數倉業務詳解

我們資料倉庫是基於維度建模,主要使用星型模型

  1. 維度表:一般是對事實的描述資訊。每一張維表對應現實世界中的一個物件或者概念。例如:使用者、商品、日期、地區等。

維表的特徵:

  • 維表的範圍很寬(具有多個屬性、列比較多)
  • 跟事實表相比,行數相對較小:通常< 10 萬條
  • 內容相對固定:編碼表
  1. 事實表:分為事務型事實表(每個事務或事件為單位,一旦產生就固定)和週期型事實表(不會保留所有資料,只保留固定時間間隔的資料,比如每天、每月銷售額)以及累積性事實表(累積型快照事實表用於跟蹤業務事實的變化,比如訂單的狀態變化情況)。如果需要後面狀態還會改變的就是週期型事實表,一旦確定了,就是事務性事實表。

事實表中的每行資料代表一個業務事件(下單、支付、退款、評價等)。“事實”這個術語表示的是業務事件的度量值(可統計次數、個數、金額等),例如,訂單事件中的下單金額。

每一個事實表的行包括:具有可加性的數值型的度量值、與維表相連線的外來鍵、通常具有兩個和兩個以上的外來鍵、外來鍵之間表示維表之間多對多的關係。

事實表的特徵:

  • 非常的大
  • 內容相對的窄:列數較少
  • 經常發生變化,每天會新增加很多。

對於不同的表我們使用不同的同步策略:

同步策略包括全量表,增量表,新增及變化,拉鍊表

日誌表:(商品點選,商品詳情,商品詳情頁表,廣告表,錯誤日誌表,訊息通知表等)

  1. 商品點選:使用者的基本資訊欄位,動作,商品 id,種類等。
  2. 商品詳情頁:入口,上一頁面來源,商品 id,載入時間,種類。
  3. 廣告表:入口,內容,行為,展示風格等。
  4. 錯誤日誌:錯誤詳情
  5. 訊息通知表:通知型別,展示時間,通知內容等

這些記錄性質的,都使用每日增量

業務表:(購物車,評分,評論,訂單表,訂單詳情表,退貨表,使用者表,商家表,商品分類表(一級,二級,三級),支付流水,物流資訊等)

  1. 購物車詳情:使用者 id ,商品 id,商品價格,商家 id ,商品型號,商品分類等 同步策略:這屬於週期型事實表,因為它可能會隨時改變,所以得用每日新增及變化。

  2. 評分表:評分時間,評分使用者,評分商品 ,分數等。

    同步策略:這是事務性事實表,一般可以用每日增量就可以了,因為評論只能增加,不能修改。

  3. 評論表:評論時間,評論使用者,評論商品,評論內容。

    同步策略:這個跟評分差不多,用每日新增

  4. 訂單表:訂單狀態,訂單編號,訂單金額,支付方式,支付流水,建立時間等

    同步策略:因為訂單的狀態會隨時發生改變,比如下單,支付,商家發貨,使用者收到貨,確認收貨,等這一系列的狀態會比較長,然後訂單也比較多。所以,要做歷史快照資訊的話,最好使用拉鍊表

  5. 訂單詳情表:訂單編號,訂單號,使用者 id,商品名稱,商品價格,商品數量,建立時間等。

  6. 使用者表:使用者 id,性別,等級,vip,註冊時間等等。

    同步策略:因為表不是很大,每次做全量表

  7. 商家表:商家 id,商家地址,商家規模等級,商家註冊時間,商家分類資訊。

    同步策略:每次做每日全量

總結

  1. 實體表,不大,就可以做每日全量。
  2. 對於維度表,比如說商品分類,這種不是很大,也可以做每日全量,有一些不太會發生改變的維度,就可以固定儲存一份值,比如說:地區,種族等。
  3. 事務型事實表,比如說交易流水,操作日誌,出庫資訊,這種每日比較大,且需要歷史資料的,就根據時間做每日新增,可以利用分割槽表,每日做分割槽儲存。
  4. 週期型事實表的同步策略,比如訂單表,有周期性變化,需要反應不同時間點的狀態的,就需要做拉鍊表。記錄每條資訊的生命週期,一旦一條記錄的生命週期結束,就開始下一條新的記錄。並把當前的日期放生效開始日期。

六、離線指標

  1. 日活/周活/月活統計:(每日的根據 key 聚合,求 key 的總數)
  2. 使用者新增:每日新增(每日活躍裝置 left join 每日新增表,如果 join 後,每日新增表的裝置 id 為空,就是新增)
  3. 使用者留存率:(一週留存)10 日新增裝置明細 join 11 日活躍裝置明細表,就是 10 日留存的。注意每日留存,一週留存
  4. 沉默使用者佔比:只在當天啟動過,且啟動時間在一週前
  5. 本週迴流使用者數
  6. 使用者線上時長統計
  7. 區域使用者訂單數(根據區域分割槽,然後求訂單數)
  8. 區域訂單總額(根據區域分割槽,求訂單總額。)
  9. 區域使用者訂單訪問轉化率(以區域分組成單數/訪問數)
  10. 區域客單價(訂單總額度/下訂單總人數)
  11. 總退貨率(退貨商品數/購買商品總數)
  12. 各區域退貨率(根據區域分組)
  13. GMV(成交總額)
  14. 物流平均時長(使用者收貨時間-物流發貨時間)求平均
  15. 每週銷量前十品類
  16. 每週各品類熱門商品銷量前三
  17. 各區域熱門商品銷量前五(有利於後期鋪貨)
  18. 各區域漏斗分析
  19. 商品評價人數佔比(該商品的總評價人數/該商品的總購買人數)
  20. 各品牌商家總銷售額。
  21. 各品類中銷量前三的品牌
  22. 購物車各品類佔比(說明大家想買的東西,便於後期鋪貨。)
  23. 每週廣告點選率。看到這個廣告的人數/點選這個廣告商品的人數)
  24. vip 使用者每日,周訂單總額
  25. 每日限時特賣產品佔比(限時特賣產品總額/每日交易總額)
  26. 香港特快直送渠道總交易額佔比(香港特快直送渠道總額/每日商品交易總額)
  27. 香港特快直送渠道總交易單佔比
  28. 國內保稅倉渠道總交易額佔比(國內保稅倉總額/每日商品交易總額)
  29. 國內保稅倉渠道總交易單佔比
  30. 各區域頁面平均載入時長(考察各地區網路問題。後臺訪問是否穩定)
  31. 頁面單跳轉化率統計
  32. 獲取點選下單和支付排名前 10 的品類
  33. 各類產品季度復購率

七、實時指標

  1. 每日日活實時統計
  2. 每日訂單量實時統計
  3. 一小時內日活實時統計
  4. 一小時內訂單數實時統計
  5. 一小時內交易額實時統計
  6. 一小時內廣告點選實時統計
  7. 一小時內區域訂單數統計
  8. 一小時內區域訂單額統計
  9. 一小時內各品類銷售 top3 商品統計
  10. 使用者購買明細靈活分析(根據區域,性別,品類等)

八、寫出分析最難的兩個指標

面試官說現場手寫你分析過最難的兩個指標:

最好不要選擇最難的,除非你能完全寫出來,並且還得讓面試官理解你做的指標的含義,下面選擇容易理解但不算簡單的指標:

1. 活躍使用者指標

我們經常會算活躍使用者,活躍使用者是指至少連續 5 天登入賬戶的使用者,返回的結果表按照 id 排序。

+----+-----------+
|7|Jonathan|
+----+-----------+

思路:

  1. 去重:由於每個人可能一天可能不止登陸一次,需要去重
  2. 排序:對每個 ID 的登入日期排序
  3. 差值:計算登入日期與排序之間的差值,找到連續登陸的記錄
  4. 連續登入天數計算:select id, count(*) group by id, 差值(虛擬碼)
  5. 取出登入 5 天以上的記錄
  6. 通過表合併,取出 id 對應使用者名稱

參考程式碼:

SELECTDISTINCTb.id,name
FROM
(SELECTid,login_date,
DATE_SUB(login_date,ROW_NUMBER()OVER(PARTITIONBYidORDERBYlogin_date))ASdiff
FROM(SELECTDISTINCTid,login_dateFROMLogins)a)b
INNERJOINAccountsac
ONb.id=ac.id
GROUPBYb.id,diff
HAVINGCOUNT(b.id)>=5

注意點:

  1. DATE_SUB 的應用:DATE_SUB (DATE, X),注意,X 為正數表示當前日期的前 X 天;
  2. 如何找連續日期:通過排序與登入日期之間的差值,因為排序連續,因此若登入日期連續,則差值一致;
  3. GROUP BY 和 HAVING 的應用:通過 id 和差值的 GROUP BY,用 COUNT 找到連續天數大於 5 天的 id,注意 COUNT 不是一定要出現在 SELECT 後,可以直接用在 HAVING 中

2. 使用者留存率

首先使用者留存率一般是面向新增使用者的概念,是指某一天註冊後的幾天還是否活躍,是以每天為單位進行計算的。

一般收到的需求都是一個時間段內的新增使用者的幾天留存


select'日期''註冊使用者數''次日留存率''2日留存率''3日留存率',dim_date
,total_cnt
concat_ws('%|'cast(round(dif_1cnt*100/total_cnt,2)asstring),cast(dif_1cntasstring))
concat_ws('%|'cast(round(dif_2cnt*100/total_cnt,2)asstring),cast(dif_2cntasstring))
concat_ws('%|'cast(round(dif_3cnt*100/total_cnt,2)asstring),cast(dif_3cntasstring))
concat_ws('%|'cast(round(dif_4cnt*100/total_cnt,2)asstring),cast(dif_4cntasstring))
from
(
selectp1.statedim_date
,p1.device_os
count(distinctp1.user_id)total_cnt
count(distinctif(datediff(p3.state,p1.state)=1,p1.user_id,null))dif_1cnt
count(distinctif(datediff(p3.state,p1.state)=2,p1.user_id,null))dif_2cnt
count(distinctif(datediff(p3.state,p1.state)=3,p1.user_id,null))dif_3cnt
count(distinctif(datediff(p3.state,p1.state)=4,p1.user_id,null))dif_4cnt
from
(
select
from_unixtime(unix_timestamp(cast(partition_dateasstring),'yyyyMMdd'),'yyyy-MM-dd')state,
user_id
fromuser_active_day
wherepartition_datebetweendate1anddate2
anduser_is_new=1
groupby12
)p1--日新增使用者名稱單(register_date,user_id)
leftouterjoin
(
select
from_unixtime(unix_timestamp(cast(partition_dateasstring),'yyyyMMdd'),'yyyy-MM-dd')state,
user_id
fromactive_users
wherepartition_datebetweendate1anddate2
groupby12
)p3--期間活躍使用者(active_date,user_id)
on(p3.user_id=p1.user_id)
groupby12
)p4;

九、面試官問

自己說完專案之後面試官就開始發問了,注意接招:

1. 如何保證你寫的 sql 正確性?

我一般是造一些特定的測試資料進行測試。

另外離線資料和實時資料分析的結果比較。

2. 測試資料哪來的?

一部分自己寫 Java 程式自己造,一部分從生產環境上取一部分。

3. 測試環境什麼樣?

測試環境的配置是生產的一半

4. 測試之後如何上線?

上線的時候,將指令碼打包,提交 git。先發郵件抄送經理和總監,運維。通過之後跟運維一 起上線。

5. 你做的專案工作流程是什麼?

  1. 先與產品討論,看報表的各個資料從哪些埋點中取
  2. 將業務邏輯過程設計好,與產品確定後開始開發
  3. 開發出報表 SQL 指令碼,並且跑幾天的歷史資料,觀察結果
  4. 將報表放入排程任務中,第二天給產品看結果。
  5. 週期性將表結果匯出或是匯入後臺資料庫,生成視覺化報表

6. Hadoop 宕機?

  1. 如果 MR 造成系統宕機。此時要控制 Yarn 同時執行的任務數,和每個任務申請的最大記憶體。

    調整引數:yarn.scheduler.maximum-allocation-mb(單個任務可申請的最多實體記憶體量,預設是 8192MB)

  2. 如果寫入檔案過量造成 NameNode 宕機。那麼調高 Kafka 的儲存大小,控制從 Kafka 到 HDFS 的寫入速度。高峰期的時候用 Kafka 進行快取,高峰期過去資料同步會自動跟上。

7. 說下 Spark 資料傾斜及解決?

資料傾斜以為著某一個或者某幾個 partition 的資料特別大,導致這幾個 partition 上的計算需要耗費相當長的時間。

在 spark 中同一個應用程式劃分成多個 stage,這些 stage 之間是序列執行的,而 一個 stage 裡面的多個 task 是可以並行執行,task 數目由 partition 數目決定,如 果一個 partition 的數目特別大,那麼導致這個 task 執行時間很長,導致接下來 的 stage 無法執行,從而導致整個 job 執行變慢。

避免資料傾斜,一般是要選用合適的 key,或者自己定義相關的 partitioner,通 過加鹽或者雜湊值來拆分這些 key,從而將這些資料分散到不同的 partition 去執行。

如下運算元會導致 shuffle 操作,是導致資料傾斜可能發生的關鍵點所在:

groupByKey;reduceByKey;aggregaByKey;join;cogroup

8. 為什麼 Kafka 不支援讀寫分離?

在 Kafka 中,生產者寫入訊息、消費者讀取訊息的操作都是與 leader 副本進行互動的,從 而實現的是一種主寫主讀的生產消費模型。 Kafka 並不支援主寫從讀,因為主寫從讀有 2 個很明顯的缺點:

  1. 資料一致性問題:資料從主節點轉到從節點必然會有一個延時的時間視窗,這個時間 視窗會導致主從節點之間的資料不一致。某一時刻,在主節點和從節點中 A 資料的值都為 X, 之後將主節點中 A 的值修改為 Y,那麼在這個變更通知到從節點之前,應用讀取從節點中的 A 資料的值並不為最新的 Y,由此便產生了資料不一致的問題。

  2. 延時問題:類似 Redis 這種元件,資料從寫入主節點到同步至從節點中的過程需要經歷 網路 → 主節點記憶體 → 網路 → 從節點記憶體 這幾個階段,整個過程會耗費一定的時間。而在 Kafka 中,主從同步會比 Redis 更加耗時,它需要經歷 網路 → 主節點記憶體 → 主節點磁碟 → 網路 → 從節 點記憶體 → 從節點磁碟 這幾個階段。對延時敏感的應用而言,主寫從讀的功能並不太適用。

而 kafka 的主寫主讀的優點就很多了:

  1. 可以簡化程式碼的實現邏輯,減少出錯的可能;
  2. 將負載粒度細化均攤,與主寫從讀相比,不僅負載效能更好,而且對使用者可控;
  3. 沒有延時的影響;
  4. 在副本穩定的情況下,不會出現資料不一致的情況。

十、最後的面試小技巧

最後給大家說一點面試小技巧:

一般來說,面試你的人都不是一個很好對付的人。別看他彬彬有禮,看上去笑眯眯的,很和氣的樣子。但沒準兒一肚子壞水。

有些人待人特別客氣,說話還稍稍有點結巴的,更容易讓人上當。

所以,牢記一點,面試的時候保持高度警覺,對方不經意問出來的問題,很可能是他最想知道的。

  1. 首先說話語速不要太快,有些人介紹自己時滔滔不絕,說話特快。其實這裡面有個資訊傳遞的問題,跟別人談事情,語速太快,往往容易說錯,對方接受起來也有問題。所以中等語速就可以了。

  2. 問到期望薪金的時候,最好的回答是不回答,留到下一次面試再談。或者可以反問,公司對於這個崗位定的薪金標準是多少。

  3. 不要緊張,表現得自然些,要有禮貌,別忘記和主考人招呼,說句"早上好"等。

  4. 舉止要大方,不可閃縮,要保持自信。待主考人邀請你才可禮貌地坐下,不要太隨便或左顧右盼;切忌裝出懶洋洋和滿不在乎的樣子。

  5. 微笑可以減輕你內心的不安,更可以令面試的氣氛變得融洽愉快。

  6. 讓主考人知道你珍惜這次面試的機會。當主考人說話時,要眼望對方,並留心傾聽。

  7. 讓主考人先開啟話匣子。答問題要直接了當,無須太繁複,也不要單說"是"或"不是";否則,主考人會覺得你欠缺誠意。深入的談話內容有助主考人對你作出確切的評估。

  8. 假如有不太明白主考人的問題,應該禮貌地請他重複。不懂得回答的問題,不妨坦白承認。含糊其辭或亂吹牛會導致面試的失敗。

  9. 不要打斷主考人的說話,被要求就相同的問題重複作答也不能表示不耐煩,更切忌與主考人爭辯。

  10. 主考人可能問你一些與面試或者申請的職位完全無關的問題,例如時人時事,目的在進一步瞭解你的思想及見識。

  11. 緊記在適當時機帶出自已的優點和特長。但切勿顯得過份自信或浮誇。

  12. 準備一些與該機構和申請的工作有關的問題在面試結束之前提出。這樣能表現夥的積極,亦可給主考人留下良好印象。

  13. 最後,問清楚多久才知道面試結果。不要忘記向主考人道謝及說聲"再見"才離去。

本文來自微信公眾號:五分鐘學大資料,轉載請在公眾號後臺獲取作者微信進行授權