现在java面试非常的卷,从jvm、缓存、多线程、分布式、数据库、spring相关、redis、kafka、es等等吧,现在还要求你会AI大模型,微调等等吧
有的在这里问ArrayList和数组的,还有人再问AI大模型微调的,如何运用?真的乱呀!
关系型数据库(RDBMS):基于二维表结构,使用 SQL 管理数据,支持 ACID 事务、外键约束和复杂查询(如 JOIN)。
非关系型数据库(NoSQL):灵活存储(文档、键值对、列族、图等),弱化事务和关系约束,适合高并发、分布式场景。
特性 | InnoDB | MyISAM |
---|---|---|
事务 | 支持(ACID) | 不支持 |
锁粒度 | 行级锁 | 表级锁 |
外键 | 支持 | 不支持 |
崩溃恢复 | Redo Log 保障数据持久性 | 无恢复机制(易损坏) |
适用场景 | 高并发写、事务型业务 | 只读/低频写入的报表 |
B+树结构:
所有数据存储在 叶子节点,形成有序链表,非叶子节点仅存索引键。
支持高效的范围查询(顺序遍历叶子节点)。
InnoDB 选择 B+树的原因:
磁盘友好:非叶子节点不存数据,单次磁盘 I/O 可加载更多索引键。
范围查询高效:叶子节点链表避免 B 树的中序遍历回溯。
特性 | 主键(PRIMARY KEY) | 唯一索引(UNIQUE) |
---|---|---|
唯一性 | 是(不允许 NULL) | 是(允许单个 NULL) |
| 聚簇索引 | 是(数据按主键排序存储) |
数量限制 | 每表仅 1 个 | 可多个 |
特性 | 聚簇索引 | 非聚簇索引 |
---|---|---|
存储结构 | 叶子节点存储完整行数据,表数据即索引 | 叶子节点存储主键值,需回表查询数据 |
索引数量 | 每表仅1个(由主键或隐式ROW_ID定义) | 可创建多个(如普通索引、唯一索引) |
查询机制 | 直接通过索引获取数据(无需回表) | 需两次查询:先查主键值,再回表查数据 |
适用场景 | 主键查询、范围查询(如BETWEEN、ORDER BY) | 非主键列查询(需覆盖索引优化) |
定义:查询所需字段全部包含在索引中,无需会标查询数据页。
设计方法:
规则:复合索引 (a, b, c) 生效场景:
原理:基于哈希表实现,精确匹配O(1)复杂度,不支持范围查询或排序
使用场景:等值查询,如内存表、Redis
InnoDB自适应哈希索引:自动为高频访问的索引页创建哈希索引。
定义:对大文本字段进行关键词搜索
CREATE FULLTEXT INDEX idx_content ON articles(content);
SELECT * FROM articles WHERE MATCH(content) AGAINST('mysql optimization');
INT(10):整型,10 表示显示宽度(非存储范围),存储固定 4 字节(INT)。
VARCHAR(10):可变长度字符串,最大存储 10 字符,存储空间 = 实际长度 + 1~2 字节。
问题:浮点数存在精度丢失(如 0.1 无法精确表示)。
解决方案:使用 DECIMAL 类型存储精确小数。
DECIMAL(10,2) -- 总长度 10 位,小数占 2 位
COUNT(*):统计所有行数(含 NULL),InnoDB 需遍历索引或表。
COUNT(column):统计非 NULL 的行数
,若列无索引可能全表扫描。
优化:MyISAM
表直接返回元数据(极快)。
ZEROFILL:数值显示时左补零(如 INT(5) ZEROFILL,值 12 显示为 00012)。
UNSIGNED:禁止负数,提升数值范围上限(如 TINYINT 范围从 -128~127 变为 0~255)。
ENUM:单选枚举(如 ENUM(‘red’, ‘blue’)),存储为整数索引。
SET:多选集合(如 SET(‘read’, ‘write’)),存储为位掩码。
适用场景:固定选项字段(如状态、权限标识)。
DATETIME 优势:
存储紧凑(8 字节),支持日期计算(如 DATE_ADD)。
自动校验合法性(无效日期插入失败)。
存储:保存为 UTC 时间(4 字节)。
检索:根据会话时区自动转换(可能导致显示时间变化)。
对比:DATETIME 无时区转换(存储和显示值一致)。
推荐字段:CHAR(60)(适合 Bcrypt 哈希)或 CHAR(64)(SHA-256)。
注意事项:禁止明文存储,使用盐值(Salt)增强安全性。
使用场景:动态字段、半结构化数据(如用户属性)。
限制:
索引需通过生成列(Generated Columns)。
更新效率低于传统字段。
区别:BLOB 存储二进制(如图片),TEXT 存储文本(字符集影响)。
设计注意:
大字段分离到副表(避免主表过大)。
避免 SELECT * 查询。
特性 | VARBINARY | VARCHAR |
---|---|---|
存储内容 | 二进制字节(无字符集) | 字符(受字符集影响) |
比较方式 | 按字节值区分大小写 | 根据字符集规则比较 |
适用场景 | 加密数据、文件哈希 | 普通文本 |
MySQL如何保证事务的原子性?UNDO日志的作用?
实现方式
:通过Undo Log实现回滚能力,记录食物修改前的数据镜像,失败时可恢复至原始状态。
MySQL保证原子性:
实现方式:通过Redo Log保证数据持久化。
实现方式:
实现方式:由原子性、持久性、隔离性共同保障,结合数据库约束,确保业务规则有效。
作用:协调分布式事务的提交和会馆,分为Prepare阶段(预提交)和Commit阶段(最终提交)。
定义:跨库事务标准协议,通过全局事务ID协调多资源管理器(如不同的数据库)
实现:
级别 | 问题 | 解决方案 |
---|---|---|
读未提交 | 脏读、不可重复读、幻读 | 无锁,直接读取最新数据 |
读已提交 | 不可重复读、幻读 | MVCC + 行锁 |
可重复读 | 幻读(部分场景) | MVCC + 间隙锁(Next-Key Lock) |
串行化 | 无并发问题 | 表级锁,强制事务串行执行 |
默认隔离级别:InnoDB可重复读.
MVCC机制:
每行数据维护多个版本(通过Undo Log链),根据事务ID判断可见性。
读操作基于 Read View(快照)选择可见的数据版本。
Read View作用:记录活跃事务ID列表,决定哪些数据版本对当前事务可见。
原理:
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默认机制,适用于高并发场景。
表锁:直接锁定整表,开销低但并发性能差,适用于数据量少或低并发场景。
间隙锁:锁定索引记录的间隙,阻止其他事务插入新数据,解决幻读的问题。
临键锁:组合行锁和间隙锁,锁定范围如(5,1],默认用于可重复读的隔离级别,防止范围查询时的幻读。
操作 | 锁类型 | 行为 | 适用场景 |
---|---|---|---|
SELECT … FOR UPDATE | 排他锁(X) | 禁止其他事务读写,保证数据独占。 | 数据修改前的锁定(如账户扣款)。 |
LOCK IN SHARE MODE | 共享锁(S) | 允许其他事务读,禁止写。 | 并发读取一致性(如报表生成)。 |
产生条件:
互斥:资源被独占。
请求与保持:事务持有锁的同时请求新锁。
不可剥夺:锁只能由持有事务释放。
循环等待:事务间形成环形依赖。
解决办法:
超时机制:innodb_lock_wait_timeout(默认50秒)自动释放。
死锁检测:innodb_deadlock_detect=ON自动回滚代价小的事务。
SHOW ENGINE INNODB STATUS;
查看输出中LATEST DETECTED DEADLOCK部分,包含:
死锁事务的SQL语句。
等待资源详情(如锁定的行或间隙)。
事务回滚路径建议。
乐观锁: 基于版本号或时间戳,在提交时检查数据是否被修改。 无锁冲突,适合读多写少场景。
悲观锁: 直接加数据库锁(如行锁、表锁)。 保证强一致性,但并发性能较低
定义:事务因获取锁超时而自动回滚,避免长时间阻塞。
配置参数:
innodb_lock_wait_timeout = 50 -- 默认50秒
作用:协调行锁与表锁共存,避免事务A持有行锁时事务B误加表锁
。
类型:
意向共享锁(IS):声明事务将在行级加S锁。
意向排他锁(IX):声明事务将在行级加X锁。
精准定位数据:索引减少全表扫描,缩小行锁范围(如WHERE条件命中索引)。
避免间隙锁扩大:有序索引减少间隙锁的覆盖范围。
降低锁升级风险:减少因无索引导致的行锁升级为表锁。
EXPLAIN SELECT * FROM users WHERE age > 25 ORDER BY created_at;
字段 | 说明 | 优化重点 |
---|---|---|
type | 访问类型,性能排序:system > const > eq_ref > ref > range > index > ALL47 | 避免ALL(全表扫描),至少达到range |
key | 实际使用的索引,NULL表示未使用索引 | 确保查询命中有效索引 |
rows | 预估扫描行数,值越大性能越差 | 减少扫描行数 |
Extra | 附加信息,如Using filesort(需优化排序)、Using temporary(临时表) | 消除Using filesort/temporary |
添加索引:为高频查询条件字段和排序字段建索引。
覆盖索引:查询字段均在索引中,避免回表(如SELECT id,name FROM users WHERE age=25)。
分区表:按时间或范围分区,减少单次查询数据量。
避免函数操作:如WHERE YEAR(created_at)=2023改为范围查询。
传统分页问题:
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 | IN转换为哈希查询,效率高 |
外表大,子查询结果集大 | 使用EXISTS | EXISTS只需判断是否存在,避免全量遍历 |
操作 | 特点 | 优化建议 |
---|---|---|
UNION | 去重 + 排序 ,性能低 |
仅需去重时使用,避免高频调用 |
UNION ALL | 直接合并结果,无去重和排序,性能高 | 优先使用,除非明确需去重 |
数据传输开销
:返回无用字段增加网络和内存消耗。
无法覆盖索引
:需回表查询完整数据,降低效率。
维护成本
:表结构变更可能导致应用层兼容性问题。
问题:高频更新字段(如status)的索引维护成本高,影响写入性能。
优化:
避免高频更新字段作为索引列。
使用短数据类型(如TINYINT替代VARCHAR)减少存储开销。
联合索引中将低频变更字段放在左侧。
特性 | InnoDB | MyISAM |
---|---|---|
| 读性能 | 支持MVCC机制,读操作无锁且快照一致,但需维护多版本数据,复杂查询略低 |
写性能 | 支持行级锁,高并发写入场景性能更优,但需维护事务日志(Redo/Undo) | 仅支持表级锁,写操作会阻塞其他读写,高并发写入性能差 |
适用场景 | 高并发读写、事务型业务(如订单系统、金融交易) | 读密集型场景(如日志分析、数据仓库) |
核心特点:
数据完全存储在内存中,读写速度极快(微秒级响应)。
服务重启后数据丢失,不支持TEXT/BLOB类型。
典型场景:
临时数据缓存:如用户会话(Session)、排行榜实时数据。
中间计算结果存储:复杂查询的临时结果集。
高速读写测试环境:无持久化需求的性能测试。
核心设计:
高压缩存储:数据压缩率可达90%以上,节省存储空间。
仅支持插入和查询:不支持UPDATE/DELETE操作,适合归档历史数据。
适用场景:
日志归档:如历史订单、操作日志的批量存储。
审计数据存储:仅追加(Append-Only)且无需修改的数据。
ALTER TABLE table_name ENGINE = InnoDB; -- 切换为目标引擎(如InnoDB)
Redo Log(重做日志):
作用:保证事务的持久性(Durability),记录物理页修改。
流程:事务提交时,先将修改写入Redo Log,再异步刷盘到数据文件。
Undo Log(回滚日志):
作用:支持事务回滚和MVCC,记录逻辑操作(如旧版本数据)。
流程:事务修改前生成Undo Log,用于回滚或提供一致性读快照。
协同机制:
事务提交时,Redo Log确保数据持久化,Undo Log保留至事务不再被引用45。
崩溃恢复时,Redo Log重放未刷盘的修改,Undo Log回滚未提交的事务
主库流程:
主库将数据变更(DML/DDL)记录到二进制日志(binlog)中,由Binlog Dump线程负责发送给从库。
事务提交后,异步或半同步模式下主库立即返回客户端,不等待从库确认。
从库流程:
I/O线程:拉取主库binlog并写入中继日志(relay log)。
SQL线程:解析并重放relay log中的事件,更新从库数据。
常见问题
主从延迟:
原因:主库高并发写入、从库单线程重放、网络延迟。
表现:从库查询数据滞后,影响读写分离一致性。
数据不一致:异步复制导致主库宕机时从库丢失部分事务。
特性 | 半同步复制 | 全同步复制 |
---|---|---|
数据一致性 | 主库等待至少一个从库确认收到事务日志。 | 主库等待所有从库执行完事务才返回。 |
性能影响 | 延迟较低,适用于对一致性要求较高的场景。 | 高延迟,仅适合低并发场景。 |
容灾能力 | 容忍部分从库故障,只要一个从库存活即可。 | 任一从库故障会导致主库阻塞 |
优化主库写入:
减少事务大小,避免大事务拆分。
使用SSD提升主库I/O性能。
提升从库处理能力:
启用并行复制(多线程SQL线程)。
从库硬件配置与主库对齐。
业务层规避:
非实时性查询走从库,关键操作强制读主库。
定义:全局事务标识符(Global Transaction Identifier),由server_uuid:事务序列号组成,唯一标识事务。
作用:
简化主从切换:无需依赖binlog文件名和位置。
保证事务唯一性:避免重复执行或遗漏事务
。
启用条件:MySQL 5.6+版本支持,需配置gtid_mode=ON。
主从复制+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段,减少锁竞争。
如何定位和优化慢查询?慢查询日志的配置方法?
定位方法
优化策略
事务机制冲突:InnoDB的MVCC(多版本并发控制)导致同一查询不同事务可能读取不同版本数据,缓存易失效。
高并发写入场景:频繁数据更新使缓存命中率低,维护缓存开销大。
缓冲池(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缓存热点数据,降低数据库压力。
读写分离:通过主从架构将读请求分流到从库。
分库分表:按业务拆分表或库,分散负载。
定义:将大表按规则(如时间、范围)拆分为物理独立的分区,提升查询效率。
适用场景:历史数据归档、按时间范围快速检索[通用知识]。
分区类型:
Range分区:按时间或数值范围划分(如按月分区)[通用知识]。
Hash分区:均匀分散数据,减少热点[通用知识]。
特性 | 表分区 | 数据库分片 |
---|---|---|
数据分布 | 单库内逻辑拆分 | 跨多库或多实例物理拆分 |
扩展性 | 有限,依赖单机资源 | 支持水平扩展,分散负载 |
维护成本 | 低,无需应用层改造 | 高,需处理跨片查询和事务 |
实时状态:
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改为范围查询)。
隐式类型转换(如字符串字段用数字查询)。
DELETE、TRUNCATE和DROP的区别?
维度 | DELETE | TRUNCATE | DROP |
---|---|---|---|
操作类型 | DML(数据操作语言) | DDL(数据定义语言) | DDL(数据定义语言) |
删除范围 | 按条件删除部分或全部数据,保留表结构: | 删除全部数据,重置表结构(如自增列) | 删除表结构及数据,释放存储空间 |
事务支持 | 支持回滚,记录事务日志 | 不支持回滚,不记录事务日志 | 不支持回滚,立即生效 |
性能 | 逐行删除,速度较慢 | 清空数据页,速度快于 DELETE | 直接删除表,速度最快 |
适用场景 | 需保留表结构且有条件删除数据时 | 快速清空全表数据且无需回滚时 | 彻底删除表及数据时 |
操作类型 | 示例语句 |
---|---|
表结构变更 | CREATE TABLE、ALTER TABLE、DROP TABLE |
权限管理 | GRANT、REVOKE |
事务控制 | START TRANSACTION 后执行 DDL |
类型 | 特点 | 示例 |
---|---|---|
标量子查询 | 返回单行单列结果,用于 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) |
核心区别
GROUP BY:对结果集按字段分组,通常与聚合函数(如 SUM、COUNT)联用[通用知识]。
HAVING:过滤分组后的结果,类似 WHERE 但作用于聚合后的数据。
-- 统计每个部门的平均工资,过滤平均工资大于5000的部门
SELECT department, AVG(salary)
FROM employee
GROUP BY department
HAVING AVG(salary) > 5000;
导入优化
批量插入:使用 LOAD DATA INFILE 替代逐行 INSERT^。
关闭约束检查:临时禁用 AUTOCOMMIT、FOREIGN_KEY_CHECKS。
导出优化
分片导出:按条件分批导出数据(如按时间范围)。
压缩传输:使用压缩格式(如 .gz)减少网络开销。
维度 | Redo Log | Binlog |
---|---|---|
定位 | InnoDB 引擎层日志,保证事务持久性 | MySQL Server 层日志,用于主从复制和数据恢复 |
日志类型 | 物理日志(记录数据页修改) | 逻辑日志(记录 SQL 或行变更) |
写入时机 | 事务执行中持续写入(顺序追加) | 事务提交后写入(可异步刷盘) |
崩溃恢复作用 | 恢复未刷盘的脏页 | 数据恢复事务逻辑操作 |
关联事务状态 | 记录所有事务修改(含未提交) | 仅记录已提交事务 |
InnoDB 崩溃恢复流程:
前滚(Redo):通过 Redo Log 重放所有已提交和未提交的事务修改,恢复数据页到崩溃前状态38。
回滚(Undo):利用 Undo Log 回滚未提交事务的修改,保证数据一致性。
核心机制:Redo Log 记录物理修改,Undo Log 记录逆向操作,二者配合实现崩溃恢复。
格式 | 特点 | 适用场景 | 缺点 |
---|---|---|---|
ROW | 记录每行数据的变更(精确) | 主从复制高一致性需求(如金融场景) | 日志量大(如批量更新) |
STATEMENT | 记录 SQL 语句原文(可读性强) | 简单 SQL 场景(日志量小) | 依赖上下文(如 NOW() 导致主从不一致) |
MIXED | 混合模式(自动选择 ROW/STATEMENT) | 通用场景(平衡性能与一致性) | 逻辑判断可能误选格式 |
定位 Binlog 文件:通过 SHOW BINARY LOGS 确定需恢复的日志范围7。
解析日志:使用 mysqlbinlog 工具导出可执行的 SQL 文件(如 mysqlbinlog binlog.000001 > restore.sql)。
执行恢复:将 SQL 文件导入数据库(如 mysql -u root -p < restore.sql)
GTID 机制:
每个事务分配全局唯一标识(GTID)。
从库根据 GTID 顺序重放事务,避免重复执行。
配置步骤:
主从库均启用 GTID(gtid_mode=ON)。
从库设置 MASTER_AUTO_POSITION=1 自动同步主库 GTID 位置。
定义:所有数据修改先写入日志(Redo Log),再异步刷盘到数据文件13。
优势:减少随机 I/O,提升事务提交速度,保证崩溃恢复能力
INCR/DECR
原子操作应对瞬时高并发写入。version
)实现无锁化更新,减少竞争。DECR
原子操作实现快速扣减,配合 Lua 脚本保证原子性:。高并发设计:通过Redis缓存+批量更新优化计数器;消息队列削峰+Redis预扣库存实现秒杀。
分布式系统:TCC/Saga保障事务,Redlock/ZooKeeper实现分布式锁,分库分表配合双写迁移。
数据库管理:冷热数据分层存储,Binlog(ROW格式)+GTID同步数据。
日志与恢复:Redo Log物理回滚未提交事务,Undo Log逆向补偿,WAL提升写入性能。
SQL操作:DELETE支持事务但性能低,TRUNCATE快速清表,DROP彻底删表。
调优手段:慢查询分析索引优化,读写分离中间件提升吞吐,InnoDB集群实现高可用。