天翼视联 Java研发工程师 一面
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 自我介绍
- HashMap 原理,随 JDK 版本的变化?
- 垃圾回收器 G1 和 CMS 的区别?各自优缺点?
- Spring AOP 原理?
- 数据库慢查询的优化思路?
- HTTPS 的原理和流程?
- Redis 的 RDB 和 AOF 是什么?区别?
- Kafka 分区的概念?
- 实习期间遇到最大的困难?如何解决的?
- 反问环节
《参考解析》
HashMap 的版本演进:JDK 7 是数组 + 链表,插入用头插法,扩容时链表可能被反转,并发扩容会成环;JDK 8 改成数组 + 链表 + 红黑树,链表长度到 8 且数组容量到 64 时转红黑树,退化阈值是 6,插入改成尾插,扩容时用高低位链表拆分、不用重新计算 hash。改动解决的是查询从 O(n) 退化成 O(log n) 的问题,也顺手修掉了并发成环。容量永远是 2 的幂,这样 (n-1) & hash 才能等价取模;默认负载因子 0.75 是空间和冲突率的折中。
G1 与 CMS:CMS 的目标是最短停顿,用标记清除,分初始标记、并发标记、重新标记、并发清除四步,问题是会产生内存碎片、并发失败时会退化成单线程 Full GC,且浮动垃圾只能等下次。G1 把堆切成大小相等的 Region,按「回收收益」优先回收(Garbage First),整体是标记整理、局部是复制,可以预测停顿时间(-XX:MaxGCPauseMillis),堆大时比 CMS 稳。JDK 9 起 G1 成为默认,CMS 在 JDK 14 被移除。选型上:堆 4G 以内、停顿敏感选 CMS 的时代已经过去,现在默认用 G1,超大堆再考虑 ZGC / Shenandoah。
Spring AOP:核心是动态代理,运行时为目标对象生成代理对象,把切面逻辑(通知)织入方法调用。接口用 JDK 动态代理,没有接口用 CGLIB 生成子类(Spring Boot 2.x 起默认强制 CGLIB)。切点表达式匹配到方法后,调用链是「代理 → 通知链 → 目标方法」。面试追问常落在自调用失效(同一个类里 this.method() 不走代理)、final 方法不能被 CGLIB 代理、以及循环依赖靠三级缓存解决这几处。
慢查询优化与 HTTPS:慢查询先定位再优化——开慢查询日志或用 explain 看 type、key、rows、Extra,重点确认有没有走索引、有没有回表、有没有 filesort。常见手段:给 where / order by / group by 建联合索引并遵守最左前缀、覆盖索引免回表、避免在索引列上做函数或隐式类型转换、深分页改成游标(where id > ?)或延迟关联、大事务拆小、读写分离和加缓存。HTTPS 是 HTTP 跑在 TLS 之上:TCP 握手后做 TLS 握手,客户端发 ClientHello(支持的版本、套件、随机数),服务端回 ServerHello + 证书,客户端校验证书链、用非对称加密协商出会话密钥,之后用对称加密传数据,证书里公钥用来验证身份和做密钥交换,对称加密才是性能关键。
Redis 持久化与 Kafka 分区:RDB 是某一时刻的全量快照,二进制小、恢复快,但会丢两次快照之间的数据且 fork 时可能抖动;AOF 追加写命令,always / everysec / no 三档刷盘,实时性好但文件大、恢复慢。生产上通常两者都开,用 RDB 做冷备、AOF 保数据,AOF 重写压体积,Redis 4.0 之后还有 RDB + AOF 混合格式。Kafka 的分区是并行度的单位:一个分区同一时刻只被组内一个消费者消费,所以分区数决定消费并发上限;分区内消息有序,跨分区不保证顺序,需要全局有序就指定同一个 key(相同 key 落到同一分区)。分区数还影响吞吐和 rebalance 成本,不是越大越好。
这一轮的整体判断:八股覆盖的是后端最基础的一层,题目之间没有雕花追问,难度偏低,属于典型的「筛基础」面试。真正拉开差距的是第 9 题,因为它是唯一一道必须用自己的项目作答的题。回答这类题要挑一个具体场景讲透:现象是什么、定位过程用了哪些工具和指标、几个候选原因怎么逐个排除、最后怎么验证修好了,而不是笼统说「加班查了两天」。作者末尾提到「不知道是不是 KPI 面」,其实从题目分布看确实偏流程化面试,准备时把基础八股过熟就够了。