
2023年度小满秋招数据库岗第一批笔试刚结束我把整套卷子和备考过程完整复盘了一遍。先说结论这批笔试题不算变态但非常考验平时是否真的写过SQL、跑过慢查询、看过执行计划纯靠背八股文的同学大概率在场景题和手写SQL环节露馅。这篇文章把考点分布、答题思路、踩坑经验全部整理出来给后面几批备考的同学做个参考也聊聊我自己的体会。需要说明的是笔试内容覆盖范围比想象中广从最基础的增删改查到索引优化、事务隔离、数据库设计再到主从同步、国产数据库适配都有涉及。如果你正准备数据库岗的校招笔试这篇文章可以直接拿来当复习清单用。1. 笔试的整体印象与考情梳理1.1 这次笔试到底考察了什么先说说卷面整体情况。整场笔试分为客观题、手写SQL题和场景设计题三大块时间一共120分钟题量大概是单选20道、多选10道、手写SQL 4道、场景设计2道。时间看起来够用但实际做下来非常紧张尤其是手写SQL部分不仅要求写对还要求考虑边界条件和执行效率。从知识点分布来看考察重点集中在四个方面SQL基础与高级查询包括多表联查、聚合函数、窗口函数、子查询优化索引原理与SQL优化包括B树结构、覆盖索引、最左前缀原则、索引失效场景事务与锁机制包括ACID特性、隔离级别、死锁成因与排查数据库设计与运维包括三范式、ER图设计、主从同步、备份恢复、连接池配置有意思的是这次笔试还考了一道国产数据库相关的题目问的是从Oracle迁移到达梦数据库时哪些语法和功能需要适配。这说明现在企业招数据库岗已经不满足于只会MySQL了具备多数据库迁移和国产化适配意识的人会更受欢迎。1.2 为什么企业要这么考很多同学觉得笔试里的SQL题随便写写能跑就行这是典型的误区。企业笔试之所以设计成现在这个结构背后是有明确逻辑的。客观题部分主要筛掉基础不牢的人。数据库字段类型选错、隔离级别搞混、索引结构说不清这些硬伤在笔试阶段不筛掉入职后写出来的SQL就是生产事故的隐患。手写SQL题考察的是真实编码能力通过你写的SQL语句能看出你是不是真的理解表结构、理解数据关系、理解索引使用。场景设计题则是模拟真实工作中给你一个需求你要设计出一套合理的表结构的能力。所以备考数据库岗笔试不能只背知识点必须动手写、动手设计。日常多写SQL、多调优慢查询、多复盘表结构设计笔试的时候自然就有手感。2. 必考核心知识点与答题思路2.1 SQL基础从增删改查到窗口函数SQL基础部分虽然叫基础但笔试的考察方式并不基础。直接考select 字段 from 表 where 条件的题目很少更多的是把多个知识点揉在一起让你写出一条能够应对复杂业务场景的查询语句。这次笔试题里有一道非常典型的题目查询每个部门薪资排名前三的员工。很多同学第一反应是用group by加limit但仔细想想就会发现group by后取limit只能取到每个分组的一条记录或者聚合结果要取前三名非常别扭。更合理的做法是用窗口函数SELECT department_name, employee_name, salary FROM ( SELECT d.department_name, e.employee_name, e.salary, DENSE_RANK() OVER (PARTITION BY d.department_id ORDER BY e.salary DESC) AS rn FROM employee e JOIN department d ON e.department_id d.department_id ) t WHERE rn 3;这里我用的是DENSE_RANK而不是ROW_NUMBER因为如果存在薪资相同的员工ROW_NUMBER会随机分配一个排名而DENSE_RANK会把相同薪资的人排在同一个名次更符合业务语义。这个细节是我实际工作中踩过坑才记住的。除了窗口函数增删改查里的涨姿势点还有一个批量更新数据时要注意where条件的写法。UPDATE account SET balance balance - 100 WHERE id IN (SELECT id FROM frozen_account WHERE status 1);笔试时容易忽略的是MySQL中直接对同一张表进行子查询更新会报错You cant specify target table for update in FROM clause。正确的做法是先包一层临时表或者使用连表更新。这类题目考察的不是你知不知道update语法而是你有没有在实际开发中处理过类似问题。2.2 索引原理B树与索引失效场景索引几乎是数据库岗笔试的必考内容而且考得很细。如果你想拿高分光知道索引能加速查询是不够的必须理解索引的底层数据结构。B树是关系型数据库最常用的索引结构它相比于B树的好处在于所有数据都存储在叶子节点并且叶子节点之间有指针相连这样范围查询的时候只需要沿着叶子节点的链表顺序扫描即可不需要回溯到上层节点。这也是为什么你在建索引的时候MySQL会默认选择B树而不是其他数据结构。笔试中关于索引的常见问题还有哪些情况会导致索引失效。我把常见的失效场景整理成了一个速查表场景示例失效原因对索引列使用函数WHERE YEAR(create_time) 2023函数改变了列的原始值隐式类型转换WHERE mobile 13800138000字符串列与数字比较时发生类型转换LIKE前置通配符WHERE name LIKE %张无法利用索引有序性OR连接非索引列WHERE age 20 OR name 张三优化器可能选择全表扫描联合索引不满足最左前缀索引(a,b)条件只用了b联合索引按a先排序关于联合索引笔试还经常考为什么最左前缀原则有效。其实很简单联合索引本质是先按第一个字段排序第一个字段相同的再按第二个字段排序。如果你跳过第一个字段直接用第二个字段查询索引的排序结构就没法用上了就像一个只有姓名拼音索引的通讯录你非要去查所有住在朝阳区的人索引根本帮不上忙。2.3 事务、锁与并发控制事务这块ACID四个特性必须脱口而出同时要理解每个特性对应数据库的哪种机制。原子性靠undo log实现持久性靠redo log实现隔离性靠锁和MVCC实现一致性靠前三者共同保证。笔试如果考到数据库宕机后为什么数据不会丢答案就在redo log。隔离级别也是高频考点。读未提交、读已提交、可重复读、串行化这四级的区别关键看能否解决脏读、不可重复读、幻读这三个问题。MySQL默认的隔离级别是可重复读但InnoDB引擎通过间隙锁在一定程度解决了幻读问题。我建议在复习的时候画一张表记住每个级别能防什么、不能防什么隔离级别脏读不可重复读幻读读未提交可能可能可能读已提交不会可能可能可重复读不会不会可能InnoDB间隙锁可规避串行化不会不会不会锁机制里行锁和表锁的对比、悲观锁和乐观锁的适用场景、死锁的成因和排查这些都要做到有问必答。死锁的典型例子是两个事务互相持有对方需要的资源比如事务A先更新id1再更新id2事务B先更新id2再更新id1两者同时执行就会互相等待。实际排查死锁时MySQL可以通过SHOW ENGINE INNODB STATUS查看最近一次死锁的详细信息定位是哪两条SQL、持有哪些锁、等待哪些锁。3. 数据库设计题到底该怎么答3.1 范式与反范式别被三大范式框死数据库设计是笔试中区分度较大的题目也是最贴近实际工作的一项考察。很多教材把三大范式讲得神乎其神但实际工作中很少有人会为了满足第三范式把所有表拆成极细的颗粒度。笔试中考察范式目的是看你能否在规范性和性能之间做出合理权衡。第一范式要求字段不可再分这是硬约束基本所有表设计都要满足。第二范式要求非主键字段完全依赖于主键第三范式要求非主键字段之间不能有传递依赖。通俗点理解第二范式管的是这张表的主键到底能不能唯一确定这一行第三范式管的是这张表里的字段是不是都只跟这张表的主键有关而不是跟其他非主键字段有关。但笔试如果出根据需求设计电商订单系统的表结构你千万不要一上来就按范式把所有表拆得七零八落。订单表需要冗余一个用户昵称或者商品名称快照即使这违反了第三范式。为什么因为订单生成之后商品改价、用户改名都不应该影响历史订单的展示。这个冗余字段就是反范式设计它换取了查询性能和数据稳定性。能够在答卷里主动说明这里我做了反范式冗余因为XX原因相当加分。3.2 场景设计题从ER图到建表语句这次笔试的场景设计题是设计一个学生选课系统需求包括学生信息管理、课程信息管理、选课记录管理、成绩录入与查询。看似简单但拿满分不容易因为有几处隐含考点。第一选课记录表必须设计联合唯一约束防止同一学生重复选同一门课。这个约束不仅是业务要求也是面试官想看到的细节。CREATE TABLE course_selection ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, student_id BIGINT NOT NULL COMMENT 学生ID, course_id BIGINT NOT NULL COMMENT 课程ID, score DECIMAL(5,2) DEFAULT NULL COMMENT 成绩, selected_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 选课时间, UNIQUE KEY uk_student_course (student_id, course_id), KEY idx_course_id (course_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT选课记录表;第二成绩字段要使用DECIMAL而不是FLOAT或者DOUBLE因为浮点数在比较和计算时存在精度问题。笔试如果考到这个知识点而你没写说明你缺少实际开发经验。第三除了主键索引我额外给course_id建了索引因为业务上经常要查询某门课程有哪些学生选了。而联合唯一索引uk_student_course本身就覆盖了student_id前缀的查询场景所以不需要单独为student_id再建索引。这种索引设计上的考量是区分度最高的地方。字段类型的选择也是设计题的隐藏考点。手机号建议用varchar存不要用bigint因为手机号可能包含前缀、国家码而且不需要参与数值运算。状态字段用tinyint即可不要一上来就设计int(11)。时间字段建议用datetime或timestamp除非有跨时区需求否则不需要设计成字符串。4. 高可用与运维主从同步、连接池与性能排查4.1 主从同步原理与常见延迟问题笔试中出现主从同步题目通常不是让你手工搭建一套MySQL集群而是考察你对同步原理的理解和排障思路。主从同步的核心是基于binlog的日志复制。主库把变更写入binlog从库的IO线程把binlog拉取到本地并写入relay log从库的SQL线程再重放relay log中的数据变更。这里有个常见的坑如果binlog格式设置不合理会导致主从数据不一致。binlog有STATEMENT、ROW、MIXED三种格式。STATEMENT格式记录的是SQL语句本身日志量小但如果SQL使用了UUID()、NOW()这类不确定性函数从库重放的结果可能与主库不一致。ROW格式记录的是每行数据的变化一致性最好也是目前生产环境推荐使用的格式缺点是日志量偏大。MIXED格式是MySQL根据SQL类型自动选择兼顾两者。关于主从延迟笔试常问主从延迟产生的原因以及如何解决。原因无非是从库的SQL线程单线程重放速度跟不上主库的并发写入从库硬件性能比主库差大事务导致主库binlog在从库重放耗时过长从库上有慢查询或锁等待阻塞了SQL线程。解决办法包括并行复制、升级从库硬件、拆分大事务、优化从库上的查询。4.2 连接池参数与审计引起索引争用这类怪异问题连接池是Java后端开发绕不开的工具笔试中经常以配置题的方式考查。你需要理解为什么用连接池因为数据库建立连接是一个开销很大的操作频繁创建销毁连接会拖垮数据库和应用程序。连接池就是维护一批已经建立好的连接应用需要时直接取用完归还避免重复握手认证的开销。以HikariCP为例核心参数有这么几个minimumIdle最小空闲连接数建议和maximumPoolSize一致避免频繁创建新连接maximumPoolSize最大连接数不是越大越好还要考虑数据库能承受的连接数上限connectionTimeout获取连接的超时时间默认30秒生产环境建议设置短一点比如3秒maxLifetime连接最大生命周期要小于数据库的wait_timeout避免被数据库服务端断开后池中还留着无效连接这次笔试还出现了一道比较怪异的题目问的是数据库开启审计后引发索引争用如何排查和解决。实际上数据库开启审计功能后每一次操作都可能被记录到审计日志中高并发场景下审计日志的写入会和业务SQL产生磁盘IO竞争同时审计锁与索引的更新操作也会产生锁等待导致SQL响应变慢。解决思路通常有几种调整审计策略只记录权限变更、DDL等高风险操作而不是记录所有DML把审计日志存储到独立的磁盘或者独立的表空间减少与业务数据文件的IO竞争把审计写入从同步改成异步批量写入如果对审计实时性要求不高可以定期轮转审计日志减小单文件带来的写入压力。这道题考的不是单纯的技术参数而是你能不能从系统整体视角去分析问题。4.3 数据备份恢复与容灾意识数据库岗笔试中备份恢复的考点非常务实考的就是你知不知道常见的备份工具和恢复流程。逻辑备份用mysqldump适合数据量较小的场景导出的是SQL语句物理备份用XtraBackup直接复制数据文件适合大数据量下的快速备份。笔试中如果让你设计备份策略正确方向是全量备份加增量备份结合。比如每天凌晨2点做一次全量备份每2小时做一次binlog增量备份这样即使数据库在下午4点崩溃也能用全量备份加上当天的binlog恢复到4点的状态。关于恢复流程需要特别强调先恢复全量备份再应用binlog增量。很多同学答成直接把最新的数据文件拷贝回去这不算错但忽略了binlog的应用会丢掉全量备份时间点到故障时间点之间的数据变更。数据一致性校验也很重要恢复完成后要对比关键表的行数、checksum确保数据完整。5. 国产数据库与生态工具5.1 从Oracle到国产数据库迁移适配怎么做这几年国产数据库的讨论热度越来越高从达梦、人大金仓到GaussDB、Doris笔试题也逐渐开始涉及。今年小满秋招笔试中出现了一道关于Oracle迁移到达梦数据库的适配题目虽然分值不高但能答出来的同学不多因为这个知识点在很多人的复习范围之外。达梦数据库DM8是国内最常见的Oracle兼容型数据库之一很多政府、金融项目都在用。从Oracle迁移过来主要适配点包括数据类型映射如NUMBER对应DECIMAL、VARCHAR2对应VARCHAR、存储过程语法差异、序列和触发器逻辑、自带函数库的差异。其中最容易踩坑的是分页查询Oracle用的是ROWNUM达梦则直接支持LIMIT语法。这类题目的意义在于企业数据库岗的日常工作不再只跟MySQL打交道具备迁移和适配能力的人会非常抢手。笔试中如果你能主动写出迁移前先做兼容性评估迁移后要做数据一致性校验和应用回归测试就已经比绝大多数考生高出一个level。5.2 数据库工具链提升效率的利器笔试中偶尔会出现工具类的选择题比如下面哪个工具可以导入导出数据库脚本如何通过IDEA连接数据库并导出数据。这类题目不难但如果你平时只用一个Navicat可能就会卡住。我常用的工具组合是这样的写SQL和调试用IDEA自带的Database面板或者DataGrip数据量小、操作简单的场景用NavicatPostgreSQL和各类开源数据库统一用DBeaver因为它是免费开源的。导出数据库脚本时IDEA的Database面板可以右键选中表或Schema选择Export Data或者Generate Script导出建表语句和数据非常方便。另外如果你要在已有重复数据的表中添加唯一约束MySQL会直接报错Duplicate entry。实战中的处理方法是先查出重复数据并清理再添加唯一索引。笔试如果出现这个场景能提前写出排查重复数据的SQL比如SELECT user_id, COUNT(*) FROM user_account GROUP BY user_id HAVING COUNT(*) 1;这代表你真的处理过脏数据问题而不是单纯背过唯一约束的概念。5.3 说说向量数据库与新型数据库现在不只是关系型数据库的天下向量数据库、时序数据库也在很多实际项目中落地了。笔试偶尔会出现这类名词解释题比如什么是向量数据库它和传统关系型数据库的区别是什么。向量数据库专门用来存储和检索高维向量典型应用是推荐系统、图像检索以及大模型的知识库。ChatGPT带火了一波向量数据库热潮Milvus、Chroma、Pinecone这些产品也被频繁提及。向量数据库与传统数据库的本质区别在于它存的是通过模型生成的embedding向量查询的时候用的是最近邻检索如余弦相似度而不是等值比较或范围查询。如果你后续看到向量数据库相关岗位的需求至少要知道它和大模型应用之间的关系。时序数据库则主要面向监控数据、IoT传感器数据这种高写入、时间序排列的数据场景最典型的开源产品是InfluxDB和TDengineDoris等分析型MPP数据库也常被用来做海量数据分析。笔试如果考到能从数据模型、写入模式、查询模式三个角度对比基本就能拿分。6. 失分点复盘与备考建议6.1 笔试中最容易丢分的地方复盘这次笔试我整理了五个典型的失分点希望能帮助你在下一次笔试中提前规避。第一SQL手写题忽略边界条件。比如查询每个部门薪资最高的员工很多人只写了group by max完全没考虑如果有多个员工薪资相同怎么处理。一个简单的窗口函数就能解决但平时不练就会想不到。第二索引失效场景答不完整。背过LIKE前置通配符会失效的人很多但能把隐式类型转换对索引列使用函数都答全的人很少。面试官问还有吗的时候你如果说不出第五个场景说明知识还是零散的没有形成体系。第三事务隔离级别和锁机制混淆。可重复读和读已提交到底差在哪间隙锁是干嘛用的这些一定要从原理上理解不能只背结论。我见过很多同学把不可重复读和幻读混为一谈把间隙锁说成表锁这种错误一旦犯就是整道题零分。第四场景设计题字段类型乱用。成绩用FLOAT、手机号用INT、状态字段用VARCHAR这些都是设计题中的雷区。笔试阅卷人看到这种答案基本可以断定你没有真实项目经验。第五完全不知道国产数据库和新趋势。很多同学复习时只看MySQL和Oracle对达梦、人大金仓、openGauss、Doris这些名词一窍不通。现在校招笔试题越来越贴近企业真实技术栈这个盲区一定要补上。6.2 高效的备考路线与长期积累基于这次笔试的复盘我总结了一套数据库岗的备考路线核心思路是理论实战双线并行。理论方面建议把《高性能MySQL》和《数据库系统概念》作为主参考书前者偏实践、后者偏原理两本配合着看。实战方面建议自己在本地安装MySQL 8.0准备一套样例数据每天练习10道SQL题重点练习窗口函数、多表联查、分组聚合这些高频考点。遇到不清楚的问题一定要动手验证。比如你怀疑某个SQL写法会触发索引失效直接在表里造十万条数据用EXPLAIN看执行计划一下就明白了。纸上谈兵永远记不住只有自己跑过一遍的执行计划才能真正成为你的肌肉记忆。另外平时可以多关注一些数据库技术社区和开源项目了解行业动态。数据库领域不像前端那样日新月异但每年都会有新工具、新特性出来。向量数据库、国产数据库适配、数据库自动运维这些方向正在成为新的面试考点。保持信息渠道畅通笔试的时候遇到陌生概念也不至于完全懵。我个人在复盘这次笔试时还有一个小技巧想分享每道错题不要只记录正确答案而是把错误原因和背后的原理一起写下来。比如联合索引失效这道题旁边备注联合索引(a,b)查询只用b时相当于从通讯录的姓氏索引去查名字自然失效。用这种通俗类比帮助理解复习效率会高出很多。笔试只是第一关后面还有技术面、HR面但把笔试准备扎实了很多面试题其实也顺势准备了。希望这份复盘对你接下来的秋招笔试有帮助。