当前位置: 首页 > news >正文

深入浅出限流算法(一):简单但有“坑”的固定窗口计数器

在现代分布式系统和 API 设计中,限流 (Rate Limiting) 是一个不可或缺的环节。它像一个尽职的门卫,保护着我们的服务资源,防止因突发流量或恶意攻击导致系统过载,同时也能确保资源的公平分配。

实现限流的算法多种多样,各有优劣。今天,我们就从最基础、最简单的一种开始聊起:计数器算法(固定窗口)。

什么是固定窗口计数器?

想象一下,一个热门景点入口,规定每分钟只能进入 100 位游客。工作人员手里有一个计数器和一个秒表。

  1. 窗口开始: 每分钟开始时(例如,10:00:00),工作人员将计数器清零。

  2. 请求到达: 每当有游客想进入(相当于一个 API 请求),工作人员就将计数器加 1。

  3. 检查限制: 在增加计数器后,工作人员检查计数器的数字是否超过了 100。

    • 如果未超过 100,游客被允许进入。
    • 如果已超过 100,则告知该游客:“本分钟名额已满,请稍后再试”(请求被拒绝)。
  4. 窗口结束与重置: 当这一分钟结束(到达 10:01:00),无论之前计数是多少,工作人员立即将计数器清零,准备下一个一分钟的计数。

这就是固定窗口计数器的核心思想:在一个固定的时间窗口内,维护一个计数器,记录该窗口接收到的请求数量。当请求到来时,计数器加一,如果超过设定的阈值,则拒绝请求。每个时间窗口结束后,计数器自动清零。

Java 实现(巧妙版)

下面是一个使用 Java 实现的固定窗口计数器。这个版本的巧妙之处在于,它避免了使用一个单独的定时任务来周期性地重置计数器,而是在每次请求到达时检查是否需要开启新的窗口。

import java.time.LocalTime; // 这个 import 在代码中实际未使用,可以移除
import java.util.concurrent.atomic.AtomicInteger;public class RateLimiterSimpleWindow {// 阈值 (例如,每秒允许的请求数 QPS)private static Integer QPS = 2;// 时间窗口大小(毫秒)private static long TIME_WINDOWS = 1000; // 1秒// 请求计数器 (使用 AtomicInteger 保证线程安全)private static AtomicInteger REQ_COUNT = new AtomicInteger(0);// 当前时间窗口的开始时间戳private static long START_TIME = System.currentTimeMillis();// 使用 synchronized 确保检查时间、重置计数器和更新开始时间这组操作的原子性public synchronized static boolean tryAcquire() {long now = System.currentTimeMillis();// 1. 检查当前时间是否已经超出了当前窗口if ((now - START_TIME) > TIME_WINDOWS) {// 如果是,说明需要开启新的时间窗口REQ_COUNT.set(0); // 重置计数器START_TIME = now; // 将窗口的开始时间更新为当前时间}// 2. 无论是否重置,都尝试为当前请求增加计数//    并检查增加后的计数值是否仍在允许的范围内return REQ_COUNT.incrementAndGet() <= QPS;}public static void main(String[] args) throws InterruptedException {// 简单的测试逻辑for (int i = 0; i < 10; i++) {Thread.sleep(250); // 每 250ms 发送一个请求long currentTimeMillis = System.currentTimeMillis();if (tryAcquire()) {System.out.println(currentTimeMillis + " 请求成功 -> ✅");} else {System.out.println(currentTimeMillis + " 请求失败 -> ❌");}}}
}

代码解读:

  • ​QPS​: 定义了每个时间窗口内允许的最大请求数(这里是 2)。

  • ​TIME_WINDOWS​: 定义了时间窗口的长度(这里是 1000 毫秒,即 1 秒)。

  • ​REQ_COUNT​: 使用 AtomicInteger​ 来存储当前窗口的请求计数。AtomicInteger​ 是线程安全的,允许多个线程并发地增加计数值而不会出错。

  • ​START_TIME​: 记录当前时间窗口的开始时间戳。

  • ​tryAcquire()​: 这是核心方法,用于尝试获取一个请求许可。

    • ​synchronized static​: 这个关键字非常重要。因为 REQ_COUNT​ 和 START_TIME​ 都是 static​ 的(所有线程共享),我们需要确保检查时间、重置计数器、更新开始时间这三个操作组合在一起是原子的。否则,可能多个线程同时判断窗口已过期,并多次重置计数器,导致逻辑错误。synchronized​ 保证了同一时刻只有一个线程能执行 tryAcquire​ 方法块内的代码。
    • 窗口检查与重置: if ((now - START_TIME) > TIME_WINDOWS)​ 判断当前时间 now​ 是否已经超过了窗口开始时间 START_TIME​ 加上窗口长度 TIME_WINDOWS​。如果是,说明旧窗口已结束,需要重置计数器 REQ_COUNT.set(0)​ 并将 START_TIME​ 更新为当前时间 now​,标志着新窗口的开始。
    • 计数与判断: REQ_COUNT.incrementAndGet()​ 原子地将计数器加 1,并返回增加后的值。然后将这个新值与 QPS​ 比较。如果小于等于 QPS​,则返回 true​(请求成功);否则返回 false​(请求被限流)。

优点

  1. 简单直观:算法逻辑和实现都非常简单,容易理解和部署。
  2. 内存占用低:只需要存储一个计数器和一个时间戳,资源消耗很小。

缺点:临界突变问题 (Edge Burst Problem)

这是固定窗口计数器算法最主要的缺陷。因为它只关心当前窗口的总量,并且在窗口边界处进行硬性切换,可能导致在两个窗口的交界处,实际通过的请求速率远超预期。

举个例子:

假设我们的 QPS 限制是 10(即每秒最多 10 个请求)。

  • 在第 1 秒的最后 100 毫秒(例如 0.9s 到 0.999s),一个客户端疯狂发送了 10 个请求,都被允许了,因为计数器从 0 增加到了 10。
  • 时间到达第 2 秒(1.0s),窗口立刻重置,计数器归零。
  • 在第 2 秒的前 100 毫秒(例如 1.0s 到 1.099s),该客户端又疯狂发送了 10 个请求,由于计数器刚清零,这些请求也都被允许了。

结果是什么? 在横跨两个窗口边界的短短 200 毫秒内,系统实际处理了 20 个请求!这相当于瞬时速率达到了 100 QPS (20 请求 / 0.2 秒),远远超过了我们设定的 10 QPS 的平均限制。这种在窗口边界可能发生的流量“突刺”就是临界突变问题。

什么时候用?

尽管有临界突变的问题,固定窗口计数器因其简单性,在某些场景下仍然可用:

  • 对限流精度要求不高的内部系统或工具。
  • 可以容忍短时流量突增的应用。
  • 作为更复杂限流算法的基础组件。

但对于需要严格、平滑地控制流量的场景(例如对外开放的 API),固定窗口计数器通常不是最佳选择。

总结

固定窗口计数器是最基础的限流算法,实现简单、资源消耗少。但它的主要缺点是临界突变问题,可能导致在窗口边界处的瞬时流量远超预期。


相关文章:

深入浅出限流算法(一):简单但有“坑”的固定窗口计数器

在现代分布式系统和 API 设计中&#xff0c;限流 (Rate Limiting) 是一个不可或缺的环节。它像一个尽职的门卫&#xff0c;保护着我们的服务资源&#xff0c;防止因突发流量或恶意攻击导致系统过载&#xff0c;同时也能确保资源的公平分配。 实现限流的算法多种多样&#xff0…...

项目上线流程梳理(Linux宝塔面板)

项目部署&#xff08;Linux宝塔面板&#xff09; 一、准备工作 1、 后端项目 梳理配置添加application-prod.yml使用maven进行打包生成jar包 2、前端项目 修改request.ts请求的后端端口&#xff08;服务器地址&#xff09;打包 二、服务器 1、服务器环境安装 2、初始化数…...

MCP Servers玩玩WebUI自动化

MCP Servers快速了解 一文搞懂 MCP Servers mcp server网站 https://mcpservers.orghttps://mcp.sohttps://glama.ai/mcp/servershttps://www.pulsemcp.com 一、安装&配置mcp clients mcp clients可以使用客户端&#xff08;常见claude desktop&#xff0c;但claude需…...

永磁同步电机控制算法-转速环电流环SMC控制器

一、原理介绍 为改进传统PI转速环电流环控制器易超调、抗干扰性能差的问题&#xff0c;转速环采用一阶滑模控制器&#xff0c;电流环采用二阶滑模控制器。 二、仿真验证 在MATLAB/simulink里面验证所提算法&#xff0c;采用和实验中一致的控制周期1e-4&#xff0c;电机部分计…...

Nginx支持HTTP2/HTTP3的并用CURL测试

对比HTTP2和HTTP3 HTTP/3 相比 HTTP/2 的主要优势&#xff1a; 项目HTTP/2HTTP/3传输层基于 TCP&#xff08; TLS&#xff09;基于 QUIC&#xff08;内置 TLS&#xff09;建立连接速度慢&#xff0c;至少 2~3 次握手&#xff08;TCP TLS&#xff09;快&#xff0c;只需 1 次握…...

阅读MySQL实战45讲第11天

目录 引言&#xff1a; 基本原理 排序方式 索引排序 文件排序&#xff08;File Sort&#xff09; 优化建议 一、全字段排序 二、rowid 排序 如果 MySQL 认为排序的单行长度太大会怎么做呢&#xff1f; 1. 使用磁盘临时表 2. 分阶段排序 3. 产生警告或错误 三、全字段排序 VS ro…...

linux 使用nginx部署vue、react项目

前言 本文基于&#xff1a;操作系统 CentOS Stream 8 使用工具&#xff1a;Xshell8、Xftp8 1.安装依赖 安装gcc、gcc-c yum install gcc gcc-c -y安装pcre、pcre-devel yum install pcre pcre-devel -y安装zlib、zlib-devel yum install zlib zlib-devel -y安装openssl、…...

逆向设计——CWDM_splitter

一、创建结构 switchtolayout; selectall; delete;## SIM PARAMS num_wg = 4; wg_width = 0.5e-6; out_wg_dist = 1e-6; mode_width = 3*wg_width; total_wg_h = num_wg*wg_width + (num_wg-1)*out_wg_dist;opt_size_x=6e-6; opt_size_y=6e-6;size_x=opt_size_x+1e-6; size_y=o…...

单片机-89C51部分:7、中断

飞书文档https://x509p6c8to.feishu.cn/wiki/A5gcwyL5giq1JOkkcsscn8eLnzf 一、中断的作用 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的&#xff0c;中断功能的存在&#xff0c;很大程度上提高了单片机处理外部或内部事件的能力。它也是单片机最重要的功…...

小波变换和图像的融合

看到一篇比较有趣的文章&#xff0c;是将小波变换融入到图像配准过程中。论文题目是Deformable medical image registration based on wavelet transform and linear attention。论文提出了一种基于小波变换和线性注意力的可变形医学图像配准方法&#xff0c;通过小波下采样模块…...

2799. 统计完全子数组的数目

给你一个由 正 整数组成的数组 nums 。 如果数组中的某个子数组满足下述条件&#xff0c;则称之为 完全子数组 &#xff1a; 子数组中 不同 元素的数目等于整个数组不同元素的数目。 返回数组中 完全子数组 的数目。 子数组 是数组中的一个连续非空序列。 示例 1&#xff…...

docker镜像构建常用参数

要退出出去ctrlpq&#xff0c;或者直接输入exit也可以直接退出 这样就生成了可以这么用&#xff0c;但安全性比较差&#xff0c;不利于审计 企业里构建的镜像这样&#xff1a; “.”是构建的地点是当前的意思&#xff1b;构建了一层在[2/2]RUN touch /leefile里面 发现有我…...

如何用postman进行批量操作

业务场景&#xff1a; 有些时候&#xff0c;我们会需要批量的将SAP B1系统中的几千条的数据删除或者取消单据&#xff0c;这个时候&#xff0c;一条条去操作&#xff0c;指定是到猴年马月了。SAP Business One本身提供了DTW这个工具&#xff0c;但是这个更新&#xff0c;可以操…...

【MCP】第三篇:Cline工具链路追踪——解码“协议引擎“的神经传导奥秘

【MCP】第三篇&#xff1a;Cline工具链路追踪——解码"协议引擎"的神经传导奥秘 一、引言二、CloudFlare AI Gateway2.1 核心定位2.2 核心能力2.3 与MCP协议逆向的深度契合 三、VSCode Cline与CloudFlare联调实战3.1 CloudFlare配置3.2 VSCode Cline配置3.3 联调实战…...

HTML标记语言_@拉钩教育【笔记】

目录 1.文本标签 2.格式化标签 3.图片标签 4.超链接标签 5.表格标签 6表单标签 6.1 6.2 6.3 7.行内框架(超链接内套一个页面) 8.多媒体标签(音/视频) 1.文本标签 2.格式化标签 3.图片标签 4.超链接标签 5.表格标签 6表单标签 6.1 6.2 6.3 7.行内框架(超链接内套一个…...

SDK游戏盾、高防IP、高防CDN三者的区别与选型指南

在网络安全防护领域&#xff0c;SDK游戏盾、高防IP和高防CDN是常见的解决方案&#xff0c;但各自的功能定位、技术实现和适用场景差异显著。本文将通过对比核心差异&#xff0c;帮助您快速理解三者特点并选择适合的防护方案。 一、核心功能定位 SDK游戏盾 功能核心&#xff1a…...

C++中的格式化字符串

C中的格式化字符串 fmt 库简介 {fmt}是一个开源的、现代化的C格式化库&#xff0c;由Victor Zverovich创建。它提供了一种安全、快速且方便的字符串格式化方式&#xff0c;其设计理念受到了Python的str.format()的启发 fmt库的主要特点 易用性&#xff1a;使用简洁的语法&a…...

民办生从零学C的第十二天:指针(1)

每日励志&#xff1a;拼搏十年&#xff0c;征战沙场&#xff0c;不忘初心&#xff0c;努力成为一个浑身充满铜臭味的有钱人。 一.内存和地址 1.内存 计算机内存是一系列存储单元的集合&#xff0c;每个存储单元都有唯一的地址来标识。这些存储单元用于存储程序的数据和指令。…...

复习Vue136~180

1.使用create-vue创建项目 npm init vuelatest 项目目录和关键文件&#xff1a; new Vue() 创建一个应用实例 > createApp()、createRouter() createStore() 、将创建实例进行了封装&#xff0c;保证每个实例的独立封闭性。 禁用vue2的插件vuter 使用vue3的插件volar scrip…...

高炉项目中DeviceNET到Ethernet的转换奥秘

在工业自动化的世界中&#xff0c;高炉项目中的数据通信至关重要。其中DeviceNET和Ethernet作为两种主流的网络协议&#xff0c;扮演着不可或缺的角色。它们之间的转换不仅仅是技术上的桥梁&#xff0c;更是实现信息高效传递的关键。今天&#xff0c;我们就来揭开从DeviceNET到…...

awk之使用详解(Detailed Explanation of Using AWK)

awk使用详解 1. 入门 1.1 什么是 awk&#xff1f; ①Awk是一种文本处理工具&#xff0c;适用于处理结构化数据&#xff0c;例如表格数据。 ②它可以读取一个或多个文本文件&#xff0c;并执行模式扫描和处理等指定的操作。 ③基本逻辑涉及数据的提取&#xff0c;排序和计算…...

TDR阻抗会爬坡? 别担心,不是你的错,你只是不够了解TDR!

在背板系统或任何长走线设计里&#xff0c;你大概都碰过这画面&#xff1a; TDR 曲线一开始乖乖在 92 Ω&#xff0c;但越往末端、阻抗越爬越高&#xff0c;来到最高 97 Ω&#xff0c;心里瞬间凉半截 &#x1f612; &#xff0c;「难不成... 板厂又翻车了吗&#xff1f;」 然…...

TypeScript之基础知识

基础知识 1. 基本类型 类型描述string字符串&#xff08;如 "hello"&#xff09;number数字&#xff08;整数或浮点数&#xff0c;支持二进制、八进制、十六进制&#xff09;boolean布尔值&#xff08;true/false&#xff09;null空值&#xff08;需显式声明&#x…...

SNMP协议之详解(Detailed Explanation of SNMP Protocol)

SNMP协议之详解 一、前言 SNMP&#xff0c;被形象地喻为网络世界大的工具箱&#xff0c;使他们能的“智慧守护者”&#xff0c;它为网络管理员装备了一套功能强够实现对网络设备状态的实时监控、性能数据的全面收集、远程配置的灵活管理以及故障事件的即时响应。借助SNMP&…...

机器学习-入门-线性模型(2)

机器学习-入门-线性模型(2) 3.4广义线性回归 一般形式&#xff1a; y g − 1 ( w T x b ) y g^{-1} \left( w^T x b \right) yg−1(wTxb) 单调可微的联系函数 (link function) 令 g ( ⋅ ) ln ⁡ ( ⋅ ) g(\cdot) \ln (\cdot) g(⋅)ln(⋅) 则得到对数线性回归 ln ⁡…...

【问题】docker容器修改环境变量的方式

问题 启动n8n之后&#xff0c;docker容器提示&#xff1a; There is a deprecation related to your environment variables. Please take the recommended actions to update your configuration: 2025-04-28 09:20:08 - N8N_RUNNERS_ENABLED -> Running n8n without tas…...

基于 Spring Boot 瑞吉外卖系统开发(八)

基于 Spring Boot 瑞吉外卖系统开发&#xff08;八&#xff09; 自动填充公共字段 MyBatis-Plus公共字段自动填充&#xff0c;也就是在插入或者更新的时候为指定字段赋予指定的值&#xff0c;使用它的好处就是可以统一对这些字段进行处理&#xff0c;降低了冗余代码的数量。本…...

LeetCode热题100--560.和为K的子数组(前缀和)--中等

1.题目 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2 示例 2&#xff1a; 输入&#xff1a;nums […...

搭建 Spark YARN 模式集群指南

在大数据处理领域&#xff0c;Apache Spark 凭借其卓越的性能和易用性广受青睐。而 YARN&#xff08;Yet Another Resource Negotiator&#xff09;作为 Hadoop 的资源管理框架&#xff0c;能高效管理集群资源。将 Spark 与 YARN 结合&#xff0c;以 YARN 模式搭建集群&#xf…...

服务器部署,Nginx安装和配置

Nginx简介 Nginx是一款轻量级和高性能的web服务器、反向代理服务器和电子邮件代理服务器。你可以使用Nginx实现网页的部署&#xff0c;解决跨域问题实现邮件服务器&#xff0c;甚至Nginx也可以实现音视频推流拉流服务器&#xff0c;Nginx可以实现的功能远超你的想象&#xff0…...

Java后端接口调用拦截处理:注解与拦截器的实现

在Java开发中&#xff0c;对后端接口调用进行拦截处理是一种常见的需求&#xff0c;通常用于权限验证、Token校验、状态更新等操作。本文将围绕 Spring框架的拦截器&#xff08;Interceptor&#xff09;、Spring AOP&#xff08;面向切面编程&#xff09; 和 Spring Security 三…...

C++(初阶)(十四)——多态

多态 面向对象的其中一大特征。 多态多态的定义及构成多态的构成条件多态的实现条件多态的分类编译时多态性运行时的多态性 虚函数定义不能成为虚函数的函数 虚函数重写&#xff08;覆盖&#xff09;选择题虚函数重写的其他问题析构函数的重写override 和final关键字重载/重写…...

PyQt6基础_QThread

目录 前置 代码&#xff1a; 运行 正常运行 QThread运行报错 视频 前置 1 PySide6.QtCore.QThread - Qt for Python QThread官方文档 2 长时间任务可以放到QThread中执行&#xff0c;避免占用主线程导致界面卡顿无法操作 代码&#xff1a; import traceback,sys fro…...

工业通讯现场中关于EtherCAT转TCPIP网关的现场应用

在当今工业自动化的浪潮中&#xff0c;EtherCAT技术以其高效、实时的特性成为了众多制造业的首选。然而&#xff0c;随着工业互联网的发展&#xff0c;对于数据的远程访问和云平台集成的需求日益增长&#xff0c;这就需要将EtherCAT协议转化为更为通用的TCP/IP协议。于是开疆智…...

vite创建vue3项目并进行配置

创建项目 方式一 执行以下命令 之后输入项目名称 选择框架 选择语言 例如 pnpm create vite此方式创建的项目较为干净 0手起步 只包含一些基础依赖 例如vue vite等 项目目录如下 "scripts": {"dev": "vite","build": "vue-tsc -…...

LeetCode 热题 100_最小路径和(92_64_中等_C++)(多维动态规划)

LeetCode 热题 100_最小路径和&#xff08;92_64&#xff09; 题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;多维动态规划&#xff09;&#xff1a; 代码实现代码实现&#xff08;思路一&#xff08;多维动态规划&…...

关于常量指针和指向常量的指针

关于指针&#xff0c;对于常量指针和指向常量的指针也是傻傻分不清。看到定义时&#xff0c;不知道是指针不能变&#xff0c;还是指针指向的内容不能变量。 先看形式&#xff1a; const char * A; char * const B; 这两种有什么区别&#xff1f;傻傻分不清。 A这种定义&am…...

新时代下的存储过程开发实践与优化

随着现代应用系统的复杂度不断增加&#xff0c;数据库作为核心的数据存储和处理引擎&#xff0c;其性能和可靠性显得尤为重要。存储过程&#xff08;Stored Procedure&#xff09;作为一种封装在数据库中的应用逻辑&#xff0c;使得开发者能够在数据库层面实现数据操作、数据校…...

4月28日日记

2025年4月28日 星期一 晴 今天过得格外充实&#xff0c;也充满了收获与喜悦。 下午&#xff0c;我参加了学校的五四述职大会。各个学院的团委书记依次上台&#xff0c;汇报过去一年的工作成果。看着大家在台上分享着各自学院的精彩故事&#xff0c;我深受触动。他们所展示的活…...

大模型性能测试

当我们部署了大模型并对外提供服务时&#xff0c;我们通常都想了解一下大模型能够支持多少个并发访问&#xff0c;在不同的并发数下&#xff0c;模型的性能如何。了解这些信息有助于我们更好的对算力进行评估&#xff0c;为用户带来更好的性能体验。 大模型通常是通过API接口的…...

利用 Google Earth Engine 探索江宁区 2010 - 2020 年 EVI 时空变化

引言 增强型植被指数&#xff08;Enhanced Vegetation Index&#xff0c;EVI&#xff09;是一种用于量化植被生长状态和覆盖程度的重要指标&#xff0c;它在监测植被动态、生态环境评估以及气候变化研究等领域发挥着关键作用。Google Earth Engine&#xff08;GEE&#xff09;…...

IEC 61850标准协议解读 2.基于Java的MMS实现

专栏文章目录 第一章 IEC 61850标准协议解读 0.导言 第二章 IEC 61850标准协议解读 1.建模讲解 第三章 IEC 61850标准协议解读 2.基于Java的MMS实现 目录 专栏文章目录前言1 依赖库引入2 创建服务端3 创建客户端4 读写模型4.1 服务端读写4.2 客户端读写 5.报告6 文件服务6.1 读…...

花费7元训练自己的GPT 2模型

在上一篇博客中&#xff0c;我介绍了用Tensorflow来重现GPT 1的模型和训练的过程。这次我打算用Pytorch来重现GPT 2的模型并从头进行训练。 GPT 2的模型相比GPT 1的改进并不多&#xff0c;主要在以下方面&#xff1a; 1. GPT 2把layer normalization放在每个decoder block的前…...

【android bluetooth 协议分析 06】【l2cap详解 10】【通过avdtp连接流程,感受l2cap通道的生命周期变化】

本篇我们通过分析一个具体的实例&#xff0c;来直观感受一下 l2cap 中通道的 状态变化。 1. 环境描述&#xff1a; 车机&#xff1a; a2dp sink手机: a2dp source场景&#xff1a; 手机主动 触发 连车机 声明一下&#xff1a; 分析的btsnoop 和 logcat 还有源码&#xff0c;…...

如何在idea中写spark程序。

要在IntelliJ IDEA中编写Spark程序&#xff0c;你可以按照以下步骤进行&#xff1a; 1. 安装和配置Java&#xff1a;确保你的计算机上已经安装了Java Development Kit (JDK)&#xff0c;并且已配置好 JAVA_HOME 环境变量。 2. 安装IntelliJ IDEA&#xff1a;下载并安装Inte…...

Pytest-mark使用详解(跳过、标记、参数 化)

1.前言 在工作中我们经常使用pytest.mark.XXXX进行装饰器修饰&#xff0c;后面的XXX的不同&#xff0c;在pytest中有不同的作 用&#xff0c;其整体使用相对复杂&#xff0c;我们单独将其抽取出来做详细的讲解。 2.pytest.mark.skip()/skipif()跳过用例 import pytest #无条…...

[Android] GKD v1.10.3

[Android] GKD 链接&#xff1a;https://pan.xunlei.com/s/VOOwKvmwpLoLl7fLi6wJZKK-A1?pwd8mey# GKD&#xff08;详情请戳 作者项目地址&#xff09;是一款免费开源简洁多规则的自动跳过广告的软件&#xff0c;整体基于kotlin开发&#xff0c;免root即可使用。简而言之&am…...

C22-作业练习之最大公约数与最小公倍数

作业练习之最大公约数与最小公倍数 代码 #include <stdio.h> int main() {//变量初始化int m,n;int i,gcd,lcm;//数据录入printf("请输入两个整数:");scanf("%d %d",&m,&n);//求最大公约数int min(m<n)?m:n; //找m与n的最小值for(imi…...

信号完整性简介第一篇

本章将讲述信号完整性相关问题。首先提出什么是高速系统设计中的信号完整性&#xff0c;其次结合影响信号完整性的各种因素&#xff0c;深入讨论在高速系统设计过程中会碰到的几类信号完整性问题&#xff0c;并对每一类问题提出相应的预防措施和解决方案。 需要说明&#xff0…...

Qt开发环境的安装与问题的解决(2)

文章目录 1. Qt开发环境安装的说明2. 通过安装包进行安装3. 通过在线下载程序 解决问题下载 https....网路错误问题解决开始安装--第一部分开始安装--第二部分 4. 建议配置环境变量&#xff08;非必须&#xff09;配置环境变量的意义 简介&#xff1a;这篇文章主要分享Qt开发环…...