hive⾯试题总结(2020最新版)
本⽂⽬录
⼀、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。
rank函数的用法五、介绍⼀下有哪些常⽤函数?
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函数
1. 继承org.apache.hadoop.hive.ql.UDF函数;
2. 重写evaluate⽅法,evaluate⽅法⽀持重载。
2. ⾃定义UDAF函数
1. 必须继承org.apache.hadoop.UDAF(函数类继承)和org.apache.hadoop.UDAFEvaluator(内部类
Evaluator实现UDAFEvaluator接⼝);
2. 重写Evaluator⽅法时需要实现 init、iterate、terminatePartial、merge、terminate这⼏个函数:
init():类似于构造函数,⽤于UDAF的初始化
iterate():接收传⼊的参数,并进⾏内部的轮转,返回boolean
terminatePartial():⽆参数,其为iterate函数轮转结束后,返回轮转数据,类似于hadoop的Combiner
merge():接收terminatePartial的返回结果,进⾏数据merge操作,其返回类型为boolean
terminate():返回最终的聚集函数结果
3. ⾃定义UDTF函数
1. 继承org.apache.hadoop.hive.ic.GenericUDTF函数;
2. 重写实现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. 开启数据倾斜时负载均衡
upby.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 中随机分布到各个节点完成。
5. 控制空值分布
将为空的 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)*100000as 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,
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论