
很多读者都在问当年的校招笔试到底考了什么作为一个把触宝科技2017秋季校招后端大数据岗位第二批完整走完的过来人我翻了翻当年的笔记和代码草稿决定把这套笔试题复盘成一篇可以直接参考的干货。这篇文章不只是罗列考题而是从岗位要求反推每一道题背后的考察意图把Java基础、大数据组件、算法设计这些核心知识点的踩坑点和答题思路一次说透。不管你是准备投递类似岗位的应届生还是想系统梳理后端大数据技能树的初级开发这篇文章都值得你花二十分钟读完。1. 笔试背景为什么触宝会单独设一场大数据后端笔试触宝当时的产品线已经覆盖输入法、电话助手等工具类应用用户量级在海外市场增长很快。这种业务形态决定了后端系统要处理的数据有几个鲜明特点输入法产生的用户输入日志是海量且高并发的电话助手涉及通讯录和通话记录的敏感数据处理而个性化推荐和用户画像又依赖大规模离线计算。所以后端岗位不再是写写接口、管管数据库这么简单它要求工程师既能扛住实时请求压力又能搞定离线数据分析链路。笔试第二批的定位也很有意思它明显是从第一批的筛选中查漏补缺考点更偏向大数据技术栈的实操能力而不是单纯考察计算机基础。整套试卷的体量是三个小时题型分布大概是Java基础与并发编程占三成大数据组件原理与应用占四成算法与数据结构占两成还有一道系统设计题占一成。从题型占比就能看出这个岗位的日常工作重心是围绕Hadoop生态体系做数据管道开发同时需要具备扎实的JVM层功底去调优运行效率。我当时看到试卷的第一感受是它不是想难倒你而是想快速筛选出真正写过分布式代码、踩过数据倾斜坑的候选人。对于准备这类笔试的同学我的建议是不要只刷力扣。你需要把重心调整到用Java写MapReduce任务理解Spark Shuffle机制设计一个合理的数据仓库分层方案这些实际工程问题上。下面我按试卷的实际考察顺序逐题拆解答题思路和知识盲区。2. Java基础题从语法糖到底层内存模型每一题都在筛人触宝的Java基础题不走偏怪路线但非常刁钻。它不考你HashMap和Hashtable的区别这种背答案的题而是通过具体的代码场景让你分析内存变化和线程安全性。我记得第一道代码阅读题给了个简单的类加载例子看似考语法实际考的是类加载时机和静态变量初始化顺序。题目大概是这样的父子类都有静态代码块和实例代码块构造函数里还有个多态方法调用。问输出顺序。这道题的关键在于两点第一类的静态初始化只会在首次主动使用时触发而且父类静态块一定先于子类静态块执行第二实例初始化阶段父类的实例块和构造方法先执行但如果构造方法中调用了被子类覆写的方法实际执行的是子类的方法体。这是个经典的构造器调用可覆写方法陷阱很多人在这一步栽跟头。我在答题时特别标注了动态分派发生在运行时这个关键点然后按步骤推导输出。这种题平时看《深入理解Java虚拟机》的类加载章节和《Java编程思想》的多态章节都能覆盖到但我建议你亲手在IDE里跑几个变体否则光看书很容易在子类方法访问未初始化字段时产生误判。接下来是并发编程题当时给了一段使用SimpleDateFormat的代码多个线程并发调用parse方法问会出现什么问题、如何修复。这道题的考察点很明确SimpleDateFormat是线程不安全的因为它的内部使用了Calendar对象parse和format操作时会修改共享的Calendar状态。修复方案有三个层次每次使用新建实例简单但高并发下有性能损耗、使用ThreadLocal包装每个线程持有独立实例、在Java 8及以后使用DateTimeFormatter不可变且线程安全。我当时选了ThreadLocal方案并给出了具体代码因为这更贴近生产环境下的折中做法。而且我还指出了一个容易忽略的细节ThreadLocal用完一定要记得remove否则在线程池场景下会引发内存泄漏这个问题在触宝这种高并发入口场景里是真实的线上故障隐患。Java基础部分还有一道题专门考内存模型涉及volatile和synchronized的区别。它不是简单问定义而是给了一个多线程计数器的场景要求写出线程安全版本并解释为什么volatile不足以解决问题。这题的核心是volatile保证可见性和有序性但不保证原子性。计数器这种读-改-写复合操作即使每个线程都看到了最新值仍然可能丢失更新。正确方案是用AtomicInteger的CAS操作或者synchronized加锁或者LongAdder在高竞争场景下用分段CAS降低冲突。我在答题时列举了三种方案并对比了适用场景这种发散式的回答比较讨喜因为它展示了你不仅知道怎么做还知道何时用哪种。3. 大数据组件题MapReduce、Spark、Hive这样答才能拿高分进入大数据组件部分试卷的深度立刻上来了。它不问你MapReduce的shuffle过程是什么这种默写题而是给了一个实际场景统计海量日志中每个用户的访问次数要求写出MapReduce的Mapper和Reducer代码。这道题看似是WordCount的变体但有一个额外的坑日志格式是时间戳 用户ID 访问URL你需要先做数据清洗把脏数据行过滤掉。我当时写Mapper时用split(\s)切分每一行然后判断数组长度是否等于3同时校验用户ID是否为纯数字避免把解析异常的脏数据传进统计链路。Reducer部分要注意的是输出的value类型必须是可序列化的我选了IntWritable而不是Integer因为Hadoop的序列化体系基于Writable接口使用Java原生类型会直接报类型不匹配错误。这种细节在日常编码中不一定遇到但笔试考的就是你有没有真正跑过MapReduce作业。接下来一道Spark题目很考验理解深度RDD的transformation和action有什么区别并举例说明哪些操作是窄依赖、哪些是宽依赖。这里有个容易混淆的点很多人只记住了transformation是惰性的action触发计算但没理解依赖关系对作业执行计划的影响。我当时画了个简单的DAG示意图map、filter是窄依赖不需要shuffle可以在同一个stage内流水线执行groupByKey、reduceByKey是宽依赖需要shuffle会产生stage切分。为了展示对性能的敏感度我特别补充了一句reduceByKey会先在map端做combiner而groupByKey不会所以在处理大key量输入时reduceByKey的shuffle数据量会小很多这是写Spark作业时最值得优化的一个点。这个补充让我在面试官眼里显得像个真正踩过Spark性能坑的人。Hive的题目考的是数据仓库的分层设计给你一个电商场景要求设计ODS、DWD、DWS、ADS四层架构并说明每一层的职责。回答这类题不能只说ODS是原始数据层那样太空泛。我用触宝的业务举例ODS层直接同步业务库和日志数据保持原始粒度只做最小的清洗DWD层做维度建模把用户行为日志、订单数据、商品信息这些事实表和维度表关联成规范的宽表DWS层按天汇总用户维度和商品维度的指标比如日活跃、购买转化率ADS层就是面向具体业务场景的报表和即席查询数据。每一层我都补充了它的存储格式选择和生命周期管理比如ODS用TextFile存最近7天DWS层用Parquet列式存储并且按分区挂载。这样的回答让阅卷人能看出你有完整的数据仓库建设思路而不是只会写SQL。4. 算法与数据结构海量数据处理是拉开差距的关键算法部分的题量和难度都比常规校招友好但有一道海量数据处理题很能拉开差距给定一个包含几十亿个整数的文件只有几百MB内存可用要求找出出现次数最多的前100个整数。这道题是经典的分治策略我在答题时写了两阶段方案。第一阶段用哈希映射把大文件拆成多个小文件哈希函数统一取hash(num) % M这样相同的数会落到同一小文件内。第二阶段对每个小文件进行词频统计内部可以用HashMap统计超过内存阈值时可以用Trie树压缩存储。最后用大小为100的小顶堆维护所有小文件统计结果中的全局Top100。这种方案的好处是空间复杂度可控而且分布式环境下天然适合用MapReduce实现Mapper阶段做哈希分桶Reducer阶段做局部TopK再加一个最终的归并任务。除了这题还有一道经典的两数之和变体给定一个有序数组和一个目标值找到两个数使得它们的和等于目标值要求时间复杂度O(n)。很多人第一反应是哈希表这当然能做但忽略了数组有序的前提直接跳到O(nlogn)或O(n)空间方案。最优解是指针夹逼左指针指向开头右指针指向末尾比较两数之和与目标值的大小大了右指针左移小了左指针右移。我在答这道题时直接把为什么有序数组可以双指针的数学依据写了出来因为递增性保证了移动指针的方向是单调收敛的不会错过有效解。这种证明性写法虽然多花了一行但让阅卷者直观感受到你的算法思维是清晰的。还有一道树的层级遍历要求输出二叉树的锯齿形遍历结果。这题在LeetCode上是原题必刷。我用的方案是双栈法一个栈存当前层从左往右的节点另一个栈存下一层从右往左的节点交替使用。用LinkedList做栈时我特意注明用addFirst和removeFirst而不是push和pop因为Java的Deque接口里push操作和addFirst有细微的语义差异在需要严格栈语义时容易踩坑。这道题不难但代码风格和API选用会直接影响阅卷印象分。5. 系统设计题一锤定音实时报表系统的完整设计思路最后一道系统设计题要求设计一个支撑千万级日活用户的应用内实时报表系统数据延迟要求在一分钟以内。这道题考察的不是某个框架的API使用而是整个技术选型和架构权衡能力。当时我的答题结构分成了四个部分数据采集、数据传输、实时计算、结果存储与展示。数据采集层我在客户端埋点和服务端接入两个方向上都做了描述。客户端埋点通过日志SDK上报服务端采集通过OpenResty或Nginx的日志模块接收两条链路都输出统一的JSON格式后写入Kafka。这里我特别强调了为什么选Kafka而不是直接通过HTTP推送到后端服务因为上报流量是突刺型的分钟级峰值可能达到正常流量的十倍以上用消息队列削峰填谷是最稳妥的做法而且Kafka的持久化特性也方便后续做离线数据回放。实时计算层是这道题的核心我对比了两种选型。方案一是Spark Streaming的微批模式它和已有的离线批处理共用Spark生态学习成本低但延迟在秒级到分钟级之间勉强满足一分钟的要求。方案二是Flink的流式处理它支持真正的事件时间处理和精确一次语义延迟在毫秒级但需要额外引入一套新的技术栈。考虑到题目要求数据延迟在一分钟以内而且业务指标都是基于事件时间统计的用户活跃、点击转化这类计数我最终选择了Flink并说明了使用事件时间窗口加Watermark机制来处理乱序数据的思路。状态存储我选了RocksDB作为state backend因为它支持大状态且不需要占用太多堆外内存。结果存储与展示层实时计算结果先写入Redis以用户维度和分钟级时间窗口维度双写方便业务侧快速查询。然后用一个定时任务把Redis中的汇总结果同步到MySQL或者ES供报表系统查询历史趋势。这里有个容易被忽视的点分钟级的实时报表通常需要支持秒级刷新如果每次都查ES或者MySQL压力太大所以前端优先读RedisRedis的滚动时间窗口数据格式用Sorted Set键是时间戳分值是指标值天然适合做趋势图。我当时还补充了缓存穿透的应对方案Redis中不存在的用户维度指标直接返回0值的默认包装对象绝不穿透到下游数据库。这道题的完整回答大概花了我四十分钟也是我当时最有把握的一部分因为它考查的是全链路思维而不是死记硬背某个组件。6. 考后复盘阅卷人想在每道题里看到什么如果只看考点清单这套笔试题和其他大厂校招没有本质区别但触宝的卷子有几个明显的出题偏好复盘之后我才真正读懂阅卷人的心理。偏好一极度重视生产环境敏感性。几乎每道题都埋了线上才会遇到的数据质量坑比如脏数据过滤、SimpleDateFormat线程安全、Spark数据倾斜。阅卷人想看到的不是标准答案而是你有没有线上事故恐惧症——写代码时天然多想一想异常分支和极端情况。所以答题时不要只写主流程一定要把防御性编程和容错设计写进去。偏好二通过对比性提问考察理解深度。卷子里多次出现A和B的区别是什么什么时候用A什么时候用B这类问题。比如synchronized和volatile比如groupByKey和reduceByKey比如Spark Streaming和Flink。这类题的回答思路应该是先说适用场景再说底层原理差异最后补充性能数据或踩坑案例。三步缺一不可最好不要只单方面罗列语义区别。偏好三系统设计题没有标准答案却最看逻辑链完整性。从技术选型到数据流走向每一步都要能自圆其说。我后来和当时参与出题的同事聊过他告诉我评分时重点看两个维度一是方案有没有考虑到数据量级和延迟要求二是是否有明确的瓶颈感知——比如在写Kafka时是否考量了分区数对消费并行度的影响在写Flink时是否注意了检查点间隔与状态大小的关系。这些细节才是阅卷人区分背过八股文和真做过项目的依据。综合来看这套卷子并不欢迎突击式选手它更青睐那些平时有意识关注系统全貌、遇到问题会往下挖三层的候选人。7. 笔试后的准备建议从这套真题反推复习地图如果你正在准备类似触宝这样的后端大数据岗位我建议不要盲目刷题而是按这套真题反推出一个完整的复习地图。我个人把准备周期分为三个阶段每个阶段的侧重点完全不同。第一阶段是Java与并发基础强化时长约一周。重点复习类加载机制、JVM内存模型、并发工具包的使用和原理。这里推荐《Java并发编程的艺术》和《深入理解Java虚拟机》两本书交叉读特别是对volatile、synchronized、ReentrantLock、CAS、ThreadLocal这几个关键点的掌握要求自己能达到能画出内存变化图、能解释清楚可见性和原子性的关系的程度。同时要配合大量手写代码的练习不光是读懂而是要能默写出线程安全的单例、生产者消费者模型、以及简单的连接池实现。第二阶段是离线计算与实时计算技能地图时长约两周。重点放在MapReduce、Spark、Hive、Flink这几个组件的核心原理和API使用上。复习时不要只看文档要自己搭一套本地或单机的伪分布式环境动手跑通几个任务。我备考时用Docker搭了一套包含Hadoop、Spark、Hive的环境把WordCount、日志清洗、用户活跃统计这几种典型任务都亲手实现过一遍。这种动手经验的积累让笔试时遇到组件原理题时能直接联想到代码执行时的内部行为而不是靠死记硬背。如果你基础强一点还可以顺手把离线数仓的分层建表SQL练熟阿里的《大数据大牛必读》合集能帮你建立数仓和调度体系的操作直觉。第三阶段是刷题与设计题模拟时长约一周。算法题重点刷LeetCode的Top100高频题中的哈希、双指针、二叉树、动态规划、海量数据处理五类。设计题的方法论是找真实的业务场景练手比如设计一个限流系统、一个短链服务、一个Feed流推荐系统然后用我上文提到的四层分析结构来拆解数据从哪来、怎么传、怎么算、怎么存怎么展示。每一层都要求自己写出具体的组件选型和数据流描述这样笔试时遇到任何开放题都不慌。另外再分享一个容易被忽略的备考动作把每道做错的题整理进一个踩坑清单标注清楚错因和正确思路。我备考期间整理了六十多条笔试前过一遍能显著降低低级失误的概率。这种复盘习惯后来在正式工作中也帮了我很多它逼着你把每次报错和每次优化都变成可复用的经验资产而不是转瞬即逝的记忆。这三个阶段走完大部分后端大数据岗位的笔试题应该都难不倒你了。如果时间紧张至少保证第二阶段完成并至少手写过三个完整的大数据任务否则笔试中的组件题很难答出细节感。这就是这套真题给我最大的启发校招笔试看重的不只是你懂多少知识点还有你是否具备把知识点落到真实数据链路里的能力。