Files
examination/topics/interview-prep/database-advanced/single_choice.json
T
wonder 0f68a64829
Deploy Examination / deploy (push) Successful in 10s
feat: add interview-prep topic group with 250 questions (6 subtopics, 5 question types)
Subtopics:
- distributed-microservice: 45 questions (分布式微服务架构)
- message-queue: 45 questions (消息队列)
- k8s-observability: 45 questions (K8s与可观测性)
- go-java-concurrency: 45 questions (Go/Java并发模型)
- database-advanced: 35 questions (数据库进阶)
- ai-engineering: 35 questions (AI工程实践)

Question types: single_choice, true_false, fill_blank, short_answer, code_reading
2026-09-09 16:36:27 +08:00

217 lines
13 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"topic": "database-advanced",
"type": "single_choice",
"schema_version": "1.0.0",
"generated": "2026-09-09T00:00:00+08:00",
"questions": [
{
"id": "sc-001",
"type": "single_choice",
"difficulty": 3,
"tags": [
"mysql",
"bplus-tree",
"index"
],
"question": "在 InnoDB 中,关于聚簇索引和非聚簇索引(二级索引)的区别,以下说法正确的是?",
"options": {
"A": "聚簇索引的叶子节点存储的是完整行数据,非聚簇索引的叶子节点存储的是主键值",
"B": "每个表可以有多个聚簇索引,但只能有一个非聚簇索引",
"C": "聚簇索引的查询效率一定比非聚簇索引高,因此应尽量为所有列都建立聚簇索引",
"D": "非聚簇索引查找数据时不需要回表,因为叶子节点直接指向磁盘上的行"
},
"answer": "A",
"explanation": "InnoDB 的聚簇索引(通常即主键索引)的叶子节点直接存储完整行数据,而非聚簇索引(二级索引)的叶子节点存储的是主键值。通过二级索引查找数据时,需要先拿到主键值,再回到聚簇索引中查找完整行,这个过程称为「回表」。每个 InnoDB 表只能有一个聚簇索引(数据物理上按聚簇索引排序存储),但可以有多个非聚簇索引。索引过多会增加写入开销和存储空间,不应盲目建立。",
"source": null,
"related": []
},
{
"id": "sc-002",
"type": "single_choice",
"difficulty": 2,
"tags": [
"mysql",
"bplus-tree",
"composite-index"
],
"question": "有一张表建立了联合索引 INDEX idx_abc(a, b, c),以下哪个查询能有效利用该索引?",
"options": {
"A": "SELECT * FROM t WHERE b = 1 AND c = 2",
"B": "SELECT * FROM t WHERE c = 2 AND a = 1",
"C": "SELECT * FROM t WHERE a = 1 AND c = 2",
"D": "SELECT * FROM t WHERE a = 1 AND b > 5 AND c = 2"
},
"answer": "B",
"explanation": "联合索引遵循最左前缀原则。MySQL 优化器会自动调整 WHERE 条件的顺序,所以选项 B(c=2 AND a=1)等价于 a=1 AND c=2,可以使用索引的 a 列。但注意 c=2 无法使用索引(中间跳过了 b)。选项 A 完全跳过了最左列 a,无法使用该索引。选项 C 使用了 a 但跳过了 b 直接用 c,只能用到 a 列。选项 D 中 b 是范围查询(b>5),根据最左前缀原则,范围查询后的列 c 无法使用索引,但 a 和 b 部分可以使用。不过选项 B 能让优化器识别出 a=1 可用索引,是本题最明确能利用索引的选项。",
"source": null,
"related": []
},
{
"id": "sc-003",
"type": "single_choice",
"difficulty": 3,
"tags": [
"mysql",
"bplus-tree",
"index",
"covering-index"
],
"question": "关于覆盖索引(Covering Index),以下描述正确的是?",
"options": {
"A": "覆盖索引是指索引包含了查询所需的所有列,从而避免回表操作",
"B": "覆盖索引要求索引列必须是主键,否则无法覆盖",
"C": "使用覆盖索引时,EXPLAIN 的 Extra 列会显示 Using filesort",
"D": "覆盖索引只适用于等值查询,范围查询无法使用覆盖索引"
},
"answer": "A",
"explanation": "覆盖索引是指查询所需的列都包含在索引中,无需回表读取聚簇索引中的完整行数据。EXPLAIN 中 Extra 列显示 Using index 表示使用了覆盖索引。覆盖索引不限于主键索引,任何二级索引只要包含了查询所需的列即可。范围查询同样可以利用覆盖索引,只要索引包含了所需列,例如 INDEX(name, age) 可以覆盖 SELECT name, age FROM t WHERE name > 'a'。Using filesort 表示需要额外排序,与覆盖索引无关。",
"source": null,
"related": []
},
{
"id": "sc-004",
"type": "single_choice",
"difficulty": 4,
"tags": [
"mysql",
"explain"
],
"question": "以下 EXPLAIN 输出中,type 列的值从最优到最差的正确排列顺序是?",
"options": {
"A": "ALL > index > range > ref > const",
"B": "const > ref > range > index > ALL",
"C": "const > range > ref > index > ALL",
"D": "range > const > ref > ALL > index"
},
"answer": "B",
"explanation": "EXPLAIN 的 type 列表示 MySQL 访问表的方式,从最优到最差的顺序为:system > const > eq_ref > ref > range > index > ALL。const 表示通过主键或唯一索引精确匹配一行;ref 表示非唯一索引等值匹配;range 表示索引范围扫描;index 表示全索引扫描(遍历索引树);ALL 表示全表扫描(最差)。选项 B 正确地将 const > ref > range > index > ALL 从最优到最差排列。",
"source": null,
"related": []
},
{
"id": "sc-005",
"type": "single_choice",
"difficulty": 3,
"tags": [
"mysql",
"explain"
],
"question": "EXPLAIN 的 Extra 列出现 Using temporary 和 Using filesort,通常意味着查询需要优化。以下哪种查询最容易同时出现这两个警告?",
"options": {
"A": "SELECT * FROM t WHERE id = 1",
"B": "SELECT DISTINCT col1 FROM t ORDER BY col2 LIMIT 10",
"C": "SELECT * FROM t FORCE INDEX(PRIMARY) WHERE id BETWEEN 1 AND 100",
"D": "SELECT count(*) FROM t WHERE col1 = 'value'"
},
"answer": "B",
"explanation": "选项 B 的查询同时涉及 DISTINCT(去重)和 ORDER BY(排序),且 col1 和 col2 不是同一个列,无法通过索引同时满足。MySQL 需要创建临时表来处理 DISTINCT,并且需要 filesort 来完成 ORDER BY,因此同时出现 Using temporary 和 Using filesort。选项 A 只是主键等值查询,type 为 const,无需临时表或排序。选项 C 使用 FORCE INDEX 做范围扫描,通常也不会触发临时表。选项 D 是简单的 WHERE 条件聚合,count(*) 不需要排序或去重。",
"source": null,
"related": []
},
{
"id": "sc-006",
"type": "single_choice",
"difficulty": 2,
"tags": [
"mysql",
"slow-query"
],
"question": "关于 MySQL 慢查询日志,以下配置和说法正确的是?",
"options": {
"A": "slow_query_log=ON 开启慢查询日志后,所有查询都会被记录到日志中",
"B": "long_query_time 默认值为 10 秒,表示执行时间超过 10 秒的 SQL 才会被记录",
"C": "慢查询日志只能记录 SELECT 语句,不包括 INSERT/UPDATE/DELETE",
"D": "开启慢查询日志会对数据库性能产生显著影响,生产环境不应开启"
},
"answer": "B",
"explanation": "MySQL 慢查询日志(slow_query_log)默认 long_query_time 为 10 秒,只有执行时间超过该阈值的 SQL 才会被记录。慢查询日志记录所有类型的语句(SELECT、INSERT、UPDATE、DELETE 等),只要执行时间超过阈值。默认情况下只有管理员可以查看慢查询日志,不会记录所有查询,因此对性能影响极小,生产环境强烈建议开启以便排查性能问题。也可以设置 log_queries_not_using_indexes=ON 记录未使用索引的查询。",
"source": null,
"related": []
},
{
"id": "sc-007",
"type": "single_choice",
"difficulty": 4,
"tags": [
"mysql",
"lock",
"next-key-lock",
"gap-lock"
],
"question": "在 InnoDB 的默认隔离级别(REPEATABLE READ)下,执行以下语句时,关于锁的行为描述正确的是?\n\nDELETE FROM orders WHERE order_id = 100;\n假设 order_id 是主键列。",
"options": {
"A": "会加行锁,锁定 order_id = 100 的那一行记录",
"B": "会加临键锁(Next-Key Lock),锁定 order_id = 100 前面的间隙",
"C": "会加间隙锁(Gap Lock),锁定 order_id = 100 周围的范围",
"D": "REPEATABLE READ 级别下不会加任何锁"
},
"answer": "A",
"explanation": "当使用主键进行精确等值匹配(WHERE order_id = 100)时,InnoDB 只需要加一个行锁(Record Lock)锁定该行即可,不需要间隙锁或临键锁。间隙锁和临键锁主要用于防止幻读,在非唯一索引的范围查询或主键的范围查询时才会出现。等值查询命中已存在的记录时,锁的粒度最小,只锁定匹配的那一行。DELETE 语句在 REPEATABLE READ 级别下会获取排他锁(X Lock),即该行在事务提交前不能被其他事务修改或读取(当前读)。",
"source": null,
"related": []
},
{
"id": "sc-008",
"type": "single_choice",
"difficulty": 3,
"tags": [
"redis",
"cluster",
"slot",
"consistent-hashing"
],
"question": "Redis Cluster 使用 16384 个 slot 分片来分布数据,关于 slot 的分配和路由机制,以下说法正确的是?",
"options": {
"A": "客户端发送任意 key 的命令时,Redis Cluster 会自动将 key 路由到任意一个节点处理",
"B": "使用 CRC16 对 key 计算哈希值后对 16384 取模来确定 key 所属的 slot",
"C": "每个 Redis 节点平均分配约 16384 个 slot,节点数固定后无法调整",
"D": "16384 个 slot 必须全部分配完毕才能正常提供服务,任何 slot 未分配都会导致集群不可用"
},
"answer": "B",
"explanation": "Redis Cluster 使用 CRC16(key) % 16384 来确定每个 key 所属的 slot。每个节点负责一部分 slot,客户端发送命令时,如果 key 不在当前节点,会收到 MOVED 重定向响应。slot 的分配是动态的,可以通过 reshard 操作在节点间迁移 slot。只要至少有 6470 个 slot 被分配(覆盖所有 slot 的一半以上 + 每个 master 至少一个),集群就可以正常工作,但通常建议 100% 覆盖。CRC16 是一种高效的哈希算法,16384 个 slot 使用 2KB 的位图在节点间通信,这是选择 16384 而非更大数字的原因之一。",
"source": null,
"related": []
},
{
"id": "sc-009",
"type": "single_choice",
"difficulty": 4,
"tags": [
"redis",
"sentinel"
],
"question": "关于 Redis Sentinel(哨兵)的故障转移流程,以下描述正确的是?",
"options": {
"A": "当 master 被标记为主观下线(SDOWN)后,Sentinel 会立即开始故障转移",
"B": "Sentinel 通过 Raft 协议选举 Leader,由 Leader 执行故障转移操作",
"C": "故障转移时,Sentinel 会优先选择 slave 的 offset 最大的节点作为新 master",
"D": "故障转移完成后,Sentinel 不会通知客户端新的 master 地址,客户端需要自行探测"
},
"answer": "B",
"explanation": "Redis Sentinel 的故障转移流程:首先,单个 Sentinel 发现 master 不响应,标记为 SDOWN(主观下线);当足够多的 Sentinel(quorum 数量)都认为 master SDOWN 后,标记为 ODOWN(客观下线);然后通过类似 Raft 的选举机制选出一个 Leader Sentinel;由 Leader 执行故障转移:从 slave 中选择合适的节点提升为新 master(优先级 > offset > runid),通知其他 slave 复制新 master,通知客户端新的 master 地址。注意不是 offset 最大就优先——还需要先看 slave-priority,只有 priority 相同时才比较 offset。",
"source": null,
"related": []
},
{
"id": "sc-010",
"type": "single_choice",
"difficulty": 3,
"tags": [
"redis",
"hybrid-persistence",
"lru"
],
"question": "关于 Redis 的持久化和内存管理,以下说法正确的是?",
"options": {
"A": "Redis 混合持久化(hybrid persistence)是在 RDB 快照的基础上追加 AOF 日志,重启时先加载 RDB 再重放增量 AOF,兼顾恢复速度和数据完整性",
"B": "Redis 混合持久化是将 RDB 和 AOF 数据同时写入同一个文件,恢复时随机读取两者的数据进行合并",
"C": "Redis 的 allkeys-lru 策略只会在键空间不足时淘汰设置了过期时间的 key",
"D": "Redis 开启内存碎片整理(activedefrag)会导致主线程完全阻塞,建议生产环境关闭"
},
"answer": "A",
"explanation": "Redis 混合持久化(Redis 4.0+)在 AOF 重写时,将当前 RDB 快照数据写入 AOF 文件头部,重写后的增量命令追加在 RDB 数据之后。重启时先加载 RDB 部分(快速恢复大部分数据),再重放后面的 AOF 增量命令(保证数据完整性)。这结合了 RDB 恢复速度快和 AOF 数据丢失少的优点。allkeys-lru 策略会在所有 key 中(不论是否设置了过期时间)淘汰最近最少使用的 key。Redis 4.0+ 的 activedefrag 在后台线程执行碎片整理,不会完全阻塞主线程,生产环境可以开启。",
"source": null,
"related": []
}
]
}