Activiti基本使用2

news2024/11/18 11:26:15

目录

3、流程实例

3.1、什么是流程实例

3.2、让实际业务与activiti表关联(BusinessKey)

3.3、挂起,激活流程实例

3.3.1、全部流程实例挂起

3.3.2、单个流程实例挂起

4、任务分配

4.1、固定分配

4.2、表达式分配

4.2.1、UEL-value

4.2.2、UEL-method 方式

4.3、监听器分配

5、流程变量

5.1、什么是流程变量

5.2、流程变量的作用域

5.2.1、globa变量

5.2.2、local变量

5.3、流程变量的使用方法

5.4、设置globa变量

5.4.1、启动流程时设置变量

5.4.2、在任务办理时设置流程变量

5.4.3、通过当前流程实例设置

5.5、设置Local变量

6、任务组

6.1、Candidate-users候选人

6.2、组任务办理流程

6.3、关键代码

6.3.1、部署及启动

6.3.2、查询组任务

6.3.2、拾取组任务

6.3.3、 查询个人待办任务

6.3.4、 办理个人任务

6.3.5、归还组任务

6.3.6、 任务交接

7、网关

7.1、排他网关

7.2、并行网关

7.3、包含网关


3、流程实例

基本操作参考:Activiti的基本使用_Relievedz的博客-CSDN博客

3.1、什么是流程实例

流程定义ProcessDefinition和流程实例ProcessInstance是Activiti重要的概念,类似于Java类和Java实例的关系

启动一个流程实例表示开始一次业务流程的运行,比如员工请假流程部署完成,如果张三要请假就可以启动一个流程实例,如果李四要请假也启动一个流程实例,两个流程的执行互相不影响,就好比定义一个 java 类,实例化两个对象一样,部署的流程就好比 java 类,启动一个流程实例就好比 new 一个 java 对象

3.2、让实际业务与activiti表关联(BusinessKey)

比如我们填写一个请假单,一定会有一个请假单的唯一标识,我们通常使用这个标识来关联activiti,这个标识在activiti中称为businesskey

BusinessKey:业务标识,通常为业务的主键,业务标识和流程标识一一对应,业务标识来源于业务系统,存储业务标识就是根据业务标识来关联查询业务系统的数据

举例:请假流程启动一个流程实例,就可以将请假单的id作为业务标识存储到activiti中,将来查询activiti的流程实例信息就可以获取请假单的id从而关联查询业务系统数据库得到请假单信息

/**
 * 启动流程实例,添加businessKey
 */
@Test
public void startUpProcessAddBusinessKey(){
    String businessKey = "1";
    // 启动流程实例,指定业务标识businessKey,也就是请假申请单id
    ProcessInstance processInstance = runtimeService.
            startProcessInstanceByKey("qingjia",businessKey);
    // 输出
    System.out.println("业务id:"+processInstance.getBusinessKey());
}

3.3、挂起,激活流程实例

某些情况可能由于流程变更需要将当前运行的流程暂停而不是直接删除,流程暂停后将不会执行;

3.3.1、全部流程实例挂起

操作流程定义为挂起状态,该流程定义下面的所有流程实例全部暂停: 流程定义为挂起状态,该流程定义将不允许启动新的流程实例,同时该流程定义下所有的流程实例将全部挂起暂停执行

//全部流程实例挂起
@Test
public void suspendProcessInstanceAll() {
    //1 获取流程定义的对象
    ProcessDefinition qingjia = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey("qingjia").singleResult();

    //2 调用流程定义对象的方法判断当前状态:挂起 激活
    boolean suspended = qingjia.isSuspended();

    //3 判断如果挂起,实现激活
    if(suspended) {
        //第一个参数 流程定义id
        //第二个参数 是否激活 true
        //第三个参数 时间点
        repositoryService
                .activateProcessDefinitionById(qingjia.getId(),
                        true,null);
        System.out.println(qingjia.getId()+"激活了");
    } else {
        //如果激活,实现挂起
        repositoryService
                .suspendProcessDefinitionById(qingjia.getId(),
                        true,null);
        System.out.println(qingjia.getId()+"挂起");
    }
}

3.3.2、单个流程实例挂起

操作流程实例对象,针对单个流程执行挂起操作,某个流程实例挂起则此流程不在继续执行,完成该流程实例的当前任务将报异常;

//单个流程实例挂起
@Test
public void SingleSuspendProcessInstance() {
    String processInstanceId = "b98e42b3-df27-11ed-b184-005056c00001";
    ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
            .processInstanceId(processInstanceId)
            .singleResult();
    boolean suspended = processInstance.isSuspended();
    if (suspended) {
        //激活
        runtimeService.activateProcessInstanceById(processInstanceId);
        System.out.println(processInstanceId + "激活");
    } else {
        runtimeService.suspendProcessInstanceById(processInstanceId);
        System.out.println(processInstanceId + "挂起");
    }
}

4、任务分配

任务分配有三种方式

  1. 固定分配

  2. UEL表达式分配

  3. 监听器分配

4.1、固定分配

在前面进行业务流程建模时指定固定的任务负责人,如:Assignee:zhangsan/lisi

4.2、表达式分配

activiti使用UEL表达式,UEL是java EE6规范的一部分,UEL即统一表达式语言,activiti支持两个UEL表达式:UEL-value和UEL-method。

4.2.1、UEL-value

新建:一个加班流程

如图:

assignee1 这个变量是 activiti 的一个流程变量

我们启动流程实例,这个启动实例的方法跟之前的方法基本一致,唯一的不同是在启动时,添加了一个参数

@Test
public void deployProcess01() {
    // 流程部署
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("process/jiaban.bpmn20.xml")
            .name("加班申请流程")
            .deploy();
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
}

/**
 * 启动流程实例
 */
@Test
public void startUpProcess01() {
    Map<String, Object> map = new HashMap<>();
    map.put("assignee1","lucy");
    map.put("assignee2","mary");
    //创建流程实例,我们需要知道流程定义的key
    ProcessInstance processInstance =
            runtimeService.startProcessInstanceByKey("jiaban", map);
    //输出实例的相关信息
    System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
    System.out.println("流程实例id:" + processInstance.getId());
}

4.2.2、UEL-method 方式

如图:

userBean 是 spring 容器中的一个 bean,表示调用该 bean 的 getUsername(int id)方法。

经理审批:${userBean.getUsername(1)}

人事审批:${userBean.getUsername(2)}

package com.atguigu.auth.activiti;

import org.springframework.stereotype.Component;

/**
 * @program: guigu-oa-perent
 * @description: userBean 是 spring 容器中的一个 bean,表示调用该 bean 的 getUsername(int id)方法。
 * @author: Mr.Zhang
 * @create: 2023-04-20 11:42
 **/
@Component
public class UserBean {

    public String getUsername(int id) {
        if(id == 1) {
            return "lilei";
        }
        if(id == 2) {
            return "wyz";
        }
        return "admin";
    }
}

部署与启动

/
//uel-method
@Test
public void deployProcess01() {
    Deployment deployment = repositoryService.createDeployment()
            .addClasspathResource("process/jiaban01.bpmn20.xml")
            .name("加班申请流程01")
            .deploy();
    System.out.println(deployment.getId());
    System.out.println(deployment.getName());
}

@Test
public void startProcessInstance01() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban01");
    System.out.println(processInstance.getProcessDefinitionId());
    System.out.println(processInstance.getId());
}

启动流程实例,就会调用bean方法,参数为:1,经理审批后,接着调用bean方法,参数为:2

4.3、监听器分配

使用监听器的方式来指定负责人,那么在流程设计时就不需要指定assignee。

任务监听器是发生对应的任务相关事件时执行自定义 java 逻辑 或表达式

Event的选项包含:

Create:任务创建后触发
Assignment:任务分配后触发
Delete:任务完成后触发
All:所有事件发生都触发

定义任务监听类,且类必须实现 org.activiti.engine.delegate.TaskListener 接口

package com.atguigu.auth.activiti;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

/**
 * @program: guigu-oa-perent
 * @description: 定义任务监听类
 * @author: Mr.Zhang
 * @create: 2023-04-21 08:55
 **/
public class MyTaskListener implements TaskListener {
    @Override
    public void notify(DelegateTask task) {
        if(task.getName().equals("经理审批")){
            //分配任务
            task.setAssignee("jack");
        } else if (task.getName().equals("人事审批")) {
            task.setAssignee("tom");
        }
    }
}

配置监听器

经理审批与人事审批,都设置一样的监听即可

部署与测试

//
//监听器分配任务
@Test
public void deployProcess02() {
    Deployment deployment = repositoryService.createDeployment()
            .addClasspathResource("process/jiaban02.bpmn20.xml")
            .name("加班申请流程02")
            .deploy();
    System.out.println(deployment.getId());
    System.out.println(deployment.getName());
}

@Test
public void startProcessInstance02() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban02");
    System.out.println(processInstance.getProcessDefinitionId());
    System.out.println(processInstance.getId());
}

 启动流程实例,就会调用MyTaskListener监听方法

5、流程变量

5.1、什么是流程变量

流程变量在 activiti 中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和 activiti 结合时少不了流程变量,流程变量就是 activiti 在管理工作流时根据管理需要而设置的变量。 比如:在请假申请流程流转时如果请假天数大于2 天则由总经理审核,否则由部门经理直接审核, 请假天 数就可以设置为流程变量,在流程流转时使用。

5.2、流程变量的作用域

流程变量的作用可以是一个流程实例,但也可以是一个任务(task)或是一个执行实例

5.2.1、globa变量

流程变量的默认作用域是流程实例。当一个流程变量的作用域为流程实例时,可以称为 global 变量

global 变量中变量名不允许重复,设置相同名称的变量,后设置的值会覆盖前设置的变量值。

5.2.2、local变量

任务和执行实例仅仅是针对一个任务和一个执行实例范围,范围没有流程实例大, 称为 local 变量。

Local 变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同没有影响。Local 变量名也可以和 global 变量名相同,没有影响。

5.3、流程变量的使用方法

通过UEL表达式使用流程变量

1、之前我们也使用过UEL表达式来设置任务处理人,例如${assignee1},activiti获取UEL表达式的值,即流程变量assignee1的值,将值作为任务的负责人进行任务分配 2、我们也可以在任务和任务间的连线上使用UEL表达式,决定流程走向 比如${ day > 2 }和${day <= 2},day就是一个流程变量名称,UEL表达式的执行结果是布尔类型

5.4、设置globa变量

5.4.1、启动流程时设置变量

在启动流程时设置流程变量,变量的作用域是整个流程实例。 通过 Map<key,value> 设置流程变量,map 中可以设置多个变量,这个 key 就是流程变量的名字

这是前面的实例代码

@Test
public void startUpProcess() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("assignee1", "zhangsan");
    variables.put("assignee2", "lisi");
    //创建流程实例,我们需要知道流程定义的key
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia", variables);
    //输出实例的相关信息
    System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
    System.out.println("流程实例id:" + processInstance.getId());
}

5.4.2、在任务办理时设置流程变量

它的作用域是整个流程实例 ,如果设置的流程变量的 key 在流程实例中已存在相同的名字则后设置的变量替换前边设置的变量。

模拟实例代码:

@Test
public void completTask() {
    Task task = taskService.createTaskQuery()
            .taskAssignee("zhangsan")  //要查询的负责人
            .singleResult();//返回一条
​
    Map<String, Object> variables = new HashMap<>();
    variables.put("assignee2", "zhao");
    //完成任务,参数:任务id
    taskService.complete(task.getId(), variables);
}

5.4.3、通过当前流程实例设置

通过流程实例 id 设置全局变量, 它的作用域是整个流程实例 ,该流程实例必须未执行完成。

模拟实例代码:

@Test
public void processInstanceIdSetVariables() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("assignee2", "wang");
    runtimeService.setVariables("1c347a90-82c6-11ed-96ca-7c57581a7819", variables);
}

5.5、设置Local变量

local 流程变量的作用域只在当前任务节点下可用

任务办理时设置local流程变量,当前运行的流程实例只能在该任务结束前使用,任务结束该变量无法在当前流程实例使用

模拟实例代码:

@Test
public void completLocalTask() {
    Task task = taskService.createTaskQuery()
            .taskAssignee("zhangsan")  //要查询的负责人
            .singleResult();//返回一条
​
    // 设置local变量,作用域为该任务
    taskService.setVariableLocal(task.getId(),"assignee2","li");
    // 查看local变量
    System.out.println(taskService.getVariableLocal(task.getId(), "assignee2"));
    //完成任务,参数:任务id
    taskService.complete(task.getId());
}

6、任务组

6.1、Candidate-users候选人

1、需求 在流程定义中在任务结点的assignee固定设置任务负责人,在流程定义时将参与者固定设置在.bpmn文件中,如果要临时变更任务负责人则需要修改流程定义,系统扩展性很差,针对这种情况,我们可以给任务设置多个候选人,从候选人中选择参与者来完成任务

2、设置任务候选人

 

6.2、组任务办理流程

第一步:查询组任务

指定候选人,查询该候选人当前的待办任务 候选人不能办理任务 第二步:拾取(claim)任务

该组任务的所有候选人都能拾取 将候选人的组任务,变成个人任务,原来的候选人就变成了该任务的负责人 如果拾取后不想办理该任务 需要将已经拾取 第三步:查询个人任务

查询方式同个人任务部分,根据assignee查询用户负责的个人任务 第四步:办理个人任务

6.3、关键代码

6.3.1、部署及启动

 

@Test
public void deployProcess04() {
    // 流程部署
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("process/jiaban04.bpmn20.xml")
            .name("请假申请流程")
            .deploy();
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
​
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban04");
    System.out.println(processInstance.getId());
}

6.3.2、查询组任务

@Test
public void findGroupTaskList() {
    //查询组任务
    List<Task> list = taskService.createTaskQuery()
            .taskCandidateUser("zhangsan01")//根据候选人查询
            .list();
    for (Task task : list) {
        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());
    }
}

6.3.2、拾取组任务

@Test
public void claimTask(){
    //拾取任务,即使该用户不是候选人也能拾取(建议拾取时校验是否有资格)
    //校验该用户有没有拾取任务的资格
    Task task = taskService.createTaskQuery()
            .taskCandidateUser("zhangsan01")//根据候选人查询
            .singleResult();
    if(task!=null){
        //拾取任务
        taskService.claim(taskId, "zhangsan01");
        System.out.println("任务拾取成功");
    }
}

张三01拾取任务了,张三02就不能拾取了

6.3.3、 查询个人待办任务

查询方式同个人任务查询

@Test
public void findGroupPendingTaskList() {
    //任务负责人
    String assignee = "zhangsan01";
    List<Task> list = taskService.createTaskQuery()
            .taskAssignee(assignee)//只查询该任务负责人的任务
            .list();
    for (Task task : list) {
        System.out.println("流程实例id:" + task.getProcessInstanceId());
        System.out.println("任务id:" + task.getId());
        System.out.println("任务负责人:" + task.getAssignee());
        System.out.println("任务名称:" + task.getName());
    }
}

6.3.4、 办理个人任务

同个人任务办理

@Test
public void completGroupTask() {
    Task task = taskService.createTaskQuery()
            .taskAssignee("zhangsan01")  //要查询的负责人
            .singleResult();//返回一条
    taskService.complete(task.getId());
}

6.3.5、归还组任务

如果个人不想办理该组任务,可以归还组任务,归还后该用户不再是该任务的负责人

@Test
public void assigneeToGroupTask() {
    String taskId = "d96c3f28-825e-11ed-95b4-7c57581a7819";
    // 任务负责人
    String userId = "zhangsan01";
    // 校验userId是否是taskId的负责人,如果是负责人才可以归还组任务
    Task task = taskService
            .createTaskQuery()
            .taskId(taskId)
            .taskAssignee(userId)
            .singleResult();
    if (task != null) {
        // 如果设置为null,归还组任务,该 任务没有负责人
        taskService.setAssignee(taskId, null);
    }
}

6.3.6、 任务交接

任务交接,任务负责人将任务交给其它候选人办理该任务

@Test
public void assigneeToCandidateUser() {
    // 当前待办任务
    String taskId = "d96c3f28-825e-11ed-95b4-7c57581a7819";
    // 校验zhangsan01是否是taskId的负责人,如果是负责人才可以归还组任务
    Task task = taskService
            .createTaskQuery()
            .taskId(taskId)
            .taskAssignee("zhangsan01")
            .singleResult();
    if (task != null) {
        // 将此任务交给其它候选人zhangsan02办理该 任务
        taskService.setAssignee(taskId, "zhangsan02");
    }
}

7、网关

网关用来控制流程的流向,通常会和流程变量一起使用。

7.1、排他网关

  • 排他网关:只有一条路径会被选择

当你的流程出现这样的场景:请假申请,两天以内,部门经理审批流程就结束了,两天以上需要总经理直接审批,这个时候就需要排他网关

7.2、并行网关

  • 并(平)行网关:所有路径会被同时选择

当出现这样的场景:请假申请开始,需要部门经理和总经理都审批,两者没有前后需要两个人全部审批才能进入下个节点人事审批。这个时候就需要并行网关

 

与排他网关的主要区别是,并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。

7.3、包含网关

包容网关:可以同时执行多条线路,也可以在网关上设置条件,可以看做是排他网关和并行网关的结合体。 当出现这样的场景:请假申请大于等于2天需要由部门总经理审批,小于2天由部门经理审批,请假申请必须经过人事经理审批。这个时候就需要包含网关

 

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

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

相关文章

“码”上反馈,自动留痕:二维码助力湖塘街道人居环境巡查高效化

绍兴市柯桥区湖塘街道将农村人居环境巡查同二维码技术相结合&#xff0c;具体应用到了“村民垃圾分类检查”、“公厕卫生检查”和“各村垃圾分类工作的督导记录”这三项检查工作中&#xff0c;做到了“码”上反馈、自动留痕&#xff0c;有效提升了巡检实效&#xff0c;在2020年…

什么是薪酬管理系统,薪酬管理有哪些功能?

阅读本文您将了解&#xff1a;1.薪酬管理系统的定义&#xff1b;2.薪酬管理系统的功能&#xff1b;3.薪酬管理系统的作用。 一、薪酬管理系统是什么 薪酬管理系统是一种用于管理企业员工的薪资和奖金的工具。它可以自动计算员工的工资和奖金&#xff0c;记录员工的考勤和休假…

凌恩生物文献分享|大热门--HiFi宏基因组有效提升真核生物群落检出效果

binning和HiFi宏基因组测序优势&#xff1a; 不依赖于微生物的分离培养&#xff0c;环境微生物单菌基因组&#xff08;框架图&#xff09;研究的一种新的途径和高性价比策略&#xff1b; 可以得到环境中丰度较低的宏基因组&#xff0c;为研究低丰度微生物提供了途径&#xff1b…

【Unity VR开发】结合VRTK4.0:高亮与标签

语录&#xff1a; 信仰到底是什么呢&#xff0c;就是纵身一跃&#xff0c;就是我们跟神之间一个永远的约定&#xff0c;是舍弃日的去开始新的生活;信仰就是从今以后&#xff0c;再也不要放开你的手。 前言&#xff1a; Interactable Highlighter &#xff1a;当我们的手柄触碰…

Android Framework源码解析篇~

应用启动流程 Activity启动流程 关键debug节点&#xff1a; //左侧 ActivithThread //右侧 ActivityTaskManagerService>..>ActivityTaskSupervisor //中继 debug:ClientTransaction.schedule>mclient.scheduleTransaction //这里是 mclient是 ApplicationThread,从…

++i与i++有什么区别?

在编程时&#xff0c;经常会用到变量的自增或自减操作&#xff0c;尤其在循环中用的最多。以自增为例&#xff0c;有两种自增方式&#xff1a;前置和后置&#xff0c;即i和i&#xff0c;它们的不同点在于i是在程序执行完毕后进行自增&#xff0c;而i是在程序开始执行前就进行自…

基于Java+Springboot+Vue+elememt社区疫情返乡管控系统设计实现

基于JavaSpringbootVueelememt社区疫情返乡管控系统设计实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系…

Python爬取电商数据:商品采集接口 商品详情数据API 商品主图接口

学习Python自动化的一个好办法就是构建一个价格追踪器。由于这项任务生成的脚本可以立即投入使用&#xff0c;所以对于初学者来说尤为方便。本文将向大家介绍如何用Python采集器建立一个可立即实现电商价格监控的可扩展价格追踪器。 价格监控的目的 价格监控的好处多多。对于…

公司招人,面了一个4年经验不会自动化的测试人,他凭什么要15K?

在深圳这家金融公司也待了几年&#xff0c;被别人面试过也面试过别人&#xff0c;大大小小的事情也见识不少&#xff0c;今天又是团面的一天&#xff0c; 一百多个人都聚集在一起&#xff0c;因为公司最近在谈项目出来面试就2个人&#xff0c;无奈又被叫到面试房间。 整个过程…

No manual entry for ls解决办法

No manual entry for ls解决办法 如果在 Linux 中运行 man ls 命令时提示“no manual entry for ls”&#xff0c;则可能是因为您的系统没有安装 man 页面或者该页面已经被删除。此外&#xff0c;也有可能是您输入的命令不是标准命令。 可以通过以下方式进行排查&#xff1a;…

Git 时间线管理

Git 时间线管理 这一部分主要讲的是 取消(undo) 变化 和在不同的时间锚点跳来跳去&#xff0c;以 command 为主。 设计到的commits有&#xff1a; checkoutrestoreresetrevert checkout checkout 的一部分作用&#xff0c;即切换分枝在 git 分支操作 中有提到过&#xff0…

ESP32-s2芯片esp32-s2-saola-1开发板 micropython的repl连接

本文只是解决通过esp32-s2-saola-1开发板 自带microUSB 作为repl与micro python通信的问题。 如果你对esp32&#xff0c;micropython不熟&#xff0c;本文不适合你。 如果你用的不是esp32-s2&#xff0c;你不需要关心。 区分两个USB&#xff1a; 1. esp32-s2原生USB&#x…

25K 入职阿里的那天,我特么哭了

悲催的经历&#xff1a; 先说一下自己的个人情况&#xff0c;计算机专业&#xff0c;17 年本科毕业&#xff0c;一毕业就进入了“腾讯”测试 岗(进去才知道是接了个腾讯外包项目&#xff0c;可是刚毕业谁知道什么外包不外包的)。 更悲催的是&#xff1a;刚入职因为家里出现一…

什么是CDN加速?CDN加速有哪些作用?

一、什么是 CDN CDN 的全称是 Content Delivery Network&#xff0c;即内容分发网络。CDN 是在现有 Internet 基础上增加一层新的网络架构&#xff0c;通过部署边缘服务器&#xff0c;采用负载均衡、内容分发、调度等功能&#xff0c;使用户可以就近访问获取所需内容&#xff…

VMware 安装 MS-DOS7.10 并配置网络

VMware 安装 MS-DOS7.10 并设置软盘共享 1. 新建虚拟机2. 开机2.1. 这几个地方都可以开机2.2. 手速慢&#xff0c;进不了BIOS的朋友可以点这里 安装 MS-DOS7.101. 先选 1 安装 MS-DOS7.10 回车2. 欢迎页面&#xff0c;客气一下而已&#xff0c;继续 Next3. 继续王婆卖瓜4. 这步…

HDCTF 2023 Pwn WriteUp

Index 前言Pwnner分析EXP: KEEP_ON分析EXP: Minions分析EXP: 后记&#xff1a; 前言 本人是菜狗&#xff0c;比赛的时候只做出来1题&#xff0c;2题有思路但是不会&#xff0c;还是太菜了。 栈迁移还是不会&#xff0c;但又都是栈迁移的题&#xff0c;真头大。得找时间好好学学…

如何在 Java 8 中使用 Streams?结合多种案例剖析学习!

Java 8 Streams 是一个非常强大的功能&#xff0c;它提供了一种简洁、优雅的方式来处理数据集合。通过使用 Streams&#xff0c;我们可以轻松地过滤、映射、排序、聚合等操作数据。本教程将介绍 Streams 的基本概念&#xff0c;以及如何在 Java 8 中使用 Streams。本教程还包括…

【计算机视觉 | 语义分割】OVSeg:分割一切后,SAM又能分辨类别了,Meta/UTAustin提出全新开放类分割模型

文章目录 一、前言二、研究背景三、论文解读3.1 动机3.2 方法3.3 结果 一、前言 前几日&#xff0c;Meta 推出了「分割一切」AI 模型 Segment Anything&#xff0c;令网友直呼 CV 不存在了&#xff1f;&#xff01; 而在另一篇被 CVPR 2023 收录的论文中&#xff0c;Meta、UT…

《计算机网络——自顶向下方法》精炼——2.2.3-2.2.5

文章目录 引言正文HTTP报文请求行首部行实体体其他方法 HTTP响应报文实体体和初始状态行首部行 cookiecookie的运行过程Web缓存条件GET方法 引言 计算机网络在这一学科中的重要性毋庸置疑&#xff0c;而黑皮书又是这一学科的教科书级经典&#xff0c;因此本书是计算机从业者的…

微服务学习之面试知识相关总结(Redis)

文章目录 前言Redis常见面试知识1 Redis与Memcache的区别2 Redis的单线程问题3 Redis的持久化方案3.1 基础知识3.2 面试话术 4 Redis的集群方式4 Redis的常用数据类型5 Redis事务机制6 Redis的Key过期策略6.1 过期删除策略6.2 内存淘汰策略6.3 面试话术&#xff1a; 7 Redis在项…