Activiti 面试题
本页只放工作流和 Activiti 的面试标准回答、追问点和知识点跳转。BPMN、流程实例、任务流转、业务表关系、版本、驳回撤回和排查细节统一放在知识点页,深度验收看 Activiti 从零到精通验收清单。
使用方式
mermaid
flowchart TD
A["面试页:先会答"] --> B["知识点页:理解原理"]
B --> C["项目页:能落地审批流"]高频问题
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 怎么判断 Activiti 是否真正学懂 | 不能只会画流程图和完成任务。真正学懂要能讲清工作流和状态机选型、BPMN 元素、流程定义和实例、运行时表和历史表、业务表关联、待办已办、网关变量、驳回撤回、流程版本、事务一致性和生产排查。 | 从零到精通验收清单 |
| Activiti 是什么 | Activiti 是基于 BPMN 的工作流引擎,用来管理流程定义、流程实例、用户任务、网关条件、流程变量和历史轨迹。它适合审批、工单、合同审核等多节点、多角色、需要留痕的业务流程。 | 商业场景训练营、从零到生产级掌握 |
| 工作流解决什么问题 | 工作流把流程从业务代码的 if/else 中抽出来,用 BPMN 显式表达节点、审批人、分支和流转规则,并由引擎负责生成待办、推进流程和记录历史。 | Activiti 总览 |
| 流程定义和流程实例有什么区别 | 流程定义是部署后的流程模板,流程实例是某一次真实业务发起的运行过程。一个流程定义可以创建很多流程实例,类似类和对象的关系。 | 从零到生产级掌握 |
| BPMN为什么不是普通流程图 | BPMN XML中的process key、Activity ID、Sequence Flow、表达式、候选人和事件会被引擎解析并生成Execution、Task、Job和历史;DI坐标主要负责图形显示。图能打开不代表业务模型正确。 | BPMN流程设计 |
| User Task和Service Task有什么区别 | User Task创建人工待办并让Execution持久化等待;Service Task由引擎调用Delegate自动执行。同步Service Task影响当前事务,异步方式通过Job解耦但必须治理幂等、重试和告警。 | Task元素原理 |
| SubProcess和Call Activity怎么选 | 嵌入子流程属于当前定义,适合整理局部复杂度;Call Activity调用独立流程定义,适合跨流程复用和独立发布,但要治理父子定义版本组合、变量映射和故障传播。 | 子流程选型 |
| 多人会签怎么设计 | 动态人员集合通常用Multi-instance User Task,要定义并行/串行、集合来源、空集合、重复人员、同意票统计和completionCondition;固定职责不同的法务与财务更适合并行网关。 | 多实例任务 |
| 业务表和流程表怎么关联 | 业务表保存领域事实、业务状态和processInstanceId;启动时以稳定业务主键作为businessKey,并记录具体processDefinitionId。Runtime保存Execution/Task,History保存轨迹,业务审批记录保存requestId、决定和操作者快照。 | 业务表、流程表与分布式一致性 |
| 怎样保证启动流程和更新业务表一致 | 同数据库且使用同一DataSource和PlatformTransactionManager时放进一个本地事务,并通过故障注入证明同提交/回滚;跨数据库时普通@Transactional无效,应评估XA/JTA,或使用持久化命令、幂等Worker、结果回写和对账。 | 本地事务与跨库方案 |
| Outbox解决什么问题 | Outbox把业务状态和待发送事件写入同一本地事务,Publisher至少一次发送;发送后标记前崩溃会重复,因此消费者用eventId和Inbox/唯一约束幂等。Outbox不能自动原子化两个独立数据库。 | Outbox原理 |
| 分布式锁能保证业务表和流程表一致吗 | 不能。锁只能减少并发,无法让业务库和Activiti库原子提交;持锁期间任一库提交后另一库失败仍会不一致。真正需要事务边界、持久化状态、幂等、重试、补偿和对账。 | 分布式锁边界 |
| 为什么不能直接修改ACT表修流程 | Task、Execution、Identity Link、Variable、Job、History和缓存共同构成状态,直接改一张表会绕过生命周期、Listener、乐观锁和历史维护。应优先公开API、补偿或迁移工具。 | 数据修复边界 |
| 待办和已办怎么查 | 待办查运行时Task,区分assignee、candidate user/group和委派;已办查HistoricTaskInstance并结合业务审批记录。列表通过processInstanceId/businessKey批量关联业务表,避免N+1。 | 任务生命周期与待办已办 |
| assignee 和 candidate 有什么区别 | assignee是当前明确办理人;candidate user/group只是可认领关系。候选任务被claim后通常变成个人待办,其他候选人不应再完成;服务端还必须校验数据权限。 | 任务候选关系 |
| 两个人同时认领或完成任务会怎样 | 两个请求可能都先读到Task,但任务Revision、状态和乐观锁让最终只有一个状态变更成功;业务层要区分同requestId幂等重试和不同用户竞争,并用数据库唯一约束保护审批记录。 | 任务并发控制 |
| 转办和委派有什么区别 | 转办通常永久更换assignee;委派保留owner并把任务交给受托人,受托人resolve后通常返回owner,再由owner最终complete。 | 转办与委派 |
| complete报错后任务为什么还在 | complete会结束Task、推进Execution、计算网关、创建下一Task并写历史,通常在同一事务中;后续表达式、Delegate、业务更新或乐观锁失败会整体回滚,因此原Task仍在是正确结果。 | complete执行全过程 |
| 网关有哪些 | 排他网关只选一条满足条件的出线,作为汇聚时不等待;并行网关激活全部出线并在汇聚处同步;包容网关激活所有条件为真的出线,汇聚时等待本次实际激活且仍可能到达的路径;事件型网关等待首先发生的消息或定时事件。 | 网关、Execution与分支汇聚 |
| 并行网关是不是多线程 | 不是。它表示一个流程实例产生多条并发Execution路径,不保证Java代码在多个线程同时执行;只有结合异步继续和Job Executor才可能由不同线程或节点处理。 | 并行网关执行原理 |
| 为什么流程卡在并行网关 | Join要等待对应并行路径到达。应根据实例真实definitionId查询Task、Execution和Job,确认理论激活几条、实际到达几条;常见原因是任务未完成、Job失败、分支绕过Join或直接改表破坏执行树。 | 并行网关排障 |
| taskService.complete时网关报错会怎样 | 完成Task、推进Execution、计算网关和创建下一Task通常属于同一引擎事务;表达式缺失、类型错误或监听器异常会回滚,所以原Task可能仍存在。 | 任务完成到网关的事务 |
| 驳回怎么设计 | 简单驳回可以在 BPMN 中走拒绝分支;复杂驳回要结合业务动作、目标节点、审批记录和权限校验设计。不能随意开放任意跳转,否则历史轨迹和业务状态容易错乱。 | 从零到生产级掌握 |
| 撤回怎么设计 | 撤回要校验流程是否未结束、当前节点是否允许撤回、当前用户是否发起人或有权限,然后终止或回退流程实例,并同步更新业务状态和审批记录。 | 从零到生产级掌握 |
| 流程版本怎么处理 | 同key的BPMN重复部署通常生成递增版本和新的definitionId。旧实例继续绑定启动时的definitionId,新实例按key启动时通常选择最新激活版本;旧Delegate、变量和表单契约必须保留到存量实例结束。 | 部署、版本与生产发布 |
| Deployment和ProcessDefinition有什么区别 | Deployment是一次资源发布批次,可包含多个BPMN资源和多个定义;ProcessDefinition是某个可执行process解析后形成的具体key、version和definitionId。二者不是固定一对一。 | 部署对象与版本字段 |
| 按key和按definitionId启动有什么区别 | 按key通常选择最新激活版本,简单但新部署可能立即承接流量;按definitionId精确控制版本,适合灰度和租户分批切换,但需要受控发布指针。 | 启动版本选择 |
| Activiti流程怎么回退 | 先阻止错误definitionId继续接收新实例,把新请求切回稳定definitionId,再分类处置已启动实例。重新部署旧XML通常得到更高版本,只是内容回退;它不能撤销业务表、消息和外部副作用。 | 版本回退全过程 |
| 为什么不能直接cascade删除Deployment | 级联删除可能移除定义、运行实例、任务和历史数据,破坏业务关联和审计。应先统计运行实例和保留要求,优先挂起定义或切换发布指针。 | Deployment删除风险 |
| 流程卡住怎么排查 | 先查流程实例和当前任务,再查 execution 卡在哪个活动;重点看网关条件、变量名和类型、并行分支是否全部到达,以及业务状态和流程状态是否事务一致。 | 从零到生产级掌握 |
项目话术
text
在医疗数据资产平台里,数据集发布、敏感字段审核、目录上架这类流程不能只靠状态字段硬写。我们会用 Activiti 管流程定义、任务和历史,用业务表保存数据集、申请状态、当前节点和审批记录。流程变量只放是否敏感、数据等级、审批结果这类小字段,权限和业务状态仍由业务系统控制。常见追问
| 追问 | 回答方向 | 跳转 |
|---|---|---|
| 为什么不把业务数据都放流程变量 | 流程变量适合网关判断和上下文,不适合保存大对象;业务查询、报表和权限应依赖业务表。 | 从零到生产级掌握 |
| Activiti 能不能替代权限系统 | 不能。Activiti 负责流程任务,真正的菜单、数据、按钮和审批权限仍要业务系统校验。 | 从零到生产级掌握 |
| 工作流和状态机怎么选 | 简单固定状态流转用状态机;多节点、多角色、条件分支、待办已办、留痕审计用工作流。 | Activiti 总览 |
| 完成任务后业务状态没变怎么办 | 先确认Runtime Task、Historic Task、下一Execution和实际结束路径,再查requestId、业务更新行数、TransactionManager、并行节点、异步Job和Outbox回写。不能仅因Task不存在就手工改业务状态。 | 完整排查流程 |
怎么判断 Activiti 是否真正学懂
| 验收问题 | 合格回答方向 | 深度知识点 |
|---|---|---|
| 工作流和状态机怎么选 | 简单固定状态用状态机,多节点、多角色、条件分支、待办已办、留痕审计用工作流。 | 从零到精通验收清单 |
| BPMN 图为什么不是普通图片 | BPMN 部署的是 XML,节点 ID、流程 key、变量表达式都会影响运行。 | 从零到精通验收清单 |
| 待办和已办为什么不能查同一张表 | 待办是运行时任务,已办是历史任务;流程结束后运行时数据会清理。 | 从零到精通验收清单 |
| 为什么业务数据不能都放流程变量 | 业务查询、报表、权限、附件、审批记录应由业务表承载,流程变量只存网关判断需要的小字段。 | 从零到精通验收清单 |
| 流程卡在并行网关怎么排查 | 查 execution、并行分支是否全部到达、是否有某个任务未完成或异步任务失败。 | 从零到精通验收清单 |
| 流程版本升级后旧实例怎么办 | 旧实例绑定启动时的definitionId;优先自然结束并保持旧执行代码兼容,必须迁移时要明确节点、任务、变量、Timer和并行Execution映射。 | 部署与版本、从零到精通验收清单 |
面试回答模板
text
Activiti 我会从 BPMN 和业务表边界说起。BPMN 部署后形成流程定义,业务发起时创建流程实例,并用 businessKey 关联业务主键。流程运行时会生成用户任务,审批人完成任务时设置变量,引擎根据网关条件决定下一步,并把过程写入历史表。业务系统不能把所有数据都塞进流程变量,业务状态、权限、表单和审批记录仍要自己设计。本章小结
Activiti 面试页负责“怎么答”。真正要学会,要回到知识点页理解流程定义、流程实例、任务、变量、网关、业务表关联、版本、驳回撤回和线上排查的完整链路。完整验收按 Activiti 从零到精通验收清单 逐项检查。
