Activiti7_使用

Activiti7_使用

  • 一、Activiti7
  • 二、绘制工作流
  • 三、通过代码部署流程,再对流程进行实例化,完整运行一遍流程即可
  • 四、在springbooot中使用


一、Activiti7

  1. 为了实现后端的咨询流转功能,学习Activiti7,记录下使用的过程及遇到的问题

二、绘制工作流

  1. 使用spring3的后端项目为基础,开发工具idea 2023.3.2,jdk,jdk17。
    点此链接link去idea官网下载插件Activiti BPMN,在idea的Settings里Plugins使用install plugin from disk把刚才的jar包导进去
  2. 在bpmn文件夹下创建bpmn文件:
    !在这里插入图片描述
  3. 使用插件以画图形式编辑bpmn:
    在这里插入图片描述
    主要使用了三种部件:开始、任务、结束在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
任务的内容填写如下,连线按住右上角的箭头拖拽到目标即可,里面的${user}表明设置为user的变量,一会可以在使用的时候绑定用户:
在这里插入图片描述
其中的分支路线我们直接使用两个互斥条件判断,不使用排他网关:
在这里插入图片描述在这里插入图片描述

排他网关(也叫异或(XOR)网关,或叫基于数据的排他网关),用来在流程中实现决策。 当流程执行到这个网关,所有分支都会判断条件是否为 true,如果为 true 则执行该分支,注意,排他网关只会选择一个为 true 的分支执行。 (即使有两个分支条件都为 true, 排他网关也会只选择一条分支去执行)。如果从网关出去的线所有条件都不满足则系统抛出异常。说明 :经过排他网关必须要有一条且只有一条分支走。
bpmn文件绘制完成了,保存成同名png文件:在这里插入图片描述

  1. 完整的bpmn代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="consult" name="consult" isExecutable="true">
    <startEvent id="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1"/>
    <userTask id="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4" name="用户填写咨询表单" activiti:assignee="${user}">
      <documentation>用户填写咨询表单</documentation>
    </userTask>
    <userTask id="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854" name="管理员指定业务人员" activiti:assignee="${admin}">
      <documentation>管理员指定业务人员</documentation>
    </userTask>
    <userTask id="sid-7b539102-6d65-479a-9958-5259a84c28b1" name="业务人员回复" activiti:assignee="${busPerson}">
      <documentation>业务人员回复</documentation>
    </userTask>
    <userTask id="sid-3af84618-4ba9-4686-a97f-6db4da96e916" name="管理员决定是否公示" activiti:assignee="${admin}">
      <documentation>管理员决定是否公示</documentation>
    </userTask>
    <endEvent id="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"/>
    <sequenceFlow id="sid-c2da4d94-8eac-4acd-9cb0-16328237a136" sourceRef="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1" targetRef="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4"/>
    <sequenceFlow id="sid-5be6635f-b5ef-4e0e-98af-1b35c6e085ae" sourceRef="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4" targetRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854"/>
    <sequenceFlow id="sid-5dc1e8b5-e2bc-45b7-b559-bffe2d3b5c24" sourceRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854" targetRef="sid-7b539102-6d65-479a-9958-5259a84c28b1"/>
    <sequenceFlow id="sid-c3c3594c-d7d1-462f-b057-59b12dbeb190" sourceRef="sid-3af84618-4ba9-4686-a97f-6db4da96e916" targetRef="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"/>
    <sequenceFlow id="sid-8a860827-e9ad-4c62-b931-939d312ddcd8" sourceRef="sid-7b539102-6d65-479a-9958-5259a84c28b1" targetRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854">
      <conditionExpression>${evection.num&gt;1}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-f4dc4277-d16a-415e-9cac-fe51d1c6ee65" sourceRef="sid-7b539102-6d65-479a-9958-5259a84c28b1" targetRef="sid-3af84618-4ba9-4686-a97f-6db4da96e916">
      <conditionExpression>${evection.num&lt;=1}</conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_consult">
    <bpmndi:BPMNPlane bpmnElement="consult" id="BPMNPlane_consult">
      <bpmndi:BPMNShape id="shape-b1791cfb-c3c9-42a9-9bd8-b7e0a8906f99" bpmnElement="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1">
        <omgdc:Bounds x="-15.0" y="-120.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-33324ea7-5905-4b2a-b615-2bfe666a0117" bpmnElement="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4">
        <omgdc:Bounds x="-50.0" y="-60.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-955afe5f-f9b7-40f0-887f-70aeb5afc173" bpmnElement="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854">
        <omgdc:Bounds x="-50.0" y="40.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-7a2e9e19-c268-4a46-af9c-aa6621dd9b86" bpmnElement="sid-7b539102-6d65-479a-9958-5259a84c28b1">
        <omgdc:Bounds x="-50.0" y="150.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-86aead71-8e5b-4de3-8d8c-ca5f0dcc63ea" bpmnElement="sid-3af84618-4ba9-4686-a97f-6db4da96e916">
        <omgdc:Bounds x="-50.0" y="255.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-1d13b250-9f5c-42db-a745-482b2c9acf56" bpmnElement="sid-bd329163-e466-4ca7-bad1-9b95787e28a6">
        <omgdc:Bounds x="-15.0" y="360.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-c60fd374-56ca-4630-9f88-c9d61baa048b" bpmnElement="sid-c2da4d94-8eac-4acd-9cb0-16328237a136">
        <omgdi:waypoint x="0.0" y="-90.0"/>
        <omgdi:waypoint x="0.0" y="-60.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-4a1da47a-a9b5-4db2-a8a9-002220e5c52a" bpmnElement="sid-5be6635f-b5ef-4e0e-98af-1b35c6e085ae">
        <omgdi:waypoint x="0.0" y="20.0"/>
        <omgdi:waypoint x="0.0" y="40.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-3d9c4ead-a6cd-4aa2-82c7-ad1f20171327" bpmnElement="sid-5dc1e8b5-e2bc-45b7-b559-bffe2d3b5c24">
        <omgdi:waypoint x="0.0" y="120.0"/>
        <omgdi:waypoint x="0.0" y="150.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-2116f8bb-51a7-4c43-a48b-7c4954868724" bpmnElement="sid-c3c3594c-d7d1-462f-b057-59b12dbeb190">
        <omgdi:waypoint x="0.0" y="335.0"/>
        <omgdi:waypoint x="0.0" y="360.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-ce0e6fc3-032f-4333-83ec-7807846b046f" bpmnElement="sid-8a860827-e9ad-4c62-b931-939d312ddcd8">
        <omgdi:waypoint x="-50.0" y="190.0"/>
        <omgdi:waypoint x="-125.0" y="135.0"/>
        <omgdi:waypoint x="-50.0" y="80.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-87fa2036-1930-4551-bede-92f275696c68" bpmnElement="sid-f4dc4277-d16a-415e-9cac-fe51d1c6ee65">
        <omgdi:waypoint x="0.0" y="230.0"/>
        <omgdi:waypoint x="0.0" y="242.5"/>
        <omgdi:waypoint x="0.0" y="255.0"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>


三、通过代码部署流程,再对流程进行实例化,完整运行一遍流程即可

需要序列化一个evection:在这里插入图片描述

package com.sumo.ipd;

import java.io.Serializable;

public class Evection implements Serializable {
    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    private int num;
}

在test里面创建ActivitiDemo类,内容:

package com.sumo.ipd;

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class ActivitiDemo {

    /**
     * 部署流程定义测试,查询,删除
     */
    @Test
    public void DeployTest() {
        // 1. 创建ProcessEngine流程引擎对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 3、使用RepositoryService进行部署,定义一个流程名字,把bpmn和png部署到数据库中
        Deployment deployment = repositoryService.createDeployment()    // 创建一个部署流程
                .name("咨询流程")                                    // 给部署流程命名
                .addClasspathResource("bpmn/consult.bpmn20.xml")        // 添加类路径下的资源文件
                .addClasspathResource("bpmn/consult.png")
                .deploy();                                                // 执行流程部署
        // 4、输出部署信息
        System.out.println("流程部署id:" + deployment.getId());
        System.out.println("流程部署名称:" + deployment.getName());
    }

    @Test
    public void queryProceccDefinition() {
        // 流程定义key
        String processDefinitionKey = "consult";
        // 创建ProcessEngine流程引擎对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 查询流程定义
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        //遍历查询结果
        List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(processDefinitionKey).orderByProcessDefinitionVersion().desc().list();
        for (ProcessDefinition processDefinition : list) {
            System.out.println("------------------------");
            System.out.println(" 流 程 部 署 id : " +processDefinition.getDeploymentId());
            System.out.println("流程定义id: " + processDefinition.getId());
            System.out.println("流程定义名称: " + processDefinition.getName());
            System.out.println("流程定义key: " + processDefinition.getKey());
            System.out.println("流程定义版本: " + processDefinition.getVersion());
        }
    }

    @Test
    public void deleteDeployment() {
        // 流程部署id
        String deploymentId = "47501";
        // 通过流程引擎获取repositoryService
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        删除启动的流程实例
        RuntimeService runtimeService = processEngine.getRuntimeService();
        runtimeService.deleteProcessInstance("50001","用户撤销");
                //删除流程定义, 如果该流程定义已有流程实例启动则删除时出错
        //repositoryService.deleteDeployment(deploymentId);
        //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设
        //置为false非级别删除方式,如果流程
        repositoryService.deleteDeployment(deploymentId, true);
    }




    /**
     * 启动流程实例
     */
    @Test
    public void startProcessTest() {
        //businessKey用于绑定外部任务表单的id
        String businessKey = "1";
        // 1、创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2、获取RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();

        // 流程变量的map
        Map<String, Object> variables = new HashMap<>();


        // 设定任务的负责人
        variables.put("user", "523097198902120431");
        variables.put("admin", "123456");
        variables.put("busPerson", "123456789");

        Evection evection = new Evection();
        evection.setNum(3);
        // 把流程变量的pojo放入map
        variables.put("evection",evection);


        // 3、根据流程定义Id启动流程,并获取流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("consult", businessKey, variables);

        // 输出内容
        System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例id:" + processInstance.getId());
        System.out.println("当前活动Id:" + processInstance.getActivityId());
        System.out.println("businessKey==" + processInstance.getBusinessKey());
    }


    /**
     * 查询当前个人待执行的任务
     */
    public void findTaskListTest(String assignee) {
        // 1.创建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2.获取TaskService
        TaskService taskService = processEngine.getTaskService();
        // 3.根据流程key 和 任务负责人 查询任务
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("consult")        //流程Key
                .taskAssignee(assignee)                    //只查询当前任务负责人的任务
                .list();
        Task task = taskService.createTaskQuery()
//                .processInstanceId("15001")            //流程实例id
                .processDefinitionKey("consult")     //流程Key
                .taskAssignee(assignee)                 //只查询当前任务负责人的任务
                .singleResult();
        String processInstanceId = task.getProcessInstanceId();
        // 2、获取RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String businessKey = processInstance.getBusinessKey();

//        list.forEach(task -> {
            System.out.println("-----------------------------------------");
            System.out.println("流程实例id:" + task.getProcessInstanceId());
            System.out.println("任务id:" + task.getId());
            System.out.println("任务负责人:" + task.getAssignee());
            System.out.println("任务名称:" + task.getName());
            System.out.println("businessKey==" + businessKey);
//        });

        Evection eve = (Evection)taskService.getVariable(task.getId(), "evection");
        System.out.println(eve.getNum());
        System.out.println("获取流程变量成功");
    }


    /**
     * 完成个人代办任务及查询下一步
     */
    @Test
    public void completTaskTest() {
        findTaskListTest("523097198902120431");
        completTask("523097198902120431");

        findTaskListTest("123456");
        completTask2("123456");

        findTaskListTest("123456789");
        completTask("123456789");

        findTaskListTest("123456");
        completTask("123456");
    }

    /**
     * 普通的完成任务
     * @param assignee
     */
    public void completTask(String assignee) {
        // 1.创建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2. 获取TaskService实例
        TaskService taskService = processEngine.getTaskService();
        // 3.根据流程key 和 任务的负责人 查询任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("consult")     //流程Key
                .taskAssignee(assignee)                 //只查询当前任务负责人的任务
                .singleResult();

        System.out.println("流程实例id:" + task.getProcessInstanceId());
        System.out.println("任务id:" + task.getId());
        System.out.println("任务负责人:" + task.getAssignee());
        System.out.println("任务名称:" + task.getName()+" 完成!");
        
        // 4.完成待办任务,参数:任务id
        taskService.complete(task.getId());
    }

    /**
     * 在完成任务时修改变量调整分支走向
     * @param assignee
     */
    public void completTask2(String assignee) {
        // 1.创建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2. 获取TaskService实例
        TaskService taskService = processEngine.getTaskService();
        // 3.根据流程key 和 任务的负责人 查询任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("consult")     //流程Key
                .taskAssignee(assignee)                 //只查询当前任务负责人的任务
                .singleResult();

        System.out.println("流程实例id:" + task.getProcessInstanceId());
        System.out.println("任务id:" + task.getId());
        System.out.println("任务负责人:" + task.getAssignee());
        System.out.println("任务名称:" + task.getName()+" 完成!");

        // 流程变量的map
        Map<String, Object> variables = new HashMap<>();

        Evection evection = new Evection();
        evection.setNum(1);
        // 把流程变量的pojo放入map
        variables.put("evection",evection);
        // 4.完成待办任务,参数:任务id
        taskService.complete(task.getId(),variables);

    }


    /**
     * 如果一个流程中有多个任务,可以用list
     */
    @Test
    public void completeTask3() {
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取操作任务的服务 TaskService
        TaskService taskService = processEngine.getTaskService();
        // 完成 经理 '李四' 的任务
        List<Task> tasks = taskService.createTaskQuery()
                .processDefinitionKey("evection")
                .taskAssignee("李四")
                .list();  // 多个任务,用list

        for (Task task : tasks) {
            if (true) {
                // 判断是哪任务
                System.out.println("流程实例id=" + task.getProcessInstanceId());
                System.out.println("任务Id=" + task.getId());
                System.out.println("任务负责人=" + task.getAssignee());
                System.out.println("任务名称=" + task.getName());
                taskService.complete(task.getId());
            }
        }
    }
}

运行ActivitiDemo完整运行一遍流程:
1DeployTest部署流程
2startProcessTest启动流程实例
3completTaskTest运行一遍流程

四、在springbooot中使用

依赖会出现报错,需要修改pom.xml

  1. 使用log4j会和springboot本身的logback冲突,排除logback
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
  1. 已经有mybatis了,把不用的注释掉在这里插入图片描述

  2. 排除slf4j-log4j12的log4j,避免和外面的log4j冲突

		<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
            <exclusions><!-- 排除slf4j-log4j12的log4j,避免和外面的log4j冲突 -->
                <exclusion>
                    <artifactId>log4j</artifactId>
                    <groupId>log4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【赠书第24期】Java项目开发实战(微视频版)

文章目录 前言 1 项目选择与需求分析 1.1 项目选择 1.2 需求分析 2 系统设计 2.1 系统架构设计 2.2 数据库设计 2.3 接口设计 3 编码实现 3.1 环境搭建 3.2 编码规范 3.3 编码实现 4 测试与部署 4.1 单元测试 4.2 系统测试 4.3 部署与上线 5 总结与展望 6 推…

行为神经科学研究利器 | FiPhA:光纤光度分析开源平台

摘要 意义&#xff1a;光纤光度法(FP)是现代行为神经科学中广泛使用的技术&#xff0c;利用基因编码荧光传感器监测清醒行为动物的神经活动和神经递质。然而&#xff0c;分析光度数据既费力又耗时。 目的&#xff1a;本研究提出了一种通用的FP分析应用——光纤光度分析(FiPhA…

n7. 图

1.定义 图的每个结构之间有着某种关系。 六度空间理论等&#xff1b; 1.1引子&#xff1a; 最短路径问题 1.2什么是图 表示一种多对多的关系 线性关系表示的是一对一的关系&#xff0c;树表示的是一对多的关系。其实线性表和树其实都可以认为是图的一种特殊的情况。包含&am…

一种改进的形态学滤波算法-以心电信号的基线校正和噪声抑制为例(MATLAB环境)

信号在釆集和传输过程中难免受到噪声源的干扰&#xff0c;反映非线性动力学行为的特征信息有可能被噪声所掩盖。尤其是在混沌振动信号噪声抑制方面&#xff0c;因为混沌信号的高度非线性及宽频特性&#xff0c;噪声和混沌信号往往具有重叠的带宽。传统的时域及频域降噪方法效果…

【设计模式】JAVA Design Patterns——Data Access Object(数据访问对象模式)

&#x1f50d;目的 对象为某种类型的数据库或其他持久性机制提供了抽象接口。 &#x1f50d;解释 真实世界例子 有一组客户数据需要持久化到数据库中。 我们需要整个额外的增删改查操作以便操作客户数据。 通俗描述 DAO是我们通过基本持久性机制提供的接口。 维基百科 在计算机…

第七届数字峰会即将举行!正宇软件助力数字赋能社会发展!

据人民日报消息&#xff0c;由国家发展改革委、国家数据局、国家网信办、科技部、国务院国资委、福建省人民政府共同主办&#xff0c;福州市人民政府和相关单位承办的“第七届数字中国建设峰会”&#xff0c;将于5月24日至25日在福建省福州市举行&#xff0c;主题是“释放数据要…

事务报错没有显示回滚导致DDL阻塞引发的问题

在业务开发过程中&#xff0c;显示的开启事务并且在事务处理过程中对不同的情况进行显示的COMMIT或ROLLBACK&#xff0c;这是一个完整数据库事务处理的闭环过程。 这种在应用开发逻辑层面去handle的事务执行的结果&#xff0c;既确保了事务操作的数据完整性&#xff0c;又遵循了…

C++:单例模型、强制类型转换

目录 特殊类的设计不能被拷贝的类实现一个类&#xff0c;只能在堆上实例化的对象实现一个类&#xff0c;只能在栈上实例化的对象不能被继承的类 单例模式饿汉模式懒汉模式饿汉模式与懒汉模式的对比饿汉优缺点懒汉优缺点懒汉模式简化版本&#xff08;C11&#xff09; 单例释放问…

速看!打造专属数字化能力模型的七大关键!

在数字化浪潮中&#xff0c;企业如何打造适应自身发展的数字化能力模型&#xff1f;这是许多企业面临的重要课题。今天&#xff0c;通过众多企业使用蚓链数字化生态解决方案实践总结&#xff0c;为大家分享至关重要的七大经验&#xff0c;助你开启数字化转型之旅&#xff01; 1…

栈和队列OJ题详解

一.有效的括号&#xff1a; 20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 首先拿到这个题目&#xff0c;我的第一个思路是利用双指针来走&#xff0c;看看是不是匹配的 但是这种情况就把双指针的这个思路直接pass了&#xff0c;明明是匹配的括号&#xff0c;用双指…

protobuf学习

学习了下protobuf这个工具&#xff0c;可以用来序列化数据结构&#xff0c;而且效率很高&#xff0c;数据可以压缩的更小。 记录下&#xff0c;我这里主要在C#里使用&#xff0c;从NuGet程序包安装以下两个 安装好后可以在该程序目录找到 packages\Google.Protobuf.Tools.3.26.…

【计算机毕业设计】安卓054基于Android校园助手

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

离线强化学习基础知识之offline MBRL和MFRL

1 离线强化学习介绍 离线强化学习&#xff08;也称为批量强化学习或完全脱策略强化学习&#xff09;仅依赖于先前收集的数据集&#xff0c;无需进一步交互。它提供了一种利用先前收集的数据集的方法以自动学习决策策略。 离线强化学习可以被定义为 data-driven 形式的强化学习…

一篇文章讲透排序算法之堆排序

1.前言 在学习这篇文章之前&#xff0c;请大家先学习堆这一数据结构中堆的概念&#xff0c;向下调整算法&#xff0c;向下调整建堆。 有关堆的实现方式请参考&#xff1a;堆的实现 堆排序就是利用堆里面学习过的知识点进行排序&#xff0c;如何进行排序呢&#xff1f; 2.堆…

拓扑排序(概念 + 模板 + 例题)

概念 : 拓扑排序只有有向图有 &#xff0c; 可以判断图中是否有环 ; Kahn(卡恩)算法 过程 : 模板 : vector<int> a[N] , res ; int d[N] ; // 存放每个结点的入度 int n , x ;bool toposort() {queue<int> q;for(int i 1; i < n; i) if(d[i] 0) q.push…

python中GUI之tkinter 模块

目录 1.tkinter 模块使用 tkinter 介绍 创建一个简单的 GUI 给窗口添加小构件 小构件种类 小构件参数说明 查看某个小构件的所有方法和属性 常用小构件用法 Button&#xff1a;按钮用法 Label&#xff1a;标签用法 Radiobutton&#xff1a;单选按钮用法 Checkbutto…

月薪5万是怎样谈的?

知识星球&#xff08;星球名&#xff1a;芯片制造与封测技术社区&#xff0c;星球号&#xff1a;63559049&#xff09;里的学员问&#xff1a;目前是晶圆厂的PE&#xff0c;但是想跳槽谈了几次薪水&#xff0c;都没法有大幅度的增长&#xff0c;该怎么办&#xff1f;“学得文武…

JavaWeb 请求响应路径调试

在使用mvc时&#xff0c;或许会遇到请求的页面响应不了&#xff0c;这种情况要对站下径。 站点根目录 启动服务器时&#xff0c;通常要知道哪个是站点根目录。相应在网页端的url的跟站点通常为http://localhost:8080/ &#xff0c;前端解析时用的是站点根目录。 <form act…

RT-Thread更改msh串口波特率

修改rt-thread文件下components下dirvers下serial.h文件里 #define RT_SERIAL_CONFIG_DEFAULT 里的默认波特率即可

这方法真牛B!论文降重从81%直降1.9%

目录 一、万字论文&#xff0c;从0到1&#xff0c;只需1小时二、获取途径三、论文从81&#xff05;降到1.9&#xff05;四、内容是别人的&#xff0c;话是自己的五、AI工具 --> 中文论文降重六、论文降重小技巧 一、万字论文&#xff0c;从0到1&#xff0c;只需1小时 通过O…