ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

大数据平台校招笔试题复盘:从Java并发到Hadoop生态的考点解析

大数据平台校招笔试题复盘:从Java并发到Hadoop生态的考点解析 2018年秋天美丽联合集团就是美丽说、蘑菇街那条线的公司开放了基础平台部的大数据平台开发工程师校招岗位。那会儿正值大数据和AI方向在互联网公司全面铺开的阶段投递量大、筛人狠。我到现在还记得打开笔试卷时的第一感受这套卷子出得很实在几乎没有一道题是为了难而难每一道题都能在真实的集群运维、数据链路由开发场景里找到出处。这篇文章把这份试卷从头到尾复盘一遍。我不打算逐字复刻原题毕竟过去这么久具体题号我已经记不全了而是聚焦试卷背后真正想考的东西每个模块在测什么能力、高频考点怎么答才不丢分、哪些地方最容易让校招生翻车。如果你正在准备大数据平台开发、基础架构方向的技术笔试这份复盘基本可以当一份备考提纲用。1. 试卷整体布局一场笔试背后的岗位能力模型1.1 卷面模块与分值逻辑这份试卷拿到手第一感觉是模块非常规整几大类题目分得清清楚楚Java基础与并发、算法与数据结构、大数据生态组件、SQL与数据库、场景设计题。我当时简单估了一下分值权重大概是这样的考察模块大致分值占比核心考察意图Java基础与并发20%左右语言工程功底、并发编程意识、JVM排查能力算法与数据结构25%左右代码基本功、边界条件思维、复杂度意识大数据生态组件25%左右对Hadoop/Spark/Kafka系列的真实理解深度SQL与数据库15%左右离线取数、数据仓库建模的基本功场景设计与综合15%左右系统设计能力、链路思维、技术选型判断这个结构放到今天看也不算过时它基本勾勒出了一个大数据平台开发工程师的日常轮廓。平台开发不像业务后端那样主要写接口也不像数据分析师那样主要写SQL取数它是夹在中间那一层你要能理解底层HDFS、MapReduce、Spark的运行机制要能写Java/Scala代码去开发平台工具还要能设计一条从业务日志到数仓的完整数据链路。所以笔试试卷里Java和算法占比高不是因为出题人偷懒套了通用后端笔试题而是因为这两样确实是大数据组件二次开发的地基。你去看Hadoop、HBase、Spark的源码几乎全是Java/Scala不懂JVM和并发根本读不下去。1.2 基础平台部到底在找什么样的人我当年投的是基础平台方向笔试前专门研究过这个部门和普通数据部门的区别。基础平台部做的不是业务数据分析而是把数据能力平台化集群资源管理、任务调度、数据采集、元数据管理、数据质量监控、甚至自研一些小工具来提升整个公司数据开发效率。这就决定了试卷的调性——它要筛掉那些只会调包调参的人。你可以不会背源码但至少要知道一条SQL在Hive里跑起来后底层是怎么翻译成MapReduce的你可以没搭过大规模集群但至少要清楚NameNode和DataNode各自承担什么职责为什么HDFS适合存大文件不适合存小文件。我记得试卷里有一道印象很深的判断题大意是说HDFS适合存储大量小文件如果你只是背过高吞吐、高容错这些关键词很容易打勾但实际上小文件会让NameNode内存被大量元数据占满严重时直接把集群拖垮。这种题考的就是你有没有真实的使用感知而不是应试记忆。2. 硬核编程题算法与Java并发高频考点拆解2.1 算法题Top K问题为何反复出现算法模块里笔试常见的有字符串处理、链表操作、动态规划入门但最贴近大数据场景的绝对是Top K问题。试卷里出现一道从海量数据中找出出现频率最高的Top K个单词之类的题我一点都不意外。Top K在大数据领域确实是出场率最高的题目原型因为MapReduce里的每个Reduce任务本质上都在做局部Top K的合并。解这类题有几个层次第一层也是最简单的全量排序后取前K个时间复杂度O(n log n)但数据量一大内存根本装不下笔试时如果只写这个解法基本拿不到高分。第二层是维护一个大小为K的小顶堆遍历一遍数据堆顶永远是当前最小的那个候选遇到比堆顶大的就替换并调整堆。时间复杂度O(n log K)当K远小于n时非常划算。这里有个细节很容易写错取Top K最大要用小顶堆不是大顶堆用大顶堆的话堆顶是最大的新元素根本进不去结果就错了。第三层是分治或者桶思想比如先用哈希把数据分批每批算局部Top K再归并。这就是MapReduce思路的简化版在笔试卷里如果能写出这层面试官对你的评价会明显上一个档次。我记得当时笔试还要求处理总数据量远超内存的前提条件我直接用手写伪代码的方式写了哈希分桶堆归并的两阶段方案并且注明了每阶段的时间复杂度。这一类题的目的不是考你会不会调API而是考你有没有把大规模问题拆小、分而治之的工程直觉。2.2 Java并发与JVM大数据组件的地基Java模块里并发和JVM是绝对的考察重心。大数据组件的NodeManager、Executor、Task调度器全是多线程模型而且常年跑在成千上万并发任务的环境里不懂并发原理的人写出来的代码要么有线程安全问题要么就是性能上不去。高频考点我梳理下来基本就这几个HashMap为什么线程不安全、ConcurrentHashMap的实现原理、volatile和synchronized的区别、线程池参数含义、JVM内存区域划分、常见GC算法。笔试里通常不会让你长篇大论背诵而是给你一段小代码让你判断输出或者找出并发问题。线程池是很多人的痛点。我记得有一道题是给出一组参数问任务提交顺序下线程池如何调度。这题想答对得把线程池的工作机制彻底吃透核心线程数corePoolSize、最大线程数maximumPoolSize、阻塞队列workQueue、拒绝策略handler它们的执行顺序是当任务进来时先看核心线程是否满了没满就开新线程执行满了就放进队列排队队列也满了才开新线程直到maximumPoolSize全满了才触发拒绝策略。我用食堂打饭来类比corePoolSize是固定窗口最大线程数是临时加开的窗口阻塞队列是排队区域拒绝策略就是队伍长得受不了时食堂挂出的暂停排队牌子。笔试时把每个参数在这种场景下的作用写清楚逻辑完整基本就稳了。JVM方面最常见的题是内存区域划分和OOM排查思路。记一个简单的方法堆内存放对象实例栈存放局部变量和调用帧方法区或元空间存放类信息程序计数器记录字节码执行位置。线上OOM时先通过jstat看堆内存使用曲线再用jmap dump堆快照最后用MAT分析是哪个对象占了大头。这个排查流程在场景题里经常用到写出来会显得你有真实的线上经验。3. 大数据生态组件专项Hadoop、Spark、Kafka的考察重心3.1 HDFS写入流程与副本放置策略大数据生态组件这块是试卷的硬菜考察的深度明显比通用后端笔试要深。HDFS相关题目里最值得展开的是一次文件写入的完整流程和副本放置策略。HDFS写入流程我建议按这个顺序答缺一不可客户端调用DistributedFileSystem.create()方法向NameNode发起创建文件的请求NameNode检查文件是否已存在、是否有权限、配额是否够校验通过后返回一个可用于写入的输出流对象客户端开始按数据包packet默认64KB写入先写到第一个DataNode再由这个DataNode把数据包转发给下一个DataNode形成一条pipeline每个DataNode写完一个chunk后会返回确认信息逐级回传所有数据包写完后客户端调用close()关闭流通知NameNode文件已写完成。这里有一个容易被忽略但笔试很爱考的点为什么不直接让客户端同时向三个DataNode发数据而是用pipeline链式转发原因是客户端节点往往不在集群内部网络带宽有限如果一对多发送客户端出口带宽会成为瓶颈链式转发把复制压力分散到了集群内部的机架间网络上这个设计思路在分布式系统里很经典。副本放置策略也考得很多默认的3副本策略规则是第一个副本放在客户端所在节点如果客户端不在集群里就随机选一个不太忙的节点第二个副本放在与第一个副本不同机架的一个节点上第三个副本放在与第二个副本相同机架、但不同服务器的节点上。这样设计是为了兼顾容灾和写入性能跨机架副本可以防止整个机架故障丢数据同机架副本又能减少跨机架写流量。3.2 MapReduce Shuffle、Spark RDD与Kafka ISRMapReduce部分Shuffle是永恒的考点。我当年答题时画了一张流程图从Map端环形缓冲区开始map输出先写入内存中的环形缓冲区默认大小为100MB达到80%阈值时后台线程开始溢写溢写前会先对key做分区和排序如果设置了Combiner会在溢写时先做一次本地合并多个溢写文件在Map任务结束前被merge成一个大的分区文件Reduce端从已完成Map任务的节点拉取属于自己分区的数据在内存中合并排序全部拉完后作为reduce函数的输入。Shuffle这块想拿高分一定要理解Combiner的本质它就是在Map端先做一次局部reduce减少跨节点传输的数据量。比如统计单词频率每个Map任务先本地数一遍hello出现了3次而不是把3个hello都扔给Reducer这样shuffle的数据量直接少了一大截。Spark相关的题目里最高频的是RDD的宽依赖和窄依赖、Stage怎么划分、以及RDD、DataFrame、Dataset三者区别。窄依赖是指父RDD的每个分区最多被子RDD的一个分区使用比如map、filter宽依赖则是一个父分区被多个子分区使用比如groupByKey、reduceByKey宽依赖必然触发Shuffle也是划分Stage的边界。RDD、DataFrame、Dataset的区别我建议用一张表格来记维度RDDDataFrameDataset数据表示Java/Scala对象Row对象结构化强类型对象 结构化类型安全编译期强类型编译期不检查字段名编译期强类型性能优化无法使用Catalyst优化器支持Catalyst优化支持Catalyst优化 编码器适用场景底层开发、函数式操作快速ETL、SQL分析需要类型安全且要优化这道题我见过很多人答成DataFrame比RDD快但不能解释为什么快。深一层的答案是DataFrame有schema信息Spark能基于Catalyst优化器做谓词下推、列剪枝、甚至把逻辑计划转换成更高效的物理计划而RDD是黑盒的Java对象Spark不知道里面装了什么没法做这些优化。笔试时能把优化器这个层面说出来绝对是加分项。Kafka的考点集中在消息可靠性上核心是ISR机制。Kafka的副本分为leader和followerfollower中与leader保持同步的副本集合被称为ISRIn-Sync Replicas。生产者写入消息时acks参数控制需要等待多少副本确认acks0发完就认为成功acks1等leader写入就返回acksall要等所有ISR副本都写入才返回。在分区只有一份副本的场景下leader挂掉消息就丢了所以生产环境一般要求最少2个副本同时设置min.insync.replicas2配合acksall来保证消息不丢。这个知识点我特别想提醒一句笔试如果只是答ISR是同步副本集合分数一定低。要把它和生产者参数、消费者offset提交方式串起来才能体现你理解的是完整链路。消费者端还有一个高频题消费完消息后是先更新offset还是先处理业务答案是先处理业务再提交offset否则消息处理到一半consumer挂了重启后会漏消费。4. 系统设计题与场景应用题从日志链路到实时计算4.1 经典场景题亿级日志采集链路怎么设计选择题和原理题之后压轴的往往是场景设计题。我记得试卷里有一道大题的背景是公司业务每天产生几十亿条用户行为日志需要采集到大数据平台做离线分析同时一部分数据要支持实时监控和实时大屏展示请设计完整链路并说明每层选型理由。这类题没有标准答案但判卷人很容易从你的答案里看出你有没有做过真实的系统。一个合格的设计应该分四层来答采集层业务服务器上的日志通过Flume或Filebeat采集日志先写入本地文件再由采集Agent做断点续传避免进程重启后丢数据。这一层的关键是Agent要有tail -F的能力能感知日志文件滚动。传输层所有日志统一进入Kafka。这是整条链路的缓冲池核心作用是削峰填谷比如电商大促时日志量是平时的几十倍如果没有Kafka直接把流量打到HDFS下游根本扛不住。Kafka的partition在这里也起到了并行度控制的作用按业务类型分topic再分partition。存储与计算层离线链路从Kafka消费数据写入HDFS按天做目录分区Hive建外部表映射凌晨跑Spark SQL生成报表实时链路则用Spark Streaming或Flink消费Kafka做分钟级聚合结果写入Redis或ES供实时大屏查询。调度与监控层用Azkaban或类似的调度系统管理离线任务依赖用监控系统盯着Kafka消费延迟和各节点磁盘水位一旦消费lag持续增长就要报警。我答题时特意把每层之间的衔接点写清楚比如离线链路从Kafka到HDFS这段是用Flume直接对接还是写一个消费程序各自优缺点是什么。用Flume的好处是部署简单、自带断点续传缺点是灵活性和数据格式控制弱一些自己写消费程序虽然麻烦但可以精确控制批次大小和写入方式。这种对比不需要很深入但能体现你做过实际选型而不是只会背架构图。4.2 实时与离线Lambda架构和Kappa架构的权衡场景设计题的第二问通常会追问离线链路和数据实时链路结果不一致怎么办这其实就是在考流批两种架构选型。Lambda架构的思路是流批并行一条离线链路由Spark SQL定时跑全量数据一条实时链路用流处理算增量数据最终结果由服务层合并。优点是两条链路独立出问题影响面小缺点是同一套逻辑要维护两套代码离线结果和实时结果对上账经常要费很大劲。Kappa架构的思路是只用一套流处理引擎把数据长期保存在Kafka里需要重算时从Kafka开头重新消费。优点是代码只有一套缺点是对Kafka的存储时长要求很高历史数据回放时资源消耗大。2018年那个时间点Spark Streaming还在用微批模式真正意义上的实时流处理逐条处理更多是在Flink上做的。笔试里涉及实时计算选型时如果能提到微批和原生流式的区别会显得你跟上了社区发展。Spark Streaming把数据按秒级切片每个批次作为一个RDD处理batch interval 5秒意味着最坏情况下延迟接近5秒Flink则使用事件驱动模型数据一到就处理延迟可以做到毫秒级同时支持精确一次的状态一致性。我当时在试卷里没有直接踩一捧一而是写了一个折中方案常规指标用Spark Streaming够用且技术栈统一对延迟和精确语义要求高的核心场景单独上Flink链路。这种回答在面试官看来是务实且可落地的而不是拿两套框架炫技。5. 复盘与备考建议哪些分最容易丢怎么补5.1 改卷视角下的高频失分点后来我工作后参与过几次校招笔试的初筛回头看这份试卷发现学生们的失分点其实非常集中。把这些坑提前暴露出来比多做十道题都管用。第一个坑是原理题只答结论不给推导。比如问为什么HDFS不适合存小文件有人就写小文件占内存这等于没答。应该展开说明小文件占用的是NameNode内存每个文件、目录、数据块在NameNode内存里对应一条元数据记录以百万级小文件计算NameNode内存消耗会到几十GB级别GC压力极大最终影响整个集群响应更麻烦的是大量小文件会让MapReduce任务变成启动任务的时间比处理数据的时间还长因为每个文件至少对应一个InputSplitMap任务数量爆炸。第二个坑是手写代码不考虑边界条件。算法题写主流程写得很顺但数组为空、堆为空、个数K等于0这几种情况完全没有处理。判卷时边界条件至少占三成以上的分这一点很多刷题时习惯只跑通主用例的同学很容易踩中。第三个坑是SQL题没有考虑数据去重和空值。SQL模块的题目不算难但写得对不对很见功底常见失误是join时忽略了一对多关联导致结果翻倍、count字段只用了count(字段)而没考虑null不计数的语义。我记得有一道题需要统计连续登录天数很多人把所有登录记录一次性group by天数然后再手动数但正确的思路是先对日期排序、用date_sub(日期, row_number())把连续日期归组再count这就是一个典型的窗口函数应用场景。第四个坑是场景设计题直接放弃。有相当一部分同学看到设计一条日志采集链路这种开放题心里就慌了觉得没有标准答案就不敢写。其实这种题只要把分层结构写出来、讲清楚每层选什么组件就已经超过半数人了完全放弃等于白丢15%的分。5.2 备战大数据平台岗的实操路径如果你现在正在准备类似的岗位我按自己能实操验证过的路径给一个参考路线总周期大概8到10周可以根据基础和课业压力调整。第一阶段Java基础、并发与JVM同时推进周期两到三周。Java语法如果薄弱先过一遍集合框架源码重点看HashMap和ConcurrentHashMap然后刷并发编程的经典问题最后看JVM内存与常见GC。不用贪深但线程池参数和OOM排查流程必须能自己完整讲出来。第二阶段算法与数据结构集中刷题周期三到四周。按数据结构和常见题型分类推进不按序号刷题。链表、二叉树、字符串、动态规划、Top K、LRU这六类命中率最高。刷题时强制自己养成先写边界条件的习惯数组越界、空指针、最大整数溢出这几个错误不许出现。第三阶段大数据组件原理系统梳理周期三周。HDFS和MapReduce可以结合源码或流程图去理解Spark重点理解DAG和宽窄依赖Kafka重点理解ISR和消费语义。每学一个组件用一张A4纸画架构图并写下它解决的核心问题、不解决什么问题以及数据流路径。学完每个组件后反问自己一个问题如果这个组件没有诞生我们还能用什么方案实现同样的效果想明白这个问题原理才算入门。第四阶段动手实操周期两到三周。在自己电脑上搭一套Hadoop伪分布式和Spark环境跑通wordcount、从Kafka读数据写到HDFS、再通过Hive SQL查询这条完整体验链路。这一步是很多校招生忽略的但我在面试中遇到过不少对原理背得滚瓜烂熟、却答不出MapReduce一次作业从提交到完成要经过哪几个进程的人动手跑一遍之后这个过程的印象会深得多。第五阶段场景题突击和面经复盘周期一周左右。把日志采集、实时大屏、数据仓库分层、任务调度这四类典型场景提前准备好自己的方案模板然后对着往年笔试复盘尝试用规范的分层思路去拆解每一道开放题。最后再分享一个小技巧笔试时遇到不会的题千万别空着。大数据平台的卷子里很多题是开放性的判卷人希望看到的是你如何逼近答案而不是标准答案本身。哪怕一道题完全没有思路你也可以写一段这类问题我会先定位是网络问题、CPU瓶颈还是GC问题再通过xx工具逐层排查的排查思路拿到步骤分的同时还向面试官传递了你的问题分析习惯。这套试卷在当年给我的最大后劲是让我意识到大数据平台开发岗的考察重心不是会用几个框架而是是否具备分布式环境下的工程直觉。这种直觉没有捷径只能在一次次把环境搭坏、把数据写丢、把任务跑挂的经历里慢慢长出来。如果你在准备这类笔试不要只盯着刷题数量多花点时间亲手把一个简单的集群从零搭起来让数据真正在管道里流过一遍比背一百道面试题都管用。
返回列表