Quartz持久化(springboot整合mybatis版本实现调度任务持久化)--提供源码下载

1、Quartz持久化功能概述

1、实现使用quartz提供的默认11张持久化表存储quartz相关信息。

2、实现定时任务的编辑、启动、关闭、删除。

3、实现自定义持久化表存储quartz定时任务信息。

4、本案例使用springboot整合mybatis框架和MySQL数据库实现持久化

5、提供源码下载

2、认识quartz持久化

可以将调度信息存储到数据库中,进行持久化,当程序中断,再次启动的时候。任然会保留中断之前的数据,继续执行。

1、Quartz中通过JobStore来存储任务和触发器信息,Quartz默认使用RAMJobstore将任务和触发器的信息存储在内存中,但是当服务器宕机内存中的信息会丢失。

2、Quartz中通过JDBCJobStore将任务和触发器等信息保存在数据库中,实现持久化。

3、JDBCJobStoreSupport中包含两个子类:

JobStoreTX:表示自己管理事务,存储在数据库中,当程序中断,调度信息不会丢失,

支持事务,支持集群,再次启动时,会恢复因程序关闭,重启而错过的任务。

JobStoreCMT:表示使用容器管理事务

3、Quartz+MySQL持久化默认依赖的表信息

针对不同的数据库,表就放在不同的sql文件中。

如果你使用的是mysql数据库表信息就在tables_mysql.sql文件中。

重点:这些表不会自动执行,需要拷贝出来手动创建在你的数据库中。

mysql表信息如下

QRTZ _JOB_DETAILS 存储每一个已配置的Job的详细信息

QRTZ _TRIGGERS      存储已配置的Trigger的信息

QRTZ_BLOB_TRIGGERS    Trigger作为Blob类型存储

QRTZ _SIMPLE_TRIGGERS   存储SimpleTrigger的信息,包括重复次数、间隔、以及已触的次数

QRTZ _CRON_TRIGGERS  存储CronTrigger,包括Cron表达式和时区信息

QRTZ _SIMPROP_TRIGGERS存储CalendarIntervalTrigger和DailyTimeIntervalTrigger两种触发器

QRTZ _CALENDARS  存储Quartz的Calendar信息

QRTZ _PAUSED_TRIGGER_GRPS      存储已暂停的Trigger组的信息

QRTZ _FIRED_TRIGGERS   存储与已触发的Trigger相关的状态信息,以及相关Job的执行信息

QRTZ _SCHEDULER_STATE    存储少量的有关Scheduler的状态信息,和别的Scheduler实例

QRTZ _LOCKS   存储程序的悲观锁的信息

创表信息如下:

#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;CREATE TABLE QRTZ_JOB_DETAILS(SCHED_NAME VARCHAR(120) NOT NULL,JOB_NAME  VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,DESCRIPTION VARCHAR(250) NULL,JOB_CLASS_NAME   VARCHAR(250) NOT NULL,IS_DURABLE VARCHAR(1) NOT NULL,IS_NONCONCURRENT VARCHAR(1) NOT NULL,IS_UPDATE_DATA VARCHAR(1) NOT NULL,REQUESTS_RECOVERY VARCHAR(1) NOT NULL,JOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);CREATE TABLE QRTZ_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,JOB_NAME  VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,DESCRIPTION VARCHAR(250) NULL,NEXT_FIRE_TIME BIGINT(13) NULL,PREV_FIRE_TIME BIGINT(13) NULL,PRIORITY INTEGER NULL,TRIGGER_STATE VARCHAR(16) NOT NULL,TRIGGER_TYPE VARCHAR(8) NOT NULL,START_TIME BIGINT(13) NOT NULL,END_TIME BIGINT(13) NULL,CALENDAR_NAME VARCHAR(200) NULL,MISFIRE_INSTR SMALLINT(2) NULL,JOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);CREATE TABLE QRTZ_SIMPLE_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,REPEAT_COUNT BIGINT(7) NOT NULL,REPEAT_INTERVAL BIGINT(12) NOT NULL,TIMES_TRIGGERED BIGINT(10) NOT NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_CRON_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,CRON_EXPRESSION VARCHAR(200) NOT NULL,TIME_ZONE_ID VARCHAR(80),PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_SIMPROP_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,STR_PROP_1 VARCHAR(512) NULL,STR_PROP_2 VARCHAR(512) NULL,STR_PROP_3 VARCHAR(512) NULL,INT_PROP_1 INT NULL,INT_PROP_2 INT NULL,LONG_PROP_1 BIGINT NULL,LONG_PROP_2 BIGINT NULL,DEC_PROP_1 NUMERIC(13,4) NULL,DEC_PROP_2 NUMERIC(13,4) NULL,BOOL_PROP_1 VARCHAR(1) NULL,BOOL_PROP_2 VARCHAR(1) NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_BLOB_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,BLOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_CALENDARS(SCHED_NAME VARCHAR(120) NOT NULL,CALENDAR_NAME  VARCHAR(200) NOT NULL,CALENDAR BLOB NOT NULL,PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_GROUP  VARCHAR(200) NOT NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_FIRED_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,ENTRY_ID VARCHAR(95) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,FIRED_TIME BIGINT(13) NOT NULL,SCHED_TIME BIGINT(13) NOT NULL,PRIORITY INTEGER NOT NULL,STATE VARCHAR(16) NOT NULL,JOB_NAME VARCHAR(200) NULL,JOB_GROUP VARCHAR(200) NULL,IS_NONCONCURRENT VARCHAR(1) NULL,REQUESTS_RECOVERY VARCHAR(1) NULL,PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);CREATE TABLE QRTZ_SCHEDULER_STATE(SCHED_NAME VARCHAR(120) NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,LAST_CHECKIN_TIME BIGINT(13) NOT NULL,CHECKIN_INTERVAL BIGINT(13) NOT NULL,PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);CREATE TABLE QRTZ_LOCKS(SCHED_NAME VARCHAR(120) NOT NULL,LOCK_NAME  VARCHAR(40) NOT NULL,PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);commit;

4、在MySQL数据库中创建表

5、quartz默认配置文档

配置文件位置:

配置参考文档:

https://www.w3cschool.cn/quartz_doc/quartz_doc-i7oc2d9l.html

6、创建springboot工程配置quartz持久化

在正式开始之前我们需要明确一点,quartz自带的表数据的添加功能是quartz源码中自带的,我们只需要正确的配置数据源即可自动的添加数据。

6.1、创建工程引入相关包信息

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.7</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>quartzpersistencedemo3</artifactId><version>0.0.1-SNAPSHOT</version><name>quartzpersistencedemo3</name><description>quartzpersistencedemo3</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><image><builder>paketobuildpacks/builder-jammy-base:latest</builder></image><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build>
</project>

6.2、配置连接数据相关参数

最重要的配置就是连接数据库及job-store-type: jdbc,其他的配置如果不需要都可以不写。

最重要的配置就是连接数据库及job-store-type: jdbc,其他的配置如果不需要都可以不写。

spring:datasource:url: jdbc:mysql://localhost:3306/quartz?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=falsedriver-class-name: com.mysql.jdbc.Driverusername: rootpassword: 123456quartz:# 任务存储类型job-store-type: jdbc# 关闭时等待任务完成wait-for-jobs-to-complete-on-shutdown: false# 是否覆盖已有的任务overwrite-existing-jobs: true# 是否自动启动计划程序auto-startup: true# 延迟启动startup-delay: 0sjdbc:# 数据库架构初始化模式(never:从不进行初始化;always:每次都清空数据库进行初始化;embedded:只初始化内存数据库(默认值))# 注意:第一次启动后,需要将always改为never,否则后续每次启动都会重新初始化quartz数据库initialize-schema: never# 用于初始化数据库架构的SQL文件的路径# schema: classpath:sql/tables_mysql_innodb.sql# 相关属性配置properties:org:quartz:scheduler:# 调度器实例名称instanceName: QuartzScheduler# 分布式节点ID自动生成instanceId: AUTOjobStore:class: org.springframework.scheduling.quartz.LocalDataSourceJobStoredriverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate# 表前缀tablePrefix: QRTZ_# 是否开启集群isClustered: true# 数据源别名(自定义)dataSource: quartz# 分布式节点有效性检查时间间隔(毫秒)clusterCheckinInterval: 10000useProperties: false# 线程池配置threadPool:class: org.quartz.simpl.SimpleThreadPoolthreadCount: 10threadPriority: 5threadsInheritContextClassLoaderOfInitializingThread: true

6.3、创建quartz配置类

在配置类中配置JobDetail和trigger监听器

这个配置类只是添加任务的快捷方式,这中方式在下面的添加任务中会被替代。

@Configuration
public class QuartzJobConfig {@Beanpublic JobDetail jobDetail(){JobDetail detail= JobBuilder.newJob(MyQuartzJob.class).withIdentity("job33","group33").storeDurably()//设置Job持久化//设置job数据.usingJobData("username","xiaochun2").usingJobData("useraddr","安徽合肥2").build();return detail;}//创建触发器,触发实例@Beanpublic Trigger trigger(){//每隔5秒执行一次CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");Trigger trigger= TriggerBuilder.newTrigger().forJob(jobDetail()).withIdentity("trigger33","group33").withSchedule(cronScheduleBuilder).startNow().build();return trigger;}
}

6.4、创建job,配置任务具体内容

@Slf4j
public class MyQuartzJob extends QuartzJobBean {@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {//执行的具体内容log.info("=========quartzpersistencedemo3--quartz具体内容============");System.out.println(context.getJobInstance());System.out.println(context.getJobDetail().getJobDataMap().get("username"));}
}

6.5、启动任务并自动向数据库添加数据

从图中可以看出,任务已经顺利的启动

6.6、查看数据库数据情况

【qrtz_cron_triggers表数据】

【qrtz_job_details表数据】

【qrtz_triggers表数据】

【qrtz_scheduler_state表数据】

6.7、暂停任务

说明1通过scheduler.pauseJob暂停任务。

说明2scheduler.pauseJob需要的两个参数是qrtz_job_details表中的JOB_NAME和JOB_GROUP字段的值。

说明3本案例中只涉及到任务本身的暂停,考虑到业务的并发和分布式的情况,在暂停前可以判断一下任务是否存在,如果还创建了自己的业务表,应该在任务暂停后修改自己的表状态。个人业务表的所有操作按照常规操作即可。

@Controller
public class QuartzController {@ResourceScheduler scheduler;//暂停任务@RequestMapping("/suspendJob")@ResponseBodypublic String suspendJob(){String jobName="job33";String jobGroup="group33";try{scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));return "暂停成功";}catch (Exception e){return "暂停失败";}}
}

6.8、重启任务

重点说明:这个时候重启项目,程序会自动的加载QuartzConfig并创建JobDetailTrigger并自动的向数据库添加数据。

核心添加的qrtz_cron_triggersqrtz_job_detailsqrtz_triggersqrtz_scheduler_state

说明1通过scheduler.resumeJob重启任务

说明2scheduler. resumeJob需要的两个参数是qrtz_job_details表中的JOB_NAME和JOB_GROUP字段的值。

@Controller
public class QuartzController {@ResourceScheduler scheduler;//重启任务@RequestMapping("/resumeJob")@ResponseBodypublic String resumeJob() {String jobName="job33";String jobGroup="group33";try {//恢复任务scheduler.resumeJob(JobKey.jobKey(jobName,jobGroup));return "重启成功";} catch (SchedulerException e) {return "重启失败";}}
}

6.9、删除任务

删除任务会清除数据库中的数据

@Controller
public class QuartzController {@ResourceScheduler scheduler;//删除任务@RequestMapping("/removeJob")@ResponseBodypublic String removeJob() throws SchedulerException {String jobName="job33";String jobGroup="group33";//先暂停任务scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));//获取任务触发器TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);try {//停止触发器scheduler.pauseTrigger(triggerKey);//移除触发器scheduler.unscheduleJob(triggerKey);//删除任务scheduler.deleteJob(JobKey.jobKey(jobName,jobGroup));return "删除任务成功";} catch (SchedulerException e) {return "删除任务失败";}}
}

6.10、立即启动任务

重点:只会启动一次

@Controller
public class QuartzController {@ResourceScheduler scheduler;//立即启动任务@RequestMapping("/triggerJob")@ResponseBodypublic String triggerJob() {String jobName="job33";String jobGroup="group33";try {scheduler.triggerJob(JobKey.jobKey(jobName,jobGroup));return "启动成功";} catch (SchedulerException e) {return "启动失败";}}
}

6.11、添加任务

【添加任务依赖对象】

对时区不了解,可以看这篇文章:Java中ZonedDateTime使用详解及时间转化(java中获取时区)_java zoneddatetime-CSDN博客

6.11.1、添加任务依赖对象

对时区不了解,可以看这篇文章:Java中ZonedDateTime使用详解及时间转化(java中获取时区)_java zoneddatetime-CSDN博客

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class JobInfo {private String jobName;//job名称private String jobGroup;//job所属组private String triggerName;//触发器名称private String jobDescription;//job任务描述private Map<String,Object> userData;//job携带的用户参数private String cron;//触发器规则private String timeZoneId;//当前时区
}

6.11.2、实现任务添加代码

在项目中使用到了ObjectMapper对象,将map转化成json字符串,不了解可以看文章:

Springboot中解析JSON字符串(jackson库ObjectMapper解析JSON字符串)-CSDN博客

重点:小伙伴需要注意了,创建任务的时候MyQuartzJob任务本身这个是需要提前创建的。

//添加任务
@RequestMapping(value = "/addJob",method = RequestMethod.POST)
@ResponseBody
public String  addJob(@RequestBody JobInfo jobInfo) throws JsonProcessingException {System.out.println("======addJob==="+jobInfo.toString());//通过jobKey判断任务是否唯一// jobKey有jobName和jobGroup组成JobKey jobKey = JobKey.jobKey(jobInfo.getJobName(), jobInfo.getJobGroup());try {JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (Objects.nonNull(jobDetail)) {scheduler.deleteJob(jobKey);}} catch (SchedulerException e) {e.printStackTrace();}//将map转化成json的工具ObjectMapper objectMapper=new ObjectMapper();//任务详情JobDetail jobDetail = JobBuilder.newJob(MyQuartzJob.class)//jobDetail描述.withDescription(jobInfo.getJobDescription())  //任务描述.usingJobData("userData",objectMapper.writeValueAsString(jobInfo.getUserData())).withIdentity(jobKey) //指定任务.build();//根据cron,TimeZone时区,指定执行计划CronScheduleBuilder builder =CronScheduleBuilder//任务表达式.cronSchedule(jobInfo.getCron()).inTimeZone(TimeZone.getTimeZone(jobInfo.getTimeZoneId()));//触发器Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobInfo.getTriggerName(), jobInfo.getJobGroup()).startNow().withSchedule(builder).build();//添加任务try {scheduler.scheduleJob(jobDetail, trigger);return "任务添加成功";} catch (SchedulerException e) {System.out.println(e.getMessage());}return "任务添加失败";
}

6.11.3、在postman中的测试

由于我们是在body中传递的数据,在addJob方法接受的参数需要使用@RequestBody注解,

如果不使用请求获取不到body的raw传递的数据。

测试参数:

{

  "jobName":"jobName1",

  "jobGroup":"jobGroup1",

  "triggerName":"triggerName1",

  "jobDescription":"三点、六点、九点发优惠卷。",

  "cron":"0/5 * * * * ?",

  "timeZoneId":"Asia/Shanghai",

  "userData":{"name":"123"}

}

数据库参数:

结果输出:

6.12、修改任务

修改任务的本质就是添加任务,只要保证jobName,jobGroup,triggerName等关键参数不变,即可修改数据。

7、自定义任务表

Quartz总共提供了11张表来持久化分布式任务调度的相关信息,总体来说功能强大,但是比较冗余。这个时候很多人希望自己创建一张简单的表,实现任务管理也是可以的。但是这个时候对自定义表的增删改查操作都需要自己写,而无法使用默认提供了功能。

创建信息可以参照如下:
CREATE TABLE `my_job` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `jobName` varchar(50) NOT NULL COMMENT '任务名称',
  `jobGroupName` varchar(50) NOT NULL COMMENT '任务组名',

  `jobTriggerName` varchar(50) NOT NULL COMMENT '触发器名称',
  `jobCron` varchar(50) NOT NULL COMMENT '时间规则表达式',
  `jobClassPath` varchar(200) NOT NULL COMMENT '类全类型',
  `jobDataMap` varchar(100) DEFAULT NULL COMMENT '用户数据',
  `jobStatus` int(2) NOT NULL COMMENT '任务状态',
  `jobDescribe` varchar(100) DEFAULT NULL COMMENT '任务功能描述',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

值得注意的是,如果这个时候通过自定义修改了任务状态为体质状态(如停止状态为1),修改之后还需要调用scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));,任他任务也是。因为我们的停止本质只是修改数据库的值。
 

8、源码下载

https://download.csdn.net/download/tangshiyilang/88660404

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024 年 10大 AI 趋势

2025 年&#xff0c;全球人工智能市场预计将达到惊人的 1906.1 亿美元&#xff0c;年复合增长率高达 36.62%。 人工智能软件正在迅速改变我们的世界&#xff0c;而且这种趋势在未来几年只会加速。 我们分析了未来有望彻底改变 2024 年的 10 个AI趋势。从生成式人工智能的兴起到…

谷歌Gemini造假始末

&#x1f4a1;大家好&#xff0c;我是可夫小子&#xff0c;《小白玩转ChatGPT》专栏作者&#xff0c;关注AIGC、读书和自媒体。 在过去一年中&#xff0c;OpenAI ChatGPT引发了一股AI新浪潮&#xff0c;而谷歌则一直处于被压制的状态&#xff0c;迫切需要一款现象级的AI产品来…

LSTM(长短期记忆网络)的设计灵感和数学表达式

1、设计灵感 LSTM&#xff08;长短期记忆网络&#xff09;的设计灵感来源于传统的人工神经网络在处理序列数据时存在的问题&#xff0c;特别是梯度消失和梯度爆炸的问题。 在传统的RNN&#xff08;循环神经网络&#xff09;中&#xff0c;信息在网络中的传递是通过隐状态向量进…

Linux6.2、IO基础(文件系统接口)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 直接使用系统接口 fopen底层封装的系统接口为open pathname也就是文件路径&#xff0c;flags我们通过一个demo来理解。 首先我们应该了解的是位图&#xff0c;int有32个比特位&#xff0c;我们根据他的比特位是否为1来决定这…

使用 fixture 机制重构 appium_helloworld

一、前置说明 在 pytest 基础讲解 章节,介绍了 pytest 的特性和基本用法,现在我们可以使用 pytest 的一些机制,来重构 appium_helloworld 。 appium_helloworld 链接: 编写第一个APP自动化脚本 appium_helloworld ,将脚本跑起来 代码目录结构: pytest.ini 设置: [pyt…

图像质量评估方法——结构相似性指数(SSIM)

结构相似性指数&#xff08;SSIM&#xff09;是一种全参考图像质量评估方法&#xff0c;用于比较两幅图像的相似性。 SSIM的计算涉及到亮度&#xff08;Luminance&#xff09;、对比度&#xff08;Contrast&#xff09;和结构&#xff08;Structure&#xff09;三个方面的相似性…

Docker 安装 MySQL5.7 和 MySQL8

文章目录 安装 MySQL5.7拉取镜像前期准备&#xff1a;启动容器 安装MySQL8.0拉取镜像查看镜像前期准备启动容器 安装 MySQL5.7 拉取镜像 docker pull mysql:5.7拉下来镜像后 执行 docker images 此时我们已经有这个镜像了。 前期准备&#xff1a; 在根目录下创建 app &…

PTA 最小生成树-kruskal

7-92 最小生成树-kruskal 分数 10 全屏浏览题目 作者 任唯 单位 河北农业大学 题目给出一个无向连通图&#xff0c;要求求出其最小生成树的权值。 温馨提示&#xff1a;本题请使用kruskal最小生成树算法。 输入格式: 输出格式: 输出一个整数表示最小生成树的各边的长度之和。…

Redis缓存常见问题之预热、雪崩、击穿、穿透

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

Ubuntu 22.04.3 Server 设置静态IP 通过修改yaml配置文件方法

目录 1.查看网卡信息 2.修改yaml配置文件 3.应用新的网络配置 4.重新启动网络服务 文章内容 本文介绍Ubuntu 22.04.3 Server系统通过修改yaml配置文件配置静态 ip 的方法。 1.查看网卡信息 使用ifconfig命令查看网卡信息获取网卡名称​ 如果出现Command ifconfig not fo…

单聊和群聊

TCP协议单聊服务端&#xff1a; import java.awt.BorderLayout; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Vec…

MySQL的替换函数及补全函数的使用

前提&#xff1a; mysql的版本是8.0以下的。不支持树形结构递归查询的。但是&#xff0c;又想实现树形结构的一种思路 提示&#xff1a;如果使用的是MySQL8.0及其以上的&#xff0c;想要实现树形结构&#xff0c;请参考&#xff1a;MySQL数据库中&#xff0c;如何实现递归查询…