分享
  1. 首页
  2. 文章

梦彻底醒了

wangzhongyang007 · · 434 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

### 梦彻底醒了 这话是上周一个学生跟我说的,他双非一本大三下,刚结束人生第一次面试,他跟我说自己那点底细在面试官面前根本藏不住 —— **简历上编的项目**,被追问两句就露了馅;**头天晚上临时抱佛脚背的八股文**,面试的时候一句也想不起来。 他说大学三年是真玩爽了,课能逃就逃,时间大多耗在宿舍里打游戏。直到面试官盯着他问 "这项目你到底做没做过",他才反应过来,**那些偷过的懒,迟早要变成拦路的坎**。 现在他暑期实习是指望不上了,目标很明确:**冲秋招**。 其实像他这样的学生我见过不少,总觉得时间还多,混到毕业再说。可职场不看你过去有多 "爽",只看你现在能拿出什么本事。**编的项目经不住推敲,临时背的知识点撑不起面试**,这些都是实实在在的教训。 ### 醒了就不算晚 秋招还有时间,把那些打游戏的功夫用在补八股、做真项目上,比什么都强。别等机会真来了,又只能眼睁睁看着它溜走。 我把他的故事分享出来,也是想给还在迷茫的同学提个醒:**与其在虚拟世界里消磨时光,不如尽早认清现实,脚踏实地提升自己,毕竟为未来努力,什么时候开始都值得**。 >如果你和他有同样的烦恼,欢迎**关注并且私信**我,我替你出谋划策。 ### 一起加油 话都说到这了,文章的剩余部分我就分享一些**数据库和缓存的常见面试题**供大家学习(复习): ### **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的区别? **答案**: | **特性** | **InnoDB** | **MyISAM** | |------------------|-------------------------------------|-----------------------------------| | **事务支持** | 支持(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_memory`、`instantaneous_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-ttl`、`allkeys-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的区别? **答案**: | **特性** | **Redis** | **Memcached** | |------------------|-------------------------------------|-----------------------------------| | **数据结构** | 支持String、List、Hash等复杂结构 | 仅支持Key-Value | | **持久化** | 支持RDB和AOF | 不支持 | | **内存管理** | 自动淘汰(LRU等策略) | 自动淘汰(LRU) | | **分布式** | 原生支持Cluster | 依赖客户端分片 | | **事务** | 支持简单事务(`MULTI`/`EXEC`) | 不支持 | | **适用场景** | 缓存、消息队列、分布式锁等 | 简单Key-Value缓存 | **总结**:Redis功能更全面,适合复杂业务场景;Memcached轻量级,适合高并发简单缓存。 ## 欢迎关注 ❤ 我们搞了一个**免费的面试真题共享群**,互通有无,一起刷题进步。 **没准能让你能刷到自己意向公司的最新面试题呢。** 感兴趣的朋友们可以加我微信:**wangzhongyang1993**,备注:面试群。

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
434 次点击 ∙ 1 赞
1 回复 | 直到 2025年07月07日 12:10:47
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏