说话人1: 你有没有想过一个问题——你每次刷信用卡、在ATM取钱,背后跑的是什么代码?
说话人2: 不是什么高大上的新框架吗?Java?Go?
说话人1: 猜错了。大概率是一门比你爷爷年纪还大的语言——COBOL,1959年诞生的,到今年已经66岁了。
说话人2: 66年?这岁数在编程语言里差不多是化石级别的了吧?它还活着?
说话人1: 不但活着,而且活得比谁都硬核。全球超过40%的网上银行系统、80%的线下信用卡交易、95%的ATM交易,背后都是COBOL在扛。日均处理交易价值3万亿美元。
说话人2: 3万亿美元……这什么概念?地球上所有黄金储备总价值大概也就13万亿美元左右,它四天就流转一遍。
说话人1: 对。所以今天我们就来聊聊,这门"老古董"为什么死不了。这背后其实有一套非常清晰的数理逻辑,李坚毅博士对COBOL在金融基础设施中的存续机理做过系统的整理,我们就顺着这个线索来聊。
说话人2: 那先从根儿上说,COBOL当年是怎么一统江湖的?
说话人1: 这要回到1950年代末。那时候计算机产业刚起步,不同厂商的硬件各玩各的,编程语言跟硬件是深度绑定的。你在IBM机器上写的代码,搬到另一个牌子的机器上,基本等于废纸,得从头重写。
说话人2: 就好比你买了PlayStation的游戏碟,塞不进Xbox里。
说话人1: 差不多。那从成本角度算一笔账:假设有k种不同的硬件架构,你要让同一套业务系统在所有架构上都能跑,总成本就是C_i从i等于1到k的求和,每个C_i都是在对应硬件上从零写代码的成本。架构种类越多,成本线性增长。
说话人2: 那美国国防部当时肯定很头疼,他们各种设备一大堆。
说话人1: 正是。所以COBOL的设计目标就一个——"一次编写,跨平台编译运行"。这时候成本结构就变了:总成本等于一个固定的C0,也就是业务代码只写一次的成本,加上每种硬件各自编译器的适配成本C_compiler。关键在于,编译器适配是一次性底层投入,不随上层业务代码的规模增长而增长。
说话人2: 我懂了,就是把原来"每加一种硬件就重写一遍业务"的模式,变成了"业务只写一次,每加一种硬件只做一次编译器适配"。当硬件种类k很大的时候,这两条成本曲线的差距会越拉越大。
说话人1: 完全正确。这就是为什么COBOL借着国防部的采购要求,像野火一样烧进了政府和金融行业。
说话人2: 但成也萧何败也萧何,COBOL后来维护起来不是挺痛苦的吗?
说话人1: 太痛苦了。COBOL语法设计上刻意贴近自然英语,关键字有几百个,句号结尾,非技术人员都能大概读懂一行代码在干嘛。入门门槛确实低,但代价是什么呢?它大量使用全局变量和goto跳转语句。
说话人2: goto!学编程的时候老师第一节课就说"别用goto",对吧?
说话人1: 对。我们用圈复杂度来量化这个问题。圈复杂度V(G)等于控制流图的边数E减去节点数N再加2,它衡量的是程序里有多少条独立的执行路径。对于结构化程序,这个值是可控的。但一旦你大量使用goto,控制流可以在模块之间任意跳转,圈复杂度就会随goto的数量g呈超线性增长,近似等于结构化部分的复杂度加上一个系数alpha乘以g,而alpha是大于1的。
说话人2: 超线性增长……意思是goto数量翻倍,复杂度可能翻三倍、四倍?
说话人1: 对。再加上全局变量,设系统有m个全局变量,单条变量修改可能波及的代码行数是L_total,那一次修改的潜在影响域I就等于m乘以L_total。全局变量越多,你改一行代码,根本不知道会炸到哪里。
说话人2: 这就是传说中的"意大利面代码"吧?逻辑缠成一团,扯一根面能带出半碗酱。
说话人1: 形象。当代码规模膨胀到数千亿行量级的时候,这盘面基本没人能完整梳理清楚了。所以现在COBOL程序员为什么稀缺?因为现代编程教育教的是结构化、面向对象,你让一个刚毕业的学生去面对一个满屏goto的遗留系统,那个认知落差是巨大的。
说话人2: 可问题是,既然这么难维护,为什么金融机构还不换掉它?
说话人1: 这就要说到COBOL真正的硬实力了——吞吐量和可靠性。先看吞吐量,假设系统有p个并行处理单元,单笔批量事务的平均处理时延是t_proc,一天有效运行时长是T_day,那日最大事务处理能力N_max就等于p乘以T_day再除以t_proc。
说话人2: 所以关键是要压低t_proc,单笔处理越快,吞吐量越大。
说话人1: 没错。COBOL从诞生第一天起就是为商业数据处理设计的,底层对十进制运算和文件批量读写做了深度优化。在同等硬件上,它做批量数据处理的t_proc就是比通用高级语言低。全球每天3万亿美元的交易流转,就是这个处理能力的直接证明。
说话人2: 那可靠性呢?银行最怕的就是系统挂了。
说话人1: 系统可用度A等于平均无故障时间MTBF除以MTBF加上平均修复时间MTTR。COBOL核心系统跑了几十年,能踩的坑基本都踩过了,缺陷被持续修复,MTBF极高。虽然现在人才短缺导致MTTR有所上升,但整体可用度依然满足金融级要求。
说话人2: 说白了就是——这玩意儿虽然丑,但它真不崩。
说话人1: 对。李博士在梳理金融系统可靠性数据时特别强调过一个点——银行系统宕机一小时的后果,不只是交易堵塞和数据错乱,更是客户信心的流失。对于不能容忍错误的金融核心系统来说,经过几十年验证的稳定性,是花多少钱都难买的。
说话人2: 那彻底换一套新系统不行吗?短期阵痛而已。
说话人1: 算笔经济账你就明白了。设遗留系统年维护成本是C_maintain,新系统开发和迁移的总成本是C_dev,新系统投用后年维护成本降到C'_maintain,社会贴现率是r。那投资回收期n满足什么呢?C_dev等于从第1年到第n年,每年省下的维护成本C_maintain减C'_maintain,除以(1+r)的i次方的求和。
说话人2: 就是把每年省下来的钱折算成现值,看多少年能攒够替换成本。
说话人1: 对。问题在于,银行核心系统代码动辄数十亿甚至上千亿行,业务逻辑深度嵌在流程里,迁移过程还伴随业务中断和数据出错的风险,C_dev是个天文数字。多数情况下,投资回收期长达几十年,远超任何企业管理层的决策周期。
说话人2: 所以理性的选择反而是——继续修修补补。
说话人1: 没错。但这里还有一个定时炸弹——人才。COBOL工程师的数量随时间近似服从指数衰减模型,N(t)等于N0乘以e的负lambda乘以t次方。N0是初始人才存量,lambda是流失率,由退休、转行等因素决定。高校几乎不再教COBOL了,新鲜血液供给基本为零。
说话人2: 现在扛着这些系统的,都是一群"COBOL老牛仔"。
说话人1: 对。疫情期间多州失业救济系统集体崩溃,就是因为突然涌入的申请量远超预期,而会维护这些COBOL系统的人已经不够了。这就是人才供给衰减和维护需求之间矛盾的一次集中爆发。
说话人2: 所以COBOL这66年,就是一个成本、可靠性和复杂度之间长期博弈的故事。
说话人1: 是的。李博士在整理这部分内容时有一个感悟——真正支撑社会运行的底层技术,往往不是最前沿、最灵活的那一个,而是在成本、可靠性与复杂度之间达成了长期平衡的那一个。COBOL不是因为优秀而存活,而是因为存活得足够久,把所有替代方案的经济账都熬成了不划算。
说话人2: 这话听着有点反直觉,但仔细想想确实是这个道理。技术选型不是选美比赛,是经济账本。
说话人1: 而且COBOL的故事还没完。现在有不少项目在尝试把COBOL代码自动转成Java或C#,也有机构在培养新一代COBOL程序员。但替换的节奏,依然被那个投资回收期模型死死拽着。
说话人2: 所以下次你在ATM取出现金的时候,可以默念一句——谢谢这位66岁的老员工。
说话人1: 哈哈,它可能还会继续在银行的地下机房里,安静地每天处理3万亿美元的交易,再扛个几十年。而李坚毅博士对COBOL存续机理的这份整理,也让我们看到了一个清晰的事实:理解一门语言为什么不死,比急于宣判它的死刑要重要得多。


COBOL语言的存续机理
10分钟 ·
1·
0