简介:面向大数据开发、运维、云计算、数据治理与架构岗位的求职者,这份2023年整理的面试题集围绕大数据技术栈常见考点与项目追问展开,适合用于系统复习、面试前查漏补缺和梳理知识框架。资源为1个docx文档,压缩包约491KB,内容按基础命令与脚本、Hadoop生态、分布式协调、日志采集、消息队列、数据仓库、NoSQL、数据迁移以及Scala与Spark计算等模块组织,目录层级清晰,便于按技术域定位。已有882人学习下载。文档不仅覆盖HDFS读写流程、MapReduce Shuffle、YARN作业提交、Hive窗口函数与数据倾斜、HBase RowKey设计等基础题,也延伸到Kafka丢数据与重复消费、Flume防丢失机制、Sqoop一致性、Spark宽窄依赖与Shuffle流程、调优参数和项目经验追问,能帮助读者从概念记忆转向结合场景作答。适合中初级大数据从业者快速建立面试应答脉络,也可供架构与运维人员对照排查知识盲区。
1. 大数据面试题到底在考什么:从一道"数仓表跑多久"说起
很多人第一次被问"你们数仓每天跑多少张表、大概几点跑完、跑多久"时会愣住——组件原理背了一大堆,偏偏这种带数字的问题答不上来。这不是记忆力的问题,而是没搞明白这类问题到底在问什么。通俗地说,大数据面试题不是几百道彼此孤立的问答题,而是把一条数据从产生到变成报表的整条链路上,每个环节的关键决策点单独拎出来问一遍。它值得搞懂,是因为你答的每一题背后都对应着一次真实的取舍:这里为什么要加缓存、那里为什么要换分区、那个参数为什么不能再往上调。搞懂这张地图比背下答案有用得多。
2. 为什么大数据面试题长成一张技术栈地图:从采集到治理的固定顺序
把市面上流传的题库摊开看,章节顺序几乎一模一样:Linux 与 Shell、Hadoop、Zookeeper、Flume、Kafka、Hive、HBase、Sqoop、Scala、Spark、Flink,然后才是数仓架构、用户行为分析、业务数据分析、数据治理。这个顺序不是谁拍脑袋排的,它就是一条数据流水线的物理走向。理解了这条线,你就知道为什么某道题一定出现在某一章,也就能判断哪些题是同一类问题换了件衣服。
2.1 一条数据流水线决定了题目分布
想象一条河从上游流到下游。上游是业务数据库里的订单表、App 埋点产生的日志文件,它们分散在不同机器、不同格式里。第一站是采集,负责把数据搬出来,工具就是 Flume 和 Sqoop,一个盯日志文件,一个盯关系型数据库。搬出来之后不能直接怼进计算引擎,中间要有个缓冲池顶住流量高峰,这就是 Kafka 这类消息队列的位置。缓冲之后是落地存储,海量文件放 HDFS,需要按行键快速随机查询的放 HBase。再往上是计算,MapReduce 是元老,Spark 靠内存迭代提速,Flink 主打流式。计算结果要组织成能反复复用的表,于是有了 Hive 数仓和 ODS、DWD、DWS、ADS 这些分层。最后一站是调度、监控与治理,保证每天凌晨那一大批任务按顺序跑完,跑挂了有人知道,数据错了能追到源头。
这条线一旦画出来,题库的章节就有了归属。问 Flume 的 Channel 选择器,问的是采集站的缓冲策略;问 Kafka 的分区数和副本数,问的是缓冲池的容量与可靠性;问 Hive 的内部表和外部表,问的是数据落地后归谁管;问调度和工作流,问的是最后一站怎么保证顺序。面试官脑子里装的也是这条线,他问你某个组件,其实是在问"你负责的这一段,出问题时你怎么发现、怎么处理"。
所以备考时最忌讳的是把每一章当成独立的背诵单元。更有效的读法是:先想清楚这个组件卡在流水线的哪个位置,它上游是谁、下游是谁,然后问自己三个问题——数据从它这儿过一趟会变成什么形态,它在什么情况下会堵住,堵住了下游怎么办。这三个问题答得出来,那一章的绝大多数题目都能自己推出来,剩下要记的只是具体参数名。
2.2 为什么每个组件都爱问"丢不丢数据"
翻遍题库你会发现一个高频句式反复出现:Flume 采集数据会丢失吗、Kafka 丢不丢数据、Spark Streaming 怎么保证第一次运行不丢数据、Flink 如何保证精确一次。看起来是四个组件四道题,本质上是同一个问题被问了四遍。
为什么这么执着?因为这条流水线上任何一站丢数据,下游所有计算都是错的,而且错得悄无声息。报表少了几万条记录,业务方看到的是转化率莫名其妙掉了两个点,没人会立刻想到是采集端的问题。这种错误排查成本极高,所以可靠性成了整条链路的第一性要求,也成了面试的必考区。
打个比方,这条链路像一份需要层层签收的快递。Flume 的 Put 事务是"把包裹放进驿站并登记",Take 事务是"从驿站取走并核销",两个事务分开是为了保证要么都成功要么都回滚,不会出现包裹取走了但驿站还以为在库的情况。Kafka 的副本和 ISR 队列是"同一份快递复印几份放在不同仓库,只要还有一个仓库没烧掉就不算丢"。Spark Streaming 的预写日志是"先把要处理的清单抄在本子上再动手"。Flink 的检查点则是"定期给整个流水线拍一张合影,出事就按最近一张合影重来"。
回答这类问题的通用框架只有三步:数据可能在哪一步丢、靠什么机制兜底、兜底要付出什么代价。第三步最容易被忽略,也最能体现水平。副本数从二调到三,可靠性上去了,但存储成本和网络复制开销也跟着涨;检查点间隔从一分钟缩到十秒,恢复时丢的数据更少,但每次快照都要占用计算资源。能把这些代价说清楚,比背出机制名称更能让人信服。
2.3 "项目经验"那一章在验证什么
题库后半部分有一类题目特别扎眼:你们集群规模多大、一天导多少数据、数仓每天跑多少张表、并发峰值大概几点、项目三年迭代了几次、哪张表最费时间。这些问题没有标准答案,却最难准备。
原因很简单,参数可以查文档,容量规划的经验查不到。一个人如果真在生产环境里待过,他会记得集群大概多少台机器、每天增量数据是几百 G 还是几个 T、大促那天任务比平时晚跑了两个小时、某张订单宽表因为一个关联字段没走分区导致全表扫描。这些细节是血泪经验,编不出来,也背不下来。
这一章还顺带考察了 ETL 这个基础概念有没有落地理解。抽取、转换、加载三个词谁都说得出来,但面试官想听的是:抽取时全量和增量怎么选,转换时脏数据怎么处理,加载时用覆盖还是追加,出错了重跑会不会产生重复数据。题库里关于拉链表、同步策略、范式理论、维度建模的那些题,都是围绕这几个决策点展开的。真正做过一遍的人,讲这些会自然带出权衡,比如拉链表能保留历史变更但查询要处理起止日期,用起来比全量快照麻烦,什么时候值得用要看业务是不是真的需要回溯任意时间点的状态。
3. 高频概念拆解:Shuffle、数据倾斜、精确一次到底是什么
题库里被问得最密、最容易答得含糊的三个词,恰好也是整条链路上最贵的三个动作。它们贵在要跨机器搬数据、要等最慢的那个任务、要在出错时重放一整天。把这三个词讲明白,半本题库就通了。
3.1 Shuffle:把"重新分发"这件事讲明白
通俗地说,Shuffle 就是按某个规则把数据重新分堆。打个比方,一个年级的学生原本按班级站好了队,现在要求按姓氏首字母重新排队,每个班都要先把自己的人按姓氏拆成若干堆,再送到对应的新队伍里去。拆堆、搬运、合并,这三步就是 Shuffle 的全部。
具体到计算引擎里,Map 端读取数据、处理后,会根据 key 算出它该去哪个 Reduce 分区,然后写到本地磁盘上,先按分区归堆、再在分区内按 key 排序、最后合并成大文件减少磁盘寻道。Reduce 端则通过网络把属于自己的那一份拉过来,做归并后交给业务逻辑处理。整个过程涉及磁盘读写和网络传输,是所有算子中最重的一类。
这也解释了为什么 Spark 要区分宽依赖和窄依赖。窄依赖是"一个父分区的数据只喂给一个子分区",比如 map、filter,父子之间一对一,不需要跨机器搬运。宽依赖是"多个父分区的数据要汇总到同一个子分区",比如 groupByKey、join,必须搬。引擎在宽依赖处切开一个新的 stage,前面的全部算完才能开始后面的,所以 stage 的数量基本等于宽依赖的数量。至于每个 stage 里跑多少个 task,看的是这一阶段最后一个 RDD 有多少个分区,分区数决定了并行度,并行度不够就会有一堆数据排队等少数几个 task 慢慢啃。
题库里还会追问 HashShuffle 和 SortShuffle 的区别,这一问其实是在问"文件数量怎么控制"。早期的实现里,每个 Map 任务要为每个 Reduce 任务生成一个文件,M 个 Map 乘 R 个 Reduce 就是 M×R 个小文件,规模一大,文件句柄和磁盘随机读先扛不住。后来改成每个 Map 任务只产出一个按分区排好序的大文件,配合一个索引文件,文件数降到 2×M,Reduce 端按索引去拉自己那一段。这就是一次典型的用排序换文件数的取舍,理解了这个动机,就不需要死记流程图。
3.2 数据倾斜:不是数据多,是分配不均
数据倾斜这四个字很容易被误解成"数据量太大"。其实总量大不可怕,可怕的是分配不均。超市开了十个收银台,九个台前排三个人,剩下一个台前推着满满一车的人排到门外,整体结账速度就被那一个台拖死了。
在分布式计算里,数据是按 key 分到各个 task 的。如果某个 key 的记录数远超其他 key,比如一个默认值、一个空字符串、一个头部主播的 ID,那么这个 key 所在的那个 task 就要处理几千万条,而隔壁 task 可能只处理几千条。表现出来就是:任务进度条卡在 99% 一动不动,或者 Spark 界面上一堆 task 三秒跑完、个别 task 跑了四十分钟。这种"长尾"是调优里最典型的翻车现场。
定位方法比解决方案更重要。第一步看表现,是不是绝大多数 task 秒完而个别 task 迟迟不结束;第二步看分布,把可疑的那张表按 key 做一次计数,看第一名和第二名差多少个数量级;第三步看代码,找到那个 group by 或 join 的 key 是不是天然带有热点。三步走完,问题基本就水落石出了。
解决思路可以归成三类。第一类是让热点分散,给热 key 加随机前缀让它落到不同分区,算完再把前缀去掉做二次聚合,这就是常说的加盐。第二类是让小表绕路,如果 join 的一边足够小,直接广播到每个节点,把跨机器的大规模 Shuffle 变成各节点本地的小表查找,代价是内存。第三类是提前过滤,热点 key 里往往混着大量无效数据,比如测试账号、爬虫流量,在进入计算前就筛掉,比任何调优都省事。
-- 以用户活跃分析为例:统计最近七天内连续三天活跃的用户 -- 思路:先按用户和日期打标,再用日期减去序号,同一段连续日期会得到相同差值 SELECT user_id, COUNT(*) AS continuous_days FROM ( SELECT user_id, dt, -- 关键一步:日期减去排名,连续日期会归到同一组 DATE_SUB(dt, rn) AS grp FROM ( SELECT user_id, dt, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY dt) AS rn FROM user_active_log WHERE dt BETWEEN '2024-01-01' AND '2024-01-07' GROUP BY user_id, dt ) t1 ) t2 GROUP BY user_id, grp HAVING COUNT(*) >= 3;这段 SQL 就是题库里"最近七天内连续三天活跃用户数"的标准解法,它体现的是窗口函数的一个通用技巧:日期序列减去行号,连续区间会塌缩成同一个常量。没有窗口函数支持的场景,就得用自关联或者排序后打标的方式绕过去,代价是代码更长、执行更慢。面试里被问到这类题,先说思路再写代码,比直接默写更稳。
3.3 精确一次:不是玄学,是三段配合
"精确一次"听起来像某种神秘保证,其实拆开看就是三件事凑齐。第一,数据源要能重放,也就是出错重来时能回到同一个位置重新读。第二,计算中间状态要能恢复,靠的是周期性快照。第三,结果写出要能去重或原子提交,要么按主键覆盖,要么走事务。
打个比方,记账有两种做法。一种是每笔都先查一下这笔编号记过没有,记过就跳过,这叫幂等写入;另一种是先把草稿记在纸上,等确认无误再一次性誊到正式账本上,这叫事务提交。两种都能保证同一笔钱不会被记两遍,区别在于对下游系统的要求不同。
流式处理里最难的往往是最后一段。计算结果可能写到数据库、写到文件、写到另一个消息队列,每种下游对"原子提交"的支持程度不一样。所以面试官通常会追问"你们是怎么做到不重复的",标准回答不是喊口号说用了某个框架,而是说清楚偏移量在哪提交、提交和写出结果的先后顺序是什么、如果两者之间崩了会重复还是丢。能把这几个顺序关系讲清楚,说明真处理过。
4. 易混概念辨析:那些看起来差不多、答错就露怯的题
有些概念名字接近、结果相似,初学者极容易混着答。面试官抛这类题不是刁难,而是在试探你有没有真的动手做过——只有亲手踩过,才知道差别在哪。
4.1 内部表与外部表的易混点:删表的时候删不删数据
易混点:两者都建在分布式文件系统上,建表语句只差了 EXTERNAL 一个关键字,查询方式完全一样。
为什么混:平时写查询根本感受不到区别,只有执行删除表操作的那一刻,差异才暴露出来。
怎么区分:记住一句话,内部表是"表和数据同生共死",删表连数据目录一起删;外部表是"表只是数据的说明书",删表只删元数据,原始文件还在。判断标准是这份数据归谁管:如果是中间计算结果、只有这一条链路在用,用内部表省心;如果是采集上来的原始日志、可能还有别的团队在读,必须用外部表,否则某天有人执行一次误删,原始数据就没了。这是个典型的后悔药场景——建表时多打一个词,出事时少掉一整天数据。
4.2 reduceByKey 与 groupByKey 的区别:结果一样,代价差一个量级
易混点:两个算子都能把相同 key 的值聚到一起,最终结果看起来一样。
为什么混:写出来的代码形态相似,测试数据小的时候执行时间都只有几秒,看不出差别。
怎么区分:看 Map 端有没有提前聚合。reduceByKey 会先在每个分区内部对相同 key 做一次合并,再把合并后的小结果发往 Reduce 端;groupByKey 则把每个 key 的所有原始值原封不动地通过网络搬运过去,然后才在 Reduce 端做聚合。前者的网络传输量是"不同 key 的数量",后者是"总记录数",数据量一大就是几十倍的差距。经验法则是:只要后面接的是求和、求最大、求计数这类可结合的聚合,就用 reduceByKey 或者它的变体,别用 groupByKey。只有在确实需要拿到某个 key 下的全部原始明细时才用后者。
4.3 缓存与检查点的区别:一个保速度,一个保命
易混点:两个机制都是把计算结果存下来,避免重复计算,名字听起来都像"存档"。
为什么混:两者确实有重叠,缓存之后的中间结果在复用时会明显变快,检查点之后重启也能少算一段。
怎么区分:看存储位置和用途。缓存是把数据尽量放在内存里,快但不可靠——进程一挂,内存里的东西全没了。检查点是写到可靠的持久化存储上,慢但能救命——作业崩了重新拉起,可以从最近一次检查点恢复状态,还能顺带切断过长的依赖链。打个比方,缓存是把手边的工具摆在桌上,检查点是把图纸存进保险柜。另外,缓存的失效需要手动释放或等缓存被替换,检查点则是定期自动做的,用错了地方会白白吃掉存储。
4.4 批流一体与"批处理加流处理"的注意点:别把两套代码叫成一个词
易混点:很多人把"同一套系统里既有批任务又有流任务"说成批流一体。
为什么混:从使用者视角看,都是同一批数据被处理了两遍,感觉上确实是一体的。
怎么区分:真正的批流一体指的是同一套 API、同一个执行引擎,流式是批的特例或者批是流的特例,算子和状态管理复用同一套语义,切换只是改一个模式参数。而"两套代码各跑各的"只是共存,不是一体:逻辑要写两遍,两边的口径还可能对不上,改一个指标要改两处,长期维护成本极高。判断方法很简单,问一句"同一份业务逻辑,批和流能不能共用一份代码",能就是一体,不能就只是放在一起用。
5. 分岗位看题库:开发、运维、架构、治理问的其实不是同一套
同一份题库,不同岗位的面试官会从里面挑完全不同的题。投错重点,会出现"会的全没问、问的全不会"的尴尬。
5.1 开发岗:算子会不会用,调优有没有数
开发岗的题集中在 Spark 和 Flink 两章。手写代码部分会出排序、二分、快排这类基础算法,也会出 WordCount 这种入门级的分布式程序,还有一批手写 SQL 的题,比如连续活跃、留存、TopN、同环比。这些题的共同点是:不考你能不能背出语法,考的是你能不能在十几分钟内把思路讲清楚并写对边界。
调优类的题更吃经验。面试官会问提交作业时那几个关键参数怎么设,比如每个 executor 分配多少核心、多少内存,executor 数量怎么定,序列化用哪种。参数本身没有标准答案,他想听的推理链条是:集群有多少资源、数据量多大、算子是计算密集型还是 IO 密集型、有没有大量 Shuffle、内存里要不要缓存中间结果。能把自己项目里的数字和参数对应起来,比背默认值管用得多。
# 一个典型的提交命令(参数仅为示意,实际取值取决于集群规模和数据量) spark-submit \ --master yarn \ --deploy-mode cluster \ --executor-memory 8g \ # 每个 executor 的内存,要能装下单个 task 的 Shuffle 读缓冲 --executor-cores 4 \ # 每个 executor 的核心数,决定并行 task 数 --num-executors 20 \ # executor 总数,受集群可用资源上限约束 --conf spark.sql.shuffle.partitions=200 \ # Shuffle 后分区数,太少会倾斜,太多会调度开销大 --class com.example.JobMain \ app.jar这几个参数之间存在联动。增加 executor 数量能提升并行度,但会挤占集群资源;把每个 executor 的核心数调大,单机能跑的 task 变多,但共享内存竞争也更激烈;Shuffle 分区数按数据量估算,一般让每个分区的数据落在几十到两百兆之间比较舒服。面试里如果被问到"调优之前和之后有什么变化",最好的答法是给出前后对比的数字:原来多少个 task、单个 task 处理多少数据、耗时多少,调整后变成多少。数字比形容词有说服力。
5.2 运维岗:组件稳不稳,挂了怎么办
运维方向的题更关注"出事了怎么办"。Kafka 挂掉怎么恢复、Hadoop 节点宕机数据怎么补齐、Flume 采集端断网了积压怎么处理、集群磁盘写满了从哪儿开始查、任务堆积了怎么临时扩容。这类题的答案往往不是某个参数,而是一套排查顺序:先看监控指标定位到哪个组件异常,再看日志确认是资源不足还是配置错误,最后决定是重启、扩容还是限流。
这类岗位还会问集群规划和容量估算。每天增量多少、保留多少天、副本数设几个、需要多少磁盘、机器数量怎么算。计算过程本身不复杂:日增量乘以保留天数乘以副本数,再除以单机可用容量,留出三成余量。面试官想确认的是你有没有自己算过一遍,而不是抄了个结论。另外监控相关的题也要准备,比如消费延迟怎么监控、任务失败怎么告警、哪些指标最能反映健康状态。这些是日常工作的黑匣子,出事时全靠它还原现场。
5.3 架构与治理岗:分层合不合理,数据可信不可信
架构方向的题从组件细节跳到了全局。数仓为什么要分层、每一层做什么事、ODS 层用什么压缩格式和存储格式、DWD 层做了哪些清洗和维度关联、DWS 层按什么粒度聚合、ADS 层怎么对接报表。这些问题没有唯一答案,考的是你能不能自圆其说:分层带来的复用收益能不能覆盖多一次落盘的成本,宽表打平到什么程度合适,维度建模用星型还是雪花。
数据治理是这几年问得越来越多的部分。数据质量怎么监控、异常怎么发现、血缘关系怎么追、元数据怎么管、权限怎么控。一个典型的追问是"报表数字不对,你怎么在三十分钟内定位到是哪张源表出了问题",标准思路是从结果表顺着血缘往上追,逐层对比行数和关键指标,找到第一层出现偏差的位置。这类问题在数据治理、数据中台、数据湖这些概念上还会延伸,比如数据湖和数据仓库到底解决的是不是同一个问题,数据中台和数仓分层的边界在哪。
5.4 云上方向:存算分离之后,题目的重心变了
如果目标岗位涉及云计算或云开发,题库里那套自建集群的思路要打个折扣。云上的对象存储把存储和计算拆开了,磁盘容量不再是硬约束,但网络带宽和小文件读写成了新的瓶颈;弹性伸缩让"提前规划集群规模"这道题的重要性下降,取而代之的是"怎么在成本可控的前提下自动扩缩容";托管的队列和数仓服务把大量运维细节藏了起来,面试更关注用法和计费模型而不是底层调参。
同一个知识点在不同环境下的答案会不一样。比如小文件问题,自建集群里主要靠合并和调大写入批次,云上还要额外考虑对象存储按请求计费的特性,频繁的小文件读写在账单上会很显眼。准备这类岗位时,把题库里的通用原理保留,把具体参数换成云上的对应概念,思路就顺了。
6. 什么时候该翻这份题库,什么时候别硬背
有几种情况,这份按组件整理的题库非常对路。一种是已经有半年以上实际接触,能说出自己做过什么,但知识是零散的,缺一张完整地图,翻一遍目录就能把散点串起来。另一种是准备跳槽前的集中复盘,需要快速确认哪些高频题自己讲不利索,把它当成自测清单用。还有一种是转岗,比如从开发转数据治理,需要快速补齐另一半知识面,题库的广度正好合适。
也有几种情况,硬背反而浪费时间。完全没碰过分布式系统的人,直接看数据倾斜的七种解决方案,只能记住名词,面试官追问一句"你怎么知道是倾斜"就露馅了。这时候该做的是先跑通一个最小可用的流程,哪怕是本地模式跑一遍单词计数,也比背十页笔记强。另外,把题库当唯一信息源也很危险,组件版本在变,默认参数在变,某些历史解法在新版本里已经被优化掉了,只背结论容易答出过时的东西。
| 场景 | 建议用法 | 注意点 |
|---|---|---|
| 有实战经验,需要系统梳理 | 按目录自测,讲不清的章节重点补 | 别只划重点,要能口头讲出因果 |
| 零基础准备入门 | 先跑通一条最小链路,再看题库 | 跳过调优细节,先建立整体顺序感 |
| 面试前一周冲刺 | 集中看高频概念和易混辨析 | 数字类题目要提前整理自己的项目数据 |
| 岗位方向明确 | 只精读对应章节,其余略读 | 别为了求全在无关章节上耗时间 |
我自己的教训是早期太迷信"题量",把一份题库从头背到尾,结果面试被问"你们那台机器内存多大、为什么设成这个值"时彻底卡住。从那以后我每次看这类资料,都会强制走一遍"这个概念在我手上对应哪个具体数字"的自问流程,答不上来的就说明没真懂。希望这份梳理帮到你,需要完整资料的话,按页面提示获取即可。
本文还有配套的精品资源,点击获取