51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

设计一个支持百万级题目的在线竞赛题库系统,要求支持快速增删改查、按条件检索、实时推荐(根据学生历史答题数据推荐题目),并考虑高并发场景(如考试期间同时有数千学生访问)。请描述系统架构,关键组件,以及如何保证数据一致性和系统稳定性。

学而思竞赛教练(理科、C++)难度:困难

答案

1) 【一句话结论】

核心采用微服务分布式架构,通过分库分表(MySQL存储题目元数据)、分布式文件系统(MinIO存储题目文本)、Redis缓存、Elasticsearch检索、Kafka消息队列(推荐),结合负载均衡和限流,实现百万级题库的高并发支持,数据一致性通过最终一致性(事务+补偿机制)保障,推荐算法优化(预计算+近似)提升实时性。

2) 【原理/概念讲解】

针对百万级题库系统,需解决高并发读写、快速检索、实时推荐三大核心问题,各组件作用如下:

  • 数据库(MySQL,分库分表):题目元数据(标题、难度、标签、用户答题记录)存储在关系型数据库中。通过哈希分库分表(题目标识id取模后对应表,如id % 8对应表0-7),将数据分散存储,支持读写分离(主库写,从库读),提升读性能。题目元数据表需创建多列索引(如difficulty, tags联合索引),加速按条件检索。
  • 分布式文件系统(MinIO):存储题目文本内容(如HTML/Markdown格式)。题目元数据表新增text_url字段(指向MinIO文件路径),文本内容通过文件系统存储,避免数据库存储大文本导致性能下降。
  • Redis缓存:缓存热门题目文本(从MinIO加载后缓存)和用户历史答题数据(如用户答题记录、正确率),减少数据库和文件系统压力。
  • Elasticsearch(搜索引擎):存储题目元数据(难度、标签、用户答题行为),支持复杂检索(如按标签“算法”、难度“中等”检索)。通过倒排索引,快速匹配符合条件的题目。检索时,先查询ES,再补充题目文本(从Redis或MinIO获取)。
  • 消息队列(Kafka):处理实时推荐逻辑。用户答题后,答题数据(用户ID、题目ID、正确性、用时)写入Kafka,消费者(推荐系统)实时分析用户行为(如正确率、答题时间),生成推荐列表并更新用户推荐数据(写入数据库和Redis)。
  • 负载均衡(Nginx):分发请求到多个应用服务器,避免单点故障,支持水平扩展。考试期间,通过增加应用服务器实例,提升并发处理能力。

关键优化点:

  • 题目文本存储在MinIO,元数据存MySQL,用布隆过滤器减少Redis缓存穿透(缓存空值,过期后重新查询MinIO);
  • 推荐算法预计算用户画像(如协同过滤的相似度矩阵提前计算),减少实时计算开销;
  • 考试前10分钟执行缓存预热(将热门题目文本加载到Redis)。

3) 【对比与适用场景】

以**MySQL(元数据)与MinIO(文本)**为例,对比题目内容存储:

组件定义特性使用场景注意点
MySQL关系型数据库,支持事务、ACID事务一致,持久化存储,适合结构化元数据题目元数据(需持久化,如题目修改、用户答题记录)分库分表后需维护一致性,复杂检索效率低
MinIO分布式对象存储,高吞吐、低延迟存储大文本(如题目内容),支持版本控制题目文本内容(避免数据库存储大文本)无事务,需结合元数据(MySQL)管理文件路径
Elasticsearch分布式搜索引擎支持复杂全文检索、多条件查询(倒排索引)按标签、难度等条件检索题目(如“算法”标签、“中等”难度)不支持事务,数据最终一致性,需结合数据库存储元数据

4) 【示例】

  • 题目文本存储示例:题目ID为1001的文本存储在MinIO,路径为/minio/questions/1001.html,元数据表questions中text_url字段为该路径。
  • Elasticsearch检索示例:用户查询标签为“算法”、难度为“中等”的题目。
    GET /questions/_search
    {
      "query": {
        "bool": {
          "must": [
            { "term": { "tags": "算法" } },
            { "term": { "difficulty": "中等" } }
          ]
        }
      },
      "size": 10
    }
    
    返回结果包含题目ID、标题、难度、标签等,再从Redis获取文本内容(若缓存命中)。
  • 推荐算法预计算示例:用户画像矩阵(用户-题目相似度)提前计算并存储在Redis,用户答题后直接查询矩阵,快速生成推荐列表。

5) 【面试口播版答案】

面试官您好,针对百万级题库系统,我设计的架构是微服务分布式架构,核心是通过分库分表、分布式文件系统存储题目文本、Redis缓存、Elasticsearch检索,以及Kafka消息队列处理实时推荐,确保高并发下的快速响应。首先,题目元数据(如ID、标题、标签)存MySQL,通过哈希分库分表,创建联合索引加速检索;题目文本存储在MinIO,文本内容通过文件路径关联,用布隆过滤器减少缓存穿透。热门题目和用户历史数据缓存到Redis,减少数据库压力。检索时用ES,支持按标签、难度等复杂条件秒级返回结果。用户答题后,答题数据写入Kafka,消费者实时分析用户行为(正确率、用时),生成推荐列表并更新用户数据。考试期间,通过Nginx负载均衡分发请求,应用层限流,数据库分库分表,提前缓存热门题目(缓存预热),确保数千学生并发访问。数据一致性采用最终一致性,用户答题后先写入数据库,再异步更新缓存,失败时重试。推荐算法通过预计算用户画像(如协同过滤的相似度矩阵提前计算),减少实时计算开销,延迟控制在秒级内。这样能高效支持百万级题目的增删改查、检索和推荐,满足竞赛场景的高并发需求。

6) 【追问清单】

  1. 如何保证数据一致性?(如用户答题后推荐更新失败)

    • 回答要点:采用最终一致性,通过消息队列异步处理推荐,设置重试机制(如Kafka重试策略、数据库事务回滚),确保数据最终一致。
  2. 缓存穿透或雪崩怎么办?

    • 回答要点:缓存雪崩用随机过期时间(避免批量过期),缓存穿透用布隆过滤器或短效缓存(存储空值,过期后重新查询MinIO)。
  3. 推荐算法的实时性如何优化?(如用户答题后推荐延迟)

    • 回答要点:通过预计算用户画像(如协同过滤的相似度矩阵提前计算),减少实时计算开销,延迟控制在秒级内。
  4. 系统如何水平扩展?(如考试流量激增)

    • 回答要点:应用层通过Nginx负载均衡扩展实例,数据库分库分表(增加从库),缓存集群(Redis集群),消息队列集群(Kafka集群),实现各组件水平扩展。
  5. 题目文本修改后如何回溯?

    • 回答要点:采用事件溯源模式,记录题目变更事件(如题目修改时间、新标签),用户历史数据关联事件,回溯时通过事件重放恢复历史数据。

7) 【常见坑/雷区】

  1. 忽略题目文本存储优化:未用分布式文件系统存储大文本,导致数据库存储压力过大,检索延迟高。
  2. 推荐实时性不足:未预计算用户画像,导致用户答题后推荐延迟,影响用户体验。
  3. 缓存与数据库不一致:未处理读写分离后的数据不一致,用户答题后数据库更新但缓存未同步,返回旧数据。
  4. 高并发下未做限流:考试期间未应用限流策略,流量冲击导致系统崩溃。
  5. ES索引重建延迟:未考虑题目数据更新时ES索引重建的延迟,导致检索结果过时。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1