
字节跳动日常实习广告大数据研发实习面经初面投了字节的日常实习广告大数据研发方向接到初面邀请后准备了大概一周。整体节奏意外地紧凑面试官不是那种按部就班问八股的类型而是顺着你的项目和技术栈一路往下挖挖到你说不出来为止。整个过程大概55分钟前半程聊项目中间集中问数据组件原理后半段一道手写SQL加一道算法题最后留了几分钟反问。这篇面经我会尽量还原面试过程中被问到的核心问题并且把当时我怎么答的、后来复盘觉得应该怎么答的都写出来。因为是初面考察重点明显放在基础扎实度和项目真实度上不会为难你但如果你简历上写了某个组件那就得做好被深挖到源码级的准备。适合正在准备大数据开发实习面试的同学参考尤其是目标岗位偏广告、推荐这类业务场景的。1. 这个岗位是做什么的以及初面到底在面什么1.1 广告大数据研发日常实习的工作内容广告系统在互联网公司里属于离钱最近的业务线数据研发在其中承担的角色就是把广告从曝光、点击、转化到计费的整条链路数据完整地采集、计算、存储下来再供给算法模型、运营分析、报表系统去使用。日常实习生进去之后大概率接触的任务包括广告日志的清洗与解析、实时曝光点击流的统计、广告维表的管理、离线数仓ETL的开发、数据质量校验以及一部分报表接口的开发。字节的广告体系非常庞大穿山甲、巨量引擎这些都是同一个大部门下的产品线所以数据量级和实时性要求都比较高。面试官首先让我简单介绍了一下自己然后直接进入了项目深挖环节。这个岗位对实习生的预期很明确不需要你有工作经验但需要证明你真正动手写过代码、跑过任务、处理过数据问题。1.2 初面的考察维度与整体流程整场面试的流程可以拆成四个阶段自我介绍与项目深挖约20分钟大数据组件原理追问约15分钟手写SQL与算法题约15分钟反问环节约5分钟面试官手上有你的简历但并没有照着简历逐条问而是让你挑一个最有代表性的项目展开说。他会从项目背景、数据量级、技术选型、你负责的模块这几个角度切入然后不断追问细节。这种问法很考验你对项目的真实参与度如果只是看了几篇博客或者在课程作业里跑了个demo很容易在第三层追问时露出破绽。2. 项目深挖阶段的完整复盘2.1 项目背景介绍的正确打开方式我准备的第一个项目是一个实时用户行为分析平台技术栈是Flink Kafka ClickHouse。项目背景是业务方需要实时查看用户点击流和转化漏斗原来的离线T1报表满足不了运营快速调整策略的需求所以搭建了这套实时链路。面试官听完介绍后第一个问题就是“数据量大概什么级别高峰期的QPS和吞吐量是多少”这个问题很多同学会忽略但其实特别重要。大数据项目没有数据量支撑后面聊的技术难点都是空中楼阁。我当时回答的是数据源来自前端埋点和服务端日志日均处理约4亿条事件高峰QPS约2万Kafka单日写入峰值约120MB/s。这个数据量在字节的面试官看来肯定不算大但对于实习生项目来说已经能说明你接触过真实业务场景。后来复盘时我意识到回答数据量这类问题最好用相对值加绝对值结合的方式比如“日均4亿条约是业务高峰期每秒两万条”就比单纯说“挺大的”要直观得多。面试官真正想判断的是你能不能量化自己的项目规模而不是真的在比较谁的数据量大。2.2 项目中遇到的技术难点与解决思路面试官接着问项目里遇到过什么技术难点这也是项目深挖的核心问题。我讲了两个第一个是Kafka消费积压问题。某次上游推送突然增大消费者处理速度跟不上导致Kafka Lag持续上涨。我先通过Kafka的消费者组监控定位到是某个Flink任务的处理能力到了瓶颈然后用增加并行度加重新设计keyby策略的方式把热点key的数据分散到多个subtask去处理最终把Lag压了下来。面试官追问“为什么单纯增加并行度没有用”这个是关键考点。我当时的回答是因为原始的keyby策略会导致某个热点用户ID的数据全部集中在一个subtask上即使并行度提高了热点任务依然是瓶颈。所以需要在keyby之前对key做加盐处理比如对用户ID取hash后拼接一个随机后缀把热点数据打散。但加盐会带来一个副作用——同一个用户的多次行为会被分到不同的subtask导致基于会话的统计不准确。所以后来又做了两层设计对需要精确聚合的指标还是用原始key来做keyby对可以接受一定误差的统计指标才采用加盐的方式。面试官点了点头没有再追问。这道题其实是个非常经典的实时计算问题建议准备面试的同学务必把keyby加盐的几个方案和各自代价弄清楚。第二个难点是状态容错。我们用的是Flink的RocksDB状态后端配合Checkpoint但初期经常出现Checkpoint超时失败。排查后确认是因为状态过大导致同步快照阶段耗时过长后来开启增量Checkpoint和一些RocksDB的优化参数之后问题基本解决了。2.3 面试官深挖的隐藏考点项目讲完之后面试官突然问了一句“你们的实时计算和离线计算的数据能对上吗对不上怎么处理”这个问题其实是在考察数据一致性的工程经验。实时链路和离线链路通常走的是两套完全不同的计算逻辑实时为了性能会采用近似计算离线则追求精确。我当时项目里确实遇到了实时UV和离线UV对不上的情况主要原因是实时去重用的是BloomFilter存在一定的误判率而且凌晨跨天窗口的边界处理也有偏差。解决方案是建立了一套数据对比监控每天离线任务跑完后把前一天的实时汇总结果与离线结果进行比对差异超过阈值就会报警再由数据研发排查原因。对于UV这类指标实时链路最终以离线数为准实时报表只做趋势参考。面试官对这个回答比较满意。这类问题其实没有标准答案他看的是你有没有数据质量意识以及遇到问题时的排查思路是否清晰。3. 大数据组件原理的高频面试题与答题框架3.1 Java与并发基础考察项目环节结束后面试官把话题转向了基础。字节的研发岗面试Java知识是躲不掉的。虽然岗位是大数据研发但底层还是Java技术栈为主尤其是Flink和Hadoop本身都是Java写的所以基础题通常围绕集合、并发、JVM这三块出。我这次被问到的问题包括HashMap在JDK 7和JDK 8中的底层实现差别ConcurrentHashMap如何保证线程安全synchronized和ReentrantLock的区别volatile关键字的作用JVM内存区域划分以及哪些区域会发生OOM其中有道题值得展开说ConcurrentHashMap的put过程。这个知识点在大数据面试中出现频率非常高因为它直接关联到你写Flink算子时如何管理内部状态。我当时的回答是JDK 8的ConcurrentHashMap采用CAS加synchronized的方式put时先根据key的hash定位到对应的桶如果桶为空则直接CAS写入如果不为空则锁住链表头节点然后遍历链表或红黑树进行插入或更新。面试官追问了CAS和synchronized各自的适用场景以及为什么在桶为空时用CAS、不为空时却要加锁。这个问题的核心在于CAS适合并发冲突概率较低的场景而桶内已经有节点时说明这个桶大概率是热点桶直接CAS循环可能会不断失败性能反而下降不如直接锁住头节点。Java基础这部分建议复习到源码级别至少要搞清楚put和get的全过程。面试官大概率不会只问概念的表面含义会往下深挖一层。3.2 Hadoop生态核心原理作为大数据岗位HDFS和MapReduce的基本原理属于必问内容。我这次被问到的是HDFS的写入流程以及MapReduce的Shuffle阶段。HDFS写入流程的完整链路是客户端调用DistributedFileSystem的create方法向NameNode发起请求NameNode检查权限和文件是否存在后返回可用的DataNode列表。客户端把文件分成多个block默认每个block 128MB按顺序传输给第一个DataNode第一个DataNode再复制给第二个第二个复制给第三个。每个block写完DataNode会向NameNode汇报元数据信息。面试官追问了副本放置策略我回答的是第一个副本放在客户端所在节点如果是集群外提交则随机选一个磁盘和网络负载较低的节点第二个副本放在与第一个副本不同机架的节点上第三个副本放在与第二个副本相同机架但不同节点的位置上。这里其实隐含了一个问题为什么不把三个副本都放在同一个机架答案是容灾。如果整个机架断电多个副本同时丢失数据就无法恢复。跨机架存放副本可以保证即便是整个机架故障数据依然有至少一个副本可用。MapReduce的Shuffle时我按照Map阶段到Reduce阶段的顺序梳理了一遍Map端把输出结果写入环形缓冲区默认大小100MB达到80%阈值时触发溢写溢写前会做分区和排序。所有溢写文件归并成一个文件并做combiner优化。Reduce端拉取属于自己分区的数据先放到内存缓冲区放不下就溢写到磁盘最后对拉取到的数据做归并排序后交给reduce方法处理。3.3 Spark与Flink的对比追问面试官问到Spark时先让我说一下Spark的任务执行流程。我从提交Spark任务开始讲spark-submit启动Driver进程Driver向Cluster Manager申请资源Cluster Manager根据资源情况启动Executor进程Executor反向注册到DriverDriver将作业转化为DAG再按照宽窄依赖划分Stage每个Stage生成一组Task分发到Executor上执行。这中间最容易深挖的是宽窄依赖的划分逻辑。窄依赖是指父RDD的每个分区最多被子RDD的一个分区使用比如map、filter这类算子宽依赖是指父RDD的一个分区会被子RDD的多个分区使用典型的就是groupByKey和reduceByKey。宽依赖会产生Shuffle所以是划分Stage的依据。Flink这边被问的是Checkpoint机制。我讲了Flink的Checkpoint是基于Chandy-Lamport分布式快照算法实现的通过Barrier机制在数据流中插入特殊标记当某个算子收到所有输入流的Barrier后会将自身状态进行快照。面试官追问了Barrier对齐是什么以及不对齐会有什么影响。Barrier对齐是保证Exactly-Once语义的关键。当某个算子有多个输入流时必须等所有输入流的Barrier都到达后才能执行状态快照。如果某个输入流处理速度较慢其他快的输入流的数据需要缓存起来等待。如果禁用对齐慢流Barrier到达时快的流可能已经处理了更多数据导致快照中状态不是严格一致的时刻。3.4 Kafka与消息队列核心问题Kafka在广告数据链路中几乎是标配所以面试必考。这次被问到的问题有Kafka的整体架构、ISR机制、消息不丢失的配置、消费组重平衡的过程。消息不丢失这个点我认为是重中之重。面试官问“数据从生产到消费哪个环节最容易丢数据怎么保证不丢”这是典型的全链路数据可靠性问题答案要分三段来阐述生产过程Producer通过acks机制保证数据已经写入Brokeracksall表示所有ISR副本都写入成功才返回成功。如果发送失败需要开启retries重试机制。存储过程Broker端通过复制机制保证数据不丢leader挂了之后从ISR中选举新的leader通过min.insync.replicas配置保证最少有几个副本同步成功。消费过程关闭自动提交位移等消息真正处理成功后再手动提交offset。如果在处理过程中失败下次还会重新拉取该消息。3.5 数据仓库基础与模型设计面到后面面试官问了一下数仓的基础概念。可能是我的项目偏实时多一些所以问题没有问得很深主要集中在维度建模理论上。被问到的是事实表和维度表的区别以及星型模型和雪花模型的选择。我回答的是事实表存放业务流程中的度量值比如广告曝光量、点击量、消费金额特点是数据量大、会不断追加维度表存放描述业务对象的属性比如广告位类型、用户画像标签、地区信息特点是数据量小、变化慢。星型模型是事实表直接关联维度表查询时只需要一次join性能好但会有数据冗余雪花模型是维度表再拆分成多层更规范化但查询需要多次join。面试官追问了一句“在字节这边做大数据的报表你倾向于用星型还是雪花”我回答的是星型。因为报表场景对查询性能要求很高而雪花模型的规范化带来的存储节省在字节这个体量下基本可以忽略但查询性能和易用性上的牺牲却是实打实的。这类开放性问题没有对错关键是说出你的考量逻辑。4. SQL、算法题与场景题实战4.1 手写SQL连续登录天数面试官出的第一道手写题是SQL场景是广告投放业务让我统计每个广告主连续3天及以上有消耗的天数。题目很常见但需要在白板上完整写出来。我的思路是用窗口函数加日期差值的技巧WITH tmp AS ( SELECT advertiser_id, stat_date, DATE_SUB(stat_date, ROW_NUMBER() OVER (PARTITION BY advertiser_id ORDER BY stat_date)) AS grp FROM ad_cost_daily WHERE cost 0 ), grouped AS ( SELECT advertiser_id, grp, MIN(stat_date) AS start_date, MAX(stat_date) AS end_date, COUNT(*) AS cnt FROM tmp GROUP BY advertiser_id, grp ) SELECT advertiser_id FROM grouped WHERE cnt 3 GROUP BY advertiser_id;这个思路的原理是如果日期是连续的那么在按日期排序后日期本身与行号的差值是一个固定值连续日期会落在同一组。比如1号、2号、3号这三行分别对应行号1、2、3日期减行号都是0所以归为同一组。面试官看了之后没让我执行而是问了一个变种问题“如果数据是每小时一条统计连续5小时有消耗的广告主怎么写”思路完全一样只是把DATE_SUB换成小时级别的函数比如使用DATE_ADD按小时计算或者直接时间戳减去小时数乘以3600秒。这个变种问题考的就是你能不能灵活迁移而不是死记模板。4.2 算法题最长无重复子串手写算法题考的是LeetCode第3题“无重复字符的最长子串”的变种面试官把题目背景改成了广告点击流里的用户行为序列但核心逻辑没有变化。我写的是滑动窗口解法public int lengthOfLongestSubstring(String s) { MapCharacter, Integer map new HashMap(); int left 0; int maxLen 0; for (int i 0; i s.length(); i) { char c s.charAt(i); if (map.containsKey(c)) { left Math.max(left, map.get(c) 1); } map.put(c, i); maxLen Math.max(maxLen, i - left 1); } return maxLen; }这道题整体难度不大面试官关注的是你能不能把思路讲清楚以及代码是否规范。我写完后面试官问了一个问题“如果字符串特别长内存限制严格你有什么优化思路”我当时的回答是可以用数组替代HashMap因为如果字符集限定在ASCII范围内直接用大小为128的int数组记录每个字符上一次出现的位置查询和更新都是O(1)的不需要额外的哈希计算和内存开销。这样在极端场景下会更适合大数据的流式处理。4.3 场景设计题广告点击率的日志清洗最后一道题是纯场景设计没有任何标准答案。面试官描述了一个场景每天有几百亿条广告曝光日志要筛选出真正有效的点击行为并统计不同广告位的点击率你会怎么设计这个计算链路我的回答分了几步数据接入阶段曝光和点击日志实时写入Kafka按照广告请求ID作为key确保同一请求的曝光和点击写入同一个分区。清洗阶段Flink任务消费Kafka过滤掉无效日志比如爬虫流量、重复点击、超时点击。然后对曝光流和点击流做双流join用窗口匹配的方式关联点击时间距离曝光时间超过10秒的视为无效。统计阶段按照广告位ID和时间窗口做聚合结果写入ClickHouse供实时查询同时落一份Hive离线表做T1核对。面试官追问道“如果点击流的数据比曝光流晚到了很久在10秒窗口内join不上怎么办”我回答的是可以用侧输出流把未匹配上的点击数据暂时缓存起来延迟一段时间后再尝试和曝光数据匹配。Flink的state可以用来保存延迟到达的曝光数据设置TTL控制缓存时间。如果超过TTL还匹配不上说明这条点击大概率是无效的记录下来供后续分析。这类开放性问题面试官主要看你的逻辑是否完整有没有考虑到边界情况。能说出数据延迟、乱序、重复处理这些异常场景的处理方案基本就能过关。5. 复盘总结与准备建议5.1 面试过程中容易踩的坑整理几个我这轮面试中感知到的坑以及后续复盘总结出的建议。第一个坑是过度包装项目。简历上写了熟悉某个组件但被追问到内核原理时支支吾吾这在大数据方向的面试里会直接判死刑。字节的面试官普遍会沿着一个技术点连环追问下去通常能连续追问四五层直到你答不上来为止。与其在简历上写十个“熟悉”不如挑两三个真正深入研究过的组件写“深入了解”。第二个坑是只背结论说不清原因。比如说自己用过Spark的repartition和coalesce知道repartition会增加分区数、coalesce可以减少分区数但不知道repartition底层是shuffle操作而coalesce如果在减少分区数时且没有改变并行度要求则不会触发shuffle。面试官如果问一句“为什么”答不上来还是等于不会。第三个坑是算法题准备工作不足。日常实习面试对算法题的要求不算高基本都是LeetCode前150题范围内的题目但需要在白板上写正确并且能分析时间和空间复杂度。我这次运气比较好抽到了中等偏简单的题目但同一个面试官面别人时可能会出Hard题所以准备阶段还是建议把Hot 100刷两遍以上。5.2 针对广告大数据方向的准备重点如果目标就是字节广告方向的大数据研发实习建议在通用准备之外专门了解两块内容。第一块是广告业务的基础知识。广告系统涉及的核心概念包括广告主、计划、单元、创意这几个层级曝光、点击、转化、消耗这几个核心指标CPM、CPC、CPA这些计费模式。不要求你能设计广告系统但至少要能听懂面试官在说什么并且在场景设计题中能结合业务去思考。第二块是实时链路的实战经验。广告数据最大的特点是实时性要求高预算消耗、效果监控都需要分钟级甚至秒级的数据反馈。所以Flink和Kafka是广告大数据岗位出现频率最高的组件务必把这两个吃透。特别是Flink的窗口机制、状态管理、Checkpoint配置、背压处理以及Kafka的消费者组、位移管理、副本同步原理这些在面试中出题概率极高。5.3 日常实习面试的整体策略建议字节日常实习和校招提前批最大的区别在于面试轮次少、周期短、考察深度相对较浅。初面通过之后通常还有一轮技术面和一轮HR面整体难度是可控的。但也正因为流程紧凑每一轮都要尽可能表现得完整尽量不要有明显的知识短板。有一个比较实用的策略是在自我介绍和项目介绍环节主动把话题引向你擅长的领域。面试官很多问题都会顺着你的回答延伸如果你在介绍项目时反复强调Flink的Checkpoint调优面试官大概率会顺着这个方向追问这样你就能在自己准备好的范围内输出。反过来如果项目介绍得很模糊面试官就只能随机出题碰到盲区的概率就会变大。另外建议提前了解面试部门的产品和业务。广告部门下面有多个方向比如搜索广告、信息流广告、联盟流量等业务场景不同对数据的要求差异也很大。如果能在反问环节提出有针对性的问题比如“目前团队在实时特征计算上用的方案是什么”“数据量和延迟要求大概是什么级别”面试官会认为你真的对岗位感兴趣而不是海投简历碰运气。5.4 后续可以继续加练的方向这次面试整体通过但我复盘下来还是发现有几个点准备得不够充分。一个是Flink的状态后端细节面试官问到了RocksDB的增量Checkpoint和TTL清理机制我当时只回答了大概没有深入到实现层面。另一个是Hive SQL的优化广告业务查报表经常碰到数据倾斜虽然简单说了加盐和热点分离的思路但并没有给出具体的参数配置。这些都是实习期间大概率会实际用上的技能值得继续补强。如果你也正在准备大数据研发方向的面试我个人的体会是基础知识的广度决定你能不能过简历筛选项目深度的挖掘程度决定你能不能过技术面。八股文要背但不能只背八股文一定要能串起来讲——从一条数据进入Kafka开始到它经历Flink计算、写入存储、被报表查询每一步发生了什么、为什么这么做、出了问题怎么排查这个整链路思维才是面试官真正想在你身上看到的东西。