说实话,这半年我在团队里也参与了不少大数据方向的面试。面下来有个感受特别明显:很多候选人简历上写着“熟悉Hadoop”,能流畅背诵“HDFS是分布式文件系统、MapReduce是计算框架、YARN是资源调度”,但一旦追问到“写一个文件具体发生了什么事”“Shuffle到底在洗什么”“两个任务同时跑抢占资源怎么办”,答不上来的人不少。
这个现象本身并不奇怪。Hadoop是一套有了年头的技术栈,网上资料多且杂,很多教程把概念和原理隔离开来,背概念的人多,真正把链路串起来的人少。而面试官恰恰最喜欢从链路入手,因为链路能考察一个人是真懂还是面经背得熟。
这篇不打算按教材顺序把三大组件平铺一遍,而是按我实际面试时提问的优先级和踩过的高频坑,把HDFS、MapReduce、YARN里最容易被追问的考点拆开讲。内容包括原理拆解、面试答题的思路、以及一些文档里不会写但真实环境中一定会遇到的细节。无论你是正在准备面试,还是刚学完Hadoop想建立整体认知,这篇应该都能帮上忙。
1. 面试官问Hadoop,首先想探的底是什么
很多准备面试的人喜欢去背“HDFS优点”“MapReduce缺点”这种罗列型问题,这当然要准备,但不是核心。面试官问Hadoop,真正想快速确认的是你有没有一套完整的“数据流转”心智模型——一份数据从落盘、被计算、到资源分配完毕,中间经过了哪些环节,谁在什么时机做了什么。
1.1 三件套的分工边界,比背诵更重要
先给一个最基本的框架,HDFS解决的是“数据往哪存”的问题,MapReduce解决的是“数据怎么算”的问题,YARN解决的是“计算需要用的资源谁来给”的问题。三者更像是接力关系:HDFS先把数据分块存好,YARN负责给计算任务分配容器,MapReduce的Task在这些容器里真正跑起来。
面试中常见的一个误区是把HDFS和MapReduce的关系理解成“强绑定”,仿佛MapReduce只能算HDFS上的数据。这个理解需要修正。MapReduce完全能处理本地文件系统或其他数据源的数据,只是生产环境中HDFS是它最常搭配的存储层。类似的,YARN也不只是为MapReduce服务的,Spark、Flink跑在YARN上的场景非常普遍。
明白了这一点,面试时被问到“Hadoop和Spark的区别”这种跨框架问题,就不会只停留在“内存计算比磁盘快”的浅层,而是能讲出:Spark之所以能取代MapReduce的很多场景,关键在于它把计算过程中的中间结果留在内存,而MapReduce每个Job都会把中间结果落到磁盘,Shuffle之后又是一轮落盘,IO开销自然大得多。
1.2 高频考点分布,按投入产出比排序
以我面试他人的经验看,三大组件的提问密度其实不平均。HDFS里最常考的是读写流程、副本放置策略、元数据管理、小文件问题——尤其是小文件,已经被问烂了但依然在考察列表上。MapReduce里,Shuffle机制是绝对核心,没有之一,数据倾斜和Join优化紧随其后。YARN里,调度器的对比、任务提交流程、Container和资源隔离是重点。
这个排序背后有逻辑:这些点都指向生产环境里真正会遇到的问题。小文件会导致NameNode内存压力大,数据倾斜会让整个Job跑得奇慢,调度器选错会让不同业务线互相抢资源。面试官问这些,本质上是在判断一个候选人有没有处理真实问题的能力,而不是单纯考察记忆量。
2. HDFS面试题:从写文件到读文件,链路必须完整
HDFS的考题,看起来花样多,但都绕不开一条主线——数据是怎么可靠地存下来、高效地读出去的。把这条主线的每一步吃透,应付大部分追问就够用了。
2.1 写入流程:一次写操作里,各角色的完整动作
先回答一个高频开胃题:客户端往HDFS写一个200MB的文件,经历了什么?
这个问题标准答案分六步,但每一步都要能展开讲“为什么”。第一步,客户端调用DistributedFileSystem.create(),向NameNode发起创建请求。NameNode这时候做的事情不只是记录一个文件名,它会检查权限、检查父目录是否存在、确认客户端有写权限,通过后才在命名空间里创建文件条目,注意此时文件是处于写入状态的。
第二步,NameNode返回一个FSDataOutputStream给客户端,但真正能开始写数据前,客户端要先拿到“数据该往哪个DataNode写”的指示。这时候NameNode会根据网络拓扑选出一批DataNode节点,组成一条管道,默认副本数是3,所以通常是3个节点。
第三步是真正写数据的过程。客户端把文件切分成128MB的数据块,第一个块先写入第一个DataNode,第一个DataNode接收完同时转发给第二个DataNode,第二个再转发给第三个——这就是“流水线复制”,省去了客户端逐个节点上传的通信开销。
第四步是关于确认的。每个DataNode写完数据块后会往上游返回确认包,一路传回客户端。客户端收到整条管道的确认后,才会认为这个块写成功了,然后继续写下一个块。
第五步,文件最后一个块写完并确认后,客户端调用close(),正式告知NameNode文件写入完毕。NameNode此时才把文件状态从“正在写入”切换为“已完成”,文件对外可见。
第六步,如果中途某个DataNode写失败了,管道会断开,客户端会向NameNode重新申请一批新的DataNode,NameNode会把已经写成功的副本数记录下来,后续通过异步复制机制把副本数补齐。
面试加分点在于一个容易被忽略的细节:写入过程中,如果客户端一直不调close(),这个文件在NameNode的命名空间里会一直处于“写入中”状态,不对外可见但已经占用元数据条目。生产环境遇到进程异常退出留下的临时文件,就是这个机制的结果。
2.2 读流程与副本策略:为什么这么选节点
读取流程比写入简单一些。客户端调open(),NameNode返回文件每个块对应在哪些DataNode上的信息,客户端根据就近原则(优先本机,其次同机架,最后跨机架)选择DataNode读取数据。如果读某个块时该DataNode出错了,客户端会自动换一个节点继续读,这个过程对上层API是透明的。
副本放置策略是另一个高频追问题。默认3副本的策略是:第一个副本放在客户端所在的节点上,如果客户端不在集群内,则随机选一个节点;第二个副本放在与第一个副本不同的机架上;第三个副本放在第二个副本所在的机架但不同的节点上。
这个策略设计的核心是权衡。第一个副本放本机,是为了让写入时能直接利用本机磁盘IO,省一次网络传输;第二个副本放跨机架,是为了容灾——一个机架整体断电时数据不会丢;第三个副本放同机架不同节点,是为了省网络带宽,因为同机架内的节点间网络延迟远低于跨机架。
面试延伸题经常会考:2副本和3副本的差异、副本系数调低后数据可靠性怎么保障、机架感知没配置会有什么后果。机架感知这个问题容易被轻视——如果集群没配置机架感知,NameNode会默认把所有节点当成同一个机架,此时副本策略里的“不同机架”就形同虚设,跨机架容灾能力直接打折。
2.3 NameNode元数据管理:fsimage、edits与checkpoint
NameNode不存真实数据,存的是元数据:文件系统的目录树、文件与块的映射关系、块与DataNode的映射。这些元数据在内存里有一份完整镜像,磁盘上则通过fsimage和edits两个文件持久化。
fsimage是文件系统元数据的快照,edits是每次操作产生的增量日志。NameNode启动时会把fsimage加载进内存,再逐条回放edits里的操作日志,最终构建出最新的元数据状态。这样设计的原因很朴素:每次操作都直接改fsimage的成本太高,而把操作追加写到edits里是顺序IO,速度快得多。
但edits无限增长会带来问题:重启时回放日志时间太长,而且edits文件过大后NameNode自身管理也不方便。于是有了Checkpoint机制,由 SecondaryNameNode(或者HA模式下的Standby NameNode)定期合并fsimage和edits,生成新的fsimage。老版本里有人误以为SecondaryNameNode是NameNode的热备,这个认知需要澄清,它只负责定期合并元数据镜像,并不提供故障自动切换能力。
面试中容易接不住的是这两个追问:NameNode宕机了怎么办?数据会丢吗?答案取决于集群是否启用了HA。生产环境必须启用HA,让Active和Standby两个NameNode共享JournalNode里的编辑日志,Active挂掉后Standby能快速切换上岗。至于丢不丢数据,要看写入确认机制——如果客户端已经收到写入成功的确认,说明edits已经落盘并且同步到了JournalNode,通常不会丢,但宕机瞬间刚好在内存里未落盘的极短窗口内数据则有丢失风险。
2.4 小文件问题:一个被问烂但依然要会的经典
小文件问题之所以经典,是因为它直接牵扯HDFS的两个核心性能瓶颈:内存和IO。NameNode把所有元数据都放在内存中,一个文件无论大小,大约会占用150字节左右的元数据空间。别小看这个数字,当集群里有上亿个小文件时,NameNode内存会被吃掉一大块。
雪上加霜的是,MapReduce处理小文件时每个文件至少会生成一个InputSplit,对应一个Map任务,Map任务启动是有开销的,任务数量一多,调度成本、进程启动开销都会把整体计算效率拖垮。
面试里被问到“怎么解决小文件问题”,光说一个“合并小文件”是不够的。更完整的思路是分场景处理:数据写入阶段用SequenceFile或CombineFileInputFormat来合并;已存在的小文件通过HDFS自带的工具或Spark任务重分区来合并;流式写入场景下控制刷盘频率,避免频繁产生小文件;上线前制定分区策略,按时间或业务维度聚合数据,从源头减少零碎文件的产生。
这里我给一个实际建议:很多小文件问题的根源不在HDFS本身,而在上游写入端的配置。比如Kafka消费后直接落HDFS、又没有按时间窗口做攒批的话,小文件几乎是必然出现的。面试时如果能提到“我应该先去查上游写入频率和刷盘策略”,比直接背合并方案的区分度要高很多。
3. MapReduce面试题:Shuffle是分水岭
MapReduce这块,只要面试官的深度超过“什么是Mapper和Reducer”,必考Shuffle。因为Shuffle是MapReduce里最复杂、最影响性能的环节,也是最能区分“背过概念”和“真写过作业”的分界线。
3.1 Shuffle的完整步骤:Map端和Reduce端都说透
先明确一个定义:Shuffle指的是Map的输出到Reduce的输入之间,数据如何分区、排序、合并、传输的过程。它横跨Map端和Reduce端,是MapReduce性能的“咽喉”。
Map端有几件事按顺序发生。Map函数处理完一条数据后,输出结果不是直接写磁盘,而是先写进一个环形内存缓冲区,默认大小100MB。这个缓冲区被设计成环形是为了复用内存,一边写一边判断是否要溢写。当缓冲区使用率达到阈值(默认80%)时,后台线程开始把数据溢写到本地磁盘,这个过程叫spill。
Spill不是简单的倾倒。在spill之前,数据会先做分区——根据Reducer的数量把Map输出分成多个区,每个区对应一个Reducer;然后在每个分区内按键排序。如果用户设置了Combiner,排序后还会先做一次局部合并,把同键的值先在Map端聚合一遍,减少最终写入磁盘和网络传输的数据量。每次溢写会产生一个小文件,当Map任务结束时,可能会有多个溢写文件,这些文件会被归并排序成一个大的输出文件,其中同一个分区的数据是排好序的。
这里有一个很多候选人忽略的细节:环形缓冲区溢写的触发时机是异步的,Map函数线程不会因为后台在溢写就停下等待。数据一边写入一边溢写,如果写入速度长期高于溢写速度,缓冲区满了之后Map线程会被阻塞,直到溢写完成。真实环境中Job卡住,很大概率是这个环节背锅——比如Map端输出数据太大,或者Combiner没设置,溢写次数太多。
Reduce端的过程同样值得细讲。Reduce任务启动后,会启动若干个Fetcher线程,从各个Map任务的输出文件里拉取属于自己的分区数据。拉取到的数据先放在内存缓冲区,放不下就落盘。所有数据到齐后,Reduce端再做一次归并排序,把来自不同Map任务的相同键的数据整合到一起,形成“键—值列表”的输入结构,然后才调用Reducer函数。
面试加分点:Map端溢写时用了Combiner,Reduce端拉取来的数据又做了一次合并,两处合并的目的一样但粒度不同。Map端的Combiner是“预先聚合”,Reduce端的归并是“最终归并”。如果键的分布本身很集中,Combiner收益极高,整个Job可能快一倍都不止。
3.2 数据倾斜:追问题里出现频率最高的场景
数据倾斜是MapReduce生产环境最常遇见的性能问题。表现形式非常典型:整个Job执行时间很长,大部分Map或Reduce任务早就跑完了,就剩一个或少数几个任务卡在99%不动,日志里能明显看到某个Reduce输入的键包含大量数据。
根因不复杂——数据分布天然不均匀。比如按用户ID分组,头部用户的数据量可能是普通用户的几十倍。Reduce处理这种倾斜键时,其他Reducer都闲着,只有它一个在那儿慢慢消化,木桶效应被无限放大。
解决思路我按优先级推荐三种。第一种是提前设计,在业务层面让键更分散,比如加上随机后缀把一个大键拆成多个键,处理完成后再聚合。第二种是设置Combiner,让倾斜数据在Map端先合并一次,减轻Reduce的输入压力。第三种是用自定义分区器,把倾斜的键单独分到一个Reducer里处理,避免影响其他Reducer。
这里我要提醒一个实际经验:面试时回答“加Combiner就能解决数据倾斜”是不对的。Combiner解决的是“Map输出中有大量重复键需要合并”的情况,如果倾斜本身就是数据分布极度不均匀,Combiner能合并的数量有限,根本问题还是要靠拆分键。很多候选人分不清这两种情况的边界,面试官稍一追问就露馅。
3.3 Join优化:Map端Join与Reduce端Join的取舍
两个表Join是数据开发最常见的操作,面试官也喜欢从这个角度考察候选人是否真的理解MapReduce的计算模型。基础题是先讲清楚Reduce端Join怎么做:Map端给每条数据打标签,标明来自哪个表,以Join键作为输出键,Reduce端把同一个键下所有来自两个表的数据收集起来,再做笛卡尔积拼接。
Reduce端Join的问题一眼就能看出来——所有Join操作都在Reduce阶段进行,网络传输的是全量原始数据,Reduce端压力巨大,而且一旦存在数据倾斜,问题会加倍放大。
优化路径有两条。一条是Map端Join,适用于一个大表和一个足够小的表。做法是利用DistributedCache在Map任务启动前把小表分发到所有节点,Map读大表数据时直接从本地内存里查小表数据完成Join,整个过程没有Reduce阶段。这是剥离了Shuffle的优化,性能提升非常明显。另一条是SemiJoin或分桶优化,先把大表中用不到的键过滤掉,减少传输数据量。
面试时如果能补充一句“Map端Join并非万能,小表过大会导致节点内存压力增加”,会显得理解更全面。因为Map端Join本质上是用内存换网络和磁盘开销,小表的大小上限是需要实测和评估的,不能拍脑袋说“小于多少KB就能用”。
3.4 Combiner与Partitioner:两个容易被低估的配角
Combiner和Partitioner在面试中经常作为独立问题出现。Combiner的经典陷阱题是“Combiner能不能直接复用Reducer的逻辑”——答案是不能,因为Combiner是本地聚合,Reducer的逻辑可能包含全局聚合的语义。最典型的例子是求平均值:假设两个Map各输出两个键值对,平均值函数在Combiner里运行后,局部均值再求均值,结果不等价于全部数据的均值。能准确讲出这一个例子的候选人,基本证明了他是真的理解这两者的区别。
Partitioner则决定了一条数据去往哪个Reducer。默认的HashPartitioner是根据键的哈希值对Reducer数量取模,用户可以通过继承Partitioner来自定义分配逻辑。它的典型应用场景是全局排序——默认哈希分区无法保证各区数据的整体有序性,只能保证区内有序,要全局有序需要自定义分区器,让分区边界严格按键值范围划分。
生产环境还有一类常见用法:数据按业务维度分区,比如按日期分区,可以让每天的数据落到固定的Reducer里,便于下游按天处理,而不是分散到所有Reducer中再做一次全局扫描。这种“分区即业务分组”的思路,面试中聊起来很容易加分。
4. YARN面试题:资源调度与任务编排的底层逻辑
YARN在Hadoop三件套里是最晚出现但位置最关键的一块。面试官问YARN,目标一般很明确:考察候选人能不能把一个任务从提交到运行完成的整条链路说清楚,以及面对多个任务争抢资源时有没有判断力。
4.1 任务从提交到运行的完整链路
一个MapReduce Job提交到YARN上运行,完整流程是:客户端先创建一个ApplicationContext,向ResourceManager提交应用。ResourceManager收到请求后,会为这个应用分配一个容器,并在容器里启动ApplicationMaster,也就是应用的主控进程。
ApplicationMaster启动后,它的职责是向ResourceManager申请后续Task运行所需的资源。注意这个细节——ApplicationMaster不是自己在干活的,它是代表应用向ResourceManager“谈判”资源的。它会周期性发送心跳,携带当前已运行Task数和需要的资源量,ResourceManager收到后分配新的Container给ApplicationMaster,ApplicationMaster再把具体的Map或Reduce Task调度到对应的NodeManager上启动。
NodeManager是每个节点上的代理进程,负责启动容器、监控容器资源使用、汇报状态给ResourceManager。Task运行完成后,ApplicationMaster向ResourceManager注销应用,整个生命周期结束。
面试常追问“ResourceManager挂了会怎样”。这个问题的答案在生产环境比较沉重——集群中所有正在运行的应用都会受影响,因为ApplicationMaster和NodeManager都依赖ResourceManager做资源协调。所以HA部署几乎是标配,通过ZooKeeper实现Active/Standby切换。另一个容易混淆的点是:ResourceManager挂了不等于正在跑的Task立刻被杀掉,如果ApplicationMaster已经拿到了资源,容器内的任务还能继续跑,只是新任务的提交和资源申请会阻塞。
4.2 三种调度器:FIFO、Capacity、Fair
调度器是YARN面试题里的主干道,尤其是“你们生产环境用的哪种调度器,为什么”这种实战向问题。
FIFO是先进先出调度器,按提交顺序逐个执行应用,一个应用占用的资源不释放就不会轮到下一个。这个调度器的问题是集群利用率低——先提交的大作业把资源全占住,后提交的小作业只能等。单机环境或测试环境偶尔能用,生产集群基本不会选它。
Capacity调度器把集群资源划分成多个队列,每个队列有独立的容量上限,队列内再按FIFO或优先级调度。它解决了多团队共用集群时的资源隔离问题——A团队的作业再大,也不能把B团队的队列资源挤占干净。它的特点是“硬隔离”,队列间资源不能互相借用,空闲时利用率可能有损失。
Fair调度器的核心是“资源公平共享”——所有应用动态地平分集群资源。当一个新应用提交上来时,正在运行占用较多资源的应用会逐步释放一部分容器,让新应用能启动。它的好处是利用率高、任务间公平性好,但代价是资源分配不立刻生效,任务之间的切换有延迟,而且配置不好时容易造成任务频繁被抢占、反复重试。
表格对比更直观:
| 对比维度 | FIFO | Capacity | Fair |
|---|---|---|---|
| 调度核心 | 先来先服务 | 队列容量隔离 | 实时公平共享 |
| 集群利用率 | 低 | 中 | 高 |
| 多租户隔离 | 无 | 强 | 中 |
| 典型场景 | 测试环境 | 多部门生产集群 | 共享集群多任务混跑 |
面试如果被问到“你们怎么选”,比较稳的回答思路是:多团队共享生产集群选Capacity,保证核心业务队列不会被离线任务挤爆;如果集群主要跑多个对延迟不敏感的任务、希望最大化利用率,选Fair。
4.3 Container与资源隔离:可以深挖的细节
Container是YARN中资源分配的最小单位,一个Container包含一定量的CPU和内存,由NodeManager负责启动和监控。Container的出现把“资源”这个概念从“一台机器”细化到了“一块可分配的资源配额”,这是YARN能实现多租户共享的关键。
关于资源隔离,需要区分两个维度:CPU隔离和内存隔离。内存隔离主要靠操作系统的资源限制机制来实现,超限会被直接杀掉进程。CPU隔离早期版本更多是“软隔离”,通过调度权重来保证,后来引入Linux容器等机制后,隔离强度才上来。面试中被追问“资源是怎么被隔离的”,能答出“内存靠硬限制,CPU靠权重调度和Linux隔离机制”,就已经比多数候选人深了一层。
还有一个常见问题:一个任务的Container数量和并行度是什么关系。MapReduce里,Map Task的数量由输入分片数量决定,Reduce Task的数量由用户设置或估算,每个Task最终在Container里执行。并行度不等于Container数量——同一时刻真正并发运行的Task数量受集群可用资源上限约束,即使有1000个Task需要跑,可用资源只能支撑50个Container,那并行度就是50,其余任务排队。
4.4 资源不足时表现出的现象,以及排查思路
生产环境里,YARN队列资源打满时会有很典型的现象:应用一直处于ACCEPTED状态,申请不到Container;已经运行的任务执行速度变慢;有任务反复失败重试。定位这类问题,先看YARN的资源监控页面上每个队列的Pending和Running状态,再结合任务提交时间判断是不是排队导致的长尾。
一个我在实际中反复遇到的问题是默认参数不匹配。比如申请的内存过大,超过了NodeManager单容器允许的最大值,任务会直接提交失败,报错信息里一般会出现“required capacity exceeds maximum”之类的字样。这类问题排查不难,但前提是脑子里要有“YARN的资源申请是双向约束”的概念——既受队列容量约束,也受单节点Container上限约束。
5. 把这些知识点组织成一波有区分度的面试回答
知识是散的,面试表达需要结构。我建议准备面试的人按“定义—原理—为什么—场景化举例—不足之处”这个链路来组织任何一道Hadoop题的回答。定义先给边界,原理说明机制,为什么解释设计动机,场景化举例证明用过,不足之处证明思考过。
5.1 几种典型的面试追问走向
以“HDFS写流程”为例,基础回答是流程六步,但面试官通常会在某个节点上突然拐弯,常见拐法有三种。一种是问“写入过程中某个DataNode挂了怎么保证不丢数据”,这时候要把管道重建和副本复制机制讲清楚。另一种问“客户端写完一个块后是等所有副本都写完才确认还是写完第一个就确认”,答案是等整条管道都确认。第三种问“数据块大小能不能改”,这里要给出权衡框架——块太小导致元数据膨胀和Map任务数量暴增,块太大导致Map任务数量减少、并行度下降,128MB是经过实测的折中值。
MapReduce的Shuffle也常被引申到Spark上做对比——这正是很多候选人翻车的区域。回答的稳妥思路是:Shuffle的本质都是“上游数据按目标分区重新组织”,区别在于MapReduce的中间结果落盘和排序天然存在,而Spark的Shuffle过程可以配置是否排序、是否落盘,内存足够时可以走内存缓冲,减少IO开销。能从这个维度说,比单纯背“Spark快10倍”要有说服力得多。
5.2 容易踩的坑:概念混淆与空泛表达
面试中最减分的动作是把“明白”和“用过”混在一起。比如有人会说“我们公司的小文件用工具合并了”,但问他用的是什么工具、什么参数、合并后任务数量变化了多少,就沉默了。解决办法是哪怕只在测试环境跑过一个Demo,也要把具体参数和观察到的现象记在脑子里,一个30MB小文件的Merge任务,合并前后Map数从多少降到多少,这是可以在简历上写“有HDFS小文件处理经验”的真正底气。
另一个高频坑是“堆名词”式回答。比如被问到MapReduce性能优化时,嘴上说着“加内存、调并行度、开压缩、加Combiner”但无法针对场景排序优先级。如果面试官给一个具体场景——某Job的Reduce端明显比Map端慢,你首先考虑什么?最合理的排查顺序是:先看是否存在数据倾斜(观察各个Task完成时间的方差),再看Shuffle的数据量大不大(观察溢出磁盘量),然后才考虑调整Reduce数量或加内存。按排查顺序而非名词清单回答,面试观感完全不同。
5.3 我常用的一个面试准备方法:画数据流转图
给准备面试的朋友一个实操建议:找一张白纸,把“客户端提交一个文件”作为起点,一步步画出客户端、NameNode、DataNode、ApplicationMaster、ResourceManager、NodeManager之间所有交互箭头,标注每一步传输的关键数据。然后对着图反复问自己三个问题:这一步如果失败了怎么办?这一步的数据量大概多大?这一步有没有可能省掉?
这套方法我推荐过不少人,实际效果很好。因为面试官追问的路径往往就是这张图上的某一段链路,图在心里,回答就永远有“下一步”可以走。不是说非要背得滚瓜烂熟,而是当你对整个系统有了一张动态地图,任何追问都只是地图上的一次定位。
最后聊一点我在实际面试中比较看重的感受:候选人可以记不住某个具体参数,但不能没有“系统是协作的整体”这个意识。HDFS、MapReduce、YARN从来不是各自独立的三块功能,而是围绕“数据的存储—计算—资源管理”的三层协作。带着这个视角去准备面试,很多题目你会自动推导出答案,比你死记硬背十遍面经更管用。