校招 未知部门 / 后端-Java / 多轮

[面试日期] 2026-09-10 [面试时长] 50min
[学校背景] 北京理工大学 | 985 [学历背景] 本科
[发布人] 面试之星官方收录
<h2>分享|5年Java面得物,Java岗一个字没问Agent,我还是挂了</h2> <p>先交代背景:普通本科,Java后端,5年经验,上一家是某电商平台,负责过数据权限系统和订单系统的架构优化。</p><p>牛客9月热榜上,得物Java开发一面排在第4位,Agent开发岗面经占了第3、第6、第9。我面的得物Java岗,一面挂了。有意思的是——这场Java岗面试<strong>一个字没问Agent</strong>,但我还是挂了。</p><p><strong>📌 第一阶段:一面挂了(9月初)</strong></p><p>面试时长50分钟,项目深挖 + MySQL + Redis + 线程池 + MQ场景题,没有手撕。</p><p><strong>1️⃣ 项目深挖:数据权限的动态SQL是怎么实现的?</strong></p><p>💡 <strong>思路参考</strong>:得物面试官开场就问项目里最复杂的模块。数据权限用AOP + 动态SQL实现——在Mapper方法执行前,通过拦截器解析当前用户的权限范围(部门、角色、数据等级),动态拼接WHERE条件。核心难点:<strong>权限规则的缓存</strong>(权限规则变更不频繁,用本地缓存+Redis缓存,避免每次请求都查权限表)、<strong>SQL注入防护</strong>(动态拼接WHERE条件时用参数化查询,不能直接字符串拼接)。</p><p><strong>2️⃣ MySQL:隔离级别、幻读、间隙锁</strong></p><p>💡 <strong>思路参考</strong>:MySQL默认隔离级别是可重复读(RR)。幻读是指同一事务内两次查询返回不同的行数。InnoDB在RR级别下通过<strong>MVCC + 间隙锁</strong>防止幻读——快照读(普通SELECT)用MVCC保证可重复读,当前读(SELECT FOR UPDATE / UPDATE / DELETE)用间隙锁防止其他事务插入新行。5年经验要能说出<strong>间隙锁的加锁规则</strong>:只有可重复读隔离级别下才有间隙锁,读已提交没有。</p><p><strong>3️⃣ 索引失效场景 + EXPLAIN + 慢SQL</strong></p><p>💡 <strong>思路参考</strong>:索引失效的常见场景——函数包裹索引列(<code>WHERE DATE(create_time) = &#x27;2026-09-01&#x27;</code>)、隐式类型转换(字符串列传数字)、LIKE以%开头、OR条件中部分字段无索引、不等于操作。EXPLAIN关注type(ALL全表扫描是问题)、rows扫描行数、Extra(Using filesort / Using temporary)。5年经验要能说出<strong>一个真实的慢SQL优化案例</strong>——优化前耗时多少、优化后多少、怎么优化的。</p><p><strong>4️⃣ Redis:穿透、击穿、雪崩</strong></p><p>💡 <strong>思路参考</strong>:<strong>穿透</strong>——查询不存在的数据,缓存和DB都没有,请求全部打到DB。解决方案:布隆过滤器 + 缓存空值。<strong>击穿</strong>——热点Key过期瞬间,大量请求打到DB。解决方案:互斥锁(只让一个线程去加载)。<strong>雪崩</strong>——大量Key同时过期。解决方案:过期时间加随机值。</p><p><strong>5️⃣ 线程池七参数 + Redisson WatchDog</strong></p><p>💡 <strong>思路参考</strong>:七参数——corePoolSize、maximumPoolSize、keepAliveTime、TimeUnit、workQueue、threadFactory、handler。WatchDog是Redisson的锁续期机制——加锁成功后起守护线程,每隔锁过期时间的三分之一(默认10秒)自动续期,业务执行完手动释放锁时守护线程自动停止。</p><p><strong>复盘</strong>:得物Java岗<strong>一个字没问Agent、RAG、Harness</strong>。我准备了很多Agent相关的东西,结果全没用上。但传统后端题我也没答好——MySQL间隙锁的加锁规则说不清楚、Redis大Key的危害只答了一半、线程池参数配置没有结合实际业务场景。</p><p><strong>📌 第二阶段:二刷得物,四面终于OC(9月中)</strong></p><p>重新投递后,这次准备更充分,把MySQL和Redis的底层原理彻底梳理了一遍。</p><p><strong>一面(二刷,50分钟)——过了</strong></p><p><strong>1️⃣ 项目深挖:订单系统的QPS架构分析</strong></p><p>💡 <strong>思路参考</strong>:日均订单300万,峰值QPS约600。订单系统涉及订单创建、支付回调、状态同步、物流对接四个核心链路。5年经验要能说出<strong>接口时延的分布</strong>——哪个方法耗时最多、为什么、怎么优化的。</p><p><strong>2️⃣ Redis大Key的问题和解决</strong></p><p>💡 <strong>思路参考</strong>:大Key(超大Hash、超大List、单个Value过大的String)会导致单次操作耗时长、阻塞主线程(Redis单线程模型下影响尤其明显)、内存分布不均引发数据倾斜、主从同步时网络阻塞。解决方案:拆分大Key(按业务维度拆成多个小Key)、用SCAN替代KEYS做批量处理、对已存在的大Key定期做异步拆分迁移。</p><p><strong>3️⃣ 线程池参数设计 + 线程阻塞排查</strong></p><p>💡 <strong>思路参考</strong>:支付系统的线程池配置——核心线程数10(根据压测:每秒100笔,每笔100ms,10个线程刚好扛住),最大线程数20,队列用ArrayBlockingQueue(1000),拒绝策略CallerRunsPolicy。线程阻塞排查用jstack导出线程栈,查找BLOCKED或长时间WAITING状态的线程,结合线程名和堆栈定位具体阻塞点。</p><p><strong>二面(50分钟)——过了</strong></p><p><strong>1️⃣ 系统设计:设计一个高可用数据权限系统</strong></p><p>💡 <strong>思路参考</strong>:分层架构——接入层(网关+鉴权)、业务层(权限解析+动态SQL)、数据层(Redis缓存权限规则+MySQL持久化)。核心难点:<strong>权限规则的实时性</strong>(规则变更后多长时间生效)、<strong>多租户隔离</strong>(不同租户的权限规则完全隔离)。</p><p><strong>2️⃣ 分布式事务选型</strong></p><p>💡 <strong>思路参考</strong>:TCC适合核心资金链路(支付、转账),SAGA适合长事务(跨多个服务的业务流程),消息最终一致性适合非核心异步场景。5年经验要能说出<strong>每种方案的适用场景和性能数据</strong>。</p><p><strong>HR面——OC</strong></p><p><strong>📌 声明</strong></p><blockquote><p><em>以上思路参考来自 </em><strong><code><em>&quot;面题鸭🦆&quot;</em></code></strong><em> 各岗位专属考题的考点方向</em></p></blockquote><p><strong>📝 复盘</strong></p><p>得物这场面试让我明白:<strong>5年经验的Java岗,传统后端依然是主战场</strong>。9月同一周,得物Java一面问的是隔离级别、间隙锁、缓存三大问题、线程池七参数、Redisson WatchDog;而Agent岗问的是图谱抽取、MCP、Harness、记忆压缩。方向不同,准备的侧重点完全不同。</p><p><strong>🎯 后来怎么调整的?</strong></p><p>一面挂的原因让我意识到:5年经验不能只追逐热点(Agent),<strong>传统后端的深度才是Java岗的根基</strong>。MySQL间隙锁的加锁规则、Redis大Key的底层原因、线程池参数的配置逻辑,这些才是Java岗真正在考的。</p><p>后来在 <strong><code>&quot;面题鸭🦆&quot;</code></strong> 上刷了一遍得物Java方向的JD专属出题,MySQL底层、Redis深度、线程池实战这些方向覆盖得很全。二刷时心里有底很多。</p><a>#发面经攒人品#</a><a>#你在职场上见过哪些“水货”同事#</a><a>#聊一聊AI面试#</a><a>#双非本科求职如何逆袭#</a><a>#有哪些公司在面试时考察AICoding?#</a>
AI 推荐面试题