管道流设计模式结合业务

news/2024/5/17 20:18:55

文章目录

    • 流程图
    • 代码实现
      • pom
      • context
        • EventContext
        • BizType
        • AbstractEventContext
      • filter
        • EventFilter
        • AbstractEventFilter
        • EventFilterChain
        • FilterChainPipeline
        • DefaultEventFilterChain
      • selector
        • FilterSelector
        • DefaultFilterSelector
    • 调用代码
      • PipelineApplication
      • controller
      • entity
      • service
      • service.business1
      • service.business1.context
      • service.business1.filters
      • service.business1.plugins
      • service.business2
      • service.business2.context
      • service.business2.filters
      • service.business2.plugins
      • service.config
      • service.selector
      • application.yml

流程图

请添加图片描述

代码实现

请添加图片描述

完整代码:https://gitee.com/gitee_pikaqiu/easy-pipeline

pom

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.plugin</groupId><artifactId>spring-plugin-core</artifactId><version>${spring.plugin.core.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency>
</dependencies>

context

EventContext
public interface EventContext {/*** 是否继续调用链*/boolean continueChain();/*** 获取当前过滤器选择器*/FilterSelector getFilterSelector();}
BizType
public interface BizType {/*** 获取业务类型码值*/Integer getCode();/*** 业务类型名称**/String getName();}
AbstractEventContext
public abstract class AbstractEventContext implements EventContext{private final BizType businessType;private final FilterSelector filterSelector;protected AbstractEventContext(BizType businessType, FilterSelector filterSelector) {this.businessType = businessType;this.filterSelector = filterSelector;}@Overridepublic boolean continueChain() {return true;}@Overridepublic FilterSelector getFilterSelector() {return filterSelector;}}

filter

EventFilter
public interface EventFilter<T extends EventContext> {/*** 过滤逻辑封装点** @param context 上下文对象* @param chain   调用链*/void doFilter(T context, EventFilterChain<T> chain);}
AbstractEventFilter
public abstract class AbstractEventFilter<T extends EventContext> implements EventFilter<T> {@Overridepublic void doFilter(T context, EventFilterChain<T> chain) {// 执行if (context.getFilterSelector().matchFilter(this.getClass().getSimpleName())) {handler(context);}// 是否继续执行调用链if (context.continueChain()) {chain.nextHandler(context);}}/*** 执行器** @param context 上下文对象*/protected abstract void handler(T context);}
EventFilterChain
public interface EventFilterChain<T extends EventContext> {/*** 执行当前过滤器** @param context 上下文对象*/void handler(T context);/*** 跳过当前过滤器 执行下一个执行过滤器** @param context 上下文对象*/void nextHandler(T context);}
FilterChainPipeline
@Slf4j
@Component
public class FilterChainPipeline<F extends EventFilter>{private DefaultEventFilterChain<EventContext> last;public FilterChainPipeline<F> append(F filter){last = new DefaultEventFilterChain<>(last, filter);return this;}public FilterChainPipeline<F> append(String description, F filter){log.debug("过滤器调用链管道开始设置 {} 过滤器",description);last = new DefaultEventFilterChain<>(last, filter);return this;}public DefaultEventFilterChain<EventContext> getFilterChain() {return this.last;}}
DefaultEventFilterChain
public class DefaultEventFilterChain<T extends EventContext> implements EventFilterChain<T> {private final EventFilterChain<T> next;private final EventFilter<T> filter;public DefaultEventFilterChain(EventFilterChain<T> next, EventFilter<T> filter) {this.next = next;this.filter = filter;}@Overridepublic void handler(T context) {filter.doFilter(context,this);}@Overridepublic void nextHandler(T context) {if (next != null) {next.handler(context);}}}

selector

FilterSelector
public interface FilterSelector {/*** 匹配过滤器** @param currentFilterName 过滤器名称* @return true 匹配成功*/boolean matchFilter(String currentFilterName);/*** 获取当前所有过滤器名称** @return 过滤器名称*/List<String> getAllFilterNames();
}
DefaultFilterSelector
public class DefaultFilterSelector implements FilterSelector{@Setterprivate  List<String> filterNames = CollUtil.newArrayList();@Overridepublic boolean matchFilter(String currentFilterName) {return filterNames.stream().anyMatch(s -> Objects.equals(s,currentFilterName));}@Overridepublic List<String> getAllFilterNames() {return filterNames;}}

调用代码

请添加图片描述

PipelineApplication

@SpringBootApplication
@EnablePluginRegistries(value = {Business1PostPlugin.class, Business2PostPlugin.class})
public class PipelineApplication {public static void main(String[] args) {SpringApplication.run(PipelineApplication.class, args);}
}

controller

@RestController
@RequestMapping("/pipelineTest")
public class PipelineController {@Autowiredprivate Business1Service business1PipelineTestService;@Autowiredprivate Business2Service business2PipelineTestService;@GetMapping("/business1")public void business1(){PipelineRequestVo pipelineTestRequest = new PipelineRequestVo();pipelineTestRequest.setUuid("business1-1110-1111231afsas-123adss");pipelineTestRequest.setBusinessCode("business1");pipelineTestRequest.setModel2(new Business1Model2());pipelineTestRequest.setModel1(new Business1Model1());business1PipelineTestService.doService(pipelineTestRequest);}@GetMapping("/business2")public void business2(){PipelineRequestVo pipelineTestRequest = new PipelineRequestVo();pipelineTestRequest.setUuid("business2-1110-1111231afsas-123adss");pipelineTestRequest.setBusinessCode("business2");pipelineTestRequest.setModel3(new Business2Model1());pipelineTestRequest.setModel4(new Business2Model2());business2PipelineTestService.doService(pipelineTestRequest);}}

entity

@Data
public class PipelineRequestVo {private String uuid;private String businessCode;/*** 在自定义的filter中处理*/@Setter@Getterprivate Business1Model1 model1;/*** 在自定义的filter中处理*/@Setter@Getterprivate Business1Model2 model2;/*** 在自定义的filter中处理*/@Setter@Getterprivate Business2Model1 model3;/*** 在自定义的filter中处理*/@Setter@Getterprivate Business2Model2 model4;}

service

@Getter
@AllArgsConstructor
public enum BusinessTypeEnum implements BizType {BUSINESS_1(1,"业务1"),BUSINESS_2(2,"业务2"),BUSINESS_3(3,"业务3"),;private Integer code;private String name;}

service.business1

public interface Business1Service {void doService(PipelineRequestVo pipelineTestRequest);
}
@Slf4j
@Service
public class Business1ServiceImpl implements Business1Service {@Qualifier("business1PipelineSelectorFactory")@Autowiredprivate  PipelineSelectorFactory business1PipelineSelectorFactory;@Autowiredprivate  FilterChainPipeline<Business1PipelineFilter> filterChainPipeline;@Autowiredprivate  PluginRegistry<Business1PostPlugin, Business1Model1> business1PostPlugin;@Overridepublic void doService(PipelineRequestVo pipelineTestRequest) {log.info("===============business1开始===============");// 处理器参数log.info("===============开始获取FilterSelector===============");FilterSelector filterSelector = business1PipelineSelectorFactory.getFilterSelector(pipelineTestRequest);Business1Context pipelineEventContext = new Business1Context(BusinessTypeEnum.BUSINESS_1, filterSelector);log.info("获取FilterSelector完成: {}",filterSelector.getAllFilterNames());log.info("===============获取FilterSelector完成===============");// 处理log.info("===============开始执行过滤器===============");pipelineEventContext.setPipelineTestRequest(pipelineTestRequest);pipelineEventContext.setModel2(pipelineTestRequest.getModel2());pipelineEventContext.setModel1(pipelineTestRequest.getModel1());filterChainPipeline.getFilterChain().handler(pipelineEventContext);log.info("===============执行过滤器完成===============");// 处理后获取值log.info("===============开始执行后置处理器===============");Business1Model2 model2 = pipelineEventContext.getModel2();Business1Model1 model1 = pipelineEventContext.getModel1();PipelineRequestVo pipelineTestRequest1 = pipelineEventContext.getPipelineTestRequest();business1PostPlugin.getPluginsFor(model1).forEach(handler -> handler.postProcessing(model1));log.info("===============执行后置处理器完成===============");log.info("===============business1结束===============");}}

service.business1.context

public class Business1Context extends AbstractEventContext {/*** 在自定义的filter中处理*/@Setter@Getterprivate Business1Model1 model1;/*** 在自定义的filter中处理*/@Setter@Getterprivate Business1Model2 model2;/*** 在自定义的filter中处理*/@Setter@Getterprivate PipelineRequestVo pipelineTestRequest;public Business1Context(BizType businessType, FilterSelector filterSelector) {super(businessType, filterSelector);}@Overridepublic boolean continueChain() {return true;}}
@Data
public class Business1Model1 {private Integer id;private String name1;private String name2;private String name3;}
@Data
public class Business1Model2 {private Integer id;private String name;private String desc;private String age;}

service.business1.filters

public interface Business1PipelineFilter extends EventFilter<Business1Context> {int order();
}
@Slf4j
@Component
public class Business1Filter1 extends AbstractEventFilter<Business1Context> implements Business1PipelineFilter {@Overridepublic void handler(Business1Context context) {// 模拟操作数据库 等业务操作 可以利用门面模式进行解耦Business1Model1 model1 = context.getModel1();model1.setName1("张三");model1.setName2("李四");model1.setName3("王五");model1.setId(1);Business1Model2 model2 = context.getModel2();model2.setId(2);model2.setDesc("");model2.setAge("18");model2.setName("小白");log.info("Filter1执行完毕...");// 存入新的值到上下文对象中 下个处理器继续处理context.setModel1(model1);context.setModel2(model2);}@Overridepublic int order() {return 1;}
}
@Slf4j
@Component
public class Business1Filter2 extends AbstractEventFilter<Business1Context>  implements Business1PipelineFilter {@Overridepublic void handler(Business1Context context) {// 模拟操作数据库 等业务操作 可以利用门面模式进行解耦Business1Model1 model1 = context.getModel1();model1.setName1(model1.getName1() + "-------------");model1.setName2(model1.getName2() + "-------------");model1.setName3(model1.getName3() + "-------------");model1.setId(100);log.info("Filter2执行完毕...");// 存入新的值到上下文对象中 下个处理器继续处理context.setModel1(model1);context.setModel2(context.getModel2());}@Overridepublic int order() {return 2;}
}

service.business1.plugins

public interface Business1PostPlugin extends Plugin<Business1Model1> {/*** 后置处理** @param model 处理参数*/void postProcessing(Business1Model1 model);}
@Slf4j
@Component
public class Business1ServicePluginImpl implements Business1PostPlugin {@Overridepublic boolean supports(Business1Model1 pipelineEventContext) {return true;}@Overridepublic void postProcessing(Business1Model1 model) {log.info("===>{}",model.getId());}}
@Slf4j
@Component
public class Business1ServicePluginImpl2 implements Business1PostPlugin {@Overridepublic boolean supports(Business1Model1 model) {return true;}@Overridepublic void postProcessing(Business1Model1 model) {log.info("===>{}",model.getId());}}

service.business2

public interface Business2Service {void doService(PipelineRequestVo pipelineTestRequest);
}
@Slf4j
@Service
public class Business2ServiceImpl implements Business2Service {@Qualifier("business2PipelineSelectorFactory")@Autowiredprivate PipelineSelectorFactory business2PipelineSelectorFactory;@Autowiredprivate FilterChainPipeline<Business2PipelineFilter> filterChainPipeline;@Autowiredprivate PluginRegistry<Business2PostPlugin, Business2Model1> business2PostPlugin;@Overridepublic void doService(PipelineRequestVo pipelineTestRequest) {log.info("===============business2开始===============");// 处理器参数log.info("===============开始获取FilterSelector===============");FilterSelector filterSelector = business2PipelineSelectorFactory.getFilterSelector(pipelineTestRequest);Business2Context pipelineEventContext = new Business2Context(BusinessTypeEnum.BUSINESS_2, filterSelector);log.info("获取FilterSelector完成: {}",filterSelector.getAllFilterNames());log.info("===============获取FilterSelector完成===============");// 处理log.info("===============开始执行过滤器===============");pipelineEventContext.setPipelineTestRequest(pipelineTestRequest);pipelineEventContext.setModel2(pipelineTestRequest.getModel4());pipelineEventContext.setModel1(pipelineTestRequest.getModel3());filterChainPipeline.getFilterChain().handler(pipelineEventContext);log.info("===============执行过滤器完成===============");// 处理后获取值log.info("===============开始执行后置处理器===============");Business2Model2 model2 = pipelineEventContext.getModel2();Business2Model1 model1 = pipelineEventContext.getModel1();PipelineRequestVo pipelineTestRequest1 = pipelineEventContext.getPipelineTestRequest();business2PostPlugin.getPluginsFor(model1).forEach(handler -> handler.postProcessing(model1));log.info("===============执行后置处理器完成===============");log.info("===============business2结束===============");}}

service.business2.context

public class Business2Context extends AbstractEventContext {/*** 在自定义的filter中处理*/@Setter@Getterprivate Business2Model1 model1;/*** 在自定义的filter中处理*/@Setter@Getterprivate Business2Model2 model2;/*** 在自定义的filter中处理*/@Setter@Getterprivate PipelineRequestVo pipelineTestRequest;public Business2Context(BizType businessType, FilterSelector filterSelector) {super(businessType, filterSelector);}@Overridepublic boolean continueChain() {return true;}}
@Data
public class Business2Model1 {private Integer id;private String name1;private String name2;private String name3;}
@Data
public class Business2Model2 {private Integer id;private String name;private String desc;private String age;}

service.business2.filters

public interface Business2PipelineFilter extends EventFilter<Business2Context> {int order();
}
@Slf4j
@Component
public class Business2Filter1 extends AbstractEventFilter<Business2Context> implements Business2PipelineFilter {@Overridepublic void handler(Business2Context context) {// 模拟操作数据库 等业务操作 可以利用门面模式进行解耦Business2Model1 model1 = context.getModel1();model1.setName1("张三");model1.setName2("李四");model1.setName3("王五");model1.setId(1);Business2Model2 model2 = context.getModel2();model2.setId(2);model2.setDesc("");model2.setAge("18");model2.setName("小白");log.info("Filter1执行完毕...");// 存入新的值到上下文对象中 下个处理器继续处理context.setModel1(model1);context.setModel2(model2);}@Overridepublic int order() {return 1;}
}
@Slf4j
@Component
public class Business2Filter2 extends AbstractEventFilter<Business2Context>  implements Business2PipelineFilter {@Overridepublic void handler(Business2Context context) {// 模拟操作数据库 等业务操作 可以利用门面模式进行解耦Business2Model1 model1 = context.getModel1();model1.setName1(model1.getName1() + "-------------");model1.setName2(model1.getName2() + "-------------");model1.setName3(model1.getName3() + "-------------");model1.setId(100);log.info("Filter2执行完毕...");// 存入新的值到上下文对象中 下个处理器继续处理context.setModel1(model1);context.setModel2(context.getModel2());}@Overridepublic int order() {return 2;}
}

service.business2.plugins

public interface Business2PostPlugin extends Plugin<Business2Model1> {/*** 后置处理** @param model 处理参数*/void postProcessing(Business2Model1 model);}
@Slf4j
@Component
public class Business2ServicePluginImpl implements Business2PostPlugin {@Overridepublic boolean supports(Business2Model1 pipelineEventContext) {return true;}@Overridepublic void postProcessing(Business2Model1 model) {log.info("===>{}",model.getId());}}
@Slf4j
@Component
public class Business2ServicePluginImpl2 implements Business2PostPlugin {@Overridepublic boolean supports(Business2Model1 model) {return true;}@Overridepublic void postProcessing(Business2Model1 model) {log.info("===>{}",model.getId());}}

service.config

@ConfigurationProperties(prefix = "test")
@Component
@Data
public class FilterConfigProperties {private Map<String, List<String>> configs;public Map<String, List<String>> getConfigs() {if (configs == null) {configs = MapUtil.newHashMap(16);}return configs;}}
@Component
@RequiredArgsConstructor
public class PipelineFilterConfig {private final List<Business1PipelineFilter> business1PipelineFilter;private final FilterChainPipeline<Business1PipelineFilter> business1FilterChainPipeline;private final List<Business2PipelineFilter> business2PipelineFilter;private final FilterChainPipeline<Business2PipelineFilter> business2FilterChainPipeline;private final FilterConfigProperties filterConfigProperties;@Beanpublic FilterChainPipeline<Business1PipelineFilter> business1ChargePipeline() {Map<String, List<String>> configs = filterConfigProperties.getConfigs();if (business1PipelineFilter.isEmpty() || configs.isEmpty()){return business1FilterChainPipeline;}Set<Map.Entry<String, List<String>>> filtersName = configs.entrySet();long distinctCount = filtersName.stream().distinct().count();if (distinctCount > business1PipelineFilter.size()) {throw new IllegalArgumentException("设置的过滤器数量大于实际过滤器数量");}business1PipelineFilter.stream().sorted(Comparator.comparing(Business1PipelineFilter::order)).forEach(business1FilterChainPipeline::append);return business1FilterChainPipeline;}@Beanpublic FilterChainPipeline<Business2PipelineFilter> business2ChargePipeline() {Map<String, List<String>> configs = filterConfigProperties.getConfigs();if (business2PipelineFilter.isEmpty() || configs.isEmpty()){return business2FilterChainPipeline;}Set<Map.Entry<String, List<String>>> filtersName = configs.entrySet();long distinctCount = filtersName.stream().distinct().count();if (distinctCount > business2PipelineFilter.size()) {throw new IllegalArgumentException("设置的过滤器数量大于实际过滤器数量");}business2PipelineFilter.stream().sorted(Comparator.comparing(Business2PipelineFilter::order)).forEach(business2FilterChainPipeline::append);return business2FilterChainPipeline;}}

service.selector

public interface PipelineSelectorFactory {FilterSelector  getFilterSelector(PipelineRequestVo request);
}
@Component("business1PipelineSelectorFactory")
public class Business1PipelineSelectorFactory implements PipelineSelectorFactory {@Autowiredprivate FilterConfigProperties filterConfigProperties;@Overridepublic FilterSelector getFilterSelector(PipelineRequestVo request) {String businessCode = request.getBusinessCode();DefaultFilterSelector defaultFilterSelector = new DefaultFilterSelector();if (businessCode.equals("business1")){defaultFilterSelector.setFilterNames(filterConfigProperties.getConfigs().getOrDefault(businessCode, Collections.unmodifiableList(new ArrayList<>())));}return defaultFilterSelector;}
}
@Component("business2PipelineSelectorFactory")
public class Business2PipelineSelectorFactory implements PipelineSelectorFactory {@Autowiredprivate FilterConfigProperties filterConfigProperties;@Overridepublic FilterSelector getFilterSelector(PipelineRequestVo request) {String businessCode = request.getBusinessCode();DefaultFilterSelector defaultFilterSelector = new DefaultFilterSelector();if (businessCode.equals("business2")){defaultFilterSelector.setFilterNames(filterConfigProperties.getConfigs().getOrDefault(businessCode, Collections.unmodifiableList(new ArrayList<>())));}return defaultFilterSelector;}}

application.yml

server:port: 8080test:configs:business1:- Business1Filter1- Business1Filter2business2:- Business2Filter1- Business2Filter2

http://www.mrgr.cn/p/55386704

相关文章

vue3+elementplus+axios+router的入门项目总结

一、使用vite方式创建项目:1、创建空文件夹,用vscode打开空文件夹,终端上运行如下命令$ npm init vite-app [项目名]:初始化项目 $ cd [项目名]:进入项目 $ npm install:安装项目依赖 $ npm run dev:启动项目2、启动项目后会出现访问地址: 3、进入访问地址: 二、引入…

找win电脑代理地址

1.进入控制面板2.Internet属性3.局域网设置

C语言野指针【入门详解】

目录 一、什么是野指针 二、野指针的成因 2.1 指针未初始化 2.2 指针越界访问 2.3 指针指向的空间释放 三、如何规避野指针 3.1 初始化指针 3.2 小心越界访问 3.3 当指针不用时&#xff0c;及时置为空 3.4 避免返回局部变量的地址 *结语&#xff1a; 希望这篇关于指…

RHCE2

一.配置server主机要求如下&#xff1a; 1.server主机的主机名称为 ntp_server.example.com //修改主机名 hostnamectl set-hostname ntp_server.example.comreboot 修改主机名后一定要记住重启。 2.server主机的IP为&#xff1a; 172.25.254.100 //主机ip配置 [rootntpse…

BOSHIDA DC电源模块的发展趋势和前景展望

BOSHIDA DC电源模块的发展趋势和前景展望 随着电子产品的普及和多样化,对电源模块的需求也越来越大。其中,DC电源模块作为一种重要的电源供应方式,在各个领域有着广泛的应用。在过去的几十年里,DC电源模块已经经历了多次技术革新和发展,未来的发展趋势也值得关注。本文将从…

Vue3 + vite 项目自定义一个svg-icon组件

1. 安装vite-plugin-svg-icons插件npm i vite-plugin-svg-icons -D2.vite.config.ts中配置import path from "path"; import { createSvgIconsPlugin } from "vite-plugin-svg-icons"; export default defineConfig({plugins: [......createSvgIconsPlugin…

HarmonyOS NEXT应用开发之Tab组件实现增删Tab标签

介绍 本示例介绍使用了Tab组件实现自定义增删Tab页签的功能。该场景多用于浏览器等场景。 效果图预览使用说明:点击新增按钮,新增Tab页面。 点击删除按钮,删除Tab页面。实现思路设置Tab组件的barHeight为0,隐藏组件自带的TabBar。Tabs() {... } .barHeight(0) // 隐藏tab组…

光学雨量计雨量传感器技术的优势与应用范围

光学雨量计雨量传感器技术的优势与应用范围 光学雨量计是一种利用光学原理来测量降雨量的仪器。相比于传统的雨量计,光学雨量计具有许多优势,也扩大了其应用范围。 光学雨量计的优势之一就是其高精度和高分辨率。光学雨量计可以实时记录和计算降雨量,精确到0.1毫米的分辨率…

【R语言】动画图:散点图

绘制成如下的散点图&#xff1a; 如果数据量大&#xff0c;有多个年份&#xff0c;就会生成多张图&#xff0c;例如&#xff1a; 具体代码如下&#xff1a; library(gapminder)#加载 gapminder 包&#xff0c;其中包含了从 1952 年至 2007 年各个国家的 GDP、预期寿命和人口数据…

2024-04-18 tsconfig.json 常用的配置项作用

TypeScript 编译器的配置文件,用于指定编译 TypeScript 代码时的编译选项和编译目标等信息。 通过修改该文件,可以定制 TypeScript 编译器的行为,例如指定编译目标、启用或禁用特定的语言特性、设置代码检查规则等。以下是一些常用的配置项及其作用: compilerOptions:编译…

【原创教程】EPLAN电气图纸设计规范

EPLAN电气图纸中的通用说明&#xff0c;说白了就是电气图纸的图纸概述、制图规范&#xff08;这里的规范根据每个公司及客户的要求不同进行更改&#xff09;。下面就以我们公司的规范要求&#xff0c;以实际的项目案例来对照讲述一下&#xff0c;通用说明的制作。 1.首先新建页…

实验6循环结构程序设计(for语句的应用)

实验6循环结构程序设计(for语句的应用) 一、实验目的 1.熟练掌握三种循环语句并能正确运用; 2.能够用循环实现一些常用算法,如穷举法,迭代法,递推法等; 3.进一步学习程序调试; 4.了解中国算法,百钱买百鸡。 二、实验硬、软件环境 Windows计算机、Devc6.0 三、实验内容…

Perforce (P4)版本控制使用指南

转载自:https://blog.csdn.net/zyhse/article/details/119083666以下为P4常规和一些必要操作如何达到同步?本质就是需要告诉P4你干了什么,然后P4再别人的机器上模拟你所做的操作操作的宗旨如果想让别人知道你的操作,就需要去主动通知✘31、登录账号密码相关信息会在入职手册…

模拟电路学习笔记——半导体基础知识

1.纯净的具有晶体结构的半导体称为本征半导体 2.导体导电只有一种载流子,即自由电子导电本征半导体含两种载流子:自由电子和空穴载流子:运载电荷的粒子 3.杂质半导体*本征半导体中掺入少量合适的杂质元素,便可得到杂质半导体3.1 N型半导体:纯净的硅晶体中掺入五价元素(如磷…

llama-factory SFT系列教程 (二),大模型在自定义数据集 lora 训练与部署

文章目录 简介支持的模型列表2. 添加自定义数据集3. lora 微调4. 大模型 lora 权重&#xff0c;部署问题 参考资料 简介 文章列表&#xff1a; llama-factory SFT系列教程 (一)&#xff0c;大模型 API 部署与使用llama-factory SFT系列教程 (二)&#xff0c;大模型在自定义数…

高效生产管理:选择顺通鞋业ERP系统派单的理由

显然,传统的生产管理模式已经难以满足现代企业的需求,因此选择一款适合自身业务特点的生产管理软件成为了企业的当务之急。顺通鞋业ERP系统作为一款功能强大的生产管理软件,凭借其出色的派单功能,正逐渐成为众多企业的首选。通过系统派单,企业可以及时发现并解决生产过程中…

【Python微信机器人】写一个监控采集公众号文章的插件

原文链接: https://mp.weixin.qq.com/s/f8zbM6wMld3koqjaFbCuxw 前言 弄了个视频号下载后,同一个问题每天都会被问,回答的有点烦了。想了想根本原因还是缺少一个交流平台,微信群的话,刚进群的看不到之前的聊天记录。想整个知识星球,发现只能弄个收费的,免费的需要激活码才…

SD卡最终有望在2025年达到4TB

西部数据计划明年推出首款4TB SD卡。在上周四&#xff0c;该存储公司宣布计划下周亲自演示该产品。 西部数据将以其 SanDisk 品牌推出遵循 SD 协会安全数字超容量 (SDUC) 标准的 SD 卡&#xff0c;并将其推向“复杂的媒体和娱乐工作流程”&#xff0c;例如使用相机的高帧率高分…

Redmi Turbo 3新品发布,天星金融(原小米金融)优惠加持护航新机体验

Redmi新十年使命不变&#xff0c;挑战不断升级。Redmi Turbo 3&#xff0c;作为Turbo系列的开篇之作&#xff0c;将自身定位为新生代性能旗舰&#xff0c;决心重塑中端性能新格局。据悉&#xff0c;Redmi Turbo 3于4月10日已正式发布。预售期间更是连续数日&#xff0c;蝉联小米…

Linux编辑器-vim的使用

vim的基本概念 vim的三种模式(其实有好多模式&#xff0c;目前掌握这3种即可),分别是命令模式&#xff08;command mode&#xff09;、插 入模式&#xff08;Insert mode&#xff09;和底行模式&#xff08;last line mode&#xff09;&#xff0c;各模式的功能区分如下&#…