梦彻底醒了

梦彻底醒了

这话是上周一个学生跟我说的,他双非一本大三下,刚结束人生第一次面试,他跟我说自己那点底细在面试官面前根本藏不住 —— 简历上编的项目,被追问两句就露了馅;头天晚上临时抱佛脚背的八股文,面试的时候一句也想不起来。

他说大学三年是真玩爽了,课能逃就逃,时间大多耗在宿舍里打游戏。直到面试官盯着他问 “这项目你到底做没做过”,他才反应过来,那些偷过的懒,迟早要变成拦路的坎

现在他暑期实习是指望不上了,目标很明确:冲秋招

其实像他这样的学生我见过不少,总觉得时间还多,混到毕业再说。可职场不看你过去有多 “爽”,只看你现在能拿出什么本事。编的项目经不住推敲,临时背的知识点撑不起面试,这些都是实实在在的教训。

醒了就不算晚

秋招还有时间,把那些打游戏的功夫用在补八股、做真项目上,比什么都强。别等机会真来了,又只能眼睁睁看着它溜走。

我把他的故事分享出来,也是想给还在迷茫的同学提个醒:与其在虚拟世界里消磨时光,不如尽早认清现实,脚踏实地提升自己,毕竟为未来努力,什么时候开始都值得

如果你和他有同样的烦恼,欢迎关注并且私信我,我替你出谋划策。

一起加油

话都说到这了,文章的剩余部分我就分享一些数据库和缓存的常见面试题供大家学习(复习):

MySQL常见面试题

1. 索引的作用是什么?有哪些类型?

答案
索引是一种数据结构,用于快速定位表中的数据,减少I/O操作。其核心作用包括:

  • 加速查询:通过B+树或哈希结构快速定位数据。
  • 减少锁竞争:缩小查询范围,降低锁的粒度。
  • 支持覆盖索引:避免回表查询,直接从索引中获取数据。

常见索引类型包括:

  • B+树索引:适用于范围查询和排序(如WHERE id > 100)。
  • 哈希索引:适用于等值查询(如WHERE name='Alice'),但不支持范围查询。
  • 全文索引:用于文本搜索(如MATCH AGAINST)。
  • 组合索引:多个字段联合索引,遵循最左前缀原则

注意:索引并非越多越好,需避免过度索引导致写入性能下降。

2. 事务的ACID特性是什么?如何实现?

答案
ACID是事务的四大特性:

  • 原子性(Atomicity):事务中的操作要么全部成功,要么全部回滚。
  • 一致性(Consistency):事务执行前后,数据状态保持合法。
  • 隔离性(Isolation):多个事务并发执行时,相互不干扰。
  • 持久性(Durability):事务提交后,数据永久保存。

实现机制

  • 原子性:通过Undo Log实现回滚。
  • 持久性:通过Redo Log实现故障恢复。
  • 隔离性:通过锁机制和MVCC(多版本并发控制)实现。
  • 一致性:由原子性、隔离性和持久性共同保证。

MySQL的事务隔离级别(从低到高):

  • 读未提交(Read Uncommitted):可能出现脏读。
  • 读已提交(Read Committed):避免脏读,但可能出现不可重复读。
  • 可重复读(Repeatable Read):默认级别,避免脏读和不可重复读,但可能出现幻读。
  • 串行化(Serializable):最高级别,通过锁表实现,性能较低。
3. InnoDB和MyISAM的区别?

答案

特性InnoDBMyISAM
事务支持支持(ACID特性)不支持
锁机制行锁(细粒度)表锁(粗粒度)
索引结构B+树,聚簇索引B+树,非聚簇索引
外键支持支持不支持
存储文件.frm(表结构)、.ibd(数据+索引).frm(表结构)、.MYD(数据)、.MYI(索引)
适用场景高并发写入、事务型业务读多写少、非事务场景

总结:InnoDB是MySQL的默认引擎,适合电商、金融等需要事务和高并发的场景;MyISAM已逐渐被淘汰,仅用于历史项目。

4. 数据库锁的类型有哪些?乐观锁和悲观锁的区别?

答案
数据库锁按粒度分为:

  • 表锁:锁整个表,并发性能差(如MyISAM)。
  • 行锁:锁单行数据,并发性能好(如InnoDB)。
  • 页锁:介于表锁和行锁之间。

按操作类型分为:

  • 共享锁(S锁):允许读取,不允许修改。
  • 排他锁(X锁):禁止其他事务加锁。

乐观锁 vs 悲观锁

  • 悲观锁:假设数据冲突频繁,通过SELECT ... FOR UPDATE手动加锁,阻塞其他事务。
  • 乐观锁:假设数据冲突较少,通过版本号(version字段)或CAS(Compare-And-Swap)实现无锁操作。

场景:悲观锁适用于冲突频繁的场景(如秒杀),乐观锁适用于冲突较少的场景(如商品库存更新)。

5. 如何优化慢查询?

答案
优化步骤如下:

  1. 定位慢查询:开启慢查询日志(slow_query_log),使用pt-query-digest分析。
  2. 分析执行计划:通过EXPLAIN查看索引使用情况,检查是否存在全表扫描。
  3. 优化索引
    • 为频繁查询的字段添加索引。
    • 避免索引失效(如避免在索引列使用函数、OR条件)。
    • 使用覆盖索引(索引包含所有查询字段)。
  4. 优化SQL语句
    • 避免SELECT *,只查询必要字段。
    • 减少子查询,使用JOIN替代。
    • 分页优化(如WHERE id > last_id LIMIT 10)。
  5. 硬件与配置
    • 增加内存,提升缓存命中率。
    • 调整InnoDB参数(如innodb_buffer_pool_size)。
  6. 分库分表:数据量过大时,按业务拆分数据库或表。
6. 主从复制的原理是什么?如何解决主从延迟?

答案
主从复制原理

  1. 主库(Master):将更新操作记录到二进制日志(Binlog)。
  2. 从库(Slave):通过I/O线程读取主库的Binlog,写入中继日志(Relay Log)。
  3. 从库:通过SQL线程回放中继日志,实现数据同步。

主从延迟原因

  • 主库写入压力大,从库处理速度慢。
  • 网络延迟或硬件性能差异。

解决方法

  1. 优化主库性能:减少锁竞争,优化SQL语句。
  2. 提升从库硬件:增加CPU、内存或SSD。
  3. 使用并行复制:MySQL 5.7+支持多线程复制,并行回放事务。
  4. 监控延迟:通过SHOW SLAVE STATUS查看Seconds_Behind_Master,设置报警阈值。
7. 分库分表的策略有哪些?如何选择?

答案
分库分表策略分为:

  1. 垂直拆分
    • 垂直分库:按业务模块拆分数据库(如用户库、订单库)。
    • 垂直分表:将大表拆分为主表和扩展表(如用户基本信息表和用户详情表)。
  2. 水平拆分
    • 哈希分片:通过hash(id) % N将数据分散到N个库/表。
    • 范围分片:按时间或数值范围分片(如按年份拆分订单表)。
    • 一致性哈希:减少节点变动时的数据迁移量。

选择策略

  • 垂直拆分:适用于业务模块清晰、数据耦合度低的场景。
  • 水平拆分:适用于数据量极大、单库性能不足的场景。
  • 哈希分片:数据分布均匀,但扩容复杂。
  • 范围分片:适合时间序列数据(如日志),但可能导致热点问题。

注意事项

  • 拆分后需解决分布式事务、跨库Join和分布式ID生成问题。
  • 常用中间件:Sharding-JDBC、Mycat。
8. 数据库范式是什么?为什么需要范式化?

答案
数据库范式是设计数据库表结构的规则,目的是减少数据冗余,提高数据一致性。常见范式包括:

  • 第一范式(1NF):字段原子性,不可再分。
  • 第二范式(2NF):消除非主属性对主键的部分依赖。
  • 第三范式(3NF):消除非主属性对主键的传递依赖。

范式化的优点

  • 减少数据冗余,节省存储空间。
  • 降低数据不一致性风险。
  • 便于维护和更新。

缺点

  • 增加表连接操作,可能影响查询性能。

反范式化
在性能敏感的场景(如报表系统),可适当引入冗余字段,减少Join操作。

9. 如何处理高并发下的写入问题?

答案

  1. 优化索引:避免全表锁,减少锁竞争。
  2. 批量写入:使用INSERT INTO ... VALUES (...),(...)替代逐条插入。
  3. 异步写入:通过消息队列(如Kafka)缓冲写入请求,削峰填谷。
  4. 分库分表:分散写入压力,避免单库瓶颈。
  5. 读写分离:主库负责写入,从库负责读取,分担压力。
  6. 事务优化:减少事务范围,避免长事务。
  7. 使用缓存:对高频写入的数据(如点赞数),先写入缓存,再异步同步到数据库。
  8. 批量提交:InnoDB中设置innodb_flush_log_at_trx_commit=2,降低日志刷盘频率(牺牲部分持久化)。
10. 解释一下MVCC(多版本并发控制)?

答案
MVCC是InnoDB实现可重复读隔离级别的核心机制,通过版本号和Undo Log实现多版本数据共存。其原理如下:

  1. 版本号:每行数据有两个隐藏字段trx_id(事务ID)和roll_ptr(指向Undo Log的指针)。
  2. 读视图(Read View):事务执行时生成一个快照,记录当前活跃事务ID的集合。
  3. 数据可见性
    • 当前事务修改的数据对自身可见。
    • 其他事务修改的数据,根据版本号和读视图判断是否可见。
  4. Undo Log:保存旧版本数据,用于回滚和MVCC读。

优点

  • 读写互不阻塞,提升并发性能。
  • 避免幻读(通过间隙锁和MVCC结合)。

局限性

  • 增加内存和磁盘空间占用(需维护多个版本)。
  • 长时间未提交的事务可能导致Undo Log膨胀。

Redis常见面试题

1. Redis支持哪些数据结构?各自的应用场景?

答案
Redis支持以下数据结构:

  1. String
    • 场景:缓存简单对象(如用户ID对应的Session)、计数器(INCR)。
  2. List
    • 场景:消息队列(LPUSH + BRPOP)、最新消息列表。
  3. Hash
    • 场景:存储对象(如用户信息:hset user:1 name Alice)。
  4. Set
    • 场景:去重(如用户已读消息ID)、交集/并集运算(SINTER/SUNION)。
  5. ZSet(Sorted Set)
    • 场景:排行榜(如按分数排序的用户排名)、带权重的任务队列。
  6. HyperLogLog
    • 场景:基数统计(如日活用户数),内存占用低。
  7. Geospatial
    • 场景:地理位置查询(如附近的POI)。

示例

  • 微博热搜榜:使用ZSet,分数为搜索量。
  • 电商购物车:使用Hash,键为用户ID,字段为商品ID,值为数量。
2. Redis的持久化机制有哪些?RDB和AOF的区别?

答案
Redis支持两种持久化机制:

  1. RDB(Redis Database Snapshot)

    • 原理:定期将内存数据快照保存到磁盘(dump.rdb)。
    • 触发方式:手动执行SAVE/BGSAVE,或配置自动触发(如save 900 1:900秒内至少1次写操作)。
    • 优缺点
      • 优点:恢复速度快,文件体积小。
      • 缺点:可能丢失最后一次快照后的所有数据。
  2. AOF(Append Only File)

    • 原理:将写命令追加到日志文件(appendonly.aof)。
    • 同步策略
      • always:每条命令同步到磁盘(安全,性能低)。
      • everysec:每秒同步一次(默认,平衡安全与性能)。
      • no:由操作系统决定(性能高,风险大)。
    • 优缺点
      • 优点:数据丢失少,支持增量恢复。
      • 缺点:文件体积大,恢复速度慢。

选择建议

  • 同时开启RDB和AOF,RDB用于快速恢复,AOF用于减少数据丢失。
  • 对数据安全性要求极高的场景,使用everysec策略。
3. 缓存穿透、雪崩、击穿是什么?如何解决?

答案

  1. 缓存穿透

    • 定义:查询不存在的数据,导致请求直达数据库。
    • 解决方案
      • 布隆过滤器:提前过滤不存在的Key。
      • 空值缓存:缓存NULL值,设置短过期时间。
  2. 缓存雪崩

    • 定义:大量缓存同时失效,请求瞬间压垮数据库。
    • 解决方案
      • 随机过期时间:为缓存设置随机过期时间(如TTL = 300 + random(60))。
      • 热点数据永不过期:通过后台线程定期更新缓存。
      • 限流降级:使用Hystrix等工具限制流量,返回默认值。
  3. 缓存击穿

    • 定义:热点Key失效瞬间,大量请求直达数据库。
    • 解决方案
      • 互斥锁:使用SET ... NX加锁,确保只有一个线程重建缓存。
      • 逻辑过期:在缓存中存储过期时间,业务线程主动更新缓存。
4. Redis事务的特性?与MySQL事务的区别?

答案
Redis事务特性

  • 原子性:事务中的命令要么全部执行,要么全部失败。
  • 一致性:事务执行前后,数据状态保持一致。
  • 隔离性:事务执行期间,不会被其他事务打断(单线程模型保证)。
  • 不支持持久性:事务执行结果仅保存在内存,需依赖持久化机制。

与MySQL事务的区别

特性Redis事务MySQL事务
原子性命令级原子性(但不支持回滚)事务级原子性(支持回滚)
隔离性单线程执行,无并发问题多线程并发,需锁机制和MVCC
持久性依赖RDB/AOF,不保证持久化强持久化(Redo Log)
使用场景简单批量操作(如INCR + SET复杂事务(如银行转账)

注意:Redis事务中的命令在入队时检查语法错误,执行时不回滚。

5. Redis集群的实现方式?主从复制和哨兵模式的区别?

答案
Redis集群实现方式包括:

  1. 主从复制

    • 原理:一个主节点(Master)负责写,多个从节点(Slave)负责读。
    • 作用:提升读性能和数据冗余。
  2. 哨兵模式(Sentinel)

    • 原理:哨兵节点监控主从节点状态,自动进行故障转移(选举新主节点)。
    • 优点:实现高可用性,无需人工干预。
  3. Redis Cluster

    • 原理:数据分片存储(Sharding),每个节点存储部分数据,支持自动故障转移。
    • 优点:水平扩展,支持海量数据。

主从复制 vs 哨兵模式

  • 主从复制:仅实现数据复制,需手动处理故障。
  • 哨兵模式:在主从复制基础上,增加自动故障转移功能,提升可用性。

选择建议

  • 小规模场景:主从复制 + 手动切换。
  • 中规模场景:哨兵模式。
  • 大规模场景:Redis Cluster。
6. 如何优化Redis的性能?

答案
优化Redis性能的策略包括:

  1. 内存优化

    • 合理设置maxmemory和淘汰策略(如allkeys-lru)。
    • 避免大Key(bigkey),减少内存碎片。
    • 使用MEMORY USAGE监控内存占用。
  2. 网络优化

    • 使用短连接(默认)或长连接(keepalive)。
    • 调整TCP参数(如tcp-backlog)。
  3. 命令优化

    • 使用Pipeline减少网络往返次数。
    • 避免在循环中执行Redis命令。
    • 合理使用MULTI/EXEC事务。
  4. 持久化优化

    • 优先使用RDB,减少AOF日志量。
    • 定期清理AOF日志(BGREWRITEAOF)。
  5. 硬件与配置

    • 使用SSD提升持久化速度。
    • 绑定CPU核心,避免线程上下文切换。
  6. 监控与调优

    • 使用redis-cli info监控指标(如used_memoryinstantaneous_ops_per_sec)。
    • 分析慢查询日志(slowlog get),优化慢命令。
7. 如何处理Redis的内存不足问题?

答案
处理Redis内存不足的步骤如下:

  1. 分析内存使用情况

    • 使用redis-cli --rdb memory分析RDB文件的内存占用。
    • 找出大Key(如redis-cli --bigkeys)。
  2. 优化内存占用

    • 压缩数据(如使用snappy压缩JSON)。
    • 调整数据结构(如用ZSet替代List)。
    • 淘汰过期Key(active-expire-effort参数)。
  3. 调整淘汰策略

    • 根据业务需求选择maxmemory-policy(如volatile-ttlallkeys-lru)。
    • 避免频繁淘汰热点数据。
  4. 扩容

    • 增加节点,采用Redis Cluster分片。
    • 升级硬件,增加内存。
  5. 持久化优化

    • 降低AOF日志同步频率(appendfsync everysec)。
    • 减少RDB快照频率,或改用AOF。
8. 解释一下Redis的管道(Pipeline)和事务的区别?

答案

特性Pipeline事务
命令执行批量发送命令,服务端顺序执行命令入队,通过EXEC原子执行
原子性不保证原子性(可能部分成功)保证原子性(全部成功或失败)
网络开销减少网络往返次数,提升吞吐量单次网络请求,开销低
错误处理错误命令会被忽略执行时发现错误,事务终止
适用场景批量读操作(如MGET复杂写操作(如INCR + SET

示例

  • 批量查询用户信息:使用Pipeline发送多个GET命令。
  • 原子性扣减库存:使用事务MULTI + DECR + SET
9. Redis的过期策略有哪些?内存淘汰策略有哪些?

答案
过期策略

  • 定期删除:每秒随机检查少量Key,删除过期Key。
  • 惰性删除:访问Key时检查是否过期,过期则删除。

内存淘汰策略(通过maxmemory-policy配置):

  1. volatile-ttl:优先淘汰剩余TTL短的Key。
  2. allkeys-lru:淘汰最近最少使用的Key(默认策略)。
  3. allkeys-random:随机淘汰Key。
  4. volatile-lru:在设置了过期时间的Key中淘汰最近最少使用的。
  5. volatile-random:在设置了过期时间的Key中随机淘汰。
  6. noeviction:内存不足时拒绝写入,只读。

选择建议

  • 对时效性要求高的场景:volatile-ttl
  • 通用场景:allkeys-lru
  • 避免内存溢出:不建议使用noeviction
10. Redis和Memcached的区别?

答案

特性RedisMemcached
数据结构支持String、List、Hash等复杂结构仅支持Key-Value
持久化支持RDB和AOF不支持
内存管理自动淘汰(LRU等策略)自动淘汰(LRU)
分布式原生支持Cluster依赖客户端分片
事务支持简单事务(MULTI/EXEC不支持
适用场景缓存、消息队列、分布式锁等简单Key-Value缓存

总结:Redis功能更全面,适合复杂业务场景;Memcached轻量级,适合高并发简单缓存。

欢迎关注 ❤

我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。

没准能让你能刷到自己意向公司的最新面试题呢。

感兴趣的朋友们可以私信我,备注:面试群。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值