2017年秋招结束之后,很长一段时间里,触宝科技这轮“后端大数据”方向的笔试题目都在圈子里被反复提起。原因很简单:它不像很多大厂铺天盖地堆算法题,而是把后端基础、大数据组件、工程思维揉在一张卷子里考察。如果你当年投过触宝,或者正在准备25届、26届校招的后端/大数据方向,这份复盘应该能帮你少走不少弯路。我从题目结构、考点拆解、答题策略三个维度把当时的笔试场景还原出来,并结合这些年的面试经验做些延展分析。
1. 回看触宝笔试题:它在筛选什么样的候选人
1.1 “工具型”互联网公司的技术用人逻辑
先聊聊触宝这家公司。做输入法、来电秀这类工具产品起家,用户量数十亿级别,这类业务的典型特点是:不需要像电商、金融那样极致的业务复杂度,但对“高并发”“海量数据”“稳定性”的要求一点都不低。后端每天要处理的是全球用户产生的输入行为、来电识别、内容推荐数据,量级上来之后,传统的单体架构撑不住,必须靠分布式系统和大数据链路去解决。
2017年这个时间点很微妙。Hadoop生态还是大数据领域绝对的主流,Spark正处于快速上升期,Flink才刚刚开始被人讨论。所以触宝笔试里大数据部分的题目,几乎全部围绕Hadoop、Hive、Spark这些组件展开。这背后反映出的用人逻辑是:候选人不需要有多么惊艳的业务想象力,但必须掌握一套能处理海量数据的成熟工具链,并且理解它们的运行原理。笔试里反复出现的“集群”“调度”“数据倾斜”,本质上都是在问你:把你丢到一个每天产生几个T数据的环境里,你能不能干活。
1.2 第二批试卷的总体结构复盘
第二批笔试题型和大部分互联网公司校招一致:选择题、填空题、手写代码、简答/设计题。总共时间大概是90分钟到120分钟,题量不小,想全部答完且答好,时间非常紧张。从考点分布看,大致能分为四块:
- Java基础与并发编程,约占总分25%,重点在集合原理、JVM内存模型、线程池。
- 数据结构与算法,约占总分25%,包括选择题里的复杂度和手撕代码题,难度中等偏上。
- 计算机网络与操作系统,约占总分15%,考察TCP/UDP、进程线程等经典知识点。
- 大数据方向,约占总分35%,覆盖Hadoop、Hive、Spark以及简单的架构设计,是整张卷子的区分度所在。
把大数据占比放到35%这个位置,可以明确看到岗位定位:这不是一个“会写Java就能来”的后端岗,而是希望候选人已经对大数据技术栈有系统性的理解和项目实操经验。如果你当年只刷了算法题就去考,大概率会被大数据模块拖垮。
1.3 为什么这套题放在今天仍有参考价值
有人可能觉得2017年的笔试题太老了,现在都流行云原生、AI Infra,看这种题有什么意义?我个人的看法是:基础知识的考察逻辑没有变。Java集合的底层实现、并发编程的三大特性、分布式系统的CAP理论、MapReduce的Shuffle过程,这些东西十年过去了依然是后端面试的高频考点。大数据的组件会迭代,但核心思想一直是“分而治之”和“移动计算而非移动数据”。
另外,这两年大模型带火了RAG、向量数据库这些新东西,但企业级的数据处理底座还是离不开Spark、Hive、Flink这一套。很多25届同学一问大数据就只会说“我用过Spark SQL”,再往深问DAG调度、数据倾斜、动态分区就答不上来了,这种基础功的薄弱在笔试里暴露得特别快。所以这篇复盘我尽量把每个考点背后的原理讲透,而不只是罗列答案。
2. 逐题复盘:基础题与算法题的考察重点
2.1 Java基础与并发:不只是背八股
触宝的后端主语言是Java,所以Java题目出得相当细。选择题里印象比较深的两道:一道是HashMap在JDK 1.7和JDK 1.8之间的变化,考察内容包括数组+链表的结构、头插法和尾插法的区别、红黑树引入的条件(链表长度达到8且数组长度达到64)。这道题当年难倒了不少人,很多人知道HashMap线程不安全,但说不出为什么不安全,更说不清JDK 1.7并发put时为什么会出现死循环。
还有一道是volatile关键字的作用,选项里既有“保证可见性”“禁止指令重排”这些正确答案,也混着“保证原子性”这种错误选项。这道题考察的是你对JMM(Java内存模型)的理解深度,如果只是背过“volatile不保证原子性”这句话,而不知道为什么,很容易被绕进去。顺便说一句,现在面试里很多同学依然在这个问题上栽跟头,每次我都会建议他们自己写一个多线程累加的小示例去跑一遍,眼见为实比什么都管用。
配套的编程题里还出现过线程池参数设计:给定一个IO密集型的任务场景,让你选择核心线程数、最大线程数、队列长度。这种题没有标准答案,考察的是你有没有实际调过线程池参数的经验。我的思路是:IO密集型任务核心线程数可以设置成CPU核数的2倍左右,队列用有界队列避免任务无限堆积,拒绝策略用CallerRunsPolicy让提交线程自己执行任务,起到天然限流的作用。重要的是把每一步选择的理由写清楚。
2.2 数据结构与算法题:中规中矩,但手速要快
算法题部分,触宝这批没有出特别偏难怪的题目,基本都在LeetCode中等难度范围内。我印象里出现了:单链表反转、二叉树层序遍历、一个无序数组找第K大(TopK问题)。这三个都是高频题,但笔试题有个特殊性:在线IDE没有自动补全,而且函数签名已经给定,你必须直接写完整的类或函数,边写边自己检查语法。
这里说说TopK那题。最优解是用堆,Java里用PriorityQueue,时间复杂度O(nlogk)。但很多人一上来就写数组排序,Arrays.sort之后再取第k个,这种解法在笔试里通常只能拿一半分,因为面试官期待的是你能分析不同方案的复杂度差异。如果题目还特别强调了“数据量很大,无法一次性加载到内存”,那就要想到分治的思路:先用哈希取模把大文件拆成小文件,再在每一个小文件里求TopK,最后归并。触宝笔试题里就有一道类似的简答题,聊到这个思路会有加分。
算法部分的另一个体会是:练题不能只练“能做出来”,还要练“快速做出来”。在线笔试时间紧,一道中等题如果30分钟还没AC,基本就等于这场笔试告别了。我自己的策略是优先保证链表、二叉树、哈希表、堆、动态规划这五类题型的熟练度,贪心、回溯、图论放到次优先级。这不是说图论不重要,而是笔试题出现频率确实有差异,备考效率优先。
2.3 网络与操作系统:经典题目的“变化”
网络和操作系统占比不高,但出现频率非常稳定:TCP三次握手、四次挥手、TIME_WAIT状态的意义、进程和线程的区别、进程间通信方式。触宝的选择题里有一道关于TCP的选项特别有意思:出现“TIME_WAIT是主动关闭方进入的状态”和“TIME_WAIT会持续2MSL时间”这两个正确选项,同时又设置了“TIME_WAIT是被动关闭方进入的状态”这个干扰项。考察你真的知道是谁主动谁被动,而不是把流程背一遍。
操作系统方面有进程状态切换的选择题(就绪、运行、阻塞,以及条件不满足时从运行态回到就绪态还是阻塞态),还有虚拟内存和页面置换算法的概念题。这些内容如果科班出身,上课都学过,但到了校招阶段很多人已经忘得差不多了。我的建议是把操作系统里“进程线程”“内存管理”“文件系统”这三章拉出来快速过一遍,配合刷一些考研408的题目,基本能覆盖校招笔试题里的大部分操作系统考点。网络同理,TCP/UDP、HTTP/HTTPS、DNS解析流程,每个都花不到半天就能复习完,性价比很高。
3. 大数据方向核心考点:拉分题全在这
3.1 MapReduce与Shuffle:大数据笔试的“必考老题”
整张卷子里最核心的拉分模块就是大数据方向。第一道大题基本围绕MapReduce展开,要求描述一个WordCount作业从提交到完成的完整过程。看似简单,但想拿高分必须把细节写全:InputFormat如何将文件切分成split、RecordReader如何逐行读取并生成key-value、Map阶段的分区和排序、Shuffle阶段的复制与合并、Reduce阶段的归并与输出。
其中Shuffle是考察重点。至少要把这四个关键点写清楚:分区(Partitioner,默认按key哈希取模)、排序(按key排序)、合并(Combiner,在Map端做局部合并减少网络传输)、分组(GroupingComparator,决定哪些key进入同一个reduce方法)。如果只写到“Map输出经过Shuffle传给Reduce”,基本拿不到分。我记得另一个候选人朋友当时在复盘里提到,他把MapReduce的执行流程画成了时序图来记忆,这个思路我非常推荐——对分布式框架的理解,能用图画出来才算是真理解。
还有一道简答题是“描述数据倾斜的原因及解决方案”。数据倾斜这个考点直到今天依然是面试官最爱问的分布式问题之一,可见其重要性。原因类的主要有:key本身分布不均匀(比如大量空值、热点key)、分区函数设计不合理、业务数据天然倾斜(比如两张大表join时关联字段大量重复)。解决方案至少应该写出:加盐随机前缀打散热点key、两个阶段聚合(局部聚合+全局聚合)、调整Combiner、使用SALTSALT预处理、广播小表代替reduce join。如果能把Map端Join和Reduce端Join的区别也说清楚,这道题就稳了。
3.2 Hive与SQL:必须掌握的四个核心方向
像触宝这类数据量大的公司,Hive几乎是离线数据仓库的标配。笔试里Hive相关的题目,集中在四类:建表语句与分区表、HiveQL与SQL的区别、开窗函数、数据查询优化。
分区表是高频考点,考察你是否知道动态分区和静态分区的区别、分区字段为什么不能和表内字段重复、分区和分桶的适用场景。笔试中出现过一道排序题:给出一个复杂的HiveQL,要求选出执行顺序。很多人从SQL的执行顺序去套,但Hive与标准SQL不完全一样,关键是理解HiveQL最终会翻译成MapReduce作业,解析器会先做AST语法树,再经过逻辑计划、物理计划,最后生成多个MapReduce任务。这道题能看出你对Hive原理的真实掌握程度。
开窗函数那题更有趣,场景是“求每个用户最近三天的订单金额”,需要用到ROW_NUMBER()或者SUM() OVER(PARTITION BY user_id ORDER BY order_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)。这种题目现在已经成了大数据SQL笔试的标配,LeetCode上的SQL题就有大量类似场景。建议备考时把以下几类题型全部过一遍:TopN问题、连续登录天数、留存率计算、行转列、列转行、累计求和、同比环比。每一类都手写一遍HiveQL和标准SQL两种风格,面试时就不慌了。
3.3 Spark核心概念:从RDD到DAG的连贯理解
2017年是Spark大火的年份,触宝的笔试题自然不会放过。有一道选择题问Spark与MapReduce相比的优势有哪些,选项包括“中间结果可以缓存在内存中”,“DAG调度减少不必要的Shuffle”,“提供多种语言的API”,“实时性更好”。如果你只学过Hadoop,没有真正跑过Spark的作业,很容易漏选DAG调度这一个点。
简答题里还出现过“简述Spark作业提交后的执行流程”,可以按这个顺序答:提交SparkSubmit、构建SparkContext、DAGScheduler将作业切分成Stage、TaskScheduler分发Task到Executor、Executor执行任务并返回结果。这里要注意,题目虽然没直接问,但最好顺带写清楚宽依赖和窄依赖的区别,以及宽依赖为什么会产生Shuffle、Stage是怎么根据Shuffle划分的。能把这几个概念串联起来,说明你是真的在用它做过事,而不只是看过理论。
Spark SQL和Spark Streaming也各有一道选择题,难度不大:Spark SQL的DataFrame和RDD的异同、Spark Streaming的批处理间隔(batch interval)意味着什么。Flink在2017年还没那么普及,所以卷子里没有出现,如果你现在准备校招,建议把Flink的检查点机制、事件时间与窗口也补充进知识图谱里。
3.4 集群与架构题:从单机思维切换到分布式思维
笔试题最后有一道开放式设计题,大致背景是:某业务每天产生大量日志,需要离线统计和实时告警,请设计一套数据架构并说明各组件选型理由。这种题没有标准答案,拼的是知识广度和工程判断力。
我当时给的方案是:日志采集用Flume或Kafka,离线链路用HDFS做存储,Hive或Spark SQL做ETL和分析,调度用Azkaban或Oozie;实时链路用Spark Streaming消费Kafka,结果写入MySQL或Redis,告警则通过简单规则引擎触发。关键在于每一个选型都要给出理由,例如“Kafka选它的原因是削峰填谷、消息持久化、支持多消费者”,“HDFS采用NameNode+DataNode架构,适合大文件顺序读写,不适合小文件随机读写”。
这种设计题对纯后端候选人来说比较吃力,他们可能更熟悉Spring Cloud那套微服务方案,对大数据组件了解有限。但换一个角度想,这种题恰恰是在模拟真实的工程场景:触宝的后端开发每天就是和数据管道、离线任务调度打交道,如果你能体现出“我理解组件之间的数据流转和瓶颈所在”,就已经超过了大部分竞争者。
4. 从这场笔试反推:校招后端大数据方向的备战路线
4.1 基础不牢,地动山摇:先补齐四门核心课
如果让我给你一条从零开始的校招准备路径,第一步一定不是追新技术热点,而是把计算机基础打牢。数据结构与算法、操作系统、计算机网络、数据库原理,这四个科目是笔试的底座,也是面试里八股的来源。触宝这套题里,Java并发和网络操作系统的题目,本质上都是基础课的延伸。
具体的时间分配上,我建议非科班或者基础薄弱的同学,用4到6周集中过一遍重点:算法刷题保持在每天2到3道,操作系统和网络各花约一周看高频考点,数据库重点看索引和事务,Java语言层面把集合、并发、JVM三块吃透。不建议死记硬背“面试题合集”,而是跟着问题去查源码、看官方文档,哪怕只是把HashMap的putVal方法源码读一遍,收获也比背十道面试题大得多。
4.2 大数据方向,项目经验比证书更管用
大数据岗位的笔试和面试,越来越看重“你有没有真正用一个大数据框架写过东西”。触宝的Hive和Spark题目,如果只看书不实践,很容易眼高手低。我的建议是:用一台8G内存的电脑装一个单机版的Hadoop集群(或者用Docker基础镜像把NameNode、DataNode、ResourceManager几个核心进程拉起来),再配一个Hive,把官网的示例数据导入进去,跑几条复杂的SQL。这个过程会让你把环境变量、端口号、配置文件这些细节彻底过一遍,而这些细节往往是笔试填空题的考点。
更进一步的话,可以做一个完整的离线数仓小项目:从日志生成、采集到HDFS,再用Hive做分层建模(ODS、DWD、ADS),最后用Sqoop或DataX导出到MySQL,用Superset或FineBI做可视化。这一段经历写到简历里比任何证书都能打。面试官问“你能讲讲你们的数仓分层吗”,你就能把每一层的职责、为什么要分层、有没有遇到数据质量问题都展开聊,这就是真实的项目经验带来的底气。
4.3 刷题的策略:不是题海战术,而是刻意练习
备考阶段的刷题策略,我总结成一句话:先分类、再限时、后复盘。按数据结构分类刷题可以快速建立“看到什么题用什么数据结构”的直觉;限时是为了模拟笔试的紧张感,我一般建议一道算法题控制在30分钟以内,超过时间直接看题解,不要死磕;复盘比刷新题更重要,每一道做错的题都要记录错误原因、最优解思路、我能想到的变体,这样才叫有效刷题。
大数据方向的SQL题也一样,牛客网和LeetCode上的SQL题库都值得刷。但千万不要只看题解,一定要自己敲一遍,用本地环境或者在线SQL运行器验证执行结果。手写SQL时的字段别名、空值处理、日期函数这些细节,不实际运行一遍很难发现自己的盲区。
5. 笔试实战中的问题与心得
5.1 在线笔试平台未必友好,提前适应环境
这类校招笔试通常使用第三方在线评测平台,界面和牛客网差不多,但有几件事必须提前确认:第一,是否允许使用本地IDE。有些平台禁止跳出页面切到本地,这时你就得适应网页上的在线编辑器,没有代码高亮和自动补全,写起来非常别扭。第二,题目是否支持C++、Java、Python多种语言。大数据岗位一般可以用Java写,但如果代码题里涉及的字符串处理很繁琐,用Python写会快很多。第三,注意输入输出的格式,很多在线笔试的算法题不要求你处理文件读取,只需要从标准输入读取,但有些平台要求写完整的Main类或特定函数签名。
我当时就吃过亏:有一道Java代码题,平台自动生成的主类名是Main,我下意识按照平时练习的类名写,结果编译直接报错,浪费了宝贵的五分钟。所以接到笔试通知后,建议先去官网熟悉一下平台的示例题目,把读写模板提前准备好,真开考时直接复制修改,能省下不少时间。
5.2 时间分配:先拿基础分,再啃硬骨头
触宝这套题90到120分钟,题量不小,合理的时间分配是答题效率的关键。我的习惯是:拿到试卷先花两分钟浏览全卷,按题型和分值把时间切块。选择题和填空题一般控制在30到40分钟内完成,遇到拿不准的不要恋战,先标记一下,做完其他题再回头。代码题每道控制在25到30分钟,如果一道题超过40分钟还没有AC,建议先把能写的思路写上去,哪怕只通过部分用例,也比空着强。简答和设计题放在最后,这类题即使思考时间短,只要结构完整、关键点覆盖到位,也能拿到不错的分数。
5.3 触宝笔试牛客网版本的复现参考(示例题目)
也许有人想看一份接近原卷的示例,我根据参与过的类似笔试和公开面经信息,整理了三道具有代表性的题目,供大家练手用。
示例一:手写代码题(TopK)
给定一个整数数组,求数组中第K大的数。
public int findKthLargest(int[] nums, int k) { // 使用最小堆,时间复杂度 O(nlogk) PriorityQueue<Integer> minHeap = new PriorityQueue<>(); for (int num : nums) { minHeap.offer(num); if (minHeap.size() > k) { minHeap.poll(); } } return minHeap.peek(); }如果数据量超大没法全部载入内存,就问怎么办:先用哈希分片,把数据拆到多个小文件,每个小文件内求TopK,最后把每组的TopK归并。这种分治思路在工程场景下更常见。
示例二:HiveSQL题(连续登录/窗口函数)
有一个用户登录表login(user_id, login_date),求每个用户连续登录的最大天数。
SELECT user_id, MAX(consecutive_days) AS max_days FROM ( SELECT user_id, DATE_SUB(login_date, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY login_date)) AS group_id, COUNT(*) AS consecutive_days FROM ( SELECT user_id, login_date FROM login GROUP BY user_id, login_date ) t GROUP BY user_id, DATE_SUB(login_date, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY login_date)) ) tmp GROUP BY user_id;这种题的关键是理解“用登录日期减去行号得到锚点日期”的思路。锚点日期相同的行就是连续日期序列。
示例三:简答题(数据倾斜)
这类开放性题目建议按“现象-原因-常规对策-进阶对策”四层结构作答。常规对策包括:扩大分区数、设置Combiner、对小表进行广播;进阶对策包括:将热点key加上随机前缀后分两次聚合,或者采用采样方式找出大key先做预处理。如果你能补充一个自己在项目中真实遇到的倾斜场景和解决过程,含金量会大幅提升。
5.4 笔试前一周的“急救包”
最后分享一个我自己的考前一周急救方法:把以下内容整理成一张A4纸,每天睡前过一遍——TCP三次握手与四次挥手状态、HashMap与ConcurrentHashMap原理、JVM内存区域与GC Roots、MapReduce Shuffle流程、Hive的执行顺序、Spark宽窄依赖与Stage划分、Kafka的消费者组概念、常见SQL窗口函数写法。这些知识覆盖了后端大数据笔试的高频考点,临阵磨枪能帮你稳定住基础题的得分率。
笔试考察的本质不是“你是否遇到过原题”,而是“遇到问题时的分析思路和知识体系是否完整”。这张A4纸的意义,是让你在紧张的考试环境下有一个快速提取知识的索引,不至于因为紧张把脑子里已有的内容忘了。