成都小厂java面经:慢SQL、JVM与面向对象
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 自我介绍。
- 怎么优化慢 SQL?
- 介绍一下你的项目(面试官围绕项目做追问)。
- RBAC 权限模型讲一下。
- JVM 的结构是什么?
- JVM 调优怎么做?
- HashMap 和 Hashtable 有什么区别?
- Spring Boot 的部署特性有哪些?
- MyBatis 的传参方式有哪些?
- AI 编程你了解多少、用过哪些?
- 面向对象的特征是什么?
- 多态的实现方法有哪些?
- 面向对象的核心设计原则是什么?
- 了解数据标注和数据训练吗?
- 了解数字资产吗?
《参考解析》
慢 SQL 优化:先定位再动手:第一步永远是拿到真实 SQL 和执行计划,EXPLAIN 看 type(出现 ALL 就是全表扫)、key(实际用了哪个索引)、rows(预估扫描行数)、Extra(Using filesort、Using temporary 都是危险信号),必要时用慢查询日志或 performance_schema 找到 TOP 消耗的语句。常见手段按性价比排序:加合适的联合索引并遵守最左前缀,注意区分度高的列放前面、避免在索引列上做函数或隐式类型转换(会让索引失效);把 select * 收敛到需要的列以支持覆盖索引;用 limit 与游标分页替代大 offset;把 or、in 子查询改写成 union all 或 join;拆解大事务与批量写(分批提交);数据量到亿级才谈分区、归档或引入缓存与搜索引擎。最后一定要用真实数据量验证,别拿几万行的测试库下结论。
RBAC 权限模型:核心是「用户—角色—权限」的间接映射,好处是权限变更只改角色、不动用户。落地时通常会扩展成 RBAC1(角色继承,比如部门管理员继承普通用户)和 RBAC2(角色约束,如职责分离,同一个人不能同时持有申请与审批角色)。工程上的四个要点:一是权限校验入口收敛到一个统一的注解或拦截器,别散落在各处;二是权限要分层,功能权限(能不能进这个页面、调这个接口)与数据权限(能看到哪些行、哪些字段)分开管,数据权限常用「角色挂数据范围」的方式在查询条件里注入;三是缓存鉴权结果并在角色变更时立即失效;四是所有敏感操作留审计日志。多租户场景下每张表都要带租户维度,唯一约束和查询条件都不能漏。
JVM 结构与调优:结构按内存区域答——线程私有的程序计数器、虚拟机栈、本地方法栈,线程共享的堆、方法区(JDK 8 后是元空间,用本地内存),再加上直接内存。堆再分新生代(Eden 加两个 Survivor)与老年代,默认比例 1:2、Survivor 之间 8:1:1。调优的顺序是「先定目标再调参数」:目标通常是降低 Full GC 频率与停顿、避免 OOM。手段包括设合理的 -Xmx 与 -Xms(相等可避免动态扩容抖动)、按对象存活特性选收集器(低延迟走 G1 或 ZGC,高吞吐走 Parallel)、用 -XX:MaxMetaspaceSize 兜住元空间、用 jstat、jmap、jstack 或 arthas 定位大对象与内存泄漏。调优的依据必须是 GC 日志和堆快照,而不是凭感觉加参数;多数「JVM 调优」问题最后其实是代码问题(大对象、缓存无上限、连接未释放)。
HashMap 与 Hashtable:最核心的区别是线程安全性——HashMap 非线程安全但性能好,Hashtable 每个方法加 synchronized,全表一把锁、并发性能差,已经基本被淘汰,需要线程安全时用 ConcurrentHashMap。其他差异:Hashtable 不允许 null 键和 null 值,HashMap 允许一个 null 键与多个 null 值;初始容量与扩容策略不同(Hashtable 默认 11、扩容为 2n+1,HashMap 默认 16、扩容翻倍且容量保持 2 的幂以便用位运算取模);迭代器行为不同(HashMap 是 fail-fast,Hashtable 的 Enumerator 不是)。HashMap 本身要能讲底层:数组加链表加红黑树(链表长度到 8 且容量到 64 才树化)、扩容时的高低位拆分、以及为什么 1.8 之后不再有死循环问题(头插改尾插)。面试官常顺势问 ConcurrentHashMap,记得讲 1.8 的 CAS 加桶级 synchronized。
Spring Boot 部署特性与 MyBatis 传参:Spring Boot 的部署优势在于内嵌容器(Tomcat、Jetty、Undertow 打成可执行 jar,java -jar 即可运行)、自动配置与 starter 依赖管理、以及 profile 驱动的多环境配置(配置文件或环境变量覆盖)。生产实践要提:spring-boot-maven-plugin 打 fat jar 与分层 jar(便于镜像分层缓存)、优雅停机(server.shutdown=graceful)、健康检查与外部化配置(别把密钥打进包里),以及 war 部署到外部容器的兼容做法。MyBatis 传参主要四种:单参数直接引用、多参数用 @Param 命名或 arg0/param1 的位置引用、JavaBean 按属性名引用、Map 按 key 引用;集合与数组要包在 @Param 的名字里用 foreach 遍历。常见坑一个是 ${} 拼接导致 SQL 注入(排序字段这类必须走白名单),一个是 #{} 与 ${} 在 like 场景下的差异,还有一个是动态 SQL(if、choose、where、trim)里多余的 and/or 处理。
面向对象与这场里的行业问题:三大特征(封装、继承、多态)要能配例子讲,多态的实现方式分编译期的重载(方法签名不同)和运行期的重写(父类引用指向子类对象、走虚方法表动态分派),再补一句「多态的前提是继承与重写」。核心设计原则用 SOLID 加两个补充来说:单一职责、开闭(对扩展开放对修改关闭)、里氏替换、接口隔离、依赖倒置,再加上迪米特法则与合成复用优先。被问到数据标注、数据训练、数字资产这类业务概念时,按「我了解到的是什么 + 与我岗位的关系 + 我需要补什么」回答即可——不了解就直说不了解,同时给出你理解的边界(比如数据标注是训练数据的生产环节,涉及标注规范、质检与一致性评估),比硬编一个答案安全。二面被提到是领导面时,一般会问项目深度与稳定性意向,提前把项目的难点与个人贡献准备成两个具体故事。