大数据·Java面试题红宝书
红宝书目录
说在前面
你好! 各位萌新!
阳光明媚风清云淡,是这个“金三银四”季节里最美好的回忆。
正是这个招聘热潮,激励着每一个怀揣梦想的人儿奋斗不息,拼搏不止。
找到一个让自己满意的工作,是一件多么让自己高兴的事情。
而每一次面试,面对不同项目组不同需求,不同侧重,我们又是在一次又一次的挫折中不断成长。
作者在找到工作前,几乎每一天都在面试。
面对不同的面试官,不同的面试题,有过潇潇洒洒谈吐优雅,有过支支吾吾语塞脸红。
这些也都积淀下来成为了技术研究路上不可磨灭的回忆。
本着互相成就的精神,这里写下来历次面试中,面试官的真实面试案例,以及不完整的解析,不足之处请指正。
面试题目侧重不同,难易度也不尽相同,希望能够帮助辛勤拼搏的每一个求职者,祝大家好运。
写于2019/03/21,家中。
大数据面试题
Hadoop和Spark运行模式有哪些?
Spark运行模式有四种,分别是:
- 本地模式:Spark单机运行,一般用于开发测试。
- Standalone模式:构建一个由Master+Slave构成的Spark集群,Spark运行在集群中。
- Spark on Yarn模式:Spark客户端直接连接Yarn。不需要额外构建Spark集群。
- Spark on Mesos模式:Spark客户端直接连接Mesos。不需要额外构建Spark集群。
Hadoop运行模式有三种,分别是:
- 单机模式。
- 伪分布式。
- 完全分布式。
工作中用的复杂一点的MR
略。
HDFS的主要节点
HDFS中主要节点有三个,分别是:1)NameNode;2)SecondaryNameNode;3)DataNode。
- NameNode:NameNode维护着HDFS中的元数据信息,包括文件和Block之间关系的信息、Block数量信息、Block和DataNode
之间的关系信息。
NameNode中的元数据信息存储在内存以及文件中,内存中为实时信息,文件中为数据镜像作为持久化存储使用。
文件包括:
fsimage 元数据镜像文件。存储某NameNode元数据信息,并不是实时同步内存中的数据。
edits 操作日志文件,记录了NameNode所要执行的操作。
fstime 保存最近一次checkpoint的时间。
当有写请求时,NameNode会首先写editlog到磁盘edits文件中,成功后才会修改内存,并向客户端返回。所以,fsimage中的数据并不是实时的数据,而是在达到条件时再进行更新,更新过程需要SecondaryNameNode参与NameNode的metadata信息会在启动后加载到内存中。
为了防止在同一台服务器上启动多个namenode,会在namenode节点上多出一个dfs/name/in_use.lock文件。
查看edits文件:hdfs oev -i edits_inprogress_0000000000000000001 -o edits.xml -p XML
查看fsimage文件:hdfs oiv -i fsimage_0000000000000000008 -o aa.xml -p XML
- SecondaryNameNode:SecondaryNameNode并不是NameNode的热备份,而是协助者帮助NameNode进行元数据的合并,从另外的角度来看可以提供一定的备份功能(不能保证所有的数据都能恢复,只有在数据产生合并的时候才有这种性能),但并不是热备,这种合并过程可能会造成极端情况下数据丢失!可以从snn中恢复部分数据,但是无法恢复全部。
何时触发数据合并?
根据配置文件设置的时间间隔:fs.checkpoint.period 默认3600秒。
根据配置文件设置的edits log大小 fs.checkpoint.size 默认64MB。
当Hadoop被重启的时候,也会触发合并。
合并过程
达到条件后 snn会将nn中的fsimage和edits文件通过网络拷贝过来,同时nn中会创建一个新的edits.new文件,新的读写请求会写入到这个edits.new中,在snn中将拷贝过来的fsimage和edits合并为一个新的fsimage,最后snn将合并完成的fsimage文件拷贝回nn中替换之前的fsimage,nn再将edtis.new改为edits。
由于NameNode实时数据都在内存中,此处的合并指的是磁盘中的持久化的数据的处理。
判断:snn可以对元数据做一定程度的备份,但是不是热备,对不对?
思考:什么情况下可能造成NameNode元数据信息丢失?
snn并不是nn的热备,但是能保存大部分备份数据。原因就在于edits.new中的数据丢失了就找不回来了。
通常NameNode和SNN要放置到不同机器中以此提升性能,并提供一定的元数据安全性。 - DataNode:在hadoop中,数据是存放在DataNode上面的。是以Block的形式存储的。DataNode节点会不断向NameNode节点发送心跳报告。初始化时,每个数据节点将当前存储的数据块告知NameNode节点。通过向NameNode主动发送心跳保持与其联系(3秒一次)。后续DataNode节点在工作的过程中,数据节点仍会不断的更新NameNode节点与之对应的元数据信息,并接受来自NameNode节点的指令,创建、移动或者删除本地磁盘上的数据块。如果10分钟都没收到dn的心跳,则认为其已经lost,并copy其上的block到其他DataNode上。注意,在HDFS中,DataNode上存储的复本Replication是多复本策略。默认是三个。
MapReduce Shullfer过程以及调优
Shuffle过程图
MapReduce Shullfer过程分为Map阶段和Reduce阶段,同时Shullfer调优也围绕着这两个阶段进行。
Map阶段:
- MapTask在接收到FileSplit之后进行按行读取。
- 每读取一行调用一次map方法。
- 执行完一次map之后会将输出的数据写到缓冲区中。
- 缓冲区的大小默认是100M,可以通过io.sort.mb来进行调节。
- 在缓冲区中,会对数据进行分区-partition,排序 - sort,合并 - combine操作。
- 当缓冲区的容量利用率达到阈值0.8的时候,会启动给一个后台线程将缓冲区中的数据写到指定目录下的溢写文件中,这个过程称之为是溢写 (Spill)。
- 每次的Spill都会产生一个新的溢写文件。
- 等最后所有的数据都写完之后,会将所有的溢写文件进行一次合并 (merge),合并到一个新的分区并且排序的文件中。
- 如果在最终合并的时候,溢写文件个数>=3,那么合并完成之后会再执行一次Combiner。
注意:
- 当产生溢写的时候,缓冲区最后残留的数据会flush到最后一个溢写文件中。
- Spill理论上默认是80M,但是要考虑序列化以及最后的冲刷等因素。
- 不能凭借一个MapTask处理的切片大小来衡量MapTask之后的输出数据的多少。
- 每一个切片对应一个MapTask,每一个MapTask对应一个缓冲区。
- 缓冲区本质上是一个字节数组。
- 缓冲区又叫环形缓冲区,好处在于可以重复利用同一块地址的缓冲区。
- 阈值的作用是避免Spill过程产生阻塞。
- merge过程可能不会发生。
Reduce阶段:
- ReduceTask通过Http的方式来得到输出文件的分区,这个过程称之为fetch。
- 每一个ReduceTask将获取的分区的数据再次进行merge,然后进行排序,将相同的key做聚合,将值放入迭代器中。
- 调用reduce方法,将key和迭代器传入。
注意:
- fetch的默认线程数是5,
- ReduceTask的阈值为5%,即当5%的MapTask完成之后,ReduceTask就开始启动。
- Merge因子默认为10,即每10个文件合并成一个文件。
Shuffle调优:
Map阶段:
- 调大缓冲区,一般可以调为250~350M。
- 可以引入combine过程。
- merge之后的文件可以进行压缩,减少网络传输的消耗。
Reduce阶段:
- 增多fetch的线程数。
- 降低ReduceTask的阈值。
- 提高merge因子。
Java面试题
SpringMVC核心组件
-
前端控制器(DispatcherServlet):
本质上是一个Servlet,相当于一个中转站,所有的访问都会走到这个Servlet中,再根据配置进行中转到相应的Handler(Controller)中进行处理,获取到数据和视图后,在使用相应视图做出响应。 -
处理器映射器(HandlerMapping):
本质上就是一段映射关系,将访问路径和对应的Handler(Controller)存储为映射关系,在需要时供前端控制器查阅。(解析页面请求) -
处理器适配器(HandlerAdapter):
本质上是一个适配器,可以根据要求找到对应的Handler(Controller)来运行。前端控制器通过处理器映射器找到对应的Handler信息之后,将请求响应和对应的Handler信息交由处理器适配器处理,处理器适配器找到真正handler执行后,将结果即model和view返回给前端控制器 -
视图解析器(ViewResolver):
本质上也是一种映射关系,可以将视图名称映射到真正的视图地址。前端控制器调用处理器适配完成后得到model和view,将view信息传给视图解析器得到真正的view。
SprintMVC请求响应流程图解:
SpringMVC中的重定向和转发的实现
请求转发和重定向的区别:
“请求重定向”和“请求转发”都是web开发中资源跳转的方式。
请求转发是服务器内部的跳转:
- 地址栏不发生变化;
- 只有一个请求响应;
- 可以通过request域传递数据。
请求重定向是浏览器自动发起对跳转目标的请求:
- 地址栏会发生变化;
- 两次请求响应;
- 无法通过request域传递对象。
SpringMVC中实现转发和重定向:
-
在SpringMVC中仍然可以使用传统方式实现转发和重定向:
request.getRequestDispatcher("").forward(request,response);
response.sendRedirect("")
-
在SpringMVC中也提供了快捷方法实现转发和重定向,只要在返回时图时,使用如下方式指定即可:
redirect:/xxx.action
forward:/xxx.action
数据库面试题
Python面试题
结语
更新于2019.03.22日,暂未完结,将持续更新。