SpringBoot+Activiti7工作流入门实例

news2024/9/28 20:04:28

目录

文章目录

  • 目录
  • 准备Activiti建模工具
    • 1、BPMN-js在线设计器
      • 1.1 安装
      • 1.2 使用说明
      • 1.3运行截图
    • 2、IDEA安装Activiti Designer插件
      • 2.1安装插件
      • 2.2 设置编码格式防止中文乱码
      • 2.3 截图
  • 简单工作流入门实例
    • 1. 新建Spring Boot工程
    • 2. 引入Activiti相关依赖
      • 添加版本属性
      • 指定仓库
      • 添加依赖
      • 完整的pom文件
    • 3.配置数据库
      • 添加MySQL依赖
      • 修改配置文件
      • 4.配置application.yml文件清单
    • 4启动SpringBoot
    • 5.新建流程
      • 绘制流程
      • 生成png图像
      • 部署工作流程
      • 启动一个流程实例
      • 任务查询
      • 任务处理
    • 查询历史

准备Activiti建模工具

这里可以使用两种建模工具:bpmn.js和 IDEA的插件

1、BPMN-js在线设计器

bpmn.js是一个BPMN2.0渲染工具包和web建模器。

1.1 安装

需要使用到nodejs环境
1.1. 1 切换到项目目录下运行 npm install 安装依赖,也可以使用

cnpm  install

1.1.2. 运行 npm run dev 启动

npm run dev

在这里插入图片描述

1.2 使用说明

可在页面进行拖拽设计 activiti 的流程图,支持导出 bpmn 流程图和 svg 图片

1.3运行截图

在这里插入图片描述

2、IDEA安装Activiti Designer插件

2.1安装插件

在IDEA的File菜单中找到子菜单”Settings”,后面我们再选择左侧的“plugins”菜单,搜索actiBPM插件。
在这里插入图片描述

重启IDEA就可以使用了。

2.2 设置编码格式防止中文乱码

更改idea配置文件, 否则工作流中输入中文会乱码

  1. 进入idea安装目录的bin文件夹下, 找到idea.exe.vmoptions与idea64.exe.vmoptions两个文件
  2. 在两个文件的最后加入 -Dfile.encoding=UTF-8

2.3 截图

在这里插入图片描述

简单工作流入门实例

这里使用 SpringBoot+Activiti 实现一个最基础的工作流

1. 新建Spring Boot工程

打开IDEA创建一个SpringBoot项目

输入组织名,包名,打包方式jar,创建Maven项目,java版本8

选择要使用的组件,你可以在这里选择自己需要的,在生成最终的项目时会自动加入到maven中。

2. 引入Activiti相关依赖

添加版本属性

<properties>
    <java.version>1.8</java.version>
    <activiti.version>7.1.0.M6</activiti.version>
</properties>
声明依赖版本
<!-- 声明依赖-->
<dependencyManagement>
    <dependencies>
        <!-- 声明activiti依赖的版本-->
        <dependency>
            <groupId>org.activiti.dependencies</groupId>
            <artifactId>activiti-dependencies</artifactId>
            <version>${activiti.version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>

指定仓库

添加私服仓库地址,不然容易出现无法下载包的问题

<!--指定仓库-->
<repositories>
    <!-- activiti仓库  -->
    <repository>
        <id>alfresco</id>
        <name>Activiti Releases</name>
        <url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
    </repository>
</repositories>

添加依赖

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
</dependency>

完整的pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ts</groupId>
    <artifactId>springboot_activiti_demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_activiti_demo</name>
    <description>Spring Boot + Activiti实例</description>

    <properties>
        <java.version>1.8</java.version>
        <activiti.version>7.1.0.M6</activiti.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

       <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-spring-boot-starter</artifactId>
           <version>${activiti.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- 生成图片 -->
        <!--<dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-image-generator</artifactId>
        </dependency>-->

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
            <scope>runtime</scope>
        </dependency>

        <!-- 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>


        <!-- Thymeleaf依赖 -->
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>-->

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!--指定仓库-->
    <repositories>

        <!-- activiti仓库  -->
        <repository>
            <id>alfresco</id>
            <name>Activiti Releases</name>
            <url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

    <!-- 声明依赖-->
    <dependencyManagement>
        <dependencies>
            <!-- 声明activiti依赖的版本-->
            <!--<dependency>
                <groupId>org.activiti.dependencies</groupId>
                <artifactId>activiti-dependencies</artifactId>
                <version>${activiti.version}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>-->
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.配置数据库

添加MySQL依赖

在正常使用中,一般系统会有自己的数据库,而不会采用Activiti默认内存的数据库H2,这里使用MySQL数据库。

<dependency>
<groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
    <scope>runtime</scope>
</dependency>

修改配置文件

修改application.yml文件

spring :
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC&nullCatalogMeansCurrent=true
    #url: jdbc:mysql://127.0.0.1:3306/activiti?useUnicode=true&characterEncoding=utf-8&serverTimezone=CTT&useSSL=false
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
    initialization-mode: always
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500


Activiti相关配置
修改application.yml文件

activiti:
  # 自动建表
  #database-schema: activiti
  database-schema-update: true
  history-level: full
  db-history-used: true
database-schema-update表示启动时检查数据库表,不存在则创建
history-level表示哪种情况下使用历史表,这里配置为full表示全部记录历史,方便绘制流程图
db-history-used为true表示使用历史表,如果不配置,历史表没有建立,则流程图及运行节点无法展示

4.配置application.yml文件清单

spring :
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/testactiviti?useUnicode=true&characterEncoding=utf-8&serverTimezone=CTT&useSSL=false
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
    initialization-mode: always
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

#  mvc:
    # 静态资源
    # static-path-pattern: /static/**

#  thymeleaf:
#    mode: HTML
#    encoding: utf-8
#    #关闭缓存
#    cache: false

  activiti:
    #1.flase: 默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
    #2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
    #3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
    #4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
    database-schema-update: true
    #记录历史等级 可配置的历史级别有none, activity, audit, full
    history-level: full
    #检测历史表是否存在
    db-history-used: true
    #校验流程文件,默认校验resources下的processes文件夹里的流程文件
    check-process-definitions: false

4启动SpringBoot

启动SpringBoot工程,生成表(25张)

5.新建流程

创建bpmn工作流文件
首先选中存放图形的目录(选择resources下的bpmn目录),点击菜单:New-BpmnFile

绘制流程

在这里插入图片描述

绘制完成以后修改id和name,然后指定任务负责人
在这里插入图片描述

生成png图像

复制bpmn_test.bpmn并更名bpmn_test.xml
在这里插入图片描述
在这里插入图片描述

右键选中Diagrams–》show BPMN2.0
在这里插入图片描述

点击Export to file ,然后放在resources下的bpmn目录下就可以了。
在这里插入图片描述
在这里插入图片描述

部署工作流程

要将上边绘制的图形即流程定义(.bpmn)部署在工作流程引擎activiti中
创建一个测试类ActivitiTest

package com.ts;

//import org.activiti.api.process.runtime.ProcessRuntime;
//import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 *  流程测试类
 * @author ZQ
 * @date 2020/11/23 0019 15:16
 **/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiTest {

    //@Autowired
    //private ProcessRuntime processRuntime;

    //@Autowired
    //private ProcessEngine processEngine;

    @Autowired
    private RepositoryService repositoryService;

    private static final Logger log = LoggerFactory.getLogger(ActivitiTest.class);
    /**
     * 流程定义的部署
     * activiti相关表
     * act_re_deployment  部署信息
     * act_re_procdef     流程定义的一些信息
     * act_ge_bytearray   流程定义的bpmn文件及png文件
     */
    @Test
    public void createDeploy() {
        //RepositoryService repositoryService = processEngine.getRepositoryService();

        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("bpmn/bpmn_test.bpmn")//添加bpmn资源
                .addClasspathResource("bpmn/bpmn_test.png")
                .name("请假申请单流程")
                .deploy();

        log.info("流程部署id:" + deployment.getName());
        log.info("流程部署名称:" + deployment.getId());
    }
}

执行此操作后activiti会将上边代码中指定的bpm文件和图片文件保存在activiti数据库。

启动一个流程实例

流程定义部署在activiti后就可以通过工作流管理业务流程了,也就是说上边部署的请假申请流程可以使用了。
针对该流程,启动一个流程表示发起一个新的请假申请单,这就相当于java类与java对象的关系,类定义好后需要new创建一个对象使用,当然可以new多个对象。
对于请假申请流程,张三发起一个请假申请单需要启动一个流程实例,李四发起一个请假单也需要启动一个流程实例。

/**
 * 2
 * 启动流程实例:
 * 前提是先已经完成流程定义的部署工作
 * <p>
 * 背后影响的表:
 * act_hi_actinst     已完成的活动信息
 * act_hi_identitylink   参与者信息
 * act_hi_procinst   流程实例
 * act_hi_taskinst   任务实例
 * act_ru_execution   执行表
 * act_ru_identitylink   参与者信息
 * act_ru_task  任务
 */
@Test
public void startProcessInstance() {
    RuntimeService runtimeService = processEngine.getRuntimeService();
    //启动流程实例
    ProcessInstance processInstance = runtimeService
            .startProcessInstanceByKey("myProcess_1");//这里的key就是流程图的ID

    log.info("流程定义ID:" + processInstance.getProcessDefinitionId());
    log.info("流程实例ID:" + processInstance.getId());
}

任务查询

流程启动后,各各任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。

/**
 * 3
 * 查询当前用户的任务列表
 */
@Test
public void findPersonalTaskList() {
    TaskService taskService = processEngine.getTaskService();

    //流程启动后,各各任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。
    //根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
    List<Task> taskList = taskService.createTaskQuery()
            //流程实例key
            .processDefinitionKey("myProcess_1")
            //查询谁的任务
            .taskAssignee("张三")
            .list();

    for (Task task : taskList) {
        System.out.println("-----------------------");
        System.out.println("流程实例ID:" + task.getProcessInstanceId());
        System.out.println("执行对象ID:" + task.getExecutionId ());
        System.out.println("流程定义ID:" + task.getProcessDefinitionId ());

        System.out.println("任务ID:" + task.getId());
        System.out.println("任务名称:" + task.getName());
        System.out.println("任务负责人:" + task.getAssignee());
        System.out.println("任务的创建时间:" + task.getCreateTime ());
    }
}

任务处理

任务负责人查询待办任务,选择任务进行处理,完成任务。

/**
 * 3
 * 处理当前用户的任务
 * 背后操作的表:
 * act_hi_actinst
 * act_hi_identitylink
 * act_hi_taskinst
 * act_ru_identitylink
 * act_ru_task
 */
@Test
public void completeTask() {
    String processDefinitionKey = "myProcess_1";
    TaskService taskService = processEngine.getTaskService();

    //查询任务
    Task task = taskService
            .createTaskQuery()
            .processDefinitionKey(processDefinitionKey)
            .taskAssignee("张三")
            .singleResult();
    if(task != null){
        //处理任务,结合当前用户任务列表的查询操作的话
        taskService.complete(task.getId());
        log.info("处理完成当前用户的任务");
    }else{
        log.info("当前用户暂无任务");
    }
}

查询历史

/*
 * 查询历史
 * @author zq
 * @param *[]
 * @return void
 **/
@Test
public void queryHistory() {
    HistoryService historyService = processEngine.getHistoryService();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //查询流程定义
    ProcessDefinitionQuery processDefinitionQuery =
            repositoryService.createProcessDefinitionQuery();
    String processDefinitionKey = "myProcess_1";
    //遍历查询结果
    ProcessDefinition processDefinition =
            processDefinitionQuery
            .processDefinitionKey(processDefinitionKey)
            .orderByProcessDefinitionVersion().desc().singleResult();

    if (processDefinition != null) {
        HistoricActivityInstanceQuery query = historyService
                .createHistoricActivityInstanceQuery();

        List<HistoricActivityInstance> list =
                query.processDefinitionId(processDefinition.getId())
                .orderByHistoricActivityInstanceStartTime().asc().list();//排序StartTime

        for (HistoricActivityInstance ai : list) {
            System.out.println("历史活动ID:" + ai.getActivityId());
            System.out.println("历史活动Name:" + ai.getActivityName());
            System.out.println("流程定义ID" + ai.getProcessDefinitionId());
            System.out.println("流程实例ID" + ai.getProcessInstanceId());
            System.out.println("==============================");
        }
    }
}

执行结果
在这里插入图片描述

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

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

相关文章

10.1软件工程知识详解上

软件工程概述 软件开发生命周期 软件定义时期&#xff1a;包括可行性研究和详细需求分析过程&#xff0c;任务是确定软件开发工程必须完成的总目标&#xff0c;具体可分成问题定义、可行性研究、需求分析等。软件开发时期&#xff1a;就是软件的设计与实现&#xff0c;可分成…

一文上手SpringSecuirty【六】

自定义认证流程完成之后,前端收到了后端生成的token,那么在之后的所有请求当前,都必须携带token.作为服务器来说,得验证这个token,是否合法. 一、验证token是否合法 1.1 OncePerRequestFilter过滤器 OncePerRequestFilter是 Spring 框架中的一个过滤器&#xff0c;用于确保在…

强化-极限

不利于元素及时提现 要学会构建导数&#xff08;按照定义&#xff09;

老挝旅游如何解决沟通问题?《老挝语翻译通》app支持语音识别翻译功能,能有效解决语言不同的痛点

老挝&#xff0c;一个东南亚的神秘国度&#xff0c;以其独特的文化和语言吸引着全球旅行者和语言爱好者。为了帮助大家更好地了解和学习老挝语&#xff0c;我们推出了《老挝语翻译通》App&#xff0c;一款集翻译、学习、旅游于一体的多功能工具。 功能亮点 实时翻译&#xff1…

滚珠丝杆如何安装滚珠?

滚珠丝杆安装滚珠是一门非常专业的知识&#xff0c;其安装过程需要细致且精确&#xff0c;这样才能确保其后续运行的顺畅与稳定。以下是安装滚珠的详细步骤&#xff1a; 一、准备工作 确保工作区域清洁无尘&#xff0c;准备合适的螺丝刀、扳手等工具&#xff0c;以及适量的润滑…

win10文件共享设置 - 开启局域网文件共享 - “您没有权限访问,请与网络管理员联系请求访问权限”解决方案

实现步骤&#xff1a; 1、在“网络和共享中心”关闭“密码保护的共享” 2、在“启用和关闭windows功能”中开启SMB文件共享支持。 3、在磁盘安全选项中添加“everyone”用户&#xff08;重点&#xff01;&#xff09; 详细操作&#xff1a; https://blog.csdn.net/Skyirm/a…

怎么不用付费直接编辑pdf?5款pdf在线编辑器免费推荐给你!

在我们日常工作中&#xff0c;可能会经常需要直接编辑修改pdf内容&#xff0c;例如&#xff0c;在将文档发送给其它人之前&#xff0c;您可能需要进行一些修改&#xff1b;或者当扫描的文本出现错误时&#xff0c;您也需要进行修正。此时&#xff0c;如果有一款在线编辑器&…

【笔记】7.1 小功率整流滤波电路

一、 单相整流电路 任务&#xff1a;把正弦电压转变为单向脉动的电压。 类型&#xff1a;有单相半波、全波、桥式和倍压整流等。 分析方法&#xff1a;为分析简单起见&#xff0c;把二极管当作理想元件处理&#xff0c;即二极管的正向导通电阻为零&#xff0c;反向电阻为无穷…

北斗三号多模对讲机TD70:公专网融合、数模一体、音视频调度,推动应急通信效能升级

随着国家对应急通信和精准定位技术的重视程度不断提高&#xff0c;相关技术和设备的研发与应用也得到了迅猛发展。特别是在边防巡逻、林业巡防、海上作业等领域&#xff0c;通信设备的可靠性和功能性直接关系到人员的生命安全和任务的成功完成。 近年来&#xff0c;我国政府高度…

软件测试面试100问(含答案+文档)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、问&#xff1a;你在测试中发现了一个bug&#xff0c;但是开发经理认为这不是一个bug&#xff0c;你应该怎样解决? 首先&#xff0c;将问题提交到缺陷管理库里…

py 元组,列表,函数的学习和使用

代码 下面两个Python脚本&#xff0c;分别解决问题。 1. 脚本 test1.ipynb # 创建一个元组 t1 和一个空列表 list1 t1 (1, 2, R, py, Matlab) list1 [] # 使用 while 循环&#xff0c;将 t1 中的元素添加到 list1 i 0 while i < len(t1): list1.append(t1[i]) …

计241 作业2:C程序设计初步

问题 A: C语言实验——计算AB&#xff08;顺序结构&#xff09; 思路讲解: 这个直接计算ab就好&#xff0c;没有什么困难的&#xff0c;用来熟悉环境最适合不过 代码实现: #include<stdio.h>int main() {int a,b;scanf("%d %d",&a,&b);printf("…

时间技能物品竞品抢拍拍卖发布h5公众号小程序开源版开发

时间技能物品竞品抢拍拍卖发布h5公众号小程序开源版开发 利用新型营销方式&#xff0c;将闲置的物品通过拍卖&#xff0c;让价格一提再提让用户趣在其中&#xff0c;营造一种不一样的购物体验! 拍卖列表页 列表页采用多分类&#xff0c;广告轮播及流动公告和拍卖商品列表组成…

2024年9月26日 linux笔记

1、提示符 1.1 提示符 1.2 命令格式 1.3 路径 2、指令 2.1 pwd 显示当前路径 2.2 cd 切换路径、改变路径 2.3 mkdir 创建目录 [-p] 创建目录及子目录 mkdir -p dir1/dir2 2.4 rmdir 删除目录 &#xff08;注&#xff1a;不能删除空目录&#xff09; 2.5 ls 显示当前目录文…

设计模式之策略设计模式

一、状态设计模式概念 策略模式&#xff08;Strategy&#xff09; 是一种行为设计模式&#xff0c; 它能让你定义一系列算法&#xff0c; 并将每种算法分别放入独立的类中&#xff0c; 以使算法的对象能够相互替换。 适用场景 当你想使用对象中各种不同的算法变体&#xff0c; …

构建Python机器学习模型的8个步骤

本文旨在系统地介绍构建机器学习模型的基本步骤&#xff0c;并通过一个具体的实战案例——股票价格预测&#xff0c;展示这些步骤的实际应用。通过遵循这些步骤&#xff0c;读者可以更好地理解和掌握机器学习模型构建的全过程。 步骤一&#xff1a;定义问题 首先&#xff0c;我…

【移植】一种快速移植OpenHarmony Linux内核的方法

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 移植概述 本文面向希望将 OpenHarmony 移植到三方芯片平台硬件的开…

【4.6】图搜索算法-DFS和BFS解合并二叉树

一、题目 给定两个二叉树&#xff0c;想象当你将它们中的一个覆盖到另一个上时&#xff0c;两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是 如果两个节点重叠&#xff0c;那么将他们的 值相加作为节点合并后的新值&#xff0c;否则不为 NUL L…

如何选择主数据管理系统平台

企业数据量呈现爆炸式增长&#xff0c;多系统并存、数据分散的现象日益普遍。主数据管理&#xff08;MDM&#xff09;作为确保企业核心业务数据准确、一致、完整的关键环节&#xff0c;对于企业的决策制定、业务流程优化和数据分析至关重要。而选择一个合适的主数据管理系统平台…

Vivado时序报告之CDC详解大全

目录 一、前言 二、Report CDC 2.1 Report CDC 2.2 配置界面 2.3 CDC报告 2.3.1 General Information 2.3.2 Summary 2.3.3 CDC Details 2.4 Waiver 2.4.1 设置Waiver 2.4.2 报告查看 2.4.3 去除Waiver设置 三、工程设计 四、参考资料 一、前言 前面已经针对…