java面试题(四),现在都这么卷了,八股文还适用吗?

文章目录

  • 前言
  • 一、基础概念
    • 什么是关系型数据库?与非关系型数据库的主要区别是什么?
    • MySQL的存储引擎有哪些?InnoDB和MyISAM在事务、锁、外键上的区别?‌
    • 什么是B+树索引?为什么InnoDB选择B+树而非B树?
    • 主键和唯一索引的区别是什么?
    • 聚簇索引和非聚簇索引的区别‌
    • 什么是覆盖索引?如何设计覆盖索引?
    • 什么是索引的最左前缀原则?
    • 索引失效的常见场景有哪些?
    • 什么是哈希索引?适用场景是什么?
    • 什么是全文索引?如何创建和使用?
    • INT(10)和VARCHAR(10)的区别是什么?
    • FLOAT和DOUBLE的精度问题如何解决?
    • 为什么COUNT(*)比COUNT(column)慢?
    • 什么是ZEROFILL属性?如何与UNSIGNED配合使用?
    • 什么是ENUM和SET类型?适用场景是什么?
    • 为什么时间字段建议用DATETIME而非字符串?
    • 什么是TIMESTAMP的时区问题?
    • 如何存储密码的哈希值?推荐的字段类型?
    • JSON类型在MySQL中的使用场景和限制?
    • 什么是BLOB和TEXT类型?设计大字段时的注意事项?
    • VARBINARY和VARCHAR的区别?
  • 二、事务与ACID
    • 事务的四大特性(ACID)如何实现?
    • 事务的持久性如何通过REDO日志实现?
    • 事务的隔离性如何实现?
    • 事务的一致性如何实现?
    • 什么是两阶段提交(2PC)?在分布式事务中的作用?
    • 什么是XA协议?如何实现跨库事务?
    • 事务的隔离级别有哪些?默认隔离级别是什么?‌
    • 什么是Read View?在MVCC中的作用?
    • 为什么InnoDB的可重复读(RR)能避免幻读?
  • 三、锁机制
    • 行锁和表锁的实现原理及适用场景?
    • 间隙锁(Gap Lock)和Next-Key锁的作用?
    • SELECT ... FOR UPDATE和LOCK IN SHARE MODE的区别?‌
    • 死锁的产生条件和解决方法?
    • 如何通过SHOW ENGINE INNODB STATUS分析死锁?
    • 乐观锁和悲观锁的实现方式?
    • 什么是锁等待超时?如何配置?
    • 什么是意向锁?与共享锁、排他锁的关系?
    • 为什么索引的合理设计能减少锁竞争?
  • 四、查询优化
    • 如何通过EXPLAIN分析查询执行计划?
    • 索引的类型有哪些?适用场景分别是什么?
    • 如何优化大表查询?避免全表扫描的方法?
    • 超大分页(如LIMIT 1000000)的优化方法?
    • IN和EXISTS的性能对比及使用场景?
    • UNION和UNION ALL的区别及优化选择?‌
    • 为什么SELECT *比指定字段慢?
    • 如何优化频繁更新的字段?
    • 批量插入的优化方法(如LOAD DATA INFILE)?
    • 如何优化多表关联查询(JOIN)的性能?
  • 五、存储引擎
    • InnoDB和MyISAM在读写性能上的差异?
    • Memory存储引擎的适用场景?
    • Archive存储引擎的设计目标?
    • 如何通过ALTER TABLE切换存储引擎?
    • InnoDB的事务日志(Redo/Undo)如何工作?
  • 六、复制与高可用
    • MySQL主从复制的原理和常见问题?
    • 半同步复制和强同步复制的区别?‌
    • 如何处理主从延迟问题?
    • 什么是GTID?在主从复制中的作用?
    • 如何实现MySQL的高可用(HA)方案?
    • 读写分离的实现方式及一致性问题?
    • 分布式事务的实现方式(如基于中间件)?
    • 如何设计分库分表策略(水平/垂直拆分)?
    • 分布式主键的设计方案(如雪花算法)?
  • 七、性能调优
    • 查询缓存为什么在InnoDB中使用较少?
    • 如何通过调整InnoDB参数(如缓冲池、日志大小)提升性能?
    • 热点数据的定义和优化方法?
    • 如何优化高并发场景下的写入性能?
    • 什么是分区表?如何通过分区优化查询?
    • 表分区和数据库分片的区别?
    • 如何监控MySQL的性能(如SHOW STATUS、SHOW PROCESSLIST)?
    • 如何避免全表扫描?索引优化策略?
  • 八、SQL与DML
    • DELETE、TRUNCATE 和 DROP 对比表
    • 事务的隐式提交?哪些语句会隐式提交?
    • 如何优化多表关联时的笛卡尔积问题?
    • 子查询的三种类型(标量子查询、表子查询、exists子查询)?
    • 如何优化复杂子查询?
    • GROUP BY和HAVING的使用场景?
    • 如何优化ORDER BY和GROUP BY?
    • 什么是DISTINCT的优化策略?
    • 如何处理大数据量的导入导出?
    • 如何优化频繁查询的字段?
  • 九、日志与恢复
    • Redo Log和Binlog的区别?
    • 如何通过Redo Log恢复未提交的事务?
    • Binlog的三种格式(ROW、STATEMENT、MIXED)?
    • 如何通过Binlog实现数据恢复?
    • 如何通过GTID实现主从同步?
    • 什么是WAL(预写日志)技术?
    • 如何通过Slow Query Log分析慢查询?
    • 如何通过General Log调试问题?
  • 十、设计模式与最佳实践
    • 高并发计数器设计
    • 支持事务的分布式系统设计
    • 数据库冷热数据分离方案
    • 秒杀库存系统设计
    • 分库分表迁移方案
    • 海量数据搜索引擎设计
    • 高可用 MySQL 集群设计
    • 支持事务的分布式锁设计
    • 水平扩容数据库架构
    • 读写分离中间件设计
  • 总结


前言

现在java面试非常的卷,从jvm、缓存、多线程、分布式、数据库、spring相关、redis、kafka、es等等吧,现在还要求你会AI大模型,微调等等吧
有的在这里问ArrayList和数组的,还有人再问AI大模型微调的,如何运用?真的乱呀!


一、基础概念

什么是关系型数据库?与非关系型数据库的主要区别是什么?

‌关系型数据库(RDBMS)‌:基于二维表结构,使用 ‌SQL‌ 管理数据,支持 ‌ACID 事务‌、外键约束和复杂查询(如 JOIN)。
‌非关系型数据库(NoSQL)‌:灵活存储(文档、键值对、列族、图等),弱化事务和关系约束,适合高并发、分布式场景。

MySQL的存储引擎有哪些?InnoDB和MyISAM在事务、锁、外键上的区别?‌

特性‌ ‌InnoDB‌ ‌MyISAM‌
‌事务‌ 支持(ACID) 不支持
‌锁粒度‌ 行级锁 表级锁
‌外键‌ 支持 不支持
崩溃恢复‌ Redo Log 保障数据持久性 无恢复机制(易损坏)
适用场景‌ 高并发写、事务型业务 只读/低频写入的报表

什么是B+树索引?为什么InnoDB选择B+树而非B树?

‌B+树结构‌
所有数据存储在 叶子节点‌,形成有序链表,非叶子节点仅存索引键。
支持高效的范围查询(顺序遍历叶子节点)。
‌InnoDB 选择 B+树的原因‌:
‌磁盘友好‌:非叶子节点不存数据,单次磁盘 I/O 可加载更多索引键。
‌范围查询高效‌:叶子节点链表避免 B 树的中序遍历回溯。

主键和唯一索引的区别是什么?

‌特性‌ ‌主键(PRIMARY KEY)‌ ‌唯一索引(UNIQUE)‌
‌唯一性‌ 是(不允许 NULL) 是(允许单个 NULL)
聚簇索引‌ 是(数据按主键排序存储)
‌数量限制‌ 每表仅 1 个 可多个

聚簇索引和非聚簇索引的区别‌

特性‌ ‌ ‌聚簇索引‌ ‌‌ 非聚簇索引‌
存储结构‌ 叶子节点存储完整行数据,表数据即索引‌ ‌ 叶子节点存储主键值,需回表查询数据‌
‌索引数量‌ ‌ 每表仅1个(由主键或隐式ROW_ID定义)‌‌ 可创建多个(如普通索引、唯一索引)‌
查询机制‌ ‌ 直接通过索引获取数据(无需回表)‌ ‌ 需两次查询:先查主键值,再回表查数据‌
‌适用场景‌ ‌ 主键查询、范围查询(如BETWEEN、ORDER BY)‌ ‌ 非主键列查询(需覆盖索引优化)‌

什么是覆盖索引?如何设计覆盖索引?

定义:查询所需字段全部包含在索引中,无需会标查询数据页。
设计方法

  • 高频查询的字段加入索引。
  • 避免 SELECT *,减少不必要的字段。

什么是索引的最左前缀原则?

‌规则‌:复合索引 (a, b, c) 生效场景:

  • 查询条件包含最左列(如 WHERE a=1 AND b=2)。
  • 排序或分组依赖最左列(如 ORDER BY a, b)。
    ‌失效场景‌:跳过最左列(如 WHERE b=2)。

索引失效的常见场景有哪些?

  • 隐式类型转换:WHERE str_col = 123(字段为字符串,值用数字)。
  • 函数操作:WHERE UPPER(name)=‘JOHN’。
  • 前导通配符:WHERE name LIKE ‘%abc%’。
  • OR条件:WHERE a = 1 OR b = 2。
  • 数据倾斜:索引列值重复率高。

什么是哈希索引?适用场景是什么?

原理:基于哈希表实现,精确匹配O(1)复杂度,不支持范围查询或排序
使用场景:等值查询,如内存表、Redis
InnoDB自适应哈希索引:自动为高频访问的索引页创建哈希索引。

什么是全文索引?如何创建和使用?

定义:对大文本字段进行关键词搜索

CREATE FULLTEXT INDEX idx_content ON articles(content);
SELECT * FROM articles WHERE MATCH(content) AGAINST('mysql optimization');

INT(10)和VARCHAR(10)的区别是什么?

‌INT(10)‌:整型,10 表示显示宽度(非存储范围),存储固定 4 字节(INT)。
‌VARCHAR(10)‌:可变长度字符串,最大存储 10 字符,存储空间 = 实际长度 + 1~2 字节。

FLOAT和DOUBLE的精度问题如何解决?

‌问题‌:浮点数存在精度丢失(如 0.1 无法精确表示)。
‌解决方案‌:使用 DECIMAL 类型存储精确小数。

DECIMAL(10,2) -- 总长度 10 位,小数占 2 位  

为什么COUNT(*)比COUNT(column)慢?

COUNT(*)‌:统计所有行数(含 NULL),InnoDB 需遍历索引或表。
‌COUNT(column)‌:统计非 NULL 的行数,若列无索引可能全表扫描。
‌优化‌:MyISAM 表直接返回元数据(极快)。

什么是ZEROFILL属性?如何与UNSIGNED配合使用?

‌ZEROFILL‌:数值显示时左补零(如 INT(5) ZEROFILL,值 12 显示为 00012)。
‌UNSIGNED‌:禁止负数,提升数值范围上限(如 TINYINT 范围从 -128~127 变为 0~255)。

什么是ENUM和SET类型?适用场景是什么?

‌ENUM‌:单选枚举(如 ENUM(‘red’, ‘blue’)),存储为整数索引。
‌SET‌:多选集合(如 SET(‘read’, ‘write’)),存储为位掩码。
‌适用场景‌:固定选项字段(如状态、权限标识)。

为什么时间字段建议用DATETIME而非字符串?

‌DATETIME 优势‌:
存储紧凑(8 字节),支持日期计算(如 DATE_ADD)。
自动校验合法性(无效日期插入失败)。

什么是TIMESTAMP的时区问题?

‌存储‌:保存为 UTC 时间(4 字节)。
‌检索‌:根据会话时区自动转换(可能导致显示时间变化)。
‌对比‌:DATETIME 无时区转换(存储和显示值一致)。

如何存储密码的哈希值?推荐的字段类型?

‌推荐字段‌:CHAR(60)(适合 Bcrypt 哈希)或 CHAR(64)(SHA-256)。
‌注意事项‌:禁止明文存储,使用盐值(Salt)增强安全性。

JSON类型在MySQL中的使用场景和限制?

‌使用场景‌:动态字段、半结构化数据(如用户属性)。
‌限制‌:
索引需通过生成列(Generated Columns)。
更新效率低于传统字段。

什么是BLOB和TEXT类型?设计大字段时的注意事项?

‌区别‌:BLOB 存储二进制(如图片),TEXT 存储文本(字符集影响)。
‌设计注意‌:
大字段分离到副表(避免主表过大)。
避免 SELECT * 查询。

VARBINARY和VARCHAR的区别?

特性‌ ‌VARBINARY‌ ‌VARCHAR‌
存储内容‌ 二进制字节(无字符集) 字符(受字符集影响)
比较方式‌ 按字节值区分大小写 根据字符集规则比较
‌适用场景‌ 加密数据、文件哈希 普通文本

二、事务与ACID

事务的四大特性(ACID)如何实现?

MySQL如何保证事务的原子性?UNDO日志的作用?
实现方式:通过Undo Log实现回滚能力,记录食物修改前的数据镜像,失败时可恢复至原始状态。
MySQL保证原子性:

  • 事务执行前生成UndoLog,逻辑记录变更
  • 若食物失败或显式ROLLBACK,基于UndoLog逆向恢复数据。

事务的持久性如何通过REDO日志实现?

实现方式:通过Redo Log保证数据持久化。

  • 事务提交时,先将变更写入Redo Log,再异步刷新值数据文件。
  • 崩溃恢复时,通过Redo Log重放为落盘的操作。

事务的隔离性如何实现?

实现方式:

  • 锁机制:行所、间隙锁防止并发写冲突
  • MVCC:多版本并发控制,通过Undo Log和Read View实现非阻塞读。

事务的一致性如何实现?

实现方式:由原子性、持久性、隔离性共同保障,结合数据库约束,确保业务规则有效。

什么是两阶段提交(2PC)?在分布式事务中的作用?

作用:协调分布式事务的提交和会馆,分为Prepare阶段(预提交)和Commit阶段(最终提交)。

  • Prepare:各参与者锁定资源并反馈就绪状态。
  • Commit:协调者通知所有参与者提交或回滚。

什么是XA协议?如何实现跨库事务?

定义:跨库事务标准协议,通过全局事务ID协调多资源管理器(如不同的数据库)
实现:

  • XA START、XA END、XA PREPARE、XA COMMIT 分阶段控制事务‌6。
  • 需配合支持XA的存储引擎(如InnoDB)‌

事务的隔离级别有哪些?默认隔离级别是什么?‌

级别‌ ‌问题‌ ‌解决方案‌
读未提交‌ 脏读、不可重复读、幻读 无锁,直接读取最新数据
读已提交‌ 不可重复读、幻读 MVCC + 行锁
可重复读‌ 幻读(部分场景) MVCC + 间隙锁(Next-Key Lock)‌
串行化‌ 无并发问题 表级锁,强制事务串行执行

默认隔离级别:InnoDB可重复读.

什么是Read View?在MVCC中的作用?

‌MVCC机制‌
每行数据维护多个版本(通过Undo Log链),根据事务ID判断可见性‌。
读操作基于 ‌Read View‌(快照)选择可见的数据版本‌。
‌Read View作用‌:记录活跃事务ID列表,决定哪些数据版本对当前事务可见‌。

为什么InnoDB的可重复读(RR)能避免幻读?

原理

  • 快照读:通过MVCC的Read View保证同一事务内读取一致性。
  • 当前读:使用间隙锁阻止其他事务插入新数据。

三、锁机制

MySQL的锁类型有哪些?按粒度分有哪些锁?
‌锁类型‌
‌共享锁(S锁)‌:允许多事务并发读,禁止写操作,如LOCK IN SHARE MODE‌。
‌排他锁(X锁)‌:独占数据,禁止其他事务读写,如SELECT … FOR UPDATE‌。
‌意向锁(IS/IX锁)‌:表级锁,声明事务即将在行级加S/X锁,避免与表锁冲突‌。
‌间隙锁(Gap Lock)‌:锁定索引间隙范围,防止幻读‌。
‌临键锁(Next-Key Lock)‌:行锁 + 间隙锁,锁定左开右闭区间‌。
‌记录锁(Record Lock)‌:锁定单行数据‌。
‌按粒度分类‌
‌表级锁‌:
‌表锁‌:锁定整张表,语法如LOCK TABLES … WRITE,MyISAM引擎默认‌。
‌元数据锁(MDL)‌:自动加锁,保护表结构变更‌。
‌行级锁‌:
‌行锁‌:基于索引锁定单行或多行数据‌。
‌间隙锁‌:锁定不存在数据的索引范围‌。

行锁和表锁的实现原理及适用场景?

行锁:基于索引定位行,加S/X锁,InnoDB默认机制,适用于高并发场景。
表锁:直接锁定整表,开销低但并发性能差,适用于数据量少或低并发场景。

间隙锁(Gap Lock)和Next-Key锁的作用?

间隙锁:锁定索引记录的间隙,阻止其他事务插入新数据,解决幻读的问题。
临键锁:组合行锁和间隙锁,锁定范围如(5,1],默认用于可重复读的隔离级别,防止范围查询时的幻读。

SELECT … FOR UPDATE和LOCK IN SHARE MODE的区别?‌

操作‌ ‌锁类型‌ ‌行为‌ ‌适用场景‌
SELECT … FOR UPDATE 排他锁(X) 禁止其他事务读写,保证数据独占‌。 数据修改前的锁定(如账户扣款)‌。
LOCK IN SHARE MODE 共享锁(S) 允许其他事务读,禁止写‌。 并发读取一致性(如报表生成)‌。

死锁的产生条件和解决方法?

产生条件
‌互斥‌:资源被独占‌。
‌请求与保持‌:事务持有锁的同时请求新锁‌。
‌不可剥夺‌:锁只能由持有事务释放‌。
‌循环等待‌:事务间形成环形依赖‌。
解决办法
超时机制‌:innodb_lock_wait_timeout(默认50秒)自动释放‌。
‌死锁检测‌:innodb_deadlock_detect=ON自动回滚代价小的事务‌。

如何通过SHOW ENGINE INNODB STATUS分析死锁?

SHOW ENGINE INNODB STATUS;  

查看输出中LATEST DETECTED DEADLOCK部分,包含:
死锁事务的SQL语句‌。
等待资源详情(如锁定的行或间隙)‌。
事务回滚路径建议‌。

乐观锁和悲观锁的实现方式?

‌乐观锁‌: 基于版本号或时间戳,在提交时检查数据是否被修改‌。 无锁冲突,适合读多写少场景‌。
‌悲观锁‌: 直接加数据库锁(如行锁、表锁)‌。 保证强一致性,但并发性能较低‌

什么是锁等待超时?如何配置?

‌定义‌:事务因获取锁超时而自动回滚,避免长时间阻塞‌。
配置参数:

innodb_lock_wait_timeout = 50  -- 默认50秒  

什么是意向锁?与共享锁、排他锁的关系?

‌作用‌:协调行锁与表锁共存,避免事务A持有行锁时事务B误加表锁‌
‌类型‌:
‌意向共享锁(IS)‌:声明事务将在行级加S锁‌。
‌意向排他锁(IX)‌:声明事务将在行级加X锁‌。

为什么索引的合理设计能减少锁竞争?

‌精准定位数据‌:索引减少全表扫描,缩小行锁范围(如WHERE条件命中索引)‌。
‌避免间隙锁扩大‌:有序索引减少间隙锁的覆盖范围‌。
‌降低锁升级风险‌:减少因无索引导致的行锁升级为表锁‌。

四、查询优化

如何通过EXPLAIN分析查询执行计划?

EXPLAIN SELECT * FROM users WHERE age > 25 ORDER BY created_at;  
‌字段‌ ‌说明‌ ‌优化重点‌
type 访问类型,性能排序:system > const > eq_ref > ref > range > index > ALL‌47 避免ALL(全表扫描),至少达到range
key 实际使用的索引,NULL表示未使用索引‌ 确保查询命中有效索引
rows 预估扫描行数,值越大性能越差‌ 减少扫描行数
Extra 附加信息,如Using filesort(需优化排序)、Using temporary(临时表)‌ 消除Using filesort/temporary

索引的类型有哪些?适用场景分别是什么?

  • 主键索引:唯一性约束字段(如id),默认自动创建‌。
  • 唯一索引:‌需保证字段唯一性(如手机号、邮箱)‌。
  • 普通索引:高频查询条件字段(如username、order_no)‌。
  • 联合索引:多条件查询(如WHERE a=1 AND b=2),遵循最左前缀原则‌。
  • 全文索引:文本内容搜索,如文章关键词。

如何优化大表查询?避免全表扫描的方法?

‌添加索引‌:为高频查询条件字段和排序字段建索引‌。
‌覆盖索引‌:查询字段均在索引中,避免回表(如SELECT id,name FROM users WHERE age=25)‌。
‌分区表‌:按时间或范围分区,减少单次查询数据量‌。
‌避免函数操作‌:如WHERE YEAR(created_at)=2023改为范围查询‌。

超大分页(如LIMIT 1000000)的优化方法?

传统分页问题:

SELECT * FROM users LIMIT 1000000, 10;  -- 需扫描前1000000+10行,性能差‌。

优化方案:
主键分页:

SELECT * FROM users WHERE id > 1000000 ORDER BY id LIMIT 10;  -- 利用有序主键快速定位‌

延迟关联:

SELECT * FROM users JOIN (SELECT id FROM users LIMIT 1000000,10) AS tmp USING(id);  -- 先查ID再回表‌ 

IN和EXISTS的性能对比及使用场景?

‌场景‌ ‌推荐操作‌ ‌说明‌
子查询结果集小‌ 使用IN IN转换为哈希查询,效率高‌
‌外表大,子查询结果集大‌ 使用EXISTS EXISTS只需判断是否存在,避免全量遍历‌

UNION和UNION ALL的区别及优化选择?‌

操作‌ ‌特点‌ ‌优化建议‌
‌UNION‌ 去重 + 排序,性能低 仅需去重时使用,避免高频调用‌
UNION ALL‌ 直接合并结果,无去重和排序,性能高 优先使用,除非明确需去重‌

为什么SELECT *比指定字段慢?

数据传输开销‌:返回无用字段增加网络和内存消耗‌。
无法覆盖索引‌:需回表查询完整数据,降低效率‌。
维护成本‌:表结构变更可能导致应用层兼容性问题‌。

如何优化频繁更新的字段?

‌问题‌:高频更新字段(如status)的索引维护成本高,影响写入性能‌。
‌优化‌:
避免高频更新字段作为索引列。
使用短数据类型(如TINYINT替代VARCHAR)减少存储开销‌。
联合索引中将低频变更字段放在左侧‌。

批量插入的优化方法(如LOAD DATA INFILE)?

  1. LOAD DATA INFILE
    LOAD DATA INFILE ‘data.csv’ INTO TABLE users; – 比逐条INSERT快10倍以上‌
  2. 合并事务
    START TRANSACTION;
    INSERT INTO users VALUES (…), (…), (…); – 单事务批量插入
    COMMIT;
  3. 关闭自动提交。

如何优化多表关联查询(JOIN)的性能?

  • 索引优化‌:确保关联字段(如ON a.id=b.user_id)有索引‌。‌
  • 小表驱动大表‌:优先用数据量小的表作为驱动表‌。
  • 避免复杂JOIN‌:拆分为单表查询或使用冗余字段减少关联次数‌。
  • 使用EXPLAIN分析‌:检查type是否为eq_ref或ref,避免ALL和Using join buffer‌。
    总结:通过合理使用索引、优化查询语句、分析执行计划,结合业务场景选择最佳操作(如EXISTS替代IN),可显著提升MySQL性能,避免全表扫描和锁竞争问题。

五、存储引擎

InnoDB和MyISAM在读写性能上的差异?

特性‌ ‌InnoDB‌ ‌MyISAM‌
读性能‌ 支持MVCC机制,读操作无锁且快照一致,但需维护多版本数据,复杂查询略低‌
‌写性能‌ 支持行级锁,高并发写入场景性能更优,但需维护事务日志(Redo/Undo)‌ 仅支持表级锁,写操作会阻塞其他读写,高并发写入性能差‌
‌适用场景‌ 高并发读写、事务型业务(如订单系统、金融交易)‌ 读密集型场景(如日志分析、数据仓库)‌

Memory存储引擎的适用场景?

‌核心特点‌:
数据完全存储在内存中,读写速度极快(微秒级响应)‌。
服务重启后数据丢失,不支持TEXT/BLOB类型‌。
‌典型场景‌:
‌临时数据缓存‌:如用户会话(Session)、排行榜实时数据‌。
‌中间计算结果存储‌:复杂查询的临时结果集‌。
‌高速读写测试环境‌:无持久化需求的性能测试‌。

Archive存储引擎的设计目标?

‌核心设计‌:
‌高压缩存储‌:数据压缩率可达90%以上,节省存储空间‌。
‌仅支持插入和查询‌:不支持UPDATE/DELETE操作,适合归档历史数据‌。
‌适用场景‌:
‌日志归档‌:如历史订单、操作日志的批量存储‌。
‌审计数据存储‌:仅追加(Append-Only)且无需修改的数据‌。

如何通过ALTER TABLE切换存储引擎?

ALTER TABLE table_name ENGINE = InnoDB;  -- 切换为目标引擎(如InnoDB)  

InnoDB的事务日志(Redo/Undo)如何工作?

‌Redo Log(重做日志)‌
‌作用‌:保证事务的持久性(Durability),记录物理页修改‌。
‌流程‌:事务提交时,先将修改写入Redo Log,再异步刷盘到数据文件‌。
‌Undo Log(回滚日志)‌
‌作用‌:支持事务回滚和MVCC,记录逻辑操作(如旧版本数据)‌。
‌流程‌:事务修改前生成Undo Log,用于回滚或提供一致性读快照‌。
‌协同机制‌
事务提交时,Redo Log确保数据持久化,Undo Log保留至事务不再被引用‌45。
崩溃恢复时,Redo Log重放未刷盘的修改,Undo Log回滚未提交的事务‌

六、复制与高可用

MySQL主从复制的原理和常见问题?

主库流程‌:
主库将数据变更(DML/DDL)记录到二进制日志(binlog)中,由Binlog Dump线程负责发送给从库‌。
事务提交后,异步或半同步模式下主库立即返回客户端,不等待从库确认‌。
‌从库流程‌:
‌I/O线程‌:拉取主库binlog并写入中继日志(relay log)‌。
‌SQL线程‌:解析并重放relay log中的事件,更新从库数据‌。
‌常见问题‌
‌主从延迟‌:
原因:主库高并发写入、从库单线程重放、网络延迟‌。
表现:从库查询数据滞后,影响读写分离一致性‌。
‌数据不一致‌:异步复制导致主库宕机时从库丢失部分事务‌。

半同步复制和强同步复制的区别?‌

特性‌ ‌半同步复制‌ ‌全同步复制‌
数据一致性‌ 主库等待至少一个从库确认收到事务日志‌。 主库等待所有从库执行完事务才返回‌。
‌性能影响‌ 延迟较低,适用于对一致性要求较高的场景‌。 高延迟,仅适合低并发场景‌。
容灾能力‌ 容忍部分从库故障,只要一个从库存活即可‌。 任一从库故障会导致主库阻塞‌

如何处理主从延迟问题?

‌优化主库写入‌
减少事务大小,避免大事务拆分‌。
使用SSD提升主库I/O性能‌。
‌提升从库处理能力‌
启用并行复制(多线程SQL线程)‌。
从库硬件配置与主库对齐‌。
‌业务层规避‌
非实时性查询走从库,关键操作强制读主库‌。

什么是GTID?在主从复制中的作用?

‌定义‌:全局事务标识符(Global Transaction Identifier),由server_uuid:事务序列号组成,唯一标识事务‌。
‌作用‌:
简化主从切换:无需依赖binlog文件名和位置‌。
保证事务唯一性:避免重复执行或遗漏事务‌
‌启用条件‌:MySQL 5.6+版本支持,需配置gtid_mode=ON‌。

如何实现MySQL的高可用(HA)方案?

主从复制+HAProxy/Keepalived‌:
主库故障时,VIP漂移到从库,实现快速切换‌。
‌组复制(MGR)‌:
多主架构,基于Paxos协议保证数据一致性,自动故障转移‌。
‌中间件方案(如ProxySQL)‌:
自动路由读写请求,支持健康检查与负载均衡。

读写分离的实现方式及一致性问题?

实现方式‌
‌中间件代理‌:如ProxySQL、MyCat,配置读写规则。
‌应用层分库分表‌:通过ORM框架(如ShardingSphere)动态切换数据源。
‌一致性问题‌
‌强制读主库‌:关键查询(如余额)直连主库‌。
‌半同步复制‌:确保从库至少有一个节点与主库数据一致‌。
‌延迟监控‌:通过SHOW SLAVE STATUS检查Seconds_Behind_Master,超时则切换读主库‌。

分布式事务的实现方式(如基于中间件)?

‌XA协议‌:基于两阶段提交(2PC),强一致性但性能低。
‌柔性事务‌
‌TCC模式‌:业务层实现Try-Confirm-Cancel[通用知识]。
‌消息队列‌:异步最终一致性(如RocketMQ事务消息)。

如何设计分库分表策略(水平/垂直拆分)?

‌拆分类型‌ ‌适用场景‌ ‌示例‌
‌水平拆分‌ 单表数据量过大(如订单表按用户ID取模)[。 user_id % 64分散到64个库/表[通用知识]。
‌垂直拆分‌ 字段访问频率差异大(如分离用户基础信息与扩展信息)。 用户表拆分为user_base和user_profile[。

分布式主键的设计方案(如雪花算法)?

‌雪花算法(Snowflake)‌
64位结构:时间戳(41位)+节点ID(10位)+序列号(12位)。
优点:全局唯一、趋势递增、无中心化生成。
‌数据库分段‌
使用单独表预生成ID段,减少锁竞争。

七、性能调优

如何定位和优化慢查询?慢查询日志的配置方法?
‌定位方法‌

  1. 开启慢查询日志‌:
    配置slow_query_log=ON,设置long_query_time=1(单位:秒),日志路径指定为slow_query_log_file‌。
    记录未使用索引的查询:log_queries_not_using_indexes=ON‌。
  2. 分析日志工具‌:
    使用mysqldumpslow或pt-query-digest汇总高频慢查询‌。
  3. 执行计划分析‌:
    EXPLAIN查看type(访问类型)、key(使用索引)、rows(扫描行数)‌。
    关注Extra列,如Using filesort(需优化排序)或Using temporary(需避免临时表)‌。
  4. 性能调试工具‌:
    SHOW PROFILE分析查询各阶段耗时,OPTIMIZER_TRACE查看优化器决策过程‌。

‌优化策略‌

  1. 索引优化‌:为WHERE/JOIN/ORDER BY字段添加联合索引,避免冗余索引‌。
  2. SQL重构‌:拆分复杂查询,避免SELECT *,分页改用延迟关联(如SELECT id FROM … LIMIT)‌。
  3. 参数调优‌:增大innodb_buffer_pool_size(缓冲池大小),减少磁盘I/O‌。

查询缓存为什么在InnoDB中使用较少?

‌事务机制冲突‌:InnoDB的MVCC(多版本并发控制)导致同一查询不同事务可能读取不同版本数据,缓存易失效。
‌高并发写入场景‌:频繁数据更新使缓存命中率低,维护缓存开销大。

如何通过调整InnoDB参数(如缓冲池、日志大小)提升性能?

缓冲池(Buffer Pool)‌
设置innodb_buffer_pool_size为物理内存的70%~80%,缓存热点数据页‌。
监控命中率:(1 - Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests) * 100%,目标>95%‌。
日志文件(Redo Log)‌
增大innodb_log_file_size(如1GB以上),减少日志切换频率‌。
高并发写入时设置innodb_flush_log_at_trx_commit=2(仅写入OS缓存,不立即刷盘)‌。

热点数据的定义和优化方法?

‌定义‌:高频访问的少量数据(如热门商品、用户信息)。
优化方法‌
‌缓存层隔离‌:使用Redis缓存热点数据,降低数据库压力。
‌读写分离‌:通过主从架构将读请求分流到从库。
‌分库分表‌:按业务拆分表或库,分散负载。

如何优化高并发场景下的写入性能?

  • 批量插入‌:使用INSERT INTO … VALUES (…), (…)合并写入,减少事务提交次数。
  • 禁用唯一约束检查‌:临时关闭unique_checks和foreign_key_checks提升批量写入速度[。
  • 异步提交‌:设置innodb_flush_log_at_trx_commit=0或2,牺牲部分持久性换取性能‌。

什么是分区表?如何通过分区优化查询?

‌定义‌:将大表按规则(如时间、范围)拆分为物理独立的分区,提升查询效率。
‌适用场景‌:历史数据归档、按时间范围快速检索[通用知识]。
‌分区类型‌
‌Range分区‌:按时间或数值范围划分(如按月分区)[通用知识]。
‌Hash分区‌:均匀分散数据,减少热点[通用知识]。

表分区和数据库分片的区别?

‌特性‌ ‌ 表分区‌ ‌数据库分片‌
‌数据分布‌ 单库内逻辑拆分 跨多库或多实例物理拆分
‌扩展性‌ 有限,依赖单机资源 支持水平扩展,分散负载
‌维护成本‌ 低,无需应用层改造 高,需处理跨片查询和事务

如何监控MySQL的性能(如SHOW STATUS、SHOW PROCESSLIST)?

‌实时状态‌
SHOW PROCESSLIST:查看活跃线程,识别阻塞操作(如State=Waiting for table lock)‌。
SHOW STATUS:监控关键指标(如Slow_queries、Innodb_row_lock_waits)‌。
‌历史趋势‌
使用Performance Schema跟踪资源消耗和锁等待情况。

如何避免全表扫描?索引优化策略?

‌覆盖索引‌:查询字段均在索引中,避免回表(如SELECT name FROM users WHERE age=25)‌。
‌最左前缀原则‌:联合索引(a,b,c)仅支持a、a,b、a,b,c条件查询‌。
避免索引失效‌
不使用函数或表达式(如WHERE YEAR(date)=2023改为范围查询)‌。
隐式类型转换(如字符串字段用数字查询)‌。

八、SQL与DML

DELETE、TRUNCATE和DROP的区别?

DELETE、TRUNCATE 和 DROP 对比表

维度 DELETE TRUNCATE DROP
操作类型 DML(数据操作语言) DDL(数据定义语言)‌ DDL(数据定义语言)‌
删除范围 按条件删除部分或全部数据,保留表结构‌: 删除全部数据,重置表结构(如自增列)‌ 删除表结构及数据,释放存储空间‌
事务支持 支持回滚,记录事务日志‌ 不支持回滚,不记录事务日志‌ 不支持回滚,立即生效‌
性能 逐行删除,速度较慢‌ 清空数据页,速度快于 DELETE‌ 直接删除表,速度最快‌
适用场景 需保留表结构且有条件删除数据时‌ 快速清空全表数据且无需回滚时‌ 彻底删除表及数据时‌

事务的隐式提交?哪些语句会隐式提交?

‌操作类型‌ ‌示例语句‌
表结构变更 CREATE TABLE、ALTER TABLE、DROP TABLE‌
权限管理 GRANT、REVOKE‌
事务控制 START TRANSACTION 后执行 DDL‌

如何优化多表关联时的笛卡尔积问题?

  • 添加关联条件‌:确保 JOIN 语句包含有效关联字段(如 ON user.id = order.user_id)。‌
  • 避免全表扫描‌:为关联字段添加索引,减少扫描范围。
  • 子查询替代‌:将大表拆分为子查询,缩小数据集后再关联。

子查询的三种类型(标量子查询、表子查询、exists子查询)?

‌类型‌ ‌ 特点‌ ‌示例‌
‌标量子查询‌ 返回单行单列结果,用于 SELECT 或 WHERE SELECT (SELECT MAX(price) FROM product)
‌表子查询‌ 返回多行多列结果,作为临时表使用 SELECT * FROM (SELECT id FROM user) AS t
‌EXISTS 子查询‌ 检查是否存在满足条件的记录,返回布尔值 SELECT * FROM order WHERE EXISTS (SELECT 1 FROM user)

如何优化复杂子查询?

  • 改用 JOIN‌:将子查询转换为 JOIN 操作(如 IN 子查询改为 INNER JOIN)。
  • 临时表缓存‌:将子查询结果存储到临时表,减少重复计算。
  • 避免多层嵌套‌:通过业务逻辑拆分多层子查询。

GROUP BY和HAVING的使用场景?

‌核心区别‌
‌GROUP BY‌:对结果集按字段分组,通常与聚合函数(如 SUM、COUNT)联用[通用知识]
‌HAVING‌:过滤分组后的结果,类似 WHERE 但作用于聚合后的数据。

-- 统计每个部门的平均工资,过滤平均工资大于5000的部门
SELECT department, AVG(salary) 
FROM employee 
GROUP BY department 
HAVING AVG(salary) > 5000;

如何优化ORDER BY和GROUP BY?

  • 索引覆盖‌:为 ORDER BY/GROUP BY 字段创建联合索引(如 INDEX (age, salary))。
  • 减少排序字段‌:仅选择必要字段排序或分组,避免全表排序。
  • 调整缓冲区大小‌:增大 sort_buffer_size 参数,提升排序性能。

什么是DISTINCT的优化策略?

  • 避免重复数据源‌:通过业务逻辑去重(如插入时限制唯一性)。
  • 索引覆盖‌:为 DISTINCT 字段添加索引,减少全表扫描。
  • 改用 EXISTS‌:在存在性检查场景,用 EXISTS 替代 DISTINCT。

如何处理大数据量的导入导出?

‌导入优化‌
‌批量插入‌:使用 LOAD DATA INFILE 替代逐行 INSERT^。
‌关闭约束检查‌:临时禁用 AUTOCOMMIT、FOREIGN_KEY_CHECKS。
‌导出优化‌
‌分片导出‌:按条件分批导出数据(如按时间范围)。
‌压缩传输‌:使用压缩格式(如 .gz)减少网络开销。

如何优化频繁查询的字段?

  • 索引覆盖‌:为高频查询字段创建索引(如 INDEX (status))。
  • 缓存层隔离‌:使用 Redis 缓存热点数据(如用户信息)。
  • 冗余字段‌:在关联表中冗余高频字段,避免 JOIN 操作。

九、日志与恢复

Redo Log和Binlog的区别?

‌维度‌ ‌ Redo Log‌ ‌Binlog‌
‌定位‌ InnoDB 引擎层日志,保证事务持久性‌ MySQL Server 层日志,用于主从复制和数据恢复‌
‌日志类型‌ 物理日志(记录数据页修改)‌ 逻辑日志(记录 SQL 或行变更)‌
‌写入时机‌ 事务执行中持续写入(顺序追加)‌ 事务提交后写入(可异步刷盘)‌
‌崩溃恢复作用‌ 恢复未刷盘的脏页 数据‌恢复事务逻辑操作‌
‌关联事务状态‌ 记录所有事务修改(含未提交)‌ 仅记录已提交事务‌

如何通过Redo Log恢复未提交的事务?

InnoDB 崩溃恢复流程
‌前滚(Redo)‌:通过 Redo Log 重放所有已提交和未提交的事务修改,恢复数据页到崩溃前状态‌38。
‌回滚(Undo)‌:利用 Undo Log 回滚未提交事务的修改,保证数据一致性‌。
‌核心机制‌:Redo Log 记录物理修改,Undo Log 记录逆向操作,二者配合实现崩溃恢复‌。

Binlog的三种格式(ROW、STATEMENT、MIXED)?

‌格式‌ ‌ 特点‌ ‌适用场景‌ ‌缺点‌
‌ROW‌ 记录每行数据的变更(精确)‌ 主从复制高一致性需求(如金融场景)‌ 日志量大(如批量更新)‌
‌STATEMENT‌ 记录 SQL 语句原文(可读性强)‌ 简单 SQL 场景(日志量小)‌ 依赖上下文(如 NOW() 导致主从不一致)‌
‌MIXED‌ 混合模式(自动选择 ROW/STATEMENT)‌ 通用场景(平衡性能与一致性)‌ 逻辑判断可能误选格式‌

如何通过Binlog实现数据恢复?

‌定位 Binlog 文件‌:通过 SHOW BINARY LOGS 确定需恢复的日志范围‌7。
‌解析日志‌:使用 mysqlbinlog 工具导出可执行的 SQL 文件(如 mysqlbinlog binlog.000001 > restore.sql)‌。
‌执行恢复‌:将 SQL 文件导入数据库(如 mysql -u root -p < restore.sql)‌

如何通过GTID实现主从同步?

‌GTID 机制‌:
每个事务分配全局唯一标识(GTID)‌。
从库根据 GTID 顺序重放事务,避免重复执行‌。
‌配置步骤‌:
主从库均启用 GTID(gtid_mode=ON)‌。
从库设置 MASTER_AUTO_POSITION=1 自动同步主库 GTID 位置‌。

什么是WAL(预写日志)技术?

‌定义‌:所有数据修改先写入日志(Redo Log),再异步刷盘到数据文件‌13。
‌优势‌:减少随机 I/O,提升事务提交速度,保证崩溃恢复能力‌

如何通过Slow Query Log分析慢查询?

  1. 启用日志‌:
    SET GLOBAL slow_query_log = 1;
    SET GLOBAL long_query_time = 2; – 定义慢查询阈值(秒) ‌
  2. 分析工具‌:
    使用 mysqldumpslow 或 Percona Toolkit 的 pt-query-digest 解析日志。
  3. 优化方向‌:
    添加缺失索引(如 EXPLAIN 分析执行计划)。
    重写复杂查询或拆分大事务。

如何通过General Log调试问题?

  1. 启用日志‌:
    SET GLOBAL general_log = 1; – 记录所有查询(谨慎开启,影响性能)
  2. 日志路径‌:
    默认输出到文件或表(general_log_file 参数指定路径)。
  3. 典型场景‌:
    跟踪特定会话的完整 SQL 执行序列。

十、设计模式与最佳实践

高并发计数器设计

  1. 分层架构
    Redis 缓存层:存储实时计数(如点赞数),通过 INCR/DECR 原子操作应对瞬时高并发写入。
    MySQL 持久层:定时同步 Redis 数据到数据库,确保数据最终一致性。
  2. 并发控制
    乐观锁:利用版本号字段(version)实现无锁化更新,减少竞争。
    分布式锁:通过 Redis 或 Zookeeper 协调多节点写入,避免超卖‌:。
  3. 性能优化
    批量合并更新:将高频单条计数合并为批量操作,降低数据库压力‌:。

支持事务的分布式系统设计

  1. 分布式事务协议
    TCC 模式**(Try-Confirm-Cancel):业务层实现补偿逻辑,适用于复杂业务场景‌。
    Saga 模式:通过事件驱动和异步补偿,保证长事务最终一致性‌}。
  2. 中间件支持
    消息队列**(如 Kafka):解耦服务,异步处理事务分支,配合本地事务表实现可靠消息‌。
  3. 数据一致性
    二阶段提交(2PC):协调者统一管理事务提交/回滚,牺牲部分可用性换取强一致性‌}。

数据库冷热数据分离方案

  1. 数据分类
    热数据:高频访问数据(如最近订单)存储于 SSD 或内存数据库(如 Redis)‌。
    冷数据:历史数据(如6个月前订单)迁移至 HDD 或对象存储(如 S3)‌。
  2. 存储策略
    分区表:按时间范围分区,自动归档过期数据至冷存储‌。
    数据生命周期管理:通过定时任务或触发器实现自动迁移‌。

秒杀库存系统设计

  1. 流量削峰
    令牌桶限流:控制请求进入系统速率,避免瞬时过载‌}。
    异步队列:用户请求先入队,异步处理扣减逻辑‌}。
  2. 库存预扣
    Redis 预扣库存:利用 DECR 原子操作实现快速扣减,配合 Lua 脚本保证原子性‌:。
    数据库最终扣减:异步同步 Redis 预扣结果到 MySQL,确保数据准确‌:。
  3. 防作弊机制
    用户限购:基于用户 ID/IP 限制购买次数‌}。

分库分表迁移方案

  1. 双写阶段
    同时写入新旧库,确保数据一致性‌。
  2. 数据同步
    使用 Binlog 同步工具(如 Canal)增量迁移历史数据‌。
  3. 灰度切换
    按用户 ID 分批次切流,验证新库稳定性后全量切换‌。

海量数据搜索引擎设计

  1. 分布式索引
    Elasticsearch 集群:分片与副本机制实现水平扩展和高可用‌。
  2. 数据分层
    倒排索引+列存储:优化查询性能与存储效率‌。
  3. 近实时更新
    Translog 机制:保证写入过程崩溃后可恢复‌。

高可用 MySQL 集群设计

  1. 主从复制
    GTID 同步:确保主从数据一致性,支持自动故障切换‌。
  2. 中间件层
    ProxySQL 或 MyCat:实现读写分离和故障自动转移‌。
  3. 多活部署
    跨机房同步:通过半同步复制+延迟容忍策略保证异地容灾‌。

支持事务的分布式锁设计

  1. Redis 锁
    Redlock 算法:多节点加锁,结合 TTL 防止死锁‌:。
  2. ZooKeeper 锁
    临时有序节点:通过 Watcher 机制实现锁释放通知‌。
  3. 数据库锁
    悲观锁(SELECT FOR UPDATE):事务内锁定资源,保证强一致性‌:。

水平扩容数据库架构

  1. 分片策略
    Hash 分片:按主键 Hash 值均匀分布数据。
    范围分片:按时间或 ID 范围分片,便于冷热分离‌。
  2. 弹性伸缩
    在线分片拆分:通过中间件动态调整分片数量‌。

读写分离中间件设计

  1. 路由策略
    权重分配:按负载情况动态分配读请求到多个从库‌。
  2. 故障处理
    心跳检测:自动剔除不可用节点,保障服务可用性‌。
  3. 连接池管理
    多路复用:减少连接创建开销,提升吞吐量。

总结

‌高并发设计‌:通过Redis缓存+批量更新优化计数器;消息队列削峰+Redis预扣库存实现秒杀。
‌分布式系统‌:TCC/Saga保障事务,Redlock/ZooKeeper实现分布式锁,分库分表配合双写迁移。
‌数据库管理‌:冷热数据分层存储,Binlog(ROW格式)+GTID同步数据。
‌日志与恢复‌:Redo Log物理回滚未提交事务,Undo Log逆向补偿,WAL提升写入性能。
‌SQL操作‌:DELETE支持事务但性能低,TRUNCATE快速清表,DROP彻底删表。
‌调优手段‌:慢查询分析索引优化,读写分离中间件提升吞吐,InnoDB集群实现高可用。

你可能感兴趣的:(java面试题,java,开发语言)