系统设计-高频面试题(更新中...)

张开发
2026/5/16 5:58:38 15 分钟阅读
系统设计-高频面试题(更新中...)
写在前面我把后端Java面试题做了一个汇总有兴趣大家可以看看这里⭐️在反复复习面试题时我发现不同资料的解释五花八门容易造成概念混淆。尤其是很多总结性的文章和视频要么冗长难记要么过于简略导致关键知识点含糊不清。⭐️为了系统梳理知识我决定撰写一份面试指南不只是简单汇总而是融入个人理解层层拆解复杂概念构建完整的知识体系。我希望它不仅帮助自己更自信地应对面试也能为同行提供清晰、实用的参考。系统设计面试题B站千亿级点赞系统服务架构设计思考方向明确需求 - 系统架构 - 数据存储 - 高并发 - 容灾降级 - 异步处理首先点赞系统的核心业务能力主要有几类用户可以对作品点赞、取消点赞也支持点踩、取消点踩。用户需要查询点赞状态比如某个稿件自己有没有点过赞可以是单个查询也可以是批量查询。作品维度要能查点赞总数、点赞人列表。用户维度要能查自己的点赞列表以及统计自己作品收到的总点赞数。明确了这些之后我会把整个系统拆成五个大的部分流量入口层负责多机房流量调度和分配。业务网关层做统一鉴权、风控、限流避免刷赞。点赞服务层对外暴露接口RPC/HTTP处理核心逻辑。异步任务层主要用于异步写入、缓存刷新、消息分发。数据存储层底层数据存储包括数据库、缓存、KV、本地缓存。在数据模型上我会设计两张核心表点赞记录表存用户对作品的操作记录用户 ID、作品 ID、操作类型、时间可以按用户 ID、作品 ID 建联合索引。点赞计数表存某个作品的累计点赞数和点踩数按作品 ID 建索引。存储我会分三层DB比如 TiDB 这种分布式数据库保证最终持久化和回源能力。Redis 缓存抗住大部分读流量缓存点赞数、用户点赞列表Key 一般是业务 ID作品 ID。本地缓存LocalCache针对热点作品进一步加速避免 Redis 被打爆。利用最小堆算法在可配置的时间窗口范围内统计出访问最频繁的缓存Key,并将热KeyValue按照业务可接受的TTL存储在本地内存中。高并发和热点的优化上写优化写请求走异步点赞计数批量聚合再写 DB降低 IO 压力。读优化典型的 Cache-Aside 模式配合热点识别把热点 key 放到本地缓存。热点识别自动识别热门作品优先加速。容灾和降级方面因为点赞是用户强感知的功能存储层我会做多级容灾Redis、DB、KV 互相兜底。跨机房容灾每个机房都有备份可以快速切换。降级策略方面如果存储挂了接口不会直接报错而是返回空值保证体验等服务恢复后再补写。一致性这块点赞这种业务允许小范围不一致我们会有错误重试机制关键链路比如点赞记录会无限重试。极少数情况下不同存储间数据不一致也是可以接受的。最后吞吐量优化上可以通过消息队列把同步写转成异步写进一步提升吞吐。关键链路会用事务消息加回查机制保证用户操作不会丢。如何设计一个百万人抽奖系统其实对于商品秒杀、抽奖活动、抢红包类的系统而言架构设计的思路很多都是类似的核心思路都是对于这种瞬时超高流量的系统尽可能在负载均衡层就把99%的无效流量拦截掉。然后在1%的流量进入核心业务服务后此时每秒并发还是可能会上万那么可以基于Redis实现核心业务逻辑 抗住上万并发。最后对于类似秒杀商品发货、抽奖商品发货、红包资金转账之类的非常耗时的操作完全可以基于MQ来限流削峰后台有一个服务慢慢执行即可。V1负载均衡分流当用户上升到百万的时候我们就要加多台机器组成集群用负载均衡把流量分散开。Nginx 都可以做避免单台服务器过载。但是单纯加机器没用因为瞬时高峰流量可能是平时的几十倍所以我们还得继续。V2服务限流防止重复抽奖限流的目的是防止瞬时流量把后端打挂。常见策略用户级限流比如一个用户一分钟只能抽一次恶意脚本直接拦掉。可以在网关层用 Sentinel、或者直接在 Nginx 上做 IP 频率限制。这样就避免了无效请求消耗资源。V3共享状态其实像秒杀、抽奖、抢红包这类场景都有一个共同点奖品是有限的可能 50 万人涌进来前几百或者前几千请求就把奖品发完了后续几十万请求都是无效的。如果还让这些请求继续打到后台服务上去执行业务逻辑纯属浪费资源。所以更合理的做法是当奖品一旦抽完就直接在负载均衡层把流量拦掉返回“抽奖结束”。这样比如 50 万人同时请求可能只有 2 万请求真正落到后台抽奖服务剩下 48 万直接在入口层被挡住了系统压力会小很多。那这里就涉及一个问题负载均衡层怎么知道奖品已经发完了答案就是要有一个共享状态。常见的方式有两种用Redis存库存和抽奖状态轻量级且能抗很高并发抽奖服务更新状态后负载均衡层查询即可。或者用ZooKeeper这类分布式协调组件抽奖服务更新一个 znode 节点状态负载均衡层通过 zk 客户端监听节点变化立刻感知到奖品发完了。一般来说Redis 足够轻量、延迟更低所以更多时候会首选 Redis。V4线程优化在服务端还需要调整线程池大小不能太大也不能太小需要通过压测找到一个平衡点。经验值可能是 200~500 之间这样既能充分利用 CPU又不会让线程上下文切换成本过高。V5抽奖逻辑如果基于MySQL来实现核心的抽奖业务逻辑抽奖服务频繁对MySQL进行增删改查这一个MySQL实例也是很难抗住的。通常这种场景下都是基于Redis来实现核心的业务逻辑。Redis 的set或者list结构很适合用来随机抽取中奖人并且可以做到去重和弹出。这样性能很高MySQL 完全不用顶住高并发。V6流量削峰最后就是中奖通知。假设有一万人中奖如果直接同步去调通知服务或者写 MySQL瞬间压力很大。这时候我们就把中奖结果写到 MQKafka / RocketMQ / RabbitMQ里异步处理。通知服务慢慢消费比如两个实例每秒发 100 条1 万条也就延迟 1~2 分钟。用户体验基本没影响但系统压力小很多。如何从零开始设计一个秒杀系统用户点击秒杀请求HTTP/HTTPS请求先到 CDN/WAF防刷、限速、静态化。到网关鉴权登录、签名 幂等检查 人机校验必要时。本地快速判断缓存检查活动是否开始/结束、是否在白名单、每用户限购数、是否已购买等这些在 Redis /本地缓存。Token 预占 / 本地速率控制每台应用机器都在本地维护一个令牌桶这样避免所有请求都打到 Redis。每个请求先尝试拿一个令牌拿到才允许继续处理没拿到就直接返回“繁忙”。如果想实现全局限流QPS限制10w内那就必须有一个全局统一的计数器否则多台机器加起来会超标。Redis 就可以充当全局令牌桶的存储定时往桶里投放令牌比如每秒 10 万个。Redis Lua 脚本做原子库存扣减核心用 Redis 的 Lua 脚本做原子库存检查与扣减且同时用 SETNX 控制单用户限购避免超卖。如果 Redis 扣减成功立即返回“排队成功/下单中”给用户低延迟体验并把用户下单事件发到 MQ。订单服务端 从 MQ 消费做幂等检查、创建订单DB 写冻结/扣款流程、写支付/结算流程。若下单失败触发补偿返库存或人工干预。定期/实时对账把 Redis 预占与落库的订单做对账定时任务若不一致触发补库存或差错处理。库存 Keyseckill:stock:{goodsId}→ 剩余库存数。扣减库存用 Lua 脚本原子操作if stock 0 then decr stock end。用户限购 Keyseckill:user:{activityId}:{userId}→ 用户是否已买/买了多少。用SETNX/INCR保证原子性避免超购。本地令牌桶 Keyseckill:token:{activityId}→ 存放令牌数量Redis 本地桶配合削峰。也可以用list/stream做发放。为什么不直接写库- 会成为瓶颈容易死锁异步 MQ 能削峰并提高可用性。如何保证最终一致性- Redis 记录 MQ 消费幂等 周期性对账 补偿流程。如何防刷- CDN 验证码 设备指纹 行为风控 动态签名。淘宝购物场景问题分析在淘宝购物场景中从点击支付跳转到支付页面输入支付码完成支付之后返回响应的订单列表页面可能存在的问题包括支付流程的安全性、支付页面的加载速度、支付信息的准确性、订单状态的及时更新、网络异常导致的支付失败或重复支付、第三方支付平台的兼容性等。架构设计思路 安全方面采用SSL/TLS加密协议保障数据传输安全对支付信息进行加密处理防止信息泄露和篡改。同时进行严格的身份验证确保用户身份的真实性。性能优化对支付页面进行优化如减少页面元素、采用CDN加速等提高页面加载速度。在服务器端可采用负载均衡、分布式缓存等技术应对高并发访问。数据处理建立可靠的支付状态同步机制确保支付结果能及时准确地反馈到订单系统。可采用消息队列实现异步处理提高系统响应速度和可靠性。容错机制设计完善的异常处理机制如网络超时重试、支付失败后的回滚操作等确保在出现异常情况时系统能稳定运行避免影响用户体验。兼容性针对不同的第三方支付平台进行充分的兼容性测试确保在不同平台上的支付流程都能正常进行。表新增字段问题分析在表上新增一个字段时如果这个表正在进行读写操作可能会导致锁表、影响现有操作的性能甚至造成数据不一致等问题。处理方法 使用在线DDL如MySQL的pt-online-schema-change工具它可以在不锁定表的情况下逐步完成表结构的变更确保在变更过程中表的读写操作不受影响。创建新表并迁移数据创建一个新表结构与原表相同只是新增了字段然后通过批处理的方式将原表的数据插入到新表中最后替换原表。选择合适的时间窗口如果业务允许可在业务低峰期进行表结构的变更操作减少对业务的影响。使用事务和锁机制在变更过程中合理使用事务和锁机制确保数据的一致性和完整性。选课系统设计问题分析选课系统中课的人数不能超人的时间段不能重需要设计合理的数据结构和算法来满足这些约束条件。设计思路 数据结构设计为课程和学生建立数据模型课程包含课程ID、名称、最大人数、上课时间等属性学生包含学生ID、已选课程列表等属性。人数限制实现在学生选课时先检查课程的当前人数是否已满若未满则允许选课并增加课程人数计数否则拒绝选课请求。时间冲突检测当学生选课时遍历其已选课程的时间段与待选课程的时间段进行比较若存在重叠则提示时间冲突不允许选课否则添加到已选课程列表中。事务处理将选课操作作为一个事务处理确保在选课过程中数据的一致性如在人数增加和课程添加到学生列表的操作中若其中一个失败则进行回滚操作。微博评论系统设计问题分析微博成千上万的评论一个评论可能还会有很多回复需要设计一个高效、可扩展的评论系统。设计思路 数据模型设计建立评论和回复的数据模型评论包含评论ID、用户ID、微博ID、评论内容、创建时间等属性回复则关联到对应的评论ID包含回复ID、用户ID、回复内容、创建时间等属性。分层存储采用分层存储策略热门微博的评论和回复可缓存在内存数据库如Redis中提高读取速度较早或访问量较低的评论数据可存储在关系型数据库中定期进行归档处理。分页和懒加载在前端展示时对评论进行分页处理每次只加载一定数量的评论减少数据传输量。对于评论下的回复可采用懒加载方式当用户点击查看回复时才进行数据加载。异步处理和消息队列当用户发表评论或回复时先将请求放入消息队列中异步进行数据存储和处理提高系统的响应速度和吞吐量避免高并发写入导致的阻塞。索引和查询优化在数据库中对微博ID、创建时间等字段建立索引优化评论的查询性能。对于复杂的查询条件如按点赞数排序等可采用预计算或物化视图等技术。高并发抢票系统设计问题分析设计一个类似12306的高并发抢票系统需要应对海量用户的并发访问和复杂的业务逻辑。设计思路 用户队列和预处理用户请求先进入队列系统如使用Kafka等消息队列对请求进行缓冲和预处理如验证用户身份、检查票源等避免直接冲击数据库。票源管理和并发控制采用分布式缓存如Redis存储票源信息使用分布式锁或乐观锁机制控制票源的并发访问防止超卖和重复售票。同时对票源进行实时监控和预警及时发现余票不足等情况。异步任务和分布式架构将订单生成、支付处理等操作设计为异步任务通过分布式任务调度框架如xxl-job进行管理和调度提高系统的响应速度和吞吐量。采用微服务架构将系统拆分成多个独立的服务模块如用户服务、票源服务、订单服务等每个模块可根据自身的特点进行优化和扩展。CDN和静态资源优化将静态资源如图片、CSS、JS文件等部署到CDN上提高静态资源的加载速度。对前端页面进行优化如采用懒加载、分页加载等技术减少页面加载时间和数据传输量。数据一致性和容错性建立完善的数据一致性和容错性机制如采用分布式事务、消息补偿等技术确保在高并发和复杂网络环境下数据的准确性和完整性。对系统可能出现的故障进行预演和演练制定相应的应急预案提高系统的可靠性和稳定性。

更多文章