Workflow Core 1.6.0 新特性深度解析:Saga 事务与 CompensateWith 补偿机制实战指南
后端工作流自动化流程编排【免费下载链接】workflow-coreLightweight workflow engine for .NET Standard项目地址https://gitcode.com/gh_mirrors/wo/workflow-core点击查看免费下载本篇技术指南聚焦 Workflow Core 1.6.0 版本引入的两大核心能力**Saga 事务Saga transaction**与.CompensateWith补偿特性。1.6.0 的发布说明 ReleaseNotes/1.6.0.md 明确指出这两个特性是本次版本的重点它允许你把一组步骤封装进一个 saga 事务并为其中每一步单独指定反向补偿步骤从而在业务步骤抛异常时自动回滚已完成的副作用。读完本文你将掌握如何用 Fluent API 为 saga 事务配置逐步骤补偿、失败重试与整事务兜底补偿如何向补偿步骤传参如何在 JSON/YAML 中表达 saga以及这套机制在引擎内部的执行原理基于SagaContainer、CompensateHandler与执行指针状态机。一、1.6.0 版本特性概览Workflow Core 1.6.0 的发布说明共列出两项核心变更Added Saga transaction feature—— 新增 Saga 事务特性Added.CompensateWithfeature—— 新增.CompensateWith补偿特性。两者的关系是.CompensateWith是 Saga 事务的配套手段它允许在 saga 内的任意步骤乃至 saga 外、工作流顶层的普通步骤上挂接一个或多个补偿步骤。当被补偿的步骤抛出异常时引擎会自动按相反顺序执行已执行过的步骤所对应的补偿步骤保证事务的副作用被撤销。围绕这一特性1.6.0 的发布说明给出了四类实战场景为 saga 事务的每个组件分别指定补偿步骤、重试失败的事务、补偿整个事务、向补偿步骤传递参数并提供了完整的 JSON 表达示例。下文逐一展开。二、为 saga 事务的每个组件指定补偿步骤Saga 事务的核心用法是用.Saga(...)把一组步骤包裹成一个事务然后对事务内的每个步骤用.CompensateWithTStep()分别指定它的撤销步骤。发布说明中的示例Task2抛异常后UndoTask2与UndoTask1会依次被触发builder .StartWithSayHello() .CompensateWithUndoHello() .Saga(saga saga .StartWithDoTask1() .CompensateWithUndoTask1() .ThenDoTask2() .CompensateWithUndoTask2() .ThenDoTask3() .CompensateWithUndoTask3() ) .ThenSayGoodbye();2.1 执行语义补偿是逆序回滚上述示例的执行语义非常明确若Task2即DoTask2抛出异常那么之前已经成功完成的步骤对应的补偿步骤会按逆序被触发即先UndoTask2、再UndoTask1而尚未执行的DoTask3不会被执行。SayHello也有自己的补偿UndoHello同样在需要时触发。这意味着 saga 事务具备典型的补偿式compensating事务行为不依赖分布式事务中间件而是通过业务层面撤销动作的方式保证最终一致性。2.2 底层机制从.Saga()到SagaContainer从源码看.Saga(...)在 StepBuilder.cs 中并非创建一个普通容器而是创建了一个SagaContainerSequence类型的工作流步骤public IStepBuilderTData, Sequence Saga(ActionIWorkflowBuilderTData builder) { var newStep new SagaContainerSequence(); WorkflowBuilder.AddStep(newStep); var stepBuilder new StepBuilderTData, Sequence(WorkflowBuilder, newStep); Step.Outcomes.Add(new ValueOutcome { NextStep newStep.Id }); builder.Invoke(WorkflowBuilder); stepBuilder.Step.Children.Add(stepBuilder.Step.Id 1); return stepBuilder; }SagaContainerTStepBodySagaContainer.cs本身非常精简却承载了关键语义public class SagaContainerTStepBody : WorkflowStepTStepBody where TStepBody : IStepBody { public override bool ResumeChildrenAfterCompensation false; public override bool RevertChildrenAfterCompensation true; public override void PrimeForRetry(ExecutionPointer pointer) { base.PrimeForRetry(pointer); pointer.PersistenceData null; } }ResumeChildrenAfterCompensation false补偿之后不恢复子步骤继续执行普通容器如Sequence的默认值是trueRevertChildrenAfterCompensation true补偿时回滚所有已完成子步骤即逆序触发它们的补偿步骤PrimeForRetry覆盖重试前清空PersistenceData确保 saga 作为整体从零重跑而不是从失败的中间状态续跑。2.3 补偿步骤的注册CompensationStepId每个步骤的补偿步骤信息存放在WorkflowStep基类的CompensationStepId属性上WorkflowStep.cs。.CompensateWithTStep()的实现StepBuilder.cs会创建补偿步骤并将其 Id 写入Step.CompensationStepIdpublic IStepBuilderTData, TStepBody CompensateWithTStep(ActionIStepBuilderTData, TStep stepSetup null) where TStep : IStepBody { WorkflowStepTStep newStep new WorkflowStepTStep(); WorkflowBuilder.AddStep(newStep); var stepBuilder new StepBuilderTData, TStep(WorkflowBuilder, newStep); if (stepSetup ! null) { stepSetup.Invoke(stepBuilder); } newStep.Name newStep.Name ?? typeof(TStep).Name; Step.CompensationStepId newStep.Id; return this; }也就是说一个步骤的补偿步骤在定义期就被静态地关联起来异常发生时引擎据此查找并调度补偿执行指针。除了泛型版本CompensateWith还提供两个内联重载StepBuilder.cs接受FuncIStepExecutionContext, ExecutionResult或ActionIStepExecutionContext委托方便直接用 lambda 写补偿逻辑。三、重试失败的 saga 事务Saga 事务失败后除了补偿回滚还可以选择整体重试。发布说明中的示例指定了每 5 秒重试一次整个 sagabuilder .StartWithSayHello() .CompensateWithUndoHello() .Saga(saga saga .StartWithDoTask1() .CompensateWithUndoTask1() .ThenDoTask2() .CompensateWithUndoTask2() .ThenDoTask3() .CompensateWithUndoTask3() ) .OnError(Models.WorkflowErrorHandling.Retry, TimeSpan.FromSeconds(5)) .ThenSayGoodbye();3.1.OnError的语义与枚举取值.OnError(WorkflowErrorHandling behavior, TimeSpan? retryInterval null)StepBuilder.cs为步骤设置两个字段public IStepBuilderTData, TStepBody OnError(WorkflowErrorHandling behavior, TimeSpan? retryInterval null) { Step.ErrorBehavior behavior; Step.RetryInterval retryInterval; return this; }WorkflowErrorHandling枚举定义于 WorkflowDefinition.cs枚举值含义Retry稍后按RetryInterval重试失败步骤/容器Suspend挂起工作流等待人工干预后恢复Terminate终止整个工作流实例状态置为TerminatedCompensate执行补偿回滚当Retry与 saga 容器组合时由于SagaContainer.PrimeForRetry会清空PersistenceData重试并非从失败步骤继续而是整个 saga 从头重新执行这就是重试整个事务的实现基础。3.2 重试的时间线计算RetryHandlerRetryHandler.cs是重试行为的落地实现public void Handle(WorkflowInstance workflow, WorkflowDefinition def, ExecutionPointer pointer, WorkflowStep step, Exception exception, QueueExecutionPointer bubbleUpQueue) { pointer.RetryCount; pointer.SleepUntil _datetimeProvider.UtcNow.Add(step.RetryInterval ?? def.DefaultErrorRetryInterval ?? _options.ErrorRetryInterval); step.PrimeForRetry(pointer); }重试间隔的优先级为步骤级RetryInterval 定义级DefaultErrorRetryInterval 全局WorkflowOptions.ErrorRetryInterval。其中全局默认值为 60 秒WorkflowOptions.cs可通过services.AddWorkflow(x x.UseErrorRetryInterval(...))调整。3.3 集成测试佐证saga 重试行为仓库集成测试 RetrySagaScenario.cs 完整验证了该语义一个 3 步骤 saga 中Event1Fired前两次抛异常Event1Fired 3时 throw工作流配置为.OnError(WorkflowErrorHandling.Retry, TimeSpan.FromSeconds(1))。断言结果显示Event1Fired 3步骤执行了 3 次前 2 次失败Event2Fired 1、Event3Fired 1第 3 次整体重跑成功后执行Compensation2Fired 2、Compensation3Fired 2每次失败后已完成的 saga 内步骤StartWith与第一步的补偿都被触发且补偿发生在重试之前Compensation4Fired 0从未执行的第三步不需要补偿最终工作流状态为Complete。这印证了 retry 语义每次失败先逆序补偿已完成步骤再整体重试 saga。四、补偿整个事务master compensation如果不希望为每个步骤分别指定补偿也可以只给整个 saga 指定一个总补偿步骤序列。发布说明的示例builder .StartWithSayHello() .CompensateWithUndoHello() .Saga(saga saga .StartWithDoTask1() .ThenDoTask2() .ThenDoTask3() ) .CompensateWithSequence(comp comp .StartWithUndoTask1() .ThenUndoTask2() .ThenUndoTask3() ) .ThenSayGoodbye();4.1.CompensateWithSequence的实现.CompensateWithSequence(ActionIWorkflowBuilderTData builder)StepBuilder.cs的实现要点public IStepBuilderTData, TStepBody CompensateWithSequence(ActionIWorkflowBuilderTData builder) { var newStep new WorkflowStepSequence(); WorkflowBuilder.AddStep(newStep); var stepBuilder new StepBuilderTData, Sequence(WorkflowBuilder, newStep); Step.CompensationStepId newStep.Id; builder.Invoke(WorkflowBuilder); stepBuilder.Step.Children.Add(stepBuilder.Step.Id 1); return this; }它创建的是一个WorkflowStepSequence容器把整条补偿链挂到外层步骤这里是 saga的CompensationStepId上。当 saga 内任意步骤失败时这条总补偿序列作为 saga 的补偿被执行。注意逐步骤补偿与总补偿是两种可选的建模风格——若每个步骤都声明了自己的CompensateWith则默认按逆序执行各步骤自己的补偿CompensateWithSequence适用于粒度较粗、统一撤销的场景。五、向补偿步骤传递参数补偿步骤同样遵循 Workflow Core 标准的参数注入机制。发布说明中的示例通过Input表达式向补偿步骤传入常量值builder .StartWithSayHello() .CompensateWithPrintMessage(compensate { compensate.Input(step step.Message, data undoing...); })compensate.Input(step step.Message, data undoing...)的含义是把表达式data undoing...这里的data是工作流数据对象TData的结果映射到补偿步骤PrintMessage的Message属性上。由于CompensateWithTStep(ActionIStepBuilderTData, TStep stepSetup)重载暴露了IStepBuilderTData, TStep补偿步骤可以被像普通步骤一样配置Input/Output/BeforeExecute等一切能力——包括读取工作流数据、上下文IStepExecutionContext乃至环境变量详见 DSL 的输入表达式解析逻辑 DefinitionLoader.cs。例如可以从工作流数据中读取原始订单号、用户 ID 等回滚所需的关键信息。六、引擎内部补偿是如何被调度的要真正理解 saga需要了解引擎在异常发生时的调度链路。整体流程如下异常进入错误处理管线ExecutionResultProcessor.HandleStepExceptionExecutionResultProcessor.cs发布WorkflowError生命周期事件将失败指针状态置为PointerStatus.Failed然后计算错误策略并派发到对应的IWorkflowErrorHandler。策略判定错误策略取exceptionStep.ErrorBehavior ?? (shouldCompensate ? WorkflowErrorHandling.Compensate : def.DefaultErrorBehavior)见同一文件第 126 行。ShouldCompensate会向上遍历当前指针的Scope链只要发现某个祖先步骤设置了CompensationStepId或RevertChildrenAfterCompensation true就认定应当补偿。CompensateHandler逆序回滚CompensateHandlerCompensateHandler.cs从失败指针的Scope栈逆序向上遍历将每个涉及的 scope 指针置为Failed/Compensated若该步骤配置了CompensationStepId调用_pointerFactory.BuildCompensationPointer(...)生成补偿执行指针并追加到执行指针集合多个补偿指针之间通过PredecessorId建立先后依赖后一个补偿指针对前一个标记PendingPredecessor状态保证补偿按序执行若步骤的RevertChildrenAfterCompensation true还会找出同一 scope 内所有已Complete的兄弟指针为每个也生成了补偿指针这就是SagaContainer回滚所有已完成子步骤的由来。执行补偿步骤补偿指针的StepId指向补偿步骤定义StepName由def.Steps.FindById(compensationStepId).Name解析ExecutionPointerFactory.cs随后由WorkflowExecutor正常执行这些指针。执行指针状态枚举PointerStatusExecutionPointer.cs中的Compensated 7与PendingPredecessor 9即为补偿流程专用的状态标记。这套机制对上层完全透明你只需要在定义期用.CompensateWith声明关系引擎便自动完成逆序补偿 兄弟回滚 顺序调度。七、用 JSON / YAML 表达 sagaDSL 方式Saga 事务同样可以通过 JSON 或 YAML 声明式定义无需编写 C# 代码。核心规则见 docs/sagas.md 与 1.6.0 发布说明使用WorkflowCore.Primitives.Sequence, WorkflowCore作为容器步骤类型将该步骤的Saga参数设为true此时 DSL 加载器会将其构建为SagaContainer见 DefinitionLoader.csif (nextStep.Saga) containerType typeof(SagaContainer).MakeGenericType(stepType);通过CompensateWith参数为步骤声明补偿步骤列表每个补偿步骤自身也是 Step 对象可以像普通步骤一样配置NextStepId从而形成多步补偿链。7.1 发布说明中的 JSON 示例{ Id: Saga-Sample, Version: 1, DataType: MyApp.MyDataClass, MyApp, Steps: [ { Id: Hello, StepType: MyApp.HelloWorld, MyApp, NextStepId: MySaga }, { Id: MySaga, StepType: WorkflowCore.Primitives.Sequence, WorkflowCore, NextStepId: Bye, Saga: true, Do: [ [ { Id: do1, StepType: MyApp.Task1, MyApp, NextStepId: do2, CompensateWith: [ { Id: undo1, StepType: MyApp.UndoTask1, MyApp } ] }, { Id: do2, StepType: MyApp.Task2, MyApp, CompensateWith: [ { Id: undo2-1, NextStepId: undo2-2, StepType: MyApp.UndoTask2, MyApp }, { Id: undo2-2, StepType: MyApp.DoSomethingElse, MyApp } ] } ] ] }, { Id: Bye, StepType: MyApp.GoodbyeWorld, MyApp } ] }要点拆解Saga: true是 saga 容器的开关Do是一个二维数组用于声明容器内的分支/子步骤[ [ ... ] ]表示单分支顺序执行每个业务步骤的CompensateWith数组列出它的补偿步骤如do2配了undo2-1执行UndoTask2后经NextStepId跳到undo2-2再执行DoSomethingElse——这证明JSON 中一个步骤可以挂多步补偿链补偿步骤无需NextStepId指向业务步骤它只在自己的补偿链内流转。7.2 对应的 YAML 写法相同的定义用 YAML 表达来自 docs/sagas.mdId: Saga-Sample Version: 1 DataType: MyApp.MyDataClass, MyApp Steps: - Id: Hello StepType: MyApp.HelloWorld, MyApp NextStepId: MySaga - Id: MySaga StepType: WorkflowCore.Primitives.Sequence, WorkflowCore NextStepId: Bye Saga: true Do: - - Id: do1 StepType: MyApp.Task1, MyApp NextStepId: do2 CompensateWith: - Id: undo1 StepType: MyApp.UndoTask1, MyApp - Id: do2 StepType: MyApp.Task2, MyApp CompensateWith: - Id: undo2-1 NextStepId: undo2-2 StepType: MyApp.UndoTask2, MyApp - Id: undo2-2 StepType: MyApp.DoSomethingElse, MyApp - Id: Bye StepType: MyApp.GoodbyeWorld, MyApp7.3 DSL 模型与加载细节JSON/YAML 中的这些字段与 DSL 数据模型一一对应。StepSourceV1StepSourceV1.cs声明了Saga默认false、CompensateWithListStepSourceV1、DoListListStepSourceV1、ErrorBehavior、RetryInterval、NextStepId等字段。DefinitionLoader.ConvertStepsDefinitionLoader.cs会在步骤类型解析阶段遇到Saga true就实例化SagaContainerstepType把CompensateWith中的每个子步骤压栈构建并在收尾阶段将列表首元素的ExternalId解析为target.CompensationStepId第 227-237 行若CompensateWith内有多步通过NextStepId串联DSL 会自动把它们注册为独立步骤并通过NextStepId形成补偿链。加载完成后通过IDefinitionLoader.LoadDefinition(source, deserializer)JSON 用JsonConvert.DeserializeObjectDefinitionSourceV1YAML 同理即可注册到工作流注册表之后像普通工作流一样启动运行参见 DefinitionLoader.cs。八、Saga 的完整实战形态结合补偿、重试与错误策略综合 1.6.0 的能力一个生产可用的 saga 事务通常组合运用以下要素saga 内逐步骤补偿每个副作用步骤声明自己的CompensateWith保证最小粒度的回滚saga 级错误策略用.OnError(...)决定失败后是重试Retry 间隔、挂起Suspend等待人工介入还是终止Terminatesaga 外兜底补偿在 saga 外层再用.CompensateWith(...)/.CompensateWithSequence(...)挂总补偿用于处理逐步骤补偿都不适用的场景。仓库集成测试 SagaScenario.cs 正是这种组合形态的写照StartWith带Compensate1saga 内三步各自带补偿saga 外层挂Compensate5尾步骤再挂Compensate6。其ExceptionScenario断言显示当 saga 内第二步抛异常时Compensate2与Compensate3被触发saga 内已完成步骤逆序补偿、Compensate5被触发saga 自身的补偿、Compensate4未触发第三步未执行、最终工作流仍以Complete收尾异常被补偿消化后流程继续。8.1 错误行为配置的优先级无论是 Fluent API 还是 DSL错误行为都遵循同一优先级RetryHandler中体现为step.RetryInterval ?? def.DefaultErrorRetryInterval ?? _options.ErrorRetryInterval步骤自身.OnError(...)指定的行为与间隔工作流定义级DefaultErrorBehavior/DefaultErrorRetryInterval可通过 DSL 的顶层字段配置全局WorkflowOptions.ErrorRetryInterval默认 60 秒WorkflowOptions.cs。特别的若失败步骤没有显式ErrorBehavior引擎会先调用ShouldCompensate检查其 scope 链上是否存在补偿步骤——存在则默认走Compensate策略否则回落到定义级默认策略ExecutionResultProcessor.cs。这就是只要配了CompensateWith就会自动补偿背后的判定逻辑。九、总结与版本延续Workflow Core 1.6.0 的 Saga 事务与.CompensateWith特性为 .NET 工作流引擎补齐了声明式补偿事务能力Fluent API.Saga() 逐步骤.CompensateWithT()、.CompensateWithSequence()、.OnError(WorkflowErrorHandling.Retry, interval)、Input传参DSLWorkflowCore.Primitives.SequenceSaga: trueCompensateWith数组JSON 与 YAML 均可引擎原理SagaContainer的RevertChildrenAfterCompensation与PrimeForRetry、CompensateHandler的逆序回滚与补偿指针链、ExecutionPointerFactory.BuildCompensationPointer、PointerStatus.Compensated/PendingPredecessor状态机共同支撑整个补偿流程。这些能力在后续版本中持续演进相关文档见 docs/sagas.md 与 docs/error-handling.md并沉淀了SagaScenario、RetrySagaScenario、CompensationScenario等一批集成测试作为行为契约位于 test/WorkflowCore.IntegrationTests/Scenarios。如果你正在用 Workflow Core 编排涉及多步外部副作用如扣款、发消息、改库存的业务流程1.6.0 的这套补偿机制就是实现最终一致性最直接的官方方案。赞分享后端工作流自动化流程编排【免费下载链接】workflow-coreLightweight workflow engine for .NET Standard项目地址https://gitcode.com/gh_mirrors/wo/workflow-core点击查看免费下载相关推荐终极指南toBeBetterJavaer中的Saga补偿模式轻松解决分布式事务难题终极指南toBeBetterJavaer中的Saga补偿模式轻松解决分布式事务难题 在分布式系统架构中确保数据一致性是开发者面临的重大挑战。toBeBet文档教程知识库技术博客后端如何用PDF补丁丁快速解决PDF字体缺失问题完整字体嵌入指南如何用PDF补丁丁快速解决PDF字体缺失问题完整字体嵌入指南 你是否遇到过这样的困扰精心制作的PDF文档在不同设备上打开时原本工整的中文字体突然变成一片空桌面应用文档CardView 跨平台适配指南iOS与Android平台差异处理CardView 跨平台适配指南iOS与Android平台差异处理 CardView 是一个功能强大的 Xamarin.Forms 组件库提供了 Cards上一篇Rust集成ONLYOFFICE Docs高性能系统中的文档处理调用下一篇DataX-Web数据库表结构解析深入理解数据同步系统底层架构创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

PHPInsights 配置完全指南:从默认预设到深度自定义的实战手册

PHPInsights 配置完全指南:从默认预设到深度自定义的实战手册

代码质量静态分析 【免费下载链接】phpinsights 🔰 Instant PHP quality checks from your console 项目地址: https://gitcode.com/gh_mirrors/ph/phpinsights 点击查看 免费下载 PHPInsights 开箱即用的默认配置带有较强的主观倾向,未必适…

2026/10/12 1:29:48 阅读更多 →
PyTorch强化学习机器人路径规划:从MDP建模到动态避障实战

PyTorch强化学习机器人路径规划:从MDP建模到动态避障实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 1:29:48 阅读更多 →
火灾火焰检测数据集与YOLO训练实战:三格式标签全解析

火灾火焰检测数据集与YOLO训练实战:三格式标签全解析

简介:面向目标检测学习者和火灾安全相关项目开发者,收录了1000张真实场景火灾与火焰图像,全部人工精标,覆盖多种火势、烟雾、光照和背景干扰情况。资源已按标准结构整理,images文件夹存放原始图片,另设YOLO…

2026/10/12 1:29:48 阅读更多 →

最新新闻

分红时代已死,资本证明时代崛起

分红时代已死,资本证明时代崛起

《分红时代已死,资本证明时代崛起》——下一轮能源周期,市场奖励的不是“投得更多”,而是“证明每一笔钱为何值得花”过去五年,能源公司靠不花钱赢得投资者;未来五年,要靠会花钱。投下去的是资本&#xff0…

2026/10/12 4:01:25 阅读更多 →
OpenUI5源码解析:DesignTime.js如何驱动可视化编辑器

OpenUI5源码解析:DesignTime.js如何驱动可视化编辑器

接触过 OpenUI5 可视化编辑器的同学,应该都对“为什么编辑器知道这个控件能拖拽、那个属性可以改”感到好奇。答案的关键,就藏在一个叫 DesignTime.js 的模块里。这是 OpenUI5 源码解析系列的第三十一篇,我们来把 DesignTime.js 完整拆开。这…

2026/10/12 4:01:25 阅读更多 →
配电网韧性提升:移动储能预布局与动态调度建模与Matlab实现

配电网韧性提升:移动储能预布局与动态调度建模与Matlab实现

1. 项目背景与核心问题剖析1.1 为什么要关注配电网韧性与移动储能先说结论:配电网韧性(Resilience)研究的本质,是在极端扰动发生后让系统"扛得住、恢复快"。传统的可靠性分析更多关注故障概率和平均停电时间&#xff0c…

2026/10/12 4:01:25 阅读更多 →
SSH 连接 VirtualBox 里的 Ubuntu

SSH 连接 VirtualBox 里的 Ubuntu

环境:VirtualBox Ubuntu 22.04.5 LTS(服务器版,镜像 ubuntu-22.04.5-live-server-amd64.iso),宿主机 Windows。初始动机 用 VirtualBox 装完 Ubuntu 服务器版后,一直盯着它自带的小黑框操作,字…

2026/10/12 4:01:25 阅读更多 →
QQ空间代码查询工具:从解压到搭建本地代码库的完整指南

QQ空间代码查询工具:从解压到搭建本地代码库的完整指南

简介:一款基于PHP编写的QQ空间代码查询工具,面向Web开发初学者、PHP爱好者以及想研究QQ空间页面结构与特效实现的用户。使用者只需输入QQ号码,程序便会向QQ空间发起请求,获取页面源码并解析出其中的HTML、CSS与JavaScript代码&…

2026/10/12 4:01:25 阅读更多 →
SonnetDB 统计聚合函数:stddev/variance/spread/median/mode

SonnetDB 统计聚合函数:stddev/variance/spread/median/mode

SonnetDB 统计聚合函数:stddev/variance/spread/median/mode SonnetDB 的统计聚合用于观察时序数据的波动、跨度和常见状态。本文介绍 stddev、variance、spread、median 和 mode,重点说明样本统计、中位数估计和类型边界。内容按 2026-10-11 当前工作树…

2026/10/12 4:00:24 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →