Hive五道經典面試題


第 1 題 連續問題

  如下數據為螞蟻森林中用戶領取的減少碳排放量

id dt lowcarbon
1001 2021-12-12 123
1002 2021-12-12 45
1001 2021-12-13 43
1001 2021-12-13 45
1001 2021-12-13 23
1002 2021-12-14 45
1001 2021-12-14 230
1002 2021-12-15 45
1001 2021-12-15 23
… …

  找出連續 3 天及以上減少碳排放量在 100 以上的用戶

第 2 題 分組問題

  如下為電商公司用戶訪問時間數據

id ts(秒)
1001 17523641234
1001 17523641256
1002 17523641278
1001 17523641334
1002 17523641434
1001 17523641534
1001 17523641544
1002 17523641634
1001 17523641638
1001 17523641654

  某個用戶連續的訪問記錄如果時間間隔小於 60 秒,則分為同一個組,結果為:

id ts(秒) group
1001 17523641234 1
1001 17523641256 1
1001 17523641334 2
1001 17523641534 3
1001 17523641544 3
1001 17523641638 4
1001 17523641654 4
1002 17523641278 1
1002 17523641434 2
1002 17523641634 3

第 3 題 間隔連續問題

  某游戲公司記錄的用戶每日登錄數據

id dt
1001 2021-12-12
1002 2021-12-12
1001 2021-12-13
1001 2021-12-14
1001 2021-12-16
1002 2021-12-16
1001 2021-12-19
1002 2021-12-17
1001 2021-12-20

  計算每個用戶最大的連續登錄天數,可以間隔一天。解釋:如果一個用戶在 1,3,5,6 登錄游戲,則視為連續 6 天登錄。

第 4 題 打折日期交叉問題

  如下為平台商品促銷數據:字段為品牌,打折開始日期,打折結束日期

brand stt edt
oppo 2021-06-05 2021-06-09
oppo 2021-06-11 2021-06-21
vivo 2021-06-05 2021-06-15
vivo 2021-06-09 2021-06-21
redmi 2021-06-05 2021-06-21
redmi 2021-06-09 2021-06-15
redmi 2021-06-17 2021-06-26
huawei 2021-06-05 2021-06-26
huawei 2021-06-09 2021-06-15
huawei 2021-06-17 2021-06-21

  計算每個品牌總的打折銷售天數,注意其中的交叉日期,比如 vivo 品牌,第一次活動時間為 2021-06-05 到 2021-06-15,第二次活動時間為 2021-06-09 到 2021-06-21 其中 9 號到 15號為重復天數,只統計一次,即 vivo 總打折天數為 2021-06-05 到 2021-06-21 共計 17 天。

第 5 題 同時在線問題

  如下為某直播平台主播開播及關播時間,根據該數據計算出平台最高峰同時在線的主播人數。

id stt edt
1001 2021-06-14 12:12:12 2021-06-14 18:12:12
1003 2021-06-14 13:12:12 2021-06-14 16:12:12
1004 2021-06-14 13:15:12 2021-06-14 20:12:12
1002 2021-06-14 15:12:12 2021-06-14 16:12:12
1005 2021-06-14 15:18:12 2021-06-14 20:12:12
1001 2021-06-14 20:12:12 2021-06-14 23:12:12
1006 2021-06-14 21:12:12 2021-06-14 23:15:12
1007 2021-06-14 22:12:12 2021-06-14 23:10:12

答案:自己一定要先做,不要直接看答案!!!

第一題:

  1)按照用戶ID以時間字段分組,計算每個用戶單日減少的碳排放量大於100的

select id,
       dt,
       sum(lowcarbon) lowcarbon
from test1
group by id,dt
having lowcarbon > 100;t1

  2)等差數列:兩個等差數列若等差相同,則相同位置的數列相減得到的結果相同
    按照用戶分組,同時按照時間排序,計算每條數據的Rank值

select id,
       dt,
       lowcarbon,
       rank() over(partition by id order by dt) rk
from t1;t2

  3)將每行數據中的日期減去Rank值

select id,
       dt,
       lowcarbon,
       date_sub(dt,rk) flag
from t2;t3

  4)按照用戶以及flag分組,找出記錄大於等於3條的

select id,
       flag,
       count(*) num
from t3
group by id,flag
having num >= 3;

  5)最終的HQL

select id,
       flag,
       count(*) num
from (
    select id,
           dt,
           lowcarbon,
           date_sub(dt,rk) flag
    from (
        select id,
               dt,
               lowcarbon,
               rank() over(partition by id order by dt) rk
        from (
            select id,
                   dt,
                   sum(lowcarbon) lowcarbon
            from test1
            group by id,dt
            having lowcarbon > 100
        ) t1
    ) t2
) t3
group by id,flag
having num >= 3;

第二題:

  1)將上一行時間數據下移

select id,
       ts,
       lag(ts,1,0) over(partition by id order by ts) lagts
from test2;t1

  2)將當前行的時間減去上一行的時間

select id,
       ts,
       ts-lagts diffts
from t1;t2

  3)每個用戶范圍內從第一行到當前行,判斷diffts是否大於等於60,若diffts>=60,則加1,否則不變

select id,
       ts,
       sum(if(diffts>=60,1,0)) over(partition by id order by ts) groupid
from t2;t3

  4)最終的HQL

select id,
       ts,
       sum(if(diffts>=60,1,0)) over(partition by id order by ts) groupid
from (
    select id,
           ts,
           ts-lagts diffts
    from (
        select id,
               ts,
               lag(ts,1,0) over(partition by id order by ts) lagts
        from test2
    ) t1
) t2

第三題:

  1)將上一行時間下移

select id,
       dt,
       lag(dt,1,'1970-01-01') lagdt
from test3;t1

  2)將當前行時間減去上一行時間

select id,
       dt,
       datediff(dt,lagdt) diffdt
from t1;t2

  3)按照用戶分組,並按時間排序,計算第一行到當前行大於2的數據總條數

select id,
       dt,
       sum(if(diffdt>2,1,0)) groupid
from t2;t3

  4)按照用戶和groupid分組,求最大時間減去最小時間,然后加1

select id,
       groupid,
       (max(dt)-min(dt)+1) maxday
from t3;t4

  5)取連續登錄天數的最大值

select id,
       max(maxday) loginmax
from t4
group by id

  6)最終的HQL

select id,
       max(maxday) loginmax
from (
    select id,
           groupid,
           (max(dt)-min(dt)+1) maxday
    from (
        select id,
               dt,
               sum(if(diffdt>2,1,0)) groupid
        from (
            select id,
                   dt,
                   datediff(dt,lagdt) diffdt
            from (
                select id,
                       dt,
                       lag(dt,1,'1970-01-01') lagdt
                from test3
            ) t1
        ) t2
    ) t3
) t4
group by id

第四題:

  1)將當前行以前的數據中最大的edt放置當前行

select id,
       stt,
       edt,
       max(edt) over(partition by id order by stt rows unbounded preceding and 1 preceding) maxEdt
from test4;t1

  2)比較開始時間與移動下來的時間,若開始時間大,則不需要操作,否則,需要將移動下來的時間加1替換當前行的開始時間,若第一行數據,maxEdt為null,不需要操作

select id,
       if(maxEdt is null,stt,if(stt>maxEdt,stt,date_add(maxEdt,1))) stt,
       edt
from t1;t2

  3)將每行數據中的結束日期減去開始日期

select id,
       datediff(edt,stt) day
from t2;t3

  4)按照品牌分組,計算每條數據加1的總和

select id,
       sum(if(day>=0,day+1,0)) days
from t3
group by id;

  5)最終的HQL

select id,
       sum(if(day>=0,day+1,0)) days
from (
    select id,
           datediff(edt,stt) day
    from (
        select id,
               if(maxEdt is null,stt,if(stt>maxEdt,stt,date_add(maxEdt,1))) stt,
               edt
        from (
            select id,
                   stt,
                   edt,
                   max(edt) over(partition by id order by stt rows unbounded preceding and 1 preceding) maxEdt
            from test4
        ) t1
    ) t2
) t3
group by id;

第五題:

  1)對數據分類,在開始時間后添加1,表示有主播上線,同時在關閉時間后添加-1,表示有主播下線

select id,
       stt dt,
       1 p
from test5
union
select id,
       edt dt,
       -1 p
from test5;t1

  2)按照時間排序,計算累加人數

select id,
       dt,
       sum(p) over(order by dt) sum_p
from t1;t2

  3)找出同時在線人數最大值

select max(sum_p)
from t2;

  4)最終的HQL

select max(sum_p)
from (
    select id,
           dt,
           sum(p) over(order by dt) sum_p
    from (
        select id,
               stt dt,
               1 p
        from test5
        union
        select id,
               edt dt,
               -1 p
        from test5
    ) t1
) t2;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM