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

设计一个高并发的广告投放请求处理系统,要求支持百万级QPS,请求包含用户特征(如地理位置、设备类型、历史行为)、广告位信息(如位置、尺寸、预算),需要实时计算匹配结果并返回。请描述系统架构,包括前端、后端、缓存、数据库等组件的职责,以及如何保证低延迟和高可用。

360Web服务端开发工程师-投放方向难度:困难

答案

1) 【一句话结论】
采用分层分布式架构,通过前端负载均衡、缓存热点数据、后端实时出价与预计算匹配结合,结合数据库分库分表与消息队列异步任务,实现百万级QPS下的低延迟和高可用。

2) 【原理/概念讲解】
老师口吻解释系统各组件职责:

  • 前端:Nginx做负载均衡,分发请求到后端集群,实现请求分发与流量控制。
  • 后端:拆分为请求解析(解析用户特征、广告位信息)、特征处理(清洗、标准化,如地理位置编码为经纬度)、匹配计算(根据用户特征和广告位信息,结合预计算模型或实时算法,计算匹配度)、出价计算(根据匹配结果动态计算CPM/CPC,如匹配度越高,出价越高)、结果组装(生成响应)。
  • 缓存:Redis存储热点数据(用户特征、广告位信息、预计算匹配结果),减少数据库查询,降低延迟。
  • 数据库:存储冷数据(用户历史行为、广告位详细配置、预算记录),支持持久化与事务。
  • 消息队列:异步处理非实时任务(如用户行为日志写入、广告位预算更新),避免阻塞主流程。
  • 分布式锁:保证并发场景下的资源竞争(如更新预算时防止超卖,用Redis锁,设置超时时间避免死锁)。

类比:缓存像“快速缓存”,数据库像“持久化仓库”,消息队列像“任务队列”,分布式锁像“互斥锁”,确保资源安全。

3) 【对比与适用场景】

组件定义特性使用场景注意点
缓存(Redis)内存键值存储,支持高并发读写延迟低(毫秒级),支持数据过期热点数据(用户特征、广告位信息)、预计算匹配结果需处理缓存击穿(热点数据失效)、雪崩(大量数据失效)、过期策略(TTL)
数据库(MySQL/ClickHouse)持久化存储,支持事务事务支持、持久化、支持复杂查询冷数据(用户历史行为、广告位配置、预算记录)需分库分表(水平扩展),读写分离(提升读性能)
消息队列(Kafka/RabbitMQ)异步消息传输系统高吞吐、持久化、支持事务异步任务(日志写入、预算更新)消息持久化(如Kafka的持久化存储),确保不丢失
分布式锁(Redis锁)分布式互斥锁高并发、低延迟、可重入资源竞争(如预算更新)设置锁超时时间,避免死锁

4) 【示例】

  • 请求示例:
    {
      "user_id": "u123",
      "user_features": {
        "location": "北京",
        "device": "手机",
        "history": ["商品A", "商品B"]
      },
      "ad_slot": {
        "position": "首页Banner",
        "size": "300x50",
        "budget": 100
      }
    }
    
  • 处理流程:
    1. 负载均衡(Nginx)分发请求到后端。
    2. 后端解析请求,从Redis获取用户特征(缓存未命中则数据库读取并缓存)。
    3. 从Redis获取广告位信息(同理,缓存未命中则数据库读取)。
    4. 匹配计算:布隆过滤器过滤无效广告位,减少数据库查询;预计算模型(如用户画像与广告标签的匹配矩阵)计算匹配得分。
    5. 出价计算:根据匹配得分动态计算CPM(如匹配得分*预算/1000),生成出价。
    6. 组装响应(广告ID、出价、点击率预估),返回客户端。

5) 【面试口播版答案】
面试官您好,设计高并发广告投放系统,核心是分层架构,结合实时出价、预计算匹配和异步处理。前端用Nginx做负载均衡,分发请求到后端集群。后端拆分为请求解析、特征处理、匹配计算、出价计算模块。缓存层用Redis存储用户特征、广告位信息(热点数据),数据库存储冷数据(用户行为、预算)。匹配计算采用布隆过滤器减少数据库查询,预计算模型存储在Redis的Hash或Sorted Set中。出价计算根据匹配结果动态计算CPM/CPC。消息队列异步处理日志和预算更新,避免阻塞。通过数据库分库分表(按用户ID/广告位ID)、读写分离,以及缓存预加载、互斥锁防雪崩,确保百万级QPS下的低延迟和高可用。

6) 【追问清单】

  • 问题1:如何处理缓存击穿?
    回答要点:设置热点数据预加载(如定时任务),或使用互斥锁+缓存(当缓存失效时,用锁保证只有一个请求去数据库加载并缓存,其他请求等待缓存)。
  • 问题2:数据库如何分库分表?
    回答要点:按用户ID或广告位ID分片(如用户ID取模分片,广告位按位置分片),结合读写分离(主从复制,读请求路由到从库,提升读性能)。
  • 问题3:如何保证匹配算法的实时性?
    回答要点:预计算常用广告位与用户特征的匹配规则(如用户画像与广告标签的匹配矩阵),实时计算时结合缓存加速,减少数据库查询。
  • 问题4:系统如何扩容?
    回答要点:水平扩容后端服务器,增加缓存节点(如Redis集群),调整数据库分片策略(如增加分片数量),重新分配缓存分片。
  • 问题5:如何处理请求超时?
    回答要点:设置请求超时时间(如500ms),结合重试机制(指数退避,如第一次重试1秒,第二次2秒,避免雪崩)。

7) 【常见坑/雷区】

  • 坑1:忽略缓存雪崩,只考虑缓存击穿。反问:如果大量缓存同时失效,如何避免系统崩溃?答:设置随机过期时间(TTL随机),或使用熔断降级,避免集中失效。
  • 坑2:没有异步处理,实时任务阻塞主流程。反问:如果用户行为写入数据库导致延迟,如何保证匹配计算不阻塞?答:使用消息队列异步写入,主流程不等待,提高吞吐。
  • 坑3:匹配算法复杂导致延迟高。反问:如果匹配逻辑涉及机器学习模型,如何优化?答:模型训练后,将特征工程后的结果预计算并存储,实时查询时直接使用预计算结果,减少计算量。
  • 坑4:数据库没有读写分离,影响读性能。反问:如果读请求过多,如何提升数据库读性能?答:主从复制,读请求路由到从库,主库负责写,提升读吞吐。
  • 坑5:分布式锁使用不当,导致死锁。反问:如果多个服务同时更新预算,如何避免超卖?答:使用Redis分布式锁,设置锁超时时间(如10秒),避免死锁,超时后自动释放锁。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1