宣传信息网网站规划书/seo优化常识
1 多线程知识回顾
⭐⭐⭐⭐⭐⭐
Github主页👉https://github.com/A-BigTree
笔记仓库👉https://github.com/A-BigTree/tree-learning-notes
个人主页👉https://www.abigtree.top
⭐⭐⭐⭐⭐⭐
如果可以,麻烦各位看官顺手点个star~😊
如果文章对你有所帮助,可以点赞👍收藏⭐支持一下博主~😆
文章目录
- 1 多线程知识回顾
- 1.1 基础概念
- 1.1.1 程序、进程、线程
- 程序
- 进程
- 线程
- 1.1.2 串行、并行、并发
- 串行
- 并行和并发
- 1.1.3 sleep()和wait()
- `sleep()`进入等待状态不释放锁
- `wait()`进入等待状态释放锁
- 小结
- 1.1.4 同步方法和同步代码块
- 相同点
- 区别
- 小结
- 1.2 创建多线程
- 1.2.1 继承Thread类
- 实现方法
- `start()` 方法和 `run()` 方法区别
- 评价
- 1.2.2 实现Runnable接口
- 实现接口形式
- 匿名内部类形式
- Lambda表达式
- 1.2.3 使用Callable接口配合FutureTask
- `FutureTask`类和`Runnable`接口的关系
- Future接口
- `FutureTask`类的构造器
- Callable接口
- 测试代码
- callable和Runnable对比
- 1.2.4 线程池
- 参考代码
- 1.2.5 并行计算
- 1.2.6 Timer定时任务
- 1.2.7 Spring异步方法
- 准备SpringBoot环境
- 使用异步方法
- 1.3 线程状态与生命周期
- 1.3.1 线程状态枚举类
- 源代码
- 说明
- 1.3.2 线程的生命周期
- 1.4 线程间通信
- 1.4.1 核心语法
- `Object` 类的 `wait()` 方法
- `Object` 类的 `notify()` 方法
- `Object` 类的 `notifyAll()` 方法
- 1.4.2 虚假唤醒
1.1 基础概念
1.1.1 程序、进程、线程
程序
-
程序从开发到发布的过程:源程序(源代码) → 打包封装 → 应用软件 ;
-
笼统的来说,源程序、应用软件都可以称之为『程序』;
-
相对于进程、线程来说,程序是一个静态的概念;
进程
- 内部视角:程序运行起来就是一个进程。所以相对于程序来说,进程是一个动态的概念;
- 外部视角:站在操作系统的层次上来说,现代的大型操作系统都是支持多进程模式运行的,这样操作系统就可以同时执行很多个任务;
线程
在一个进程中,需要同时处理多个不同任务,每一个任务由一个线程来执行。从这个意义上来说,可以把进程看做是线程的容器。
1.1.2 串行、并行、并发
串行
多个操作在同一个线程内按顺序执行。这种情况下的工作模式我们往往也称之为:同步。按照同步模式执行的多个操作,当前操作没有结束时,下一个操作就必须等待。处于等待中的状态往往也称为:阻塞(block)。
并行和并发
并行和并发都是以异步的模式来执行操作的。异步工作模式下不同线程内的操作互相不需要等待。
- 并行:多个 CPU(或 CPU 核心)同时执行多个任务
- 并发:一个 CPU(或 CPU 核心)同时执行多个任务
1.1.3 sleep()和wait()
二者最关键的区别是下面两点:
sleep()
会让线程拿着锁去睡;wait()
会让线程放开锁去睡;
sleep()
进入等待状态不释放锁
// 1、创建一个对象,作为锁对象
Object lockObj = new Object();// 2、创建执行 sleep 的线程
new Thread(()->{System.out.println(Thread.currentThread().getName() + " begin");// ※ 两个线程使用同一个锁对象,就会存在竞争关系synchronized (lockObj) {System.out.println(Thread.currentThread().getName() + " get lock");try {// ※ sleep() 方法拿着锁去睡TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " release lock");}System.out.println(Thread.currentThread().getName() + " end");}, "thread-a").start();// ※ 让主线程睡一会儿,确保 a 线程先启动
try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}// 3、创建竞争锁的线程
new Thread(()->{System.out.println(Thread.currentThread().getName() + " begin");// ※ 两个线程使用同一个锁对象,就会存在竞争关系synchronized (lockObj) {System.out.println(Thread.currentThread().getName() + " get lock");}System.out.println(Thread.currentThread().getName() + " end");
}, "thread-b").start();
打印结果:
thread-a begin
thread-a get lock
thread-b begin
thread-a release lock
thread-b get lock
thread-b end
thread-a end
wait()
进入等待状态释放锁
// 1、创建一个对象,作为锁对象
Object lockObj = new Object();// 2、创建执行 sleep 的线程
new Thread(()->{System.out.println(Thread.currentThread().getName() + " begin");// ※ 两个线程使用同一个锁对象,就会存在竞争关系synchronized (lockObj) {System.out.println(Thread.currentThread().getName() + " get lock");try {// ※ wait() 方法放开锁去睡lockObj.wait(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " release lock");}System.out.println(Thread.currentThread().getName() + " end");}, "thread-a").start();// ※ 让主线程睡一会儿,确保 a 线程先启动
try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}// 3、创建竞争锁的线程
new Thread(()->{System.out.println(Thread.currentThread().getName() + " begin");// ※ 两个线程使用同一个锁对象,就会存在竞争关系synchronized (lockObj) {System.out.println(Thread.currentThread().getName() + " get lock");}System.out.println(Thread.currentThread().getName() + " end");
}, "thread-b").start();
打印结果:
thread-a begin
thread-a get lock
thread-b begin
thread-b get lock
thread-b end
thread-a release lock
thread-a end
小结
wait() | sleep() | |
---|---|---|
声明位置 | Object 类 | Thread 类 |
影响线程的方式 | 通过调用 wait() 方法的对象影响到线程 | 直接影响当前线程 |
性质 | 非静态方法 | 静态方法 |
释放锁资源 | 放开锁进入等待 | 不释放锁进入等待 |
同步要求 | 必须在同步上下文中使用 | 不要求在同步上下文中 |
应用场景 | 用于线程间通信 | 用来让线程暂停一段时间 |
1.1.4 同步方法和同步代码块
相同点
都会用到synchronized
关键字
区别
锁对象 | 锁定范围 | |
---|---|---|
同步代码块 | 由程序员指定 | 代码块的范围(灵活) |
同步方法 | 静态:类.class 非静态:this | 整个方法体 |
小结
- 结论1:静态同步方法使用类.class作为锁对象;非静态同步方法使用this作为锁对象;
- 结论2:多个线程如果使用同一个锁对象就会有竞争关系;否则没有竞争关系;
1.2 创建多线程
无论有多少种形式,创建多线程的真正的方法,其实只有两种:
继承 Thread 类
实现 Runnable 接口
其它形式都是这两种方式的变体
1.2.1 继承Thread类
实现方法
- 第一步:继承 Thread 类;
- 第二步:重写 run() 方法;
- 第三步:创建 Thread 子类对象;
- 第四步:调用 start() 方法启动线程;
public class CreateThread01Extends {public static void main(String[] args) {DemoThread demo = new DemoThread("AAA");demo.start();}}class DemoThread extends Thread {public DemoThread(String threadName) {super(threadName);}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " thread working ...");}
}
start()
方法和 run()
方法区别
调用 run() 方法仅仅只是调用了一个子类中重写的父类方法,并没有真正开启一个新的线程,还是在当前线程运行,也就是 main 线程。
评价
因为 Java 是单继承的,一个类继承了 Thread 类就不能继承其它类,所以通常不采用这个办法创建多线程。
1.2.2 实现Runnable接口
实现接口形式
public class CreateThread02Impl {public static void main(String[] args) {// 第四步:创建实现了 Runnable 接口的类的对象MyRunnableThread runnable = new MyRunnableThread();// 第五步:创建 Thread 类对象// 参数1:runnable 对象// 参数2:线程名称Thread thread = new Thread(runnable, "thread 002");// 第六步:调用 Thread 对象的 start() 方法启动线程thread.start();}}// 第一步:实现 Runnable 接口
class MyRunnableThread implements Runnable {// 第二步:实现 run() 方法@Overridepublic void run() {// 第三步:编写线程中的逻辑代码System.out.println(Thread.currentThread().getName() + " is working");}
}
匿名内部类形式
// 第一步:以匿名内部类的方式创建 Runnable 接口类型的对象
Runnable runnable = new Runnable() {@Overridepublic void run() {// 第二步:编写线程中的逻辑代码System.out.println(Thread.currentThread().getName() + " is working");}
};// 第三步:创建 Thread 类对象
// 参数1:runnable 对象
// 参数2:线程名称
Thread thread = new Thread(runnable, "thread 003");// 第四步:调用 Thread 对象的 start() 方法启动线程
thread.start();
Lambda表达式
声明变量:
// 编写 Lambda 表达式的口诀:
// 复制小括号
// 写死右箭头
// 落地大括号// 第一步:以匿名内部类的方式创建 Runnable 接口类型的对象
Runnable runnable = () -> {// 第二步:编写线程中的逻辑代码System.out.println(Thread.currentThread().getName() + " is working");
};// 第三步:创建 Thread 类对象
// 参数1:runnable 对象
// 参数2:线程名称
Thread thread = new Thread(runnable, "thread 004");// 第四步:调用 Thread 对象的 start() 方法启动线程
thread.start();
不声明变量:
// 第一步:创建 Thread 类对象并调用 start() 方法启动线程
// 参数1:以Lambda 表达式形式创建的 runnable 对象
// 参数2:线程名称
new Thread(() -> {// 第二步:编写线程中的逻辑代码System.out.println(Thread.currentThread().getName() + " is working");
}, "thread 005").start();
1.2.3 使用Callable接口配合FutureTask
该方案最核心的价值是:使用 Callable 接口限定的功能 + Future 接口限定的功能 = 汇总各个线程执行结果 最终执行汇总操作的这一步会被阻塞,直到前面各个线程完成了计算。
FutureTask
类和Runnable
接口的关系
从继承关系能够看到,FutureTask
本身也间接实现了Runnable
接口。FutureTask
类的对象也是Runnable
接口的实例,可以用于在创建Thread
对象时,传入Thread构造器。
Future接口
停止任务:
boolean cancel(boolean mayInterruptIfRunning);
如果尚未启动,它将停止任务。如果已启动,则仅在 mayInterrupt 为 true 时才会中断任务。
获取任务的结果:
V get() throws InterruptedException, ExecutionException;
如果任务完成,它将立即返回结果,否则将等待任务完成,然后返回结果。
判断任务是否完成:
boolean isDone();
如果任务完成,则返回true,否则返回false。
FutureTask
类的构造器
介绍:
FutureTask
类兼具 Runnable
和 Future
接口的功能,并方便地将两种功能组合在一起。关于 FutureTask
类的使用有如下建议:
- 在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给 Future 对象在后台完成;
- 当主线程将来需要时,就可以通过 Future 对象获得后台作业的计算结果或者执行状态;
- 一般 FutureTask 多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果;
- 仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get() 方法;
- 一旦计算完成,就不能再重新开始或取消计算;
- get() 方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常;
- get() 只执行一次,因此get() 方法放到最后;
可以使用的构造器:
public FutureTask(Callable<V> callable) {if (callable == null)throw new NullPointerException();this.callable = callable;this.state = NEW; // ensure visibility of callable}
根据这个构造器,我们知道,创建 FutureTask 对象时,传入一个 Callable 类型的对象即可。
Callable接口
@FunctionalInterface
public interface Callable<V> {/*** Computes a result, or throws an exception if unable to do so.** @return computed result* @throws Exception if unable to compute a result*/V call() throws Exception;
}
从 call() 方法的声明我们可以看出,它有一个返回值。这个返回值可以将当前线程内计算结果返回。
测试代码
// 1.创建三个FutureTask对象,封装三个线程的执行逻辑
FutureTask<Integer> task01 = new FutureTask<>(() -> {int result = (int) (Math.random() * Math.random() * 100);System.out.println(Thread.currentThread().getName());return result;
});
FutureTask<Integer> task02 = new FutureTask<>(() -> {int result = (int) (Math.random() * Math.random() * 1000);System.out.println(Thread.currentThread().getName());return result;
});
FutureTask<Integer> task03 = new FutureTask<>(() -> {int result = (int) (Math.random() * Math.random() * 10000);System.out.println(Thread.currentThread().getName());return result;
});// 2.创建三个线程对象,然后启动线程
new Thread(task01, "thread01").start();
new Thread(task02, "thread02").start();
new Thread(task03, "thread03").start();// 3.上面三个线程执行完成后,可以收集它们各自运算的结果
Integer task01Result = task01.get();
Integer task02Result = task02.get();
Integer task03Result = task03.get();System.out.println("task01Result = " + task01Result);
System.out.println("task02Result = " + task02Result);
System.out.println("task03Result = " + task03Result);
callable和Runnable对比
Runnable接口 | Callable接口 |
---|---|
重写run()方法 | 重写call()方法 |
run()没有返回值 | call()有返回值 |
run()没有声明抛出异常 | call()声明抛出Exception |
没有汇总各个线程结果的机制 | 有汇总各个线程结果的机制 |
1.2.4 线程池
参考代码
// 1.创建线程池对象
ExecutorService pool = Executors.newFixedThreadPool(5);// 2.给线程池对象分配任务,每一个任务是一个线程
pool.execute(() -> {System.out.println(Thread.currentThread().getName() + " " + new Date());
});pool.execute(() -> {System.out.println(Thread.currentThread().getName() + " " + new Date());
});pool.execute(() -> {System.out.println(Thread.currentThread().getName() + " " + new Date());
});
1.2.5 并行计算
List<String> list = Arrays.asList("a", "b", "c", "d", "e");// 串行计算
list.stream().forEach(System.out::print);System.out.println();// 并行计算
list.parallelStream().forEach(System.out::print);
1.2.6 Timer定时任务
// 1、创建 Timer 对象封装定时任务中要执行的操作
// 每一个 Timer 对象会使用一个线程来执行定时任务
Timer timer01 = new Timer();// 2、调用 schedule() 指定任务和执行周期
// 参数1:timerTask 封装具体任务操作
// 参数2:delay 指定定时任务延迟多久后开始执行
// 参数3:period 指定定时任务执行的时间间隔
timer01.schedule(new TimerTask() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() +" is working");}
}, 0, 1000);Timer timer02 = new Timer();timer02.schedule(new TimerTask() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() +" is working");}
}, 0, 1000);
1.2.7 Spring异步方法
在 Spring 环境下,如果组件 A(假设是 ControllerA)要调用组件 B(假设是 ServiceB)的多个方法,而且希望这些方法能够异步执行。
准备SpringBoot环境
引入依赖:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.5.2</version></dependency>
</dependencies>
创建主启动类:
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
创建Service:
@Service
public class DemoService {public void doSth() {System.out.println("Demo Service " + Thread.currentThread().getName());}}
创建Controller:
@RestController
public class DemoController {@Autowiredprivate DemoService demoService;@RequestMapping("/demo/test/async")public String callServiceMethod() {demoService.doSth();demoService.doSth();demoService.doSth();demoService.doSth();demoService.doSth();return "success";}}
使用异步方法
开启异步功能:
在主启动类使用 @EnableAsync 注解:
// 开启支持异步方法调用功能
@EnableAsync
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
标记异步方法:
在想要异步调用的方法上使用 @Async 注解:
@Service
public class DemoService {// 在想要实现异步调用的方法上加 @Async注解@Asyncpublic void doSth() {System.out.println("Demo Service " + Thread.currentThread().getName());}}
1.3 线程状态与生命周期
1.3.1 线程状态枚举类
源代码
public enum State {/*** Thread state for a thread which has not yet started.*/NEW,/*** Thread state for a runnable thread. A thread in the runnable* state is executing in the Java virtual machine but it may* be waiting for other resources from the operating system* such as processor.*/RUNNABLE,/*** Thread state for a thread blocked waiting for a monitor lock.* A thread in the blocked state is waiting for a monitor lock* to enter a synchronized block/method or* reenter a synchronized block/method after calling* {@link Object#wait() Object.wait}.*/BLOCKED,/*** Thread state for a waiting thread.* A thread is in the waiting state due to calling one of the* following methods:* <ul>* <li>{@link Object#wait() Object.wait} with no timeout</li>* <li>{@link #join() Thread.join} with no timeout</li>* <li>{@link LockSupport#park() LockSupport.park}</li>* </ul>** <p>A thread in the waiting state is waiting for another thread to* perform a particular action.** For example, a thread that has called <tt>Object.wait()</tt>* on an object is waiting for another thread to call* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on* that object. A thread that has called <tt>Thread.join()</tt>* is waiting for a specified thread to terminate.*/WAITING,/*** Thread state for a waiting thread with a specified waiting time.* A thread is in the timed waiting state due to calling one of* the following methods with a specified positive waiting time:* <ul>* <li>{@link #sleep Thread.sleep}</li>* <li>{@link Object#wait(long) Object.wait} with timeout</li>* <li>{@link #join(long) Thread.join} with timeout</li>* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>* </ul>*/TIMED_WAITING,/*** Thread state for a terminated thread.* The thread has completed execution.*/TERMINATED;}
说明
英文名称 | 中文名称 | 含义 |
---|---|---|
NEW | 新建 | 线程对象刚创建 |
RUNNABLE | 就绪 | 等待 CPU 时间片 |
RUNNING | 运行 | 得到了 CPU 时间片,正在执行 |
BLOCKED | 阻塞 | 等待同步锁 |
WAITING | 等待 | 等待被唤醒 |
TIMED_WAITING | 限时等待 | 在进入等待状态时设定了等待时间。时间一到自动回到就绪状态 |
TERMINATED | 终止 | 线程因为代码执行完成或抛异常而停止执行 |
1.3.2 线程的生命周期
1.4 线程间通信
在多线程模式下进行工作,除了要考虑各个线程之间是否同步、如何竞争锁等问题,还要考虑这样一个问题:线程之间有的时候需要相互配合来共同完成一件事情。 把一个大的任务拆分成多个不同的任务线,每个任务线中都有更小的执行步骤。各个线程之间需要彼此配合:A 线程执行一步唤醒 B 线程,自己等待;B 线程执行一步,唤醒 A 线程,自己等待……
1.4.1 核心语法
Object
类的 wait()
方法
Causes the current thread to wait until another thread invokes the
java.lang.Object
#notify() method or thejava.lang.Object
#notifyAll() method for this object.
wait()
方法会导致当前线程进入等待状态;- 必须是另外一个线程调用
notify()
或notifyAll()
方法来唤醒; - “for this object” 表示还是要使用 同一个对象 分别调用
wait()
、notify()
、notifyAll()
这些方法;
Object
类的 notify()
方法
Wakes up a single thread that is waiting on this object’s monitor. If any threads are waiting on this object, one of them is chosen to be awakened.
notify()
方法只唤醒一个线程;- 处于等待状态的线程会被存放在对象监视器中的一个数组中;
- 如果在这个对象的监视器中维护的处于等待状态的线程是多个,那么
notify()
方法会随机唤醒一个; notfiy()
方法无法精确唤醒一个指定的线程,这个需求可以通过 Lock + Condition 方式实现(定制化通信);
Object
类的 notifyAll()
方法
Wakes up all threads that are waiting on this object’s monitor.
唤醒当前对象监视器上等待的**所有**线程。
1.4.2 虚假唤醒
这种情况,我们称之为:虚假唤醒。
要解决虚假唤醒问题,就需要对线程间通信时的判断条件使用 while
循环结构来执行,而不是 if 分支判断。
相关文章:

【Java多线程】1——多线程知识回顾
1 多线程知识回顾 ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记仓库👉https://github.com/A-BigTree/tree-learning-notes 个人主页👉https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star…...

音视频处理 - 音频概念详解,码率,采样率,位深度,声道,编码
1. 音频采样 与视频不同,音频的最小单位不是一帧,而是一个采样。 采样是当前一刻声音的声音样本,样本需要经过数字转换才能存储为样本数据。 真实声音是连续的,但是在计算机中,声音是离散且均匀的声音样本。 2. 位深…...

【PLC】PROFIBUS(二):总线协议DP、PA、FMS
1、总线访问协议 (FDL) 1.1、多主通信 多个主设备间,使用逻辑令牌环依次向从设备发送命令。 特征: 主站间使用逻辑令牌环、主从站间使用主从协议主站在一个限定时间内 (Token Hold Time) 对总线有控制权从站只是响应一个主站的请求它们对总线没有控制…...

Mysql配置autocommit实际使用(慎用)
以下内容都是基于MySQL5.7。所有操作建议在MySQL客户端执行。navicat可能会先意想不到的问题 在导入频繁执行update、insert的时候,可以考虑关闭MySQL的自动提交 首先查询当前的状态 1开启 0关闭 select autocommit;设置本次连接关闭自动提交(如果需要永久关闭请修…...

Mac电脑高清媒体播放器:Movist Pro for mac下载
Movist Pro for mac是一款专为Mac操作系统设计的高清媒体播放器,支持多种常见的媒体格式,包括MKV、AVI、MP4等,能够流畅播放高清视频和音频文件。Movist Pro具有强大的解码能力和优化的渲染引擎,让您享受到更清晰、更流畅的观影体…...

Linux 网站定时备份+滚动删除脚本:文件、数据库(命令篇)
为确保数据安全,我们定期对网站相关文件和数据进行备份,以防止因各种原因导致的丢失情况。同时,考虑到服务器空间的限制,我们也会定期清理历史备份数据。 本文以 CentOS 7.9 系统为例,记录如何通过脚本和定时任务实现备…...

Cache缓存:HTTP缓存策略解析
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

智慧公厕的全域感知、全网协同、全业务融合和全场景智慧赋能
公共厕所是城市的重要组成部分,为市民提供基本的生活服务。然而,传统的公厕管理模式存在诸多问题,如排队等候时间长、卫生状况差、空气质量差等,严重影响市民的出行和生活质量。为了解决这些问题,智慧公厕应运而生&…...

Day44:WEB攻防-PHP应用SQL盲注布尔回显延时判断报错处理增删改查方式
目录 PHP-MYSQL-SQL操作-增删改查 PHP-MYSQL-注入函数-布尔&报错&延迟 基于布尔的SQL盲注-逻辑判断(需要有回显,没回显搞不了)跟union需要的条件差不多 基于时间的SQL盲注-延时判断(不需要任何回显) 基于报错的SQL盲注-报错回显(需要报错回显,没报错回…...

C# 将 Word 转文本存储到数据库并进行管理
目录 功能需求 范例运行环境 设计数据表 关键代码 组件库引入 Word文件内容转文本 上传及保存举例 得到文件Byte[]数据方法 查询并下载Word文件 总结 功能需求 将 WORD 文件的二进制信息存储到数据库里,即方便了统一管理文件,又可以实行权限控…...

VRRP协议
目录 VRRP协议基本概述 VRRP的基本结构 设备类型 VRRP工作原理 VRRP配置的实现 VRRP的实验 VRRP协议基本概述 1.VRRP能够在不改变组网的情况下,将多台路由器虚拟成一个虚拟路由器,通过配置虚拟路由器 的IP地址为默认网关,实现网关的备…...

Python学习之-基础语法
第1关:行与缩进 任务描述 本关任务:改正代码中不正确的缩进,使其能够正常编译,并输出正确的结果。 编程要求 根据提示,改正右侧编辑器中代码的缩进错误,使其能够正确运行,并输出结果。 测试说明…...

Java八股文(SpringCloud Alibaba)
Java八股文のSpringCloud Alibaba SpringCloud Alibaba SpringCloud Alibaba Spring Cloud Alibaba与Spring Cloud有什么区别? Spring Cloud Alibaba是Spring Cloud的衍生版本,它是由Alibaba开发和维护的,相比于Spring Cloud,它在…...

【物联网开源平台】tingsboard安装与编译
别看这篇了,这篇就当我的一个记录,我有空我再写过一篇,编译的时候出现了一个错误,然后我针对那一个错误执行了一个命令,出现了绿色的succes,我就以为整个tingsboard项目编译成功了,后面发现的时候ÿ…...

俚语加密漫谈
俚语加密是一种古老而有效的通信方式,将特定词语或短语在群体内赋予特殊含义,从而隐藏真实信息。类似于方言,它在历史上的应用不可忽视。随着计算机时代的到来,现代密码学通过数学运算编织密语,使得加密变得更加高深莫…...

【Java程序设计】【C00368】基于(JavaWeb)Springboot的箱包存储系统(有论文)
TOC 博主介绍:java高级开发,从事互联网行业六年,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,博客中有上百套程序可供参考,欢迎共同交流学习。 项目简介 项目获取 🍅文末点击卡片…...

Mysql中的执行计划怎么分析?
一、背景 在我们日常工作中,我们可能会遇到一些慢SQL语句或者要对一些SQL进行性能优化,那么就需要使用explain对SQL进行执行计划分析了。Mysql中的执行计划可以通过EXPLAIN或DESCRIBE关键字获取,当我们拿到执行计划后可以帮助我们分析这条sq…...

sever00启动AList
sever00启动AList cd ~/domains/alist && ~/.npm-global/bin/pm2 start ./alist -- server 其他 Serv00是一个提供免费的Virtual Host的平台,其托管平台使用的是FreeBSD系统,并不是Linux。每个账号有效期10年,超过三个月不登入Pan…...

【产品经理】进阶为一名优秀的数字孪生与仿真产品经理
数字孪生和仿真这个领域的内容太前沿了,很多经验、心得都没有对外流传。对于想成为这种产品经理的同学来说比较困难。 数字孪生:百度的解释是,数字孪生是充分利用物理模型、传感器更新、运行历史等数据,集成多学科、多物理量、多尺…...

CloudCompare 二次开发(29)——最小二乘拟合平面
目录 一、概述二、代码集成三、结果展示一、概述 使用CloudCompare实现的最小二乘拟合平面。具体计算原理见:PCL 最小二乘拟合平面。 二、代码集成 1、mainwindow.h文件public中添加: void doActionPCLLeastSquareFitPlane(); // 最小二乘拟合平面2、mainwindow.cpp文件…...

代码随想录算法训练营第三十五天|860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球
860.柠檬水找零 本题看上好像挺难,其实挺简单的,大家先尝试自己做一做。 https://programmercarl.com/0860.%E6%9F%A0%E6%AA%AC%E6%B0%B4%E6%89%BE%E9%9B%B6.html 题目大意: 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。 顾客排…...

28位驻华大使、公使参访苏州金龙 点赞刚刚全球发布的新V系大巴
3月26日下午,由外交部组织的“驻华使节团参访江苏”活动走进苏州金龙。来自28个国家和国际组织的驻华大使、公使参观了苏州金龙展厅,并试乘体验了苏州金龙全新V系大巴。外交部中国政府欧洲事务特别代表吴红波,外交部礼宾司、翻译司、非洲司、…...

jenkins权限分配
1.安装权限插件 Role-Based Strategy 2.创建用户 3.修改全局安全配置中的授权策略为Role-Based Strategy 4.进入Manage and Assign Roles创建Global roles和Item roles 4.进入Assign Roles给用户分配role...

感受精酿啤酒的啤酒屋那份与众不同的宁静与惬意
在繁华的都市中,隐藏着一片天地,那就是Fendi Club啤酒的啤酒屋。这里不仅提供上好的啤酒,还有与众不同的氛围和服务,让每一位顾客都能享受到宾至如归的感觉。 走进Fendi Club啤酒的啤酒屋,你会被其与众不同的装饰风格所…...

大数加法C++实现
题目:假设输入是2个数字,可能超过long long类型能表示的范围,请输出两数相加的运算结果。 思路:2个数输入的时候,肯定都是用string存的,先将短的数在末尾补0,使得二者一样长。然后挨个位相加&am…...

如何使用CHAT-AI?
伴随着CHAT-GPT的出现,人们都喜欢上了CHAT-AI。嗯?你还不会用?! 教程来喽! 首先点这里的 … 点击扩展 接着选择“管理扩展” 点击之后搜索“wetab” 最后你需要注册一个号,然后就可以使用CHAT-AI啦&#x…...

文献速递:基于SAM的医学图像分割--SAMUS:适应临床友好型和泛化的超声图像分割的Segment Anything模型
Title 题目 SAMUS: Adapting Segment Anything Model for Clinically-Friendly and Generalizable Ultrasound Image Segmentation SAMUS:适应临床友好型和泛化的超声图像分割的Segment Anything模型 01 文献速递介绍 医学图像分割是一项关键技术,用…...

23届嵌入式被裁,有什么好的就业建议?
最近看到了一个提问,原话如下: 本人23届毕业生,就业方向嵌入式软件,坐标深圳,工作3月公司裁员,目前接近12月开始找工作。 boss上投递简历,校招岗,比较有规模的好公司基本已读不回&am…...

你的 Python 代码需要解释一下了!
Python 是一种相对简单的编程语言。它主要以解释型语言著称,这意味着每行代码都要通过解释器逐行执行。不过在某些时候,将 Python 代码翻译成计算机可以理解的内容,然后再逐行执行,可以减少繁琐。 在这种情况下,编译器…...

听说,抖音小店要废除新手期了?没错!大动作来了!
大家好,我是电商小布。 一个项目从它的推出,到发展,再到成为行业的头部,都是需要不断进行完善的。 抖音小店这个项目也是一样。 这不,抖店平台在前两天又推出了新的通知,宣布废止新手期商家规范。 也就…...