编程逻辑这个词,被误解得很深。

很多人觉得它等同于“聪明”,等同于“能解算法题”,甚至等同于“智商高”。我以前也这么认为,直到自己写了几万行烂代码之后才慢慢咂摸出味儿来——编程逻辑,本质上不是什么高深智力,而是一种“驯服条件”的能力。

逻辑
打开网易新闻 查看精彩图片
逻辑

什么意思?拿个最简单的例子说。

你写一个登录功能。用户输入用户名密码,点登录。逻辑是什么?是“if 账号存在 and 密码正确 then 登录成功 else 提示错误”吗?那是初中生都能写的表层逻辑。

真正的编程逻辑,是你坐下来开始想:“账号存在”这个判断,背后藏着多少个条件——

  • 账号是被禁用的吗?被禁用了还让不让输密码?
  • 账号是不是已经过期了?会员到期了是直接拦还是弹续费?
  • 错误密码试了五次,要不要锁五分钟?锁了之后提示什么?
  • 如果用户在锁定期内,他输入正确密码怎么处理?是解锁还是继续提示被锁?
  • 数据库查不到账号,是返回“账号不存在”还是统一返回“账号或密码错误”防止撞库?

你看,一个表面上只有两个分支的简单逻辑,一旦把真实世界的复杂度加进去,判定树蹭蹭蹭往外长。编程逻辑的本质,就是在一团混沌里,把这棵判定树一点一点画清楚,然后确保每个叶子节点都有对应的处理动作。

简单代码
打开网易新闻 查看精彩图片
简单代码

而新手和有经验的工程师最大的区别,往往不在编码速度,而在判定树的完整程度。新手看到的是一个二选一的分支,老手看到的是带着异常、边界、安全、体验、降级五个维度的逻辑森林。

我印象特别深的一件事。刚入行第二年,我写了一个订单状态流转的逻辑。当时觉得自己写得特别好,if-else 清清楚楚,每个状态都覆盖到了。上线第二天,线上出了个诡异的 bug——用户支付成功之后,订单状态变成了“已取消”。

我查了一整天日志才发现问题:我的逻辑里,支付回调进来时先检查订单状态,如果是“待支付”就改成“已支付”,其他状态一律报错。但有一个边界我没覆盖——如果支付回调比用户主动取消的请求先到达呢?网络延迟嘛,用户点取消的时候银行那边支付其实已经成功了,只是回调消息在路上多堵了两秒。等回调到达时,订单已经被用户取消了,状态是“已取消”,然后我的逻辑一看:不是“待支付”,报错。但报错之后,我的异常处理是直接给用户退款,于是已支付的订单被取消了,还把钱退了回去。

一单亏了好几万。

我当时觉得自己蠢透了。但后来我想明白了:这不是蠢,是我的逻辑树里缺了一条分支——“支付回调到达时订单已被取消,但支付事实已经发生”该怎么处理。这背后其实是一个很常见的分布式场景:两个动作竞态,谁的请求先到谁说了算,但业务上你需要一个补偿机制。

从那以后我养成一个习惯:每次写条件判断,都会多问一句“如果这个条件此时不成立,但在上一秒是成立的,会发生什么?”这就是把时间维度加进逻辑树里。

编程逻辑训练的第二个核心维度,是学会区分“业务逻辑”和“技术实现”

很多人写代码,把这两件事搅在一起——为了用某个设计模式,硬把简单业务套进去;为了复用代码,强行抽象出一堆没人用的接口。真正好的编程逻辑,是先想清楚“业务上这个动作的输入输出是什么、边界是什么、失败意味着什么”,再去想“技术上用什么容器、什么框架、什么模式来实现”。

业务逻辑是“做什么”,技术实现是“怎么做”。两者不是一回事。能把这两条线清晰地拆开,你的代码自然干净。

业务i逻辑
打开网易新闻 查看精彩图片
业务i逻辑

第三个维度,也是最后一个,是学会用“命题”来思考

每一段逻辑,本质上都是一个命题:“如果 A 且 B,则 C,否则 D”。编程逻辑好的人,写代码之前已经在脑子里把命题的真值表推演过一遍了——A 真 B 真、A 真 B 假、A 假 B 真、A 假 B 假,四种情况分别对应什么结果,每一格都有清晰的输出。这种“真值表思维”,比任何编程技巧都管用。

我经常跟新人说的一句话是:别急着写代码,先花时间把条件的每种组合在纸上写一遍。写出来了,代码就是填空。写不出来,写出来的代码也是漏洞百出的。

说到底,编程逻辑不是什么天赋,它就是一套不断追问“然后呢?那如果反过来呢?那如果同时发生呢?”的习惯。问得多了,你的逻辑树就会越来越密,越来越经得起真实世界的冲击。

我把自己这些年摸爬滚打留下的思维碎片、反模式案例和一些极简项目骨架都放在 GitHub 上了。不是什么标准答案,更像一本“错误集”——你看到哪处觉得“这傻叉居然这么写”,那就算没白看。