2023最新版本Activiti7系列-多实例详解

news2024/12/23 18:14:06

在这里插入图片描述

工作流多实例

1.多实例介绍

  多实例活动是为业务流程中的某个步骤定义重复的一种方式。在编程概念中,多实例与 for each 结构相匹配:它允许对给定集合中的每个项目按顺序或并行地执行某个步骤或甚至一个完整的子流程。

  多实例是一个有额外属性(所谓的 “多实例特性”)的常规活动,它将导致该活动在运行时被多次执行。以下活动可以成为多实例活动。

  • Service Task 服务任务
  • Send Task 发送任务
  • User Task 用户任务
  • Business Rule Task 业务规则任务
  • Script Task 脚本任务
  • Receive Task 接收任务
  • Manual Task 手动任务
  • (Embedded) Sub-Process (嵌入)子流程
  • Call Activity 发起活动
  • Transaction Subprocess 事务子流程

网关或事件不能成为多实例。

  如果一个活动是多实例的,这将由活动底部的三条短线表示。三条垂直线表示实例将以并行方式执行,而三条水平线表示顺序执行。
在这里插入图片描述

按照规范的要求,每个实例所创建的执行的每个父执行将有以下变量:

  • nrOfInstances: 实例的总数量
  • nrOfActiveInstances: 当前活动的,即尚未完成的实例的数量。对于一个连续的多实例,这将永远是1。
  • nrOfCompletedInstances: 已经完成的实例的数量。

这些值可以通过调用 “execution.getVariable(x) “方法检索。

此外,每个创建的执行将有一个执行本地变量(即对其他执行不可见,也不存储在流程实例级别)。

  • loopCounter: 表示该特定实例的for each循环中的索引

为了使一个活动成为多实例,活动xml元素必须有一个multiInstanceLoopCharacteristics子元素。

<multiInstanceLoopCharacteristics isSequential="false|true">
 ...
</multiInstanceLoopCharacteristics>

isSequential属性表示该活动的实例是按顺序执行还是并行执行。

2. 基本应用

  多实例应用中我们需要指的具体生成几个实例任务。指派的方式可以通过loopCardinality属性来指的。通过loopCardinality来指定既可以是固定值也可以指定表达式(只要结果是整数即可)

<multiInstanceLoopCharacteristics isSequential="false">
  <loopCardinality>3</loopCardinality>
</multiInstanceLoopCharacteristics>
或者
<multiInstanceLoopCharacteristics isSequential="false">
  <loopCardinality>${num}</loopCardinality>
</multiInstanceLoopCharacteristics>

在这里插入图片描述

  如果我们需要同时指派多实例任务中的任务处理人。这时可以通过collectionelementVariable结合使用。

在这里插入图片描述

<multiInstanceLoopCharacteristics isSequential="false"
                              activiti:collection="${assigneeList}" activiti:elementVariable="assignal">
      </multiInstanceLoopCharacteristics>
@Test
void startFlow(){
    RuntimeService runtimeService = processEngine.getRuntimeService();
    // 启动流程的同时我们需要绑定对应的流程变量
    Map<String,Object> map = new HashMap<>();
    map.put("assignList", Arrays.asList("张三","李四","王五"));
    ProcessInstance processInstance = runtimeService
            .startProcessInstanceById("muti-instance-02:1:347503",map);
    String description = processInstance.getDescription();
    System.out.println("description = " + description);
    System.out.println("processInstance.getId() = " + processInstance.getId());
}

在这里插入图片描述

  在多实例中我们也可以设置提前结束的条件,也就是不用等多实例中的每个实例都审批。通过completionCondition属性就能达到我们的目的。比如审批的数量超过一半就通过结束。可以如下设置

      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${assigneeList}" activiti:elementVariable="assignal">
        <completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.5 }</completionCondition>
      </multiInstanceLoopCharacteristics>

  上面表达式返回true表示多实例结束也就是多实例中剩余的实例将被销毁,如果返回的是false则继续等待剩余的实例完成相关的操作。为了更加灵活的控制多实例的结束。这块我们可以通过绑定Spring容器中的对象中的特定方法来处理。相关的多实例默认的变量存储在DelegateExecution中,这块我们需要应用到。具体如下:

@Component("mutiInstanceDelegate")
public class MutiInstanceDelegate {

    public boolean completeInstanceTask(DelegateExecution execution){
        Integer nrOfInstances = (Integer) execution.getVariable("nrOfInstances");
        // 当前活跃。即还未完成的
        Integer nrOfActiveInstances = (Integer) execution.getVariable("nrOfActiveInstances");
        Integer nrOfCompletedInstances = (Integer) execution.getVariable("nrOfCompletedInstances");
        System.out.println("总的会签任务数量:" + nrOfInstances
                + "当前获取的会签任务数量:" + nrOfActiveInstances
                + " - " + "已经完成的会签任务数量:" + nrOfCompletedInstances);

        return nrOfCompletedInstances > nrOfActiveInstances;
    }
}

然后对应的配置为:

<multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${assigneeList}" activiti:elementVariable="assignee">
  <completionCondition>${mutiInstanceDelegate.completeInstanceTask(execution)}</completionCondition>
</multiInstanceLoopCharacteristics>

3.服务任务

  上面的案例都是在用户任务中实现。我们也可以在Service Task来实现。具体如下:
在这里插入图片描述

具体的流程定义信息

<?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="muti-instance-04-service-task" name="muti-instance-04-service-task" isExecutable="true">
    <documentation>muti-instance-04-service-task</documentation>
    <startEvent id="startEvent1"></startEvent>
    <userTask id="sid-6E319DF5-9A30-4FB0-A4F8-619F9E90002C" name="用户任务"></userTask>
    <sequenceFlow id="sid-10D69676-67F5-4514-A171-604748306FA5" sourceRef="startEvent1" targetRef="sid-6E319DF5-9A30-4FB0-A4F8-619F9E90002C"></sequenceFlow>
    <sequenceFlow id="sid-D9FBD759-2872-40FA-8606-B993FE722E02" sourceRef="sid-6E319DF5-9A30-4FB0-A4F8-619F9E90002C" targetRef="sid-7E8B8F41-07EE-4439-9F76-4EBE1C77CE75"></sequenceFlow>
    <endEvent id="sid-88E37A2E-33F5-4381-BC26-5A171D933F83"></endEvent>
    <sequenceFlow id="sid-B135AB86-A96D-4423-A0A5-D221054AD366" sourceRef="sid-7E8B8F41-07EE-4439-9F76-4EBE1C77CE75" targetRef="sid-88E37A2E-33F5-4381-BC26-5A171D933F83"></sequenceFlow>
    <serviceTask id="sid-7E8B8F41-07EE-4439-9F76-4EBE1C77CE75" name="服务任务" activiti:class="com.boge.activiti.delegate.MyMutiInstanceJavaDelegate">
      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${assignList}" activiti:elementVariable="userName">
        <completionCondition>${myMutiInstanceDelegate.completeMutiInstanceTask(execution)}</completionCondition>
      </multiInstanceLoopCharacteristics>
    </serviceTask>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_muti-instance-04-service-task">
    <bpmndi:BPMNPlane bpmnElement="muti-instance-04-service-task" id="BPMNPlane_muti-instance-04-service-task">
      <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
        <omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-6E319DF5-9A30-4FB0-A4F8-619F9E90002C" id="BPMNShape_sid-6E319DF5-9A30-4FB0-A4F8-619F9E90002C">
        <omgdc:Bounds height="80.0" width="100.0" x="175.0" y="138.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-88E37A2E-33F5-4381-BC26-5A171D933F83" id="BPMNShape_sid-88E37A2E-33F5-4381-BC26-5A171D933F83">
        <omgdc:Bounds height="28.0" width="28.0" x="465.0" y="164.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-7E8B8F41-07EE-4439-9F76-4EBE1C77CE75" id="BPMNShape_sid-7E8B8F41-07EE-4439-9F76-4EBE1C77CE75">
        <omgdc:Bounds height="80.0" width="100.0" x="320.0" y="138.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-B135AB86-A96D-4423-A0A5-D221054AD366" id="BPMNEdge_sid-B135AB86-A96D-4423-A0A5-D221054AD366">
        <omgdi:waypoint x="420.0" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="465.0" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-D9FBD759-2872-40FA-8606-B993FE722E02" id="BPMNEdge_sid-D9FBD759-2872-40FA-8606-B993FE722E02">
        <omgdi:waypoint x="275.0" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="320.0" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-10D69676-67F5-4514-A171-604748306FA5" id="BPMNEdge_sid-10D69676-67F5-4514-A171-604748306FA5">
        <omgdi:waypoint x="130.0" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="175.0" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

然后绑定的JavaDelegate为:

public class MyMutiInstanceJavaDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        Object userName = execution.getVariable("userName");
        Object loopCounter = execution.getVariable("loopCounter");
        System.out.println("第"+loopCounter+"个,用户的名称是:"+ userName);
    }
}

然后完成条件对应的方法为:

@Component("myMutiInstanceDelegate")
public class MyMutiInstanceDelegate {

    public boolean completeMutiInstanceTask(DelegateExecution execution){
        // 获取当前多实例中的相关的参数
        // 总得流程实例数量
        Integer nrOfInstances = (Integer) execution.getVariable("nrOfInstances");
        // 当前活跃的实例数量【没有审批的数量】
        Integer nrOfActiveInstances = (Integer) execution.getVariable("nrOfActiveInstances");
        // 当前已经审批的数量
        Integer nrOfCompletedInstances = (Integer) execution.getVariable("nrOfCompletedInstances");
        System.out.println("nrOfInstances = " + nrOfInstances);
        System.out.println("nrOfActiveInstances = " + nrOfActiveInstances);
        System.out.println("nrOfCompletedInstances = " + nrOfCompletedInstances);
        return nrOfCompletedInstances > nrOfActiveInstances;
    }
}

然后流程流转到多实例节点的日志输出如下:

第0个,用户的名称是:张三2
nrOfInstances = 3
nrOfActiveInstances = 2
nrOfCompletedInstances = 1
第1个,用户的名称是:李四2
nrOfInstances = 3
nrOfActiveInstances = 1
nrOfCompletedInstances = 2

4.子流程应用

  多实例的场景也可以在子流程中来使用,具体我们通过案例来讲解。本质上和我们前面介绍的是差不多的
在这里插入图片描述

完整的流程图

<?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="muti-instance-05-sub-process" name="muti-instance-05-sub-process" isExecutable="true">
    <documentation>muti-instance-05-sub-process</documentation>
    <startEvent id="startEvent1"></startEvent>
    <userTask id="sid-B2597779-A6FB-47DD-BD94-E31C499F8DBC" name="用户任务1"></userTask>
    <sequenceFlow id="sid-E9764E43-33D7-4865-93EC-24F352B68978" sourceRef="startEvent1" targetRef="sid-B2597779-A6FB-47DD-BD94-E31C499F8DBC"></sequenceFlow>
    <subProcess id="sid-EDCBFFC9-7B9C-4BE2-80BF-5346F4CE170A" name="部门审批流程">
      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${deptList}" activiti:elementVariable="dept">
        <completionCondition>${myMutiInstanceDelegate.completeMutiInstanceTask(execution)}</completionCondition>
      </multiInstanceLoopCharacteristics>
      <startEvent id="sid-6DD60C57-8D17-46A4-8E43-6093EC636137"></startEvent>
      <userTask id="sid-5075051C-77FD-40DA-8CDA-1EA1AF0771D3" name="领导审批"></userTask>
      <userTask id="sid-D1DB857A-D45E-4A7C-9408-E0D9D5E002DB" name="助理盖章"></userTask>
      <endEvent id="sid-7BD69F6C-70A4-4D76-BD22-3CC8E0C8FE8A"></endEvent>
      <sequenceFlow id="sid-50D82417-8A82-46E5-89BF-4A74A115A846" sourceRef="sid-6DD60C57-8D17-46A4-8E43-6093EC636137" targetRef="sid-5075051C-77FD-40DA-8CDA-1EA1AF0771D3"></sequenceFlow>
      <sequenceFlow id="sid-025AB6E4-A756-4241-A5D9-4F33147AB299" sourceRef="sid-5075051C-77FD-40DA-8CDA-1EA1AF0771D3" targetRef="sid-D1DB857A-D45E-4A7C-9408-E0D9D5E002DB"></sequenceFlow>
      <sequenceFlow id="sid-40380635-A29E-4EAE-8778-F9145C237801" sourceRef="sid-D1DB857A-D45E-4A7C-9408-E0D9D5E002DB" targetRef="sid-7BD69F6C-70A4-4D76-BD22-3CC8E0C8FE8A"></sequenceFlow>
    </subProcess>
    <sequenceFlow id="sid-051CE217-E7E0-406C-A96A-9EBBC94E69D0" sourceRef="sid-B2597779-A6FB-47DD-BD94-E31C499F8DBC" targetRef="sid-EDCBFFC9-7B9C-4BE2-80BF-5346F4CE170A"></sequenceFlow>
    <userTask id="sid-F361AC3E-A6C9-41B8-BE56-FB62E0AC0308" name="用户任务2"></userTask>
    <sequenceFlow id="sid-7C5829FE-C2B4-4829-A585-7F504F30A768" sourceRef="sid-EDCBFFC9-7B9C-4BE2-80BF-5346F4CE170A" targetRef="sid-F361AC3E-A6C9-41B8-BE56-FB62E0AC0308"></sequenceFlow>
    <endEvent id="sid-5C3B37EA-422C-4020-9015-59665363D7CB"></endEvent>
    <sequenceFlow id="sid-685FAC99-C12A-4A27-9E73-53FFD43008D6" sourceRef="sid-F361AC3E-A6C9-41B8-BE56-FB62E0AC0308" targetRef="sid-5C3B37EA-422C-4020-9015-59665363D7CB"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_muti-instance-05-sub-process">
    <bpmndi:BPMNPlane bpmnElement="muti-instance-05-sub-process" id="BPMNPlane_muti-instance-05-sub-process">
      <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
        <omgdc:Bounds height="30.0" width="30.0" x="90.0" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-B2597779-A6FB-47DD-BD94-E31C499F8DBC" id="BPMNShape_sid-B2597779-A6FB-47DD-BD94-E31C499F8DBC">
        <omgdc:Bounds height="80.0" width="100.0" x="165.0" y="165.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-EDCBFFC9-7B9C-4BE2-80BF-5346F4CE170A" id="BPMNShape_sid-EDCBFFC9-7B9C-4BE2-80BF-5346F4CE170A">
        <omgdc:Bounds height="315.0" width="544.0" x="360.0" y="44.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-6DD60C57-8D17-46A4-8E43-6093EC636137" id="BPMNShape_sid-6DD60C57-8D17-46A4-8E43-6093EC636137">
        <omgdc:Bounds height="30.0" width="30.0" x="429.5" y="189.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-5075051C-77FD-40DA-8CDA-1EA1AF0771D3" id="BPMNShape_sid-5075051C-77FD-40DA-8CDA-1EA1AF0771D3">
        <omgdc:Bounds height="80.0" width="100.0" x="504.5" y="164.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-D1DB857A-D45E-4A7C-9408-E0D9D5E002DB" id="BPMNShape_sid-D1DB857A-D45E-4A7C-9408-E0D9D5E002DB">
        <omgdc:Bounds height="80.0" width="100.0" x="649.5" y="164.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-7BD69F6C-70A4-4D76-BD22-3CC8E0C8FE8A" id="BPMNShape_sid-7BD69F6C-70A4-4D76-BD22-3CC8E0C8FE8A">
        <omgdc:Bounds height="28.0" width="28.0" x="794.5" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-F361AC3E-A6C9-41B8-BE56-FB62E0AC0308" id="BPMNShape_sid-F361AC3E-A6C9-41B8-BE56-FB62E0AC0308">
        <omgdc:Bounds height="80.0" width="100.0" x="949.0" y="161.5"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-5C3B37EA-422C-4020-9015-59665363D7CB" id="BPMNShape_sid-5C3B37EA-422C-4020-9015-59665363D7CB">
        <omgdc:Bounds height="28.0" width="28.0" x="1094.0" y="187.5"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-50D82417-8A82-46E5-89BF-4A74A115A846" id="BPMNEdge_sid-50D82417-8A82-46E5-89BF-4A74A115A846">
        <omgdi:waypoint x="459.5" y="204.0"></omgdi:waypoint>
        <omgdi:waypoint x="504.5" y="204.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-685FAC99-C12A-4A27-9E73-53FFD43008D6" id="BPMNEdge_sid-685FAC99-C12A-4A27-9E73-53FFD43008D6">
        <omgdi:waypoint x="1049.0" y="201.5"></omgdi:waypoint>
        <omgdi:waypoint x="1094.0" y="201.5"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-E9764E43-33D7-4865-93EC-24F352B68978" id="BPMNEdge_sid-E9764E43-33D7-4865-93EC-24F352B68978">
        <omgdi:waypoint x="120.0" y="205.0"></omgdi:waypoint>
        <omgdi:waypoint x="165.0" y="205.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-051CE217-E7E0-406C-A96A-9EBBC94E69D0" id="BPMNEdge_sid-051CE217-E7E0-406C-A96A-9EBBC94E69D0">
        <omgdi:waypoint x="265.0" y="204.58033573141486"></omgdi:waypoint>
        <omgdi:waypoint x="360.0" y="203.7829736211031"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-7C5829FE-C2B4-4829-A585-7F504F30A768" id="BPMNEdge_sid-7C5829FE-C2B4-4829-A585-7F504F30A768">
        <omgdi:waypoint x="904.0" y="201.5"></omgdi:waypoint>
        <omgdi:waypoint x="949.0" y="201.5"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-025AB6E4-A756-4241-A5D9-4F33147AB299" id="BPMNEdge_sid-025AB6E4-A756-4241-A5D9-4F33147AB299">
        <omgdi:waypoint x="604.5" y="204.0"></omgdi:waypoint>
        <omgdi:waypoint x="649.5" y="204.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-40380635-A29E-4EAE-8778-F9145C237801" id="BPMNEdge_sid-40380635-A29E-4EAE-8778-F9145C237801">
        <omgdi:waypoint x="749.5" y="204.0"></omgdi:waypoint>
        <omgdi:waypoint x="794.5" y="204.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

部署启动后。子流程作为多流程实例。会产生多个任务。只有子流程中的流程审批完成后才表示一个实例的完成。

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

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

相关文章

【Java并发】如何进行死锁诊断?

文章目录 1.什么是死锁2.死锁怎么产生的3.如何进行死锁诊断&#xff1f;3.1 通过命令查看3.2 jconsole可视化工具3.2 VisualVM&#xff1a;故障处理工具 1.什么是死锁 死锁&#xff08;Deadlock&#xff09;是指两个或多个进程&#xff08;线程&#xff09;在执行过程中&#…

spss什么是描述性分析,以及如何去处理。

描述性分析是数据分析的第一步&#xff0c;是了解和认识数据基本特征和结构的方法&#xff0c;只有在完成了描述性统计分析&#xff0c;充分的了解和认识数据特征后&#xff0c;才能更好地开展后续更复杂的数据分析。因此&#xff0c;描述性分析是开展数据分析过程中最基础且必…

怎么在python里面安装库,如何在python中安装库

大家好&#xff0c;给大家分享一下python外部库安装后放在哪里&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; Python成为最流行的语言之一&#xff0c;除了它的简单易学和语法简单外&#xff0c;还有一个重要的原因是Python有非常强大的第…

PMP认证考试有何变化?该如何备考

截至2023年1月31日&#xff0c;全球有超130万PMP有效持证人士&#xff0c;其中中国有效持证人数已超过了43万人。持有PMP也已成为企业衡量项目经理人专业度的重要指标之一。 PMP考证人数的快速发展&#xff0c;与其考试大纲和知识体系的科学性和实战性密不可分。PMP考纲和教材…

【雕爷学编程】Arduino动手做(201)---行空板硬件控制之LED与按键

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

数组slice、splice字符串substr、split

一、定义 这篇文章主要对数组操作的两种方法进行介绍和使用&#xff0c;包括&#xff1a;slice、splice。对字符串操作的两种方法进行介绍和使用&#xff0c;包括&#xff1a;substr、split (一)、数组 slice:可以操作的数据类型有&#xff1a;数组字符串 splice:数组 操作数组…

Spring依赖注入、对象装配

文章目录 依赖注入与对象装配依赖注入的常见方式属性注入&#xff08;Property Injection&#xff09;属性注入的优缺点 Setter 注入&#xff08;Setter Injection&#xff09;Setter注入优缺点 构造函数注入&#xff08;Constructor Injection&#xff09;构造函数注入优缺点 …

Unity游戏源码分享-多角色fps射击游戏

Unity游戏源码分享-多角色fps射击游戏 项目地址&#xff1a;https://download.csdn.net/download/Highning0007/88204023

Flutter BottomSheet 三段式拖拽

BottomSheetBehavior 追踪 BottomSheet系统默认实现效果准备要实现的功能点&#xff1a;定义三段式状态&#xff1a;BottomSheetBehavoir阀值定义1. 未达到滚动阀值&#xff0c;恢复状态2. 达到滚动阀值&#xff0c;更新状态 前面倒是有讲过Android原生的BottomSheetBehavior&a…

Camunda 7.x 系列【2】开源工作流引擎框架

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址&#xff1a;https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. 开源工作流引擎框架2.1 jBPM2.2 Activ…

综合技巧练习 - Packet Tracer 简介

1.7.1&#xff1a;综合技巧练习 - Packet Tracer 简介 拓扑图&#xff1a; 以基本完成的逻辑拓扑为起点。 设备 接口 IP 地址 子网掩码 默认网关 R1-ISP Fa0/0 192.168.254.253 255.255.255.0 不适用 S0/0/0 10.10.10.6 255.255.255.252 R2-Central Fa0/0 17…

DTC服务(0x14 0x19 0x85)

DTC相关的服务有ReadDTCInformation (19) service&#xff0c;ControlDTCSetting (85) service和ReadDTCInformation (19) service ReadDTCInformation (19) service 该服务允许客户端从车辆内任意一台服务器或一组服务器中读取驻留在服务器中的诊断故障代码( DTC )信息的状态…

并发——ThreadPoolExecutor 类简单介绍

文章目录 1 ThreadPoolExecutor 类分析2 推荐使用 ThreadPoolExecutor 构造函数创建线程池 线程池实现类 ThreadPoolExecutor 是 Executor 框架最核心的类。 1 ThreadPoolExecutor 类分析 ThreadPoolExecutor 类中提供的四个构造方法。我们来看最长的那个&#xff0c;其余三个…

P15 电路定理——巧妙-灵性-智慧

1、戴维南定理 2、戴维南定理的证明 对于线性含源的一个结构&#xff0c; 右边接一个支路N&#xff0c;再用电流源替代N 情况一&#xff1a;A没有独立源&#xff0c;那么A可以等价于一个电阻 情况二&#xff1a;A有独立源&#xff0c;例证法&#xff1a; 使用叠加法&#xf…

获取 Android 的 SHA1 值

1、调试版&#xff0c;可以直接在 Android studio 中的 gradle 中查看。也可以用下面方法进行 前提要先确定签名文件所在的路径&#xff1a;调试版默认使用的签名文件是debug.keystore&#xff0c;文件处于 C 盘用户目录下的.android文件夹下。打开命令行工具&#xff0c; 1、…

分析为何科研转化率低

最近这两天&#xff0c;[广西审计:高校1.31亿科研经费成果转化率为0] 话题引发热议。据报道&#xff0c;广西壮族自治区审计厅近日公布的《关于2022年度自治区本级预算执行和其他财政收支的审计工作报告》披露了广西在科教振兴资金审计方面 9 所高校开展科研的相关情况。报告发…

Flutter:文件上传与下载(下载后预览)

Dio dio是一个强大的Dart Http请求库&#xff0c;提供了丰富的功能和易于使用的API&#xff0c;支持文件上传和下载。 这个就不介绍了&#xff0c;网上有很多的封装案例。 background_downloader 简介 适用于iOS&#xff0c;Android&#xff0c;MacOS&#xff0c;Windows和L…

使用 prometheus client SDK 暴露指标

目录 1. 使用 prometheus client SDK 暴露指标1.1. How Go exposition works1.2. Adding your own metrics1.3. Other Go client features 2. Golang Application monitoring using Prometheus2.1. Metrics and Labels2.2. Metrics Types2.2.1. Counters:2.2.2. Gauges:2.2.3. …

【ECharts】树图

将3级改成4级 demo上是3层&#xff0c;如何实现4层。 initialTreeDepth: 4

【hello C++】特殊类设计

目录 一、设计一个类&#xff0c;不能被拷贝 二、设计一个类&#xff0c;只能在堆上创建对象 三、设计一个类&#xff0c;只能在栈上创建对象 四、请设计一个类&#xff0c;不能被继承 五、请设计一个类&#xff0c;只能创建一个对象(单例模式) C&#x1f337; 一、设计一个类&…