文/一个把Hello World当项目做了十年的产品经理型程序员
前阵子我们团队在复盘一个做了三年、迭代了十几次的项目。我翻着那些版本记录,从最初的”能跑就行”到后来的”高可用、可扩展、可观测”,每一步都历历在目。
突然有个念头冒了出来:如果把Hello World当成一个正经产品,像做商业软件一样给它做版本规划,它会经历什么样的演变?
这个念头越想越有意思。我决定把这个脑洞写出来——一个Hello World软件的十次版本迭代。每一版都是一个真实的软件开发场景,每一版背后都是我曾经踩过的坑。
v1.0:可以输出”Hello, World!”
这是最原始的需求。用户说:”我想在屏幕上看到一句话。”产品经理说:”好,那就打印’Hello, World!’。”
你花了一分钟写完了代码,部署,用户说看到了,项目上线。你觉得自己是天才。
但你知道这个故事不会在这里结束。
v2.0:要支持多语言
用户说:”我认识一个外国朋友,他看不懂英文,你能不能出个中文版?”产品经理说:”我们加一个语言切换功能吧。”
你加了一个参数,–lang=zh输出”你好,世界”,–lang=en输出”Hello, World!”。代码多了十几行,但你觉得自己挺灵活。
然后用户说:”我还需要日语、韩语、法语、西班牙语……”你开始意识到,需求是永远加不完的。
v3.0:要好看,要加UI
用户说:”黑底白字太丑了,我想要个好看的界面。要彩色、要字体漂亮、要居中显示、最好还有点动画。”
你开始折腾HTML和CSS。加背景色、加渐变、加阴影、加一个缓慢浮现的动画效果。你把输出从终端搬到了浏览器。用户说”这才像个软件”,你松了口气。
但页面在手机上变形了,你又花了一周做响应式适配。
v4.0:让用户自定义内容
用户说:”我不一定每次都要说Hello World,我想换成别的话,比如’你好,妈妈’或者’Good morning, boss’。”
你加了一个配置文件,用户可以在里面修改输出内容。你还做了参数校验、错误处理、默认值回退。代码量从原来的几行变成了几百行。你第一次感觉到了”功能膨胀”的味道。
你开始想:如果再这么加下去,这个项目会变成什么样子?
v5.0:要支持网络传输
用户说:”我现在有十台机器,想让它们同时输出同样的内容,我不想一台台去改配置文件。”
你开始设计一个”中心配置服务”。Hello World客户端启动时从中心服务拉取配置,然后输出。你加上了网络请求、JSON解析、超时重试、缓存机制。代码从几百行变成了几千行,你开始用版本控制、写文档、画架构图。
你从”写代码的”变成了”做系统的”。
v6.0:要能自我监控
用户说:”有时候服务挂了,我怎么知道?你得告诉我它活没活着。”
你加了一个健康检查端点,/ping返回ok。你加了日志,每次启动和输出都有时间戳。你加了指标采集,输出次数、延迟、错误率都上报给监控系统。你甚至还写了一个简单的看板,红绿灯显示服务状态。
你开始处理”运维”的事了。你发现自己不光要写代码,还要管它怎么跑、怎么活下去。
v7.0:架构大重构
用户说:”我现在有上千台机器,配置中心扛不住了,你得重新设计。”
你发现当初那个简单的”中心拉取配置”模型在规模面前不堪一击。你需要分布式配置管理、需要服务发现、需要负载均衡、需要容错降级。你花了三个月把整个系统拆成了微服务——配置服务、分发服务、输出服务、监控服务。
代码量从几千行变成了几万行。你开始招聘,因为一个人干不完。你有了一个团队,你要开会、要写设计文档、要评审代码。你越来越像一个”软件工程”的负责人了。
而那个最初的Hello World,被深埋在输出服务的某个角落,三行代码,从来没人动过。
v8.0:性能优化无止境
用户说:”现在输出延迟有点高,能不能优化到10毫秒以内?”
你开始做性能分析。火焰图、CPU profiling、内存分析。你发现瓶颈在序列化、在网络传输、在日志写入。你换掉了JSON用Protobuf,你加了本地缓存减少了网络调用,你改成了异步日志。延迟从100毫秒降到了15毫秒。
用户说”还行,但还能再快吗?”你又开始下一轮优化。你意识到性能优化是没有终点的马拉松。
v9.0:用户说”我只想要最初那个”
有一天,一个老用户找到你,说:”我就是想输出一句’Hello, World!’,为什么现在要装十几个组件、配几十个参数、等五分钟才能启动?你们搞得太复杂了。”
你愣住了。你回头看这十年的迭代,发现自己造了一艘航空母舰,而用户一开始只是想要一艘小木船。需求变了,规模变了,你跟着变化一路狂奔,但有些人从来没离开过港湾。他们只是想要那一行字。
你开始反思:所有那些附加的功能、架构、监控、优化,到底有多少是真实需要的?有多少是为了解决”因复杂而产生的复杂”?
v10.0:回归,但不一样了
你决定发布一个”精简版”——一个独立的、单文件的、没有依赖的Hello World。代码回到了最初的几行,输出那行字,然后退出。没有任何额外的功能、配置、网络、监控。
用户说”这才是我要的”。
但你知道,这一次的”回归”和十年前完全不同了。你不是因为不会写别的而写这行字,你是经历了所有之后,主动选择了写这行字。你删掉的那些代码,每一行你都清楚地知道它为什么存在、它解决了什么问题、它现在为什么可以不存在。
这种”有意识的最小化”,和”无知的最小化”,隔着十万八千里的修炼。
那个Hello World,最后教会了我什么
这个故事当然是我编的。没有哪个Hello World真的迭代了十个大版本。但每一个真实的项目,都走过类似的路。
我从这个故事里学到的东西只有一件:软件的价值,从来都不在于你写了多少行、架构多漂亮、用了多新的技术。软件的价值在于它解决了一个真实的问题,并且在解决问题的过程中,没有制造出比问题本身更大的麻烦。
那个最初的Hello World,用一行代码解决了一个问题——让屏幕上出现一句话。
后来我们做的一切,都是在让这个”出现”变得更灵活、更好看、更可靠、更规模化。但如果我们忘了最初的那行字才是根本,所有的附加都成了空中楼阁。
所以我现在看项目,第一件事永远是问:我们最小可用的”Hello World”是什么?在不加任何修饰、不做任何准备的情况下,这个东西能跑起来吗?
然后我从那里出发。但我不再忘记那里。
十次版本迭代,最后回到了同一个地方。但这一次,我知道我为什么在那里。