当前位置: 首页 > news >正文

工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求

前言

大家好,我是老马。

最近想设计一款审批系统,于是了解一下关于流程引擎的知识。

下面是一些的流程引擎相关资料。

工作流引擎系列

工作流引擎-00-流程引擎概览

工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求

工作流引擎-02-BPM OA ERP 区别和联系

工作流引擎-03-聊一聊流程引擎

工作流引擎-04-流程引擎 activiti 优秀开源项目

工作流引擎-05-流程引擎 Camunda 8 协调跨人、系统和设备的复杂业务流程

工作流引擎-06-流程引擎 Flowable、Activiti 与 Camunda 全维度对比分析

工作流引擎-07-流程引擎 flowable-engine 入门介绍

工作流引擎-08-流程引擎 flowable-engine 优秀开源项目

工作流引擎-09-XState 是一个 JavaScript 和 TypeScript 的状态管理库,它使用状态机和状态图来建模逻辑

Activiti 基础介绍

主页:http://activiti.org

是什么

在解释activiti之前我们看一下什么是工作流。

workflow-工作流

工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。

我的理解是,工作流将一套大的业务逻辑分解成业务逻辑段, 并统一控制这些业务逻辑段的执行条件,执行顺序以及相互通信。

实现业务逻辑的分解和解耦。

Activiti

Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求。

Activiti Cloud 现在是新一代的业务自动化平台,提供一组旨在在分布式基础架构上运行的云原生构建块。

BPMN即业务流程建模与标注(Business Process Model and Notation,BPMN) ,描述流程的基本符号,包括这些图元如何组合成一个业务流程图(Business Process Diagram)。

快速开始

开始方式

可以基于云,也可以基于 java api 进行实现。

我们这里进行 java 的入门学习,java core api。

Activiti Core Runtime API 入门

创建新 API 的目的很明确,旨在满足以下要求:

  • 为我们的云方法提供清晰的路径

  • 隔离内部和外部 API 以提供向前的向后兼容性

  • 通过遵循单一职责方法提供模块化的未来路径

  • 减少旧版本 API 的混乱

  • 将安全和身份管理作为一等公民

  • 减少常见用例的价值实现时间,在这些用例中您希望依赖流行框架提供的约定

  • 提供底层服务的替代实现

  • 使社区能够在尊重既定合同的同时进行创新

我们尚未弃用旧 API,因此您仍然可以自由使用它,但我们强烈建议使用新 API 以获得长期支持。

此 API 处于测试阶段,这意味着我们可能会在 GA 发布之前对其进行更改和完善。我们将感谢我们从社区用户那里获得的所有反馈,如果您想参与该项目,请与我们联系。

是时候让我们接触几个示例项目了。

任务运行时 API

如果您正在构建业务应用程序,为您组织中的用户和组创建任务可能会很方便。

TaskRuntime API 可以帮助您。

你可以从 GitHub 克隆这个例子:https://github.com/Activiti/activiti-examples

本节的代码可以在 activiti-api-basic-task-example maven 模块中找到。

如果您在 Spring Boot 2 应用程序中运行,您只需要添加 activiti-spring-boot-starter 依赖项和一个 DB 驱动程序,您可以使用 H2 进行内存存储。

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/pom.xml#L45

maven 引入

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

我们建议使用我们的 BOM

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/pom.xml#L30

<dependencyManagement><dependencies><dependency><groupId>org.activiti.dependencies</groupId><artifactId>activiti-dependencies</artifactId><version>7.1.0.M5</version><scope>import</scope><type>pom</type></dependency></dependencies>
</dependencyManagement>

现在让我们切换到我们的 DemoApplication.class:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L25

TaskRuntime

然后你就可以使用 TaskRuntime:

@Autowired
private TaskRuntime taskRuntime;

例如,您可以通过执行以下操作来创建任务:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L45

taskRuntime.create(TaskPayloadBuilder.create().withName("First Team Task").withDescription("This is something really important").withGroup("activitiTeam").withPriority(10).build());

此任务仅对属于 activitiTeam 的用户和所有者(当前登录的用户)可见。

您可能已经注意到,您可以使用 TaskPayloadBuilder 以流畅的方式参数化将要发送到 TaskRuntime 的信息。

为了处理安全性、角色和组,我们依赖 Spring Security 模块。

因为我们在 Spring Boot 应用程序中,所以我们可以使用 UserDetailsService 来配置可用用户及其各自的组和角色。

我们目前正在 @Configuration 类中执行此操作:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplicationConfiguration.java#L26

这里需要注意的重要一点是,为了作为用户与 TaskRuntime API 交互,您需要具有角色:ACTIVITI_USER (Granted Authority: ROLE_ACTIVITI_USER) 。

在与 REST 端点交互时,授权机制将设置当前登录的用户,但为了示例,我们使用了一个实用程序类(SecurityUtil.java#L26) 允许我们在上下文中设置手动选择的用户。

请注意,除非您正在尝试并且想在不通过 REST 端点的情况下更改用户,否则您永远不应该这样做。

查看“网络”示例以查看更多根本不需要此实用程序类的真实场景。

示例中要强调的最后一件事是任务事件侦听器的注册:

DemoApplication.java#L89

@Bean
public TaskRuntimeEventListener taskAssignedListener() {return taskAssigned-> logger.info(">>> Task Assigned: '"+ taskAssigned.getEntity().getName()+"' We can send a notification to the assignee: "+ taskAssigned.getEntity().getAssignee());
}

您可以根据需要注册任意数量的 TaskRuntimeEventListener。

这将使您的应用程序能够在服务触发运行时事件时收到通知。

进程运行时 API

以类似的方式,如果您想开始使用 ProcessRuntime API,您需要包含与以前相同的依赖项。

我们的目标是在未来提供更多的灵活性和独立的运行时,但现在同一个 Spring Boot Starter 提供 TaskRuntime 和 ProcessRuntime API。

本节的代码可以在“activiti-api-basic-process-example”maven 模块中找到。

接口

public interface ProcessRuntime {ProcessRuntimeConfiguration configuration();ProcessDefinition processDefinition(String processDefinitionId);Page processDefinitions(Pageable pageable);Page processDefinitions(Pageable pageable,GetProcessDefinitionsPayload payload);ProcessInstance start(StartProcessPayload payload);Page processInstances(Pageable pageable);Page processInstances(Pageable pageable,GetProcessInstancesPayload payload);ProcessInstance processInstance(String processInstanceId);ProcessInstance suspend(SuspendProcessPayload payload);ProcessInstance resume(ResumeProcessPayload payload);ProcessInstance delete(DeleteProcessPayload payload);void signal(SignalPayload payload);...
}

与 TaskRuntime API 类似,为了与 ProcessRuntime API 交互,当前登录的用户需要具有“ACTIVITI_USER”角色。

自动装配

首先,让我们自动装配我们的 ProcessRuntime:

DemoApplication.java#L32

@Autowired
private ProcessRuntime processRuntime;@Autowired
private SecurityUtil securityUtil;

和以前一样,我们需要我们的 SecurityUtil 助手来定义我们正在与我们的 API 交互的用户。

现在我们可以开始与 ProcessRuntime 交互:

DemoApplication.java#L47

Page processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
logger.info("> Available Process definitions: " +processDefinitionPage.getTotalItems());
for (ProcessDefinition pd : processDefinitionPage.getContent()) {logger.info("\t > Process definition: " + pd);
}

流程定义需要放在 /src/main/resources/processes/ 中。

对于本示例,我们定义了以下流程:

我们正在使用 Spring 调度功能每秒启动一个进程,从数组中获取随机值以进行处理:

DemoApplication.java#L67

@Scheduled(initialDelay = 1000, fixedDelay = 1000)
public void processText() {securityUtil.logInAs("system");String content = pickRandomString();SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy HH:mm:ss");logger.info("> Processing content: " + content+ " at " + formatter.format(new Date()));ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder.start().withProcessDefinitionKey("categorizeProcess").withProcessInstanceName("Processing Content: " + content).withVariable("content", content).build());logger.info(">>> Created Process Instance: " + processInstance);
}

和以前一样,我们使用 ProcessPayloadBuilder 以流畅的方式参数化我们想要启动哪个流程以及使用哪些流程变量。

现在,如果我们回顾流程定义,您会发现 3 个服务任务。

为了提供这些服务任务的实现,您需要定义连接器:

DemoApplication.java#L81

@Bean
public Connector processTextConnector() {return integrationContext -> {Map inBoundVariables = integrationContext.getInBoundVariables();String contentToProcess = (String) inBoundVariables.get("content")// Logic Here to decide if content is approved or notif (contentToProcess.contains("activiti")) {logger.info("> Approving content: " + contentToProcess);integrationContext.addOutBoundVariable("approved",true);} else {logger.info("> Discarding content: " + contentToProcess);integrationContext.addOutBoundVariable("approved",false);}return integrationContext;};
}

这些连接器使用 Bean 名称自动连接到 ProcessRuntime,在本例中为“processTextConnector”。

这个 bean 名称是从我们流程定义中的 serviceTask 元素的 implementation 属性中提取的:

categorize-content.bpmn20.xml#L22

<bpmn:serviceTask id="Task_1ylvdew" name="Process Content" implementation="processTextConnector">

这个新的连接器接口是 JavaDelegates 的自然演变,新版本的 Activiti Core 将尝试通过将它们包装在连接器实现中来重用你的 JavaDelegates:

public interface Connector {IntegrationContext execute(IntegrationContext integrationContext);
}

连接器接收带有流程变量的 IntegrationContext 并返回修改后的 IntegrationContext 以及需要映射回流程变量的结果。

在前面的示例中,连接器实现正在接收“内容”变量并根据内容处理逻辑添加“已批准”变量。

在这些连接器中,您可能会包含系统到系统调用,例如 REST 调用和基于消息的交互。 这些交互往往变得越来越复杂,因此我们将在未来的教程中看到如何从 ProcessRuntime(云连接器)上下文之外运行中提取这些连接器,以解耦此类外部交互的责任。 ProcessRuntime 范围。

检查 maven 模块 activiti-api-spring-integration-example 以获得更高级的示例,使用 Spring Integrations 基于文件轮询器启动进程。

相关文章:

工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求

前言 大家好&#xff0c;我是老马。 最近想设计一款审批系统&#xff0c;于是了解一下关于流程引擎的知识。 下面是一些的流程引擎相关资料。 工作流引擎系列 工作流引擎-00-流程引擎概览 工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎&#x…...

自定义geojson生成物体的样式

在上节我们学习了如何在cesium中导入geojson数据,本节我们来学习如何让它变得更加炫酷. // 加载GeoJSON数据 // 使用Cesium的GeoJsonDataSource加载指定URL的地理数据 Cesium.GeoJsonDataSource.load("https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json&quo…...

在tensorflow源码环境里,编译出独立的jni.so,避免依赖libtensorflowlite.so,从而实现apk体积最小化

需要在APP里使用tensorflow lite来运行PC端训练的model.tlite&#xff0c;又想apk的体积最小&#xff0c;尝试了如下方法&#xff1a; 1. 在gradle里配置 implementation("org.tensorflow:tensorflow-lite:2.16.1") 这样会引入tensorflow.jar&#xff0c;最终apk的…...

springboot框架 集成海康ISUP-SDK 并实现 协议透传给设备下发指令!

最近有一个需求 需要通过springboot框架 来和 海康的摄像头设备进行通信&#xff0c;就研究了一下 海康的官方ISUP-SDK 文档对接。这个sdk 主要实现了 第三方快速集成海康的设备。 海康的文档地址&#xff1a; https://open.hikvision.com/docs/docId?productId5cda567cf47ae8…...

【移动应用安全】Android系统安全与保护机制

Android系统安全与保护机制是一个多层次、多维度的防御体系&#xff0c;其安全架构与系统层级紧密耦合。以下是对各层级安全机制的扩展分析&#xff1a; Linux内核层&#xff08;Linux Kernel&#xff09;安全机制 强制访问控制&#xff08;MAC&#xff09; 通过SELinux&#…...

Spring Boot中如何使用RabbitMQ?

前面已经了解了怎么使用RabbitMQ的JDK原生客户端&#xff0c;现在我们来了解Spring Boot中如何使用RabbitMQ&#xff0c;在学习之前&#xff0c;先做好准备工作&#xff1a; 1. 添加依赖 在Spring Boot中使用RabbitMQ&#xff0c;需要使用如下依赖&#xff1a; <dependenc…...

kotlin 将一个list按条件分为两个list(partition )

前言 在安卓开发过程中&#xff0c;我们经常需要将一个列表按照特定条件拆分为两个子列表。随着对语言的深入理解&#xff0c;我发现了一些更高效、更简洁的实现方式&#xff0c;现在与大家分享。 实现 传统Java实现 假设我们有以下列表需要处理&#xff1a; List<Stri…...

R语言学习--Day04--数据分析技巧

在清洗完数据&#xff0c;在对数据分析前&#xff0c;我们要懂得先梳理一下我们的逻辑&#xff0c;即数据是什么形式的&#xff0c;要进行哪种分析&#xff0c;有可能呈现什么特点&#xff0c;进而再想怎么处理数据去画图可以最大程度地凸显我们要的特点。 一般来讲&#xff0…...

企业终端设备的安全管控

企业终端设备的安全管控是信息安全体系中的重要环节&#xff0c;涉及从设备准入到数据防护的全生命周期管理。 以下是一套系统化的解决方案&#xff0c;涵盖技术、管理和人员三个维度&#xff1a; 一、终端设备全生命周期管控 设备准入控制 802.1X网络认证&#xff1a;对接企业…...

桥梁凝冰在线监测装置:科技守护道路安全的新防线

在交通基础设施安全领域&#xff0c;桥梁凝冰问题始终是冬季道路管理的重点挑战。传统人工巡检方式存在时效性差、覆盖范围有限等缺陷&#xff0c;而桥梁凝冰在线监测装置的普及应用&#xff0c;正为这一难题提供智能化解决方案。 一、装置工作原理 桥梁凝冰在线监测装置通过多…...

【开源】一个基于 Vue3 和 Electron 开发的第三方网易云音乐客户端,具有与官方客户端相似的界面布局

&#x1f3b5; XCMusic&#xff1a;高颜值第三方网易云音乐客户端 &#x1f3b6; &#x1f4cd; 项目亮点 XCMusic 是一款基于Vue3Electron开发的开源、跨平台网易云音乐客户端。 此音乐播放器基于 Electron 开发&#xff0c;旨在为用户提供简洁、美观、兼容多平台的音乐体验。…...

Android 中拖拽从一个组件到另外一个组件的写法(跨容器拖拽)

在 Android 中&#xff0c;拖拽一个图片&#xff08;例如 ImageView&#xff09;到另一个组件&#xff08;如 LinearLayout、FrameLayout 等容器&#xff09;涉及以下步骤&#xff1a; 准备工作 源组件&#xff1a;你从哪里开始拖动&#xff08;如 ImageView&#xff09;。 目…...

MATLAB实现GAN用于图像分类

生成对抗网络&#xff08;GAN&#xff09;是一种强大的生成模型&#xff0c;由生成器&#xff08;Generator&#xff09;和判别器&#xff08;Discriminator&#xff09;组成。生成器用于生成图像&#xff0c;判别器用于判断图像是真实的还是生成的。在MATLAB中实现GAN用于图像…...

武汉副市长李湛莅临指导 珈和展会精彩亮相引《武汉电视台》深度报道 以硬核科技赋能农业强链新范式获政府媒体“双重点赞”

为充分响应“双循环”新发展格局&#xff0c;深化区域产业协作、推动供需精准对接&#xff0c;进一步促进经济高质量发展&#xff0c;5月16日-18日&#xff0c;由武汉市经济和信息化局主办的2025年产业链供需对接&#xff08;绍兴&#xff09;推广活动在绍兴国际会展中心举办。…...

matlab慕课学习3.4

于20250319 3.4用for语句实现循环结构 3.4.1什么是循环结构 循环结构又称重复结构&#xff0c;是利用计算机运算速度快以及能进行逻辑控制的特点来重复执行某些操作。 3.4.2for语句 for 循环变量表达式1&#xff1a;表达式2&#xff1a;表达式3 循环体语句 end 说明&…...

matlab编写的BM3D图像去噪方法

BM3D&#xff08;Block-Matching and 3D Filtering&#xff09;是一种基于块匹配和三维滤波的图像去噪方法&#xff0c;广泛应用于图像处理领域。它通过在图像中寻找相似的块&#xff0c;并将这些块堆叠成三维数组进行滤波处理&#xff0c;从而有效地去除噪声&#xff0c;同时保…...

当科技邂逅浪漫:在Codigger的世界里,遇见“爱”

520&#xff0c;一个充满爱意的日子&#xff0c;人们用各种方式表达对彼此的深情。而在科技的世界里&#xff0c;我们也正经历着一场特别的邂逅——Codigger&#xff0c;一个分布式操作系统的诞生&#xff0c;正在以它独特的方式&#xff0c;重新定义我们与技术的关系。 Codigg…...

深入理解 Python 中的几种方法:实例方法、类方法、静态方法与特殊方法

前置阅读&#xff0c;了解什么是类属性、实例属性&#xff0c;对于理解类方法、实例方法会有帮助&#xff1a;Python 中的类属性与实例属性详解 0、总体介绍 在 Python 中&#xff0c;方法&#xff08;method&#xff09; 是定义在类&#xff08;class&#xff09;内部的函数&…...

游戏开发实战(二):Python复刻「崩坏星穹铁道」嗷呜嗷呜事务所---源码级解析该小游戏背后的算法与设计模式【纯原创】

文章目录 奇美拉和队列奇美拉被动技能多对多观察者关系实现自定义元类奇美拉基类 管理奇美拉的队列奇美拉队列类心得体会扩展 规则定义工作相关奇美拉相关 奇美拉属性 在本篇博文&#xff0c;我将介绍本项目的整体框架&#xff0c;以及“编码规则”&#xff0c;这些规则保证了本…...

Python实战:打造一个功能完整的单位转换器(长度/温度/货币)

&#x1f4da; 文章导读 在本文中&#xff0c;我将为大家介绍如何使用Python开发一个实用的单位转换器。这个项目不仅适合Python初学者练手&#xff0c;也能帮助你更好地理解Python的基础语法和函数设计。 &#x1f50d; 主要特性 ✅ 支持多种长度单位互转&#xff08;米、千…...

嵌入式学习笔记 D24 :系统编程之i/o操作

系统编程基本概念及一般组成文件的常见i/o操作 一、系统编程基本概念及一般组成 系统编程属于应用程序编程&#xff0c;即在操作系统运行成功的基础上执行程序。其一般包含以下四部分&#xff1a; 1&#xff09;文件&#xff1a;存储在存储设备上的相关信息集合&#xff0c;是…...

利用朴素贝叶斯对UCI 的 mushroom 数据集进行分类

朴素贝叶斯&#xff08;Naive Bayes&#xff09;是一种基于贝叶斯定理的简单而有效的分类算法&#xff0c;特别适合处理文本分类和多类别分类问题。UCI的Mushroom数据集是一个经典的分类数据集&#xff0c;包含蘑菇的特征和类别&#xff08;可食用或有毒&#xff09;。 1. 数据…...

Index-AniSora模型论文速读:基于人工反馈的动漫视频生成

Aligning Anime Video Generation with Human Feedback 一、引言 论文开头指出&#xff0c;尽管视频生成模型不断涌现&#xff0c;但动漫视频生成面临动漫数据稀缺和运动模式异常的挑战&#xff0c;导致生成视频存在运动失真和闪烁伪影等问题&#xff0c;难以满足人类偏好。现…...

FineBI 和 Axure工具比较——数据分析VS原型设计

FineBI和Axure是两款定位截然不同的工具&#xff0c;分别服务于数据分析和原型设计领域。以下从核心功能、应用场景、操作门槛等维度进行对比分析&#xff1a; 一、核心功能对比 FineBI 作为商业智能&#xff08;BI&#xff09;工具&#xff0c;聚焦于数据整合、清洗、分析及可…...

跟踪AI峰会,给自己提出的两个问题。

踪红杉AI峰会全纪录&#xff1a;AI打开万亿美元市场&#xff0c;卖的不是工具&#xff0c;而是收益。 原文链接&#xff1a; 红杉AI峰会全记录&#xff1a;AI打开万亿美元市场&#xff0c;卖的不是工具&#xff0c;而是收益&#xff08;全文&#xff09;_腾讯新闻 自己的学习…...

分布式ID生成器:原理、对比与WorkerID实战

一、为什么需要分布式ID&#xff1f; 在微服务架构下&#xff0c;单机自增ID无法满足跨服务唯一性需求&#xff0c;且存在&#xff1a; • 单点瓶颈&#xff1a;数据库自增ID依赖单表写入 • 全局唯一性&#xff1a;跨服务生成可能重复 • 扩展性差&#xff1a;分库分表后ID规…...

AR 开启昆虫学习新视界,解锁奇妙微观宇宙

在传统昆虫学习中&#xff0c;课堂教学是主要方式&#xff0c;老师通过板书、PPT 传授知识&#xff0c;但学生被动接受&#xff0c;书本静态图片无法展现昆虫真实比例、立体形态&#xff0c;学生难以直观感受复杂身体结构。博物馆的昆虫标本也是学习途径&#xff0c;不过标本放…...

WPF技巧-常用的Converter集合(更新ing)

文章目录 [toc]&#x1f9e9; 示例 1&#xff1a;BooleanToVisibilityConverter&#x1f9e9; 示例 2&#xff1a;InvertedBooleanToVisibilityConverter&#x1f9e9; 示例 3&#xff1a;StringToColorConverter&#x1f9e9; 示例 4&#xff1a;StringToBrushConverter&#…...

PostGIS栅格数据类型解析【raster】

PostGIS 栅格数据类型解析&#xff1a;结构、转换与应用 一、栅格数据类型概述 在 PostGIS 中&#xff0c;raster 是用于存储和处理栅格数据的核心类型&#xff0c;支持从多种格式&#xff08;如 JPEG、GeoTIFF、PNG、DEM&#xff09;导入的数据。每个栅格由一个或多个波段&a…...

985,成立人工智能学院

5月17日&#xff0c;北京理工大学AI变革与科教创新论坛暨人工智能学院成立大会在中关村校区举行。 北京理工大学校长姜澜介绍了学校近年来高质量发展取得的成绩。他表示&#xff0c;北京理工大学对人工智能高度重视、提前布局&#xff0c;具备扎实基础。学校将通过“一零一一”…...

使用 ARCore 和 Kotlin 开发 Android 增强现实应用入门指南

环境准备 1. 工具与设备要求 Android Studio&#xff1a;Arctic Fox 或更高版本设备&#xff1a;支持 ARCore 的 Android 设备&#xff08;查看支持列表&#xff09;依赖库&#xff1a;// build.gradle (Module级) dependencies {implementation com.google.ar:core:1.35.0im…...

房贷利率计算前端小程序

利率计算前端小程序 视图效果展示如下&#xff1a; 在这里插入代码片 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&qu…...

剧本杀小程序:指尖上的沉浸式推理宇宙

在推理热潮席卷社交圈的当下&#xff0c;你是否渴望随时随地开启一场烧脑又刺激的冒险&#xff1f;我们的剧本杀小程序&#xff0c;就是你掌心的“推理魔法盒”&#xff0c;一键解锁无限精彩&#xff01; 海量剧本库&#xff0c;满足多元口味&#xff1a;小程序汇聚了从古风权…...

shp2pgsql 导入 Shp 到 PostGIS 空间数据库

前言 ❝ shp2pgsql是PostGIS自带的命令行工具&#xff0c;用于将Shapefile文件声称SQL脚本导入到PostGIS空间数据库。 1. 安装 PostGIS 通过Application Stack Builder或者下载单独的PostGIS包进行安装。而shp2pgsql则是与PostGIS工具集成在一起&#xff0c;无需单独下载。该命…...

什么是 ERP、MES、PLM,生产制造中如何应用

生产制造领域数字化转型加速背景下&#xff0c;ERP、MES、PLM 系统的应用成为企业提升竞争力的关键。然而&#xff0c;部分企业因对三者功能认知模糊、系统搭配不当、实施流程缺失&#xff0c;导致生产计划混乱、库存失衡、质量管控失效等问题频发。明晰系统功能定位与协同逻辑…...

Android Edge-to-Edge

Android Edge-to-Edge显示&#xff1a;开发者综合指南 一、什么是Android Edge-to-Edge ​ Android Edge-to-Edge是一种先进的用户界面&#xff08;UI&#xff09;设计理念&#xff0c;旨在最大化利用设备的显示区域。它允许应用程序的内容延伸至屏幕的各个边缘&#xff0c;包…...

Java期末总复习 编程题(偏基础)

71. ①编写一个含 2 个属性的类&#xff0c;并为其设计有参构造方法&#xff0c;再设计一个用于显示属性值的方法。②编写该类的一个子类&#xff0c;除继承父类的 2 个属性外再增加一个属性&#xff0c;并创建有参构造方法对 3个属性初始化&#xff0c;重写显示属性的方法用于…...

进阶知识:自动化框架开发之有参的函数装饰器@wraps()和无参之间的对比

进阶知识&#xff1a;自动化框架开发之有参的函数装饰器wraps() 一、核心代码解析 1.1 有参装饰器结构 def func_3(argTrue): # 外层接收参数def inner_func(func): # 中间层接收被装饰函数wraps(func) # 保留元信息def wrap_func(*args, **kwargs): …...

es疑惑解读

好的&#xff0c;没问题。下面是我们对话中关于 Elasticsearch 数据库的知识点汇总&#xff0c;以问答对的形式呈现&#xff0c;希望能成为一个清晰的教程。 Elasticsearch 基础与 CRUD 操作 Q1: 我有 pymysql 的使用经验&#xff0c;想学习 Elasticsearch (ES) 的增删改查&am…...

Elasticsearch面试题带答案

Elasticsearch面试题带答案 Elasticsearch面试题及答案【最新版】Elasticsearch高级面试题大全(2025版),发现网上很多Elasticsearch面试题及答案整理都没有答案,所以花了很长时间搜集,本套Elasticsearch面试题大全,Elasticsearch面试题大汇总,有大量经典的Elasticsearch面…...

Linux 的 TCP 网络编程 -- 回显服务器,翻译服务器

目录 1. 相关函数介绍 1.1 listen() 1.2 accept() 1.3 connect() 2. TCP 回显服务器 2.1 Common.hpp 2.2 InetAddr.hpp 2.3 TcpClient.cc 2.4 TcpServer.hpp 2.5 TcpServer.cc 2.6 demo 测试 3. TCP 翻译服务器 3.1 demo 测试 1. 相关函数介绍 其中一些函数在之前…...

差动讯号(2):奇模与偶模

我们经常在探讨差动对时经常听到差模&#xff08;Differential mode&#xff09;与共模&#xff08;Common mode&#xff09;&#xff0c;究竟什么是差模&#xff1f; 什么是共模&#xff1f; 这一切就要从奇模&#xff08;Odd mode&#xff09;与偶模&#xff08;Even mode&am…...

口腔牙科小程序源码介绍

基于ThinkPHP、FastAdmin以及UniApp开发的口腔牙科小程序源码&#xff0c;专为口腔牙科行业设计&#xff0c;旨在提供一个便捷、高效的线上服务平台。 从技术层面看&#xff0c;这套源码结合了ThinkPHP的强大后端功能、FastAdmin的快速开发特性以及UniApp的跨平台优势&#xf…...

云计算与大数据进阶 | 27、存储系统如何突破容量天花板?可扩展架构的核心技术与实践—— 分布式、弹性扩展、高可用的底层逻辑(上)

数据中心里&#xff0c;存储系统是至关重要的组成部分。由于相关硬件组件与存储操作系统的多样性和复杂性&#xff0c;如何在保证存储稳定、安全、可靠的同时&#xff0c;实现灵活扩展和自服务&#xff0c;一直是困扰数据中心全面云化的难题。 简单来说&#xff0c;现在的难题…...

企业级物理服务器选型指南 - 网络架构优化篇

在分布式系统架构中&#xff0c;物理服务器的网络质量直接影响业务连续性。本文将通过真实场景演示如何选择符合业务特性的物理服务器。 一、网络拓扑设计原则 当企业需要覆盖多地域用户时&#xff0c;建议采用混合组网方案&#xff1a; # 网络质量检测脚本&#xff08;Pytho…...

可视化图解算法42:寻找峰值

牛客网 面试笔试TOP101 | LeetCode 162. 寻找峰值 1. 题目 描述 给定一个长度为n的数组nums&#xff0c;请你找到峰值并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回任何一个所在位置即可。 1.峰值元素是指其值严格大…...

java每日精进 5.20【MyBatis 联表分页查询】

1. MyBatis XML 实现分页查询 1.1 实现方式 MyBatis XML 是一种传统的 MyBatis 使用方式&#xff0c;通过在 XML 文件中编写 SQL 语句&#xff0c;并结合 Mapper 接口和 Service 层实现分页查询。分页需要手动编写两条 SQL 语句&#xff1a;一条查询分页数据列表&#xff0c;…...

瀚高安全版4.5.8/4.5.9字符串默认按字节存储导致数据无法写入(APP)

文章目录 环境文档用途详细信息 环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;4.5 文档用途 解决安全版4.5.8/4.5.9字符串默认使用字节存储导致插入时提示数据超长。 详细信息 使用sysdba用户执行&#xff0c;重载配置或重启数据库…...

python新手学习笔记①

本笔记是根据Bilibili里的【3小时超快速入门Python | 动画教学【2025新版】【自学Python教程】【零基础Python】【计算机二级Python】【Python期末速成】】 https://www.bilibili.com/video/BV1Jgf6YvE8e/这个视频合集制作的代码笔记&#xff01; 1.字符串连接 运行结果 2.…...

用于管理共享内存的 C# 类 ShareMemory

可以在 Windows 和 Linux 上运行&#xff0c;利用了 .NET Core 的 System.IO.MemoryMappedFiles 库。这个类实现了共享内存的创建、打开、读取和写入功能。以下是对代码的一些分析和建议改进。 代码分析 初始化与打开共享内存: Init 方法用于创建新的共享内存段。OpenMem 方法…...