当前位置: 首页 > news >正文

spring-bus消息总线的使用

文章目录

  • 依赖
  • bus应用
    • 接口
    • 用到的封装参数类
  • 接收的应用
    • 监听器
    • 定义的事件类
  • 使用bus
    • 定义bus远程调用
    • A应用数据更新后通过bus数据同步给B应用

依赖

   <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp</artifactId></dependency>

bus应用

  • 类似于生产者

接口

  • 供内部其他应用使用,远程调用该接口实现各应用之间数据同步
  • 参数1定义事件,参数2定义操作具体crud,参数3定义传参数据,参数4定义给哪个应用(nacos注册的应用名)同步数据
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.xyc.sms.common.bus.events.DataSyncEventEnum;
import com.xyc.sms.common.bus.events.DataSyncEventFactory;
import com.xyc.sms.common.bus.events.DataSyncOperateTypeEnum;
import com.xyc.sms.common.entity.Result;
import org.springframework.cloud.bus.ServiceMatcher;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;/*** 数据同步通知事件控制器,该事件主要用于平台中常规的数据同步通知,* 需要用于其他功能请新增类* 需要增加同步的方式请在{@link DataSyncEventEnum}增加事件枚举* 同时在{@link com.xyc.sms.common.bus.events.dataSync}下增加事件类,新增的事件类需要继承{@link com.xyc.sms.common.bus.events.DataSyncEvent}*/
@RestController
@RequestMapping("/default")
public class DataSyncNotifyEventController {private static final Log logger = LogFactory.get();@Resourceprivate ServiceMatcher busServiceMatcher;@Resourceprivate ApplicationEventPublisher applicationEventPublisher;/*** 发布数据同步通知事件** @param eventEnum   事件枚举,可通过枚举找到对应的事件类* @param operateType 操作类型枚举* @param obj         需要处理的消息* @param destination 目的地,为null则是广播给所有该事件的监听器* @return 发布结果*/@PostMapping("/publish/{eventEnum}/{operateType}")public Result publishDataSyncNotifyEvent(@PathVariable("eventEnum") DataSyncEventEnum eventEnum,@PathVariable("operateType") DataSyncOperateTypeEnum operateType,@RequestBody Object obj,@RequestParam(value = "destination", required = false) String destination) {try {applicationEventPublisher.publishEvent(DataSyncEventFactory.getInstanceForEvent(eventEnum,operateType,obj,busServiceMatcher.getServiceId(),destination));return Result.returnSuccessWithMsg("success");} catch (Exception e) {logger.error(e);return Result.returnFail(e.getMessage());}}
}
  • 事件工厂类
import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;public class DataSyncEventFactory {private static final ObjectMapper OM = new ObjectMapper();/*** 通过事件的类模板获取构造器并调用,生成事件的实体类** @param operateType        操作类型* @param source             事件原数据* @param originService      原服务* @param destinationService 目标服务* @return 事件实体类* @throws NoSuchMethodException     通过类模板无法找到相应的构造方法所抛出的异常* @throws InvocationTargetException 构造器创建实例可能出现的调用目标异常* @throws InstantiationException    构造器创建实例可能出现的实例化异常* @throws IllegalAccessException    构造器创建实例可能出现的无法访问异常* @throws IOException               json转化出现IO的异常* @throws ClassNotFoundException    通过类名{@link DataSyncEventEnum#getEventClassName()}没有找到对应类*/public static DataSyncEvent<?> getInstanceForEvent(DataSyncEventEnum eventEnum,DataSyncOperateTypeEnum operateType,Object source,String originService,String destinationService)throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {Constructor<?>[] constructors = DataSyncEventFactory.getEventClass(eventEnum).getDeclaredConstructors();Constructor<?> constructor = Arrays.stream(constructors).filter(c -> c.getParameterCount() == 4).findFirst().orElseThrow(NoSuchMethodException::new);// 值转化Object o = OM.readValue(OM.writeValueAsString(source), constructor.getParameterTypes()[1]);return (DataSyncEvent<?>) constructor.newInstance(operateType, o, originService, destinationService);}private static Class<?> getEventClass(DataSyncEventEnum eventEnum) throws ClassNotFoundException {return Class.forName(eventEnum.getEventClassName());}
}

用到的封装参数类

在这里插入图片描述

  • 定义各事件的枚举(只定义全类限定名称)
public enum DataSyncEventEnum {/*** 黑名单同步,参数为事件的类型名,注意需要使用全限定类名* @see com.xyc.sms.common.bus.events.dataSync.BlackListSyncEvent*/BLACKLIST_SYN("com.xyc.sms.common.bus.events.dataSync.BlackListSyncEvent"),/*** 路由同步* @see com.xyc.sms.common.bus.events.dataSync.RouteSyncEvent*/ROUTE_SYN("com.xyc.sms.common.bus.events.dataSync.RouteSyncEvent");/*** 事件类型名* @see DataSyncEvent 该抽象类的实现类*/private final String eventClassName;DataSyncEventEnum(String eventClassName) {this.eventClassName = eventClassName;}public String getEventClassName() {return eventClassName;}
}
  • 定义crud操作枚举
public enum DataSyncOperateTypeEnum implements Serializable {ADD, UPD, DEL
}
  • 推送的事件类
/*** 数据同步通知事件,作为一般通用事件使用,如需要特殊处理建议新增事件*/
public abstract class DataSyncEvent<T> extends RemoteApplicationEvent {/*** 事件数据*/private DataSync<T> dataSync;public DataSync<T> getDataSync() {return dataSync;}public void setDataSync(DataSync<T> dataSync) {this.dataSync = dataSync;}/*** 基础构造器** @param source             引发事件的原始数据* @param originService      引发事件的原始服务* @param destinationService 事件的目标服务*/public DataSyncEvent(DataSync<T> source, String originService, String destinationService) {super(source, originService, destinationService);this.dataSync = source;}/*** 事件的日志打印,会在监听器监听到事件时输出打印* 结果尽可能不要有换行,保证日志输出在一行内* 该方法可以在子类中重写** @return 日志*/public String logPrint() {return String.format("{\"originService\":\"%s\",\"destinationService\":\"%s\",\"id\":\"%s\",\"dataSync\":%s,\"timestamp\":\"%s\"}", this.getId(), this.getOriginService(), this.getDestinationService(), Objects.nonNull(this.dataSync) ? this.dataSync.toString() : "null", this.getTimestamp());}/*** 数据同步的原始数据封装*/public static class DataSync<T> implements Serializable {private DataSyncOperateTypeEnum operateType;private T data;public DataSync() {}public DataSync(DataSyncOperateTypeEnum operateType, T data) {this.operateType = operateType;this.data = data;}public DataSyncOperateTypeEnum getOperateType() {return operateType;}public T getData() {return data;}@Overridepublic String toString() {return "{\"operateType\":" +operateType+ ",\"data\":" +data+ "}";}}
}
  • 应用枚举
/*** 服务枚举*/
public enum ServiceEnum {SMS_BLACK_API("sms-black-api"),SMS_RULES("sms-rules");public final String serviceName;ServiceEnum(String serviceName) {this.serviceName = serviceName;}
}

接收的应用

  • 类似于消费者

监听器

  • 推送过来的操作枚举类crud的值,决定执行哪个crud的具体方法
  • 该类放在接收的应用中,其他顶部继承的类放在common包中即可
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.xyc.sms.common.bus.DataSyncListener;
import com.xyc.sms.common.bus.events.dataSync.RouteSyncEvent;
import com.xyc.sms.common.entity.sms.Route;
import com.xyc.sms.rules.dao.boss.RouteMapper;
import com.xyc.sms.rules.data.RuleSymbol;
import com.xyc.sms.rules.service.SynService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;/*** 路由同步通知监听器*/
@Component
public class RouteSynNotifyListener extends DataSyncListener<RouteSyncEvent, List<Route>> {private static final Log log = LogFactory.get();@Autowiredprivate RouteMapper routeMapper;@Autowiredprivate SynService synService;@Overridepublic void handleByADD(List<Route> data) {Optional.ofNullable(data).ifPresent(ls -> {if (ls.isEmpty()) {return;}long l = System.currentTimeMillis();String time = DateUtil.formatDateTime(ls.get(0).getCreateTime());List<Route> list = routeMapper.selectByCreatetime(time);if (CollectionUtil.isEmpty(list)) {return;}// 加载到内存中list.forEach(r -> RuleSymbol.RouteMap.put(r.getId(), r));synService.transformRoute(list, (s, r) -> RuleSymbol.RouteChannelMap.put(s, r));log.info("RouteSynNotifyListener - {} - add | createTime:{}", (System.currentTimeMillis() - l), time);});}@Overridepublic void handleByUPD(List<Route> data) {// 流程还是先删除后新增的方式Optional.ofNullable(data).ifPresent(ls -> {List<Integer> collect = ls.stream().map(Route::getId).filter(Objects::nonNull).collect(Collectors.toList());if (collect.isEmpty()) {return;}long l = System.currentTimeMillis();// 如果有,先删除List<Route> c = collect.stream().map(RuleSymbol.RouteMap::get).filter(Objects::nonNull).collect(Collectors.toList());if (!c.isEmpty()) {synService.transformRoute(c, (s, r) -> RuleSymbol.RouteChannelMap.remove(s, r));}// 如果有,再加入List<Route> list = routeMapper.selectById(collect);if (!list.isEmpty()) {list.forEach(r -> RuleSymbol.RouteMap.put(r.getId(), r));synService.transformRoute(list, (s, r) -> RuleSymbol.RouteChannelMap.put(s, r));}log.info("RouteSynNotifyListener - {} - update | {}", (System.currentTimeMillis() - l), collect);});}@Overridepublic void handleByDEL(List<Route> data) {Optional.ofNullable(data).ifPresent(ls -> {long l = System.currentTimeMillis();List<Route> collect = ls.stream().map(r -> RuleSymbol.RouteMap.remove(r.getId())).filter(Objects::nonNull).collect(Collectors.toList());if (collect.isEmpty()) {return;}synService.transformRoute(collect, (s, r) -> RuleSymbol.RouteChannelMap.remove(s));log.info("RouteSynNotifyListener - {} - remove", (System.currentTimeMillis() - l));});}
}
  • 继承的抽象监听类
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.xyc.sms.common.bus.events.DataSyncEvent;
import org.springframework.context.ApplicationListener;/*** 数据同步事件监听器* 需要具体的子类实现,并注册到spring容器中** @param <T> 数据同步件*/
public abstract class DataSyncListener<T extends DataSyncEvent<D>, D> implements ApplicationListener<T> {private static final Log logger = LogFactory.get();@Overridepublic void onApplicationEvent(T event) {logger.info("[DataSyncListener][onApplicationEvent] trigger event - {} - {}", event.getClass().getName(), event.logPrint());try {triggerEvent(event);} catch (Exception e) {logger.error(e);}}/*** 触发监听,处理事件** @param event 事件*/public void triggerEvent(T event) {DataSyncEvent.DataSync<D> source = event.getDataSync();switch (source.getOperateType()) {case ADD:handleByADD(source.getData());return;case UPD:handleByUPD(source.getData());return;case DEL:handleByDEL(source.getData());return;default:}}/*** 处理添加事件* 由子类实现** @param data 需要处理的数据*/public abstract void handleByADD(D data);/*** 处理修改事件* 由子类实现** @param data 需要处理的数据*/public abstract void handleByUPD(D data);/*** 处理删除事件* 由子类实现** @param data 需要处理的数据*/public abstract void handleByDEL(D data);
}

定义的事件类

  • 上面封装的事件枚举所记录的是该类的全类限定名称
package com.xyc.sms.common.bus.events.dataSync;import com.xyc.sms.common.bus.events.DataSyncEvent;
import com.xyc.sms.common.bus.events.DataSyncOperateTypeEnum;
import com.xyc.sms.common.entity.sms.Route;import java.util.List;public class RouteSyncEvent extends DataSyncEvent<List<Route>> {private static final long serialVersionUID = -501657066268464154L;public RouteSyncEvent(DataSyncOperateTypeEnum operateType, List<Route> Routes, String originService, String destinationService) {super(new DataSync<>(operateType, Routes), originService, destinationService);}
}
  • 继承的抽象事件类
/*** 数据同步通知事件,作为一般通用事件使用,如需要特殊处理建议新增事件*/
public abstract class DataSyncEvent<T> extends RemoteApplicationEvent {/*** 事件数据*/private DataSync<T> dataSync;public DataSync<T> getDataSync() {return dataSync;}public void setDataSync(DataSync<T> dataSync) {this.dataSync = dataSync;}/*** 基础构造器** @param source             引发事件的原始数据* @param originService      引发事件的原始服务* @param destinationService 事件的目标服务*/public DataSyncEvent(DataSync<T> source, String originService, String destinationService) {super(source, originService, destinationService);this.dataSync = source;}/*** 事件的日志打印,会在监听器监听到事件时输出打印* 结果尽可能不要有换行,保证日志输出在一行内* 该方法可以在子类中重写** @return 日志*/public String logPrint() {return String.format("{\"originService\":\"%s\",\"destinationService\":\"%s\",\"id\":\"%s\",\"dataSync\":%s,\"timestamp\":\"%s\"}", this.getId(), this.getOriginService(), this.getDestinationService(), Objects.nonNull(this.dataSync) ? this.dataSync.toString() : "null", this.getTimestamp());}/*** 数据同步的原始数据封装*/public static class DataSync<T> implements Serializable {private DataSyncOperateTypeEnum operateType;private T data;public DataSync() {}public DataSync(DataSyncOperateTypeEnum operateType, T data) {this.operateType = operateType;this.data = data;}public DataSyncOperateTypeEnum getOperateType() {return operateType;}public T getData() {return data;}@Overridepublic String toString() {return "{\"operateType\":" +operateType+ ",\"data\":" +data+ "}";}}
}

使用bus

  • 引用注入bus应用的接口远程调用

定义bus远程调用

@FeignClient(value="sms-bus", fallbackFactory = DataSyncNotifyEventServiceFallbackFactory.class)
public interface DataSyncNotifyEventService {/*** 发布数据同步通知事件* destination 参数被删除,不需要指定服务** @param eventEnum   事件枚举,可通过枚举找到对应的事件类* @param operateType 操作类型枚举* @param obj         需要处理的消息* @return 发布结果*/@PostMapping("/default/publish/{eventEnum}/{operateType}")Result publishDataSyncNotifyEvent(@PathVariable("eventEnum") DataSyncEventEnum eventEnum,@PathVariable("operateType") DataSyncOperateTypeEnum operateType,@RequestBody Object obj,@RequestParam("destination") String destination);
}
  • 注入使用
    在这里插入图片描述

A应用数据更新后通过bus数据同步给B应用

  • 在A应用的业务层写以下代码
 try {result = dataSyncNotifyEventService.publishDataSyncNotifyEvent(DataSyncEventEnum.ROUTE_SYN,DataSyncOperateTypeEnum.ADD,new ArrayList<Route>() {{Route r = new Route();r.setCreateTime(date);add(r);}}, ServiceEnum.SMS_RULES.serviceName);log.info("新增路由调用通知同步所有服务 result:{}", result);} catch (Exception e) {log.error("同步异常 {}", result, e);}

相关文章:

spring-bus消息总线的使用

文章目录 依赖bus应用接口用到的封装参数类 接收的应用监听器定义的事件类 使用bus定义bus远程调用A应用数据更新后通过bus数据同步给B应用 依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp…...

isctf---re

crackme 解压得到crackme.exe 运行得到flag babyRe 先猜e65537的rsa 先用Z3强行求出p、q&#xff0c;算出常规rsa中的phi&#xff0c;然后套用公式求出m exp #babyre wp from z3 import * import libnum from Crypto.Util.number import * p,q,cInts(p q c) S Solver() S…...

C语言第十二弹--扫雷

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 扫雷 1、扫雷游戏分析和设计 1.1、扫雷游戏的功能说明 1.2 游戏的分析和设计 1.2.1、数据结构的分析 1.2.2、文件结构设计 2、扫雷游戏的结构分析 2.1、用…...

网路服务器——线程池技术

文章目录 一、线程池技术二、使用原理三、优点总结 一、线程池技术 预创建原则&#xff0c;线程池内部准备线程备用&#xff0c; 不宜过多。线程应该重用性&#xff0c;可以一对多处理任务或服务不同的客户端。处理单元(线程)数量并不固定&#xff0c;动态扩容与缩减(任务量)。…...

探索设计模式的魅力:深入了解适配器模式-优雅地解决接口不匹配问题

设计模式专栏&#xff1a;http://t.csdnimg.cn/nolNS 目录 一、引言 1. 概述 2. 为什么需要适配器模式 3. 本文的目的和结构 二、简价 1. 适配器模式的定义和特点 定义 特点 2. 适配器模式的作用和适用场景 作用 适用场景 3. 适配器模式与其他设计模式的比较 三、适配…...

matlab窗函数-hann窗和hamming窗函数

窗函数的作用 在时域上&#xff0c;窗函数可以看作是对原始信号进行截断或调制的加权函数。这些窗函数通常在时域上是有限的宽度&#xff0c;并且具有对称性&#xff0c;如矩形窗、汉宁窗、汉明窗和布莱克曼窗等。例如&#xff0c;汉明窗是一种对称窗函数&#xff0c;它可以用…...

Java项目实战--瑞吉外卖DAY03

目录 P22新增员工_编写全局异常处理器 P23新增员工_完善全局异常处理器并测试 p24新增员工_小结 P27员工分页查询_代码开发1 P28员工分页查询_代码开发2 P22新增员工_编写全局异常处理器 在COMMON新增全局异常捕获的类&#xff0c;其实就是代理我们这些controlle。通过aop把…...

docker 里使用vcs 2018 verdi等eda 图形界面

书接上文。之前借用别人的docker&#xff0c;使用EDA工具&#xff0c;苦于没有图形界面。如果只是编码&#xff0c;编译可能问题不大&#xff0c;但是如果要看波形之类的&#xff0c;就没法实现了。 docker 使用 vcs/2018 Verdi等 eda 软件-CSDN博客https://blog.csdn.net/guy…...

OpenHarmony—不支持解构赋值

规则&#xff1a;arkts-no-destruct-assignment 级别&#xff1a;错误 ArkTS不支持解构赋值。可使用其他替代方法&#xff0c;例如&#xff0c;使用临时变量。 TypeScript let [one, two] [1, 2]; // 此处需要分号 [one, two] [two, one];let head, tail [head, ...tail]…...

让AI帮你说话--GPT-SoVITS教程

有时候我们在录制视频的时候&#xff0c;由于周边环境嘈杂或者录音设备问题需要后期配音&#xff0c;这样就比较麻烦。一个比较直观的想法就是能不能将写好的视频脚本直接转换成我们的声音&#xff0c;让AI帮我们完成配音呢&#xff1f;在语音合成领域已经有很多这类工作了&…...

线性回归需要满足的几个假设

线性回归模型是基于一些假设构建的&#xff0c;这些假设有助于确保模型的有效性和可解释性。以下是线性回归需要满足的几个主要假设&#xff1a; 线性关系假设&#xff08;Linearity&#xff09;: 线性回归假设因变量&#xff08;目标变量&#xff09;与自变量&#xff08;特征…...

go语言(十八)---- goroutine

一、goroutine package mainimport ("fmt""time" )func main() {//用go创建承载一个形参为空&#xff0c;返回值为空的一个函数go func() {defer fmt.Println("A.defer")func() {defer fmt.Println("B.defer")//退出当前goroutinefmt…...

城市开发区视频系统建设方案:打造视频基座、加强图像数据治理

一、背景需求 随着城市建设的步伐日益加快&#xff0c;开发区已经成为了我国工业化、城镇化和对外开放的重要载体。自贸区、开发区和产业园的管理工作自然也变得至关重要。在城市经开区的展览展示馆、进出口商品展示交易中心等地&#xff0c;数千路监控摄像头遍布各角落&#…...

宏景eHRSmsAcceptGSTXServle存在XXE漏洞

指纹特征 app"HJSOFT-HCM"漏洞复现 POST /servlet/sms/SmsAcceptGSTXServlet HTTP/1.1 Host: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Content-Length: 137 Content…...

LLVM实战之模块化设计

目录 1. llvm基础理念 2. 准备工作 3. 详细步骤 3.1 指令合并优化 3.2 无用参数消除优化 4. Pass管理器(Pass Manager)...

可以运行在浏览器的Windows 2000

Windows 2000 可以在浏览器里跑了&#xff0c;缺点就是速度慢。 JSLinux JSLinux 在浏览器中运行 Linux 或其他操作系统&#xff01; 可以使用以下仿真系统&#xff1a; 中央处理器操作系统用户 界面VF同步 访问启动 链接TEMU 配置评论x86阿尔派Linux 3.12.0安慰是的点击这…...

CUDA笔记

CUDA笔记 nvidia-smi 命令使用 nvidiasmi -q&#xff1a;查询GPU详细信息&#xff1b; nvidia-smi -q -l 0&#xff1a;查询特定GPU详细信息&#xff1b; nvidia-smi -q -l 0 -d MEMORY&#xff1a;显示GPU特定信息&#xff1b; nvidia-smi -h&#xff1a;英伟达的帮助命令。…...

Open CASCADE学习| ​提取曲面的PCurve

PCurve这个概念&#xff0c;字面上来理解就是参数曲线&#xff08;Parametric Curve&#xff09;。参数空间曲线是在参数曲面的双参数空间中的二维样条曲线。 二维曲线定义的目的只有一个&#xff1a;pCurve&#xff0c;参数曲线。OCC采用参数法构建几何结构&#xff0c;所有的…...

GMS测试BTSfail-CVE-2022-20451

描述&#xff1a; 项目需要过GMS兼容性测试&#xff0c;BTS这块我们环境没有&#xff0c;送检之后出现了一个BTS的Alert&#xff0c;这个是必须要解决的。下面的warning可以不考虑。 这个是patch问题&#xff0c;根据代理提供的pdf文件找到一个id:为A-235098883的补丁&#xf…...

Vue学习笔记12--Vue3之setup/ref函数/reactive函数/Vue3响应式原理/reactive对比ref

一、拉开序幕的setup 理解&#xff1a;Vue3中一个新的配置项&#xff0c;值为一个函数。setup是所有Composition API(组合API&#xff09;表演的舞台。组件中所用到的&#xff1a;数据、方法等&#xff0c;均要配置在setup中。setup函数的两种返回值&#xff1a; 若返回一个对…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...