像挑选书籍一样挑选技术:略读、精读,还是直接跳过?

这篇文章,想记录的是:当我面对一个新技术时,我是怎么决定要不要深入学习它的。

起因是工作流引擎。最近项目里要用 Flowable,我像往常一样,准备花几周时间啃源码、画类图、写笔记。但动手之前,我突然问了自己一个问题:

这个技术,真的值得我投入这么多精力吗?

这个问题让我停下来,重新审视了一遍自己的学习策略。慢慢地,我形成了一套判断标准------就像我们挑选书籍一样:有些值得精读,有些略读即可,有些直接跳过。

这不是说工作流不重要,而是说:不是所有技术都需要用同样的深度去学习


一、技术学习的困境:什么都想学,什么都学不深

我们都经历过这种焦虑:

  • 听说团队要引入工作流引擎,赶紧去看 Flowable 文档
  • 看到别人讨论规则引擎,担心自己落后了,马上去研究 Drools
  • 刷到一篇 Netty 源码解析,觉得"高并发必备",收藏准备周末啃
  • Redis 的跳表、Kafka 的零拷贝、MySQL 的 MVCC......技术清单越列越长

结果就是:每个都学了一点,每个都没学透。更糟糕的是,花了大量时间研究的东西,可能在实际工作中根本用不上,或者只是当黑盒用一下就够了。

问题出在哪?我觉得是没有分层学习的意识。

就像读书一样:

  • 工具书,查到需要的就行(字典)
  • 经典著作,值得反复精读(红楼梦)
  • 畅销小说,快速翻完即可(爽文)
  • 有些书,看目录就够了

技术学习也应该这样。


二、我的判断框架:三个问题决定学习深度

经过这次对工作流的思考,我给自己总结了三个判断标准:

问题1:它的核心是算法/理论创新,还是工程组合?

值得精读的技术,通常包含计算机科学的核心知识:

  • MySQL 的 B+ 树:理解索引为什么这样设计,为什么范围查询快,为什么联合索引有顺序要求
  • Redis 的跳表:理解概率平衡的巧妙,为什么比红黑树更适合有序集合
  • Raft 算法:理解分布式共识的本质,为什么需要日志复制
  • Netty 的 Reactor 模型:理解 I/O 多路复用,为什么能高并发

这些技术学到的是可迁移的知识------学会了跳表,你就理解了概率数据结构的思想;学会了 Raft,你就掌握了一类共识问题的解法。

只需略读或黑盒使用的技术,更多是工程堆砌:

  • Swagger:注解解析 + 模板渲染,没什么核心算法
  • Hibernate:ORM 映射 + SQL 生成,工程复杂但理论简单
  • Spring:依赖注入 + AOP + 一堆整合,庞大但不深奥

这类技术的复杂度来自需求的累积,而不是算法本身的难度。学会用比学实现重要。

问题2:理解它的本质模型,需要看源码吗?

有些技术,你只要抓住了核心抽象,就已经理解了 80% 的本质。剩下的 20% 是工程细节,看不看源码区别不大。

这就是我给自己的第二个判断标准:能不能通过抽象推导出它的大致实现?

如果答案是"能",那就没必要深挖源码。

问题3:我的目标是解决问题,还是掌握技术本身?

最后一个问题,也是最容易被忽略的:

你学这个技术,到底是为了什么?

  • 如果是为了在项目里用好它,那学会 API、理解适用场景、知道坑在哪,就够了
  • 如果是为了成为这个领域的专家、写技术书、做开源贡献,那确实需要深入源码

大部分时候,我们只是要用好一个工具,而不是成为工具的制造者。


三、用工作流引擎验证我的判断框架

现在,让我用工作流引擎来验证一下这三个问题。

它的核心是算法创新,还是工程组合?

我试着不看任何文档,靠直觉推导一下工作流引擎可能是怎么实现的。

在我看来,工作流本质上就是三样东西:

1. 一张通用的"骨干图"(流程定义)

图里描述了有哪些节点、哪些连线、哪些条件判断、哪些分支。这张图是所有实例共享的模板。

就像游戏地图:定义了城市A、城市B、城市C,以及它们之间的道路和传送门。

2. 一条"复刻这张图"的数据实例(流程实例)

每来一条业务数据,相当于在这张图上跑一个"实例"。这个实例记录着:

  • 当前走到哪个节点了
  • 哪些节点已经走过(亮的)
  • 哪些还没走(灰的)
  • 携带的业务数据(订单号、申请人、金额等)

用一个更直观的比喻:图是地图,实例就是地图上的小人和高亮路径。你玩游戏时,已探索的区域是亮的,未探索的是灰的,你的角色站在某个位置上。工作流实例就是这样一个"存档"。

3. 外部事件触发这张"静止的图"向前推进

这些外部事件可能是:

  • main 方法里的一次调用
  • 一个定时任务扫到该执行了
  • 用户点了前端页面上的"同意/提交/下一步"按钮
  • 外部系统的回调

本质动作只有一个:读取当前实例的状态,根据图上的定义和条件,算出下一步到哪个节点,然后更新状态。

从这个角度看,工作流就是一套"持久化的状态机 + 事件驱动推进"的通用框架。

核心无非就是:

  • 表达式引擎(判断条件)
  • 字符串解析(解析 XML/JSON)
  • 状态机(节点流转)
  • 持久化(保存状态到数据库)

这些东西单独拿出来都不难,难的是把它们组合起来,处理各种边界情况,做得稳定、易用、可监控。

结论:工作流属于"工程组合型"技术,没有特别核心的算法。

能通过抽象推导出实现吗?

我甚至可以写个最简单的工作流验证我的理解:

场景:根据用户的性别和年龄,推荐游戏

流程图:

markdown 复制代码
开始 → 获取用户数据 → 性别=男? 
                        ↓ 是
                      年龄<18?
                        ↓ 是
                    推荐王者荣耀
                        ↓
                      结束

代码实现:

java 复制代码
// 1. 流程定义(图)
WorkflowDefinition def = new WorkflowDefinition();
def.addNode("start", new StartNode("getData"));
def.addNode("getData", new TaskNode(() -> loadUserData(), "gateway1"));
def.addNode("gateway1", new GatewayNode(Map.of(
    data -> "男".equals(data.get("性别")) && (int)data.get("年龄") < 18,
    "recommend1"
)));
def.addNode("recommend1", new TaskNode(
    () -> System.out.println("推荐:王者荣耀"),
    null
));

// 2. 创建流程实例(图 + 数据)
Map<String, Object> userData = Map.of(
    "性别", "男",
    "年龄", 16
);

// 3. 执行流程(事件推进)
WorkflowEngine engine = new WorkflowEngine();
engine.run(def, userData);
// 输出:推荐:王者荣耀

这可能就是工作流的本质了。无非就是:

  • 根据数据的条件,判断往哪走
  • 走到哪,就来到了预定义的框框里,执行框框里的语句

结论:能。理解了核心抽象后,剩下的就是工程细节。

我的目标是什么?

我要做的是:

  • 在项目里用好 Flowable
  • 知道什么场景适合用工作流,什么场景不适合
  • 遇到问题时知道怎么排查

我不需要:

  • 成为工作流引擎的专家
  • 给 Flowable 贡献代码
  • 从零实现一个工作流引擎

结论:黑盒使用 + 理解边界,就够了。


四、什么场景适合工作流?什么场景不适合?

既然决定了把工作流当黑盒用,那就要搞清楚它的适用边界。

我给自己定了一个判断原则:

更适合交给工作流的:

  • 多步骤、长生命周期的过程(跨小时、跨天,甚至跨周)
  • 多角色或多系统参与的过程
  • 可复用的通用流程骨架
  • 需要强运营、可视化、审计能力的场景

不那么适合交给工作流的:

  • 单系统内的核心领域逻辑(定价规则、促销规则、库存扣减算法)
  • 短生命周期、一次性的小流程(几行同步逻辑,用 if-else 就够了)
  • 变化频繁、需要灵活调整的核心算法

举两个例子,感受一下区别:

场景1:请假审批(适合)

这是工作流的经典场景:

  1. 员工提交请假申请
  2. 主管审批
  3. 如果超过3天,需要HR审批
  4. 审批通过,发邮件通知
  5. 超时未处理,自动提醒

画成图就是:

markdown 复制代码
提交申请 → 主管审批 → (天数>3?) → HR审批 → 结束
                ↓ 拒绝
              驳回

这种场景特别适合工作流:

  • 多步骤,跨时间(可能要等好几天)
  • 多角色参与(员工、主管、HR)
  • 需要记录历史(谁审批的、什么时候审批的)
  • 需要可视化(看当前卡在哪个环节)

场景2:电商订单定价(不适合)

订单计价逻辑:

  1. 商品原价
  2. 会员折扣
  3. 优惠券
  4. 满减活动
  5. 运费计算

这些逻辑虽然也是多步骤,但它们是核心领域模型,应该用代码、用领域对象来表达,而不是画在流程图里。

如果把定价规则也塞进工作流,就有问题了:

  • 变化频繁(促销活动天天变)
  • 需要灵活组合(今天满减+优惠券,明天换成秒杀)
  • 需要单元测试(定价逻辑必须测得很细)

这些特征决定了它不适合用工作流,而应该用策略模式、责任链模式等代码来实现。

场景3:电商发货流程(适合)

订单支付成功后,要开始发货:

  1. 选择最近的仓库
  2. 仓库出库
  3. 调用第三方物流接口
  4. 回写物流单号
  5. 如果物流接口调用失败,重试3次
  6. 还失败,转人工处理

这个流程适合用工作流来做。因为:

  • 跨系统(订单系统、仓库系统、物流系统)
  • 长生命周期(从出库到签收可能好几天)
  • 需要容错和重试
  • 需要知道当前走到哪了

在这种划分下:

  • 订单服务专注核心领域逻辑和状态管理
  • 发货工作流服务是一个黑盒编排器,对外暴露"创建发货流程实例"、"查询发货状态"、"触发某些人工/系统步骤"等接口

五、推而广之:其他技术的分类

理解了工作流的学习策略之后,我试着把同样的思路应用到其他技术上。

值得精读的技术(有核心算法/理论)

技术 核心价值 可迁移的知识
MySQL B+ 树 为什么范围查询快 树形索引结构的通用设计思想
Redis 跳表 为什么有序集合高效 概率数据结构的巧妙
Kafka 日志结构 为什么吞吐量大 顺序写、零拷贝等高性能技巧
Netty Reactor 为什么高并发 I/O 多路复用的本质
Raft 算法 分布式共识 一类共识问题的解法

这些技术的学习投入产出比高,因为学到的是底层原理,可以迁移到其他场景。

适合略读的技术(工程组合型)

技术 本质 学习策略
工作流引擎 状态机 + 持久化 + 事件驱动 理解模型 + 黑盒使用
规则引擎 条件匹配 + 动作执行 理解适用场景即可
Spring 依赖注入 + AOP + 整合 会用 + 知道原理
Swagger 注解解析 + 模板渲染 会配置就行

这些技术的复杂度在我看来,更多来自工程需求的堆砌,而不是算法本身的难度。学会用可能比学实现重要。


六、一个类比:Akka 和工作流

聊到这,我想起之前尝试理解 Akka 的经历。

刚听说 Akka 的时候,看到各种术语:Actor 模型、消息传递、监督策略、位置透明......当时觉得很玄乎。

但我试着剥开这些术语,慢慢发现可能本质就是:

  • 每个 Actor 像一个独立的小工人
  • 有自己的邮箱(消息队列)
  • 工人之间不共享数据,只通过发消息交流
  • 底层是线程池 + 阻塞队列

换句话说,Akka 的核心在我看来,可能就是:"线程池 + 消息队列 + 事件回调"的高级封装。

理解了这个之后,我觉得:

  • Akka 的原理可能不复杂
  • 但它在这个基础上做了大量工程化:监督策略、集群、远程通信、背压控制
  • 我可能不需要从零造一个 Akka,但我可以理解它的适用场景

工作流给我的感觉也是一样的。


七、我的学习策略总结

基于前面的思考,我给自己定了一个学习策略:

对于"值得精读"的技术(算法/理论型):

  • 看书、看论文、看源码
  • 手写实现一遍(自己实现个 LRU、跳表、简易 Raft)
  • 深入理解为什么这样设计
  • 目标:掌握可迁移的核心知识

对于"适合略读"的技术(工程组合型):

  • 理解核心抽象和适用场景
  • 会用 API,知道坑在哪
  • 遇到问题时,看一小段源码/表结构,确认行为
  • 目标:能解决问题 + 知道边界

对于"可以跳过"的技术:

  • 看官方文档的 Quick Start
  • 遇到问题再查
  • 目标:知道有这么个东西,能快速上手

工作流引擎,在我看来,显然属于第二类。


八、为什么我决定"不手写工作流引擎"

理解了本质之后,我面临一个选择:要不要自己实现一个简单的工作流引擎?

说实话,我确实有过这个冲动。毕竟理解了原理,写个玩具版本也不难。

但想了想,我的判断是:

工作流的核心思想不复杂,但工程实现很重

流程定义解析、运行时表设计、事务一致性、并发控制、作业调度、可视化、边界事件、补偿机制......这些东西做一个"够用"的版本都不轻松,做一个"好用又稳定"的版本更是长期工程。

对我个人来说,我觉得更划算的是:

  • 理解本质(图 + 实例 + 事件推进 + 适用场景)
  • 学会合理地使用和评估现成引擎(Flowable/Camunda 等)
  • 在真有需要时:
    • 用工作流引擎做多步骤、多系统、多角色的长流程编排
    • 用任务调度/重试系统做分布式执行保障
    • 用自己的业务代码承载核心领域逻辑

所以我给自己的结论是:

工作流对我来说,可能不值得"从零手写一个完整引擎",更适合作为一个可替换的黑盒组件,被我理解、评估、使用、测试,而不是重造一遍。

这不是说手写没有价值,而是说对我当前的阶段和目标来说,ROI 不高。


九、最后的思考:技术人的成熟,是学会战略性放弃

写到这里,我想起一句话:

真正的高手,不是什么都会,而是知道什么值得学,什么可以不学。

技术的海洋太大了,我们的时间和精力有限。如果每个技术都要深挖源码、手写实现、成为专家,那最后的结果只能是:什么都学了一点,什么都没学深。

更重要的是,我们学技术的目的是什么?

  • 是为了解决实际问题
  • 是为了提升系统的质量
  • 是为了构建自己的知识体系

而不是为了"掌握所有技术"这个虚无的目标。

所以,我给自己的建议是:

像挑选书籍一样挑选技术:

  • 有些技术,值得精读,反复咀嚼(MySQL、Redis、分布式算法)
  • 有些技术,略读即可,知道大概(工作流、规则引擎、Spring)
  • 有些技术,看目录就够,用到再查(Swagger、各种小工具)

判断的标准是:

  1. 它包含核心算法/理论吗?(是否有可迁移的知识)
  2. 理解它的本质,需要看源码吗?(是否能通过抽象推导)
  3. 我的目标是解决问题,还是掌握技术本身?(投入产出比)

对于工作流引擎,我的答案是:

  • 理解核心抽象:图 + 实例 + 事件推进
  • 搞清楚适用场景:多步骤、长流程、多角色、需要可视化
  • 黑盒使用 Flowable/Camunda,遇到问题再看源码

这样,我的学习目标就基本完成了。


十、结语

这篇文章,从工作流引擎出发,但想表达的不只是工作流。

更重要的是:面对任何新技术,我们都应该先问自己三个问题,再决定要投入多少精力。

不是所有技术都值得深挖,也不是所有技术都可以浅尝辄止。关键是找到适合自己的学习节奏和深度。

对我来说:

  • 理解技术的本质和边界,比精通它的所有细节更重要
  • 知道什么时候用、什么时候不用,比会用更重要
  • 把时间花在真正有价值的技术上,比什么都学更重要

当然,这只是我个人在现阶段的判断。不同场景、不同阶段,可能会有不同的选择。

但至少,我现在有了一个判断框架。

下次再遇到新技术时,我会先问自己:

这本"技术书",我该精读、略读,还是直接跳过?

相关推荐
源代码•宸2 小时前
goframe框架签到系统项目开发(用户认证、基于 JWT 实现认证、携带access token获取用户信息)
服务器·开发语言·网络·分布式·后端·golang·jwt
期待のcode2 小时前
static关键字
java·后端
SimonKing2 小时前
Java汉字转拼音的四种方案,99%的开发场景都够用了!
java·后端·程序员
kobe_OKOK_2 小时前
windows 部署 django 的 方案
后端·python·django
卜锦元2 小时前
Golang后端性能优化手册(第一章:数据库性能优化)
大数据·开发语言·数据库·人工智能·后端·性能优化·golang
lbb 小魔仙2 小时前
FP8赋能高效生成:Stable Diffusion 3.5架构解析与落地优化指南
stable diffusion·架构
廋到被风吹走3 小时前
【Spring】HandlerInterceptor解析
java·后端·spring
q_19132846953 小时前
基于SpringBoot+Vue.js的教师绩效考核管理系统
vue.js·spring boot·笔记·后端·mysql·毕业设计