Hive面試題匯總

一、hive架構相關

遇到這類問題,可以靈活的去回答,比如可以結合平時使用hive的經驗作答,也可以結合下圖從數據的讀入、解析、元數據的管理,數據的存儲等角度回答:
hive架構

二、hive的特點

本題主要為了考察對hive的整體使用場景的掌握程度,畢竟只有知道了hive的特點,才能有針對性的在實際項目中的合適場景下使用hive。

可以從下面四個角度去分析:

  1. 數據存儲位置

    Hive的數據存儲在hdfs上,元數據可以存儲在指定的地方比如mysql,PostgreSQL等。

  2. 數據更新

    Hive處理數據時一般不對數據進行改寫,因為它不支持行級別的增刪操作,如果要進行更新數據,一般可以通過分區或者表直接覆蓋。

  3. 執行效率

    Hive 執行延遲較高。雖然在小數據量時傳統數據庫延遲更低,但是當數據規模大到超過傳統數據庫的處理能力的時候,Hive 的并行計算顯然能體現出優勢。

  4. 數據規模

    Hive 支持大規模的數據計算,通常是PB級別的數據。

三、內部表和外部表的區別?

  1. 內部表(MANAGED_TABLE):內部表其實就是管理表,當我們刪除一個管理表時,Hive 也會刪除這個表中數據。因此管理表不適合和 其他工具共享數據。
  2. 外部表(EXTERNAL_TABLE):刪除該表并不會刪除掉原始數據,刪除的是表的元數據。

四、4個by的區別?

  1. Sort By:在同一個分區內排序
  2. Order By:全局排序,只有一個Reducer;
  3. Distrbute By:類似 MapReduce 中Partition,進行分區,一般結合sort by使用。
  4. Cluster By:當 Distribute by 和 Sort by 字段相同時,可以使用Cluster by方式。Cluster by 除了具有 Distribute by 的功能外還兼具 Sort by 的功能。但是只能升序排序,不能指定排序規則為ASC或者DESC。

五、介紹一下有哪些常用函數?

5.1、行轉列函數
  1. CONCAT(string A/col, string B/col…):返回輸入字符串連接后的結果,支持任意個輸入字符串。

    例如: concat( aa, ‘:’, bb) 就相當于把aa列和bb列用冒號連接起來了,aa:bb。

  2. CONCAT_WS(separator, str1, str2,…):CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一個參數是其它參數的分隔符。分隔符的位置放在要連接的兩個字符串之間。分隔符可以是一個字符串,也可以是其它參數。如果分隔符為 NULL,則結果為 NULL。函數會忽略任何分隔符參數后的 NULL 值。但是CONCAT_WS()不會忽略任何空字符串。 (然而會忽略所有的 NULL)。

  3. COLLECT_SET(col):函數只接受基本數據類型,它的主要作用是將某字段的值進行去重匯總,產生array類型字段。

5.2、列轉行函數
  1. EXPLODE(col):將hive某列中復雜的array或者map結構拆分成多行。

  2. LATERAL VIEW:常和UDTF函數一起使用。

    用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias

    解釋:用于和split, explode等UDTF一起使用,它能夠將一列數據拆成多行數據,在此基礎上可以對拆分后的數據進行聚合。

5.3、Rank排名函數
  1. RANK() 排序相同時會重復,總數不會變;
  2. DENSE_RANK() 排序相同時會重復,總數會減少;
  3. ROW_NUMBER() 根據順序計算排名。

在實際開發中,以上三個rank函數通常是和開窗函數一起使用的。

5.4、窗口函數(開窗函數)
  1. OVER():用于指定分析函數工作時的數據窗口大小,這個數據窗口大小可能會隨著行的變而變化;

  2. CURRENT ROW:當前行;

  3. n PRECEDING:往前n行數據;

  4. n FOLLOWING:往后n行數據;

  5. UNBOUNDED:起點,UNBOUNDED PRECEDING 表示從前面的起點, UNBOUNDED FOLLOWING表示到后面的終點;

  6. LAG(col,n,default_val):往前第n行數據;

  7. LEAD(col,n, default_val):往后第n行數據;

  8. NTILE(n):把有序分區中的行分發到指定數據的組中,各個組有編號,編號從1開始,對于每一行,NTILE返回此行所屬的組的編號。這個函數需要注意:n必須為int類型。

六、UDF、UDAF、UDTF相關面試題

6.1、UDF、UDAF、UDTF的區別?

當Hive自帶的函數無法滿足我們的業務處理需求時,hive允許我們自定義函數來滿足需求。

根據自定義函數的類別分為以下三種:

  1. UDF:User-Defined-Function,用戶自定義函數,數據是一進一出,功能類似于大多數數學函數或者字符串處理函數;
  2. UDAF:User-Defined Aggregation Function,用戶自定義聚合函數,數據是多進一出,功能類似于 count/max/min;
  3. UDTF:User-Defined Table-Generating Functions,用戶自定義表生成函數,數據是一進多處,功能類似于lateral view explore();
6.2、怎么自定義UDF、UDAF、UDTF函數?
  1. 自定義UDF函數

    • 繼承org.apache.hadoop.hive.ql.UDF函數;
    • 重寫evaluate方法,evaluate方法支持重載。
  2. 自定義UDAF函數

    • 必須繼承org.apache.hadoop.hive.ql.exec.UDAF(函數類繼承)和org.apache.hadoop.hive.ql.exec.UDAFEvaluator(內部類Evaluator實現UDAFEvaluator接口);

    • 重寫Evaluator方法時需要實現 init、iterate、terminatePartial、merge、terminate這幾個函數:

      init():類似于構造函數,用于UDAF的初始化

      iterate():接收傳入的參數,并進行內部的輪轉,返回boolean

      terminatePartial():無參數,其為iterate函數輪轉結束后,返回輪轉數據,類似于hadoop的Combiner

      merge():接收terminatePartial的返回結果,進行數據merge操作,其返回類型為boolean

      terminate():返回最終的聚集函數結果

  3. 自定義UDTF函數

    • 繼承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF函數;

    • 重寫實現initialize, process, close三個方法。

      1. UDTF首先會調用initialize方法,此方法返回UDTF的返回行的信息(返回個數,類型)。

      2. 初始化完成后,會調用process方法,真正的處理過程在process函數中,在process中,每一次forward()調用產生一行;如果產生多列可以將多個列的值放在一個數組中,然后將該數組傳入到forward()函數。

      3. 最后close()方法調用,對需要清理的方法進行清理。

通常使用 UDF 函數解析公共字段;用 UDTF 函數解析事件字段。

七、hive怎么解決數據傾斜?

  1. group by

    注:group by 優于 distinct group

    情形:group by 維度過小,某值的數量過多

    后果:處理某值的 reduce 非常耗時

    解決方式:采用 sum() group by 的方式來替換 count(distinct)完成計算。

  2. count(distinct)

    情形:某特殊值過多

    后果:處理此特殊值的 reduce 耗時;只有一個 reduce 任務

    解決方式:count distinct 時,將值為空的情況單獨處理,比如可以直接過濾空值的行,

    在最后結果中加 1。如果還有其他計算,需要進行 group by,可以先將值為空的記錄單獨處

    理,再和其他計算結果進行 union。

  3. 不同數據類型關聯產生數據傾斜

    情形:比如用戶表中 user_id 字段為 int,log 表中 user_id 字段既有 string 類型也有 int 類

    型。當按照 user_id 進行兩個表的 Join 操作時。

    后果:處理此特殊值的 reduce 耗時;只有一個 reduce 任務

    默認的 Hash 操作會按 int 型的 id 來進行分配,這樣會導致所有 string 類型 id 的記錄都分配

    到一個 Reducer 中。

    解決方式:把數字類型轉換成字符串類型

    select * from users a 
    left outer join logs b
    on a.usr_id = cast(b.user_id as string)
    
  4. 開啟數據傾斜時負載均衡

    set hive.groupby.skewindata=true;
    

      思想:就是先隨機分發并處理,再按照 key group by 來分發處理。

      操作:當選項設定為 true,生成的查詢計劃會有兩個 MRJob。

      第一個 MRJob 中,Map 的輸出結果集合會隨機分布到 Reduce 中,每個 Reduce 做部分聚合操作,并輸出結果,這樣處理的結果是相同的 GroupBy Key 有可能被分發到不同的Reduce 中,從而達到負載均衡的目的;

      第二個 MRJob 再根據預處理的數據結果按照 GroupBy Key 分布到 Reduce 中(這個過程可以保證相同的原始 GroupBy Key 被分布到同一個 Reduce 中),最后完成最終的聚合操作。

      總結:它使計算變成了兩個 mapreduce,先在第一個中在 shuffle 過程 partition 時隨機給 key 打標記,使每個 key 隨機均勻分布到各個reduce 上計算,但是這樣只能完成部分計算,因為相同 key 沒有分配到相同 reduce 上。所以需要第二次的 mapreduce,這次就回歸正常 shuffle,但是數據分布不均勻的問題在第一次 mapreduce 已經有了很大的改善,因此基本解決數據傾斜。因為大量計算已經在第一次mr 中隨機分布到各個節點完成。

    • 控制空值分布

      將為空的 key 轉變為字符串加隨機數或純隨機數,將因空值而造成傾斜的數據分不到多個 Reducer。

      注:對于異常值如果不需要的話,最好是提前在 where 條件里過濾掉,這樣可以使計算量大大減少。

      實踐中,可以使用 case when 對空值賦上隨機值。此方法比直接寫 is not null 更好,因為前者 job 數為 1,后者為 2.

      使用 case when 實例 1:

      select userid, name from user_info a
      join (
      select case when userid is null
      then
      cast (rand(47)* 100000 as int )
      else userid end from user_read_log
      )b
      on a.userid = b.userid
      

      使用 case when 實例 2:

      select
      '${date}' as thedate,
      a.search_type,
      a.query,
      a.category,
      a.cat_name,
      a.brand_id,
      a.brand_name,
      a.dir_type,
      a.rewcatid,
      a.new_cat_name,
      a.new_brand_id,
      f.brand_name as new_brand_name,
      a.pv,
      a.uv,
      a.ipv,
      a.ipvuv,
      a.trans_amt,
      a.trans_num,
      a.alipay_uv
      from fdi_search_query_cat_qp_temp a
      left outer join brand f
      on
      f.pt='${date}000000' and case when a.new_brand_id is null then concat('hive',rand() ) else
      a.new_brand_id end = f.brand_id;
      

    如果上述的方法還不能解決,比如當有多個 JOIN 的時候,建議建立臨時表,然后拆分HIVE SQL 語句。

    八、hive優化相關面試題

    1. MapJoin

      如果不指定 MapJoin 或者不符合 MapJoin 的條件,那么 Hive 解析器會將 Join 操作轉換 成 Common Join,即:在 Reduce 階段完成 join。容易發生數據傾斜。可以用MapJoin把小 表全部加載到內存在 map 端進行 join,避免 reducer 處理。

    2. 行列過濾

      列處理:在 SELECT 中,只拿需要的列,如果有,盡量使用分區過濾,少用 SELECT *。

      行處理:在分區剪裁中,當使用外關聯時,如果將副表的過濾條件寫在 Where 后面,那 么就會先全表關聯,之后再過濾。

    3. 多采用分桶技術

    4. 結合實際環境合理設置 Map 數

      1. 通常情況下,作業會通過 input的目錄產生一個或者多個map任務。 主要的決定因素有:input的文件總個數,input的文件大小,集群設置的文件塊大小;
      2. map數不是越多越好;如果一個任務有很多小文件(遠遠小于塊大小 128m),則每個小文件 也會被當做一個塊,用一個 map 任務來完成,而一個 map 任務啟動和初始化的時間遠遠大 于邏輯處理的時間,就會造成很大的資源浪費。而且,同時可執行的 map 數是受限的。解決這個問題需要減少map數。
      3. 并不是每個map處理接近128m的文件塊就是完美的;比如有一個 127m 的文件,正常會用一個 map 去完成,但這個文件只 有一個或者兩個小字段,卻有幾千萬的記錄,如果 map 處理的邏輯比較復雜,用一個 map 任務去做,肯定也比較耗時。解決這個問題需要增加map數。
    5. 合并大量小文件

      在Map執行前合并小文件,可以減少Map數:CombineHiveInputFormat 具有對小文件進行合并的功能(系統默認的格式)。HiveInputFormat 沒有對小文件合并功能。

    6. 設置合理的Reduce數

      Reduce 個數也并不是越多越好

      1. 過多的啟動和初始化 Reduce 也會消耗時間和資源;
      2. 有多少個 Reduce,就會有多少個輸出文件,如果生成了很多個小文件,那么如果這些小文件作為下一個任務的輸入,則也會出現小文件過多的問題;
      3. 在設置Reduce個數的時候也需要考慮這兩個原則:處理大數據量利用合適的 Reduce 數;使單個 Reduce 任務處理數據量大小要合適;
    7. 輸出合并小文件常用參數

      SET hive.merge.mapfiles = true; -- 默認 true,在 map-only 任務結束時合并小文件
      SET hive.merge.mapredfiles = true; -- 默認 false,在 map-reduce 任務結束時合并小文件
      SET hive.merge.size.per.task = 268435456; -- 默認 256M
      SET hive.merge.smallfiles.avgsize = 16777216; -- 當輸出文件的平均大小小于 16m 該值時,啟動一個獨立的 map-reduce 任務進行文件 merge
      
    8. 開啟 map 端 combiner(不影響最終業務邏輯)

      開啟命令:

      set hive.map.aggr=true;
      
    9. 中間結果壓縮

      設置 map 端輸出、中間結果壓縮。(不完全是解決數據傾斜的問題,但是減少了 IO 讀寫和網絡傳輸,能提高很多效率)

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/web/83361.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/web/83361.shtml
    英文地址,請注明出處:http://en.pswp.cn/web/83361.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    樹莓派超全系列教程文檔--(57)如何設置 Apache web 服務器

    如何設置 Apache web 服務器 設置 Apache web 服務器安裝 Apache測試 web 服務器更改默認網頁 為 Apache 安裝 PHP 文章來源: http://raspberry.dns8844.cn/documentation 原文網址 設置 Apache web 服務器 Apache 是一款流行的 web 服務器應用程序,您…

    (九)現代循環神經網絡(RNN):從注意力增強到神經架構搜索的深度學習演進

    現代循環神經網絡的內容,將介紹幾種先進的循環神經網絡架構,包括門控循環單元(GRU)、長短期記憶網絡(LSTM)的變體,以及注意力機制等。這些內容將幫助你更深入地理解循環神經網絡的發展和應用。 …

    牛市與熊市:市場周期的雙面鏡

    牛市推動資產增值與風險積累,熊市擠壓泡沫并孕育機會,兩者交替循環,構成市場自我調節機制。 1、概念對比:情緒與趨勢的博弈 牛市(Bull Market):指資產價格持續上漲(通常漲幅超20%&a…

    web程序設計期末復習-填空題

    常用標簽 塊級標記 行內標記等 一、塊級元素 特點&#xff1a; 獨占一行可以設置寬度、高度、內外邊距默認情況下會從上到下垂直排列 常見標簽&#xff1a; 標簽 含義 <div> 最常用的通用塊級容器 <p> 段落 <h1>到<h6> 標題&#xff08;一級…

    go全局配置redis,全局只需要連接一次,然后全局可以引用使用

    創建redis文件夾、創建dadeRedis.go package redisimport ("context""github.com/go-redis/redis/v8""log""time" )var (client *redis.Clientctx context.Background() )// 初始化Redis連接&#xff08;建議在程序啟動時調用&am…

    緩沖區(C語言緩沖區+內核緩沖區)一個例子解釋他們的關系和作用!!!

    首先提出問題&#xff1a; 為什么以下代碼是先sleep三秒后&#xff0c;屏幕才顯示"XXXXXXX"。 #include<stdio.h> #include<unistd.h>int main() {printf("XXXXXXX");sleep(3);return 0; } 為什么以下代碼是先顯示"XXXXXXX"&#xf…

    【2025版】Java 工程師學習路線圖 —— 掌握程度描述版

    ?【2025版】Java 工程師學習路線圖 &#x1f4a1; 目標&#xff1a;成為合格的 Java 工程師&#xff08;前后端都要會&#xff09; &#x1f4dd; 結構清晰 | 階段明確 | 掌握程度分級 | 適合自學或轉行 &#x1f539; 階段一&#xff1a;編程基礎 計算機通識 模塊內容推薦掌…

    從零實現一個紅隊智能體

    從零實現一個紅隊智能體(持續更新) 2025-06-09 背景&#xff1a;最近學了基礎些東西和工具基礎使用&#xff0c;發現一套流程下來太多需要手工要做的&#xff0c;就像自己能不能結合自己的技術棧實現小工具 &#x1f947; 第一步&#xff1a;從實用性開始分析 目標場景 希望…

    Uniapp實現多選下拉框

    文章目錄 前言一、效果展示1.1 下拉效果圖1.2 下拉選擇效果圖1.3 選擇顯示效果圖 二、組件源碼2.1.CustomCheckbox.vue源碼2.2.niceui-popup-select.vue源碼 三、demo.vue代碼演示 前言 之前在使用Uniapp時&#xff0c;一直都是下拉框單選。今天某個項目需求需要使用Uniapp實現…

    JavaScript-Array.from

    Array.from() 是 JavaScript 中用于將類數組對象&#xff08;array-like&#xff09;或可迭代對象&#xff08;iterable&#xff09;轉換為真實數組的一個非常有用的方法。 &#x1f4cc; 一、基本語法 Array.from(arrayLike, mapFn?, thisArg?)參數說明&#xff1a; 參數類…

    二刷蒼穹外賣 day02

    新增員工 DTO 將前端傳遞的參數列表通過對應的實體類接收 當前端提交的數據和實體類中對應的屬性差別較大時&#xff0c;使用DTO來封裝數據 Data public class EmployeeDTO implements Serializable {private Long id;private String username;private String name;private…

    通過Heron Handoff 插件我們在figma設計中可以像sketch導出離線標注

    一、設計交付的歷史困境與破局契機 在數字產品開發的全流程中&#xff0c;設計標注的高效傳遞始終是連接創意與實現的關鍵紐帶。傳統設計工具如 Sketch 憑借 Bluebeam、Sketch Measure 等插件構建了成熟的離線標注體系&#xff0c;設計師可將標注文件打包交付&#xff0c;開發…

    SSE 數據的傳輸無法流式獲取

    問題 調試過程中發現SSE數據返回的時間都是一樣的&#xff0c;懷疑是接口問題。 參考 EventSource數據一次性出來&#xff0c;并未流式輸出的原因_sourceevent為什么結果一下全部返回了-CSDN博客 處理 EventStream 不能流式返回的問題&#xff1a;Nginx 配置優化 解決方案 …

    markdown文本轉換時序圖

    好久沒更新了~這篇是markdown文本轉換時序圖的常用方法 文章目錄 前言一、Mermaid語法示例二、PlantUML語法示例三、在線工具快速轉換總結 前言 使用專業工具如Mermaid或PlantUML可以直接在Markdown中繪制時序圖。這些工具支持簡潔的語法&#xff0c;生成可嵌入文檔的圖表&…

    谷粒商城-分布式微服務 -集群部署篇[一]

    十九、k8s 集群部署 19.1 k8s 快速入門 19.1.1 簡介 Kubernetes 簡稱 k8s。是用于自動部署&#xff0c;擴展和管理容器化應用程序的開源系統。 中文官網 中文社區 官方文檔 社區文檔 概述 | Kubernetes 傳統部署時代&#xff1a; 早期&#xff0c;各個組織是在物理服務器上…

    微信小程序- 用canvas生成排行榜

    設計功能不是很復雜&#xff0c;也不想用插件&#xff0c;最終出現現在版本&#xff0c;主要用到微信小程序 wx.canvasToTempFilePath方法 // 直接調用改方法 createQRCode() {const qrCodeCanvasId "qrcodeCanvas";drawQrcode({width: 200,height: 200,canvasId: …

    深度剖析:UI 設計怎樣為小程序構建極致輕量體驗

    內容摘要 在小程序的世界里&#xff0c;用戶都追求快速、便捷的輕量體驗。但你是否好奇&#xff0c;為啥有些小程序能讓人輕松上手&#xff0c;快速達成目標&#xff0c;而有些卻讓人感覺繁瑣、卡頓&#xff1f;這里的關鍵差異&#xff0c;往往就藏在 UI 設計中。UI 設計到底施…

    【網絡安全】Qt免殺樣本分析

    初步研判 SHA256&#xff1a;9090807bfc569bc8dd42941841e296745e8eb18b208942b3c826b42b97ea67ff 我們可以看到引擎0檢出&#xff0c;是個免殺樣本&#xff0c;不過通過微步云沙箱的行為分析&#xff0c;已經被判為惡意 行為分析 進程行為 可以看到demo顯示調用了winver獲…

    window 顯示驅動開發-如何查詢視頻處理功能(六)

    D3DDDICAPS_FILTERPROPERTYRANGE請求類型 UMD 返回指向 DXVADDI_VALUERANGE 結構的指針&#xff0c;該結構包含傳遞D3DDDICAPS_FILTERPROPERTYRANGE請求類型時特定視頻流上特定篩選器設置允許的值范圍。 Direct3D 運行時在D3DDDIARG_GETCAPS的 pInfo 成員指向的變量中為特定視…

    Oracle線上故障問題解決

    ----重啟電腦找不到sid Listener refused the connection with the following error: ORA-12505, TNS:listener does not currently know of SID given in connect descriptor Could not open connection sqlplus "/as sysdba" SQL> shutdown immediate 數據庫…