分布式架构与XXL-JOB
目录
先了解什么是任务调度?
什么是分布式任务调度?
了解XXL-JOB分布式任务调度平台
如何搭建XXL-JOB?
分片广播
作业分片方案
最近学习在项目的媒资管理模块如何高效处理大量视频,上传单个视频可能涉及到转码,内容审核等多个处理部分
如果采用传统的单线程处理模式可能会导致资源利用率低下,所有操作依次排队会导致执行处理视频耗时较长,效率不高的问题出现
因此,在处理大量视频文件时,我们需要学习更高效的任务处理方式,如何高效满足这些视频处理需求?
1.采用多线程
- 在处理大量视频任务时,单线程处理效率较低,无法充分利用系统资源。为了提高处理效率可以采用多线程技术来并发处理任务
核心思想是:将一个任务拆分为多个子任务,并发执行这些子任务,充分利用CPU和内存资源,提高任务处理效率
2.采用分布式架构+多线程
- 通过分布式架构和多线程技术的结合,最大化利用计算资源,高效处理大规模任务,例如我们所说的处理大量视频文件
采用分布式+线程可扩展性更强,同时它也是一种 分布式任务调度 的处理方案
先了解什么是任务调度?
任务调度:顾名思义就是对任务的调度,它是指系统为了完成特定的业务,基于给定的时间点,给定的时间间隔或者给定执行次数自动执行任务
我们思考一下下面业务场景
- 某财务系统需要在每天上午10点结算前一天的账单数据,统计汇总
- 12306网站会根据车次不同,设置几个时间点分批放票
- 商品成功发货后,需要向客户发送短信提醒
以上这些场景,就是 任务调度 所需要解决的问题,类似场景还有很多,我们该如何实现?这里我举例三种实现方法
1.多线程方式实现
回顾多线程思想,当我们可以开启一个线程,每sleep一段时间,就去检查是否已经到预期执行时间
简单实现任务调度的功能(按一定的间隔时间执行任务调度的功能):
public static void main(String[] args){//任务执行时间间隔final long timeInterval = 1000;Runnable runnable = new Runnable()}{public void run(){while(true){//TODO:somethingtry{Thread.sleep(timeInterval);}catch(InterruptedException e){e.printStackTrace(); } }}};Thread thread = new Thread(runnable); thread.start(); }
}
2.Timer 和 ScheduledExecutor(JDK提供的相关支持)是用于定时任务调度的工具类,帮助我们在指定的时间点或周期性的执行任务
Timer的核心功能:
- 单次任务:在指定的延迟后执行一次任务
- 周期性任务:以固定的时间间隔重复执行任务
Timer的优点在于简单易用,每个Timer对应一个线程,因此可以同时启动多个Timer并行执行多个任务,同一个Timer中的任务是串行执行
Timer方法的实现:
public static void main(String[] args){Timer timer = new Timer();timer.schedule(new TimerTask(){@Overridepublic void run(){//TODO:someting }},1000,2000); //一秒开始调度,每2秒执行一次}
ScheduledExecutor方式实现:
public static void main(String [] args){//创建一个固定大小为10的线程池,用于执行定时任务(线程池中的线程可以并发执行多个任务)ScheduledExecutorService service = Executors.newScheduledThreadPool(10);service.scheduleAtFixedRate(new Runnable(){@Override//任务逻辑是打印“todo something”public void run(){//TODO:somethingSystem.out.print("todo something");}//任务将在一秒后首次执行,之后,任务以每2秒执行一次},1,2,TimeUnit.SECONDS);
}
scheduleAtFixedRate:
是用于以固定的速率调度任务,任务会在指定的初始延迟后开始执行,之后以固定的时间间隔重复执行
基于线程池设计的ScheduledExecutor,其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,因为任务是并发执行的,相互之间不会受到打扰
Timer和ScheduledExecutor都仅能提供基于开始时间与重复间隔的任务调度,不能胜任更加复杂的调度需求 — 比如,设置每月第一天凌晨1点执行任务,复杂调度任务的管理,任务间传递数据等等
3.再学习另一个功能强大的 任务调度框架Quartz,它可以满足更多更复杂的调度需求,Quartz设计的核心类包括Scheduler,Job以及Trigger,其中,Job负责定义需要执行的任务,Trigger负责设置调度策略,Scheduler将两者组装起来,并触发任务开始执行,Quartz支持简单的按时间间隔调度,还支持按日历调度方式,通过设置CronTrigger表达式(包括:秒,分,时,日,月,周,年)进行任务调度
public static void main(String [] agrs) throws SchedulerException {//创建一个SchedulerSchedulerFactory schedulerFactory = new StdSchedulerFactory();Scheduler scheduler = schedulerFactory.getScheduler();//创建JobDetailJobBuilder jobDetailBuilder = JobBuilder.newJob(MyJob.class);jobDetailBuilder.withIdentity("jobName","jobGroupName");JobDetail jobDetail = jobDetailBuilder.build();//创建触发的CronTrigger 支持按日历调度CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("triggerName", "triggerGroupName").startNow().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")).build();scheduler.scheduleJob(jobDetail,trigger);scheduler.start();
}public class MyJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext){System.out.println("todo something");}
}
通过以上内容学习了什么是任务调度,任务调度所解决的问题,以及任务调度的多种实现方式
什么是分布式任务调度?
通常任务调度的程序是集成在应用中的,比如:优惠卷服务中包括了定时发放优惠卷的的调度程序,结算服务中包括了定期生成报表的任务调度程序,由于采用分布式架构,一个服务往往会部署多个冗余实例来运行我们的业务,在这种分布式系统环境下运行任务调度,我们称之为分布式任务调度,如下图:
分布式调度要实现的目标:
不管是任务调度程序集成在应用程序中,还是单独构建的任务调度系统,如果采用分布式调度任务的方式就相当于将任务调度程序分布式构建,这样就可以具有分布式系统的特点,并且提高任务的调度处理能力
1.并行任务调度
并行任务调度实现靠多线程,如果有大量任务需要调度,此时光靠多线程就会有瓶颈了,因为一台计算机CPU的处理能力是有限的
如果将任务调度程序分布式部署,每个结点还可以部署为集群,这样就可以让多台计算机共同去完成任务调度,我们可以将任务分割为若干个分片,由不同的实例并行执行,来提高任务调度的处理效率。
2、高可用
若某一个实例宕机,不影响其他实例来执行任务。
3、弹性扩容
当集群中增加实例就可以提高并执行任务的处理效率。
4、任务管理与监测
对系统中存在的所有定时任务进行统一的管理及监测。让开发人员及运维人员能够时刻了解任务执行情况,从而做出快速的应急处理响应。
5、避免任务重复执行
当任务调度以集群方式部署,同一个任务调度可能会执行多次,比如在上面提到的电商系统中到点发优惠券的例子,就会发放多次优惠券,对公司造成很多损失,所以我们需要控制相同的任务在多个运行实例上只执行一次。
了解XXL-JOB分布式任务调度平台
XXL-JOB是一个 轻量级分布式任务调度平台,专门解决分布式系统中的定时任务调度问题,其核心设计目标是开发迅速、学习简单、轻量级、易扩展
官网:https://www.xuxueli.com/xxl-job/
XXL-JOB(如图所示)主要有调度中心,执行器,任务:
1.调度中心(XXL-JOB Admin):
调度中心是XXL-JOB的核心管理平台,负责对任务进行统一的管理和调度,它提供了一个可视化的Web界面,方便开发者进行任务的配置,监控和管理
2.执行器(XXL-JOB Executor)
执行器是实际执行任务的组件,它负责接收调度中心发送的任务请求,并执行具体的业务逻辑,执行器可以部署在多个节点上,实现分布式任务执行
3.任务
负责执行具体的业务逻辑
调度中心与执行器之间的工作流程如下:
执行流程:
1.任务执行器根据配置的调度中心的地址,自动注册到调度中心
2.达到任务触发条件,调度中心下发任务
3.执行器基于线程池执行任务,并将执行结果放到内存队列中,把执行日志写入日志文件中
4.执行器消费内存队列中的执行结果,主动上报给调度中心
5.当用户在调度中心查看任务日志,调度中心请求任务执行器,任务执行器读取任务日志文件并返回日志详情
如何搭建XXL-JOB?
首先需要下载XXL-JOB,可以从GitHub地址或者Gitee地址进行下载
GitHub 地址:
-
仓库地址:GitHub - xuxueli/xxl-job: A distributed task scheduling framework.(分布式任务调度平台XXL-JOB)
Gitee 地址:
-
仓库地址:xxl-job: 一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
如何集成XXL-JOB?我在我的媒资管理模块项目中进行演示
1.当下载好后,用IDEA打开目录显示界面如下
其中的 xxl-job-admin为调度中心,xxl-job-core为公共依赖,xxl-job-executor-samples为执行器(推荐使用Springboot版本,通过Springboot管理执行器)
2.再创建一个命名为xxl_job_2.3.1的数据库
CREATE DATABASE xxl_job_2.3.1 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
根据数据库脚本创建数据库,修改数据库连接信息和端口,启动xxl-job-admin,访问http://local:18088/xxl-job-admin/(分布式任务调度平台 — 管理和调度分布式环境中的定时任务)
使用用户名:admin / 密码:123456 登录
下面配置执行器,执行器负责与调度中心通信接收调度中心发起的任务调度请求
1.进入调度中心添加执行器
启动成功之后,可以选择在Linux上运行
使用maven命令,将xxl-job-admin打包,然后将其上传至Linux中,使用命令启动
nohup java -jar /绝对路径/xxl-job-admin-2.3.1.jar &
添加完执行器后,接着配置执行器,执行器负责与调度中心通信,接收调度中心发起的任务调度请求
1.首先在media-service工程中添加依赖(父工程中完成了版本控制,这里的版本是2.3.1)
<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId>
</dependency>
2.在nacos下的media-service-dev.yaml下配置xxl-job
注意这里配置的appname是执行器的应用名,稍后会在调度中心配置执行器的时候使用
xxl:job:admin:addresses: http://192.168.101.128:18088/xxl-job-admin/executor:appname: media-process-serviceaddress:ip:port: 9999logpath: /data/applogs/xxl-job-jobhandlerlogretentiondays: 30accessToken: default_token
3.配置xxl-job的执行器
将xxl-job-executor-sample-springboot示例工程下的配置类拷贝到媒资管理的service工程下:
该类中的属性就是获取配置文件中的配置得到的,同时提供了一个执行器的Bean,用于初始化XXL-JOB执行器的核心组件XxIJobSpringExecutor
并将其注册为Spring Bean,使得执行器能够连接到XXL-JOB管理平台并接收任务调度请求
@Configuration
public class XxlJobConfig {private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);@Value("${xxl.job.admin.addresses}")private String adminAddresses;@Value("${xxl.job.accessToken}")private String accessToken;@Value("${xxl.job.executor.appname}")private String appname;@Value("${xxl.job.executor.address}")private String address;@Value("${xxl.job.executor.ip}")private String ip;@Value("${xxl.job.executor.port}")private int port;@Value("${xxl.job.executor.logpath}")private String logPath;@Value("${xxl.job.executor.logretentiondays}")private int logRetentionDays;@Beanpublic XxlJobSpringExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppname(appname);xxlJobSpringExecutor.setAddress(address);xxlJobSpringExecutor.setIp(ip);xxlJobSpringExecutor.setPort(port);xxlJobSpringExecutor.setAccessToken(accessToken);xxlJobSpringExecutor.setLogPath(logPath);xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);return xxlJobSpringExecutor;}/*** 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;** 1、引入依赖:* <dependency>* <groupId>org.springframework.cloud</groupId>* <artifactId>spring-cloud-commons</artifactId>* <version>${version}</version>* </dependency>** 2、配置文件,或者容器启动变量* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'** 3、获取IP* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();*/}
再次进入调度中心,添加执行器
重启媒资管理服务模块,就可以看到执行器在调度中心注册成功
下面我们编写任务演示如何使用,在media-service下新建包com.project.media.service.jobhandler,在该包下定义我们的任务类
package com.xuecheng.media.service.jobhandler;import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;/*** @description 测试执行器* @author Mr.M* @date 2022/9/13 20:32* @version 1.0*/@Component@Slf4j
public class SampleJob {/*** 1、简单任务示例(Bean模式)*/@XxlJob("testJob")public void testJob() throws Exception {log.info("开始执行.....");}}
然后进入调度中心添加任务,进入任务管理,新增任务信息
调度类型:固定速度指按固定的间隔定时调度
Cron:通过Cron表达式实现更丰富的定时调度策略,它的表达式是一个字符串,通过它可以定义调度策略,格式如下:
{秒数}{分数}{小时}{日期}{月份}{星期}{年份(可为空)}
比如:
30 10 1**?表示每天1点10分30秒触发
0/30****? 每30秒触发一次
* 0/10***?每10分钟触发一次
添加成功,启动任务
下面启动媒资管理的service工程,启动执行器并观察执行器方法的执行
掌握了xxL-Job的基本使用,继续思考如何进行分布式任务处理?比如说我们会启动多个执行器组成一个集群,去执行任务
结合以上XXL-JOB的实现,我们可以利用 分片广播策略 来提高处理效率尤其是处理数据库中大量数据(比如项目中媒资管理模块需要处理大量视频文件)
分片广播
分片广播是分布式任务调度中一种常见模式,主要用于将一个大任务拆分成多个子任务(分片),并将这些子任务 并发分发 到多个执行器节点上执行,从而提高任务处理效率
以上图示是 调度中心以执行器为维度进行分片,将集群中的执行器标上序号:0,1,2,3....,广播是指每次调度会向集群中的所有执行器发送任务调度,请求中携带分片参数,每个执行器收到调度请求同时接收分片参数
像这种分片广播适用于哪些场景?
分片任务场景:10个执行器的集群来处理10w条数据(数据之多),每台机器只需要处理1w条数据(分片执行),耗时降低10倍;
广播任务场景:广播执行器同时运行shell脚本,广播集群节点进行缓存更新等
"分片广播" 和普通任务开发流程一致,不同之处在于可以获取分片参数进行分片业务处理。
测试分片广播策略
1.定义作业分片的任务方法
/***分片广播任务*/@XxlJob("shardingJobHandler")public void shardingJobHandler() throws Exception{//分片参数int shardIndex = XxlJobHelper.getShardIndex();int shardTotal = XxlJobHelper.getShardTotal();Log.info("分片参数:当前分片序号 = {},总分片数 = {}",shardIndex,shardTotal);
}
2.在调度中心添加任务
回到任务调度界面,可以看到该项任务添加成功
3.启动任务,观察日志
下面需要启动两个执行器实例,观察每个实例的执行情况
1.首先在nacos中配置media-service的本地优先部署
#配置本地优先
spring:cloud:config:override-none: true
2.将media-service启动两个实例,两个实例在启动时端口不能冲突
例如:在VM options处添加:-Dserver.port=63051 - Dxxl.job.executor.port=9998
在VM options处添加: -Dserver.port=63050 - Dxxl.job.executor.port=9999
3.启动两个实例,观察任务调度中心,稍等片刻执行器会有两个
分别观察这两个执行实例的日志
日志一:
日志二:
从日志可以看到每个实例的分片序号不同,如果其中一个执行器挂掉,只剩下一个执行器在工作,稍等片刻调用中心发现少了一个执行器将动态调整总分片数为1
作业分片方案
以上任务添加成功后,对于要处理的任务会添加到待处理任务表中,现在启动多个执行器实例去查询这些待处理任务,如何保证多个执行器不会查询到重复的任务呢?
XXL-JOB并不直接提供数据处理的功能,它只会给执行器分配好分片序号,在向执行器任务调度的同时下发分片总数以及分片序号等这些参数,执行器收到这些参数后根据自己的业务需求去利用这些参数
下图表示了多个执行器获取视频处理任务的结构:
每个执行器收到广播任务会有两个参数:分片总数,分片序号
每次执行从数据表取任务时可以让任务id 模上(取模运算) 分片总数,如果等于分片 序号则能执行此任务
假设我们有6个待处理的视频任务,任务ID依次为1-6,同时有3个执行器实例,那么分片总数就是3,对应的分片序号则为0,1,2。具体任务分配情况如下:
任务序号 | 任务 ID 分片总数(求模运算) | 应执行的执行器分片序号 |
---|---|---|
1 | 1 % 3 = 1 | 执行器 2 |
2 | 2 % 3 = 2 | 执行器 3 |
3 | 3 % 3 = 0 | 执行器 1 |
4 | 4 % 3 = 1 | 执行器 2 |
5 | 5 % 3 = 2 | 执行器 3 |
6 | 6 % 3 = 0 | 执行器 1 |
从上述表格中可以清晰地看到,每个任务都根据其任务ID的取模结果被精准地分配到了对应的执行器上,而不会出现多个执行器获取到同一个任务的情况
通过这种XXL-JOB的分片机制,可以用于处理视频转码,视频审核,视频分发等任务,将大量视频处理任务均匀分配给多个执行器,保证任务的高效执行和不会重复处理
相关文章:

分布式架构与XXL-JOB
目录 先了解什么是任务调度? 什么是分布式任务调度? 了解XXL-JOB分布式任务调度平台 如何搭建XXL-JOB? 分片广播 作业分片方案 最近学习在项目的媒资管理模块如何高效处理大量视频,上传单个视频可能涉及到转码,…...
leetcode day18 移除元素 26+283
26 删除有序数组中的重复项 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元…...

【HarmonyOS Next】鸿蒙监听手机按键
【HarmonyOS Next】鸿蒙监听手机按键 一、前言 应用开发中我们会遇到监听用户实体按键,或者扩展按键的需求。亦或者是在某些场景下,禁止用户按下某些按键的业务需求。 这两种需求,鸿蒙都提供了对应的监听事件进行处理。 onKeyEvent 默认的…...
用Deepseek查询快证API-物流查询-实名认证-企业实名认证
快证API可能是一个提供多种验证和查询服务的平台,包括但不限于企业实名认证、短链接生成、手机号归属地查询、IP地址查询等。以下是根据搜索结果整理的关于快证API的相关信息: 企业实名认证API: 功能:通过与企业相关数据库进行…...
一个简洁高效的Flask用户管理示例
Flask-Login 是 Flask 的用户管理扩展,提供 用户身份验证、会话管理、权限控制 等功能。 适用于: • 用户登录、登出 • 记住用户(“记住我” 功能) • 限制未登录用户访问某些页面 • 用户会话管理 1. 安装 Flask-Login pi…...
分布式之分布式ID
目录 需求 1. 全局唯一性 2. 高性能 3. 高可用性 4. 可扩展性 5. 有序性 6. 时间相关 7. 长度适中 8. 安全性 9. 分布式一致性 10. 易于集成 常见解决方案 选择依据 数据库号段模式 核心概念 工作流程 优点 缺点 实现示例 优化策略 适用场景 Snowflake雪…...

(萌新入门)如何从起步阶段开始学习STM32 —— 0.碎碎念
目录 前言与导论 碎碎念 所以,我到底需要知道哪些东西呢 从一些基础的概念入手 常见的工具和说法 ST公司 MDK5 (Keil5) CubeMX 如何使用MDK5的一些常用功能 MDK5的一些常见的设置 前言与导论 非常感谢2301_77816627-CSDN博客的提问,他非常好奇…...

边缘计算网关与 PLC:注塑机车间数据互联新变革
在当今数字化浪潮席卷而来的时代,制造业的智能化转型成为了提升竞争力的关键路径。对于注塑机车间而言,如何实现数据的高效采集与互联,进而优化生产流程、提高生产效率,是众多企业亟待解决的问题。而明达MBox20边缘计算网关与 PLC…...
LeetCode刷题---哈希表---347
前 K 个高频元素 347. 前 K 个高频元素 - 力扣(LeetCode) 题目: 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1…...

LED灯闪烁实验:实验介绍
文章目录 1 实验目标2 工具链2.1 硬件2.2 软件 3 实验流程 1 实验目标 本实验结合Matlab/Simulink工具链和STM工具链,实现STM32开发板上的LED灯闪烁功能。 2 工具链 2.1 硬件 STM32F103C8T6最小系统板 STM32F103C8T6最小系统板是基于STM32F103C8T6微控制器的开发…...

论文笔记(七十二)Reward Centering(一)
Reward Centering(一) 文章概括摘要1 奖励中心化理论 文章概括 引用: article{naik2024reward,title{Reward Centering},author{Naik, Abhishek and Wan, Yi and Tomar, Manan and Sutton, Richard S},journal{arXiv preprint arXiv:2405.0…...

C#之上位机开发---------C#通信库及WPF的简单实践
〇、上位机,分层架构 界面层 要实现的功能: 展示数据 获取数据 发送数据 数据层 要实现的功能: 转换数据 打包数据 存取数据 通信层 要实现的功能: 打开连接 关闭连接 读取数据 写入数据 实体类 作用: 封装数据…...
使用 pjsua2 开发呼叫机器人,批量拨打号码并播放固定音频
如何使用 pjsua2 开发呼叫机器人,批量拨打号码并播放固定音频 声明 该播客仅提供实现思路,并非实际的方案记录,不要盲目照搬。 pjsua2库的安装会有较多问题,请参考本人之前的播客进行安装 pjsua2。 pjsua2 库具体的 api 说明请参考开源库内的 范例代码。 引言 在今天的…...

从函数到神经网络
所有一切的前提是,你要相信这个世界上的所有逻辑和知识,都可以用一个函数来表示。Functions describe the world ! 比如输入物体的质量和加速度,根据牛顿第二定律,就可以得到物体施加的力,这就是人工智能早期的思路&am…...
用自定义注解实现Excel数据导入中的枚举值校验
使用自定义注解实现Excel数据导入中的枚举值校验 在实际开发中,我们经常需要从Excel文件中导入数据,并且这些数据需要符合一定的规则,比如某些字段的值必须是预定义的枚举值。本文将介绍如何使用自定义注解来实现这一功能,以提高…...

网络安全技术pat实验 网络安全 实验
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 网络安全实验3 前言Kali 常用指令工具教程 ettercap 基本使用 一、口令破解 John the ripper 破解 linux 密码l0phtcrack7 破解 windows 密码John 破解 zip 压…...

4、IP查找工具-Angry IP Scanner
在前序文章中,提到了多种IP查找方法,可能回存在不同场景需要使用不同的查找命令,有些不容易记忆,本文将介绍一个比较优秀的IP查找工具,可以应用在连接树莓派或查找IP的其他场景中。供大家参考。 Angry IP Scanner下载…...
1018. 锤子剪刀布 (20)-PAT乙级真题
题目来源: PTA | 程序设计类实验辅助教学平台 代码实现(代码一): 这个版本是自己写的;(很好理解,但定义了很多变量),有部分样例测试不通过 #include <iostream>…...
MyBatis 中 SqlMapConfig 配置文件详解
精心整理了最新的面试资料,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 configuration:包裹所有配置标签,是整个配置文件的顶级标签。 properties:属性,该标签可以引入外部配置的属性ÿ…...

复杂项目中的多级WBS应该如何分解?
如果你曾经参与过一个复杂的项目,或许就会感受到: 任务繁杂、责任不清、进度难追踪, 真的是每一位项目经理的噩梦。 而这一切的根源,往往就是缺少一个清晰、有效的任务分解结构—— 没有把庞大、复杂的工作拆解得足够明确&…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...