模型服务连接失败

猿辅导 / 未知岗位 / 4.1

系统设计JavaKafka消息队列MySQL网络Redis
来源标题
猿辅导
题目数
18
已沉淀
0
来源类型
interview_experience
更新时间
2026/04/01 19:49

面经摘要

记录了项目介绍、Redis、Kafka、网络、JVM、数据库与算法相关面试题。

关联题目(18)

面经原题待沉淀分布式系统
使用 Redis 和 Kafka 的原因是什么?
并发系统设计Kafka消息队列MySQLRedis
Redis 和 Kafka 通常分别解决不同层面的问题,组合使用是为了同时满足低延迟读写、削峰解耦和高可用扩展等需求。 如果放在账户系统这类业务里,使用 Redis 的原因通常有: 1. 访问速度快,适合缓存热点数据,降低数据库压力。 2. 支持丰富的数据结构,便于做计数、状态缓存、排行榜、分布式锁等场景。 3. 可以提升系统吞吐量和响应时间,尤其适合高并发读多写少或短期状态存储的场景。 4. 具备过期机制,适合存放临时数据、验证码、会话信息等。 使用 Kafka 的原因通常有: 1. 作为消息队列实现系统解耦,生产者和消费者可以独立扩缩容。 2. 能削峰填谷,把瞬时高并发请求转化为后续异步处理,保护下游系统和数据库。 3. 吞吐量高,适合日志、埋点、异步通知、事件驱动等大数据量场景。 4. 具备持久化和消费位点管理能力,便于失败重试、故障恢复和保证消息处理流程可追踪。 两者一起使用时,常见模式是:前台请求先写核心链路,非核心操作通过 Kafka 异步化;热点数据或中间状态放 Redis,加快读取并减轻数据库压力。这样系统的性能、可扩展性和稳定性都会更好。
查看原文 QA
Question 1: 使用 Redis 和 Kafka 的原因是什么? Answer: Redis 和 Kafka 通常分别解决不同层面的问题,组合使用是为了同时满足低延迟读写、削峰解耦和高可用扩展等需求。 如果放在账户系统这类业务里,使用 Redis 的原因通常有: 1. 访问速度快,适合缓存热点数据,降低数据库压力。 2. 支持丰富的数据结构,便于做计数、状态缓存、排行榜、分布式锁等场景。 3. 可以提升系统吞吐量和响应时间,尤其适合高并发读多写少或短期状态存储的场景。 4. 具备过期机制,适合存放临时数据、验证码、会话信息等。 使用 Kafka 的原因通常有: 1. 作为消息队列实现系统解耦,生产者和消费者可以独立扩缩容。 2. 能削峰填谷,把瞬时高并发请求转化为后续异步处理,保护下游系统和数据库。 3. 吞吐量高,适合日志、埋点、异步通知、事件驱动等大数据量场景。 4. 具备持久化和消费位点管理能力,便于失败重试、故障恢复和保证消息处理流程可追踪。 两者一起使用时,常见模式是:前台请求先写核心链路,非核心操作通过 Kafka 异步化;热点数据或中间状态放 Redis,加快读取并减轻数据库压力。这样系统的性能、可扩展性和稳定性都会更好。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统Kafka消息队列
查看题库题
面经原题待沉淀数据库
Redis Zset 的底层结构是什么?
系统设计Redis
Redis 的 Zset(有序集合)底层并不是固定单一结构,而是根据数据规模采用不同实现: 1. 在元素数量较少、元素和成员长度较小时,使用压缩存储结构。旧版本常见是 ziplist,新版本主要是 listpack。 2. 当数据量或元素大小超过阈值后,会转为“哈希表 + 跳表”的组合结构。 其中: - 哈希表用于根据 member 快速找到对应的 score,时间复杂度接近 O(1)。 - 跳表用于按 score 有序存储数据,支持范围查询、排序、获取排名等操作,时间复杂度一般是 O(logN)。 之所以这样设计,是因为 Zset 既要支持按成员快速查找,也要支持按分值排序和范围操作,单独用一种结构很难同时兼顾这两类需求。
查看原文 QA
Question 2: Redis Zset 的底层结构是什么? Answer: Redis 的 Zset(有序集合)底层并不是固定单一结构,而是根据数据规模采用不同实现: 1. 在元素数量较少、元素和成员长度较小时,使用压缩存储结构。旧版本常见是 ziplist,新版本主要是 listpack。 2. 当数据量或元素大小超过阈值后,会转为“哈希表 + 跳表”的组合结构。 其中: - 哈希表用于根据 member 快速找到对应的 score,时间复杂度接近 O(1)。 - 跳表用于按 score 有序存储数据,支持范围查询、排序、获取排名等操作,时间复杂度一般是 O(logN)。 之所以这样设计,是因为 Zset 既要支持按成员快速查找,也要支持按分值排序和范围操作,单独用一种结构很难同时兼顾这两类需求。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统系统设计MySQLRedis
查看题库题
面经原题待沉淀数据库
跳表的原理是什么?
系统设计Redis
跳表本质上是在有序链表的基础上增加多层索引,使查找时可以“跳着走”,从而把平均查找效率提升到 O(logN)。 它的核心原理是: 1. 最底层是一个完整的有序链表,保存所有元素。 2. 在上层为部分节点建立索引,越高层节点越稀疏。 3. 查找时从最高层开始,先横向移动;如果下一个节点仍然小于目标值就继续走,否则向下一层。 4. 最终在底层定位到目标节点。 插入时: - 先在底层链表中找到插入位置。 - 然后通过随机策略决定该节点要提升到几层。 - 再把该节点插入对应层级的索引链表中。 删除时: - 需要把该节点在各层中的索引都删掉。 跳表的优点: 1. 实现相对比平衡树简单。 2. 插入、删除、查找平均复杂度都是 O(logN)。 3. 天然适合范围查询和有序遍历。 缺点是: - 需要额外索引层,空间开销比普通链表大。 - 最坏情况下复杂度可退化,但通过随机层高设计,实际表现通常比较稳定。
查看原文 QA
Question 3: 跳表的原理是什么? Answer: 跳表本质上是在有序链表的基础上增加多层索引,使查找时可以“跳着走”,从而把平均查找效率提升到 O(logN)。 它的核心原理是: 1. 最底层是一个完整的有序链表,保存所有元素。 2. 在上层为部分节点建立索引,越高层节点越稀疏。 3. 查找时从最高层开始,先横向移动;如果下一个节点仍然小于目标值就继续走,否则向下一层。 4. 最终在底层定位到目标节点。 插入时: - 先在底层链表中找到插入位置。 - 然后通过随机策略决定该节点要提升到几层。 - 再把该节点插入对应层级的索引链表中。 删除时: - 需要把该节点在各层中的索引都删掉。 跳表的优点: 1. 实现相对比平衡树简单。 2. 插入、删除、查找平均复杂度都是 O(logN)。 3. 天然适合范围查询和有序遍历。 缺点是: - 需要额外索引层,空间开销比普通链表大。 - 最坏情况下复杂度可退化,但通过随机层高设计,实际表现通常比较稳定。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统系统设计MySQLRedis
查看题库题
面经原题待沉淀数据库
为什么不用 B+ 树实现 Redis Zset,而用跳表?
并发MySQLRedis
Redis Zset 选择跳表而不是 B+ 树,主要是工程实现和使用场景上的权衡。 1. Redis 是内存数据库,磁盘页局部性不是主要矛盾。 B+ 树最明显的优势是在磁盘或页式存储中减少随机 I/O,因为它的多叉结构能降低树高。但 Redis 主要在内存中操作,访问成本主要不是磁盘 I/O,所以 B+ 树的核心优势没有那么突出。 2. 跳表实现更简单。 跳表基于多层链表,实现插入、删除、查找都比较直观;而 B+ 树在节点分裂、合并、平衡维护上实现复杂度更高。对于 Redis 这种强调高性能和代码可维护性的系统,跳表是更合适的选择。 3. 跳表范围查询和有序遍历也很高效。 Zset 很常见的操作是按 score 排序、范围查询、分页获取。跳表天然支持顺序遍历,做范围查询比较方便。 4. 跳表在并发和局部修改上的思维模型更直接。 虽然 Redis 本身主要是单线程执行命令,但从数据结构维护角度看,跳表在插入删除时只影响局部指针,逻辑清晰。 5. 综合性能足够。 跳表的查找、插入、删除平均都是 O(logN),对 Zset 的典型业务场景已经足够好,没有必要为了理论上的树形结构优势引入更高复杂度。 所以总结来说:B+ 树更适合磁盘/页存储场景,而 Redis Zset 是以内存有序集合操作为主,跳表能以更低实现复杂度提供足够优秀的性能和范围查询能力,因此更合适。
查看原文 QA
Question 4: 为什么不用 B+ 树实现 Redis Zset,而用跳表? Answer: Redis Zset 选择跳表而不是 B+ 树,主要是工程实现和使用场景上的权衡。 1. Redis 是内存数据库,磁盘页局部性不是主要矛盾。 B+ 树最明显的优势是在磁盘或页式存储中减少随机 I/O,因为它的多叉结构能降低树高。但 Redis 主要在内存中操作,访问成本主要不是磁盘 I/O,所以 B+ 树的核心优势没有那么突出。 2. 跳表实现更简单。 跳表基于多层链表,实现插入、删除、查找都比较直观;而 B+ 树在节点分裂、合并、平衡维护上实现复杂度更高。对于 Redis 这种强调高性能和代码可维护性的系统,跳表是更合适的选择。 3. 跳表范围查询和有序遍历也很高效。 Zset 很常见的操作是按 score 排序、范围查询、分页获取。跳表天然支持顺序遍历,做范围查询比较方便。 4. 跳表在并发和局部修改上的思维模型更直接。 虽然 Redis 本身主要是单线程执行命令,但从数据结构维护角度看,跳表在插入删除时只影响局部指针,逻辑清晰。 5. 综合性能足够。 跳表的查找、插入、删除平均都是 O(logN),对 Zset 的典型业务场景已经足够好,没有必要为了理论上的树形结构优势引入更高复杂度。 所以总结来说:B+ 树更适合磁盘/页存储场景,而 Redis Zset 是以内存有序集合操作为主,跳表能以更低实现复杂度提供足够优秀的性能和范围查询能力,因此更合适。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统系统设计MySQLRedis
查看题库题
面经原题待沉淀数据库
Redis String 的底层结构是什么?
Redis
Redis String 的底层实现是 SDS,也就是 Simple Dynamic String,而不是传统的 C 字符串。 SDS 的特点主要有: 1. 显式记录字符串长度,所以获取长度是 O(1),不像 C 字符串那样要遍历到 '\0'。 2. 二进制安全,不依赖字符串结束符,因此不仅能存文本,也能存图片、序列化数据等二进制内容。 3. 减少缓冲区溢出风险。SDS 在拼接和修改时会先检查空间是否足够,不够就自动扩容。 4. 具备空间预分配和惰性空间释放机制,减少频繁内存分配带来的开销。 补充一点,从 Redis 对象编码角度看,String 对象还可能根据存储内容表现为不同编码方式,比如整数值时可用 int 编码,普通字符串可用 raw 或 embstr 编码;但它们本质上仍然服务于 String 类型对象的底层表示。
查看原文 QA
Question 5: Redis String 的底层结构是什么? Answer: Redis String 的底层实现是 SDS,也就是 Simple Dynamic String,而不是传统的 C 字符串。 SDS 的特点主要有: 1. 显式记录字符串长度,所以获取长度是 O(1),不像 C 字符串那样要遍历到 '\0'。 2. 二进制安全,不依赖字符串结束符,因此不仅能存文本,也能存图片、序列化数据等二进制内容。 3. 减少缓冲区溢出风险。SDS 在拼接和修改时会先检查空间是否足够,不够就自动扩容。 4. 具备空间预分配和惰性空间释放机制,减少频繁内存分配带来的开销。 补充一点,从 Redis 对象编码角度看,String 对象还可能根据存储内容表现为不同编码方式,比如整数值时可用 int 编码,普通字符串可用 raw 或 embstr 编码;但它们本质上仍然服务于 String 类型对象的底层表示。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统系统设计MySQLRedis
查看题库题
面经原题待沉淀分布式系统
Redis 分布式锁如何做延期?
并发网络Redis
Redis 分布式锁做延期,核心是给锁“续期”,避免业务执行时间超过锁的过期时间导致锁被提前释放。 常见做法是: 1. 加锁时使用 SET key value NX PX expireTime,一次性完成加锁和设置过期时间。 2. value 不能是固定值,通常是客户端唯一标识,比如 UUID + 线程信息,用来保证只有持有锁的线程才能释放或续期。 3. 启动一个后台续期机制,在锁即将过期前判断锁是否仍属于自己,如果是,就延长过期时间。 4. 释放锁时通过 Lua 脚本先校验 value 是否匹配,再删除 key,保证原子性,避免误删别人的锁。 续期一般有两种实现思路: - 定时任务/守护线程:每隔一段时间检查锁是否还属于当前线程,如果属于就执行 PEXPIRE 续期。 - 看门狗机制:比如 Redisson 的 watchdog,会在业务线程未完成时自动续期,直到线程释放锁或进程挂掉。 要注意的问题: 1. 续期必须先校验锁归属,不能直接延长,否则可能给别人的锁续命。 2. 续期间隔不能太长,一般在过期时间的三分之一左右触发比较稳妥。 3. 如果服务进程宕机,续期线程也会停止,锁会在 TTL 到期后自动释放,避免死锁。 4. 如果业务对强一致性要求很高,还要考虑主从切换、网络分区等问题,单 Redis 锁并不能解决所有分布式一致性问题。 面试里可以总结为:Redis 分布式锁延期就是通过守护线程或看门狗,在锁快过期时校验锁仍归当前持有者,再原子地延长过期时间。
查看原文 QA
Question 6: Redis 分布式锁如何做延期? Answer: Redis 分布式锁做延期,核心是给锁“续期”,避免业务执行时间超过锁的过期时间导致锁被提前释放。 常见做法是: 1. 加锁时使用 SET key value NX PX expireTime,一次性完成加锁和设置过期时间。 2. value 不能是固定值,通常是客户端唯一标识,比如 UUID + 线程信息,用来保证只有持有锁的线程才能释放或续期。 3. 启动一个后台续期机制,在锁即将过期前判断锁是否仍属于自己,如果是,就延长过期时间。 4. 释放锁时通过 Lua 脚本先校验 value 是否匹配,再删除 key,保证原子性,避免误删别人的锁。 续期一般有两种实现思路: - 定时任务/守护线程:每隔一段时间检查锁是否还属于当前线程,如果属于就执行 PEXPIRE 续期。 - 看门狗机制:比如 Redisson 的 watchdog,会在业务线程未完成时自动续期,直到线程释放锁或进程挂掉。 要注意的问题: 1. 续期必须先校验锁归属,不能直接延长,否则可能给别人的锁续命。 2. 续期间隔不能太长,一般在过期时间的三分之一左右触发比较稳妥。 3. 如果服务进程宕机,续期线程也会停止,锁会在 TTL 到期后自动释放,避免死锁。 4. 如果业务对强一致性要求很高,还要考虑主从切换、网络分区等问题,单 Redis 锁并不能解决所有分布式一致性问题。 面试里可以总结为:Redis 分布式锁延期就是通过守护线程或看门狗,在锁快过期时校验锁仍归当前持有者,再原子地延长过期时间。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统并发Redis
查看题库题
面经原题待沉淀数据库
Redis 的过期方法有哪些?
并发Redis
Redis 的过期删除机制主要有三种: 1. 定时删除 在设置过期键时,同时创建定时器,到时间立即删除。 优点是内存释放及时;缺点是如果过期键很多,会带来较大的 CPU 开销,所以 Redis 并没有主要采用这种方式。 2. 惰性删除 只有当客户端访问某个 key 时,Redis 才检查它是否过期;如果过期再删除。 优点是对 CPU 友好;缺点是如果很多过期键一直不访问,会持续占用内存。 3. 定期删除 Redis 会周期性随机抽取一部分设置了过期时间的 key,检查并删除其中已过期的 key。 这样是在 CPU 和内存之间做折中。 Redis 实际采用的是“惰性删除 + 定期删除”结合的方式,而不是单独依赖某一种策略。 另外,如果内存不足触发淘汰,还会结合内存淘汰策略,比如 volatile-lru、allkeys-lru、volatile-ttl 等,但这属于内存淘汰机制,不完全等同于过期删除机制。
查看原文 QA
Question 7: Redis 的过期方法有哪些? Answer: Redis 的过期删除机制主要有三种: 1. 定时删除 在设置过期键时,同时创建定时器,到时间立即删除。 优点是内存释放及时;缺点是如果过期键很多,会带来较大的 CPU 开销,所以 Redis 并没有主要采用这种方式。 2. 惰性删除 只有当客户端访问某个 key 时,Redis 才检查它是否过期;如果过期再删除。 优点是对 CPU 友好;缺点是如果很多过期键一直不访问,会持续占用内存。 3. 定期删除 Redis 会周期性随机抽取一部分设置了过期时间的 key,检查并删除其中已过期的 key。 这样是在 CPU 和内存之间做折中。 Redis 实际采用的是“惰性删除 + 定期删除”结合的方式,而不是单独依赖某一种策略。 另外,如果内存不足触发淘汰,还会结合内存淘汰策略,比如 volatile-lru、allkeys-lru、volatile-ttl 等,但这属于内存淘汰机制,不完全等同于过期删除机制。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统并发Redis
查看题库题
面经原题待沉淀分布式系统
Redis 集群、主从等架构各有什么优缺点?
并发系统设计Redis
Redis 常见架构可以从单机、主从、哨兵、Cluster 这几个层次来回答。 1. 单机架构 优点: - 部署简单。 - 没有复制和路由开销,性能高。 缺点: - 单点故障明显。 - 容量和吞吐都受单机限制。 - 不适合生产高可用场景。 2. 主从架构 优点: - 主库写、从库读,可以分担读压力。 - 数据有副本,可靠性比单机更好。 - 架构相对简单。 缺点: - 主节点仍然是单点,主挂了需要人工切换或借助其他机制。 - 主从复制是异步的,可能存在数据延迟或少量数据丢失。 - 写能力仍受主节点限制。 3. 哨兵架构 优点: - 在主从基础上增加监控、自动故障转移、主节点发现。 - 提升高可用能力。 - 对业务侧接入相对友好。 缺点: - 本质上还是主从模型,写扩展能力有限。 - 故障切换期间可能有短暂不可用。 - 仍可能存在复制延迟和切换导致的数据一致性问题。 4. Redis Cluster 架构 优点: - 数据按槽位分片,支持水平扩容。 - 既解决高可用问题,也提升整体容量和并发能力。 - 节点间自动维护部分集群状态。 缺点: - 架构更复杂,运维和排障难度更高。 - 跨槽操作受限制,多 key 操作、事务、Lua 脚本等有使用约束。 - 数据迁移和热点 key 问题需要特别关注。 总结: - 如果只是简单使用,可以从单机或主从开始。 - 如果重点是高可用,常用主从 + 哨兵。 - 如果既要高可用又要水平扩展,通常选 Redis Cluster。
查看原文 QA
Question 8: Redis 集群、主从等架构各有什么优缺点? Answer: Redis 常见架构可以从单机、主从、哨兵、Cluster 这几个层次来回答。 1. 单机架构 优点: - 部署简单。 - 没有复制和路由开销,性能高。 缺点: - 单点故障明显。 - 容量和吞吐都受单机限制。 - 不适合生产高可用场景。 2. 主从架构 优点: - 主库写、从库读,可以分担读压力。 - 数据有副本,可靠性比单机更好。 - 架构相对简单。 缺点: - 主节点仍然是单点,主挂了需要人工切换或借助其他机制。 - 主从复制是异步的,可能存在数据延迟或少量数据丢失。 - 写能力仍受主节点限制。 3. 哨兵架构 优点: - 在主从基础上增加监控、自动故障转移、主节点发现。 - 提升高可用能力。 - 对业务侧接入相对友好。 缺点: - 本质上还是主从模型,写扩展能力有限。 - 故障切换期间可能有短暂不可用。 - 仍可能存在复制延迟和切换导致的数据一致性问题。 4. Redis Cluster 架构 优点: - 数据按槽位分片,支持水平扩容。 - 既解决高可用问题,也提升整体容量和并发能力。 - 节点间自动维护部分集群状态。 缺点: - 架构更复杂,运维和排障难度更高。 - 跨槽操作受限制,多 key 操作、事务、Lua 脚本等有使用约束。 - 数据迁移和热点 key 问题需要特别关注。 总结: - 如果只是简单使用,可以从单机或主从开始。 - 如果重点是高可用,常用主从 + 哨兵。 - 如果既要高可用又要水平扩展,通常选 Redis Cluster。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统并发系统设计
查看题库题
面经原题待沉淀分布式系统
Redis 跨槽位问题是什么,怎么解决?
系统设计Redis
Redis Cluster 把数据分布到 16384 个槽位上,key 会根据 CRC16 计算后映射到某个槽。所谓跨槽位问题,就是一次操作涉及多个 key,而这些 key 不在同一个槽位,导致 Redis Cluster 无法直接执行该操作。 常见受影响的场景有: - 多 key 操作,如 MGET、MSET、SUNION 等。 - 事务操作。 - Lua 脚本中同时访问多个 key。 为什么会有限制: 因为不同槽位可能分布在不同节点上,而 Redis Cluster 不支持把一个多 key 命令拆成分布式事务去执行,所以要求相关 key 必须落在同一槽。 解决方式主要有: 1. 使用 hash tag。 例如把 key 设计为 user:{123}:info 和 user:{123}:order,Redis 在计算槽位时只取大括号中的内容,这样这两个 key 会落到同一槽位。 这是最常见、最推荐的方案。 2. 调整业务模型。 避免强依赖多 key 原子操作,把逻辑拆开,减少跨 key 事务需求。 3. 把强关联数据合并存储。 如果几个 key 总是要一起操作,可以考虑合并到一个 key 的复合结构中,比如 Hash。 4. 客户端侧聚合。 对于不要求原子性的场景,可以分别读取不同节点的数据,再在应用层合并结果。 总结来说,Redis 跨槽位的本质是 Cluster 分片后多 key 操作必须同槽,最典型的解决方法是通过 hash tag 让相关 key 路由到同一个槽位。
查看原文 QA
Question 9: Redis 跨槽位问题是什么,怎么解决? Answer: Redis Cluster 把数据分布到 16384 个槽位上,key 会根据 CRC16 计算后映射到某个槽。所谓跨槽位问题,就是一次操作涉及多个 key,而这些 key 不在同一个槽位,导致 Redis Cluster 无法直接执行该操作。 常见受影响的场景有: - 多 key 操作,如 MGET、MSET、SUNION 等。 - 事务操作。 - Lua 脚本中同时访问多个 key。 为什么会有限制: 因为不同槽位可能分布在不同节点上,而 Redis Cluster 不支持把一个多 key 命令拆成分布式事务去执行,所以要求相关 key 必须落在同一槽。 解决方式主要有: 1. 使用 hash tag。 例如把 key 设计为 user:{123}:info 和 user:{123}:order,Redis 在计算槽位时只取大括号中的内容,这样这两个 key 会落到同一槽位。 这是最常见、最推荐的方案。 2. 调整业务模型。 避免强依赖多 key 原子操作,把逻辑拆开,减少跨 key 事务需求。 3. 把强关联数据合并存储。 如果几个 key 总是要一起操作,可以考虑合并到一个 key 的复合结构中,比如 Hash。 4. 客户端侧聚合。 对于不要求原子性的场景,可以分别读取不同节点的数据,再在应用层合并结果。 总结来说,Redis 跨槽位的本质是 Cluster 分片后多 key 操作必须同槽,最典型的解决方法是通过 hash tag 让相关 key 路由到同一个槽位。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统系统设计MySQLRedis
查看题库题
面经原题待沉淀数据库
Redis 的持久化方法有哪些?
Redis
Redis 的持久化主要有两种:RDB 和 AOF,也可以同时开启混合使用。 1. RDB RDB 是在某个时间点把内存中的数据快照写入磁盘,生成 dump.rdb 文件。 优点: - 文件体积相对较小,适合备份和灾难恢复。 - 恢复速度通常较快。 - 对运行时性能影响相对可控。 缺点: - 两次快照之间如果发生故障,会丢失这一时间段的数据。 - fork 子进程生成快照时,数据量很大时可能带来额外开销。 2. AOF AOF 是把写命令按追加日志的方式记录下来,重启时通过重放命令恢复数据。 优点: - 数据更不容易丢失,持久化粒度更细。 - 可根据 appendfsync 策略在性能和数据安全之间权衡。 缺点: - 文件通常比 RDB 更大。 - 恢复速度一般比 RDB 慢。 - 长期运行需要重写 AOF 文件。 appendfsync 常见策略: - always:每次写都刷盘,最安全但性能开销最大。 - everysec:每秒刷盘一次,是常用折中方案。 - no:由操作系统决定刷盘时机,性能最好但丢数据风险更高。 3. 混合持久化 Redis 4.0 以后支持混合持久化,重写 AOF 时把 RDB 快照内容和增量 AOF 命令结合起来。 优点是兼顾恢复速度和数据安全性。 面试中可以总结:Redis 持久化主要是 RDB 和 AOF,RDB适合做快照备份,AOF更关注数据完整性,生产中常根据业务需求选择其一或结合使用。
查看原文 QA
Question 10: Redis 的持久化方法有哪些? Answer: Redis 的持久化主要有两种:RDB 和 AOF,也可以同时开启混合使用。 1. RDB RDB 是在某个时间点把内存中的数据快照写入磁盘,生成 dump.rdb 文件。 优点: - 文件体积相对较小,适合备份和灾难恢复。 - 恢复速度通常较快。 - 对运行时性能影响相对可控。 缺点: - 两次快照之间如果发生故障,会丢失这一时间段的数据。 - fork 子进程生成快照时,数据量很大时可能带来额外开销。 2. AOF AOF 是把写命令按追加日志的方式记录下来,重启时通过重放命令恢复数据。 优点: - 数据更不容易丢失,持久化粒度更细。 - 可根据 appendfsync 策略在性能和数据安全之间权衡。 缺点: - 文件通常比 RDB 更大。 - 恢复速度一般比 RDB 慢。 - 长期运行需要重写 AOF 文件。 appendfsync 常见策略: - always:每次写都刷盘,最安全但性能开销最大。 - everysec:每秒刷盘一次,是常用折中方案。 - no:由操作系统决定刷盘时机,性能最好但丢数据风险更高。 3. 混合持久化 Redis 4.0 以后支持混合持久化,重写 AOF 时把 RDB 快照内容和增量 AOF 命令结合起来。 优点是兼顾恢复速度和数据安全性。 面试中可以总结:Redis 持久化主要是 RDB 和 AOF,RDB适合做快照备份,AOF更关注数据完整性,生产中常根据业务需求选择其一或结合使用。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统系统设计MySQLRedis
查看题库题
面经原题待沉淀分布式系统
Redis 的选举过程是怎样的?
Redis
如果面试里问 Redis 选举过程,一般指的是 Redis Sentinel 在主节点故障时如何选出新的主节点。 可以分成两个阶段回答:先选出负责故障转移的哨兵领导者,再由它从从节点中选出新的主节点。 一、哨兵领导者选举 1. 当多个 Sentinel 都认为 master 主观下线后,会进一步通过投票确认是否客观下线。 2. 一旦达到法定票数,说明 master 确实故障。 3. 各个 Sentinel 会发起领导者选举,类似分布式投票:每个 Sentinel 在一个纪元内只会投一票,先到先得。 4. 获得超过半数票的 Sentinel 成为本次故障转移的领导者,负责后续切换。 二、新主节点选择 领导者 Sentinel 会从现有从节点中挑选一个最合适的提升为主节点,主要考虑: 1. 与原主节点断开时间不能太长,太久说明数据可能太旧。 2. 优先选择 replica-priority 配置较高的从节点(数值越小优先级越高,0 表示永不提升)。 3. 如果优先级相同,优先选择复制偏移量更大的从节点,说明数据更新。 4. 如果偏移量也相同,再比较 run id 等信息做最终决定。 三、故障转移流程 1. 将被选中的从节点执行 SLAVEOF NO ONE,提升为新主。 2. 通知其他从节点改为复制新主节点。 3. 更新客户端可感知的主节点地址信息。 4. 原主节点如果后续恢复,会被重新配置为新主的从节点。 需要补充的是: - Redis 主从复制本身是异步的,所以故障切换时仍可能丢失少量尚未同步的数据。 - 如果问的是 Redis Cluster,也存在故障发现和主从切换,但其投票与切换机制和 Sentinel 细节不完全一样。通常面试里单独说“Redis 选举过程”,默认优先回答 Sentinel。
查看原文 QA
Question 11: Redis 的选举过程是怎样的? Answer: 如果面试里问 Redis 选举过程,一般指的是 Redis Sentinel 在主节点故障时如何选出新的主节点。 可以分成两个阶段回答:先选出负责故障转移的哨兵领导者,再由它从从节点中选出新的主节点。 一、哨兵领导者选举 1. 当多个 Sentinel 都认为 master 主观下线后,会进一步通过投票确认是否客观下线。 2. 一旦达到法定票数,说明 master 确实故障。 3. 各个 Sentinel 会发起领导者选举,类似分布式投票:每个 Sentinel 在一个纪元内只会投一票,先到先得。 4. 获得超过半数票的 Sentinel 成为本次故障转移的领导者,负责后续切换。 二、新主节点选择 领导者 Sentinel 会从现有从节点中挑选一个最合适的提升为主节点,主要考虑: 1. 与原主节点断开时间不能太长,太久说明数据可能太旧。 2. 优先选择 replica-priority 配置较高的从节点(数值越小优先级越高,0 表示永不提升)。 3. 如果优先级相同,优先选择复制偏移量更大的从节点,说明数据更新。 4. 如果偏移量也相同,再比较 run id 等信息做最终决定。 三、故障转移流程 1. 将被选中的从节点执行 SLAVEOF NO ONE,提升为新主。 2. 通知其他从节点改为复制新主节点。 3. 更新客户端可感知的主节点地址信息。 4. 原主节点如果后续恢复,会被重新配置为新主的从节点。 需要补充的是: - Redis 主从复制本身是异步的,所以故障切换时仍可能丢失少量尚未同步的数据。 - 如果问的是 Redis Cluster,也存在故障发现和主从切换,但其投票与切换机制和 Sentinel 细节不完全一样。通常面试里单独说“Redis 选举过程”,默认优先回答 Sentinel。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统系统设计MySQLRedis
查看题库题
面经原题待沉淀分布式系统
Kafka 的 partition 和消费者是什么关系?
Kafka消息队列
Kafka 中 partition 是 topic 的分区,消费者通常以 consumer group 的方式消费数据。它们之间的关系可以从几个方面来理解: 1. 一个 topic 可以有多个 partition。 每个 partition 内部消息是有序的,但 topic 全局不保证绝对有序。 2. 消费是以 consumer group 为单位进行负载均衡的。 同一个 consumer group 里的多个消费者会共同消费一个 topic 的不同 partition。 3. 在同一个 consumer group 内,一个 partition 在同一时刻只能被一个消费者消费。 这是为了保证该 partition 内消息消费顺序。 4. 一个消费者可以消费多个 partition。 如果 partition 数量大于消费者数量,就会有某些消费者负责多个 partition。 5. 如果消费者数量大于 partition 数量,多出来的消费者会空闲。 因为一个 partition 不能同时分配给同组内多个消费者。 6. 不同 consumer group 之间互不影响。 同一份消息可以被不同消费组各自消费一次,因此 Kafka 也常用于广播式多下游消费场景。 总结: - partition 决定并行度上限; - consumer group 决定消费协作关系; - 同组内“一个 partition 同时只对应一个消费者”,但“一个消费者可以对应多个 partition”。
查看原文 QA
Question 12: Kafka 的 partition 和消费者是什么关系? Answer: Kafka 中 partition 是 topic 的分区,消费者通常以 consumer group 的方式消费数据。它们之间的关系可以从几个方面来理解: 1. 一个 topic 可以有多个 partition。 每个 partition 内部消息是有序的,但 topic 全局不保证绝对有序。 2. 消费是以 consumer group 为单位进行负载均衡的。 同一个 consumer group 里的多个消费者会共同消费一个 topic 的不同 partition。 3. 在同一个 consumer group 内,一个 partition 在同一时刻只能被一个消费者消费。 这是为了保证该 partition 内消息消费顺序。 4. 一个消费者可以消费多个 partition。 如果 partition 数量大于消费者数量,就会有某些消费者负责多个 partition。 5. 如果消费者数量大于 partition 数量,多出来的消费者会空闲。 因为一个 partition 不能同时分配给同组内多个消费者。 6. 不同 consumer group 之间互不影响。 同一份消息可以被不同消费组各自消费一次,因此 Kafka 也常用于广播式多下游消费场景。 总结: - partition 决定并行度上限; - consumer group 决定消费协作关系; - 同组内“一个 partition 同时只对应一个消费者”,但“一个消费者可以对应多个 partition”。

相关题库题

分布式系统Kafka消息队列
查看题库题
分布式系统Kafka消息队列Redis
查看题库题
面经原题待沉淀分布式系统
Kafka 为什么高性能?
Kafka消息队列网络
Kafka 高性能主要是因为它在磁盘、网络、批处理和顺序写等方面做了很多针对吞吐量的优化。 1. 顺序写磁盘 Kafka 采用追加写日志的方式,消息顺序写入 partition 文件。顺序写比随机写效率高得多,即使落盘也能获得很高吞吐。 2. 利用操作系统 Page Cache Kafka 大量依赖 OS 的页缓存,读写很多时候先经过内存缓存,减少直接磁盘 I/O 开销。 3. 零拷贝 Kafka 在数据发送给消费者时可以利用零拷贝机制,减少用户态和内核态之间的数据拷贝次数,降低 CPU 消耗,提高网络传输效率。 4. 批量处理 生产者可以批量发送消息,Broker 也按批次处理和拉取,减少网络请求次数和协议开销。 5. 分区机制带来的并行能力 一个 topic 可以拆成多个 partition,生产、存储、消费都可以并行进行,从而提升整体吞吐量。 6. 顺序读 消费者通常按 offset 顺序拉取消息,顺序读性能也比较好。 7. 高效的网络模型 Kafka 使用高效的 I/O 模型和紧凑的二进制协议,减少额外开销。 8. 生产者端压缩与异步发送 消息可以在生产者端压缩并异步发送,进一步减少网络带宽占用,提高吞吐。 面试中可以概括为:Kafka 高性能的核心原因是“顺序写磁盘 + Page Cache + 零拷贝 + 批量处理 + 分区并行”。
查看原文 QA
Question 13: Kafka 为什么高性能? Answer: Kafka 高性能主要是因为它在磁盘、网络、批处理和顺序写等方面做了很多针对吞吐量的优化。 1. 顺序写磁盘 Kafka 采用追加写日志的方式,消息顺序写入 partition 文件。顺序写比随机写效率高得多,即使落盘也能获得很高吞吐。 2. 利用操作系统 Page Cache Kafka 大量依赖 OS 的页缓存,读写很多时候先经过内存缓存,减少直接磁盘 I/O 开销。 3. 零拷贝 Kafka 在数据发送给消费者时可以利用零拷贝机制,减少用户态和内核态之间的数据拷贝次数,降低 CPU 消耗,提高网络传输效率。 4. 批量处理 生产者可以批量发送消息,Broker 也按批次处理和拉取,减少网络请求次数和协议开销。 5. 分区机制带来的并行能力 一个 topic 可以拆成多个 partition,生产、存储、消费都可以并行进行,从而提升整体吞吐量。 6. 顺序读 消费者通常按 offset 顺序拉取消息,顺序读性能也比较好。 7. 高效的网络模型 Kafka 使用高效的 I/O 模型和紧凑的二进制协议,减少额外开销。 8. 生产者端压缩与异步发送 消息可以在生产者端压缩并异步发送,进一步减少网络带宽占用,提高吞吐。 面试中可以概括为:Kafka 高性能的核心原因是“顺序写磁盘 + Page Cache + 零拷贝 + 批量处理 + 分区并行”。

相关题库题

分布式系统Kafka消息队列
查看题库题
网络协议消息队列网络
查看题库题
面经原题待沉淀网络协议
TCP 与 UDP 的优缺点是什么?
系统设计MySQL网络
TCP 和 UDP 都是传输层协议,但设计目标不同。 TCP 的优点: 1. 面向连接,通信前先建立连接。 2. 可靠传输,有确认应答、重传、校验、顺序控制等机制。 3. 提供流量控制和拥塞控制。 4. 能保证数据按序到达,适合对可靠性要求高的场景。 TCP 的缺点: 1. 由于要建立连接、维护状态、确认重传等,开销较大。 2. 时延通常高于 UDP。 3. 报文头更大,实现也更复杂。 UDP 的优点: 1. 无连接,发送开销小。 2. 报文头小,传输效率高。 3. 时延低,适合实时性要求高的场景。 4. 支持广播和多播。 UDP 的缺点: 1. 不保证可靠到达,可能丢包、乱序、重复。 2. 没有内建的流量控制和拥塞控制。 3. 需要应用层自己处理可靠性问题时,实现成本会上升。 适用场景上: - TCP 适合网页访问、文件传输、数据库连接等要求可靠性的场景。 - UDP 适合音视频、实时通信、DNS、直播、游戏等对时延敏感、能容忍少量丢包的场景。
查看原文 QA
Question 14: TCP 与 UDP 的优缺点是什么? Answer: TCP 和 UDP 都是传输层协议,但设计目标不同。 TCP 的优点: 1. 面向连接,通信前先建立连接。 2. 可靠传输,有确认应答、重传、校验、顺序控制等机制。 3. 提供流量控制和拥塞控制。 4. 能保证数据按序到达,适合对可靠性要求高的场景。 TCP 的缺点: 1. 由于要建立连接、维护状态、确认重传等,开销较大。 2. 时延通常高于 UDP。 3. 报文头更大,实现也更复杂。 UDP 的优点: 1. 无连接,发送开销小。 2. 报文头小,传输效率高。 3. 时延低,适合实时性要求高的场景。 4. 支持广播和多播。 UDP 的缺点: 1. 不保证可靠到达,可能丢包、乱序、重复。 2. 没有内建的流量控制和拥塞控制。 3. 需要应用层自己处理可靠性问题时,实现成本会上升。 适用场景上: - TCP 适合网页访问、文件传输、数据库连接等要求可靠性的场景。 - UDP 适合音视频、实时通信、DNS、直播、游戏等对时延敏感、能容忍少量丢包的场景。

相关题库题

数据库系统设计MySQL
查看题库题
分布式系统系统设计MySQLRedis
查看题库题
面经原题待沉淀分布式系统
Kafka 任务堆积怎么处理?
并发系统设计Kafka消息队列MySQL网络Redis
Kafka 任务堆积本质上是生产速度持续大于消费速度,处理时要先止血、再定位瓶颈、最后做长期优化。 可以按以下思路回答: 1. 先确认堆积情况 - 看 topic、partition 的 lag,确认是整体堆积还是部分 partition 堆积。 - 看堆积增长趋势,是突发流量还是持续性消费能力不足。 - 判断是否只有某个 consumer group 堆积,还是多个消费组都堆积。 2. 优先提升消费能力 - 增加消费者实例数,但要注意同一个消费组的并行度上限受 partition 数量限制。 - 如果 partition 太少,可以评估扩 partition。 - 优化消费者业务逻辑,比如减少不必要的同步调用、批量处理消息、提高线程池处理能力。 - 区分核心逻辑和非核心逻辑,把耗时操作异步化。 3. 排查是否有异常消息或热点分区 - 检查是否有某个 partition 堆积严重,可能是分区分配不均或 key 设计导致热点。 - 检查消费者是否因为某条脏数据、反序列化异常、外部依赖超时而卡住。 - 如果是消息重试导致反复消费失败,要把问题消息隔离到死信队列或旁路处理。 4. 检查下游瓶颈 - 例如数据库、Redis、第三方接口是否响应变慢。 - 如果消费逻辑依赖下游服务,下游抖动会直接拉低消费速率。 - 必要时做限流、降级、熔断,避免整个消费链路被拖垮。 5. 临时止血方案 - 对非关键消息可考虑降级处理或延后处理。 - 紧急情况下可以扩容 consumer、增加机器资源。 - 如果业务允许,可以临时跳过历史低优先级数据或做离线补偿,但这要非常谨慎。 6. 长期优化方案 - 合理规划 partition 数。 - 优化消息体大小,降低网络和反序列化开销。 - 批量消费、批量落库。 - 做好消费监控,对 lag、消费耗时、失败率、重试次数设置报警。 - 保证消费幂等,便于失败重试和补偿。 面试里可以总结为:先看 lag 和热点 partition,判断是消费者能力不足、异常消息卡住还是下游瓶颈;然后通过扩 consumer、增加 partition、优化消费逻辑、隔离失败消息和提升下游能力来处理堆积。
查看原文 QA
Question 15: Kafka 任务堆积怎么处理? Answer: Kafka 任务堆积本质上是生产速度持续大于消费速度,处理时要先止血、再定位瓶颈、最后做长期优化。 可以按以下思路回答: 1. 先确认堆积情况 - 看 topic、partition 的 lag,确认是整体堆积还是部分 partition 堆积。 - 看堆积增长趋势,是突发流量还是持续性消费能力不足。 - 判断是否只有某个 consumer group 堆积,还是多个消费组都堆积。 2. 优先提升消费能力 - 增加消费者实例数,但要注意同一个消费组的并行度上限受 partition 数量限制。 - 如果 partition 太少,可以评估扩 partition。 - 优化消费者业务逻辑,比如减少不必要的同步调用、批量处理消息、提高线程池处理能力。 - 区分核心逻辑和非核心逻辑,把耗时操作异步化。 3. 排查是否有异常消息或热点分区 - 检查是否有某个 partition 堆积严重,可能是分区分配不均或 key 设计导致热点。 - 检查消费者是否因为某条脏数据、反序列化异常、外部依赖超时而卡住。 - 如果是消息重试导致反复消费失败,要把问题消息隔离到死信队列或旁路处理。 4. 检查下游瓶颈 - 例如数据库、Redis、第三方接口是否响应变慢。 - 如果消费逻辑依赖下游服务,下游抖动会直接拉低消费速率。 - 必要时做限流、降级、熔断,避免整个消费链路被拖垮。 5. 临时止血方案 - 对非关键消息可考虑降级处理或延后处理。 - 紧急情况下可以扩容 consumer、增加机器资源。 - 如果业务允许,可以临时跳过历史低优先级数据或做离线补偿,但这要非常谨慎。 6. 长期优化方案 - 合理规划 partition 数。 - 优化消息体大小,降低网络和反序列化开销。 - 批量消费、批量落库。 - 做好消费监控,对 lag、消费耗时、失败率、重试次数设置报警。 - 保证消费幂等,便于失败重试和补偿。 面试里可以总结为:先看 lag 和热点 partition,判断是消费者能力不足、异常消息卡住还是下游瓶颈;然后通过扩 consumer、增加 partition、优化消费逻辑、隔离失败消息和提升下游能力来处理堆积。

相关题库题

分布式系统并发系统设计Redis
查看题库题
分布式系统Kafka消息队列
查看题库题
面经原题待沉淀Java JVM
Java Full GC 或 Old GC 怎么排查?
并发JavaThreadLocal
排查 Full GC 或 Old GC,一般遵循“先看现象,再定位原因,最后针对性优化”的思路。 1. 先确认问题现象 - 看 GC 日志,确认 Full GC/Old GC 的频率、每次停顿时间、回收前后各代内存变化。 - 关注是偶发还是持续高频,是否已经影响接口 RT、吞吐量或服务可用性。 - 结合监控看 CPU、内存、线程数、QPS、对象分配速率等指标。 2. 打开并分析 GC 日志 常见做法是开启详细 GC 日志,然后用 GCEasy、GCViewer 等工具分析。 重点关注: - 老年代是不是持续上涨。 - Full GC 后内存是否明显回落。 - 晋升是否过快,是否存在大对象直接进入老年代。 - 是否出现频繁 CMS/G1 回收失败、Concurrent Mode Failure、Promotion Failure 等问题。 3. 判断常见原因 常见导致 Full GC/Old GC 的原因有: - 老年代空间不足。 - 年轻代对象晋升过快。 - 大对象分配过多。 - 内存泄漏,导致对象无法释放。 - 缓存设置不合理,长期持有大量对象。 - 不合理的 JVM 参数配置。 - System.gc() 被显式调用。 4. 配合堆分析定位问题对象 - 在 Full GC 前后导出 heap dump。 - 用 MAT、jmap、jcmd 等工具分析大对象、对象数量、引用链和支配树。 - 重点看哪些对象占用内存最多,是否有集合不断增长、ThreadLocal 未清理、缓存未淘汰、连接对象未释放等情况。 5. 结合代码和业务场景排查 - 是否有一次查大量数据到内存。 - 是否有大批量 JSON 反序列化、文件处理、报表导出等大对象场景。 - 是否有线程池任务堆积导致对象无法及时释放。 - 是否有本地缓存、静态集合、ThreadLocal 使用不当。 6. 优化手段 - 先从代码层解决:减少对象创建、及时释放引用、分页处理大查询、优化缓存策略。 - 调整堆大小和新生代/老年代比例。 - 选择合适的垃圾回收器并调参数,如 G1、CMS(旧版本)等。 - 避免显式调用 System.gc()。 - 对大对象和高频临时对象场景做专项优化。 面试中可以总结为:先通过 GC 日志判断 Full GC 的触发模式,再结合 heap dump 分析哪些对象占住老年代,最后从代码、缓存、对象生命周期和 JVM 参数几方面定位并优化。
查看原文 QA
Question 16: Java Full GC 或 Old GC 怎么排查? Answer: 排查 Full GC 或 Old GC,一般遵循“先看现象,再定位原因,最后针对性优化”的思路。 1. 先确认问题现象 - 看 GC 日志,确认 Full GC/Old GC 的频率、每次停顿时间、回收前后各代内存变化。 - 关注是偶发还是持续高频,是否已经影响接口 RT、吞吐量或服务可用性。 - 结合监控看 CPU、内存、线程数、QPS、对象分配速率等指标。 2. 打开并分析 GC 日志 常见做法是开启详细 GC 日志,然后用 GCEasy、GCViewer 等工具分析。 重点关注: - 老年代是不是持续上涨。 - Full GC 后内存是否明显回落。 - 晋升是否过快,是否存在大对象直接进入老年代。 - 是否出现频繁 CMS/G1 回收失败、Concurrent Mode Failure、Promotion Failure 等问题。 3. 判断常见原因 常见导致 Full GC/Old GC 的原因有: - 老年代空间不足。 - 年轻代对象晋升过快。 - 大对象分配过多。 - 内存泄漏,导致对象无法释放。 - 缓存设置不合理,长期持有大量对象。 - 不合理的 JVM 参数配置。 - System.gc() 被显式调用。 4. 配合堆分析定位问题对象 - 在 Full GC 前后导出 heap dump。 - 用 MAT、jmap、jcmd 等工具分析大对象、对象数量、引用链和支配树。 - 重点看哪些对象占用内存最多,是否有集合不断增长、ThreadLocal 未清理、缓存未淘汰、连接对象未释放等情况。 5. 结合代码和业务场景排查 - 是否有一次查大量数据到内存。 - 是否有大批量 JSON 反序列化、文件处理、报表导出等大对象场景。 - 是否有线程池任务堆积导致对象无法及时释放。 - 是否有本地缓存、静态集合、ThreadLocal 使用不当。 6. 优化手段 - 先从代码层解决:减少对象创建、及时释放引用、分页处理大查询、优化缓存策略。 - 调整堆大小和新生代/老年代比例。 - 选择合适的垃圾回收器并调参数,如 G1、CMS(旧版本)等。 - 避免显式调用 System.gc()。 - 对大对象和高频临时对象场景做专项优化。 面试中可以总结为:先通过 GC 日志判断 Full GC 的触发模式,再结合 heap dump 分析哪些对象占住老年代,最后从代码、缓存、对象生命周期和 JVM 参数几方面定位并优化。

相关题库题

Java 并发并发JavaJava 并发ThreadLocal
查看题库题
Java 并发并发JavaJava 并发ThreadLocal
查看题库题
面经原题待沉淀数据库
遇过数据库死锁吗?怎么排查和处理?
MySQL
可以从“什么是死锁、怎么定位、怎么处理、怎么预防”四个层次来回答。 我遇到过数据库死锁,本质上是两个或多个事务互相等待对方持有的锁,最终谁也无法继续,只能由数据库回滚其中一个事务来打破僵局。 排查思路一般是: 1. 先看数据库报错和业务日志,确认是否真的是死锁,而不是普通锁等待超时。 2. 在 MySQL 里可以通过 SHOW ENGINE INNODB STATUS 查看最近一次死锁信息,里面会有涉及的事务、SQL、锁类型和回滚情况。 3. 结合慢 SQL、事务日志和代码调用链,找到冲突 SQL 是哪些表、哪些索引、按什么顺序加锁的。 4. 判断是行锁冲突、间隙锁、next-key lock,还是因为索引不命中导致锁范围扩大。 常见原因有: - 两个事务更新多行数据时加锁顺序不一致。 - 范围查询在可重复读隔离级别下触发间隙锁。 - 没有走索引,导致扫描和加锁范围过大。 - 事务里执行了过多业务逻辑,持锁时间太长。 处理方式: 1. 让应用捕获死锁异常并做有限重试,因为数据库已经自动回滚了其中一个事务。 2. 优化 SQL 和索引,尽量让语句精确命中需要的数据,缩小锁范围。 3. 统一加锁顺序,比如多个事务都按相同顺序更新资源,减少循环等待。 4. 缩短事务时间,不要在事务中做远程调用、复杂计算或长时间等待。 5. 必要时调整查询方式或隔离级别,减少间隙锁影响。 预防上最核心的是:走合适索引、控制事务范围、统一访问顺序、尽量避免大范围锁定。
查看原文 QA
Question 17: 遇过数据库死锁吗?怎么排查和处理? Answer: 可以从“什么是死锁、怎么定位、怎么处理、怎么预防”四个层次来回答。 我遇到过数据库死锁,本质上是两个或多个事务互相等待对方持有的锁,最终谁也无法继续,只能由数据库回滚其中一个事务来打破僵局。 排查思路一般是: 1. 先看数据库报错和业务日志,确认是否真的是死锁,而不是普通锁等待超时。 2. 在 MySQL 里可以通过 SHOW ENGINE INNODB STATUS 查看最近一次死锁信息,里面会有涉及的事务、SQL、锁类型和回滚情况。 3. 结合慢 SQL、事务日志和代码调用链,找到冲突 SQL 是哪些表、哪些索引、按什么顺序加锁的。 4. 判断是行锁冲突、间隙锁、next-key lock,还是因为索引不命中导致锁范围扩大。 常见原因有: - 两个事务更新多行数据时加锁顺序不一致。 - 范围查询在可重复读隔离级别下触发间隙锁。 - 没有走索引,导致扫描和加锁范围过大。 - 事务里执行了过多业务逻辑,持锁时间太长。 处理方式: 1. 让应用捕获死锁异常并做有限重试,因为数据库已经自动回滚了其中一个事务。 2. 优化 SQL 和索引,尽量让语句精确命中需要的数据,缩小锁范围。 3. 统一加锁顺序,比如多个事务都按相同顺序更新资源,减少循环等待。 4. 缩短事务时间,不要在事务中做远程调用、复杂计算或长时间等待。 5. 必要时调整查询方式或隔离级别,减少间隙锁影响。 预防上最核心的是:走合适索引、控制事务范围、统一访问顺序、尽量避免大范围锁定。

相关题库题

数据库MySQL
查看题库题
数据库MySQL
查看题库题
面经原题待沉淀
请手写区间合并。
区间合并的核心思路是:先按区间起点排序,再顺序遍历,把有重叠的区间合并起来。 例如输入 [[1,3],[2,6],[8,10],[15,18]],输出 [[1,6],[8,10],[15,18]]。 Java 实现如下: ```java import java.util.*; public class Solution { public int[][] merge(int[][] intervals) { if (intervals == null || intervals.length == 0) { return new int[0][0]; } Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0])); List<int[]> res = new ArrayList<>(); int[] cur = intervals[0]; for (int i = 1; i < intervals.length; i++) { if (intervals[i][0] <= cur[1]) { cur[1] = Math.max(cur[1], intervals[i][1]); } else { res.add(cur); cur = intervals[i]; } } res.add(cur); return res.toArray(new int[res.size()][]); } } ``` 时间复杂度是 O(n log n),主要来自排序;遍历合并是 O(n)。空间复杂度如果不算返回结果,额外空间主要是结果集合。
查看原文 QA
Question 18: 请手写区间合并。 Answer: 区间合并的核心思路是:先按区间起点排序,再顺序遍历,把有重叠的区间合并起来。 例如输入 [[1,3],[2,6],[8,10],[15,18]],输出 [[1,6],[8,10],[15,18]]。 Java 实现如下: ```java import java.util.*; public class Solution { public int[][] merge(int[][] intervals) { if (intervals == null || intervals.length == 0) { return new int[0][0]; } Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0])); List<int[]> res = new ArrayList<>(); int[] cur = intervals[0]; for (int i = 1; i < intervals.length; i++) { if (intervals[i][0] <= cur[1]) { cur[1] = Math.max(cur[1], intervals[i][1]); } else { res.add(cur); cur = intervals[i]; } } res.add(cur); return res.toArray(new int[res.size()][]); } } ``` 时间复杂度是 O(n log n),主要来自排序;遍历合并是 O(n)。空间复杂度如果不算返回结果,额外空间主要是结果集合。
当前没有检索到明显相关的题库题。

来源原文

猿辅导 4.1 项目 账户系统 使用redis+kafka的原因是什么 面经 redis Zset底层结构 跳表的原理 为什么不用B+树 redis String底层结构 redis分布式锁延期 redis的过期方法 redis集群/主从或其他架构优缺点 redis跨槽位 redis持久化方法 redis选举过程 kafka partition和消费者关系 kafka为什么高性能 tcp与udp的优缺点 场景题 kafka任务堆积怎么处理 Java full gc或者old gc怎么排查 遇过数据库死锁吗 手撕 区间合并

沉淀概览

已沉淀 0 / 18
待处理 18

元信息

公司: 猿辅导
岗位: 未知
轮次: 4.1

来源文档

标题: 猿辅导
类型: interview_experience
更新时间: 2026/04/01 19:49