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

Guava限流神器:RateLimiter使用指南

1. 引言

可能有些小伙伴听到“限流”这个词就觉得头大,感觉像是一个既复杂又枯燥的话题。别急,小黑今天就要用轻松易懂的方式,带咱们一探RateLimiter的究竟。

想象一下,当你去超市排队结账时,如果收银台开得越多,排队的人就会越少,速度也就越快。但如果超市为了节省成本,只开了一两个收银台,那排队的速度就会大大降低,甚至造成拥堵。在软件世界里,特别是在处理网络请求或资源访问时,也存在类似的问题。这时候,RateLimiter就像是那个调节收银台开放数量的智能系统,它能帮助我们控制资源的访问速率,防止过载。

2. RateLimiter的基本概念

我们得先弄清楚RateLimiter到底是什么。简单来说,RateLimiter是一个用于控制操作频率的工具。就像你家的水龙头,你可以调节它的开关,控制水流的大小。RateLimiter也一样,它可以控制程序中某个操作的执行频率。

处理网络请求或者数据库操作时,这个工具显得尤为重要。想象一下,如果咱们的服务器接到太多请求,或者数据库同时被大量查询,没有任何限制地处理这些请求,服务器和数据库可能就会因为负载过重而崩溃。这就像是一个突然涌入的人潮,把超市挤得水泄不通。RateLimiter能帮助我们像调节水龙头一样,合理分配处理能力,确保系统的稳定运行。

RateLimiter是怎么工作的呢?它其实是基于令牌桶算法的。简单来说,这个算法就像是一个放有令牌的桶,桶里的令牌按固定速率放入。每次操作(比如一个网络请求)都需要从桶里取走一个令牌。如果桶里没有令牌了,操作就需要等待,直到桶里再次有了令牌。这样,操作的频率就被控制住了。

让咱们来看一个简单的例子,用Java代码实现RateLimiter:

import com.google.common.util.concurrent.RateLimiter;public class RateLimiterDemo {public static void main(String[] args) {// 创建一个每秒放入5个令牌的RateLimiterRateLimiter limiter = RateLimiter.create(5.0);for (int i = 0; i < 10; i++) {// 请求一个令牌limiter.acquire();System.out.println("处理请求: " + i);}}
}

这段代码创建了一个RateLimiter,它每秒产生5个令牌。在一个循环中,我们通过acquire()方法

从RateLimiter获取令牌。如果令牌不够,acquire()会阻塞,直到获取到令牌。

PS: 小黑收集整理了一份超级全面的复习面试资料包,在这偷偷分享给你~
链接:https://sourl.cn/CjagkK 提取码:yqwt

3. Guava RateLimiter的工作原理

现在咱们来深入挖掘一下RateLimiter的内部机制。了解它是如何工作的,不仅能帮助我们更好地使用它,还能让我们在遇到问题时,更有针对性地解决。

令牌桶算法

RateLimiter的核心是一种被称为“令牌桶算法”的东西。想象一个桶,这个桶以固定速率往里面放入小令牌。每次咱们的程序想要执行一个操作(比如发起一个网络请求),就需要从这个桶里取出一个令牌。如果桶空了,意味着令牌用完了,操作就得等一等,直到桶里再次有令牌。这个过程控制了操作的频率,确保了咱们的程序不会因为太“急躁”而崩溃。

平滑速率限制

Guava的RateLimiter不仅仅是简单地实现了令牌桶算法,它还提供了“平滑”速率的限制。平滑限制意味着RateLimiter会尽量平均地分配令牌,而不是突然间就把所有令牌都释放出来。这种方式更加符合实际应用场景,比如处理网络请求时,咱们通常希望请求以相对平稳的速率处理,而不是一会儿很快一会儿很慢。

SmoothBursty与SmoothWarmingUp

RateLimiter提供了两种模式:SmoothBursty和SmoothWarmingUp。

  • SmoothBursty:这种模式适合于突发请求较多的场景。它允许在短时间内处理大量请求,然后速率会逐渐下降到稳定状态。

  • SmoothWarmingUp:这个模式适用于需要预热的场景。它会在启动时逐渐增加发放令牌的速率,直到达到稳定状态。这对于那些刚开始时资源较少但随后需要稳定运行的系统很有用。

让咱们通过一些Java代码来看看这两种模式:

import com.google.common.util.concurrent.RateLimiter;public class RateLimiterModes {public static void main(String[] args) {// SmoothBursty模式RateLimiter burstyLimiter = RateLimiter.create(5.0); // 每秒5个令牌// 这里模拟请求,观察令牌获取情况// SmoothWarmingUp模式RateLimiter warmingUpLimiter = RateLimiter.create(5.0, 1, TimeUnit.SECONDS); // 每秒5个令牌,预热时间1秒// 同样模拟请求,观察令牌获取情况}
}

在这段代码中,小黑创建了两个RateLimiter的实例,分别代表两种不同的模式。可以看到,通过简单的API调用,就能实现复杂的限流逻辑。

理解了RateLimiter的内部机制后,咱们就能更好地理解它为什么能有效地控制操作频率,保证系统的稳定性。同时,了解这些原理也能帮助咱们根据不同的应用场景选择合适的RateLimiter模式。

4. 实际代码示例

基本使用

咱们先来看一个最基础的RateLimiter使用案例。在这个例子中,小黑会创建一个RateLimiter,然后模拟一系列请求,看看RateLimiter是如何控制请求速率的。

import com.google.common.util.concurrent.RateLimiter;public class BasicRateLimiterExample {public static void main(String[] args) {// 创建一个每秒允许2个请求的RateLimiterRateLimiter limiter = RateLimiter.create(2.0);for (int i = 1; i <= 10; i++) {double waitTime = limiter.acquire(); // 请求令牌并获取等待时间System.out.println("处理请求 " + i + ",等待时间: " + waitTime + "秒");}}
}

这段代码中,小黑创建了一个每秒允许两个请求的RateLimiter。通过循环模拟了10个请求,并打印每个请求的等待时间。这个简单的例子能帮助咱们直观地看到RateLimiter如何控制请求的速率。

高级用法

现在,咱们来看一个更高级的用法。在这个例子中,小黑会使用SmoothWarmingUp模式的RateLimiter,这种模式对于需要“预热”过程的场景非常适用。

import com.google.common.util.concurrent.RateLimiter;
import java.util.concurrent.TimeUnit;public class AdvancedRateLimiterExample {public static void main(String[] args) {// 创建一个预热时间为10秒,每秒5个请求的RateLimiterRateLimiter warmingUpLimiter = RateLimiter.create(5.0, 10, TimeUnit.SECONDS);for (int i = 1; i <= 10; i++) {double waitTime = warmingUpLimiter.acquire(); // 请求令牌并获取等待时间System.out.println("处理请求 " + i + ",等待时间: " + waitTime + "秒");}}
}

在这段代码中,RateLimiter的预热时间被设为10秒,意味着它会在这段时间内逐渐增加发放令牌的速率,直到达到每秒5个请求的速度。这个例子展示了RateLimiter在应对需要平滑启动或增加负载的场景时的强大能力。

实际应用场景

让咱们想象一个实际的应用场景。比如说,在一个Web服务中,咱们可能需要控制某些接口的调用频率,以避免服务器过载。这时,RateLimiter就能大显身手了。

import com.google.common.util.concurrent.RateLimiter;
import java.util.stream.IntStream;public class WebServiceRateLimiting {private final RateLimiter rateLimiter = RateLimiter.create(1.0); // 每秒1个请求public void handleRequest(int requestId) {if (rateLimiter.tryAcquire()) {System.out.println("处理请求: " + requestId);// 进行实际的请求处理} else {System.out.println("请求 " + requestId + " 被限流");// 可以返回错误信息或者进行其他操作}}public static void main(String[] args) {WebServiceRateLimiting service = new WebServiceRateLimiting();IntStream.rangeClosed(1, 5).forEach(service::handleRequest);}
}

在这个例子中,小黑创建了一个Web服务的简化模型,其中使用

RateLimiter来控制请求的处理频率。如果请求过于频繁,超出了RateLimiter的限制,那些超出限制的请求就会被拒绝。

5. 高级特性和最佳实践

高级配置

RateLimiter除了基本的创建和使用之外,还提供了一些高级的配置选项,让咱们可以根据具体需求调整其行为。

比如,RateLimiter允许咱们设置超时时间,这在处理不能无限等待的操作时非常有用。看看下面的例子:

import com.google.common.util.concurrent.RateLimiter;public class TimeoutRateLimiterExample {public static void main(String[] args) {RateLimiter limiter = RateLimiter.create(5.0); // 每秒5个令牌// 模拟请求处理for (int i = 0; i < 10; i++) {boolean acquired = limiter.tryAcquire(); // 尝试获取令牌if (acquired) {System.out.println("处理请求: " + i);} else {System.out.println("请求 " + i + " 因超时而放弃");// 处理超时逻辑}}}
}

在这个例子中,小黑使用了tryAcquire()方法而不是acquire()tryAcquire()会立即返回一个布尔值,告诉咱们是否成功获取到了令牌,而不会让程序等待。这对于那些需要快速响应的应用场景非常实用。

最佳实践

使用RateLimiter时,遵循一些最佳实践可以帮助咱们更好地利用其功能,同时避免常见的陷阱。下面是一些小黑总结的要点:

  1. 理解需求:在使用RateLimiter之前,先明确你的应用场景。是需要平滑的限流,还是需要应对突发流量?选择合适的RateLimiter模式对应用的成功至关重要。

  2. 避免过度设计:有时候,简单的限流策略就足够了。不要为了使用RateLimiter而使用RateLimiter。考虑你的实际需求,如果简单的解决方案能工作得很好,就不必复杂化。

  3. 监控和调整:在使用RateLimiter的过程中,监控其表现是很重要的。根据实际运行情况调整RateLimiter的参数,确保它能够适应应用的变化。

  4. 并发考虑:在多线程环境中使用RateLimiter时,要特别注意线程安全和性能问题。正确地管理并发,可以最大限度地发挥RateLimiter的效能。

实践案例

让咱们来看一个实际的案例,展示如何在一个多线程环境中使用RateLimiter。

import com.google.common.util.concurrent.RateLimiter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;public class ConcurrencyRateLimiterExample {private static final RateLimiter rateLimiter = RateLimiter.create(5.0); // 每秒5个请求public static void handleRequest(int requestId) {if (rateLimiter.tryAcquire()) {System.out.println("处理请求: " + requestId);// 进行实际的请求处理} else {System.out.println("请求 " + requestId + " 被限流");// 可以返回错误信息或者进行其他操作}}public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(10); // 创建一个含有10个线程的线程池IntStream.rangeClosed(1, 20).forEach(i ->executor.submit(() -> handleRequest(i)));executor.shutdown(); // 关闭线程池}
}

在这个例子中,小黑创建了一个线程池来模拟多线程环境,并使用RateLimiter来控制对handleRequest方法的调用频率。这样即使多个线程同时尝试执行操作,RateLimiter也能确保整体的请求速率不会超过设定的限制。

6. RateLimiter与其他Java限流工具的比较

咱们已经探讨了RateLimiter的许多方面,但是在Java的世界里,RateLimiter并不是唯一的限流工具。小黑这次要带大家看看RateLimiter和其他一些流行的Java限流工具的对比,这样咱们在选择合适的工具时就能更有依据。

RateLimiter与Semaphore

Semaphore是Java并发包中的一个工具,它可以限制对某些资源的并发访问。在某些方面,它和RateLimiter有相似之处,但也有明显的区别。

  • Semaphore:它更多的是用于限制同时进行的操作数量,而不是操作的频率。Semaphore允许一定数量的线程同时访问资源。

  • RateLimiter:它主要用于控制操作的速率,保证在给定时间内只允许一定数量的操作发生。

代码示例:Semaphore

让我们看一个简单的Semaphore的使用例子:

import java.util.concurrent.Semaphore;public class SemaphoreExample {private static final Semaphore semaphore = new Semaphore(5); // 同时允许5个线程访问资源public static void handleRequest(int requestId) {try {semaphore.acquire(); // 请求一个许可System.out.println("处理请求: " + requestId);// 进行实际的请求处理} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {semaphore.release(); // 释放一个许可}}public static void main(String[] args) {for (int i = 0; i < 10; i++) {new Thread(() -> handleRequest(i)).start();}}
}

在这个例子中,Semaphore控制了同时访问资源的线程数量,而不是访问的频率。

RateLimiter与Java 8的Stream API

Java 8的Stream API并不是一个专门的限流工具,但它可以用于处理数据流的速率。通过组合不同的操作,可以实现类似限流的效果。

  • Stream API:主要用于数据流的处理,可以通过其各种操作实现对数据处理速率的控制。

  • RateLimiter:更专注于控制操作的执行频率。

选择合适的工具

选择合适的限流工具时,重要的是要考虑你的具体需求:

  • 如果你需要控制操作的频率,比如API调用或数据库查询的速率,RateLimiter是个不错的选择。
  • 如果你需要控制并发访问资源的数量,Semaphore可能更适合。
  • 对于数据流处理和复杂的数据操作,可以考虑使用Java 8的Stream API。

了解不同工具的优势和适用场景,可以帮助咱们做出更明智的技术决策。每种工具都有它的用武之地,关键在于根据你的应用需求来选择最合适的那一个。

7. 常见问题解答

在小黑之前的章节里,咱们已经探讨了RateLimiter的很多方面,包括它的基本使用、高级特性、以及和其他限流工具的比较。现在,让小黑来帮大家解答一些在使用RateLimiter时可能遇到的常见问题。这些问题基于实际应用场景,希望能帮助咱们更好地理解和使用RateLimiter。

Q1: RateLimiter在分布式系统中如何使用?

在分布式系统中使用RateLimiter时,最大的挑战是如何在多个服务实例间共享限流状态。Guava的RateLimiter是基于单个JVM设计的,它不支持分布式环境。如果你需要在分布式系统中实现限流,可能需要考虑使用像Redis这样的外部存储来维护限流状态,或者使用专门为分布式环境设计的限流工具。

Q2: RateLimiter能否应对突发流量?

RateLimiter的SmoothBursty模式可以应对一定程度的突发流量。它允许在短时间内消耗已经累积的令牌,处理突然增加的请求。但是,如果突发流量超过了RateLimiter的承载能力,超出部分的请求仍然会被限制或延迟处理。

Q3: 使用RateLimiter时,系统的性能会受到影响吗?

使用RateLimiter可能会对系统性能产生一定影响,因为它需要管理和维护令牌的生成与分发。在大多数情况下,这种影响是可接受的,特别是考虑到它带来的系统稳定性。然而,在高性能要求的场景中,建议进行详细的性能测试,以确保RateLimiter的使用不会成为瓶颈。

Q4: RateLimiter适用于哪些场景?

RateLimiter特别适用于需要控制请求速率的场景,如API限流、数据库访问控制等。它也可以用于控制资源的使用频率,比如文件读写、网络通信等。总之,任何需要平滑流量、避免资源过载的场景都可以考虑使用RateLimiter。

Q5: 如何调整RateLimiter的限流策略?

RateLimiter允许动态调整限流策略。你可以使用setRate(double permitsPerSecond)方法来调整每秒允许的请求数量。这在应对动态变化的负载或实现更灵活的限流策略时非常有用。

示例代码:动态调整RateLimiter

下面是一个如何动态调整RateLimiter的例子:

import com.google.common.util.concurrent.RateLimiter;public class DynamicRateLimiterExample {public static void main(String[] args) {RateLimiter limiter = RateLimiter.create(5.0); // 初始每秒5个令牌// 模拟请求处理for (int i = 0; i < 10; i++) {limiter.acquire();System.out.println("处理请求: " + i);if (i == 5) {limiter.setRate(10.0); // 动态调整为每秒10个令牌}}}
}

在这段代码中,小黑开始时设置RateLimiter每秒产生5个令牌。处理了一些请求后,小黑动态地将速率调整为每秒10个令牌,以适应可能的变化需求。

8. 总结

RateLimiter的优点
  1. 灵活性:RateLimiter提供了多种限流策略,满足不同场景的需求,比如SmoothBursty和SmoothWarmingUp模式,以及能够动态调整速率的特性。

  2. 简单易用:Guava的RateLimiter非常容易理解和使用,API设计直观,使得在实际项目中快速实现限流成为可能。

  3. 性能:虽然RateLimiter会带来一定的性能开销,但是在大多数场景下,这种开销是可接受的,特别是考虑到它带来的稳定性和可靠性。

  4. 稳定性:使用RateLimiter可以有效地防止系统过载,提高系统的稳定性和可靠性,特别是在面对高并发和大量请求的场景下。

适用场景

RateLimiter特别适用于以下几种场景:

  1. API限流:在Web服务中控制API的访问频率,防止因过度使用而导致的服务不稳定。

  2. 数据库访问控制:控制对数据库的访问频率,减少数据库压力,避免因查询过多而导致的性能问题。

  3. 资源使用管理:在需要控制对文件、网络等资源的访问频率时,使用RateLimiter可以平滑地管理资源使用。

最后的建议

RateLimiter是一个强大且实用的工具,但是像所有工具一样,关键在于如何使用它。理解你的需求,选择合适的限流策略,合理地集成到你的应用中,这些都是成功使用RateLimiter的关键。

最后,小黑希望这篇文章能帮助大家更好地理解和使用RateLimiter,让咱们的应用更加稳定和高效。


面对寒冬,我们更需团结!小黑收集整理了一份超级强大的复习面试资料包,也强烈建议你加入我们的Java后端报团取暖群,一起复习,共享各种学习资源,互助成长,分享经验,提升技能,闲聊副业,共同抵御不确定性,进群方式以及资料,点击如下链接即可获取!

链接:https://sourl.cn/CjagkK 提取码:yqwt

相关文章:

Guava限流神器:RateLimiter使用指南

1. 引言 可能有些小伙伴听到“限流”这个词就觉得头大&#xff0c;感觉像是一个既复杂又枯燥的话题。别急&#xff0c;小黑今天就要用轻松易懂的方式&#xff0c;带咱们一探RateLimiter的究竟。 想象一下&#xff0c;当你去超市排队结账时&#xff0c;如果收银台开得越多&…...

【六大排序详解】开篇 :插入排序 与 希尔排序

插入排序 与 希尔排序 六大排序之二 插入排序 与 希尔排序1 排序1.1排序的概念 2 插入排序2.1 插入排序原理2.2 排序步骤2.3 代码实现 3 希尔排序3.1 希尔排序原理3.2 排序步骤3.3 代码实现 4 时间复杂度分析 Thanks♪(&#xff65;ω&#xff65;)&#xff89;下一篇文章见&am…...

凸优化问题求解

这里写目录标题 1. 线性规划基本定理2.单纯形法2.1 转轴运算 3. 内点法3.1 线性规划的内点法 1. 线性规划基本定理 首先我们指出&#xff0c;线性规划均可等价地化成如下标准形式 { min ⁡ c T x , s . t A x b , x ⪰ 0 , \begin{align}\begin{cases}\min~c^Tx,\\\mathrm{s.…...

文件操作入门指南

目录 一、为什么使用文件 二、什么是文件 2.1 程序文件 2.2 数据文件 2.3 文件名 三、文件的打开和关闭 3.1 文件指针 3.2 文件的打开和关闭 四、文件的顺序读写 ​编辑 &#x1f33b;深入理解 “流”&#xff1a; &#x1f342;文件的顺序读写函数介绍&#xff1a; …...

Axure之交互与情节与一些实例

目录 一.交互与情节简介 二.ERP登录页到主页的跳转 三.ERP的菜单跳转到各个页面的跳转 四.省市联动 五.手机下拉加载 今天就到这里了&#xff0c;希望帮到你哦&#xff01;&#xff01;&#xff01; 一.交互与情节简介 "交互"通常指的是人与人、人与计算机或物体…...

【数据库设计和SQL基础语法】--连接与联接--多表查询与子查询基础(二)

一、子查询基础 1.1 子查询概述 子查询是指在一个查询语句内部嵌套另一个查询语句的过程。子查询可以嵌套在 SELECT、FROM、WHERE 或 HAVING 子句中&#xff0c;用于从数据库中检索数据或执行其他操作。子查询通常返回一个结果集&#xff0c;该结果集可以被包含它的主查询使用…...

Android studio中导入opencv库

具体opencv库的导入流程参考链接&#xff1a;Android Studio开发之路 &#xff08;五&#xff09;导入OpenCV以及报错解决 一、出现的错误&#xff1a;NullPointerException: Cannot invoke “java.io.File.toPath()” because “this.mySdkLocation” is null 解决办法&#…...

Linux(1)_基础知识

第一部分 一、Linux系统概述 创始人&#xff1a;芬兰大学大一的学生写的Linux内核&#xff0c;李纳斯托瓦兹。 Linux时unix的类系统&#xff1b; 特点&#xff1a;多用户 多线程的操作系统&#xff1b; 开源操作系统&#xff1b; 开源项目&#xff1a;操作系统&#xff0c;应用…...

网络相关面试题

简述 TCP 连接的过程&#xff08;淘系&#xff09; 参考答案&#xff1a; TCP 协议通过三次握手建立可靠的点对点连接&#xff0c;具体过程是&#xff1a; 首先服务器进入监听状态&#xff0c;然后即可处理连接 第一次握手&#xff1a;建立连接时&#xff0c;客户端发送 syn 包…...

Vue2面试题:说一下对跨域的理解?

http请求分为两大类&#xff1a;普通http请求&#xff08;如百度请求&#xff09;和ajax请求&#xff08;跨域是出现在ajax请求&#xff09; 同源策略&#xff1a;在浏览器发起ajax请求时&#xff0c;当前的网址和被请求的网址协议、域名、端口号必须完全一致&#xff0c;目的是…...

Axure中如何使用交互样式交互事件交互动作情形

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《产品经理如何画泳道图&流程图》 ⛺️ 越努力 &#xff0c;越幸运 目录 一、Axure中交互样式 1、什么是交互样式&#xff1f; 2、交互样式的作用&#xff1f; 3、Axure中如何…...

1112. 迷宫(DFS之连通性模型)

1112. 迷宫 - AcWing题库 一天Extense在森林里探险的时候不小心走入了一个迷宫&#xff0c;迷宫可以看成是由 n∗n 的格点组成&#xff0c;每个格点只有2种状态&#xff0c;.和#&#xff0c;前者表示可以通行后者表示不能通行。 同时当Extense处在某个格点时&#xff0c;他只…...

飞天使-k8s知识点1-kubernetes架构简述

文章目录 名词功能要点 k8s核心要素CNCF 云原生框架简介k8s组建介绍 名词 CI 持续集成, 自动化构建和测试&#xff1a;通过使用自动化构建工具和自动化测试套件&#xff0c;持续集成可以帮助开发人员自动构建和测试他们的代码。这样可以快速检测到潜在的问题&#xff0c;并及早…...

linux中deadline调度原理与代码注释

简介 deadline调度是比rt调度更高优先级的调度&#xff0c;它没有依赖于优先级的概念&#xff0c;而是给了每个实时任务一定的调度时间&#xff0c;这样的好处是&#xff1a;使多个实时任务场景的时间分配更合理&#xff0c;不让一些实时任务因为优先级低而饿死。deadline调度…...

jquery、vue、uni-app、小程序的页面传参方式

jQuery、Vue、Uni-app 和小程序&#xff08;例如微信小程序&#xff09;都有它们自己的页面传参方式。下面分别介绍这几种方式的页面传参方式&#xff1a; jQuery: 在jQuery中&#xff0c;页面传参通常是通过URL的查询参数来实现的。例如&#xff1a; <a href"page2…...

ModuleNotFoundError: No module named ‘openai.error‘

ModuleNotFoundError: No module named ‘openai.error’ result self.fn(*self.args, **self.kwargs) File “H:\chatGPTWeb\chatgpt-on-wechat\channel\chat_channel.py”, line 168, in _handle reply self._generate_reply(context) File “H:\chatGPTWeb\chatgpt-on-wec…...

理解pom.xml中的parent标签

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 循序渐进学SpringBoot ✨特色专栏&…...

element ui el-avatar 源码解析零基础逐行解析

avatar功能介绍 快捷配置头像的样式 avatar 的参数配置 属性说明参数size尺寸type string 类型 &#xff08;‘large’,‘medium’,‘small’&#xff09;number类型 validator 校验shape形状circle (原型) square&#xff08;方形&#xff09;icon传入的iconsrc传入的图片st…...

Linux下c语言实现动态库的动态调用

在Linux操作系统下&#xff0c;有时候需要在不重新编译程序的情况下&#xff0c;运行时动态地加载库&#xff0c;这时可以通过Linux操作系统提供的API可以实现&#xff0c;涉及到的API主要有dlopen、dlsym和dlclose。使用时&#xff0c;需要加上头文件#include <dlfcn.h>…...

为什么MCU在ADC采样时IO口有毛刺?

大家在使用MCU内部ADC进行信号采样一个静态电压时&#xff0c;可能在IO口上看到这样的波形。这个时候大家一般会认识是信号源有问题&#xff0c;但仔细观察会发现这个毛刺的频率是和ADC触发频率一样的。 那么为什么MCU在ADC采样时IO口会出现毛刺呢&#xff1f;这个毛刺对结果有…...

C# 将 Word 转化分享为电子期刊

目录 需求 方案分析 相关库引入 关键代码 Word 转 Pdf Pdf 转批量 Jpeg Jpeg 转为电子书 实现效果演示 小结 需求 曾经的一个项目&#xff0c;要求实现制作电子期刊定期发送给企业进行阅读&#xff0c;基本的需求如下&#xff1a; 1、由编辑人员使用 Microsoft Word…...

网络世界的黑暗角落:常见漏洞攻防大揭秘

网络世界的黑暗角落&#xff1a;常见漏洞攻防大揭秘 今天带来了网站常见的漏洞总结,大家在自己的服务器上也需要好好进行防护,密码不要过于简单.不然非常容易遭到攻击,最终达到不可挽回的损失.很多黑客想网络乞丐一样将你服务器打宕机,然后要求你进行付费.不知道大家有没有遇到…...

通信领域发展方向

5G网络技术&#xff1a;随着5G网络的建设和商用推广&#xff0c;各家运营商、厂商和研究机构都在探索5G技术的应用场景和解决方案&#xff0c;如网络切片、毫米波通信、多用户MIMO等。 物联网技术&#xff1a;物联网技术已经成为通信行业的重点发展领域&#xff0c;包括传感器…...

21 3GPP中 5G NR高速列车通信标准化

文章目录 信道模型实验——物理层设计相关元素μ(与子载波间隔有关)设计参考信号(DMRS) 本文提出初始接入、移动性管理、线性小区设计等高层技术。描述3GPP采用HST场景的评估参数&#xff0c;阐释了HST应用的物理层技术&#xff0c;包括数字通信和参考信号设计&#xff0c;链路…...

【网络安全】-Linux操作系统—CentOS安装、配置

文章目录 准备工作下载CentOS创建启动盘确保硬件兼容 安装CentOS启动安装程序分区硬盘网络和主机名设置开始安装完成安装 初次登录和配置更新系统安装额外的软件仓库安装网络工具配置防火墙设置SELinux安装文本编辑器配置SSH服务 总结 CentOS是一个基于Red Hat Enterprise Linu…...

CCNP课程实验-OSPF-CFG

目录 实验条件网络拓朴需求 配置实现基础配置1. 配置所有设备的IP地址 实现目标1. 要求按照下列标准配置一个OSPF网络。 路由协议采用OSPF&#xff0c;进程ID为89 &#xff0c;RID为loopback0地址。3. R4/R5/R6相连的三个站点链路OSPF网络类型配置成广播型&#xff0c;其中R5路…...

【Spring Security】打造安全无忧的Web应用--入门篇

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Spring Security的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Spring Security是什么 1.概…...

【每日一题】【12.20】2828.判别首字母缩略词

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 1.题目链接 2828. 判别首字母缩略词https://leetcode.cn/problems/check-if-a-string-is-an-acronym-of-words/ 2.题目描述 今天…...

LabVIEW开发振动数据分析系统

LabVIEW开发振动数据分析系统 自动测试系统基于LabVIEW平台设计&#xff0c;采用了多种高级硬件设备。系统的硬件组成包括PCB振动加速度传感器&#xff0c;这是一种集成了传统压电加速度传感器和电荷放大器的先进设备&#xff0c;能够直接与采集仪器连接。此外&#xff0c;系统…...

去掉乘法运算的加法移位神经网络架构

[CVPR 2020] AdderNet: Do We Really Need Multiplications in Deep Learning? 代码&#xff1a;https://github.com/huawei-noah/AdderNet/tree/master 核心贡献 用filter与input feature之间的L1-范数距离作为“卷积层”的输出为了提升模型性能&#xff0c;提出全精度梯度…...

网站建设费应开具互联网信息服务吗/百度客服在哪里找

1、侯先生经常说“凡走过必留下足迹”&#xff0c;所谓“走弯路”&#xff0c;未必不是一件好事。 2、排队的时候&#xff0c;你会发现一个规律——另一排总是动的比较快&#xff1b;你换到另一排&#xff0c;你原来站的那一排&#xff0c;就开始动的比较快了&#xff1b;你站的…...

江苏网站建设开发/seo搜索引擎优化求职简历

有哪些基础的问题&#xff1f; 一些简单的问题在前面的文章中都体现了&#xff1a; 为什么要使用消息中间件&#xff1f;消息中间件有哪些缺点&#xff1f;ActiveMQ、RabbitMQ、RocketMQ和kafka都有什么优缺点&#xff1f;RabbitMQ如何保证高可用性&#xff1f;kafka如何保证…...

网站数据库转移/如何在百度上发自己的广告?

在redhat7.2下面安装iftop&#xff0c;监控系统网卡的实时流量日期&#xff1a;2004/07/30 作者&#xff1a;zcatlinux 来源&#xff1a;zclinux 在CU上面发现一篇可以监控网卡的文章&#xff0c;当时很激动&#xff0c;随手找到安装包iftop-0.16&#xff0c;在redhat9.0下面…...

数据调查的权威网站/yandex搜索引擎入口

文章目录广播广播发送setsockopt广播发送示例广播接收代码示例头文件sender.creceiver.c组播网络地址组播发送组播接收加入多播组组播收发 — 示例头文件sender.crecviver.c广播 前面介绍的数据包发送方式只有一个接受方&#xff0c;称为单播如果同时发给局域网中的所有主机&a…...

营销推广方法/宁波seo哪家好快速推广

前言   因为游戏开发在架构上要考虑性能和实际需求&#xff0c;在尽量不引入第三方库、框架的前提下进行开发&#xff0c;所以在编码时候会经常用到设计模式对代码进行复用&#xff0c;对业务逻辑架构解耦&#xff0c;尽量减少hard code。 单例模式&#xff08;Singleton P…...

湘潭自适应网站建设 磐石网络/哪些平台可以发布推广信息

2.5.1. EnableConfigurationProperties 引用自定义 *.properties 配置文件 Application.java 涮锅配置NetkillerProperties.java是 ComponentScan 扫描范围&#xff0c;可以不用声明下面注解。 EnableConfigurationProperties(NetkillerProperties.class)import org.springfram…...