《大数据面试题 V3.0》,这次不仅是之前自己收集的部分,还有就是把牛客上别人分享的经验贴给爬了,现在暂时做了个初步总结。
接下来这几道题,算是所有面经里面出现频率最高的(仅限牛客大数据开发面经分享),有的公司甚至一二面都常有重复的题(比如美团~)。
最近除了总结面试题之外,也准备重新找一套全新的大数据开发学习资料,现在Hadoop和Spark都已经跨大版本了,以前的资料确实相对比较旧了,这套资料的视频会尽力都自己先看,找一些比较好的,不会局限于一整套,后续有新的内容,就在这个基础上加就行。
有件比较尴尬的事,在牛客收(爬)集(虫)面经时,被封号了。。。。。害
俺也很无辜啊,不仅收集(爬)个面经吗?有必要这样对我吗~不过前面看的那套爬虫视频确实不错,到时候给大家分享下,2020版是两个逗比清华博士讲的(德云社风格),现在已经出新版的了,最近也看了下新版的目录,有个小demo(爬网易云评论)可能改动下做个本科毕设好像。后续我会考虑能不能将那个demo做下可视化,对数据进行处理,然后看看考虑分标签存储数据,对这些数据进行离线处理(Spark SQL),当然,也可以考虑实时(Spark或Flink都可)也做了,这样一来,不搞太花里胡哨,一个本科毕设还是没问题的。
当然,这是今天的题外话了,下面就进入正题吧。
Hadoop一、HDFS文件写入和读取过程可灵活回答:
1)HDFS读写原理(流程)
2)HDFS上传下载流程
3)讲讲(介绍下)HDFS
4)HDFS存储机制
问过的一些公司:阿里×3,阿里社招,腾讯x2,字节x2,百度,拼多多x2,浩鲸云,小米,流利说,顺丰,网易云音乐×2,有赞×2,祖龙娱乐,360×2,商汤科技,招银网络,深信服,多益,大华,快手,电信云计算,转转,美团x4,shopee×2:回答越详细越好,猿辅导×2,科大讯飞,恒生电子,搜狐,京东,头条,富途
回答这个问题之前,我们先来看下机架感知机制,也就是HDFS上副本存储结点的选择。
Hadoop3.x副本结点选择:
由上图可知,第一个副本在Client所处的节点上。如果客户端在集群外,随机选一个。
第二个副本在另一个机架的随机一个节点。
第三个副本在第二个副本所在机架的随机节点。
关于HDFS读写流程,这里还是给出两个版本,有助于理解第一个版本:简洁版
HDFS写数据流程
1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在。
2)NameNode返回是否可以上传。
3)客户端请求第一个 block上传到哪几个datanode服务器上。
4)NameNode返回3个datanode节点,分别为dn1、dn2、dn3。
5)客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。
6)dn1、dn2、dn3逐级应答客户端。
7)客户端开始往dn1上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位,dn1收到一个packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
8)当一个block传输完成之后,客户端再次请求NameNode上传第二个block的服务器。(重复执行3-7步)。
HDFS读数据流程
1)客户端通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以packet为单位来做校验)。
4)客户端以packet为单位接收,先在本地缓存,然后写入目标文件。
第二个版本:详细版,有助于理解
HDFS写数据流程
1)Client将FileA按128M分块。分成两块,block1和Block2;
2)Client向nameNode发送写数据请求,如图蓝色虚线①------>。
3)NameNode节点,记录block信息。并返回可用的DataNode,如粉色虚线②--------->。
Block1: host2,host1,host6
Block2: host7,host3,host4
4)client向DataNode发送block1;发送过程是以流式写入。
流式写入过程:
(1)将64M的block1按64k的package划分;
(2)然后将第一个package发送给host2;
(3)host2接收完后,将第一个package发送给host1,同时client想host2发送第二个package;
(4)host1接收完第一个package后,发送给host6,同时接收host2发来的第二个package。
(5)以此类推,如图红线实线所示,直到将block1发送完毕。
(6)host2,host1,host6向NameNode,host2向Client发送通知,说“消息发送完了”。如图粉红颜色实线所示。
(7)client收到host2发来的消息后,向namenode发送消息,说我写完了。这样就完成了。如图黄色粗实线。
(8)发送完block1后,再向host7,host3,host4发送block2,如图蓝色实线所示。
(9)发送完block2后,host7,host3,host4向NameNode,host7向Client发送通知,如图浅绿色实线所示。
(10)client向NameNode发送消息,说我写完了,如图黄色粗实线。。。这样就完毕了。
HDFS读数据流程
1)client向namenode发送读请求。
2)namenode查看Metadata信息,返回fileA的block的位置。
block1:host2,host1,host6
block2:host7,host3,host4
3)block的位置是有先后顺序的,先读block1,再读block2。而且block1去host2上读取;然后block2,去host7上读取。
二、MapReduce工作原理可灵活回答:
1)MapReduce执行流程
2)对MapReduce的理解
3)MapReduce过程
4)MapReduce的详细过程
5)MapTask和ReduceTask工作机制
6)MapReduce中有没有涉及到排序
问过的一些公司:(美团最爱)美团×15,阿里×3,字节×6,头条,滴滴,百度,腾讯×4,Shopee,小米,爱奇艺,祖龙娱乐,360×5,商汤科技,网易×5,51×2,星环科技,招银网络,映客直播,字节×2,有赞,58×3,华为x2,创略科技,米哈游,快手,京东×3,趋势科技,海康威视,顺丰,好未来,一点资讯,冠群驰骋,中信信用卡中心,金山云,米哈游,途牛
1)准备一个200M的文件,submit中对原始数据进行切片;
2)客户端向YARN提交信息,YARN开启一个MrAppmaster,MrAppmaster读取客户端对应的信息,主要是job.split,然后根据切片个数(这里2个)开启对应数量的MapTask(2个);
3)MapTask通过InputFormat去读取数据(默认按行读取),K是偏移量,V是一行内容,数据读取后交给Mapper,然后根据用户的业务需求对数据进行处理;
4)数据处理之后输出到环型缓冲区(默认100M),环型缓冲区一边是存数据,一边存的是索引(描述数据的元数据)。环型缓冲区存储数据到达80%后进行反向溢写,并对数据进行分区、排序;
5)再对分区且区内有序的文件进行归并排序 ,然后存储到磁盘;
6)当所有MapTask任务完成后,启动相应数量的ReduceTask,并告知ReduceTask处理数据范围(数据分区)。注意:不是必须等到所有MapTask结束后才开始,可以自行配置。
7)ReduceTask开启后,ReduceTask主动从MapTask对应的分区拉取数据;
8)再对ReduceTask拉取过来的数据进行一个全局合并排序;
9)顺序读取数据,按key分,key相同的数据进入同一个Reducer,一次读取一组数据;
10)Reducer处理完数据,通过OutPutFormat往外写数据,形成对应文件。
简洁版:面试可手写
ZookeeperZookeeper的选举机制可灵活回答:
1)Zookeeper的选举策略
2)Zookeeper的选举过程
3)Zookeeper的Leader选举是如何实现的
问过的一些公司:阿里,字节x2,腾讯,贝壳,网易,去哪儿
1)半数机制:集群中半数以上机器存活,集群可用。所以Zookeeper适合安装奇数台服务器。
2)Zookeeper虽然在配置文件中并没有指定Master和Slave。但是,Zookeeper工作时,是有一个节点为Leader,其他则为Follower,Leader是通过内部的选举机制临时产生的。
3)选举过程
假设有五台服务器组成的Zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么。
(1)服务器1启动,发起一次选举。服务器1投自己一票。此时服务器1票数一票,不够半数以上(3票),选举无法完成,服务器1状态保持为LOOKING;
(2)服务器2启动,再发起一次选举。服务器1和2分别投自己一票并交换选票信息:此时服务器1发现服务器2的ID比自己目前投票推举的(服务器1)大,更改选票为推举服务器2。此时服务器1票数0票,服务器2票数2票,没有半数以上结果,选举无法完成,服务器1,2状态保持LOOKING
(3)服务器3启动,发起一次选举。此时服务器1和2都会更改选票为服务器3。此次投票结果:服务器1为0票,服务器2为0票,服务器3为3票。此时服务器3的票数已经超过半数,服务器3当选Leader。服务器1,2更改状态为FOLLOWING,服务器3更改状态为LEADING;
(4)服务器4启动,发起一次选举。此时服务器1,2,3已经不是LOOKING状态,不会更改选票信息。交换选票信息结果:服务器3为3票,服务器4为1票。此时服务器4服从多数,更改选票信息为服务器3,并更改状态为FOLLOWING;
(5)服务器5启动,同4一样当小弟。
HiveHive的内部表和外部表的区别问过的一些公司:字节,阿里社招,快手,美团x2,蘑菇街x2,祖龙娱乐,作业帮x2,360,小米,竞技世界,猿辅导,冠群驰骋,好未来,富途
内部表(managed table):未被external修饰
外部表(external table):被external修饰
区别:
1)内部表数据由Hive自身管理,外部表数据由HDFS管理;
2)内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定(如果没有LOCATION,Hive将在HDFS上的/user/hive/warehouse文件夹下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里);
3)删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;
4)对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name;)
FlumeFlume的source、channel、sink分别都有哪些可灵活回答:
1)Flume的source、channel、sink分别用的什么类型的?
2)Flume的Kafka sink
3)Flume分为哪几块?
4)channel的类型
问过的一些公司:阿里x2,腾讯,字节,快手x2,流利说,创略科技,宇信科技,猿辅导,转转,bigo,多益,富途x2
Flume组成架构如下图
Agent
Agent是一个JVM进程,它以事件的形式将数据从源头送至目的。
Agent主要由Source、Channel、Sink3个部分组成。
Source
Source是负责接收数据到Flume Agent的组件。
ChannelChannel是位于Source和Sink之间的缓冲区。因此,Channel允许Source和Sink运作在不同的速率上。Channel是线程安全的,可以同时处理几个Source的写入操作和几个Sink的读取操作。
SinkSink不断地轮询Channel中的事件且批量地移除它们,并将这些事件批量写入到存储或索引系统、或者被发送到另一个Flume Agent。
KafkaKafka是如何实现高吞吐的可灵活回答:
1)Kafka为什么低延迟高吞吐?
2)Kafka高吞吐的原因
3)Kafka为什么高可用、高吞吐?
4)Kafka如何保证高吞吐量?
问过的一些公司:蘑菇街x2,腾讯,美团x2,猿辅导,转转,小鹏汽车,京东,字节,网易
Kafka是分布式消息系统,需要处理海量的消息,Kafka的设计是把所有的消息都写入速度低容量大的硬盘,以此来换取更强的存储能力,但实际上,使用硬盘并没有带来过多的性能损失。
kafka主要使用了以下几个方式实现了超高的吞吐率。
1)顺序读写
kafka的消息是不断追加到文件中的,这个特性使kafka可以充分利用磁盘的顺序读写性能,顺序读写不需要硬盘磁头的寻道时间,只需很少的扇区旋转时间,所以速度远快于随机读写。
Kafka官方给出了测试数据(Raid-5,7200rpm):
顺序 I/O: 600MB/s
随机 I/O: 100KB/s
2)零拷贝
先简单了解下文件系统的操作流程,例如一个程序要把文件内容发送到网络。
这个程序是工作在用户空间,文件和网络socket属于硬件资源,两者之间有一个内核空间。
在操作系统内部,整个过程为:
在 Linux kernel2.2 之后出现了一种叫做"零拷贝(zero-copy)"系统调用机制,就是跳过“用 户缓冲区”的拷贝,建立一个磁盘空间和内存的直接映射,数据不再复制到“用户态缓冲区” 。
系统上下文切换减少为 2 次,可以提升一倍的性能。
3)文件分段kafka的队列topic被分为了多个区partition,每个partition又分为多个段segment,所以一个队列中的消息实际上是保存在N多个片段文件中
通过分段的方式,每次文件操作都是对一个小文件的操作,非常轻便,同时也增加了并 行处理能力
4)批量发送
Kafka允许进行批量发送消息,先将消息缓存在内存中,然后一次请求批量发送出去,比如可以指定缓存的消息达到某个量的时候就发出去,或者缓存了固定的时间后就发送出去 ,如100 条消息就发送,或者每5秒发送一次,这种策略将大大减少服务端的I/O次数
5)数据压缩
Kafka 还支持对消息集合进行压缩,Producer可以通过GZIP或Snappy格式对消息集合进行压缩,压缩的好处就是减少传输的数据量,减轻对网络传输的压力,Producer压缩之后,在 Consumer需进行解压,虽然增加了CPU的工作,但在对大数据处理上,瓶颈在网络上而不是 CPU,所以这个成本很值得。
HBaseHBase的rowkey设计原则可灵活回答:
1)HBase如何设计rowkey?
2)你HBase的rowkey为什么这么设计?有什么优缺点?
3)Hbase rowKey设置讲究
问过的一些公司:阿里x3,腾讯x2,美团x3,顺丰,360,小米x4,富途,蘑菇街,陌陌x2,美团,冠群驰骋,携程x2,vivo
HBase中,表会被划分为1...n个Region,被托管在RegionServer中。Region二个重要的属性:StartKey与EndKey表示这个Region维护的rowKey范围,当我们要读/写数据时,如果rowKey落在某个start-end key范围内,那么就会定位到目标region并且读/写到相关的数据。
那怎么快速精准的定位到我们想要操作的数据,就在于我们的rowkey的设计了。
设计原则如下:
1、rowkey长度原则
Rowkey是一个二进制码流,Rowkey的长度被很多开发者建议说设计在10~100个字节,不过建议是越短越好,不要超过16个字节。
原因如下:
1)数据的持久化文件HFile中是按照Key Value 存储的,如果Rowkey过长比如100个字节,1000万列数据光Rowkey就要占用100*1000 万=10亿个字节,将近1G数据,这会极大影响 HFile的存储效率;
2)MemStore将缓存部分数据到内存,如果 Rowkey字段过长内存的有效利用率会降低,系统将无法缓存