25年11月星云联动 Java开发 一面

#JAVA##JAVA面经##JAVA内推#

1. 详细说说MySQL的事务机制

思路

  • 核心:先讲事务的ACID特性,再讲实现原理(redo/undo日志、锁、MVCC),最后补充隔离级别及解决的问题。
  • 重点:原子性/持久性靠redo/undo日志,隔离性靠锁+MVCC,一致性是最终目标。

回答示例

MySQL事务的核心是保证一组操作的原子性和数据一致性,核心围绕ACID特性实现:

  1. 原子性:通过undo日志实现,事务执行时记录反向操作(如插入→删除、更新→还原),回滚时执行undo日志恢复数据;
  2. 一致性:事务执行前后数据符合业务规则(如转账总金额不变),由原子性、隔离性、持久性共同保证;
  3. 隔离性:通过锁(行锁/表锁/间隙锁)和MVCC(多版本并发控制)实现,避免多事务并发干扰,MySQL默认可重复读隔离级别;
  4. 持久性:通过redo日志实现,事务提交时先写redo日志(落盘),再刷数据到磁盘,即使宕机也能通过redo日志恢复已提交数据。 此外,InnoDB通过两阶段提交(prepare→commit)保证事务与日志的一致性,避免数据丢失。

2. 你实际做过SQL优化的落地实现吗?具体怎么做的?

思路

  • 步骤:定位慢SQL(慢查询日志/explain)→ 分析问题(无索引/全表扫描/关联不当)→ 优化手段(加索引/改写SQL/分库分表)→ 验证效果(执行时间/扫描行数)。
  • 举例:结合具体场景(如订单查询),体现实操性。

回答示例

做过,核心是“定位-分析-优化-验证”的闭环:

  1. 定位问题:开启MySQL慢查询日志,筛选出执行时间>1s的订单列表查询SQL,用explain分析发现type=ALL(全表扫描),rows=10万+;
  2. 分析根因:查询条件包含user_idcreate_time,但未建联合索引,导致全表扫描;
  3. 优化手段
    • order表建user_id + create_time联合索引,遵循最左前缀原则;
    • 改写SQL,避免select *,只查询需要的字段(减少回表);
    • 分页查询时限制limit行数,避免一次性加载大量数据;
  4. 验证效果:优化后SQL执行时间从1.2s降至0.05s,扫描行数从10万+降至100+,接口响应效率大幅提升。

3. 如何检查SQL是否使用了覆盖索引?

思路

  • 核心:覆盖索引=查询的所有字段都在索引中(无需回表),通过explain的Extra字段判断。
  • 步骤:执行explain + SQL,看Extra是否显示Using index(覆盖索引生效);补充判断条件(查询字段、where字段都在索引中)。

回答示例

检查SQL是否使用覆盖索引核心看explain执行计划的Extra字段:

  1. 执行命令explain SELECT name, age FROM user WHERE id = 10;
  2. 判断依据:若Extra列显示Using index,说明使用了覆盖索引(查询的name、age和where条件的id都在索引中,无需回表查聚簇索引);若显示Using where; Using index,说明where条件命中索引且查询字段覆盖索引;若显示Using filesort/Using temporary或无Using index,则未用到覆盖索引。 实操中,需保证“查询的所有字段(select)+ 筛选字段(where/join)”都包含在同一索引中,才能触发覆盖索引。

4. CMS和G1的区别

思路

  • 维度对比:回收模式(CMS标记-清除,G1标记-整理+分区)、内存布局(CMS分新生代/老年代,G1划分为Region)、停顿特性(CMS不可预测,G1可预测)、适用场景(CMS适用于低延迟,G1适用于大内存/可预测停顿)。

回答示例

CMS和G1是两款不同设计目标的GC,核心区别如下:

维度 CMS垃圾收集器 G1垃圾收集器
内存布局 分新生代(Eden/S0/S1)、老年代 将堆划分为多个大小相等的Region(新生代/老年代混合)
回收算法 标记-清除(产生内存碎片) 标记-整理+复制(无碎片)
停顿特性 并发回收,停顿时间短但不可预测 可预测停顿(通过设置MaxGCPauseMillis)
回收范围 仅回收老年代 可回收新生代+老年代
适用场景 小内存(4-8G)、低延迟要求 大内存(8G以上)、需可预测停顿
内存碎片 有(标记-清除导致) 无(标记-整理)

5. G1是如何实现可预测停顿时间的功能的?

思路

  • 核心:基于Region分区+优先级排序,通过“设置停顿目标+选择回收价值最高的Region”控制停顿时间。
  • 步骤:维护Region回收成本-收益模型→ 每次GC前计算可回收Region→ 只回收在停顿目标内的Region。

回答示例

G1实现可预测停顿的核心是“分区管理+优先级调度”:

  1. Region分区:将堆划分为多个大小相等的Region(默认1-32MB),每个Region可动态标记为新生代/老年代,回收时以Region为单位,而非整代回收;
  2. 成本-收益模型:G1会记录每个Region的回收成本(耗时)和收益(释放内存大小),维护优先级队列;
  3. 停顿预测与控制:启动时设置-XX:MaxGCPauseMillis(默认200ms),每次GC前,G1根据优先级队列选择“在停顿目标内,收益最高的Region集合”进行回收,避免整堆扫描,保证停顿时间不超过设定值;
  4. 并发标记:通过并发标记阶段提前标记存活对象,减少STW(Stop The World)时间,进一步控制停顿。

6. Redis的持久化机制有哪些?分别怎么实现?

思路

  • 核心:RDB(快照)+ AOF(日志),分别讲触发方式、实现原理、优缺点。
  • 补充:混合持久化(RDB+AOF)的实现(Redis4.0+支持)。

回答示例

Redis有两种核心持久化机制,且支持混合持久化:

1. RDB(快照持久化)

  • 实现:在指定时间间隔内,将内存中的数据快照写入二进制文件(dump.rdb);
  • 触发方式:手动(save/bgsave)、自动(配置save m n,如save 60 1000表示60秒内1000次修改触发);
  • 原理:bgsave时fork子进程,子进程写快照,父进程继续处理请求,避免阻塞;
  • 优缺点:文件小、恢复快,但可能丢失最近的数据。

2. AOF(追加日志持久化)

  • 实现:记录所有写命令(如set、hset),重启时重放命令恢复数据;
  • 触发方式:实时写(配置appendfsync:always/everysec/no);
  • 原理:命令追加到aof_buf→刷盘到appendonly.aof→定期重写(bgrewriteaof)压缩日志(合并重复命令);
  • 优缺点:数据安全性高(everysec仅丢1秒数据),但文件大、恢复慢。

3. 混合持久化

Redis4.0+支持,AOF文件前半部分是RDB快照,后半部分是增量AOF日志,兼顾RDB的恢复速度和AOF的数据安全性。

7. Redis的内存淘汰机制包含哪些策略?

思路

  • 分类:按是否过期筛选(淘汰过期键/所有键),按淘汰规则(LRU/LFU/随机/TTL)。
  • 核心策略:volatile-lru(过期键LRU)、allkeys-lru(所有键LRU)、volatile-lfu(过期键LFU)、volatile-ttl(过期键按TTL短优先)、noeviction(默认,不淘汰报错)。

回答示例

Redis内存淘汰机制是当内存达到maxmemory时,按预设策略淘汰键,核心策略分两类:

  1. 仅淘汰过期键
    • volatile-lru:从过期键中选最近最少使用(LRU)的淘汰;
    • volatile-lfu:从过期键中选最不常用(LFU)的淘汰;
    • volatile-ttl:从过期键中选TTL(剩余生存时间)最短的淘汰;
    • volatile-random:从过期键中随机淘汰。
  2. 淘汰所有键
    • allkeys-lru:

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

本专栏在精不在多,内容分为八股文、大厂真实面经,面试通过后将offer和面试题私发给我,可退还专栏的收益部分费用。欢迎大家共建专栏

全部评论

相关推荐

评论
2
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务