万丈金数服务端开发二面面经(已OC)

万丈金数 · 服务端开发工程师 · 二面 · 2026-06

《面试题目》

  1. 聊简历上的项目,梳理核心业务的调用链路
  2. Git 是怎么做版本管理、记录所有版本变更的?如果让你来实现,你会怎么设计?
  3. .git 文件夹里面有什么内容,有没有看过?
  4. MySQL 的事务隔离级别有哪些?
  5. MySQL 默认的可重复读隔离级别,模拟一下读的整个过程
  6. 如果要开启一个新事务怎么办?如果自己写一套事务框架会怎么实现?
  7. 如果发生嵌套事务,要求事务隔离,怎么保证事务之间不会互相影响?
  8. 子事务如果抛异常回滚,会不会影响父事务?
  9. Java 异常的两大分类是什么?为什么要区分这两种异常?
  10. MySQL 的字符串类型有哪些?char 和 varchar 怎么选择?varchar 和 text 怎么取舍?
  11. 项目的数据库中有用过 JSON 类型的字段吗?
  12. 二分查找在实际项目中的什么场景会用到?
  13. 数据库索引的机制是什么,B+树的结构是怎样的?
  14. varchar 这类变长类型,数据库是怎么管理它们的存储结构的?
  15. AI 工具用得多吗?聊聊 AI 使用情况和项目中 AI 生成代码的比例

《参考解析》

  1. MySQL 事务隔离级别:从低到高依次是读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read,InnoDB 默认级别)、串行化(Serializable)。可重复读级别下,同一事务内多次读取同一份数据结果保持一致,这是通过 MVCC(多版本并发控制)在事务开始时生成一份 ReadView 实现的;同时 InnoDB 还通过间隙锁(Gap Lock)弥补了标准可重复读下可能出现的幻读问题。
  2. 嵌套事务/子事务回滚:MySQL 原生不支持真正的嵌套事务,通常借助 Savepoint 模拟——子事务对应一个保存点,子事务异常时只回滚到该保存点,不影响父事务已提交的其他操作;如果不使用 Savepoint,子事务的回滚可能会连带影响整个外层事务,因此在设计上需要显式声明事务传播行为(类似 Spring 的 REQUIRES_NEWNESTED)来控制隔离范围。
  3. Java 异常两大分类:受检异常(Checked Exception,编译期强制要求处理或声明抛出,如 IOException)和非受检异常(Unchecked Exception,即 RuntimeException 及其子类,运行时才会暴露)。这样区分的目的是把”可预见、调用方应该主动处理的外部异常”和”编程错误导致的异常”分开:前者强制处理保证程序健壮性,后者不强制捕获,避免过度的 try-catch 掩盖真正的 bug。
  4. char / varchar / text 选型:char 是定长类型,存储时会用空格补齐到指定长度,适合长度固定的短字段(如状态码、md5 值),读写性能更好;varchar 是变长类型,按实际内容长度存储(加长度前缀),适合长度不固定的字段,但有长度上限(受行大小限制,最大 65535 字节,且要和其他字段共享该上限);text 用于存储更大的文本内容,不能设置默认值,通常只能建前缀索引,字段本身也不会存储在行内(可能存到溢出页)。
  5. B+树索引结构:B+树的所有数据都存储在叶子节点(聚簇索引的叶子节点存整行数据,二级索引的叶子节点存主键值),非叶子节点只存索引键作为导航,不存数据,因此非叶子节点可以容纳更多索引项、树的层高更低,磁盘 IO 次数更少;同时叶子节点之间通过双向链表相连,天然适合范围查询和排序查询。这也是 MySQL 选择 B+树而不是普通 B树或哈希索引的核心原因。