【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解

news2024/12/22 18:03:26

 🎉🎉欢迎光临🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟特别推荐给大家我的最新专栏《Spring 狂野之旅:从入门到入魔》 🚀

本专栏带你从Spring入门到入魔!

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽icon-default.png?t=N7T8http://suzee.blog.csdn.net/

本文重点讲解原理!如要看批量数据处理的实战请关注下文(后续补充敬请关注):

实例应用:数据清洗和转换

使用Spring Batch清洗和转换数据

实例应用:数据导入和导出

使用Spring Batch导入和导出数据

实例应用:批处理定时任务

使用Spring Batch实现定时任务

目录

实例应用:数据清洗和转换

使用Spring Batch清洗和转换数据

实例应用:数据导入和导出

使用Spring Batch导入和导出数据

实例应用:批处理定时任务

使用Spring Batch实现定时任务

介绍Spring Batch

Spring Batch入门

解析

需求缔造:假设我们有一个需求,需要从一个CSV文件中读取学生信息,对每个学生的成绩进行转换和校验,并将处理后的学生信息写入到一个数据库表中。

数据处理

扩展Spring Batch

自定义读取器、写入器和处理器

 与其他Spring项目的集成

与Spring Integration的集成:

与Spring Cloud Task的集成:


介绍Spring Batch

Spring Batch是一个基于Java的开源批处理框架,用于处理大规模、重复性和高可靠性的任务。它提供了一种简单而强大的方式来处理批处理作业,如数据导入/导出、报表生成、批量处理等。

什么是Spring Batch?

Spring Batch旨在简化批处理作业的开发和管理。它提供了一种可扩展的模型来定义和执行批处理作业,将作业划分为多个步骤(Step),每个步骤又由一个或多个任务块(Chunk)组成。通过使用Spring Batch,可以轻松处理大量的数据和复杂的业务逻辑。

Spring Batch的特点和优势

  1. 可扩展性和可重用性:Spring Batch采用模块化的设计,提供了丰富的可扩展性和可重用性。可以根据具体需求自定义作业流程,添加或删除步骤,灵活地适应不同的批处理场景。

  2. 事务管理:Spring Batch提供了强大的事务管理机制,确保批处理作业的数据一致性和完整性。可以配置事务边界,使每个步骤或任务块在单独的事务中执行,保证了作业的可靠性。

  3. 监控和错误处理:Spring Batch提供了全面的监控和错误处理机制。可以通过监听器和回调函数来监控作业的执行情况,处理错误和异常情况,以及记录和报告作业的状态和指标。

  4. 并行处理:Spring Batch支持并行处理,可以将作业划分为多个独立的线程或进程来执行,提高作业的处理速度和效率。

Spring Batch入门

1. 安装和配置Spring Batch

首先,确保你的Java开发环境已经安装并配置好。然后,可以使用Maven或Gradle等构建工具来添加Spring Batch的依赖项到你的项目中。详细的安装和配置可以参考Spring Batch的官方文档。

2. 创建第一个批处理作业

在Spring Batch中,一个批处理作业由一个或多个步骤组成,每个步骤又由一个或多个任务块组成。下面是一个简单的示例,演示如何创建一个简单的批处理作业:

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("Hello, Spring Batch!");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Job job(Step step1) {
        return jobBuilderFactory.get("job")
                .start(step1)
                .build();
    }
}

解析

首先使用@Configuration@EnableBatchProcessing注解将类标记为Spring Batch的配置类。然后,使用JobBuilderFactoryStepBuilderFactory创建作业和步骤的构建器。在step1方法中,定义了一个简单的任务块,打印"Hello, Spring Batch!"并返回RepeatStatus.FINISHED。最后,在job方法中,使用jobBuilderFactory创建一个作业,并将step1作为作业的起始步骤。

3. 理解Job、Step和任务块

  • Job(作业):作业是一个独立的批处理任务,由一个或多个步骤组成。它描述了整个批处理过程的流程和顺序,并可以有自己的参数和配置。

  • Step(步骤块):步骤是作业的组成部分,用于执行特定的任务。一个作业可以包含一个或多个步骤,每个步骤都可以定义自己的任务和处理逻辑。

  • 任务块(Chunk):任务块是步骤的最小执行单元,用于处理一定量的数据。任务块将数据分为一块一块进行处理,可以定义读取数据、处理数据和写入数据的逻辑。

需求缔造:
假设我们有一个需求,需要从一个CSV文件中读取学生信息,对每个学生的成绩进行转换和校验,并将处理后的学生信息写入到一个数据库表中。

数据处理

  • 数据读取和写入:Spring Batch提供了多种读取和写入数据的方式。可以使用ItemReader读取数据,例如从数据库、文件或消息队列中读取数据。然后使用ItemWriter将处理后的数据写入目标,如数据库表、文件或消息队列。
    首先,我们需要定义一个数据模型来表示学生信息,例如
    public class Student {
        private String name;
        private int score;
    
        // Getters and setters
        // ...
    }

    接下来,我们可以使用Spring Batch提供的FlatFileItemReader来读取CSV文件中的数据:

    @Bean
    public FlatFileItemReader<Student> studentItemReader() {
        FlatFileItemReader<Student> reader = new FlatFileItemReader<>();
        reader.setResource(new ClassPathResource("students.csv"));
        reader.setLineMapper(new DefaultLineMapper<Student>() {
            {
                setLineTokenizer(new DelimitedLineTokenizer() {
                    {
                        setNames(new String[] { "name", "score" });
                    }
                });
                setFieldSetMapper(new BeanWrapperFieldSetMapper<Student>() {
                    {
                        setTargetType(Student.class);
                    }
                });
            }
        });
        return reader;
    }

支持的数据格式和数据源

  • Spring Batch支持各种数据格式和数据源。可以使用适配器和读写器来处理不同的数据格式,如CSV、XML、JSON等。同时,可以通过自定义的数据读取器和写入器来处理不同的数据源,如关系型数据库、NoSQL数据库等。

数据转换和校验

  • Spring Batch提供了数据转换和校验的机制。可以使用ItemProcessor对读取的数据进行转换、过滤和校验。ItemProcessor可以应用自定义的业务逻辑来处理每个数据项。

      我们配置了一个FlatFileItemReader,设置了CSV文件的位置和行映射器,指定了字段分隔符和字段到模型属性的映射关系。

    接下来,我们可以定义一个ItemProcessor来对读取的学生信息进行转换和校验:

    @Bean
    public ItemProcessor<Student, Student> studentItemProcessor() {
        return new ItemProcessor<Student, Student>() {
            @Override
            public Student process(Student student) throws Exception {
                // 进行转换和校验
                if (student.getScore() < 0) {
                    // 校验不通过,抛出异常
                    throw new IllegalArgumentException("Invalid score for student: " + student.getName());
                }
                // 转换操作,例如将分数转换为百分制
                int percentage = student.getScore() * 10;
                student.setScore(percentage);
                return student;
            }
        };
    }
     

     在上述代码中,我们定义了一个ItemProcessor,对学生信息进行校验和转换。如果学生的分数小于0,则抛出异常;否则,将分数转换为百分制。

    最后,我们可以使用Spring Batch提供的JdbcBatchItemWriter将处理后的学生信息写入数据库:

    @Bean
    public JdbcBatchItemWriter<Student> studentItemWriter(DataSource dataSource) {
        JdbcBatchItemWriter<Student> writer = new JdbcBatchItemWriter<>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        writer.setSql("INSERT INTO students (name, score) VALUES (:name, :score)");
        writer.setDataSource(dataSource);
        return writer;
    }

作业调度和监控

  • 作业调度器的配置:Spring Batch提供了作业调度器来配置和管理批处理作业的执行。可以使用Spring的调度框架(如Quartz)或操作系统的调度工具(如cron)来调度作业。通过配置作业调度器,可以设置作业的触发时间、频率和其他调度参数。
     

    在上述代码中,我们配置了一个JdbcBatchItemWriter,设置了SQL语句和数据源,将处理后的学生信息批量插入数据库表中。

    最后,我们需要配置一个作业步骤来组装数据读取、处理和写入的过程:

    @Bean
    public Step processStudentStep(ItemReader<Student> reader, ItemProcessor<Student, Student> processor, ItemWriter<Student> writer) {
        return stepBuilderFactory.get("processStudentStep")
            .<Student, Student>chunk(10)
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .build();
    }

    在上述代码中,我们使用stepBuilderFactory创建了一个步骤,并指定了数据读取器、处理器和写入器。

  • 作业执行的监控和管理:Spring Batch提供了丰富的监控和管理功能。可以使用Spring Batch的管理接口和API来监控作业的执行状态、进度和性能指标。还可以使用日志记录、通知和报警机制来及时获取作业执行的状态和异常信息。
     

    最后,我们可以配置一个作业来调度执行该步骤:

    @Bean
    public Job processStudentJob(JobBuilderFactory jobBuilderFactory, Step processStudentStep) {
        return jobBuilderFactory.get("processStudentJob")
            .flow(processStudentStep)
            .end()
            .build();
    }

    我们使用jobBuilderFactory创建了一个作业,并指定了步骤来执行。

    通过以上的示例,我们演示了Spring Batch中数据读取和写入的方式,使用了FlatFileItemReader读取CSV文件,使用了JdbcBatchItemWriter将处理后的学生信息写入数据库。同时,我们使用了ItemProcessor对读取的学生信息进行转换和校验。这个例子还展示了Spring Batch对不同数据源和数据格式的支持,以及如何配置和组装作业步骤来完成整个批处理任务。

错误处理和重试机制

  • Spring Batch提供了错误处理和重试机制,以确保批处理作业的稳定性和可靠性。可以配置策略来处理读取、处理和写入过程中的错误和异常情况。可以设置重试次数、重试间隔和错误处理策略,以适应不同的错误场景和需求。
    首先,我们可以在步骤配置中设置错误处理策略。例如,我们可以使用SkipPolicy来跳过某些异常,或者使用RetryPolicy来进行重试。
    @Bean
    public Step processStudentStep(ItemReader<Student> reader, ItemProcessor<Student, Student> processor, ItemWriter<Student> writer) {
        return stepBuilderFactory.get("processStudentStep")
            .<Student, Student>chunk(10)
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .faultTolerant()
            .skip(Exception.class)
            .skipLimit(10)
            .retry(Exception.class)
            .retryLimit(3)
            .build();
    }

    我们使用faultTolerant()方法来启用错误处理策略。然后,使用skip(Exception.class)指定跳过某些异常,使用skipLimit(10)设置跳过的最大次数为10次。同时,使用retry(Exception.class)指定重试某些异常,使用retryLimit(3)设置重试的最大次数为3次。

    在默认情况下,如果发生读取、处理或写入过程中的异常,Spring Batch将标记该项为错误项,并尝试跳过或重试,直到达到跳过或重试的次数上限为止。

    此外,您还可以为每个步骤配置错误处理器,以定制化处理错误项的逻辑。例如,可以使用SkipListener来处理跳过的项,使用RetryListener来处理重试的项。
     

    @Bean
    public SkipListener<Student, Student> studentSkipListener() {
        return new SkipListener<Student, Student>() {
            @Override
            public void onSkipInRead(Throwable throwable) {
                // 处理读取过程中发生的异常
            }
    
            @Override
            public void onSkipInWrite(Student student, Throwable throwable) {
                // 处理写入过程中发生的异常
            }
    
            @Override
            public void onSkipInProcess(Student student, Throwable throwable) {
                // 处理处理过程中发生的异常
            }
        };
    }
    
    @Bean
    public RetryListener studentRetryListener() {
        return new RetryListener() {
            @Override
            public <T, E extends Throwable> boolean open(RetryContext retryContext, RetryCallback<T, E> retryCallback) {
                // 在重试之前执行的逻辑
                return true;
            }
    
            @Override
            public <T, E extends Throwable> void onError(RetryContext retryContext, RetryCallback<T, E> retryCallback, Throwable throwable) {
                // 处理重试过程中发生的异常
            }
    
            @Override
            public <T, E extends Throwable> void close(RetryContext retryContext, RetryCallback<T, E> retryCallback, Throwable throwable) {
                // 在重试之后执行的逻辑
            }
        };
    }
    
    @Bean
    public Step processStudentStep(ItemReader<Student> reader, ItemProcessor<Student, Student> processor, ItemWriter<Student> writer,
                                   SkipListener<Student, Student> skipListener, RetryListener retryListener) {
        return stepBuilderFactory.get("processStudentStep")
            .<Student, Student>chunk(10)
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .faultTolerant()
            .skip(Exception.class)
            .skipLimit(10)
            .retry(Exception.class)
            .retryLimit(3)
            .listener(skipListener)
            .listener(retryListener)
            .build();
    }

批处理最佳实践

  • 数据量控制:在批处理作业中,应注意控制数据量的大小,以避免内存溢出或处理速度过慢的问题。可以通过分块(Chunk)处理和分页读取的方式来控制数据量。

  • 事务管理:在批处理作业中,对于需要保证数据一致性和完整性的操作,应使用适当的事务管理机制。可以配置事务边界,确保每个步骤或任务块在独立的事务中执行。

  • 错误处理和日志记录:合理处理错误和异常情况是批处理作业的重要部分。应使用适当的错误处理策略、日志记录和报警机制,以便及时发现和处理问题。

  • 性能调优:在批处理作业中,应关注性能调优的问题。可以通过合理的并行处理、合理配置的线程池和适当的数据读取和写入策略来提高作业的处理速度和效率。

  • 监控和管理:对于长时间运行的批处理作业,应设置适当的监控和管理机制。可以使用监控工具、警报系统和自动化任务管理工具来监控作业的执行情况和性能指标。

扩展Spring Batch

自定义读取器、写入器和处理器

Spring Batch提供了许多扩展点,可以通过自定义读取器、写入器和处理器以及其他组件来扩展和定制批处理作业的功能。

public class MyItemReader implements ItemReader<String> {
    private List<String> data = Arrays.asList("item1", "item2", "item3");
    private Iterator<String> iterator = data.iterator();

    @Override
    public String read() throws Exception {
        if (iterator.hasNext()) {
            return iterator.next();
        } else {
            return null;
        }
    }
}

自定义写入器:

public class MyItemWriter implements ItemWriter<String> {
    @Override
    public void write(List<? extends String> items) throws Exception {
        for (String item : items) {
            // 自定义写入逻辑
        }
    }
}

自定义处理器:

public class MyItemProcessor implements ItemProcessor<String, String> {
    @Override
    public String process(String item) throws Exception {
        // 自定义处理逻辑
        return item.toUpperCase();
    }
}

批处理作业的并行处理:

Spring Batch支持将批处理作业划分为多个独立的步骤,并通过多线程或分布式处理来实现并行处理。

  1. 多线程处理:可以通过配置TaskExecutor来实现多线程处理。通过使用TaskExecutor,每个步骤可以在独立的线程中执行,从而实现并行处理。
    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        return executor;
    }
    
    @Bean
    public Step myStep(ItemReader<String> reader, ItemProcessor<String, String> processor, ItemWriter<String> writer) {
        return stepBuilderFactory.get("myStep")
                .<String, String>chunk(10)
                .reader(reader)
                .processor(processor)
                .writer(writer)
                .taskExecutor(taskExecutor())
                .build();
    }

    在上述代码中,我们通过taskExecutor()方法定义了一个线程池任务执行器,并将其配置到步骤中的taskExecutor()方法中。

  2. 分布式处理:如果需要更高的并行性和可伸缩性,可以考虑使用分布式处理。Spring Batch提供了与Spring Integration和Spring Cloud Task等项目的集成,以实现分布式部署和处理。

 与其他Spring项目的集成

  1. 与Spring Integration的集成:

首先,需要在Spring Batch作业中配置Spring Integration的消息通道和适配器。可以使用消息通道来发送和接收作业的输入和输出数据,使用适配器来与外部系统进行交互。

@Configuration
@EnableBatchProcessing
@EnableIntegration
public class BatchConfiguration {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    private MyItemReader reader;

    @Autowired
    private MyItemProcessor processor;

    @Autowired
    private MyItemWriter writer;

    @Bean
    public IntegrationFlow myJobFlow() {
        return IntegrationFlows.from("jobInputChannel")
                .handle(jobLaunchingGateway())
                .get();
    }

    @Bean
    public MessageChannel jobInputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel jobOutputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel stepInputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel stepOutputChannel() {
        return new DirectChannel();
    }

    @Bean
    public JobLaunchingGateway jobLaunchingGateway() {
        SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
        jobLauncher.setJobRepository(jobRepository());
        return new JobLaunchingGateway(jobLauncher);
    }

    @Bean
    public JobRepository jobRepository() {
        // 配置作业存储库
    }

    @Bean
    public Job myJob() {
        return jobBuilderFactory.get("myJob")
                .start(step1())
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<String, String>chunk(10)
                .reader(reader)
                .processor(processor)
                .writer(writer)
                .inputChannel(stepInputChannel())
                .outputChannel(stepOutputChannel())
                .build();
    }
}

在上述代码中,我们配置了Spring Batch作业的消息通道和适配器。myJobFlow()方法定义了一个整合流程,它从名为jobInputChannel的消息通道接收作业请求,并通过jobLaunchingGateway()方法启动作业。jobLaunchingGateway()方法创建一个JobLaunchingGateway实例,用于启动作业。

与Spring Cloud Task的集成:

首先,需要在Spring Batch作业中配置Spring Cloud Task的任务启动器和任务监听器。任务启动器用于启动和管理分布式任务,任务监听器用于在任务执行期间执行一些操作。

@Configuration
@EnableBatchProcessing
@EnableTask
public class BatchConfiguration {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    private MyItemReader reader;

    @Autowired
    private MyItemProcessor processor;

    @Autowired
    private MyItemWriter writer;

    @Bean
    public TaskConfigurer taskConfigurer() {
        return new DefaultTaskConfigurer();
    }

    @Bean
    public TaskExecutor taskExecutor() {
        return new SimpleAsyncTaskExecutor();
    }

    @Bean
    public Job myJob() {
        return jobBuilderFactory.get("myJob")
                .start(step1())
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<String, String>chunk(10)
                .reader(reader)
                .processor(processor)
                .writer(writer)
                .taskExecutor(taskExecutor())
                .build();
    }

    @Bean
    public TaskListener myTaskListener() {
        return new MyTaskListener();
    }

    @Bean
    public TaskExecutionListener myTaskExecutionListener() {
        return new MyTaskExecutionListener();
    }
}

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

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

相关文章

【Pytorch入门】常见Transforms/ __call__方法

在Python中&#xff0c;__call__方法是一个特殊方法&#xff0c;用于使对象可以像函数一样被调用。当一个对象实现了__call__方法时&#xff0c;可以直接使用括号运算符将对象作为函数调用。 通过实现__call__方法&#xff0c;可以为对象提供函数式的行为&#xff0c;使其更加…

超全Chat GPT论文修改指令

文献综述指令润色修改指令论文选题指令论文大指令研究理论指令论文致谢指令参考文献指令论文润色整体逻辑论文整体优化提问指令 1&#xff0e;文献综述指令 请你帮我写一份关于&#xff08;研究主题&#xff09;的文献综述。我的论文选题方向是 XXXX &#xff0c;我已经找到了…

Vue.js 修饰符:精准控制组件行为

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

IDEA中Maven无法下载jar包问题解决

在项目中经常会遇到jar包无法下载的问题&#xff0c;可以根据以下几种方法进行排查。 1. 排查网络连接 网络连接失败&#xff0c;会导致远程访问Maven仓库失败&#xff0c;所以应确保网络连接正常。 2. 排查Maven的配置 Maven配置文件&#xff08;settings.xml&#xff09;…

《数字图像处理(MATLAB版)》相关算法代码及其分析(3)

目录 1 对边界进行子采样 1.1 输入参数检查 1.2 处理重复坐标 1.3 计算边界最大范围 1.4 确定网格线数量 1.5 构建网格位置向量 1.6 计算曼哈顿距离 1.7 整理输出结果 1.8 返回结果 2 改变图像的存储类别 2.1 函数输入 2.2 数据类型转换 2.3 错误处理 2.4 返回结…

LabVIEW高温摩擦磨损测试系统

LabVIEW高温摩擦磨损测试系统 介绍了一个基于LabVIEW的高温摩擦磨损测试系统的软件开发项目。该系统实现高温条件下材料摩擦磨损特性的自动化测试&#xff0c;通过精确控制和数据采集&#xff0c;为材料性能研究提供重要数据支持。 项目背景 随着材料科学的发展&#xff0c;…

视觉Transformers中的位置嵌入 - 研究与应用指南

视觉 Transformer 中位置嵌入背后的数学和代码简介。 自从 2017 年推出《Attention is All You Need》以来&#xff0c;Transformer 已成为自然语言处理 (NLP) 领域最先进的技术。 2021 年&#xff0c;An Image is Worth 16x16 Words 成功地将 Transformer 应用于计算机视觉任务…

小迪安全31WEB 攻防-通用漏洞文件上传js 验证mimeuser.ini语言特性

#知识点&#xff1a; 1、文件上传-前端验证 2、文件上传-黑白名单 3、文件上传-user.ini 妙用 4、文件上传-PHP 语言特性 #详细点&#xff1a; 检测层面&#xff1a;前端&#xff0c;后端等 2、检测内容&#xff1a;文件头&#xff0c;完整性&#xff0c;二次渲染…

docker快照备份回滚

1. 安装系统 1.1 vm安装Ubuntu 参考:https://blog.csdn.net/u010308917/article/details/125157774 1.2 其他操作 添加自定义物理卷 –待补充– 1.2.1 查询可用物理卷 fdisk -l 输出如下 Disk /dev/loop0: 73.9 MiB, 77492224 bytes, 151352 sectors Units: sectors of …

Vue 项目重复点击菜单刷新当前页面

需求&#xff1a;“在当前页面点击当前页面对应的菜单时&#xff0c;也能刷新页面。” 由于 Vue 项目的路由机制是路由不变的情况下&#xff0c;对应的组件是不重新渲染的。所以重复点击菜单不会改变路由&#xff0c;然后页面就无法刷新了。 方案一 在vue项目中&#xff0c;…

英特尔/ARM/国产化EMS储能控制器解决方案

新型储能是建设新型电⼒系统、推动能源绿⾊低碳转型的重要装备基础和关键⽀撑技术&#xff0c;是实现碳达峰、碳中和⽬标的重要⽀撑。说到储能&#xff0c;大众首先想到的就是电池&#xff0c;其好坏关系到能量转换效率、系统寿命和安全等重要方面&#xff0c;但储能要想作为一…

[LeetBook]【学习日记】数组内乘积

题目 按规则计算统计结果 为了深入了解这些生物群体的生态特征&#xff0c;你们进行了大量的实地观察和数据采集。数组 arrayA 记录了各个生物群体数量数据&#xff0c;其中 arrayA[i] 表示第 i 个生物群体的数量。请返回一个数组 arrayB&#xff0c;该数组为基于数组 arrayA …

vue点击按钮同时下载多个文件

点击下载按钮根据需要的id调接口拿到返回需要下载的文件 再看返回的数据结构 数组中一个对象&#xff0c;就是一个文件&#xff0c;多个对象就是多个文件 下载函数 // 下载tableDownload(row) {getuploadInventoryDownload({ sysBatch: row.sysBatch, fileName: row.fileName…

STM32 TIM编码器接口

单片机学习&#xff01; 目录 文章目录 前言 一、编码器接口简介 1.1 编码器接口作用 1.2 编码器接口工作流程 1.3 编码器接口资源分布 1.4 编码器接口输入引脚 二、正交编码器 2.1 正交编码器功能 2.2 引脚作用 2.3 如何测量方向 2.4 正交信号优势 2.5 执行逻辑 三、编码器定时…

前端+php:实现提示框(自动消失)

效果 php部分&#xff1a;只展示插入过程 <?php//插入注册表中$sql_insert "INSERT INTO regist_user(userid,password,phone,email)VALUES (" . $_POST[UserID] . "," . CryptPass($_POST[Password]) . "," . $_POST[Phone] . ",&qu…

“而且,再加上”可以用哪个语法来表示,柯桥考级韩语学习

语法 --는/은/ㄴ 데다가 1.语法&#xff1a;는/은/ㄴ 데다가 2.表示&#xff1a;用于谓词词干和体词谓词形后, 表示在原有的状况上再加上其他情况。 3.添加&#xff1a; 4.例句&#xff1a; 当然&#xff0c;与这个语法含义相近的还有不少语法&#xff0c;有一部分是初级暂时…

【AI视野·今日NLP 自然语言处理论文速览 第八十期】Fri, 1 Mar 2024

AI视野今日CS.NLP 自然语言处理论文速览 Fri, 1 Mar 2024 Totally 67 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Loose LIPS Sink Ships: Asking Questions in Battleship with Language-Informed Program Sampling Authors G…

Libevent的使用及reactor模型

Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库&#xff0c;主要有以下几个亮点&#xff1a;事件驱动&#xff08; event-driven&#xff09;&#xff0c;高性能;轻量级&#xff0c;专注于网络&#xff0c;不如 ACE 那么臃肿庞大&#xff1b;源代码相当精炼、易读…

HTTP常用状态码详解

目录 1xx - 信息性状态码 2xx - 成功状态码 3xx - 重定向状态码 4xx - 客户端错误状态码 5xx - 服务器错误状态码 总结 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于传输超文本的应用层协议。在HTTP通信中&#xff0c;服务器和客户端之间会通过状态…

Chrome禁止自动升级

一、关闭计划任务 1、首先我们需要右键点击我的电脑&#xff0c;在打开的选项里选择管理。   2、在打开的对话框中选择任务计划程序。   3、在任务计划程序库中找到两个和chrome自动更新相关的任务计划GoogleUpdateTaskMachineCore与GoogleUpdateTaskMachineUA。     4…