【面试题】1. InnoDB 的意向锁(Intention Lock)是什么?它跟行锁是什么关系?
【标准答案】意向锁是表级锁,但它不是直接锁数据——而是个"标记",告诉后来者这表里已经有行锁了。分两种:IS(意向共享锁),事务想对某些行加 S 锁,先在表上加 IS;IX(意向排他锁),事务想加 X 锁,先在表上加 IX。核心价值是解决表锁和行锁的冲突判断——如果没有意向锁,有人想 LOCK TABLES,得逐行检查有没有行锁,O(N) 开销。有了意向锁,看一眼表上有没有 IX 就知道里面有没有排他行锁,O(1)。注意:意向锁之间不互斥(IS 和 IX 兼容),它们只跟表级锁互斥,这就是多粒度锁协议的核心。日常你感觉不到它,但它默默工作着。
【面试题】2. 什么叫索引选择性?选择性低的字段建索引到底有没有用?
【标准答案】索引选择性 = 不重复的索引值数 / 总行数。选择性越接近 1 越好,性别字段选择性 2/百万≈0,建了等于没建。但"选择性低就不建索引"是教科书教条,实战要看查询模式。比如 status 字段只有 0/1/2 三个值,但 99% 数据是 status=0,你要查 status=2 的异常数据——走索引过滤掉 99% 数据,效果拔群。关键不是选择性绝对值,而是索引能不能大幅减少扫描行数。诀窍:EXPLAIN 看 rows 过滤比,过滤掉越多越值得建。如果 status=0 占 95%,查它就不如全表扫。总结:看"区分度"不如看"过滤度",结合具体查询判断,别死记教条。
【面试题】3. Hive 的 ORC 和 Parquet 两种列存格式,什么时候选哪个?
【标准答案】两者都是列存,但设计哲学不同。ORC 是 Hive 亲儿子,支持轻量索引(Bloom Filter + min/max 统计),做谓词下推时能直接跳过不相关的 Stripe,聚合查询比 Parquet 快 20%-30%。Parquet 跨引擎兼容性好,Spark、Impala、Flink 原生支持,社区更活跃。选型口诀:纯 Hive 数仓、ETL 链路重、追求极致查询性能选 ORC;多引擎混用(Spark ETL + Presto 即席查询)、追求生态兼容选 Parquet。还有一个细节:ORC 对嵌套结构支持不如 Parquet 灵活,如果业务有复杂嵌套 JSON 就用 Parquet。压缩率二者差不多,都支持 Snappy/Zstd。
【面试题】4. TokuDB 的 Fractal Tree 跟 InnoDB 的 B+Tree 有什么本质区别?什么时候用 TokuDB?
【标准答案】B+Tree 是原地更新——新数据要找到叶子节点覆盖写入,随机 IO 多。Fractal Tree 在每个内部节点加消息缓冲区,插入的新数据先写到根节点的缓冲区,缓冲区满了再批量往下推。效果:把大量随机 IO 聚合成顺序 IO,写入性能比 B+Tree 高 5-10 倍,压缩率极高(TokuDB 比 InnoDB 小 3-5 倍是常态)。代价是点查比 B+Tree 慢一点,因为要遍历节点缓冲区。适用场景:日志归档、审计流水、IoT 传感器数据——写多读少、数据量大、需要压缩省成本。不适用:大量点查和高并发 OLTP 核心链路。TokuDB 被 Percona 收购后维护渐少,新一代 LSM-Tree 引擎 MyRocks(Facebook)成了更好的选择,MySQL 8.0.20 后已有 MyRocks 插件。
【面试题】5. PostgreSQL 的表分区怎么用?三种分区方式各适合什么场景?
【标准答案】PG 从 10 开始原生支持声明式分区,三种方式:Range 分区按范围切,经典按时间分,比如 order_2026q1、order_2026q2,查历史订单只扫对应分区;List 分区按离散值,比如按地区分,查华北订单只扫华北分区;Hash 分区按哈希值均匀散列,适合没有明确业务范围的场景,用来均衡写入压力。实战技巧:分区键必须出现在主键和唯一约束里,否则 create 直接报错;默认分区(DEFAULT)兜底存不要的数据;分区裁剪自动生效——WHERE 条件带上分区键,PG 只扫命中的分区。对比 MySQL 分区:PG 的分区是独立的物理表,可单独备份、VACUUM、甚至放不同表空间,比 MySQL 分区灵活得多。
【面试题】6. YARN 的三种调度器(FIFO、Capacity、Fair)分别怎么用?生产上怎么选?
【标准答案】FIFO 最简单,一个队列先到先得——前一个大任务占着资源不放,后面小任务排队干等,只适合离线跑批。Capacity Scheduler 多队列,每个队列预留资源下限,共享集群时互不侵占,适合多部门共用同一 Hadoop 集群——A 部门队列保底 30% 资源,用不完可以被其他队列借走。Fair Scheduler 追求公平,所有运行中的作业平分资源,轻量作业秒出结果、重量作业慢慢跑,最适合混合负载。生产选型:企业内部多团队共享用 Capacity;追求交互式查询和高资源利用率用 Fair;只有 ETL 批跑用 FIFO 就够了。实战中 Fair Scheduler 坑少,Cloudera 默认推荐。
【面试题】7. Spark Shuffle 为什么会成为性能瓶颈?有哪些优化手段?
【标准答案】Shuffle 慢在三个地方:磁盘 IO(Map 端溢写排序落盘)、网络 IO(跨节点拉取数据)、CPU(全量排序和序列化)。优化四板斧:一、减少 Shuffle 数据量——用 reduceByKey 代替 groupByKey,map 端预先做局部聚合,数据量可能缩小几十倍。二、调大 shuffle.partitions 默认 200 对大数据量太小,调到 executor 核心数的 2-3 倍,让每个 task 处理的数据更均匀。三、开启 bypass 机制——shuffle.sort.bypassMergeThreshold 默认 200,分区数少于此值时跳过排序直接用 hash 写文件,消除排序开销。四、内存给足——executor 内存不够就频繁溢写磁盘,executor 内存按数据量合理配置。面试官想听的不是参数罗列,是你能根据数据量评估 Shuffle 开销并给出针对性调优。
【面试题】8. ProxySQL 和 MaxScale 做 MySQL 读写分离,架构上各有什么优劣?怎么选?
【标准答案】两者都是透明数据库代理,做到业务无感知的读写分离。ProxySQL 国内使用更广、社区更活跃,核心优势是灵活的查询路由规则——可以基于正则、用户、schema、甚至 SQL digest 做路由,还内置连接池和查询缓存,高并发下对后端 MySQL 的连接数削减能力很强。MaxScale 是 MariaDB 出品,和 MariaDB 深度整合,自带 binlog server 和 CDC 模块(Avro Router),做数据流中转很强。缺点:ProxySQL 配置偏复杂,出问题排查门槛高;MaxScale 对官方 MySQL 兼容没 MariaDB 好。选型:纯 MySQL 读写分离无脑 ProxySQL;如果已经用了 MariaDB 或者在搞 CDC 到 Kafka,MaxScale 一站搞定。
【面试题】9. ShardingSphere-JDBC 和 ShardingSphere-Proxy 架构有什么核心区别?分别适合什么场景?
【标准答案】JDBC 版是 jar 包嵌入应用,数据分片、读写分离逻辑在客户端进程内完成,零额外部署、无中间件单点、延迟最低——但每个应用都要引入,多语言栈不友好。Proxy 版是独立部署的数据库代理,对业务透明,任何语言都能连——但多一跳网络、有中间件瓶颈风险、要额外运维。我选型:Java 单体/微服务架构直接用 JDBC 版,省运维、性能好;多语言团队或要做 SQL 审计/防火墙/流量治理用 Proxy 版,集中管控。关于 MyCat:老牌但社区沉寂,功能稳定但新特性跟不上,新项目不建议,存量系统能用就继续用。ShardingSphere 已经是 Apache 顶级项目,生态和活跃度远超 MyCat。
【面试题】10. 如何用 MySQL Binlog 实现异构数据同步?Canal 和 Debezium 怎么选?
【标准答案】异构同步就是把 MySQL 的增删改实时同步到 ES、Redis、Kafka、数据仓库。Canal 是阿里开源的,伪装成 MySQL 从库拉 binlog 解析后投递到 MQ,国内用得很广。Debezium 是 Red Hat 出品,基于 Kafka Connect 框架,原生集成 Kafka 生态。核心区别:Canal 轻量、部署简单、适合直接推送到 MQ→下游消费;Debezium 重但治理能力强,自带 Schema 演化管理、失败重试、分布式快照。选型:如果你的技术栈是阿里系(Canal→RocketMQ→下游),选 Canal 简单直接;如果公司有 Kafka 基建、要求数据治理和容错,选 Debezium。还有一个关键——Canal 的 protobuf 格式性能好但序列化不通用,Debezium 的 JSON/Avro 格式标准但数据量大。实际落地别忘了加数据校验和对账,binlog 同步偶尔会有丢数据的极端情况。