Quartz任务调度框架介绍和使用

news2024/9/21 12:37:27

一、Quartz介绍

Quartz [kwɔːts] 是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:

1.持久性作业 - 就是保持调度定时的状态;

2.作业管理 - 对调度作业进行有效的管理;

Quartz是一个强大任务调度框架,可以用来干嘛?

简单来说就是实现“计划(或定时)任务”的系统,例如:订单下单后未付款,15分钟后自动撤消订单,并自动解锁锁定的商品;一个OA系统需要在每周五9点自动生成数据报表;或者想每月10号自动还款;又或者每周给暗恋的女生定时发送邮件等等。

二、Quartz的核心概念

三大核心类 JObDetail(作业类),Trigger(触发器),Scheduler(调度器)。Trigger指定JObDetail什么时候发布任务。

1,任务job

job就是你想实现的任务类,每一个job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法。

Job:工作任务调度的接口,任务类需要实现该接口,该接口中定义execute方法,类似jdk提供的TimeTask类的run方法,在里面编写任务执行的业务逻辑。

Job:实例在Quartz中的生命周期,每次调度器执行job时它在调用execute方法前,会创建一个新的job实例,当调用完成后,关联的job对象实例会被是释放,释放的实例会被垃圾回收机制回收。

2,触发器Trigger

Trigger 为你执行任务的触发器,比如你想每天定时1点发送邮件,Trigger将会设置1点执行该任务。

Trigger主要包含两种:SimpleTrigger和CronTriggerr。

3,调度器Scheduler

Scheduler是任务的调度器,会将任务job和触发器TRigger结合,负责基于Trigger设定的时间执行job。

三、Quartz的几个常用API

Scheduler :用于与调度程序交互的主程序接口。

Job :预先定义的希望在未来时间被调度程序执行的任务类,自定义。

JobDetall :使用JobDetail来定义定时任务的实例,JobDetail实例是通过JobBuilder类创建。

JobDataMap :可包含数据对象,在job实例执行的是好,可使用包含的数据;JobDataMap是java Map接口的实现,增加了一些存取基本类型方法。

Trgger触发器 :Trigger对象是用于触发执行Job的,当调度一个Job时,我们实例一个触发器然后调整它的属性来满足Job执行的条件,表明任务在什么时候执行。定义了一个已经被安排的任务将在什么时候执行的时间条件,比如每秒执行一次。

JobBuilder :用于声明一个任务实例,也可以定义关于该任务的详情比如:任务名,组名等,这个声明的实例将作为一个实例执行的任务。

TriggerBuilder :触发器创建器,用于创建触发器trigger实例。

JobListener,TriggerListener,SchedulerListener监听器,用于对组件的监听。

四、Quartz的简单使用

运行程序,可以看到程序每隔1s会打印出内容,且在12s后程序结束。

创建项目并加入依赖,参考:【普通的IDEA maven java项目demo(hello word)-1.8】待更新CSDN链接

<dependency>

    <groupId>org.quartz-scheduler</groupId>

    <artifactId>quartz</artifactId>

    <version>2.3.2</version>

</dependency>

 

新建一个能够打印任意内容的Job:

import org.quartz.Job;

import org.quartz.JobExecutionContext;

 

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Random;

 

public class PrintWordsJob implements Job {

    @Override

    public void execute(JobExecutionContext jobExecutionContext) {

        String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss:SSS").format(new Date());

        System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));

    }

}

 

创建Schedule,执行任务:

import org.quartz.*;

import org.quartz.impl.StdSchedulerFactory;

 

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.concurrent.TimeUnit;

 

public class Demo {

 

    public static void main(String[] args) throws SchedulerException, InterruptedException {

 

        // 1、创建JobDetail实例,并与PrintWordsJob类绑定(Job执行内容)

        JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)

                .withIdentity("job1", "group1").build();

 

        // 2、构建Trigger实例,每隔1s执行一次

        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")

                .startNow()// 立即生效

                .withSchedule(SimpleScheduleBuilder.simpleSchedule()

                        .withIntervalInSeconds(1)// 每隔1s执行一次

                        .repeatForever()).build();// 一直执行

 

        // 3、创建调度器Scheduler并执行

        Scheduler scheduler = new StdSchedulerFactory().getScheduler();

        scheduler.scheduleJob(jobDetail, trigger);

        System.out.println("--------scheduler start ! ------------");

        System.out.println("at:" + new SimpleDateFormat("yy-MM-dd HH-mm-ss:SSS").format(new Date()) + ", prints: Hello scheduler");

        scheduler.start();

 

        // 睡眠12秒

        TimeUnit.MILLISECONDS.sleep(12000);

        scheduler.shutdown();

        System.out.println("at:" + new SimpleDateFormat("yy-MM-dd HH-mm-ss:SSS").format(new Date()) + ", prints: Hello scheduler");

        System.out.println("--------scheduler shutdown ! ------------");

    }

}

运行结果(注意看时间):

--------scheduler start ! ------------

at:23-08-22 00-05-01:123, prints: Hello scheduler

PrintWordsJob start at:23-08-22 00-05-01:129, prints: Hello Job-69

PrintWordsJob start at:23-08-22 00-05-02:052, prints: Hello Job-68

PrintWordsJob start at:23-08-22 00-05-03:057, prints: Hello Job-93

PrintWordsJob start at:23-08-22 00-05-04:061, prints: Hello Job-32

PrintWordsJob start at:23-08-22 00-05-05:057, prints: Hello Job-14

PrintWordsJob start at:23-08-22 00-05-06:051, prints: Hello Job-55

PrintWordsJob start at:23-08-22 00-05-07:058, prints: Hello Job-30

PrintWordsJob start at:23-08-22 00-05-08:048, prints: Hello Job-82

PrintWordsJob start at:23-08-22 00-05-09:058, prints: Hello Job-28

PrintWordsJob start at:23-08-22 00-05-10:059, prints: Hello Job-97

PrintWordsJob start at:23-08-22 00-05-11:053, prints: Hello Job-88

PrintWordsJob start at:23-08-22 00-05-12:048, prints: Hello Job-18

PrintWordsJob start at:23-08-22 00-05-13:057, prints: Hello Job-93

at:23-08-22 00-05-13:135, prints: Hello scheduler

--------scheduler shutdown ! ------------

五、Quartz核心详解

1.Job和JobDetail

Job是Quartz中的一个接口,接口下只有execute方法,在这个方法中编写业务逻辑。

JobDetail用来绑定Job,为Job实例提供许多属性:name、group、jobClass、jobDataMap

JobDetail绑定指定的Job,每次Scheduler调度执行一个Job的时候,首先会拿到对应的Job,然后创建该Job实例,再去执行Job中的execute()的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除。

为什么设计成JobDetail + Job,不直接使用Job?

JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。 这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。

2.Trigger、SimpleTrigger、CronTrigger

Trigger

Trigger是Quartz的触发器,会去通知Scheduler何时去执行对应Job。

new Trigger().startAt():表示触发器首次被触发的时间;

new Trigger().endAt():表示触发器结束触发的时间;

SimpleTrigger

  SimpleTrigger可以实现在一个指定时间段内执行一次作业任务或一个时间段内多次执行作业任务。

将下述代码替换上述【Quartz的简单使用】代码的 // 2、构建Trigger实例,每隔1s执行一次 内容

程序运行5s后开始执行Job,执行Job 5s后,再延时2s结束程序:

// 2、构建Trigger实例,每隔1s执行一次

        Date startDate = new Date();

        startDate.setTime(startDate.getTime() + 5000);

 

        Date endDate = new Date();

        endDate.setTime(startDate.getTime() + 5000);

 

        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")

                .usingJobData("trigger1", "这是jobDetail1的trigger")

                .startNow()//立即生效

                .startAt(startDate)

                .endAt(endDate)

                .withSchedule(SimpleScheduleBuilder.simpleSchedule()

                        .withIntervalInSeconds(1)// 每隔1s执行一次

                        .repeatForever()).build();// 一直执行

运行结果(注意看时间):

--------scheduler start ! ------------

at:23-08-22 00-08-34:658, prints: Hello scheduler

PrintWordsJob start at:23-08-22 00-08-39:573, prints: Hello Job-81

PrintWordsJob start at:23-08-22 00-08-40:553, prints: Hello Job-63

PrintWordsJob start at:23-08-22 00-08-41:560, prints: Hello Job-87

PrintWordsJob start at:23-08-22 00-08-42:562, prints: Hello Job-25

PrintWordsJob start at:23-08-22 00-08-43:554, prints: Hello Job-65

at:23-08-22 00-08-46:666, prints: Hello scheduler

--------scheduler shutdown ! ------------

CronTrigger

  CronTrigger功能非常强大,是基于日历的作业调度,而SimpleTrigger是精准指定间隔,所以相比SimpleTrigger,CroTrigger更加常用。CroTrigger是基于Cron表达式的,了解Cron表达式可参考:【cron表达式 详解】cron表达式 详解_linux cron表达式_西晋的no1的博客-CSDN博客

在线生成corn表达式: 在线Cron表达式生成器

将下述代码替换上述【Quartz的简单使用】代码的 // 2、构建Trigger实例,每隔1s执行一次 内容

从0秒开始,每5秒执行一次定时任务

        // 2.触发器

        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger", "group").startNow()//立刻执行

                .usingJobData("trigger1", "这是jobDetail1的trigger")

                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ? *"))//表示每次0秒时候执行。

                .build();

运行结果(注意看时间):

--------scheduler start ! ------------

at:23-08-22 00-21-35:870, prints: Hello scheduler

PrintWordsJob start at:23-08-22 00-21-35:877, prints: Hello Job-39

PrintWordsJob start at:23-08-22 00-21-40:001, prints: Hello Job-68

PrintWordsJob start at:23-08-22 00-21-45:002, prints: Hello Job-8

at:23-08-22 00-21-47:873, prints: Hello scheduler

--------scheduler shutdown ! ------------

六、JobListener

创建MyJobListener实现JobListener接口

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

import org.quartz.JobListener;

 

public class MyJobListener implements JobListener {

 

 

    public String getName() {

        return this.getClass().getSimpleName();

    }

 

    //Scheduler在jobDetail将要被执行时调用这个方法(执行前)

    public void jobToBeExecuted(JobExecutionContext context) {

        String jobName = context.getJobDetail().getKey().getName();

        System.out.println("我的job名1:" + jobName);

    }

 

    //Scheduler在jobDetail即将被执行,但又被TriggerListermer 否定时会调用该方法

    public void jobExecutionVetoed(JobExecutionContext context) {

        String jobName = context.getJobDetail().getKey().getName();

        System.out.println("我的job名2:" + jobName);

    }

 

    //Scheduler在jobDetail即将被执行之后调用这个方法。(执行后)

    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {

        String jobName = context.getJobDetail().getKey().getName();

        System.out.println("我的job名3:" + jobName);

    }

}

在scheduler创建后加入监听即可生效

scheduler.getListenerManager().addJobListener(new MyJobListener());

将下述蓝色代码放于上述【Quartz的简单使用】对应位置

// 3、创建调度器Scheduler并执行

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

scheduler.getListenerManager().addJobListener(new MyJobListener());

scheduler.scheduleJob(jobDetail, trigger);

运行结果(注意看时间):

--------scheduler start ! ------------

at:23-08-22 00-28-12:174, prints: Hello scheduler

我的job名1:job1

PrintWordsJob start at:23-08-22 00-28-12:179, prints: Hello Job-7

我的job名3:job1

我的job名1:job1

PrintWordsJob start at:23-08-22 00-28-13:112, prints: Hello Job-39

我的job名3:job1

我的job名1:job1

PrintWordsJob start at:23-08-22 00-28-23:111, prints: Hello Job-0

我的job名3:job1

我的job名1:job1

PrintWordsJob start at:23-08-22 00-28-24:115, prints: Hello Job-12

我的job名3:job1

at:23-08-22 00-28-24:179, prints: Hello scheduler

--------scheduler shutdown ! ------------

七、TriggerListener

任务调度过程中,与触发器Trigger相关的事件包括:触发器触发,触发器未正常触发,触发器完成等。

import org.quartz.JobExecutionContext;

import org.quartz.Trigger;

import org.quartz.TriggerListener;

 

public class MyTriggerListener implements TriggerListener {

    //用于获取触发器的名称

    public String getName() {//获取默认类名

        return this.getClass().getSimpleName();

    }

 

    //当与监听器相关联的trigger被触发,job上的execute()方法将被执行时,Scheduler就调用该方法

    public void triggerFired(Trigger trigger, JobExecutionContext context) {

        System.out.println("triggerFired");

    }

 

    //在Trigger触发后,job将要被执行时由Scheduler调用这个方法。

    //TriggerListener给一个选择去否决job的执行。如方法返回true,job此次将不会为trigger触发执行。false,放行。

    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {

        System.out.println("vetoJobExecution");

        return false;

    }

 

    //Scheduler 调用这个方法是在trigger错过时触发。

    public void triggerMisfired(Trigger trigger) {

        System.out.println("triggerMisfired");

    }

 

    //triggerComplete:trigger被触发并且完成了job的执行时,Scheduler调用这个方法。

    public void triggerComplete(Trigger trigger, JobExecutionContext context,

                                Trigger.CompletedExecutionInstruction triggerInstructionCode) {

        System.out.println("triggerComplete");

    }

 

}

将下述蓝色代码放于上述【Quartz的简单使用】对应位置

// 3、创建调度器Scheduler并执行

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

scheduler.getListenerManager().addTriggerListener(new MyTriggerListener());

scheduler.scheduleJob(jobDetail, trigger);

运行结果(注意看时间):

--------scheduler start ! ------------

at:23-08-22 00-34-56:592, prints: Hello scheduler

triggerFired

vetoJobExecution

PrintWordsJob start at:23-08-22 00-34-56:601, prints: Hello Job-69

triggerComplete

triggerFired

vetoJobExecution

PrintWordsJob start at:23-08-22 00-35-07:530, prints: Hello Job-13

triggerComplete

triggerFired

vetoJobExecution

PrintWordsJob start at:23-08-22 00-35-08:535, prints: Hello Job-21

triggerComplete

at:23-08-22 00-35-08:597, prints: Hello scheduler

--------scheduler shutdown ! ------------

八、SchedulerListener

SchedulerListener会在scheduler的生命周期中关键事件发生时被调用,与Scheduler有关事件;增加或者删除一个 job/trigger,关闭scheduler等。

import org.quartz.*;

 

public class MySchedulerListener implements SchedulerListener {

 

    //用于部署JobDetail 的时候调用

    public void jobScheduled(Trigger trigger) {

        String name = trigger.getKey().getName();

        System.out.println("获取触发器名称:" + name);

    }

 

    //卸载JobDetail 的时候调用

    public void jobUnscheduled(TriggerKey triggerKey) {

        System.out.println(triggerKey.getName());

    }

 

    //当trigger来到再也不会触发的时候调用这个方法

    public void triggerFinalized(Trigger trigger) {

        String name = trigger.getKey().getName();

        System.out.println("获取触发器名称:" + name);

    }

 

    //当trigger 被暂停时候调用

    public void triggerPaused(TriggerKey triggerKey) {

        System.out.println("被暂停1");

    }

 

    //当trigger组  被暂停时候调用

    public void triggersPaused(String triggerGroup) {

        System.out.println("被暂停2");

    }

 

    ///当trigger从  被暂停 到恢复 时候 调用

    public void triggerResumed(TriggerKey triggerKey) {

        System.out.println("恢复");

    }

 

    ///当trigger组从  被暂停 到恢复 时候 调用

    public void triggersResumed(String triggerGroup) {

        System.out.println("恢复");

    }

 

    //添加工作任务调用

    public void jobAdded(JobDetail jobDetail) {

        System.out.println("添加工作任务");

 

    }

 

    //删除工作任务

    public void jobDeleted(JobKey jobKey) {

        System.out.println("删除工作任务");

 

    }

 

    public void jobPaused(JobKey jobKey) {

        // TODO Auto-generated method stub

 

    }

 

    public void jobsPaused(String jobGroup) {

        // TODO Auto-generated method stub

 

    }

 

    public void jobResumed(JobKey jobKey) {

        // TODO Auto-generated method stub

 

    }

 

    public void jobsResumed(String jobGroup) {

        // TODO Auto-generated method stub

 

    }

 

    //scheduler产生Error调用

    public void schedulerError(String msg, SchedulerException cause) {

        // TODO Auto-generated method stub

 

    }

 

    //scheduler被挂起时候调用

    public void schedulerInStandbyMode() {

        // TODO Auto-generated method stub

 

    }

 

    //scheduler开启的时候调用

    public void schedulerStarted() {

        System.out.println("scheduler 开启 的时候调用");

 

    }

 

    //scheduler 正在开启的时候调用 ing.....

    public void schedulerStarting() {

        System.out.println("scheduler 正在开启的时候调用 ing.....");

 

    }

 

    // scheduler关闭 的时候调用

    public void schedulerShutdown() {

        System.out.println("scheduler关闭 的时候调用");

 

    }

 

    //scheduler 正在关闭的时候调用 ing.....

    public void schedulerShuttingdown() {

        System.out.println("//scheduler 正在关闭的时候调用 ing.....");

 

    }

 

    //scheduler 数据被清除了的时候调用

    public void schedulingDataCleared() {

        System.out.println("//scheduler 数据被清除了的时候调用");

 

    }

 

}

将下述蓝色代码放于上述【Quartz的简单使用】对应位置

// 3、创建调度器Scheduler并执行

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());

scheduler.scheduleJob(jobDetail, trigger);

运行结果(注意看时间):

添加工作任务

获取触发器名称:trigger1

--------scheduler start ! ------------

at:23-08-22 00-37-43:391, prints: Hello scheduler

scheduler 正在开启的时候调用 ing.....

scheduler 开启 的时候调用

PrintWordsJob start at:23-08-22 00-37-43:395, prints: Hello Job-74

PrintWordsJob start at:23-08-22 00-37-44:294, prints: Hello Job-62

PrintWordsJob start at:23-08-22 00-37-45:301, prints: Hello Job-84

PrintWordsJob start at:23-08-22 00-37-46:292, prints: Hello Job-19

PrintWordsJob start at:23-08-22 00-37-47:301, prints: Hello Job-82

PrintWordsJob start at:23-08-22 00-37-48:288, prints: Hello Job-42

PrintWordsJob start at:23-08-22 00-37-49:296, prints: Hello Job-19

PrintWordsJob start at:23-08-22 00-37-50:298, prints: Hello Job-4

PrintWordsJob start at:23-08-22 00-37-51:290, prints: Hello Job-10

PrintWordsJob start at:23-08-22 00-37-52:294, prints: Hello Job-78

PrintWordsJob start at:23-08-22 00-37-53:292, prints: Hello Job-42

PrintWordsJob start at:23-08-22 00-37-54:298, prints: Hello Job-49

PrintWordsJob start at:23-08-22 00-37-55:291, prints: Hello Job-13

//scheduler 正在关闭的时候调用 ing.....

scheduler关闭 的时候调用

at:23-08-22 00-37-55:397, prints: Hello scheduler

--------scheduler shutdown ! ------------

九、定时任务参数传递问题

将下述蓝色代码放于上述【Quartz的简单使用】1和2之间的位置

// 1、创建JobDetail实例,并与PrintWordsJob类绑定(Job执行内容)

JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)

         .withIdentity("job1", "group1").build();

// 传参

JobDataMap jobDataMap=jobDetail.getJobDataMap();

jobDataMap.put("name","传参test");

jobDataMap.put("age",11);

jobDataMap.put("sex","男");

 

// 2、构建Trigger实例,每隔1s执行一次

Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")

        .startNow()// 立即生效

        .withSchedule(SimpleScheduleBuilder.simpleSchedule()

                .withIntervalInSeconds(1)// 每隔1s执行一次

                .repeatForever()).build();// 一直执行

同时更新PrintWordsJob.java文件中的代码为以下内容:

import org.quartz.Job;

import org.quartz.JobDataMap;

import org.quartz.JobExecutionContext;

 

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Random;

 

public class PrintWordsJob implements Job {

    @Override

    public void execute(JobExecutionContext jobExecutionContext) {

        String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss:SSS").format(new Date());

        System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));

        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();

        System.out.println(jobDataMap.get("name").toString() + ":" + jobDataMap.get("age").toString() +":"+ jobDataMap.get("sex").toString());

    }

}

运行结果(注意看时间):

--------scheduler start ! ------------

at:23-08-22 01-00-24:165, prints: Hello scheduler

PrintWordsJob start at:23-08-22 01-00-24:176, prints: Hello Job-6

传参test:11:男

PrintWordsJob start at:23-08-22 01-00-25:114, prints: Hello Job-70

传参test:11:男

PrintWordsJob start at:23-08-22 01-00-26:106, prints: Hello Job-54

传参test:11:男

PrintWordsJob start at:23-08-22 01-00-36:104, prints: Hello Job-73

传参test:11:男

at:23-08-22 01-00-36:181, prints: Hello scheduler

--------scheduler shutdown ! ------------

参考资料:

1. https://blog.csdn.net/faramita_of_mine/article/details/123142384?ops_request_misc=&request_id=&biz_id=102&utm_term=quartz&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-6-123142384.142^v93^chatgptT3_2&spm=1018.2226.3001.4187

2. https://blog.csdn.net/yoonbongchi/article/details/110579024?ops_request_misc=&request_id=&biz_id=102&utm_term=quartz&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-3-110579024.142^v93^chatgptT3_2&spm=1018.2226.3001.4187

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/909449.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

物联网(IoT)安全挑战与解决方案: 分析物联网设备面临的安全威胁,以及如何设计和管理安全的IoT生态系统

第一章&#xff1a;引言 随着科技的飞速发展&#xff0c;物联网&#xff08;IoT&#xff09;作为连接世界的桥梁&#xff0c;已经成为现代社会不可或缺的一部分。然而&#xff0c;随着IoT设备数量的不断增加&#xff0c;其安全问题也日益显著。本文将深入探讨IoT领域面临的安全…

【Ubuntu20.04安装Nvidia驱动、CUDA和CUDNN】

Ubuntu20.04安装Nvidia驱动、CUDA和CUDNN 1 Nvidia驱动安装1.1 安装1.2 安装Nvidia可能会遇到的问题1.2.1 NVIDIA 驱动与 Nouveau 驱动不兼容1.2.2 ERROR: Unable to find the development tool cc 2 CUDA安装2.1 下载和安装2.2 配置CUDA环境 3 安装CUDNN4 切换CUDA版本 1 Nvid…

min-height到底是什么?

1、概念 给元素设置最小高度&#xff0c;当height小于 min-height &#xff0c;min-height会覆盖height的值 2、案例 如果我有一个盒子A&#xff0c;A设置了min-height的高度为200px&#xff1b;并设置了overflow&#xff1a;auto&#xff0c;那么如果里面的内容超过了200px…

【经验】VScode 远程连接 Ubuntu 出错,Could not establish connection

用VScode常常会碰到以下情况&#xff0c;Could not establish connection。 先介绍一下VScode远程连接和终端SSH连接的区别&#xff1a;终端直接用SSH连接时&#xff0c;只需要开启SSH服务&#xff0c;并消耗少量的内存即可&#xff1b;VScode连接时&#xff0c;会自动在服务器…

MySQL基础篇 (三)

函数 回顾学过的函数 countavgsumminmax 数值函数 做数值运算的 演示 #ABS(X)SELECT ABS(0); #SIGN(X)SELECT SIGN(-10); #SQRT(X)SELECT SQRT(4); #LEAST(value1,value2,...)SELECT LEAST(10,20,15);字符串函数 做字符串处理&#xff08;CONCAT()&#xff09; 演示 #CO…

HCIP学习--三层架构

未完成 网关作为了一个广播域的中心出口&#xff1b;生成树的根网桥也是一棵树的中心&#xff0c;也是流量的集合点&#xff1b; 若将两者分配不同的设备将导致网络通讯资源浪费&#xff0c;故强烈建议两者在同一台汇聚层设备上 举个例子 看下图若VLAN2要去找VLAN3设备需要…

java+springboot+mysql医院预约挂号管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的医院预约挂号管理系统&#xff0c;系统包含超级管理员、管理员、医生、患者角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;管理员管理&#xff1b;用户管理&#xff1b;科室管理&#xff1b;床位管理&…

问道管理:沪指弱势震荡跌0.38%,金融、地产等板块走弱,算力概念等活跃

21日早盘&#xff0c;沪指盘中弱势震荡下探&#xff0c;创业板指一度跌逾1%失守2100点&#xff1b;北向资金小幅净流出。 截至午间收盘&#xff0c;沪指跌0.38%报3120.18点&#xff0c;深成指跌0.24%&#xff0c;创业板指跌0.62%&#xff1b;两市算计成交4238亿元&#xff0c;…

钛合金为何成为iPhone 15 Pro材料首选?

多年来&#xff0c;iPhone Pro一直采用厚重的钢框架&#xff0c;但不会持续太久。 有了iPhone 15 Pro&#xff0c;苹果可能会从钢框架转向钛框架&#xff0c;这不仅仅是因为它听起来更酷。钛比钢有很多优点&#xff0c;尤其是它更轻&#xff0c;这将解决iPhone Pro与普通iPhon…

Nvidia Jetson 编解码开发(3)解决H265解码报错“PPS id out of range”

1.问题描述 基于之前的开发程序 Nvidia Jetson 编解码开发(2)Jetpack 4.x版本Multimedia API 硬件编码开发--集成encode模块_free-xx的博客-CSDN博客 通过Jetson Xavier NX 硬编码的H265发出后, 上位机断点播放发出来的H265码流, 会报“PPS id out of range” 错误 …

有没有免费格式转换工具推荐?PDF转化为PPT的方法

在当今职场生活中&#xff0c;掌握文件格式转换技能变得异常重要。将PDF文档转换为PPT格式可以在演讲、报告等场合更好地展示和传达信息&#xff0c;为我们的专业形象增添亮点&#xff0c;接下来我们可以一起来看一下“有没有免费格式转换工具推荐?PDF转化为PPT的方法”相关的…

使用kubeadm安装和设置Kubernetes(k8s)

用kubeadm方式搭建K8S集群 kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。 这个工具能通过两条指令完成一个kubernetes集群的部署&#xff1a; # 创建一个 Master 节点 kubeadm init# 将一个 Node 节点加入到当前集群中 kubeadm join <Master节点的IP和端口…

2023 网络建设与运维 X86架构计算机操作系统安装与管理题解

任务描述: 随着信息技术的快速发展,集团计划2023年把部分业务由原有的X86架构服务器上迁移到ARM架构服务器上,同时根据目前的部分业务需求进行了部分调整和优化。 一、X86架构计算机操作系统安装与管理 1.PC1系统为ubuntu-desktop-amd64系统(已安装,语言为英文),登录用户…

基于深度学习的图像风格迁移发展总结

前言 本文总结深度学习领域的图像风格迁移发展脉络。重点关注随着GAN、CUT、StyleGAN、CLIP、Diffusion Model 这些网络出现以来&#xff0c;图像风格迁移在其上的发展。本文注重这些网络对图像风格迁移任务的影响&#xff0c;以及背后的关键技术和研究&#xff0c;并总结出一…

*看门狗1

//while部分是我们在项目中具体需要写的代码&#xff0c;这部分的程序可以用独立看门狗来监控 //如果我们知道这部分代码的执行时间&#xff0c;比如是500ms&#xff0c;那么我们可以设置独立看门狗的 //溢出时间是600ms&#xff0c;比500ms多一点&#xff0c;如果要被监控的程…

解决`java.lang.NoClassDefFoundError`在Nacos和Spring Boot集成中的问题

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

财务数据分析用什么软件好?奥威BI自带方案

做财务数据分析&#xff0c;光有软件还不够&#xff0c;还需要有标准化的智能财务数据分析方案。奥威BI数据可视化工具就是这样一款自带智能财务数据分析方案的软件。 ”BI方案“&#xff0c;一站式做财务数据分析 奥威BI数据可视化工具和智能财务分析方案结合&#xff0c;可…

一套基于C#语言开发的LIMS实验室信息管理系统源码

实验室信息管理系统&#xff08;LIMS)是指帮助实验室组织和管理实验数据的计算机软件系统&#xff0c;它将实验室操作有机地组织在一起&#xff0c;以满足实验室工作流程的所有要求。它能以不同的方式支持实验室的工作&#xff0c;从简单的过程(如样品采集和入库)到复杂的流程(…

抖音短视频SEO矩阵系统源码开发及开发者思路分享......

抖音矩阵号/抖音短视频SEO矩阵系统源码开发及开发者思路分享: 短视频获客系统支持短视频智能剪辑、短视频定时发布&#xff0c;短视频排名查询及优化&#xff0c;智能客服等&#xff0c;那么短视频seo系统开发时需要开发哪些功能呢&#xff1f;今天我就跟大家分享一下我们的开发…

数学建模及数据分析 || 4. 深度学习应用案例分享

PyTorch 深度学习全连接网络分类 文章目录 PyTorch 深度学习全连接网络分类1. 非线性二分类2. 泰坦尼克号数据分类2.1 数据的准备工作2.2 全连接网络的搭建2.3 结果的可视化 1. 非线性二分类 import sklearn.datasets #数据集 import numpy as np import matplotlib.pyplot as…