【面试真题拆解】5秒内限10次HTTP接口访问,结合数据结构和算法说说你的思路

面试官问:

做Web项目的时候,会暴露出一些HTTP接口,我现在想对它进行限流,限制5秒内只能访问10次,结合数据结构和算法,看如何实现,说说你的思路

当时只说了个滑动窗口就没说其他的,然后就没有然后了。。。

首先,为什么要限流?

主要有以下三个原因:

  1. 防止恶意刷接口,比如爬虫爬数据、黑客DDoS攻击。
  2. 保护服务器不被压垮,比如一个接口挂了,拖垮整个服务。
  3. 保证核心业务的可用性,比如大促场景下,支付接口优先,对普通接口进行限流。

技术选型

方案 数据结构+算法 核心思想 优缺点 适用场景
固定窗口计数器 数组/Map + 时间戳 把时间分成固定的窗口,每个窗口内计数 简单易实现; 有临界问题(比如4.9秒刷10次,5.1秒又刷10次,实际0.2秒内刷了20次) 对精度要求不高的场景
滑动窗口计数器 本地:LinkedList(双向链表) 分布式:Redis ZSet(有序集合) + 时间戳 窗口是"滑动"的,只保留当前窗口内的请求 解决了固定窗口的临界问题; 本地版 LinkedList 删头加尾 O (1),分布式版 ZSet 按时间范围操作高效; 本地版不适合分布式集群 固定时间窗口内精确计数的场景
漏桶算法 队列 + 定时器 像漏桶一样,请求先存到队列里,然后匀速处理 可以削峰填谷; 突发流量处理不了(秒杀时很多请求直接被拒) 对流量稳定性要求高的场景(比如消息队列)
令牌桶算法 队列 + 定时器 像令牌桶一样,匀速生成令牌,请求拿到令牌才能通过 可以削峰填谷,也 可以处理突发流量 对流量稳定性和突发流量都有要求的场景(比如API网关)

滑动窗口计数器

滑动窗口的核心,是窗口不再是静止分段的,而是随当前时间连续移动、互相重叠的:

比如固定窗口,窗口是死的,0-5秒、5-10秒,边界固定不变。

而滑动窗口,窗口的右边界永远是当前请求的时间,左边界永远是当前时间 - 窗口大小,窗口会跟着每一次请求一直往前滑。

数据结构选型

本地:LinkedList(双向链表)

选择双向链表是因为我们需要频繁删除链表头部的过期时间戳,并且还需要频繁在链表尾部新增新的请求时间戳,而双向链表的删头、加尾操作时间复杂度都是O(1),效率极高。

分布式:Redis ZSet(有序集合)

Web项目基本都是集群部署,本地计数器无法多实例同步,考虑用Redis实现。

选择Redis中的ZSet数据结构,ZSet的score字段可以存请求的时间戳,天然支持按时间范围排序。

实现逻辑

每次请求进来,执行 3 步:

  1. 删掉所有早于当前时间 - 窗口大小的请求
  2. 统计当前窗口内的请求数,超过 10 次直接拒绝
  3. 把当前请求的时间戳加入数据结构,放行请求

小贴士

  1. 令牌桶的令牌生成速度要合理

不能太快(等于没限流),也不能太慢(很多请求被拒),要根据业务场景调整。

  1. Redis ZSet的过期时间要设置对

要设置成窗口大小+一点缓冲(比如1秒),防止数据提前过期,导致计数不准确。

相关推荐
Raink老师1 天前
【AI面试临阵磨枪-79】实时数据 RAG:订单、商家、物流、天气、动态库存
人工智能·面试·职场和发展
Cosolar1 天前
Chroma向量库面试学习指南
数据库·人工智能·面试·职场和发展·数据库架构
kkeeper~1 天前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
小江的记录本1 天前
【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·面试·maven
2401_868534781 天前
论企业网络设计
数据结构
2401_876964131 天前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
小江的记录本1 天前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
小江的记录本1 天前
【JVM虚拟机】垃圾回收GC:垃圾收集器:G1:Region分区、Mixed GC、回收流程、适用场景(高频)(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·spring cloud·面试
c238561 天前
vector(下)
数据结构·算法
z落落1 天前
C# 冒泡排序+选择排序 + Array.Sort 自定义排序
数据结构·算法