使用Quartz.net + Topshelf完成服务调用

news2025/1/11 20:01:17

概述:

Quartz.NET 是一个开源作业调度库,可用于在 .NET 应用程序中调度和管理作业。它提供了一个灵活而强大的框架,用于调度作业在特定的日期和时间或以固定的时间间隔运行,并且还支持复杂的调度场景,例如 cron 表达式。

Quartz.NET 基于Quartz 库,该库最初是用 Java 开发的。Quartz.NET 的创建是为了将Quartz的强大功能带入 .NET 平台,它已成为 .NET 应用程序中调度作业的流行选择。

Quartz.NET 的一些关键特性包括:

  • 支持根据特定日期和时间或定期安排作业
  • 支持使用cron 表达式的复杂调度场景
  • 能够安排作业在分布式环境中的特定节点上运行
  • 支持集群、故障转移和负载平衡
  • 能够将作业和触发数据保存到数据库
  • 与流行的 .NET 框架集成,例如 ASP.NET 和 Spring.NET
    以下是配置及使用过程:
官方学习文档:
http://www.quartz-scheduler.net/documentation/index.html
使用实例介绍:
https://www.quartz-scheduler.net/documentation/quartz-2.x/quick-start.html#nuget-package
官方源码下载:
https://sourceforge.net/projects/quartznet/files/quartznet/

1、根据官方源码下载地址我们找到一个文件版本进行下载
在这里插入图片描述

文件介绍:

在这里插入图片描述

文件介绍
Configuration.cs这个文件定义了Quartz.NET的配置类,包括调度器的实例化、作业存储、线程池、触发器监听器、作业监听器等配置项
IQuartzServer.cs这个文件定义了Quartz.NET的服务器接口,包括启动、停止、暂停和恢复调度器等方法
Program.cs入口程序,演示了如何使用Quartz.NET进行作业调度
quartz.config这个文件是Quartz.NET的配置文件,用于配置调度器的行为和特性,例如调度器类型、线程池大小、作业存储类型等等
quartz_jobs.xml这个文件定义了Quartz.NET的作业和触发器,包括作业名称、作业类型、触发器类型、触发器表达式等等
QuartzServer.cs这个文件实现了IQuartzServer接口,是Quartz.NET服务器的实现代码,包括调度器的启动、停止、暂停和恢复等方法
SampleJob.cs这个文件是一个示例作业,演示了如何实现一个简单的Quartz.NET作业
QuartzServerFactory.cs这个文件是Quartz.NET服务器的工厂类,用于创建和销毁Quartz.NET服务器实例

总的来说,这些文件是Quartz.NET框架的核心文件,包含了Quartz.NET的配置、调度器、作业和触发器等组件的实现。

接下来我们运行文件,可以看到quartz_job.xml文件中配置的是10秒运行一次,运行起来之后,每隔十秒会有输出
在这里插入图片描述

搭建一个Quartz,本人本地是基于.NET Framework 4.0搭建的(可使用更高版本)

1、安装下载NuGet程序包

Common.Logging 3.4.1.0
Common.Logging.Core 3.4.1.0
log4net 2.0.15.0
Quartz 2.6.2.0
Topshelf 3.3.152.0
Topshelf.Log4Net 3.3.152.0

  
Quartz:这是 Quartz.NET 的核心包,包含了调度器、作业、触发器等组件。
Common.Logging:这个包是一个通用的日志框架,Quartz.NET 使用它来记录日志。
Common.Logging.Log4Net:这个包是 Common.Logging 的 Log4Net 适配器,Quartz.NET 需要引用它来使用 Log4Net 记录日志
Topshelf:这是 Topshelf 的核心包,包含了将应用程序转换为 Windows 服务的功能。
Topshelf.Log4Net:这个包提供了 Log4Net 日志框架的支持,允许您在 Topshelf 中使用 Log4Net 记录日志。  

2、实现IJob

TimeJob.cs实现IJob,在Execute方法中编写要处理的业务逻辑,系统就会按照Quartz的配置,定时处理

using log4net;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QuartzSDS.QuartzJobs
{
    public sealed class TimeJob : IJob
    {
        private readonly ILog _logger = LogManager.GetLogger(typeof(TimeJob));

        public void Execute(IJobExecutionContext context)
        {
            _logger.InfoFormat("执行TimeJob业务");
            Console.WriteLine($"执行TimeJob业务");
        }
    }
}

3、使用Topshelf调度任务

Topshelf调度可以查看某大佬的使用介绍,以下是文章地址 :
https://www.cnblogs.com/jys509/p/4614975.html

using System;
using Common.Logging;
using Quartz.Impl;
using Topshelf;

namespace QuartzSDS
{
	/// <summary>
	/// The main server logic.
	/// </summary>
	public class QuartzServer : ServiceControl, IQuartzServer
	{
		private readonly ILog logger;
		private ISchedulerFactory schedulerFactory;
		private IScheduler scheduler;

        /// <summary>
        /// Initializes a new instance of the <see cref="QuartzServer"/> class.
        /// </summary>
	    public QuartzServer()
	    {
	        logger = LogManager.GetLogger(GetType());
	    }

	    /// <summary>
		/// Initializes the instance of the <see cref="QuartzServer"/> class.
		/// </summary>
		public virtual void Initialize()
		{
			try
			{				
				schedulerFactory = CreateSchedulerFactory();
				scheduler = GetScheduler();
			}
			catch (Exception e)
			{
				logger.Error("Server initialization failed:" + e.Message, e);
				throw;
			}
		}

        /// <summary>
        /// Gets the scheduler with which this server should operate with.
        /// </summary>
        /// <returns></returns>
	    protected virtual IScheduler GetScheduler()
	    {
	        return schedulerFactory.GetScheduler();
	    }

        /// <summary>
        /// Returns the current scheduler instance (usually created in <see cref="Initialize" />
        /// using the <see cref="GetScheduler" /> method).
        /// </summary>
	    protected virtual IScheduler Scheduler
	    {
	        get { return scheduler; }
	    }

	    /// <summary>
        /// Creates the scheduler factory that will be the factory
        /// for all schedulers on this instance.
        /// </summary>
        /// <returns></returns>
	    protected virtual ISchedulerFactory CreateSchedulerFactory()
	    {
	        return new StdSchedulerFactory();
	    }

	    /// <summary>
		/// Starts this instance, delegates to scheduler.
		/// </summary>
		public virtual void Start()
		{
	        try
	        {
	            scheduler.Start();
	        }
	        catch (Exception ex)
	        {
	            logger.Fatal(string.Format("Scheduler start failed: {0}", ex.Message), ex);
	            throw;
	        }

			logger.Info("Scheduler started successfully");
		}

		/// <summary>
		/// Stops this instance, delegates to scheduler.
		/// </summary>
		public virtual void Stop()
		{
            try
            {
                scheduler.Shutdown(true);
            }
            catch (Exception ex)
            {
                logger.Error(string.Format("Scheduler stop failed: {0}", ex.Message), ex);
                throw;
            }

			logger.Info("Scheduler shutdown complete");
		}

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
	    public virtual void Dispose()
	    {
	        // no-op for now
	    }

        /// <summary>
        /// Pauses all activity in scheduler.
        /// </summary>
	    public virtual void Pause()
	    {
	        scheduler.PauseAll();
	    }

        /// <summary>
        /// Resumes all activity in server.
        /// </summary>
	    public void Resume()
	    {
	        scheduler.ResumeAll();
	    }

	    /// <summary>
        /// TopShelf's method delegated to <see cref="Start()"/>.
	    /// </summary>
	    public bool Start(HostControl hostControl)
	    {
	        Start();
	        return true;
	    }

        /// <summary>
        /// TopShelf's method delegated to <see cref="Stop()"/>.
        /// </summary>
        public bool Stop(HostControl hostControl)
	    {
	        Stop();
	        return true;
	    }

        /// <summary>
        /// TopShelf's method delegated to <see cref="Pause()"/>.
        /// </summary>
        public bool Pause(HostControl hostControl)
	    {
	        Pause();
	        return true;
	    }

        /// <summary>
        /// TopShelf's method delegated to <see cref="Resume()"/>.
        /// </summary>
        public bool Continue(HostControl hostControl)
	    {
	        Resume();
	        return true;
	    }
	}
}

4、程序入口

using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Timers;
using Topshelf;

namespace QuartzSDS
{
 
    class Program
    {
        static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
            HostFactory.Run(x =>
            {
                x.UseLog4Net();

                x.Service<QuartzServer>();
                x.SetDescription("QuartzSDS集成平台调用");
                x.SetDisplayName("QuartzSDS");
                x.SetServiceName("QuartzSDS集成平台接口调用");

                x.EnablePauseAndContinue();
            });
        }
    }
}

5、配置quartz.config、quartz_jobs.xml、log4net.config

说明:这三个文件,分别选中→右键属性→复制到输入目录设为:始终复制,如图:
在这里插入图片描述
quartz.config文件

# You can configure your scheduler in either <quartz> configuration section
# or in quartz properties file
# Configuration section has precedence

quartz.scheduler.instanceName = QuartzTest

# configure thread pool info
quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
quartz.threadPool.threadCount = 10
quartz.threadPool.threadPriority = Normal

# job initialization plugin handles our xml reading, without it defaults are used
quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz
quartz.plugin.xml.fileNames = ~/quartzJobs.xml

# export this server to remoting context
#quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
#quartz.scheduler.exporter.port = 555
#quartz.scheduler.exporter.bindName = QuartzScheduler
#quartz.scheduler.exporter.channelType = tcp
#quartz.scheduler.exporter.channelName = httpQuartz

quartzJobs.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- This file contains job definitions in schema version 2.0 format -->

<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">

	<processing-directives>
		<overwrite-existing-data>true</overwrite-existing-data>
	</processing-directives>

	<schedule>

		<job>
			<!--name(必填) 任务名称,同一个group中多个job的name不能相同,若未设置group则所有未设置group的job为同一个分组,如:<name>sampleJob</name>-->
			<name>TimeJob</name>
			<!--group(选填) 任务所属分组,用于标识任务所属分组,如:<group>sampleGroup</group>-->
			<group>Time</group>
			<!--description(选填) 任务描述,用于描述任务具体内容,如:<description>Sample job for Quartz Server</description>-->
			<description>TimeJob执行调度</description>
			<!--job-type(必填) 任务类型,任务的具体类型及所属程序集,格式:实现了IJob接口的包含完整命名空间的类名,程序集名称,
      如:<job-type>Quartz.Server.SampleJob, Quartz.Server</job-type>-->
			<job-type>QuartzSDS.QuartzJobs.TimeJob,QuartzSDS</job-type>
			<!--durable(选填) 具体作用不知,官方示例中默认为true,如:<durable>true</durable>-->
			<durable>true</durable>
			<!--recover(选填) 具体作用不知,官方示例中默认为false,如:<recover>false</recover>-->
			<recover>false</recover>
		</job>
		<trigger>
			<cron>
				<!--name(必填) 触发器名称,同一个分组中的名称必须不同-->
				<name>TimeJobTrigger</name>
				<!--group(选填) 触发器组-->
				<group>Time</group>
				<!--description(选填) 触发器描述-->
				<description>TimeJob</description>
				<!--job-name(必填) 要调度的任务名称,该job-name必须和对应job节点中的name完全相同-->
				<job-name>TimeJob</job-name>
				<!--job-group(选填) 调度任务(job)所属分组,该值必须和job中的group完全相同-->
				<job-group>Time</job-group>
				<!--start-time(选填) 任务开始执行时间utc时间,北京时间需要+08:00,如:<start-time>2012-04-01T08:00:00+08:00</start-time>
      表示北京时间2012年4月1日上午8:00开始执行,注意服务启动或重启时都会检测此属性,若没有设置此属性或者start-time设置的时间比当前时间较早,
      则服务启动后会立即执行一次调度,若设置的时间比当前时间晚,服务会等到设置时间相同后才会第一次执行任务,一般若无特殊需要请不要设置此属性-->
				<start-time>2023-04-01T00:00:00+08:00</start-time>
				<!--am12点执行,pm12点执行-->
				<cron-expression>* * 0,12 * * ? </cron-expression>
			</cron>
		</trigger>

	</schedule>
</job-scheduling-data>

log4net.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>

  <log4net>
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <!--日志路径-->
      <param name= "File" value= "E:\QuartzSDSLog\log\"/>
      <!--是否是向文件中追加日志-->
      <param name= "AppendToFile" value= "true"/>
      <!--log保留天数-->
      <param name= "MaxSizeRollBackups" value= "10"/>
      <!--日志文件名是否是固定不变的-->
      <param name= "StaticLogFileName" value= "false"/>
      <!--日志文件名格式为:2008-08-31.log-->
      <param name= "DatePattern" value= "yyyy-MM-dd&quot;.read.log&quot;"/>
      <!--日志根据日期滚动-->
      <param name= "RollingStyle" value= "Date"/>
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n %loggername" />
      </layout>
    </appender>

    <!-- 控制台前台显示日志 -->
    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
      <mapping>
        <level value="ERROR" />
        <foreColor value="Red, HighIntensity" />
      </mapping>
      <mapping>
        <level value="Info" />
        <foreColor value="Green" />
      </mapping>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
      </layout>

      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="Info" />
        <param name="LevelMax" value="Fatal" />
      </filter>
    </appender>

    <root>
      <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
      <level value="all" />
      <appender-ref ref="ColoredConsoleAppender"/>
      <appender-ref ref="RollingLogFileAppender"/>
    </root>
  </log4net>
</configuration>

6、运行项目,以上quartzJobs.xml文件中cron-expression设置的是中午12点执行一次,凌晨12点执行一次

在这里插入图片描述

7、安装、启动、卸载服务命令

1、以管理身份运行cmd
2、例如此项目是在我电脑e盘下:
安装服务:
E:\Quartz.Net集成平台接口调用\QuartzSDS\QuartzSDS\bin\Debug\QuartzSDS.exe  install

启动服务:
E:\Quartz.Net集成平台接口调用\QuartzSDS\QuartzSDS\bin\Debug\QuartzSDS.exe  start

卸载服务:
E:\Quartz.Net集成平台接口调用\QuartzSDS\QuartzSDS\bin\Debug\QuartzSDS.exe  uninstall

在这里插入图片描述

quartz_jobs.xml详解:

  1. <job-scheduling-data>:这是根节点,它定义了 XML 文件的命名空间和版本号,同时包含了一个或多个 <schedule> 节点。

    • xmlns:指定了 XML 文件的命名空间为 http://quartznet.sourceforge.net/JobSchedulingData

    • xmlns:xsi:指定了 XML 文件中使用的 XML Schema 命名空间,用于指定 XML 文件的格式。

    • version:指定了 XML 文件的版本号,当前版本为 2.0。

  2. <schedule>:这个节点包含了作业和触发器的定义。

    • <job>:这个节点定义了一个作业。

      • <name>:作业的名称,必须唯一。

      • <group>:作业所属的组,可以用来对作业进行分组管理。

      • <description>:作业的描述信息,可以用来描述作业的用途等。

      • <job-type>:作业的类型,是一个类的完全限定名和程序集名称的组合,用于指定作业的实现类。

        例如,在上面的示例中,作业的类型为 MyNamespace.MyJob,表示在 MyAssembly 程序集中有一个名为 MyNamespace.MyJob 的类实现了该作业。

    • <trigger>:这个节点定义了一个触发器。

      • <cron>:这个节点表示使用 Cron 表达式来指定触发器的执行时间。

        • <name>:触发器的名称,必须唯一。

        • <group>:触发器所属的组,可以用来对触发器进行分组管理。

        • <description>:触发器的描述信息,可以用来描述触发器的用途等。

        • <job-name>:触发器关联的作业的名称。

        • <job-group>:触发器关联的作业所属的组。

        • <cron-expression>:Cron 表达式,用于指定触发器的执行时间。Cron 表达式是由 7 个字段组成的,分别表示秒、分、时、日、月、周、年等时间信息。

          例如,在上面的示例中,Cron 表达式 0 0/5 * * * ? 表示每隔 5 分钟执行一次。

在配置文件中,您可以定义多个作业和触发器,以便根据配置文件中的设置执行多个作业。在加载配置文件时,Quartz.NET 将会根据作业和触发器的定义创建对应的作业和触发器,并将它们添加到调度器中,以便按照指定的时间表执行作业。

Quartz的cron表达式:
官方地址:https://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/crontrigger.html#introduction
在这里插入图片描述
Cron 表达式是一种用于指定定期执行任务的时间表达式,它由 7 个字段组成,分别表示秒、分、时、日、月、周、年等时间信息。

Cron 表达式的一般格式为:

<秒> <分> <时> <日> <月> <周> <年>

其中,<秒><分><时><日><月><周><年> 都是 0 到 59 或者 0 到 23 之间的整数值,具体含义如下:

  • <秒>:表示定时任务的秒数,取值范围为 0 到 59。

  • <分>:表示定时任务的分钟数,取值范围为 0 到 59。

  • <时>:表示定时任务的小时数,取值范围为 0 到 23。

  • <日>:表示定时任务的日期,取值范围为 1 到 31。

  • <月>:表示定时任务的月份,取值范围为 1 到 12。

  • <周>:表示定时任务的星期几,取值范围为 0 到 7,其中 0 和 7 都表示星期日。

  • <年>:表示定时任务的年份,取值范围为 1970 到 2099。

Cron 表达式中还可以使用特殊字符来表示一些特殊的时间规则,包括:

  • *:表示匹配任意值,比如 * * * * * * 表示每秒都执行一次任务。

  • ?:表示不指定值,用于代替 <日><周> 中的一个,比如 0 0 12 ? * MON-FRI 表示每周一到周五中午 12 点执行一次任务。

  • -:表示指定一个范围,比如 0 0 0 1-31 * * 表示每个月的 1 号到 31 号的零点都执行一次任务。

  • ,:表示列出多个值,比如 0 0 0 * * MON,WED 表示每周一和周三的零点都执行一次任务。

  • /:表示指定一个步长,比如 0/5 * * * * * 表示每隔 5 秒钟执行一次任务。

注意,Cron 表达式中的所有时间都是基于调度器所在的服务器的本地时间而定的。如果需要使用其他时区的时间,可以在配置文件中指定时区信息。
以上是使用Quartz.net + Topshelf完成服务调用,如有错误可指正 Thanks♪(・ω・)ノ

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

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

相关文章

39.Java-interface接口

interface接口 1.interface2.接口的定义和使用3.接口中成员的特点4. 接口和类之间的关系5. 实例6. 接口中新增的方法6.1 JDK8以后新增2种方法6.1.1 允许在接口中定义默认方法6.1.2 允许在接口中定义静态方法 6.2 JDK9以后新增的方法6.3 小结 7. 接口总结 1.interface 接口就是…

Netty内存管理--内存池PoolArena

一、写在前面 到这里, 想必你已知道了Netty中的内存规格化(SizedClass), Page和SubPage级别的内存分配, 但是具体使用者不应该关心应该申请page还是subpage。而且从过去的经验来说, 申请page/subpage的数量也是个动态值, 如果申请使用完之后就释放那使用内存池的意义就不大。N…

Linux 之十九 编译工具链、.MAP 文件、.LST 文件

.map 文件和 .lst 文件是嵌入式开发中最有用的俩调试辅助文件。现在主要从事 RISC-V 架构&#xff0c;开始与 GCC 打交道&#xff0c;今天就重点学习一下 GCC 的 .map 文件、.lst 文件&#xff0c;并辅助以 ARMCC 和 IAR 作为对比。 编译工具链 .map 文件和 .lst 文件都是由编…

【数据结构】第十三站:排序性质

文章目录 一、文件外与文件内排序二、非比较排序之计数排序1.绝对映射2.相对映射3.代码实现 三、排序的稳定性 一、文件外与文件内排序 如下图所示是我们常见的的排序算法&#xff0c;也是我们已经使用代码实现过的 上面这七种排序算法我们都可以称之为文件内排序。但是归并排…

Fetch

Fetch 也是前后端通信的一种方式。是 Ajax 的一种替代方案。 Fetch 的优缺点&#xff1a; Fetch 的优点&#xff1a; 原生就有 fetch 对象&#xff0c;使用简单。基于 Promise。 Fetch 的缺点&#xff1a; 兼容性没有 Ajax 好。原生没有提供 abort、timeout等机制。 fetc…

【笔记】cuda大师班7-11 索引

一. block&#xff0c;grid 的 idx & dim 注意区分threadIdx&#xff0c;blockIdx 1.1 blockIdx 每一个线程在cuda运行时唯一初始化的blockIdx变量只取决于所属的坐标&#xff0c;blockIdx同样也是dim3类型 1.1. 对比blockIdx和threadIdx blockIdx只取决于当前block在…

786. 第k个数(C++和Python3)——2023.4.30打卡

文章目录 QuestionIdeasCode Question 给定一个长度为 n 的整数数列&#xff0c;以及一个整数 k &#xff0c;请用快速选择算法求出数列从小到大排序后的第 k 个数。 输入格式 第一行包含两个整数 n 和 k 。 第二行包含 n 个整数&#xff08;所有整数均在 1∼109 范围内&…

每天一道算法练习题--Day16 第一章 --算法专题 --- ----------哈夫曼编码和游程编码

Huffman encode(哈夫曼编码) Huffman 编码的基本思想就是用短的编码表示出现频率高的字符&#xff0c;用长的编码来表示出现频率低的字符&#xff0c;这使得编码之后的字符串的平均长度、长度的期望值降低&#xff0c;从而实现压缩的目的。 因此 Huffman 编码被广泛地应用于无…

Vue——自定义指令

目录 介绍​ 指令钩子​ 简化形式​ 对象字面量​ 在组件上使用​ 介绍​ 除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外&#xff0c;Vue 还允许你注册自定义的指令 (Custom Directives)。 我们已经介绍了两种在 Vue 中重用代码的方式&#xff1a;组件和组合…

【Android入门到项目实战-- 7.3】—— 如何调用手机摄像头和相册

目录 一、调用摄像头拍照 二、打开相册选择照片 学完本篇文章可以收获如何调用手机的摄像头和打开手机相册选择图片功能。 一、调用摄像头拍照 先新建一个CameraAlbumTest项目。 修改activity_main.xml,代码如下&#xff1a; 按钮打开摄像头&#xff0c;ImageView将拍到的…

一文打尽目标检测NMS(1): 精度提升篇

文章来自于&#xff1a;曲終人不散丶知乎&#xff0c; 连接&#xff1a;https://zhuanlan.zhihu.com/p/151914931&#xff0c; 本文仅用于学术分享&#xff0c;如有侵权&#xff0c;前联系后台做删文处理。 众所周知&#xff0c;非极大值抑制NMS是目标检测常用的后处理算法&…

黑客如何在攻击中使用生成式人工智能以及我们能做些什么?

生成式人工智能 (AI) 最近备受关注。AI 驱动的聊天机器人 ChatGPT 和 VALL-E 等其他支持自然语言处理的系统已将生成 AI 带给了公众&#xff0c;并释放了它的好处和坏处。 关于生成式 AI 的核心担忧之一是它可用于升级恶意攻击并提出更复杂的网络攻击。 那么&#xff0c;黑客…

简单有趣的轻量级网络 Shufflenet v1 、Shufflenet v2(网络结构详解+详细注释代码+核心思想讲解)——pytorch实现

这期博客咱们来学习一下Shufflenet系列轻量级卷积神经网络,Shufflenet v1 、Shufflenet v2。 首先学习一下,Shufflenet v1网络: 论文下载链接: Shufflene系列轻量级卷积神经网络由旷世提出,也是非常有趣的轻量级卷积神经网络,它提出了通道混合的概念,改善了分组卷积存…

IPsec中IKE与ISAKMP过程分析(主模式-消息3)

IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息1&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息2&#xff09;_搞搞搞高傲的博客-CSDN博客 阶段目标过程消息IKE第一阶段建立一个ISAKMP SA实现通信双发的身份鉴别和密钥交换&…

【Java笔试强训 15】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;查找输入…

Vue中 引入使用 patch-package 为依赖打补丁 (以修改 vue-pdf 打包后 [hash].worker.js 路径问题为例)

1. patch-package 简介 patch-package npm地址 patch-package github文档 npm i patch-package如果不需要在生产中运行 npm (如&#xff1a;正在制作 web 前端&#xff0c;则可使用 --save dev&#xff09; 1.2 使用方法 制作修补程序 首先更改 node_modules 文件夹中特定包…

大数据之Spark集群角色

文章目录 前言一、Spark集群角色介绍&#xff08;一&#xff09;Spark集群简介&#xff08;二&#xff09;集群角色介绍 总结 前言 #博学谷IT学习技术支持# 上篇文章主要介绍了Spark的运行流程&#xff0c;可以通过链接复习以加深印象&#xff1a;Spark运行流程&#xff0c;本…

redis面试重点------源于黑马

缓存问题三兄弟 是因为不同的原因让请求全部打到了数据库而造成的问题 什么是缓存穿透&#xff1f; 缓存穿透是指查询一个数据&#xff0c;在redis和MySQL中都不存在。也就是查询一个数据不存在的数据&#xff0c;导致每次请求都会到达数据库&#xff0c;给数据造成很大的压力…

如何选择最适合你的商城小程序开发公司

随着电子商务的快速发展&#xff0c;越来越多的企业开始认识到商城小程序的重要性。作为一个准备开发商城小程序的企业&#xff0c;你一定会面临一个重要的问题&#xff1a;商城小程序开发哪家好&#xff1f;如何选择最适合你的商城小程序开发公司&#xff1f; 在选择商城小程…

【Java笔试强训 17】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;杨辉三角…