尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

字节跳动后端实习面经:从笔试到HR面的全流程复盘与思考

字节跳动后端实习面经:从笔试到HR面的全流程复盘与思考 我为什么会出现在这个面试间里七月的某个下午我刚结束上午的实验室组会手机弹出一封邮件——字节跳动后端开发实习生 - 面试邀约。说实话那会儿我连简历上的项目描述都还没背熟脑子里塞满了 Spring Boot 的自动配置原理、JVM 垃圾回收器的区别但心里总有种“还没准备好”的不确定感。我投的是日常实习不是暑期转正项目所以流程相对紧凑。投递渠道是官网 内推同步走从投递到收到笔试链接只隔了三天。字节的效率在招聘环节体现得很明显笔试完大约一周就收到了面试邀约。整个流程从一面到 HR 面前后将近半个月。这篇内容把那次面试的完整经过、每一轮的核心问题、我的回答方式、以及复盘后意识到的问题都整理了出来。不保证现在的面试题还一模一样但考察逻辑和追问风格这些年基本没变。如果你是即将投递后端实习岗、准备系统学习后端、或者想在 Spring / MySQL / Redis / 项目实战方向上查漏补缺的人这下面经应该能帮你大概摸清字节后端实习面试的“路数”。1. 投递时间线全记录从笔试到三面结束1.1 笔试环节不算难但时间分配很容易翻车字节的实习生笔试通常在牛客网进行时长约 90 分钟包含选择题和编程题。我那次笔试是 3 道编程题加若干选择题编程题整体处于 LeetCode 中等偏下难度但最后一题如果不提前熟悉套路很容易在边界条件上卡住。印象最深的是第一题要求处理一个字符串解码问题类似 “3[a2[c]]” 这种嵌套结构展开。这类题我刷过但手速慢了导致最后一题只剩不到20分钟。最后一道是“最大连续子数组和”的变体——要求返回子数组本身而不是和。我用了贪心加指针标记但边界条件没处理好自己构造用例测了一下发现有 bug但时间已经到了只能提交。笔试后的复盘建议字符串处理、栈模拟、双指针这三类题是笔试高频优先练。牛客网的选择题有时占比不小会涉及计算机网络和操作系统的基础题别全指望笔试编程题拉分。在线编辑器没有本地 IDE 的自动补全平时练习一定要在无补全环境下写代码。笔试通过后大约五天HR 打电话约一面时间。考虑到我当时还在学校就直接约了线上的视频面试。1.2 一面基础技术扎实度才是第一道筛子一面面试官看起来年纪不大开场没有太多寒暄直接让我做了个自我介绍。我大概花了两分钟讲了自己的学校背景、正在做的前后端分离项目以及用到的技术栈。这个环节我的建议是别背简历讲清楚“我在项目中承担了什么角色、解决了什么问题”就够了。随后进入八股问答环节问题覆盖还算常规但追问很细。我记得的几个问题TCP 三次握手和四次挥手的过程以及为什么挥手要四次。HTTP 和 HTTPS 的区别HTTPS 握手过程大概是什么样。在 Spring Boot 项目里一个 HTTP 请求从进入到返回经历哪些核心组件。HashMap 的 put 方法流程以及 JDK 1.8 之后引入了什么优化。什么是线程池核心参数有哪些拒绝策略怎么选。这些问题单独拿出来每道题都能背但被追问起来节奏很快。比如“HashMap 的多线程安全问题你了解吗为什么 ConcurrentHashMap 更安全”这种连环问非常考验是否真正理解而不只是背结论。一面最后是一道算法题中序遍历二叉树要求不使用递归。我用栈实现了标准解法后面试官追加了一句“能不能用 Morris 遍历做到 O(1) 空间”。我知道 Morris 的思想是线索二叉树但当时没写过完整实现只能坦诚说了思路代码没有现场调通。面完感觉大概率过了但也没有很有把握。1.3 二面项目深挖和场景设计题的“硬碰硬”二面约在两天后面试官明显更侧重项目实际落地。我没有太多生产级项目经验简历里主要是一个基于 Spring Boot Vue 的前后端分离项目以及一个模仿 RuoYi 框架写的后台管理系统。面试官从项目入手问得非常深。具体过程在下一章节详细展开这里是整体感受二面的核心不是“你用过什么技术”而是“如果现在让你设计一个系统模块你会怎么设计”。面试官会不断给约束条件比如“如果用户量翻十倍你的方案还能不能撑住”这种场景题没有标准答案关键看思路是否清晰。二面的算法题是一道动态规划最长递增子序列。N 的规模给得比较大明摆着提示需要 O(n log n) 的解法。这道题我勉强写出了常规 O(n²) 的 DP面试官引导了一下“能否用贪心 二分优化”我在提示下勉强实现了二分查找维护 tails 数组的方案但代码写得磕磕绊绊。1.4 三面加 HR 面综合能力比想象中更重要三面在一面二面通过后隔了大约一周。三面的面试官更偏向“未来老板”的角色不会问太多死记硬背的知识点更关注逻辑思维和沟通表达。让我印象很深的是一个开放题“如果要设计一个秒杀系统你会考虑哪些东西” 这题我从来没有系统准备过只能现场梳理思路从流量控制、库存扣减、接口幂等、消息队列削峰这些角度去答。再配合两道比较常规的算法题后三面结束。HR 面反而是全流程里最轻松的只问了到岗时间、实习时长、目前有哪些其他 offer、职业规划这类常规问题。2. 面试官追问链复盘那些答得好的和翻车的回答2.1 MySQL 索引与 MVCC 的连环追问这是我最“舒服”的一段二面项目深挖阶段面试官问到了项目里的表结构设计和查询优化。我的项目里有一张用户行为记录表数据量不大但当时用到了联合索引。面试官顺势展开了索引的追问链为什么需要索引联合索引的最左前缀原则是如何实现的你了解 InnoDB 的聚簇索引和非聚簇索引的区别吗什么情况下即使有索引也不会走索引前几个问题我都能对答如流。问到“为什么最左前缀原则这么设计”时我意识到只背概念不行必须理解索引底层的数据结构。我举了个例子联合索引好比先按姓氏、再按名字排序的电话簿如果你只知道名字去找人电话簿就失效了。面试官对这种解释方式比较认可。接着他抛了一个更深的题InnoDB 的 MVCC 是怎么实现的我当时答了隐藏列DB_TRX_ID 和 DB_ROLL_PTR、undo log 版本链、ReadView 的可见性判断规则这几个核心点。这部分我反复看过《MySQL 技术内幕InnoDB 存储引擎》里相关章节所以答得还算有条理。回答完面试官追问了隔离级别与 MVCC 的关系比如“为什么可重复读级别下快照读不会出现幻读” 我说快照读用的是启动事务时创建的 ReadView后续复用所以看不到别的事务新插入的数据但当前读加锁读会出现幻读要解决需要 next-key lock。能感觉到面试官对这里比较满意因为很多人只背结论“可重复读解决了幻读”但实际上快照读和当前读是两套机制。这段追问链给我的启发是MySQL 面得非常细如果只知道索引的 B 树结构不知道 MVCC 和锁的关系很容易在连环追问下露馅。2.2 Redis 缓存与数据库的一致性一道我差点“崩掉”的题项目里我用 Redis 做了用户 Session 的缓存顺便存了一些热点配置。面试官没问我 Redis 的常见数据结构而是直接切入缓存与数据库一致性问题“如果用户修改了个人资料你是先更新数据库还是先删缓存”我回答先更新数据库再删除缓存并提到这是 Cache Aside Pattern 的常见做法。面试官继续问“如果先更新数据库成功但删除缓存失败会怎么样”这里我卡壳了。虽然知道会导致旧缓存继续被读到但一时没给出很好的补救方案。事后复盘合理的回答路径应该是删除缓存失败后可以引入重试机制比如把失败的 key 发送到消息队列由消费者重试删除。或者使用订阅 binlog 的方式异步清理缓存比如 Canal。更简单的方案是设置合理的过期时间让脏数据最快在过期时间后自然失效。我当时只答了“可以用重试机制”但没细化到消息队列或 binlog 这种工程落地手段。面试官笑着点了点头接着问“那如果是先删缓存再更新数据库会有什么问题” 这个问题我知道答案如果缓存删除后另一个线程把旧数据读回缓存而数据库还没更新完成后续读到的就是旧值。但我在回答时有点紧张表述不够清晰面试官还帮我补充了一下场景。这一段算是我面试里最踉跄的部分了。现在回头看这类题确实没有标准答案面试官要的是你说得清楚“为什么这样设计会有一致性风险”以及“有哪些兜底手段”。我因为没有真正处理过高并发下的一致性场景答得不够果断。2.3 Java 并发和 JVM 的考察角度不追求冷门但基础必须扎实一面中 Java 并发的问题相对基础但追问的深度藏在细节里。比如“volatile 能保证原子性吗”很多人第一反应是不能但要能解释为什么——volatile 只能保证可见性和有序性不能保证复合操作的原子性比如count这个操作就不是原子的包含读、加、写三步。再比如“synchronized 和 ReentrantLock 的区别”。我回答了两者都是可重入锁ReentrantLock 支持公平锁、可中断、支持多个条件队列synchronized 是 JVM 层面的关键字靠 monitor 机制实现。然后面试官追问“JDK 1.6 之后 synchronized 做了什么优化”我提到了偏向锁、轻量级锁、重量级锁的升级路径以及锁粗化、锁消除。JVM 部分问到了垃圾回收。面试官问的是“如何判断一个对象可回收” 我答了引用计数法和可达性分析重点讲了为什么主流 JVM 不用引用计数法——循环引用问题。随后追问了 CMS 和 G1 的区别、你了解 ZGC 吗。我当时只对 CMS 和 G1 有概念层面的了解ZGC 只是听说过名字所以如实说“了解不深”面试官也没继续为难。3. 项目深挖中隐藏的“出题逻辑”3.1 前后端分离项目是怎么被问出“系统设计感”的我的项目是一个前后端分离的管理后台技术栈是 Vue Spring Boot MySQL Redis。这种项目在简历上非常常见面试官不会因为项目简单就跳过反而会用“如果……”的方式层层加码把一个小项目问到系统设计的高度。比如他问“你的登录功能是怎么实现的”我答前端登录后后端校验用户名密码生成一个 Token 返回给前端前端存储后每次请求都带上这个 Token后端用拦截器校验。“那 Token 存在哪里你是用 JWT 还是普通随机串”我答用的 JWTRedis 里也存了一份做服务端主动失效控制。“如果用户注销登录这个 Token 在到期之前还能用吗”这个问题很关键因为 JWT 本身是无状态的签发后只要没过期服务端无法主动作废。所以我说我额外引入了 Redis 黑名单机制注销时把 Token 的 jti 写进 Redis 并设置剩余过期时间拦截器里先查黑名单。“那如果多个服务实例部署每个实例的拦截器如何共享黑名单”到这一步问题已经从“登录功能的实现细节”上升到了“分布式会话一致性”。我顺着回答把黑名单和 Session 状态全部放在 Redis 里所有实例共享同一个 Redis如果需要更严格的长效会话管理可以引入 Spring Session。这个方案面试官认可了。这段经验给我的启发简历里的任何一个小模块背后都可能是一个系统设计题的种子。准备项目时不能只记录“实现了什么功能”还要主动多问自己几步——“如果我来设计一个生产可用的版本该怎么考虑高可用、分布式、一致性”。这份思考量在面试时是能被感知到的。3.2 Spring、SpringBoot、RuoYi 框架相关问题的真实出题套路由于项目是基于 RuoYi 开发的我预判到面试官会问这个框架的权限设计。果然一面和二面都提到了。关于 RuoYi考察点通常集中在RBAC 权限模型的实现逻辑用户、角色、菜单三张核心表及关联表。动态菜单的实现根据用户角色的权限标识过滤菜单树。Spring Security 过滤器链的执行过程认证过滤器、授权过滤器各自的职责。数据权限如何通过注解和 AOP 做到部门级的数据隔离。我记得被问到“Spring Security 的过滤器链大概是怎么执行的”时我先说了请求会经过 FilterChainProxy然后由 SecurityFilterChain 里的各个过滤器依次处理包括 UsernamePasswordAuthenticationFilter、ExceptionTranslationFilter、FilterSecurityInterceptor 等。面试官接着问“如果我自己想实现一套简单的 Token 鉴权拦截器你会怎么设计”这算是把框架底层简化成了一个场景设计题。回答这个问题的关键是展示“过滤器 / 拦截器 上下文持有”的思想定义一个 OncePerRequestFilter从 Header 里取 Token调用用户服务解析出用户信息放到 ThreadLocal 或继承 SecurityContextHolder 的机制中后续 Controller 直接取用。如果 Token 无效直接返回 401。我的一个实用建议是不要只抱着 Spring 的用法去面要理解 Spring 的自动配置机制、条件装配原理、Bean 生命周期、AOP 原理。因为面试官一问到“为什么引入一个 starter 就能自动装配”就会牵扯到 EnableAutoConfiguration、spring.factories 和后面的 ConditionalOnClass 这些内容这些是 Spring Boot 能“开箱即用”的底层支撑。3.3 场景设计题的回答框架那次“秒杀系统”是怎么硬着头皮答完的三面被问“设计一个秒杀系统”时我其实有点慌。但我知道这类题有套路可循不需要真的做过但思路必须层层递进。我的回答逻辑大致如下前端层通过验证码、按钮置灰、答题等方式人工限流降低瞬时流量。网关 / 接入层使用 Nginx 做负载均衡和简单的 IP 限流比如漏桶或令牌桶算法。Web 应用层本地限流 分布式限流比如 Redis Lua 脚本实现令牌桶将多余请求快速返回“已抢完”。MQ 层拦截到真正有效请求后把“下单请求”令牌丢进 MQ由订单消费者异步处理。库存扣减在 Redis 中使用 Lua 脚本原子扣减库存成功后再发送 MQ 消息落库。最终一致性Redis 库存与 DB 库存之间通过异步对账或者定时任务兜底。面试官追问了一个常见问题“如果用户抢到了但一直不支付怎么办”我答订单表里设置支付超时时间使用延迟队列做未支付订单的自动取消并回补库存。说到这他追问“你了解延迟队列的实现吗” 我答了 RabbitMQ 的 TTL 死信队列方案也提了 Redis 的过期键通知和时间轮方案。这类题答得好不好关键不在方案本身多华丽而在你能不能在每个节点说出“为什么要这样”以及如何权衡可用性和一致性。我最后的回答不一定能让面试官完全满意但至少展现了从用户端到库存端的一条完整链路思考这就够把档次拉开一截了。4. 手撕代码环节这一次是真的紧张但也是进步最快的环节4.1 一面那道“中序遍历的非递归实现”让我明白手写代码要分阶段推进一面手撕代码的题目是二叉树的中序遍历要求非递归。这本是一道很基础的题但有个细节让我印象深刻——面试官在我写完栈解法后继续追问“能不能使用 Morris 遍历实现空间复杂度降到 O(1)”。我当时对 Morris 遍历不熟悉只大概知道思路是用前驱节点临时改树的结构但真正实现起来最容易出错的部分是“找当前节点左子树的最右节点把当前节点挂到它右孩子上然后清空指针恢复树结构”。我现场没有完整调通但我尽量把思路说给了面试官如果当前节点有左孩子就找到左子树中最右的节点让它指向当前节点然后移动到左孩子如果当前节点没有左孩子就输出并移动到右孩子。面试官听完说“你思路是对的回头可以仔细写一下”。我的建议是如果面试时遇到不会精确实现的题不要直接沉默先把思路分点讲清楚。面试官更看重你在新增约束条件后能不能快速调整方案。如果一句话不说埋头写反而会失去沟通分。4.2 二面“最长递增子序列”从 O(n²) 到 O(n log n) 的现场推进二面的算法题给了比较大的 N我在写完 O(n²) 的 DP 后主动说了“这个解法在数据量大时不够好”。面试官顺势让我继续优化。因为日常刷题时练过 patience sorting 的思路我知道可以用tails数组保存“当前长度递增子序列的最小末尾值”不断二分查找替换。但在现场写二分时我第一版 while 循环条件写错了导致 index 定位偏差。面试官很耐心地给了一个提示“检查一下当 target 大于所有元素时index 应该在哪个位置。” 我马上意识到应该用左闭右开的二分或者直接用Arrays.binarySearch的返回规则求插入点。改完测试用例通过后面试官点了点头。这里有一个很重要的实战建议写二分搜索时先用左闭右开区间写边界更不容易错。比如int left 0, right tails.size(); // 左闭右开 while (left right) { int mid (left right) 1; if (tails.get(mid) key) { left mid 1; } else { right mid; } } // left 即为第一个 key 的位置这种写法在“找第一个大于等于目标值的位置”时非常稳定也方便记忆。4.3 三面算法题二叉树的层序遍历 “Z 字形遍历”三面的算法题不算难考察的是层序遍历的变体。常规做法用队列每一层按顺序取出并记录数量然后按层分隔。Z 字形的要求无非就是偶数层反转一下结果列表。我顺利写完后面试官追加了一个问题“如果不用额外数组记录层内元素能否通过双向队列优化” 我当时很快想到了用Deque奇数层从尾部入、偶数层从头部入这样遍历时正好满足锯齿顺序也能避免拷贝翻转的开销。我的核心感触是字节的算法面更看重代码风格和优化意识很多时候做出来不是终点面试官会继续压时间复杂度和空间复杂度。如果你能在 baseline 解出来后主动说出“还有更优的解法吗”反而会加分。4.4 手撕代码环节的通用备战策略总结下来字节后端实习手撕代码题的备考重点大概是二叉树的遍历及变体非递归、Morris、层序/Z 字形。动态规划的高频模型最长递增子序列、背包、编辑距离、子数组/子序列问题。双指针与滑动窗口在数组和字符串题里出现概率很高。LRU 缓存这类“数据结构设计题”三面可能直接让你手写。链表题反转、合并、找环属于秒杀题绝不能失分。练习时一定注意在纯文本编辑器中手写代码不依赖 IDE 的提示。写完后手动跑一两组边界用例比如空集合、单元素、全相同元素、目标值不存在。用“先说思路 → 写代码 → 自己走查一遍 → 说复杂度”的节奏让面试官有参与感。5. 二面中最值得回看的三段细节项目描述、业务抽象、复盘心态5.1 怎么描述一个“普通”的后台项目才不显得普通我的项目不是一个造火箭项目但它能让我在面试里不断聊下去核心原因是我在描述时把“功能点”翻译成了“技术挑战”。举个例子我的项目里有一个“用户导入导出 Excel”的功能。如果只描述成“支持用户信息导入导出”面试官大概率不会感兴趣。但如果换个角度描述成“这个功能需要处理大文件内存溢出问题所以我采用了分批读取 异步任务 前端轮询获取导出状态的方案”面试官就会顺藤摸瓜问异步任务是怎么实现的、为什么不用同步导出、轮询和 WebSocket 在这个场景下怎么取舍——每一个问题都能展开聊。所以准备项目时最有效的做法是把项目里的每个功能拆出来主动加一层“当时我遇到了什么问题、为什么这么解决、有没有替代方案”的叙述。项目是否高大上不是重点重点是让面试官觉得你是真的在思考工程问题。5.2 一面二面中“回答不上来”时的真实处理方式面试中我确实有几次卡壳包括上面提到的 Morris 遍历、Redis 删除缓存失败后的解决方案。回顾一下我每次卡壳后的处理路径都有了改进这也是值得分享的地方。第一次卡壳在三面我硬着头皮猜结果越说越乱。当时我试图在 Morris 遍历上“编”代码面试官一眼看穿。后来我调整了策略遇到不确定的问题我会直接说“这块我了解不深但我理解它的核心思路大概是……”然后把知道的关键词亮出来表明有知识框架只是细节没夯实。面试官在这种时候往往更愿意给提示因为至少沟通是顺畅的。说到底面试是一场“极限压力下的知识检索测试”。你不可能每个点都覆盖到但如果你表现出“知道边界在哪 即使不知道也能基于已有知识推演”的能力面试官对综合评价反而会更高。5.3 面试中如何做知识“降维”把陌生问题拆成熟悉模型字节的面试官很爱出一个“耳目一新”的系统设计题。这时候最忌讳的是直接说“我没做过”。更合理的策略是把陌生问题拆解成几个熟悉的子问题。举一个例子如果被问到“设计一个短链接系统”你可能没有实际经验但可以这样拆发号器用分布式 ID 生成器比如雪花算法生成唯一 ID再转换为 62 进制字符串。存储短链接 key 与原始 URL 映射用 KV 存储Redis做热点缓存底层持久化到 MySQL。重定向访问时直接 302 跳转。统计埋点记录访问量。一旦拆解完你会发现每个子模块的知识点都可以从项目或八股里找对应。这套“先拆解再映射”的思路在系统设计面和二面场景题里非常关键。6. 面完之后的冷静复盘如果再来一次我会怎么准备6.1 一份“后端实习”备战清单按优先级排好了把这次面试的所见所闻梳理之后我给自己的下一次面试定了这样一份优先级清单也分享给你参考优先级模块具体内容P0算法题LeetCode 热题 100、二叉树、动态规划、滑动窗口、链表P0Java 基础集合源码、并发synchronized/volatile/线程池、JVM 内存与 GCP0MySQL索引数据结构、MVCC、隔离级别、Explain 执行计划、慢查询优化P0Redis数据结构、过期策略、持久化、缓存穿透/击穿/雪崩、分布式锁P1Spring 原理Bean 生命周期、自动配置、AOP 原理、Spring Security 过滤器链P1项目深挖每个功能模块的“为什么这么做” “如果放大十倍怎么优化”P2网络与操作系统TCP 三次握手/四次挥手、HTTP/HTTPS、进程线程协程、虚拟内存P2MQ / 分布式Kafka/RabbitMQ 的基础模型、消息可靠性、幂等消费字节的面试轮次多每一轮的侧重稍有不同但整体来看 P0 级别的知识点几乎每轮都会出现不能有任何侥幸心理。6.2 “八股文”背到什么程度才算合格很多同学会问面经里这些问题哪里可以找到标准答案我的体会是先把概念背下来再用自己的话讲一遍最后找一个不懂的人解释给他听。如果你能让他听懂说明你真的理解了。比如“什么是事务的隔离级别”这个问题如果只回答“读未提交、读已提交、可重复读、串行化”是远远不够的。至少要知道每种隔离级别解决什么问题、带来什么问题、InnoDB 默认用哪个、底层靠什么实现锁 vs MVCC。如果面试中能主动说出“可重复读在 MySQL 中通过间隙锁解决了一部分幻读问题”那这个回答就立体了。我建议准备一个简化版的“八股提词器”每个知识点只写关键词自测时只看关键词是否能展开讲 3 分钟。如果展开不了说明这块理解还不到位回到资料里再补。6.3 那些“如果再面一次我一定提前做的事”如果时间能倒流在我再次面试之前我一定会提前做三件事把 Redis 缓存一致性场景完整梳理清楚。这类题高频到可怕而我在面试中恰恰答得最差。我会把“先删缓存再更新 DB”“先更新 DB 再删缓存”“删除失败如何重试”“binlog 订阅方案怎么做”全部写成结构化的笔记并配合代码示例。把 Morris 遍历、线段树、树状数组这类“进阶但不算冷门”的算法完整实现几遍。一面二面都可能在基础题解完后被追问优化而这些优化往往来自这些进阶数据结构。把项目的所有“技术亮点”从功能描述改写为“问题 方案 权衡”的三元组并为每个三元组预先准备两道追问。这是临时抱佛脚最有效的办法。写在最后面完字节之后我明白了什么这次面试从笔试到 HR 面全程走下来我最大的感受是后端实习考察的不只是你会不会写 CRUD而是你对每个用过的组件到底理解到什么深度。RuoYi 项目的权限模块、Spring Boot 的自动配置、Redis 的缓存流程每个你“用过”的功能都有可能成为面试官挖掘你知识深度的入口。如果只说一条最想分享的经验我会说面试前一天不要试图“看完所有面经”而是挑两个你最熟悉的知识点往死里深挖。因为面试官一旦从某个点开始追问就不会轻易停下来。你熟悉的点如果挖到底会被视为“有深度”这时候哪怕你其他领域稍弱面试官也会认为你是可培养的人。而如果你正在准备下一场面试我的建议也很简单从一个“你觉得已经会了”的知识点开始写一篇能讲给别人听的技术笔记。然后带着它去面对面试官。你会发现真正讲得清楚的那一刻才算真的懂了。希望这篇面经能给你一些参考。如果我被追问的那些问题你也能一条条回答上来那你的面试大概率会比我更顺利。
返回列表