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

在线教育平台中,学生提交作业后,教师端需要实时看到。请设计一个系统架构,确保提交操作的高可用性和数据一致性(如使用消息队列、数据库事务),并说明如何处理网络延迟或消息丢失的情况。

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

答案

1) 【一句话结论】采用“数据库事务 + 消息队列异步消费”架构,前端提交作业后,服务端先本地事务写入数据库(保证数据持久化),再发布消息到消息队列;教师端订阅消息并更新界面。通过消息重试和幂等性处理网络延迟或消息丢失,确保高可用和数据最终一致性。

2) 【原理/概念讲解】

  • 高可用性:系统需在部分组件故障时仍能提供服务。例如数据库主从复制、消息队列集群,确保提交服务或消费服务单点故障不影响整体。
  • 数据一致性:采用“最终一致性”,因实时性要求高,强一致性(如分布式事务)成本高。数据库事务保证本地写入的ACID(原子性、一致性、隔离性、持久性),消息队列保证消息可靠传递。
  • 消息队列(如Kafka/RabbitMQ):解耦提交服务与教师端,提交服务快速返回,教师端异步消费,避免阻塞。类比:快递公司,提交作业是“寄件”,服务端把包裹发到快递站(消息队列),教师端去快递站取包裹(消费消息),即使快递站临时没开门(延迟),包裹最终会送达。
  • 数据库事务:提交时先执行本地事务(如插入作业记录到作业表,关联用户、题目等),事务提交后数据写入磁盘,保证数据持久化。

3) 【对比与适用场景】

方案定义特性使用场景注意点
直接调用数据库(同步)提交服务直接调用数据库API,返回后更新教师端实时性高,强一致性(本地),但阻塞提交服务,高并发下易超时作业量小、实时性要求极高(如秒级)高并发下性能差,服务端响应慢
消息队列 + 数据库事务(异步)提交服务写入数据库(事务),发布消息;教师端消费消息异步处理,解耦,高可用,最终一致性作业量大、实时性要求中等(秒级内),高并发场景需处理消息丢失、重试、幂等性

4) 【示例】(伪代码):

  • 前端提交:用户点击“提交”,前端发送POST请求到提交服务。
  • 提交服务处理:
    def submit_homework(user_id, problem_id, code):
        # 1. 数据库事务写入作业
        with db.transaction():
            db.insert('homework', user_id=user_id, problem_id=problem_id, code=code, status='pending')
        # 2. 发布消息到消息队列
        mq.publish('homework.submit', {
            'user_id': user_id,
            'problem_id': problem_id,
            'code': code,
            'timestamp': datetime.now()
        })
        return {'code': 200, 'msg': '提交成功,稍后可见'}
    
  • 教师端消费:教师端订阅消息队列,消费消息后更新界面:
    def consume_homework():
        while True:
            msg = mq.consume('homework.submit')
            if msg:
                # 更新教师端界面,标记为“待批改”
                update_teacher_ui(msg['user_id'], msg['problem_id'], msg['code'], status='pending')
    

5) 【面试口播版答案】
“老师您好,我会设计一个基于‘数据库事务 + 消息队列异步消费’的架构。首先,学生提交作业时,服务端先执行本地数据库事务,将作业数据写入数据库(保证数据持久化),然后发布一条消息到消息队列。教师端订阅该队列,异步消费消息并更新界面。这样,提交服务快速返回,避免阻塞;教师端通过消息消费实时看到作业。对于网络延迟或消息丢失,我们采用消息重试机制(如Kafka的自动重试)和幂等性处理(消息中包含唯一标识,消费时检查是否已处理),确保消息最终可靠传递。同时,数据库主从复制保证高可用,避免单点故障。核心思路是解耦服务,通过异步消息保证高可用,事务保证数据本地一致,最终实现提交操作的高可用和数据一致性。”

6) 【追问清单】

  • 追问1:消息丢失如何处理?
    回答要点:消息队列(如Kafka)提供持久化存储,未消费的消息保留在磁盘,消费端失败后自动重试,结合幂等性避免重复处理。
  • 追问2:网络延迟下教师端看不到怎么办?
    回答要点:消息队列的延迟消费特性,教师端可配置消费超时,同时前端可做本地缓存,延迟显示“正在同步”提示。
  • 追问3:高并发下数据库压力如何?
    回答要点:数据库主从复制+读写分离,提交服务写操作集中到主库,教师端读操作走从库,结合消息队列异步消费减轻数据库压力。
  • 追问4:如何保证数据最终一致性?
    回答要点:数据库事务保证本地写入一致,消息队列保证消息可靠传递,通过时间戳或版本号检测冲突,最终所有作业都能正确显示。
  • 追问5:幂等性如何实现?
    回答要点:消息中包含唯一标识(如作业ID),消费时检查该标识是否已处理,若已处理则跳过,避免重复更新教师端界面。

7) 【常见坑/雷区】

  • 坑1:忽略强一致性需求:直接用消息队列可能导致数据不一致,未考虑实时性要求,应明确最终一致性适用场景。
  • 坑2:消息队列选型错误:如用同步队列(如RabbitMQ的同步模式)导致服务阻塞,应选择异步、持久化队列(如Kafka)。
  • 坑3:事务范围过大:提交时同时写入数据库和消息队列,若消息队列失败导致事务回滚,数据丢失。应分开事务,先写数据库再发消息。
  • 坑4:未处理幂等性:消息重复消费导致教师端重复更新界面,应通过唯一标识保证幂等。
  • 坑5:高可用设计不足:仅考虑数据库主从,未考虑消息队列集群,若消息队列单点故障,可能导致消息丢失。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1