手写滑动窗口算法


	核心是时间段是动态的,根据请求进来的时间,往前数一段时间,看请求量
	如果超过了就提示,没有超过就添加进队列


import java.util.LinkedList;
import java.util.Queue;

public class SlidingWindowCounter {
    // 用队列保存每次操作的时间戳(单位:毫秒)
    private Queue<Long> timestamps = new LinkedList<>();
    // 滑动窗口的时间长度(单位:毫秒)
    private final long windowMillis;

    // 初始化时传入窗口时间(比如1分钟=60000毫秒)
    public SlidingWindowCounter(long windowMillis) {
        this.windowMillis = windowMillis;
    }

    // 记录一次操作(把当前时间戳加入队列)
    public void hit() {
        long now = System.currentTimeMillis();
        timestamps.add(now);
    }

    // 获取当前窗口内的操作次数
    public int getCount() {
        long now = System.currentTimeMillis();
        // 计算窗口的起始时间:当前时间 - 窗口长度
        long windowStart = now - windowMillis;

        // 删除窗口之外的旧数据(队列里时间小于窗口起始时间的都过期了)
        while (!timestamps.isEmpty() && timestamps.peek() < windowStart) {
            timestamps.poll();
        }

        // 剩下的队列长度就是窗口内的计数
        return timestamps.size();
    }

    public static void main(String[] args) throws InterruptedException {
        // 示例:统计最近1秒内的操作次数
        SlidingWindowCounter counter = new SlidingWindowCounter(1000);

        counter.hit(); // 记录第1次
        counter.hit(); // 记录第2次
        Thread.sleep(500); // 等待0.5秒
        counter.hit(); // 记录第3次(此时窗口内应有3次)

        System.out.println("当前计数: " + counter.getCount()); // 输出3

        Thread.sleep(600); // 再等0.6秒(总共1.1秒,最早的2次已过期)
        System.out.println("当前计数: " + counter.getCount()); // 输出1(只剩最后1次)
    }
}

你可能感兴趣的:(算法)