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

SpringBatch学习

/** * 示例一Tasklet 方式 */ Configuration EnableBatchProcessing public class TaskletBatchConfig { private static final Logger logger LoggerFactory.getLogger(TaskletBatchConfig.class); Autowired private JobBuilderFactory jobBuilderFactory; Autowired private StepBuilderFactory stepBuilderFactory; Bean public Job taskletJob() { return jobBuilderFactory.get(taskletJob) .start(taskletStep()) .build(); } Bean public Step taskletStep() { return stepBuilderFactory.get(taskletStep) .tasklet(helloWorldTasklet()) .build(); } Bean public Tasklet helloWorldTasklet() { return (contribution, chunkContext) - { int total 10; logger.info( Tasklet 开始执行 ); for (int i 1; i total; i) { logger.info(Hello World! index {}, i); // 可以在这里写任何业务逻辑 if (i % 3 0) { logger.info(第 {} 条数据处理完成特殊处理, i); } } logger.info( Tasklet 执行完成共处理 {} 条 , total); return RepeatStatus.FINISHED; }; } } /** * 示例二Chunk 方式推荐 */ Configuration EnableBatchProcessing public class ChunkBatchConfig { private static final Logger logger LoggerFactory.getLogger(ChunkBatchConfig.class); Autowired private JobBuilderFactory jobBuilderFactory; Autowired private StepBuilderFactory stepBuilderFactory; // Reader Bean public ItemReaderString nameReader() { ListString names Arrays.asList(张三, 李四, 王五, 赵六, 田七, 孙八, 周九, 吴十); return new ListItemReader(names); } // Processor Bean public ItemProcessorString, User userProcessor() { return name - { User user new User(); user.setName(name); user.setAge(20 (int) (Math.random() * 30)); user.setDesc(由 Spring Batch Chunk 处理); logger.info(【Processor】处理数据: {} → {}, name, user); return user; }; } // Writer Bean public ItemWriterUser userWriter() { return users - { logger.info(【Writer】本次批次写入 {} 条数据, users.size()); for (User user : users) { logger.info(【写入成功】 {}, user); // 实际项目中这里可以写入数据库、文件等 } }; } // Step Bean public Step chunkStep() { return stepBuilderFactory.get(chunkStep) .String, Userchunk(3) // 每3条数据为一个批次Chunk .reader(nameReader()) .processor(userProcessor()) .writer(userWriter()) .faultTolerant() // 开启容错 .skipLimit(5) // 最多跳过5条错误数据 .skip(Exception.class) // 跳过异常 .build(); } // Job Bean public Job chunkJob() { return jobBuilderFactory.get(chunkJob) .start(chunkStep()) .build(); } } Component public class CustomUserWriter implements ItemWriterUser { private static final Logger log LoggerFactory.getLogger(CustomUserWriter.class); Override public void write(List? extends User items) throws Exception { log.info(【Writer】开始批量写入 {} 条数据, items.size()); for (User user : items) { log.info(【写入数据库】 {}, user); // extUserMapper.batchInsert 或 update ... } } } Component public class CustomUserReader implements ItemReaderUser { private final ListUser users; private int index 0; public CustomUserReader() { this.users Arrays.asList( new User(张三, 25, 原始数据), new User(李四, 30, 原始数据), new User(王五, 28, 原始数据), new User(赵六, 35, 原始数据) ); } Override public User read() { if (index users.size()) { User user users.get(index); System.out.println(【Reader】读取到: {} user.getName()); return user; } return null; // 返回null表示读取结束 } } Component public class CustomUserProcessor implements ItemProcessorUser, User { private final Logger log LoggerFactory.getLogger(CustomUserProcessor.class); Override public User process(User item) throws Exception { // 业务处理 item.setAge(item.getAge() 1); item.setDesc(已加工 - LocalDateTime.now()); log.info(【Processor】加工完成: {}, item.getName()); return item; } } Configuration EnableBatchProcessing RequiredArgsConstructor public class CustomComponentBatchConfig { private final JobBuilderFactory jobBuilderFactory; private final StepBuilderFactory stepBuilderFactory; private final CustomUserReader customUserReader; private final CustomUserProcessor customUserProcessor; private final CustomUserWriter customUserWriter; Bean public Step customComponentStep() { return stepBuilderFactory.get(customComponentStep) .User, Userchunk(2) .reader(customUserReader) .processor(customUserProcessor) .writer(customUserWriter) .faultTolerant() .skipLimit(5) .skip(Exception.class) .build(); } Bean public Job customComponentJob() { return jobBuilderFactory.get(customComponentJob) .start(customComponentStep()) .build(); } } 使用监听器 Tasklet 主要使用 StepExecutionListener。 Component public class TaskletStepListener implements StepExecutionListener { private static final Logger log LoggerFactory.getLogger(TaskletStepListener.class); Override public void beforeStep(StepExecution stepExecution) { log.info(【Tasklet Step 开始】 Step名称: {}, stepExecution.getStepName()); log.info(Job参数: {}, stepExecution.getJobParameters()); } Override public ExitStatus afterStep(StepExecution stepExecution) { log.info(【Tasklet Step 结束】 读: {} 条, 写: {} 条, 跳过: {} 条, stepExecution.getReadCount(), stepExecution.getWriteCount(), stepExecution.getSkipCount()); log.info(最终状态: {}, stepExecution.getStatus()); return stepExecution.getExitStatus(); } } 在 Step 中使用 Bean public Step taskletStep(TaskletStepListener taskletStepListener) { return stepBuilderFactory.get(taskletStep) .tasklet(simpleTasklet()) .listener(taskletStepListener) // 添加监听器 .build(); } Chunk 方式可以使用的监听器更多StepExecutionListener ChunkListener Item*Listener ChunkListener示例 Component public class ChunkStepListener implements ChunkListener { private static final Logger log LoggerFactory.getLogger(ChunkStepListener.class); Override public void beforeChunk(ChunkContext context) { log.info(【Chunk 开始】 本批次即将处理数据...); } Override public void afterChunk(ChunkContext context) { log.info(【Chunk 完成】 本批次处理结束); } Override public void afterChunkError(ChunkContext context) { log.error(【Chunk 异常】 本批次处理失败); } } 使用 Bean public Step chunkInlineStep( ChunkStepListener chunkListener, StepExecutionListener stepListener) { // 可同时注入多个 return stepBuilderFactory.get(chunkInlineStep) .String, Userchunk(3) .reader(inlineReader()) .processor(inlineProcessor()) .writer(inlineWriter()) .listener(chunkListener) // Chunk 监听器 .listener(stepListener) // Step 监听器 // 也可以加 Item 级别监听器 // .listener(itemReadListener()) // .listener(itemProcessListener()) // .listener(itemWriteListener()) .faultTolerant() .build(); } 自定义监听器 Component public class UserStepListener implements StepExecutionListener { private static final Logger log LoggerFactory.getLogger(UserStepListener.class); Override public void beforeStep(StepExecution stepExecution) { log.info( User Step 开始执行 ); } Override public ExitStatus afterStep(StepExecution stepExecution) { log.info( User Step 执行结束 ); log.info(读: {}, 写: {}, 跳过: {}, 提交次数: {}, stepExecution.getReadCount(), stepExecution.getWriteCount(), stepExecution.getSkipCount(), stepExecution.getCommitCount()); return stepExecution.getExitStatus(); } } Component public class UserChunkListener implements ChunkListener { Override public void beforeChunk(ChunkContext context) { log.info(开始新 Chunk当前已提交: {} 次, context.getStepContext().getStepExecution().getCommitCount()); } Override public void afterChunk(ChunkContext context) { log.info(Chunk 执行完成); } } 配置使用 Bean public Step customComponentStep( UserStepListener stepListener, UserChunkListener chunkListener) { return stepBuilderFactory.get(customComponentStep) .User, Userchunk(10) .reader(customUserReader) .processor(customUserProcessor) .writer(customUserWriter) .listener(stepListener) // Step 监听 .listener(chunkListener) // Chunk 监听 .faultTolerant() .skipLimit(10) .skip(Exception.class) .build(); } 监听器类型 JobExecutionListener作业级监听器 监听器类型​ JobExecutionListener 触发时机​ 在整个 Job 开始执行之前、Job 执行完成之后无论成功还是失败触发 主要作用​ 用于监控和控制整个批处理任务的生命周期适合做一些全局性的初始化和收尾工作 实际业务用途非常重要​ 在 Job 开始前进行初始化操作例如清理历史临时表数据、对任务加分布式锁防止重复执行 在 Job 结束后汇总本次任务的执行结果例如统计成功处理的数据量、失败数量 发送执行完成通知如通过邮件、企业微信、钉钉等方式通知相关人员 将 Job 的执行日志、起止时间、最终状态等信息持久化到数据库便于审计和追溯 当 Job 执行失败时进行统一告警触发监控系统的异常提醒 ---------------------------------------------------------------- StepExecutionListener步骤级监听器 监听器类型​ StepExecutionListener 触发时机​ 在每一个 Step 开始之前、Step 执行完成之后触发 主要作用​ 用于监控单个 Step 的执行情况关注某个具体步骤的输入、处理和输出状态 实际业务用途非常重要​ 在 Step 开始前打印或记录当前 Step 的执行参数便于问题定位 在 Step 结束后统计该步骤中读取、处理、写入的数据量以及跳过的记录条数 记录每个 Step 的执行耗时、成功或失败状态用于性能分析和运行报表 当 Step 执行异常时记录详细的错误信息辅助后续排查和重试策略制定 ---------------------------------------------------------------- ChunkListener块级监听器 监听器类型​ ChunkListener 触发时机​ 在每个 Chunk 开始处理时、Chunk 处理完成后以及 Chunk 发生异常时触发 主要作用​ 用于监控批次级别的处理过程关注一批数据在处理过程中的状态和性能 实际业务用途非常重要​ 监控每一批次的处理进度例如打印“正在处理第 N 批数据” 统计每个 Chunk 的处理耗时识别是否存在性能瓶颈 在 Chunk 处理失败时记录错误信息和当前批次的关键数据方便后续重试或补偿 在批量处理过程中做阶段性打点用于监控大盘或日志分析 ---------------------------------------------------------------- ItemReadListener读监听器 监听器类型​ ItemReadListener 触发时机​ 在读取每一条数据之前、读取完成之后以及读取发生异常时触发 主要作用​ 用于监控和跟踪数据读取阶段的行为重点关注 Reader 的输出情况 实际业务用途非常重要​ 在调试或开发阶段打印读取到的原始数据验证数据源是否正确 记录读取失败的异常信息帮助定位数据格式或数据源问题 统计读取总数、空读次数辅助判断 Reader 是否正常工作 在某些特殊场景下对读取到的数据进行轻量级校验或标记 ---------------------------------------------------------------- ItemProcessListener处理监听器 监听器类型​ ItemProcessListener 触发时机​ 在处理每一条数据之前、处理完成之后以及处理过程出现异常时触发 主要作用​ 用于监控业务逻辑处理阶段关注 Processor 的执行情况和业务结果 实际业务用途非常重要​ 记录关键业务对象的处理日志例如订单、用户信息在业务规则处理后的变化 在处理前后埋点用于统计业务处理成功率、异常率等指标 捕获 Processor 中的业务异常记录异常原因便于后续补偿或人工干预 在复杂业务处理链路中跟踪单条数据的流转和处理结果 ---------------------------------------------------------------- ItemWriteListener写监听器 监听器类型​ ItemWriteListener 触发时机​ 在每一批数据Chunk写入之前、写入完成之后以及写入发生异常时触发 主要作用​ 用于监控数据写入阶段确保写出数据的准确性和可追溯性 实际业务用途非常重要​ 在写入前对即将落库或输出的数据进行最后校验或日志打印 在写入成功后记录成功写入的数据条数和关键字段用于对账和统计 在写入失败时记录错误详情并触发写入失败预警机制 结合事务回滚或重试策略在监听器中做补偿、告警或状态更新 ----------------------------------------------------------------- SkipListener 当 Spring Batch 在执行过程中跳过Skip某条数据时会触发这个监听器。 public interface SkipListenerT, S { // 当某条数据被跳过时触发最常用 void onSkipInRead(Throwable t); // Reader 读取时跳过 void onSkipInProcess(T item, Throwable t); // Processor 处理时跳过最常用 void onSkipInWrite(S item, Throwable t); // Writer 写入时跳过 } Component public class MySkipListener implements SkipListenerChannelVerifyBean, TlPayTransLog { private static final Logger log LoggerFactory.getLogger(MySkipListener.class); Override public void onSkipInRead(Throwable t) { log.warn(【Skip】读取数据时跳过一条记录, t); } // 最常用Processor 处理失败时跳过 Override public void onSkipInProcess(ChannelVerifyBean item, Throwable t) { log.error(【Skip】处理数据失败已跳过数据内容: {}, item, t); // 可以在这里记录到错误日志表方便后续人工处理 // errorLogService.saveSkipLog(item, t.getMessage()); } Override public void onSkipInWrite(TlPayTransLog item, Throwable t) { log.error(【Skip】写入数据失败已跳过数据: {}, item, t); } } Bean public Step myStep(MySkipListener skipListener) { return stepBuilderFactory.get(myStep) .ChannelVerifyBean, TlPayTransLogchunk(100) .reader(reader()) .processor(processor()) .writer(writer()) .faultTolerant() // 必须开启容错 .skipLimit(50) // 最多允许跳过50条 .skip(Exception.class) // 跳过所有异常可指定具体异常 // .skip(MyBusinessException.class) // 推荐指定具体异常 .listener(skipListener) // 绑定 SkipListener .build(); } ItemReadListener Component public class UserReadListener implements ItemReadListenerString { // 泛型为 Reader 读取的类型 private static final Logger log LoggerFactory.getLogger(UserReadListener.class); Override public void beforeRead() { // 每次读取一条数据之前触发 log.debug(【Read】准备读取下一条数据...); } Override public void afterRead(String item) { // 读取成功后触发 log.info(【Read】成功读取到数据: {}, item); } Override public void onReadError(Exception ex) { // 读取发生异常时触发 log.error(【Read Error】读取数据失败, ex); } } ItemProcessListener Component public class UserProcessListener implements ItemProcessListenerString, User { private static final Logger log LoggerFactory.getLogger(UserProcessListener.class); Override public void beforeProcess(String item) { // 处理之前 log.debug(【Process】开始处理数据: {}, item); } Override public void afterProcess(String item, User result) { // 处理成功后 if (result ! null) { log.info(【Process】处理完成: {} → {}, item, result); } else { log.info(【Process】数据被过滤: {}, item); } } Override public void onProcessError(String item, Exception e) { // 处理发生异常时 log.error(【Process Error】处理数据失败原始数据: {}, item, e); // 可以在这里记录失败数据到数据库 // skipLogService.save(item, e.getMessage()); } } ItemWriteListener Component public class UserWriteListener implements ItemWriteListenerUser { private static final Logger log LoggerFactory.getLogger(UserWriteListener.class); Override public void beforeWrite(List? extends User items) { // 写入之前 log.info(【Write】准备写入 {} 条数据, items.size()); items.forEach(user - log.debug(即将写入: {}, user)); } Override public void afterWrite(List? extends User items) { // 写入成功后 log.info(【Write】成功写入 {} 条数据, items.size()); items.forEach(user - log.info(写入成功: {}, user)); } Override public void onWriteError(Exception exception, List? extends User items) { // 写入发生异常时 log.error(【Write Error】写入 {} 条数据失败, items.size(), exception); items.forEach(user - log.error(失败数据: {}, user)); } } 使用监听器 Bean public Step userProcessStep( UserReadListener readListener, UserProcessListener processListener, UserWriteListener writeListener) { return stepBuilderFactory.get(userProcessStep) .String, Userchunk(10) .reader(userReader()) .processor(userProcessor()) .writer(userWriter()) // 绑定三个 Item 监听器 .listener(readListener) .listener(processListener) .listener(writeListener) .faultTolerant() .skipLimit(20) .skip(Exception.class) .build(); } 执行顺序 ItemReadListener.beforeRead() Reader.read() ItemReadListener.afterRead() ItemProcessListener.beforeProcess() Processor.process() ItemProcessListener.afterProcess() ItemWriteListener.beforeWrite() Writer.write() ItemWriteListener.afterWrite() 如果任何一步出错则会触发对应的 onXXXError() 方法。

相关文章:

SpringBatch学习

/*** 示例一:Tasklet 方式*/ Configuration EnableBatchProcessing public class TaskletBatchConfig {private static final Logger logger LoggerFactory.getLogger(TaskletBatchConfig.class);Autowiredprivate JobBuilderFactory jobBuilderFactory;Autowiredp…...

终极免费风扇控制软件:如何让你的电脑既安静又凉爽

终极免费风扇控制软件:如何让你的电脑既安静又凉爽 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/Fa…...

打磨与展望:RAG 的进阶技巧与避坑指南

走过了从加载文档到完整问答链的全程,恭喜你——你已经亲手建造出了一台可以和自己文档“对话”的 RAG 引擎。但任何一个上过生产环境的开发者都知道:原型和产品之间,往往隔着一条名为“细节”的护城河。 用户开始提各种刁钻问题,…...

Netflix 4K画质与杜比音效优化指南:解锁你的流媒体最佳体验

Netflix 4K画质与杜比音效优化指南:解锁你的流媒体最佳体验 【免费下载链接】netflix-4K-DDplus MicrosoftEdge(Chromium core) extension to play Netflix in 4K(Restricted)and DDplus audio 项目地址: https://gitcode.com/gh_mirrors/n…...

教育机构搭建AI辅助教学系统时如何通过Taotoken统一接口

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 教育机构搭建AI辅助教学系统时如何通过Taotoken统一接口 构建一个服务于师生的AI辅助教学系统,通常需要集成多种能力&a…...

除了卸载浏览器,ADB还能帮你清理哪些OPPO手机预装软件?附完整包名清单

深度优化OPPO手机:ADB卸载非必要预装应用全指南 对于追求系统纯净度的OPPO手机用户而言,预装应用往往占据宝贵存储空间并消耗后台资源。本文将系统介绍如何利用Android Debug Bridge(ADB)工具精准管理ColorOS系统中的各类预装组件…...

思源宋体CN:零成本打造专业中文排版的终极秘籍

思源宋体CN:零成本打造专业中文排版的终极秘籍 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还在为字体版权费用发愁?还在寻找既能商用又专业的中文字体&…...

基于Python与Telegram API构建消息抓取与备份工具实践

1. 项目概述与核心价值 最近在折腾一个挺有意思的小工具,起因是团队内部用Telegram群组做日常沟通和文件分享,时间一长,信息量爆炸,想找点历史资料或者特定文件简直是大海捞针。手动翻记录?效率低到令人发指。市面上虽…...

PCB线宽与电流关系详解:从原理到设计避坑指南

1. 项目概述:从一次烧板事故说起去年,我手头一个给电机驱动的小板子又冒烟了。排查了半天,发现不是芯片烧了,也不是电源接反了,问题出在一条给电机供电的电源走线上。那条线在板子上看着挺“粗壮”,但实际一…...

C#中使用MiniExcel 快速入门:读写 .xlsx 文件

背景介绍 报表绕不开 Excel。传统方案用 Microsoft.Office.Interop&#xff0c;需要安装 Office&#xff0c;且进程管理复杂。MiniExcel 是一个轻量级库&#xff08;< 1MB&#xff09;&#xff0c;通过直接操作 ZIP 压缩包&#xff08;.xlsx 本质是 ZIP&#xff09;实现读写…...

设计工程化实践:将设计思维转化为开发者技能的工具探索

1. 项目概述&#xff1a;当设计思维遇上代码技能最近在GitHub上看到一个挺有意思的项目&#xff0c;叫Arthurescc/design-fusion.skill。光看这个名字&#xff0c;就让我这个在设计和开发交叉领域摸爬滚打了十来年的老手眼前一亮。“Design Fusion”直译是“设计融合”&#xf…...

Spring Boot安全脚手架实战:快速集成认证授权与API防护

1. 项目概述&#xff1a;一个面向开发者的安全脚手架如果你是一名后端或全栈开发者&#xff0c;最近在启动一个新项目时&#xff0c;是不是总感觉有些“重复劳动”&#xff1f;比如&#xff0c;每次都要手动集成用户认证、权限管理、API安全防护、日志审计这些基础但至关重要的…...

基于SpringBoot+Vue的CRM客户管理系统毕设

博主介绍&#xff1a;✌ 专注于Java,python,✌关注✌私信我✌具体的问题&#xff0c;我会尽力帮助你。一、研究目的本研究旨在构建一个基于Spring Boot与Vue框架的CRM客户管理系统以解决传统客户关系管理中存在的信息孤岛现象与业务流程低效问题。当前企业客户管理普遍面临数据…...

DevChat:无缝集成IDE的开源AI编程助手,提升开发效率

1. 项目概述&#xff1a;一个真正融入工作流的AI编程伙伴如果你和我一样&#xff0c;每天大部分时间都花在代码编辑器里&#xff0c;那你肯定也经历过这样的场景&#xff1a;想重构一段代码&#xff0c;却卡在命名上&#xff1b;写一个复杂的函数&#xff0c;需要反复查阅文档&…...

AI驱动的工业预测性维护技术实践:AI驱动的预测性维护系统通过多传感器融合(振动、温度、电流等)实时监测设备健康状态,结合TSN网络实现毫秒级数据传输

标签:预测性维护 PHM 工业AI 振动分析 TSN 设备管理 引言:设备算命先生的时代来了 “老张,你这台风机轴承怕是撑不过两周了。” 如果有个"设备算命先生"能掐指一算就说出这句话,工厂的设备经理们大概会把他供起来。但在2024年,这个"算命先生"真的出…...

Boss-Key:Windows下一键隐藏窗口的终极隐私保护工具

Boss-Key&#xff1a;Windows下一键隐藏窗口的终极隐私保护工具 【免费下载链接】Boss-Key 老板来了&#xff1f;快用Boss-Key老板键一键隐藏静音当前窗口&#xff01;上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在数字化办公时代&#xf…...

4. 大型场馆大空间挡烟垂壁选型与布设

大型场馆、商业综合体、中庭展厅这类大空间建筑&#xff0c;空间跨度大、层高较高&#xff0c;传统隔断无法满足排烟分区要求&#xff0c;合理选用与布设挡烟垂壁&#xff0c;是解决大空间防排烟难题的核心途径。大空间场景在挡烟垂壁选型上&#xff0c;需优先适配大跨度、高空…...

Steam Deck Windows控制器驱动深度配置指南

Steam Deck Windows控制器驱动深度配置指南 【免费下载链接】steam-deck-windows-usermode-driver A windows usermode controller driver for the steam deck internal controller. 项目地址: https://gitcode.com/gh_mirrors/st/steam-deck-windows-usermode-driver 想…...

如何用BilibiliDown实现跨平台B站视频高效下载?3个核心优势解析

如何用BilibiliDown实现跨平台B站视频高效下载&#xff1f;3个核心优势解析 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_…...

工程定制丙级管道井门 物业机房通用款式

工程定制丙级管道井门&#xff0c;作为高层住宅、商业楼宇、物业机房强弱电井的专用消防配套设施&#xff0c;严格遵循国标消防规范生产&#xff0c;是建筑管井防火分隔、安全防护的核心产品。这款丙级管道井门采用钢制一体成型工艺&#xff0c;结构扎实不易变形&#xff0c;具…...

MPLAB Harmony框架实战:从驱动抽象到复杂嵌入式系统开发

1. 项目概述&#xff1a;为什么我们需要 Harmony&#xff1f;如果你在嵌入式开发领域摸爬滚打超过五年&#xff0c;尤其是深度使用过 Microchip 的 PIC32 系列 MCU&#xff0c;那你一定对“从零开始搭驱动”这件事深恶痛绝。我还记得十年前&#xff0c;为了在 PIC32MX 上跑通一…...

Boss-Key:办公隐私保护神器,一键隐藏敏感窗口的智能解决方案

Boss-Key&#xff1a;办公隐私保护神器&#xff0c;一键隐藏敏感窗口的智能解决方案 【免费下载链接】Boss-Key 老板来了&#xff1f;快用Boss-Key老板键一键隐藏静音当前窗口&#xff01;上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在当今…...

英雄联盟本地自动化工具完整指南:10分钟精通LeagueAkari终极教程

英雄联盟本地自动化工具完整指南&#xff1a;10分钟精通LeagueAkari终极教程 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power &#x1f680;. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为英雄联盟排…...

突破性创新:Midscene.js如何用AI视觉驱动重塑跨平台自动化测试

突破性创新&#xff1a;Midscene.js如何用AI视觉驱动重塑跨平台自动化测试 【免费下载链接】midscene AI-powered, vision-driven UI automation for every platform. 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene 在当今复杂的软件生态中&#xff0c;跨…...

RK3588平台IMX415摄像头驱动调试全流程与实战指南

1. 项目概述与核心挑战最近在基于瑞芯微RK3588平台调试索尼IMX415摄像头&#xff0c;整个过程可以说是既典型又充满细节。对于嵌入式Linux开发&#xff0c;尤其是多媒体应用&#xff0c;摄像头驱动调试往往是硬件适配中最关键也最磨人的一环。RK3588作为一款高性能的AIoT SoC&a…...

嘎嘎降AI和笔灵AI哪个更适合毕业论文:2026年达标率改写质量售后完整测评对比报告

嘎嘎降AI和笔灵AI哪个更适合毕业论文&#xff1a;2026年达标率改写质量售后完整测评对比报告 帮几个不同专业的同学处理过论文AI率&#xff0c;用过的工具加起来也有六七款了。 综合看&#xff0c;嘎嘎降AI&#xff08;www.aigcleaner.com&#xff09;是最稳的选择&#xff0…...

S19|MCP 与插件:多 Agent 平台 —— 外部能力总线,让外部工具安全接入

在前十八章&#xff0c;我们的 Agent 已经拥有完整的内部能力体系&#xff1a;循环、工具、计划、子代理、技能、压缩、权限、Hook、记忆、提示词流水线、错误恢复、任务系统、后台任务、定时调度、多 Agent 团队、团队协议、自主代理、Worktree 隔离&#xff0c;所有工具都写在…...

嘎嘎降AI全平台综合评测:2026年知网维普万方Turnitin达标率完整深度分析报告

嘎嘎降AI全平台综合评测&#xff1a;2026年知网维普万方Turnitin达标率完整深度分析报告 总有人问我选哪个降AI工具&#xff0c;这篇文章把主流的几款对比清楚。 综合推荐嘎嘎降AI&#xff08;www.aigcleaner.com&#xff09;&#xff0c;4.8元&#xff0c;99.26%达标率。不同…...

各高校论文AI率标准差异解读:从10%到30%不同学校标准差距2026年免费达标方案

各高校论文AI率标准差异解读&#xff1a;从10%到30%不同学校标准差距2026年免费达标方案 关于高校论文AI率标准解读&#xff0c;我系统研究过一段时间&#xff0c;也实际验证过各种说法。 这篇文章把关键的逻辑理清楚——知道了原理&#xff0c;遇到问题就知道该怎么处理了。…...

S18|Worktree 隔离:多 Agent 平台 —— 独立目录,独立车道,让并行工作互不干扰

在前十七章&#xff0c;我们的 Agent 已经拥有循环、工具、计划、子代理、技能、压缩、权限、Hook、记忆、提示词流水线、错误恢复、任务系统、后台任务、定时调度、多 Agent 团队、团队协议、自主代理十七大核心能力&#xff0c;能拆任务、认领任务、让多个 Agent 并行推进不同…...