关于滑动窗口算法的应用场景

算法原理

滑动窗口算法是一种基于双指针(又称滑动窗口)的算法,是一种常用的数据处理算法,通常用于解决数组或字符串中的子数组或子串问题。
滑动窗口算法的基本思想是使用两个指针left和right来定义一个窗口,窗口内包含满足特定条件的元素子序列,然后不断移动指针left和right来滑动窗口,以找到相应的子序列。

滑动窗口算法的具体步骤如下:

  • 初始化左指针left和右指针right,使它们都指向序列的起始位置。
  • 将窗口中的元素作为子序列进行处理,满足特定条件的子序列就是算法需要解决的问题。
  • 调整指针left和right,使得窗口向右移动:一般来说,先right边界先扩张,到达指定的位置(根据情况来定),然后left开始扩张,直到指定的位置。
  • 获得窗口内元素集合,执行业务逻辑,如记录最大值、最小值、求和等。
  • 重复上述步骤,直到滑动窗口遍历完整个序列。

由此可见,滑动窗口算法通过定义一个窗口并随着特定条件单向移动,使能够快速找到所需的子序列。
该算法也可以分类如下:

  • 固定窗口大小 —— 窗口大小是固定的,左右边界指针的扩张步长是固定的。
  • 可变窗口大小 —— 允许窗口大小随问题而变化,并且可以针对不同的问题选择最优的窗口大小。

常见应用场景

算法的优点在于时间复杂度为O(n),其中n为数组或字符串的长度。同时,由于只需要维护一个滑动窗口,算法的空间复杂度也比较低,通常为O(1)。因此滑动窗口算法可以将嵌套循环的问题,转换为单层循环问题,降低时间复杂度,提高效率。其可解决的问题,一般有如下特点:

  • 目标数据连续的、有序的、前后关联的数据集合。
  • 窗口可以通过单向递增(如由左向右滑动)实现移动

编程中常见的应用场景如下:

  • 业务接口限流模块,如电商秒杀限流、开放接口请求限流。
  • 离线统计业务场景:根据时间、账号等维度排序,以固定滑窗方式渐进执行直到跑完。
  • 算法题目如求解“无重复字符的最长子串”、“子数组的最大和”、“最长连续子数组”、“正数组中和为k的最长子数组”等,常见于针对字符串、数组、队列的运算。

离线任务

实际工作中会有很多非实时性的、可异步的计算场景,如数据对账、账号风险打分、账号打标签等等,下面拿数据对账作为例子。

按天做数据条数校对

该场景的校对算法主要依赖select conut(*),注意考虑数据量、数据库压力,评估时间窗口的大小(滚动步长),设计流程如下:

按天做数据对账

关于数据对账,一个对账执行周期包含以下几个步骤节点:

  • 拉取原生数据
  • 清洗
  • 保存
  • 对账
  • 差异处理
    当对账的数据非常大(亿级),那么在执行周期里,需要合理切分子任务,控制批次数据的量,避免过程中出现OOM(Out of memory) 。设计流程如下(注意图中的case2):

    备注1:上图简单举例limit 50000,实际上并不建议如此的查询操作,因为limit数过大会产生明显数据库查询耗时,严重时会拖垮数据库。此处可考虑分段、多此执行以累计获得这50000条。
    备注2:需要根据服务占用的内存、服务器性能来确定对账条数(上图示例50000条)。当服务分配4G以上内存时,可考虑区间为2560051200,建议采用多线程并发对账,线程数约服务器cpu数的12倍(需综合判断偏向于cpu密集型、IO密集型)。

限流场景

通常我们说的限流指代的是 限制到达系统的并发请求数,使得系统能够正常的处理 部分 用户的请求,来保证系统的稳定性,同时限流不可避免的会造成用户的请求变慢或者被拒的情况,从而会影响用户体验。这就要求有灵活的限流算法(可配置阈值),在用户体验和系统稳定性之间做平衡。
常见的限流算法有:

  • 计数器
  • 滑动窗口
  • 漏斗算法
  • 令牌桶算法
    实际上,滑动窗口在限流方面并不是最理想的。
posted @ 2023-04-10 14:50  鱼007  阅读(401)  评论(0编辑  收藏  举报