
2015年夏天一个在阿里巴巴做中间件开发的工程师在股灾到来之前做了一件事让他在之后整整两年里成为整个团队里心态最稳定的那个人。他没有预测到股灾。他只是在2014年底花了两个小时把他家当时的财务状况扔进了三个他自己编的极端场景里跑了一遍。第一个场景是大盘跌一半第二个场景是他被裁第三个场景是前两个同时发生。跑完之后他发现如果前两个场景同时发生他家的流动资金会在第九个月归零。他盯着那个数字看了几分钟然后打开手机银行把原本计划投进股市的一笔钱转进了应急储备金账户把储备金从覆盖九个月提升到了覆盖十四个月。2015年6月他持有的那几只股票和大盘一起暴跌。他周围的同事有的在跌停板上排队割肉有的在茶水间压低声音讨论“要不要把准备买房的首付挪去补仓”。他在工位上安静地写代码。后来有人问他那段时间怎么那么淡定他说他也不知道股灾会不会来但他知道自己能扛多久。知道能扛多久的人不需要预测未来。等价类划分的陷阱你测过的所有“正常情况”在黑天鹅面前一文不值你在写单元测试的时候一定会做一件事把输入数据划分成几个等价类从每个等价类里挑一两个代表值来测试。有效输入测一个无效输入测一个边界值再测一个。逻辑正常的时候怎么走参数为空的时候怎么处理超出范围的时候抛不抛异常。测试用例写完覆盖率工具跑一遍绿条拉满你觉得自己写的这段代码已经刀枪不入了。然后你把你家未来三十年的财务安全押在了一个你只测过“正常等价类”的系统上。你测过牛市。股票涨了你账户里的资产净值曲线陡峭上扬你觉得自己配置得很合理。你测过震荡市。股票一会儿涨一会儿跌你的定投计划正常扣款你的再平衡每季度触发一次一切都在按你的预期运行。你甚至可能测过温和熊市——大盘跌了百分之十五你的持仓回撤了百分之十你扛住了没有在底部割肉还在继续定投你对系统的韧性颇为满意。这三个场景——牛市、震荡市、温和熊市——是你投资生涯里到目前为止经历过或者听说过的全部市场状态。你把它们当成了你测试用例的全部等价类。你觉得既然系统在这三种输入下都表现良好那它就是鲁棒的。但你这套测试用例漏掉了一整个维度的输入空间极端状态。大盘不是跌百分之十五是十二个月内腰斩并且在跌到百分之三十的时候出现了一次你从业以来从未见过的流动性枯竭你想卖都卖不掉。你的行业不是景气度回落是你所在的公司和你的竞争对手同时开始大规模裁员你和你认识的所有同行都在同一个季度里变成了求职者。利率不是温和上升是基准利率飙到了百分之八以上你那个当初签合同的时候觉得“压力不大”的房贷月供突然翻了一倍。这些输入值在你的测试用例里被归类为“非法输入”——你认为它们发生的概率太低了不值得专门写测试用例。但你在软件工程里学到的最重要的一课是什么非法输入不是不发生是发生了之后系统不能崩溃。用户在你的输入框里填了一个负数你的系统可以拒绝处理但不能把整个服务器搞宕机。同样市场给你的资产净值输入了一个你从未见过的负数你的家庭财务系统可以缩表、可以降级运行、可以进入只有内核层还在工作的生存模式但不能直接宕机。你如果从来没有测试过你的系统在极端输入下的行为你就不知道它的崩溃边界在哪里。而不知道崩溃边界的系统不是系统是赌博。你用一套只在正常等价类里跑通了的配置去面对一个历史上每七到十年就会触发一次极端事件的真实世界。七到十年恰好比你做一次完整投资周期规划的时间跨度还要短。你职业生涯的三十到四十年里至少会遇到三到四次足以摧毁未测试系统的大型极端事件。你打算靠运气扛过去吗边界值场景构建三个你必须现在就跑的压测脚本我不想让你在恐慌中去做这些测试。恐慌状态下做的测试和你恐慌状态下做的交易一样输出的都是噪声。我要你选一个风和日丽的周末下午泡一杯茶关掉手机通知打开一张空白的Excel表格然后把下面这三个场景一个一个地、认认真真地输入进去。输入A股市十二个月内腰斩且你所在的行业同时爆发大规模裁员潮。你先把权益类资产全部乘以0.5。你的股票账户、指数基金、行业ETF、以及任何和股票市场挂钩的理财产品全部对折。如果你持有个股对折已经是很温柔的假设了——个股在真正的系统性危机里跌百分之七八十甚至退市的案例比比皆是。同时你的主动月收入降为零。你被裁了。你所在行业的头部公司都在裁员你过去十年积累的职业技能在这个时点上面临的是一个极度紧缩的招聘市场。你给自己设定一个保守的重新就业周期——六个月。在这个双输入场景下把你的月度生活硬性支出列出来。房贷或者房租、水电燃气、基础饮食、保险续费、以及任何不能因为失业就停掉的固定支出。不要自己骗自己说“失业了可以省着花”你可以在实际生活中省着花但在压测里你必须按正常支出计算。如果实际发生裁员潮的时候你的正常支出都覆盖不了那你连“省着花”的资格都没有因为你连房贷都还不上。用你的应急储备金余额除以这个月支出数字。你得到了你能存活的月份。如果你的应急储备金在第六个月之前归零而你的权益资产在那六个月里的任何一个时点因为被迫割肉而被提前清空那你在输入A下的输出就不是“生存”是“破产”。输入B基准利率飙升到百分之八以上你的浮动利率负债月供翻倍。如果你手里没有任何浮动利率的负债这个场景对你来说是无效输入可以直接跳过。但如果你有——比如你在前几年签了一笔挂钩LPR的浮动利率房贷——那这个场景对你来说是迟早要测试的。基准利率飙到百分之八在今天的低利率环境里听起来像是天方夜谭但在二十世纪九十年代初、在2007到2008年、在2022年美联储暴力加息那几个月全球主要经济体的基准利率从低位翻倍甚至翻几倍都是发生过的历史事实。中国当然有独立的货币政策但如果你持有的负债是挂钩全球利率环境的——比如你有外币贷款——那这个场景就更加不容忽视。模拟方式很简单把你月供金额里的利息部分乘以二加上本金部分不变得到新的月供数字。然后在你的月度预算里把这笔新增支出扣掉。扣掉之后你的月度结余还为正吗如果为负你的应急储备金覆盖这个新增缺口能覆盖多少个月你能否在应急金耗尽之前完成一次债务重组——比如把浮动利率转成固定利率或者提前还掉一部分本金输入C家庭主要劳动力——很可能就是你——失能六个月以上。不是因为被裁是因为身体。一场车祸一次运动损伤一次需要住院手术的突发疾病。你的主动收入可能部分中断可能完全中断取决于你所在公司的病假政策和商业保险覆盖程度。但同时你的家庭会因为治疗而产生额外的医疗支出——护工费、康复费、以及医保和商业保险报销范围之外的全部自费项目。把月收入设为你当前税后收入的百分之三十——假设公司给你发一部分病假工资。把月支出在现有基础上增加一笔预估的康复费用数额可以按你身边有过类似经历的朋友的真实花费来估算或者直接设为你目前月生活支出的百分之五十。你的应急储备金加上你的商业保险能覆盖的理赔额度减去这六个月里的总缺口。剩下的数字是正还是负如果是负的你需要在当下做什么调整输出校验系统的最低输出不叫“跑赢大盘”叫“活着”你跑完这三个压测脚本之后你会得到三组数字。每一组数字都告诉你同一个信息在你的系统当前配置下最坏的情况下你能撑多少个月。如果你的答案在所有场景里都超过了十二个月你的系统通过压测可以在生产环境继续运行。如果你的答案在某个场景里落到了六到十二个月之间你的系统有脆弱点需要在下一个季度评审日之前加固——提高应急储备金的目标水位或者增加保险覆盖范围或者把一些高风险的权益仓位转移到系统服务层的固收资产里。如果你的答案在某个场景里落到了六个月以下你的系统有致命缺陷现在就修。不要等到极端事件来了再修。压测的目的从来不是让你活在恐惧里。压测的目的是让你在风和日丽的时候就知道自己的系统在什么条件下会撑不住然后在它撑不住之前你有时间加固它。你不需要加固到能承受核战争。你只需要加固到在下一次你职业生涯里必然遇到的那几次严重但并非世界末日级别的风暴里你不会被迫在风暴中心做出你一生中最糟糕的财务决策。你测试线上服务的时候不会因为“我觉得这个接口不会被打爆”就跳过压力测试。你对自己写的每一行代码都要求它在上线之前先跑一遍压测。你把同样的标准用在你家未来几十年的财务安全上用在一个下午的Excel表格这不过分。