分类: 面试题

执行计划里 Using index condition 与 Using where 的区分场景

做 MySQL 面试复盘时,经常被候选人用一句话搪塞过去:Using index condition 就是索引下推,Using where 就是回表。这个回答在大多数场景下不算错,但只要面试官追问一句「那 Extra 里同时出现 Using index condition; Using where 该怎么解释」,八成的人就卡住了。本文从优化器实际行为出发,把

defer 与 async 加载脚本时 DOMContentLoaded 触发顺序

这道题几乎每次问「浏览器渲染流程」都会被带出来:给 <script> 加上 defer 或 async,DOMContentLoaded 到底在什么时候触发?很多人的回答停留在「defer 在 DOMContentLoaded 之前、async 不确定」,这个说法不算错,但被追问一句「多个 defer 脚本之间谁先执行」「async 脚本会不会插

面试题:唯一索引冲突下 REPLACE INTO 与 ON DUPLICATE KEY 的锁差异

线上做热点行计数,两套 SQL 都能实现「不存在就插入、存在就更新」:REPLACE INTO 和 INSERT ... ON DUPLICATE KEY UPDATE。业务语义看起来几乎一样,但在唯一索引冲突时,二者在 InnoDB 里走的路径完全不同:一个先删后插,一个先尝试插入再改走更新。路径不同,产生的锁就不同,锁不同,并发下的死锁概率和主从延迟就不

sync.Once 中 Do 内调用 panic 后再次执行的行为判定

这道面试题的问法通常是:如果传给 sync.Once.Do 的函数在执行过程中 panic 了,那么之后再调用 Do,这个函数还会不会再执行一次?很多人第一反应是「会,因为没执行成功」,也有人觉得「不会,因为 Once 标记为已执行」。两种回答都只说对了一半,而且在不同 Go 版本上行为并不一样。要答准,必须回到 sync.Once 的源码:done 这个原

Redis Pipeline 批量命令中途报错时已发送命令的部分执行边界

面试里问 Pipeline,多数人能答出「一次 RTT 发多条命令、减少网络往返」。再往下追问一句:一批命令通过 Pipeline 发出去,第 3 条因为类型错误失败了,第 4、5 条到底执不执行?已执行的那几条会不会回滚?很多候选人就答得含糊了。这个问题的价值在于,它同时考察三件事:Pipeline 与事务的区别、Redis 单线程执行模型、以及客户端侧的

唯一索引与普通索引在 INSERT 冲突时的加锁范围差异

面试里问「唯一索引和普通索引有什么区别」,多数人能答出「唯一索引不允许重复值、查询能提前终止」。但把它和 INSERT 冲突放在一起问,能答清楚的人就少了:同样是一条 INSERT 撞上已存在的键值,唯一索引下失败的那条语句会留下间隙锁,普通索引下(如果这个索引上还有唯一约束在别的列、或者干脆是二级普通索引下的重复插入)锁的表现完全不同;更常见的是 INSE

Go 接口值为空与方法为空的判定陷阱及 reflect 检测方式

先看一段能在面试现场直接把人问住的代码:一个函数接收 error 参数,调用方传入一个 *MyError 类型的 nil 指针,函数内部用 if err != nil 判空,结果判断成立,随后调用 err.Error() 触发 panic。这段代码的诡异之处在于:明明传进来的是 nil,判空却不生效。这不是编译器的 bug,也不是运行时抽风,而是 Go 接口

面试题:Integer 在高频范围之外为什么每轮会重置为 MaxValue

这道题来自一次真实面试的追问现场:面试官给了一段多轮循环里对 Integer 做自增的代码,问「为什么超出缓存范围之后,每一轮拿到的值都是 Integer.MAX_VALUE,而不是继续往上加」。很多候选人第一反应是「Integer 是不可变类,所以加不上去」,这个回答只能算对了一半,因为不可变只会导致「原对象不变、返回新对象」,不会导致「回退到最大值」。真