公司动态
网易大数据笔试解析:从Java到Spark的校招通关指南
1. 试卷考察逻辑大数据开发校招到底在筛什么人这两天整理资料时翻出了网易2018校招大数据开发工程师的笔试卷重新看了一遍最大的感受是这套题放在今天依然有很强的参考价值。那几年大数据岗位的笔试题普遍处于摸索期各家出题风格差异很大有的偏Java有的偏算法有的干脆全考SQL。网易这套题的风格比较务实Java、Hadoop生态、Spark、数据仓库、系统设计都有涉及覆盖面广但每一块都踩在关键点上。我当时参加校招时做过不少大厂的笔试题后来也参与过部门的新人招聘和试卷设计。站在现在的视角回头看这套题它真正想筛选的并不是背了多少知识点的人而是能否用工程化的思维方式理解大数据体系。举个例子卷子里考HDFS写入流程和MapReduce数据倾斜这类题目如果只在面试前突击背过答案看到变体题就容易懵但如果真在集群上跑过任务、排查过问题答起来会顺畅很多。这也是这篇文章想帮你做的事——不是简单对答案而是弄清每类题目背后的考察意图以及对应的复习方向。不管你是正在准备校招的应届生还是想转行大数据开发、想系统补基础的同学这篇解析都适用。我会按试卷的模块拆开讲每部分结合真题示例、考点分析和答题思路展开。文中涉及的具体题目和考察点参考的是当年网易这套笔试的公开回忆版和同类大厂的出题风格细节上我会标明哪些是原题原意、哪些是同类变体方便你对照复习。2. Java与JVM大数据工程师的第一道门槛2.1 集合与并发看似基础实则筛选编码功底大数据开发工程师日常写的最多的语言就是Java和Scala所以校招笔试里Java基础几乎必考。网易这套卷子的Java部分给我印象比较深的是集合和并发相关的问题。比如考察HashMap在JDK 7和JDK 8之间的底层区别死循环问题是怎么产生的ConcurrentHashMap为什么在JDK 8里放弃了分段锁。这些知识点在八股文里是老面孔但放到大数据场景下就有了新的追问角度。先说说HashMap。JDK 7的HashMap在并发扩容时头插法可能导致环形链表get操作时CPU飙升100%这个场景我后来在真实生产环境里遇到过。当时一个业务团队反馈有个节点CPU异常高排查下来是多个线程同时往一个HashMap里写数据触发了扩容和网上很多案例一模一样。JDK 8改成尾插法从结构上消除了环形链表问题但又引入了红黑树化树化阈值是8反树化阈值是6中间留了缓冲。笔试如果只答到这里只能得基础分如果能补充说明为什么树化阈值选8是基于泊松分布计算的负载参数面试官就会觉得你是真理解而不是背来的。ConcurrentHashMap同样如此。JDK 7用Segment分段锁默认16段理论上支持16个线程并发写JDK 8抛弃了分段锁改用CAS加synchronized锁Node节点锁粒度更细。这里有个容易被忽略的点JDK 8的size()方法和JDK 7不一样不再需要遍历所有Segment而是通过累加baseCount和CounterCell数组竞争激烈时分散计数最后合并。笔试时如果能把这两代实现的差异和为什么这样演进讲清楚这一题基本就稳了。2.2 JVM内存与GC从背参数到看日志定参数JVM在网易这套卷子里占的比重不小涉及内存区域划分、垃圾回收器选型和GC日志分析。这类题有个特点光背-Xmx、-Xms、-XX:NewRatio这些参数的含义没用题目经常给一段真实的GC日志让你判断新生代和老年代的使用情况、评估停顿时间是否合理。我记得卷子里有一道题给了CMS GC的日志片段问young GC频繁且耗时偏长的可能原因。这道题实际上在考两件事第一你是否知道Young GC要复制存活对象到Survivor区或老年代第二你是否能看出Survivor空间过小会导致对象提前晋升老年代进而引发频繁Full GC。生产环境里我确实排查过类似问题一个实时计算任务频繁Full GC每次停顿好几秒下游数据延迟越来越大。后来在GC日志里看到老年代增长很快调大了SurvivorRatio、把晋升阈值从默认的15调高Full GC频率立刻降了下来。讲这些是想强调复习JVM时与其死记硬背Serial、Parallel、CMS、G1的区别这种表格不如动手跑几个模拟程序用jstat、jmap、jvisualvm这些工具观察堆内存变化再对着GC日志分析一遍。笔试答题时能做到看到日志能定位问题比会默写参数表有意义得多。网易这类公司出题很务实他们要招的是能解决线上问题的人。2.3 编程题不只是算法还要写出工程化风格网易这套笔试卷的大数据方向编程题不是LeetCode那种纯算法题更像是在考察工程实现能力。比如有一类常见题是手写一个实现指定功能的Java类会设置一些边界条件或并发要求看你是不是只写出了能跑的结果还是考虑了线程安全、异常处理、资源释放这些细节。我个人建议是笔试编码环节一定要先把类结构写好再写核心逻辑。很多同学习惯直接在一个main方法里堆代码虽然能过测试用例但阅卷印象分不高。如果面试官后续追问这个变量为什么用volatile这里为什么用ConcurrentHashMap而不是Hashtable你如果写的时候根本没想过就很容易露馅。更稳妥的做法是写出清晰的注释把关键设计决策标注出来比如这里用CopyOnWriteArrayList是为了读多写少时减少锁竞争。这种细节在笔试阶段就展现出来能帮你直接进入面试官的重点观察名单。3. Hadoop生态三剑客HDFS、MapReduce与YARN3.1 HDFS写入与读取不是背流程而是理解容错设计网易这套卷子里HDFS相关的题目相当典型。其中一道经典题是描述HDFS文件写入流程。很多人的答案就是客户端调用createDistributedFileSystem返回FSDataOutputStream然后写DataNode……——这样答只能算及格。真正有区分度的回答会抓住两个核心一个是容错机制写入过程中某个DataNode挂了怎么办另一个是副本放置策略为什么是1个本地机架、2个同机架、1个跨机架。当时卷子里还有一道变体题问如果客户端写入过程中某个DataNode出现故障数据块复制会怎么恢复。这就不是在考流程背诵了而是在考你对Pipeline恢复机制的理解。实际过程是DataNode故障后写入Pipeline会断开NameNode会重新分配一个DataNode已写入的数据块会被重新复制以维持副本数。答出这个流程再补充故障检测依赖于DataNode与NameNode之间的心跳机制超时通常默认10分钟这类细节回答的完整度会明显不一样。读流程同样有关键细节客户端从NameNode获取数据块位置后会按网络拓扑选择最近的DataNode读取。这里有个容易被忽略的考点——短路读取Short-Circuit Local Reads。如果你能提到当客户端与数据块在同一个节点时可以绕过DataNode直接通过内存映射读取本地副本以降低开销说明你真的在生产环境里优化过读链路而不只是看过源码解析。3.2 MapReduceshuffle是关键数据倾斜是生命线MapReduce部分网易这套题对shuffle过程的考察非常细。Map端输出后要经过分区partition、排序sort、溢写spill、合并merge等步骤Reduce端要经历拉取fetch、合并merge、归并排序sort再交给reduce函数处理。卷子里有一道题直接问MapReduce中的Combiner和Reducer有什么区别使用Combiner需要注意什么。这个问题很经典。Combiner是在Map端本地执行的迷你Reducer目的是减少Map输出到Reduce的数据量但它的输入输出类型必须和Reducer一致而且必须有交换律和结合律否则结果会错。比如计算平均值如果直接在Map端做Combiner就会出问题——每个Map任务算了一个局部平均值Reduce端把各局部平均值再平均和全局平均结果往往不一致。这道题我在辅导学弟学妹时反复强调过笔试时一旦考察这个点很容易区分是真正理解还是泛泛了解。数据倾斜也是这套卷子的重点。我记得有一道题是什么情况下会发生数据倾斜如何解决。生产环境里数据倾斜出现频率极高join时key分布不均、group by时某个值占比异常大、空值过多都会触发。解决方案无外乎几类加盐随机前缀打散、map端join替代reduce端join、广播小表、两阶段聚合。答题时最好结合具体场景比如如果倾斜key是空字符串可以把空字符串加随机后缀如果某个热key是业务热点可以拆分维度再做合并。3.3 YARN资源调度从冷门考点到必答项2018年时很多人复习Hadoop还会忽略YARN觉得它就是个资源管理系统没什么好考的。网易这套卷子显然不这么认为里面出现了关于YARN调度器的选择题和应用提交流程的简答题。调度器这部分FIFO、Capacity Scheduler、Fair Scheduler三者的对比是高频考点。FIFO简单但容易造成队列阻塞Capacity Scheduler按队列划分资源适合多租户场景是Hadoop默认的调度器Fair Scheduler则强调任务间的公平性适合多用户提交短任务的环境也是Spark on YARN常见的配置选择。卷子里有一道场景题问的是一个集群同时跑多个业务线任务A业务线任务量大但优先级低B业务线任务量小但要求响应快应该选哪种调度器——这就是典型的Capacity Scheduler场景。关于应用提交流程考察点为客户端提交ApplicationMasterAMResourceManager与NodeManager协调AM向RM申请容器任务完成后注销AM。如果想答出区分度可以补充RM在启动AM前会先校验队列权限和资源配额避免无权限用户直接提交任务占用资源这个点在多租户集群里踩过坑的人才能答出来。另外一个细节是AM会向RM发送心跳上报任务进度RM借此判断AM是否存活超时未汇报会重新调度容器。理解这套机制后你自己排查任务卡死时会更有头绪。4. Spark核心从RDD到运行机制的高频考点4.1 RDD血缘与依赖常考常新答出容错精髓网易2018这套卷子里Spark的题量甚至超过纯Java可见当时Spark已经是大数据开发的核心技能。RDD相关的重点集中在宽窄依赖、血缘关系Lineage、checkpoint机制这几块。宽窄依赖的区分标准很简单窄依赖是每个父RDD分区最多被一个子RDD分区使用包括一对一的map和一对多的flatMap宽依赖是多个子分区依赖同一个父分区典型操作是groupByKey、reduceByKey、join。这个知识点不仅是理论考点更决定了任务的执行方式——窄依赖可以在同一个Stage内流水线执行宽依赖必须shuffle所以Stage的划分就是看宽依赖。网易卷子里的追问是RDD如何在节点故障时恢复。这个问题如果没有真正理解血缘机制很容易答成重新读取数据源。实际上Spark是通过血缘关系重新计算丢失的分区而checkpoint机制的作用是切断过长的血缘链把中间结果持久化到可靠存储如HDFS避免从头重算。我当时在项目里用Spark处理一个复杂的多阶段ETL任务因为血缘链太长任何节点故障都要从最上游重算整个作业耗时严重。后来在合适的阶段插入checkpoint重算代价大幅降低。笔试时你能答出checkpoint是空间换时间、是容错策略的补充而不是替代这个知识点才算真正掌握。4.2 Spark SQL与优化策略从能跑到跑得快Spark SQL近年占比越来越高网易这套卷子也体现了这个趋势。典型考题是Spark SQL的执行流程和Catalyst优化器做了哪些事。执行流程可以概括为SQL解析为逻辑计划、逻辑计划经过Catalyst规则优化谓词下推、列剪裁、常量折叠等、生成物理计划并转换为RDD操作。能画出这个链路不难但要答出优化器的具体规则就显得内行了。以谓词下推为例Spark SQL在逻辑优化阶段会把Filter尽量下推到数据源读取阶段减少实际扫描的数据量。同理列剪裁会只读取查询需要的列这在Parquet这类列式存储下收益特别明显。笔试如果给出一个SQL让你说明Catalyst会做哪些优化至少要说出这两点再补充如果join的右表很小优化器可能自动转换为BroadcastHashJoin避免shuffle回答就很完整了。数据倾斜在Spark里同样是高频考察点。我记得有一道题是用Spark做groupByKey后某个key的数据量特别大怎么处理。方法包括对倾斜key加盐后局部聚合再全局聚合使用广播变量加map端join调整Spark的spark.sql.shuffle.partitions参数增大shuffle分区数以分担倾斜分区压力。这里务必注意加盐是处理倾斜的常用手段但会导致相同key无法精准去重还需在全局聚合后再次去盐这一细节是很多人在面试时容易忽视的。4.3 Spark Streaming与结构化流实时计算的入门关那几年Spark Streaming在实时链路中地位很高网易的笔试卷也出现了Structured Streaming和Spark Streaming的对比题。核心考点包括Spark Streaming的微批处理模型其实是通过把流数据切分成固定间隔的RDD来实现准实时处理Structured Streaming则基于无限表Unbounded Table模型以输入表—增量查询—输出表的方式处理数据。两者的对比点是延迟、吞吐量、端到端精确一次语义的难易程度。用生活化一点的方式类比Spark Streaming像是流水线上定时打包每5秒把积累的零件打包处理一次Structured Streaming更像是持续关注流水线输出的看板每次有新零件就增量更新看板内容。理解这个差异后题目问什么场景适合Spark Streaming什么场景适合Structured Streaming就很好答了对延迟敏感度一般、希望用DStream API灵活操作的历史项目选前者需要自动处理事件时间、水位线、端到端精确一次的新项目选后者。另外watermark机制在2018年的卷子里就开始出现了。考法通常是事件时间乱序到达时如何保证不丢数据。答案核心是设置水位线阈值允许一定范围内的延迟数据参与窗口计算超过水位线的数据要么丢弃要么进入侧输出流。现在很多同学通过Flink接触watermark会觉得理所当然但当时Spark引入watermark是个很大的变化笔试考出来说明出题人在实时计算这块有较深积累。5. 数据仓库与SQL离业务最近的大数据能力5.1 范式与建模从三范式到维度建模的权衡大数据开发岗位的笔试题里SQL和数仓知识从来不缺席。网易这套卷子里有一类题给一个业务场景让你设计数仓分层结构或者判断某张表应该用哪种建模方式。这类题的通用解法是先明确业务过程再选择建模方法然后逐层设计。熟悉数仓的同学都知道三范式3NF适合OLTP系统但在大数据分析场景下为了查询性能通常选择维度建模。星型模型是最常用的方式事实表在外围、维度表在中心雪花模型是星型模型的规范化变体维度表继续拆分减少了数据冗余但join变多。这里有个很实际的权衡离线数仓一般用星型模型因为维度表拆分过细会导致查询时关联过多表性能下降而冗余一些字段反而更容易被业务使用。维度建模中还有一个高频考点缓慢变化维SCD。典型题目是用户修改了手机号维度表应该怎么处理。答案方向有直接覆盖SCD1、保留历史并新增一行SCD2、增加新列存储历史值SCD3。网易这道题我记得更贴近实际——要求既保留历史消费分析能力又保证当前联系方式正确这就需要用SCD2方案。答题时如果能说明如何通过生效日期和过期日期两个字段维护版本记录会给阅卷者留下好印象。5.2 SQL基本功从窗口函数到复杂查询笔试卷的SQL题通常会在Hive SQL或Spark SQL语境下出题常用函数如row_number()、rank()、dense_rank()的差异是必考。我记得有一道很经典的题目是统计每个部门薪资排名前3的员工答案就是用窗口函数先对部门分区按薪资排序再在外部查询中过滤排名小于等于3。这类题平时多写写基本不会失分。稍微有难度的是自连接和行转列列转行。比如用SQL找出连续登录3天以上的用户一种常见解法是利用row_number()生成编号再用登录日期减去编号天数如果差值相同说明这些日期是连续的。这个思路在笔试中出现频率极高值得多练习。另一类是多行转多列或多列转多行需要熟练使用case when结合聚合函数或者用explode在Hive/Spark SQL中实现列转行。如果你想在SQL题上拉开差距建议练习时尽量把每个查询用两种方式实现一种用传统的joingroup by一种用窗口函数。这样笔试时遇到禁止使用窗口函数的附加限制也能从容应对。另外注意Hive SQL和Spark SQL在函数支持上并不完全相同考试时看清题目限定环境再作答别把MySQL的语法直接搬过去。5.3 数据质量与链路保障容易被忽视但网易爱考大数据开发笔试里数据质量相关的问题占比不大但恰恰是区分写SQL的人和做数据开发的人的关键。网易这套卷子里有一题问如何保证Hive表的数据质量我当时看到时有点意外后来工作后才明白这个问题问得多好。回答方向可以从几个层面展开数据接入层检查源数据字段完整性、空值率和重复率ETL过程中设置数据量波动告警比如今日比昨日超过或降低20%时就触发告警数据产出后进行主键唯一性校验、同环比异常检测。如果还能提到对重要的数据表建立质量监控规则规则不通过时不让下游任务启动这已经是高级数据开发者的思维了。这套卷子里的数据倾斜、数据质量等题目都指向一个核心合格的大数据开发不只是能写得出SQL、跑得完任务而是要对自己产出数据的正确性负责。这个思维如果你在笔试阶段就建立起来后面无论是面试中聊项目还是实际工作都会比别人多想一层。6. 系统设计与算法拉开差距的关键题6.1 实时链路设计从Kafka到下游的选型与取舍网易这套笔试卷里有一道开放型设计题大概是设计一个实时数仓架构从数据采集、消息队列到实时计算和存储要能支撑秒级延迟的数据分析。这类题没有标准答案但能看出一个人的技术栈成熟度和全局视野。答题时最好分模块展开数据采集用Canal监听MySQL binlog或直接埋点上报消息队列选Kafka注意分区数要大于等于下游消费者并发数否则会浪费消费能力实时计算引擎可选Flink或Spark Streaming计算后的结果可以写入Druid、ClickHouse或MySQL看查询场景。如果只答这里面试官可能会接着追问怎么保证消息不丢失消费到重复数据怎么办这时候你能答出Kafka的acks参数设置、消费者的enable.auto.commitfalse与手动提交offset结合以及幂等写入策略设计题才算答透。我在答这类题时有个习惯先画数据流向再标注每个环节的容错策略然后说明为什么这样选。比如消息队列为什么选Kafka而不是RabbitMQ因为Kafka的分布式日志架构更适合高吞吐、多消费者订阅场景而RabbitMQ更适合RPC式的消息路由。写在卷面上阅卷人能直观看到你是在做工程决策而不是罗列名词。6.2 算法题重点在排序、TopN与海量数据处理大数据笔试里的算法题不会出太偏的题目主要集中在排序、二分查找、TopN、海量数据去重与统计。网易这套卷子有一道让我印象深刻的题是如何在内存只有1GB的情况下对100亿个整数进行去重并排序。这类题的经典思路是位图法或外部排序。100亿个整数如果直接用int存储大约是40GB显然无法一次载入内存如果用位图每个整数只占1个bit那么40亿个整数范围假设非负整数只需500MB左右可以装下。如果数字范围太大或中间有负数可以考虑分桶把数据按区间拆成多个小文件每个文件在内存中排序后归并。另一种方案是使用Bloom Filter做去重但要说明会有一定误判率后续还需要二次校验来保证精确性。TopN问题则通常用堆来解决。比如从1亿个数中找出最大的100个数维护一个大小为100的小顶堆遍历数据时如果元素比堆顶大就替换堆顶并调整堆。用哈希分片处理海量数据也很常见把数据按照key哈希到不同节点再在每个节点上做局部统计最后合并全局结果。笔试中如果能提到这种分而治之的思想即使没有写出完美代码也能传递出工程考量。6.3 原理理解题为什么这样设计背后有什么权衡这类题不会直接问Kafka是什么而是问Kafka为什么能做到高吞吐ZooKeeper在Kafka中扮演什么角色。答Kafka高吞吐时不仅要提顺序写磁盘和零拷贝最好再补充页缓存Page Cache机制——写入的数据会先进入操作系统的页缓存刷盘延迟可配置读操作命中页缓存时甚至不需要访问磁盘。这样答比单纯说顺序写和零拷贝更有层次。与之类似的还有ZooKeeper在Kafka里的作用——存储broker的元数据、管理controller的选举、保存消费组的offset旧版本。这里有个常见的理解误区新版本Kafka消费offset已存储在内部主题__consumer_offsets中不再依赖ZooKeeper存储。答出这个变化能显示你对Kafka版本演进的关注。在读源码和复习时建议带着设计者为什么这样做的视角。比如HDFS为何默认副本数为3是为了在可靠性和存储成本之间取得平衡MapReduce为何要排序后再聚合是因为排序后的归并操作比哈希聚合更稳定、不易受数据分布影响。这种理解在笔试和面试中都很值钱。7. 笔试之外的几条实在建议7.1 做题节奏不要在单个难题上恋战网易这套卷子题量不算小有选择题、简答题、编程题和设计题整体时间大约两个小时。我见过不少同学在某个SQL题或算法题上花太久结果后面的大题没时间写非常可惜。比较合理的时间分配是选择题30%~40%时间简答题40%编程和设计题至少留30分钟。另外答题时哪怕思路不完整也尽量写出关键步骤和伪代码。阅卷很多时候是看思路分空着大概率得零分写出先用哈希分桶再在每个桶内排序最后归并这样几行字至少能拿一半分。这一点在校招笔试里特别重要因为阅卷时间有限可读性高、逻辑清晰、有步骤的答案更容易得到正面评价。7.2 复习资料的筛选从热门博客到一手源码大数据生态发展快很多网上流传的面试题资料已经过时或并不准确。复习时建议把重点放在官方文档和源码注释上尤其是Hadoop、Spark、Flink这类活跃项目的官方文档它们通常有清晰的设计动机和使用场景章节。针对笔试可以把过往大厂真题按知识点分类整理而不是盲目刷题毕竟大厂真题的重复率并不高但考察方向相对稳定。网易这套卷子如果你能在不看答案的情况下写一遍再对照解析修正收获会远超直接背题。我当年备考时把做错的题摘到一份错题本里每周重做一遍等到校招时很多知识点都形成了肌肉记忆。7.3 简历与笔试的配合让考官看到你的项目经验最后想提醒一点笔试成绩只是入围门槛真正决定你能不能拿到offer的还是简历里的项目经验和面试表现。写项目时尽量突出你解决过的具体问题比如通过优化Spark作业的并行度和内存配置将任务耗时从40分钟降到12分钟这样的量化结果。笔试中即使某道题没答好只要简历里项目扎实面试官仍然愿意给你机会在面试中证明自己。反过来也一样如果笔试表现很好但简历上什么都写不出来面试官也会疑惑你是不是只会做题。所以不要只顾复习八股文真刀真枪上手做一两个项目比刷一百道题更有用——这也是当年我在网易这套卷子之外最想告诉你的经验。