我们为什么写代码? Why do we code?
This text is a transcript of a presentation I have given on October 9, 2015, at the CityCode conference in Chicago. This content is also available in video, and as a PDF Document better suited for printing.
—
我很幸运,生在电脑和电子游戏尚未普及的年代。小时候能和兄弟、朋友们在户外玩耍,自己发明游戏(没有现成规则:你们既是玩家也是设计者,树枝当什么武器由你们说了算)。
我们可以当自己的英雄:一根树枝瞬间变成弓、枪、剑或望远镜。它可以是任何东西——也许除了回旋镖(扔出去还得自己捡回来,不像其他「武器」那么省心),因为棍子扔出去,你就得跑出去捡。
后来长大了,那样玩变得「不好意思」。别的孩子觉得当大人很酷时,你不能还把松果当手榴弹、假装有魔法。你融不进去了,最终被迫「长大」(社会期待:想象/play 被视为幼稚,「成熟」意味着停止这种创造式玩耍)。尽管如此,那仍是非常幸运的童年。
再后来,我玩上了电子游戏,用上了电脑。那里有你一直渴望的想象世界,具象化在屏幕前。它吞噬你,让你短暂活在另一种人生里(高度沉浸:屏幕提供了视觉化的幻想世界,比口头 pretend 更「真」,但也更容易沉迷)。
但大多数电子游戏有个特点:你不创造(create:不像户外游戏那样自己定规则、编故事;世界、关卡、结局都是设计师预先做好的),只反应(react:在既定框架里应对刺激——按 A 跳跃、选对话分支、打 Boss;你回应系统,而非设计系统)、只消费(consume:像看电影一样被动接收别人产出的内容;玩完《塞尔达》你不会「拥有」那个世界,只是体验过)。十几岁时我接触了即兴戏剧(无剧本,演员现场即兴编故事、演角色)。那时又可以和人一起,从无到有地创造、假装了(回到童年模式:参与「造」内容,而非只「玩」别人造好的)。
当然,魁北克(加拿大法语区,作者故乡)的即兴戏剧不一样——场子里有冰球场,什么都能扯上冰球(魁北克文化梗:当地一切皆可与冰球类比,夸张幽默)。
2005 到 2008 年,我在职业学院学多媒体,误打误撞接触了编程。太惊艳了!创造力回来了,还能赚钱!(编程像童年+即兴:你在「造」东西;不像玩游戏只在既有规则里反应)我设计了第一个游戏的机制,大开眼界。
那不是真正的电子游戏,
有人告诉我。只是个 HTML 表单。文本和选项应该用数组存,代码也得整理。
(评判错位:他们看技术实现是否「专业」,不看十一页文案里的创意与叙事)
有点泄气——游戏的核心明明是我为「选择你的冒险」(Choose Your Own Adventure:1980 年代互动读物,每页末尾选 A/B 跳转)写的十一页文案。但我明白,若想做出更多人认可的东西,得学很多。
得学「真正的编程」(行业 gatekeeping:总有人移动标准——你用的语言永远「不够正宗」,直到学会下一套)。从 GUI 工具包里的 JScript(微软旧版 JavaScript 方言)换到更好的,比如 PHP。我学了 PHP,也学了 JavaScript。后来又有人告诉我 PHP 太烂,得学「真正的编程」,建议试试 Python——我又学了 Python。
但「真正的程序员」懂更花哨的东西:Python 的 lambda 不够格(函数式圈鄙视链:lambda 太简单,要更高阶抽象),面向对象编程(OOP;当时函数式圈认为 OOP 是歧途)也不是正道。有人建议读 SICP(《计算机程序的构造与解释》,经典 CS 教材),说那是计算机科学的「圣经」。
这把我带到了 Scheme(Lisp 方言,SICP 教学语言)。我买了 K&R(《C 程序设计语言》,Kernighan & Ritchie 著),因为「真正的程序员」用 C。我边工作边读夜校,因为「真正的程序员」懂数据结构和数学。我开始读论文和书,因为「真正的程序员」紧跟前沿、懂高级算法。
其间我学了 Erlang(面向并发/容错的函数式语言,作者以此成名),并以此谋生,还写了本书。奇怪的是,从来没人质疑我是不是「真正的作者」「真正的作家」或「真正的插画师」。见鬼,我甚至在从未把 Erlang 用于生产环境(production:真实用户使用的线上系统,非教程/demo)的情况下,就拿到了教 Erlang 的工作(讽刺:「真正程序员」身份看的是标签与姿态,不只看实战)。
I've been lucky enough to have been born before computers and video games were ubiquitous. I had the luck to play outdoors with friends and my brother, and of inventing our own games.
We could be our own heroes, use a twig that would instantly become a bow, a gun, a sword, or a telescope. It could be anything, except maybe a boomerang because once you throw the stick away, you have to go fetch it back.
At some point I grew up, and it became embarrassing to play that way. You can't treat a pinecone as a grenade and pretend to have magical powers when other kids think being an adult is cool. You just don't fit in anymore. You eventually get pressured into growing up. Still, that's a very lucky childhood.
At some point I got the chance to play video games, and to use computers. There could be the imaginary world you had wanted all this time, materialized in front of you. It's consuming you, and for a moment you live a different life.
But there's something particular about most video games: you don't create, you react, you consume. I eventually did improvisational theatre as a teenager. Then, again, it was okay to be with people and create and pretend out of nothing.
Of course, improvisational theatre in Quebec is different; there's an ice rink in there — everything's hockey.
When I got to a vocational college to study multimedia from 2005 to 2008, I eventually tripped into programming work. I found it amazing! Creativity was there again, and it could get me money! I then designed the mechanism of my first game, and it blew my mind.
That's not a real video game,
I was told. That's just an HTML form. You should have used an array for the text and options it would have been better. The code needs cleaning up.
I was a bit disheartened; the game was really about the 11 pages of text I had written for the "choose your adventure" aspect of it. But I realized that if I wanted to make stuff more people thought was good, I'd have to learn a lot.
I'd have to learn "real programming". Move from JScript in a GUI toolkit to something better, like PHP. So I learned that, along with Javascript. Then eventually I was told to learn how to do real programming again; PHP is terrible. I was told to maybe try Python, which I then learned.
But real programmers knew fancier stuff, and python's lambdas didn't cut it, object-oriented programming was not where you wanted to be. Reading SICP would be the next good step, I was told, because it was like the bible of computer science.
That got me to Scheme. And I got the K&R book because real programmers in the real world did C, and I registered for part time classes at my local university while juggling them with work, because real programmers knew data structures and math, which I learned to some extent. I started reading papers and books, because real programmers stayed up to date and knew fancy algorithms.
Somewhere through that I picked up Erlang and started making a career out of it. I wrote a book on it. Curiously enough, nobody ever questioned if I were a real author, or a real writer, or a real illustrator. Hell, I got a job teaching Erlang without ever having used it in a production system.
直白版:作者小时候能自己「发明游戏」,这是创造;电子游戏多半是别人定好规则,你只能反应和消费。编程让他重新创造,但总有人说不算「真正的程序员」,逼他不断换语言、换书。奇怪的是,写书没人质疑他是不是「真作家」,当程序员却要不断证明「纯度」。
In plain words: As a kid he invented games (create). Video games mostly make you react and consume. Programming brought creativity back, but gatekeepers kept saying he wasn't a "real programmer" and pushed new languages and books. Nobody questioned if he was a "real author"—only if he was a real programmer.
于是我开始满世界飞,教人们做我有时自己都没做过的事(咨询/演讲常见现象:以「专家」身份传授未亲历的经验);大家却突然相信我是「真正的程序员」——主要因为我写的书、做的演讲,起初跟日常写代码关系不大。
有一天,我从大会回来困在机场,在终端前疯狂敲字,一个古怪而温和的声音问我:
劳驾,请给我设计一套系统!
什么?!
给我设计一套系统!
我抬头,被这请求惊到了。环顾四周,是个想当开发者的小孩,让我叫他「printf」——我觉得这名字又蠢又装。他长这样:
我还不太懂电脑,但你好像懂。我想写程序、写博客,让人用、让人读。请给我设计一套系统!
这请求太意外了。那时我已连续醒着 20 小时,脑子不清、也没心情。我告诉他系统很难:不知道他要做什么、希望怎么失败(可靠性设计核心问题:系统允许怎样出错?宕机?丢数据?慢?不同答案对应不同架构)、要支撑多少读者、托管在哪——信息太少,没法设计像样的系统。
没关系。给我设计一套系统。
于是我画了这张架构图:
他看了看说:不行,这套不够好。再画一套。
我又画了一套:
并给他讲解如何运作。
新朋友礼貌地笑了。这不是我想要的,太复杂了,很多我用不着。
我有点被冒犯——我考虑了冗余、监控、备份、缓存、负载均衡、外部支付处理器(法律合规与风控)、故障转移、一键部署等等。咨询费可以收不少!没耐心了,我随手画了这张:
我还说:这就是你的设计。你要的系统在黑盒里,
(敷衍式架构:故意画空盒讽刺过度设计;没想到契合 YAGNI 原则——先做最小可用,别 premature 堆组件) 希望这敷衍回答能打发他走。没想到他回:
正是我想要的!
就这样,我认识了小 printf。
So I lived my life flying around the world, telling people how to do things I had sometimes never done myself, while everyone suddenly seemed to believe I was a real programmer because of things I did that were mostly not related to programming in the first place.
One day, I was stuck in an airport coming back from a conference, furiously typing at a terminal, when an odd, gentle voice asked me:
If you please, design me a system!
What?!
Design me a system!
I looked up from my screen, surprised by the request. I looked around and saw this kid who aspired to be a developer and wanted me to call him "printf", which I felt was very stupid and gimmicky. He looked a bit like this:
I don't know computers much yet, but it seems you do. I want to write programs and blog about them and have people use and read them. Please, design me a system!
Now that was a surprising request, and I had been awake for 20 hours by then, not too sure I fully understood or felt like it. I told him systems were hard. I didn't know what he wanted to do, how he wanted it to fail, how many readers it should support, where he'd want to host it, and I could therefore not design a proper system with so little information.
That doesn't matter. Design me a system.
So I made the following architecture diagram:
He looked at it and said No, this system is not good enough. Make me another.
So I did:
and I gave him a rundown of how it would work.
My new friend smiled politely. That is not what I want, it's way too complex and does a lot of stuff I don't need
I felt a bit insulted, having considered redundancy, monitoring, backups, caches and other mechanisms to reduce load, external payment processor for legal protection, failovers, easy deployment, and so on. I could have charged decent money as a consulting fee for that! Out of patience, I just drew this:
And I added: this is your design. The system you want is inside the black box,
hoping this shitty answer would have him leave me alone. But I was surprised to hear back:
That is exactly the way I wanted it!
And that is how I made the acquaintance of the little printf.
直白版:机场里小 printf 要作者设计系统。作者画了两套超复杂架构,都被拒。最后敷衍画了个黑盒,小 printf 反而说「正是我想要的」。要点:别一上来就过度设计,先能跑起来。
In plain words: Little printf asks for a system at the airport. Two over-engineered designs are rejected. A sarcastic empty black box is exactly what printf wanted. Lesson: start simple; don't consultant-architect a beginner project.
我很快了解这小家伙的作品集:仓库里只有小程序、带表单的简单网页、琐碎命令行工具。平淡无奇,出现又消失。
后来他开始做一个更大的程序:多模块、要 socket、读写磁盘、连真实数据库。第一次成功构建运行时,小 printf 惊叹不已。但程序还不够。
需要重构、更好的测试、文档、lint 和静态分析。程序跑了一阵,某天早上,崩溃了。
又崩。再崩。
配置错了,日志不轮转(log rotation:定期归档/删除旧日志,防磁盘满),磁盘速度不可预测,网络打嗝(hiccups:偶发延迟、丢包,分布式系统常态),bug 冒出来,编码混乱,数据库要 vacuum(PostgreSQL 等清理死元组、回收空间),事务挂起,证书过期,CVE(公开披露的安全漏洞编号)不断,监控指标却沉默(该报警时没报,或监控本身也挂了)。
代码越来越像 Spaghetti(「意大利面条代码」:结构混乱、难以维护)。
他告诉我:事实是我什么都不懂!该按自己的需求来。我傲慢地搭了套花哨系统,修它花的时间抵消了它省下的时间(过度工程陷阱:复杂架构本为省事,结果维护成本反超收益)。但我本该知道,那曾是多么美好的东西。
某天早上,他决定离开办公室。再见,
他对一盏似乎烧坏的 blinkenlight(服务器面板闪烁的灯;黑客圈戏称 blinkenlights) 说。他出去看看,软件世界除了他那台乱糟糟的小服务器,还能提供什么。
日志会继续堆积,直到硬盘再也装不下。
I soon learned of this little guy's portfolio. In his repositories were only small programs, simple web pages with forms, trivial command line utils. They would be unspectacular, would come into being, and no sooner disappear.
Then at some point, he started working on a bigger program, that used multiple modules. It needed sockets, accessed the disk, talked to an actual database. When it first built and ran properly, little printf was amazed. But the program was not enough yet.
It needed refactorings, better tests, documentation, linting and analysis. The program would run for a while, and one morning, it crashed.
And it crashed again, and again.
The configurations were wrong, the logs would not rotate, the disk had unpredictable speed, the network would get the hiccups, bugs would show up, the encodings would be confused, the database needed vacuuming, transactions would hang, certificates would expire, CVEs would keep coming, and the metrics would remain silent.
It kept turning to Spaghetti.
He told me: the fact is I didn't know anything! I ought to have judged by my needs. I got the hubris of writing a fancy system, and I spent so much time fixing it, it felt like it cancelled the time it saved me. Still, I should have known what a wonderful thing it was.
One morning, he decided to leave his office. Goodbye
, he said to a blinkenlight that seemed to have burnt out. He left to see what the world of software had to offer aside from his messy little server.
The logs would keep accumulating, until the hard drive would fill no more.
直白版:小 printf 项目做大后天天崩:配置、日志、数据库、证书、监控全出问题,代码变一团乱麻。他承认系统搭太花哨,修的时间抵消了省下的时间,于是出门找高人。
In plain words: Printf's bigger app keeps crashing—ops hell, spaghetti code. He over-built; maintenance ate the savings. He leaves his messy server to learn from others.
他走进一间联合办公空间,想找有经验的开发者讨教。
他遇到的第一个人,是位非常骄傲的高级工程师,自觉高人一等。
啊,来者何人!欢迎到我的领域——我是这里的专家。
专家?
小 printf 问。意思是你什么都能写?
对!
专家说,又补充:差不多吧;我只写「值得写」的程序。不在琐事上浪费时间。很多程序我没写过,但随手就能写。
那你能帮帮我这套系统吗?
小 printf 刚开口解释,领域专家就打断:
抱歉,我看不出做这事有什么意义。
为什么?
经验。我擅长写我会写的东西,也只写我擅长的东西。在这个相对窄的领域越精,我在其中的价值就越高。叫职场护城河也好,适者生存也好,我就这么干。
(专家只深耕窄领域以保持不可替代;拒绝帮新手,以免分散「投资」)
为什么不能帮我?
帮你会占用我投资自己的时间,去推动别人的进步——对我来说是亏本的策略。你最好的学习方式,是我当年那条路:狠狠挣扎,自己琢磨。能锻造性格。
(把「不帮忙」包装成美德:称帮人会害对方依赖,实则保护自身地位)
这好像不太高效……
你可以上学,也可以自学。本质上这是在淘汰只想走捷径的懒人,留下真正配得上这里的人。一旦让搭便车的人进来,我产出的工作的价值就被稀释。
(优绩制话术:把协作需求污名化为「搭便车」,维护精英小圈子)
你不觉得合作或同事能帮到你吗?
不太。独自工作、不被打扰时我最好。每次被迫和别人协作,我们的东西几乎不可能拼在一起。气急了,我就抓过他们的代码,按合理的方式重写大部分——然后就好了。
小 printf 惊讶:这位专家似乎对帮别人毫无兴趣,却又对他人的「低技能」非常恼火。有点难过——这人把自我定义窄到只会那一块,结果除了给自己制造问题再解决,几乎不做别的!
明白了……那我很高兴你不会帮我,
我的小朋友说。
什么意思?
这位(优绩制/精英主义)男士问,价值感似乎突然被打折扣。你不觉得我做的工作有意思吗?
有意思。只是你大概会把我当累赘和麻烦,而我要的是帮助,不是折磨。
小 printf 迅速离开,留下专家意识到:除了在职场安全上,他在更多方面也把自己变成了「碰不得」的人(untouchable 双关:工作上难被取代,人际上因傲慢而孤立)。
He went to a workspace, looking for experienced developers from whom to get tips and help.
The first one he met was a very proud senior engineer who seemed to feel rather superior.
Ah, here comes a learner! Welcome to my domain, of which I am the expert
he said.
An expert?
Little printf asked. Does this mean you can program anything and everything?
Yes!
the expert answered. He added Well almost; I only program programs that are worth programming. I don't lose my time on trivialities. Many programs I have never written but could write with all the ease in the world.
Ah, so could you help me with my system?
As soon as the little printf started explaining his business, the domain expert interrupted him:
I'm sorry, but I don't really see the point of doing that.
Why not?
Experience. I am good at programming the things I program, and I program things I am good at. By getting better at this fairly restricted set of things I'm already good at, I make sure I'm more valuable than ever at it. Call it job security, call it survival of the fittest, but that's how I roll.
And why can't you help me?
Well you see, taking my time away to help you means I divert important self-investment into furthering the progress of others — that's a losing strategy for me. The best way to learn for you is the way I took myself: struggle very hard and figure it out yourself. It helps forge character.
That doesn't seem very efficient...
Well you can go to school and learn, or you can learn on your own. Really what it does is weed out the lazy people who just want it easy, and forces everyone who stays here to be those who really deserve it. The moment we let moochers in, the very value of the work I produce goes down with it.
Do you not think cooperation or colleagues could help you?
Not really. I work best when left alone and not being distracted. Every time I end up forced working with others, it's nigh impossible to get our stuff working together. Out of exasperation, I grab their work and rewrite most of it in a sane way; then it works right.
Little printf was surprised to meet an expert who seemed so disinterested in helping others, yet so annoyed by their perceived lack of skill. It was a bit sad that this man narrowed his vision of himself to just the one area he knew, to the point where he didn't do anything else than create problems for himself to fix!
I see... well I guess I'm happy you won't give me your help
, said my little friend
What do you mean?
asked the meritocratic man, whose value seemed suddenly downgraded. Don't you think the work I do is interesting?
Oh that I do. It just seems like you would see me as a hindrance and annoyance more than anything else, and what I am looking for is help, not affliction.
And little printf left swiftly, leaving the expert to realize he had made himself untouchable in more ways than just his job security.
直白版:第一个「专家」只深耕窄领域、拒绝帮忙,把自私包装成「适者生存」和「自己挣扎才长进」。小 printf 结论:我要帮助,不要折磨。
In plain words: The senior expert won't help, frames selfishness as meritocracy and "character building." Printf decides he wants help, not abuse.
路上,小 printf 经过一间办公室,里面的人被厚厚精装书包围,封面有巫师、龙、分形和数学图案。
书不错,先生。
谢谢。我觉得是程序员必备。没有这些,你就不是真正的老手。
那我不是老手了,
小 printf 说。你最喜欢哪本?
哦,大部分我还没读。
那你不算好程序员?
不算。
开发者得意地补充:事实上,我是很烂的程序员。
真可惜,
小 printf 说,接着:我自己在进步。
听说过 Dunning-Kruger 效应(达克效应:能力越低的人越高估自己,能力越高的人越低估自己)吗?
没有,是什么?
一种认知偏差。大意是:能力弱的人倾向高估自己,能力强的人倾向系统性低估自己。
所以如果我觉着自己进步了,我大概其实不怎么样?
对,你大概很烂。另一方面,我 公开说自己是烂程序员。按 Dunning-Kruger,我大概是在低估自己——这就让我成了好开发者,懂吗?
大概?
因为自我贬低是开发者的重要工具。一旦觉得自己行了,就会松懈、停止进步。
(行业文化:永远说「我还很菜」以保持学习动力;但也被滥用来装谦虚、实则不帮忙)
那岂不是:一旦自我感觉良好,就在走向失败,然后该感觉糟糕?
对。但做法是:说一切都很烂,即使给不出解决方案。这样你显得聪明,又不用真正贡献什么。
什么意思?
比如上网看到一个不喜欢的项目。诀窍是指出所有问题,别多说。还可以不着痕迹地暗示做这事的人是个蠢货,还往往没事。
(subtly:拐弯抹角、不直说;idiot:此处意指「白痴/外行」——只泼冷水,不教怎么改)
这对任何人有什么好处?
我觉得他们知道自己走错了路会比较好,我指出来也比较好。有点像障眼法(smoke and mirrors:用烟雾和镜子骗人的把戏,喻装腔作势)。没人真知道自己在干什么,但那样看起来像是 我 知道。
要是别人请你帮忙,你又帮不了呢?
那就回到「一切都很烂」:你有太多 yak shaving(程序员黑话:为完成小任务不断被支线拖累,像给 yak 剃毛) 要做,要改进别的东西,要过度悲观。他们自求多福。
所以全是姿态?你在玩游戏?你对自己懂的事装「我不行」,让真不懂的人更难受;对自己不懂的事装「我很行」,让想进步的人也难受。
(揭穿双面表演:谦虚和自信都是策略,不是真实能力反映)
反正能力和这关系不大。声誉很重要。人们雇朋友;不受欢迎、非核心的人先被裁;想改系统的人会被讨厌。全是社交游戏。
(与第五章开头「书摆满但没读」呼应:业内晋升常靠关系与形象,不只看代码)行业就这样,学术界大概也是——我哪知道,对吧?全靠人脉、推销自己、个人品牌。业内找工作就这么回事。
要是业内必须让自己难受、也让别人难受才能混得好,也许我不想在这行找工作,
小 printf 说完走了。
On his way, little printf went in front of the door to an office occupied by a man surrounded by thick hardcover books, with fancy images on them like wizards and dragons and fractals and mathematical patterns.
Nice books, sir
, said printf
Thanks. I think they're essential material for programmers. If you don't have them, you're not really a pro
I guess I'm not a pro then
, said little printf. Which one is your favorite?
Oh, well I haven't read most of them.
Are you not a good programmer then?
No, I am not.
The developer proudly added: In fact, I'm a terrible programmer.
That's a shame
, said little printf, who continued: I'm getting better myself.
Have you heard of the Dunning-Kruger effect?
, asked the man.
No, what is it?
It's a cognitive bias thing. It basically says that people who are less competent tend to overestimate their qualifications, and people who are competent tend to systemically underestimate theirs.
So if I think I'm getting better, I'm probably not great
Yeah, exactly. You're probably bad. On the other hand, I openly say I'm a terrible programmer. But according to Dunning-Kruger, I'm probably underestimating myself, and that makes me a good developer, don't you see?
I guess?
That's because self-deprecation is a vital tool of the developer. The moment you feel you're good, you relax and stop improving.
Doesn't this mean that the moment you feel good about yourself, you're on your way to failure and then you should feel bad?
yes. But the way to go about this is to say that everything is terrible, even if you have no solutions to offer. That way you look smart, but don't have much to contribute.
What do you mean?
Say I go online and see a project I dislike. The trick is to point out everything that is wrong, give no more information than that. You can probably subtly point ways in which the person who did the thing is an idiot and get away with it.
And how is anyone better for this?
Well I like to think they are better for knowing they're on the wrong track, and I'm better off for showing them that. It's a bit of smoke and mirrors. Nobody knows what they're doing but that way it looks like I do.
And what happens when you are asked for help and can't do anything about it?
That's when you go back to saying everything is terrible; you have too much yak shaving to do, improving other things, and being overly pessimistic. They're on their own.
So this is all posturing? You're gaming your way through? You're the person who pretends to be incompetent at things they know, which makes people who actually know nothing there feel even worse, and you're the person who pretends to be competent at things you don't know, so that people trying to improve there also feel bad.
In any case, competence has very little to do with it. Reputation is pretty important though. People hire friends, and people who aren't liked and non-essential get fired first; try to change the system and you become disliked. It's all a very social game. It's how it works in the industry, and probably in academia too, though I wouldn't know, now would I? It's all about who you know, selling yourself, your own personal brand you know? That's how you get jobs in the business.
If this is how things are and that you must feel bad and make others feel bad to do well, maybe I don't want a job in the business
, said little printf, before walking out.
直白版:满墙书却没读几本的人,用达克效应玩话术:说自己烂=其实好,说你进步=其实烂。网上只喷不教,靠姿态和圈子混,不是真本事。
In plain words: The book-hoarder uses Dunning-Kruger word games and online drive-by criticism. Reputation theater beats real help.
本该是午休的时间,小 printf 打断了一个似乎忘了吃午饭的人——三明治越来越凉,人还盯着屏幕。
看起来挺忙,也许真懂行。小 printf 问:
主库(primary database:读写主节点)会挂,从库(follower/replica:只读副本)也会挂吗?
你跑的任何东西,
那人说,迟早都会挂。
连告诉你「已经挂了」的那些东西也会挂?
会。大型系统在任何时刻都处于某种部分失败状态。
(分布式系统真理:100% 正常运行几乎不存在,总有组件 degraded;可靠设计是「部分坏了还能撑」)
那做可靠系统有什么用?
那人答不上来——此刻他正响应一条 page(on-call 告警 paging,紧急呼叫值班人员):云(cloud 基础设施,非天上那朵) 挂了,天都要塌(the sky is falling:夸张说法,指大面积服务中断的恐慌),他也在想同样的问题。
那做可靠系统有什么用?
小 Printf 追问。
那人正在处理生产事故,小孩不肯走,三明治也凉了,不耐烦地回:
完全没用。编程反正全是 shit。
哦!
他倒吸一口气。
一阵完全的寂静。
小家伙带着一点怨意回应:
我不信。程序脆弱,但程序员可以努力,让东西更好、更有用。
没有回答。那人已打开「从零启动整个集群新副本」的文档,情况似乎越来越糟。
那你其实相信好程序、可靠程序——
不不不!
那人说。我不再相信好程序或可靠程序!都很烂!刚才只是生产事故上头,随口说的。你没看见我在拼命维持这些玩意儿运行吗?这些 破烂其实事关重大。
Printf 震惊地盯回去。
有真实后果?你说话像个「真正的程序员」。
(反讽:嘴上贬低编程,行动上却在扛关键系统——这正是「real programmer」在做的事)
他补充:
你把一切混成一团。世上跑过无数程序,年复一年,照样运行、照样失败。人们用过、需要过。我知道有些程序只跑在一台笔记本上,一个失误就能毁掉整个社区,甚至无人察觉。
(小 printf 反驳:程序不必庞大才重要;本地小工具也可能有巨大社会影响)你觉得这不重要?
那人保持沉默。
During the time that would have been lunch break, Printf interrupted a person who had seemingly forgotten to eat their lunch, a sandwich growing cold by the minute, while sitting at their desk and looking at their screen.
That seemed like quite a busy person who might have known what they were doing. Printf asked:
If a primary database can fail, can the follower fail too?
Everything you run
, the person said, can and will sooner or later fail.
Even the things telling you things have failed?
Yes, even these ones. All large systems are in some state of partial failure at any given time.
Then, trying to make reliable systems, what use is it?
The person did not know, for at that moment, they were trying to answer a page for the sky falling out onto their head due to a broken cloud, wondering the same thing.
Then making reliable systems, what use is it?
pressed little Printf again
Upset as the person was dealing with a production issue, with this kid not letting go and a sandwich going to waste, the person impatiently shot back:
It's of no use at all. Programming is all shit anyway.
oh!
, he gasped.
Then there was a moment of complete silence.
The little guy responded, with a hint of resent:
I don't believe you. Programs are fragile, but programmers can make good efforts and make things better and useful.
No answer came back. At that point the person had opened the document explaining how to boot a new copy of the whole cluster from scratch, and things seemed to go from bad to worse.
And you actually believe good reliable prog-
Oh no!
the person said. No no no! I don't believe in good or reliable programs! Not anymore! They're all terrible! I just told you the first thing that came to my head because I'm dealing with one of these shitty systems right now. Don't you see I'm trying to keep this stuff running? This shit is actually of consequence.
Printf stared back, with a shocked expression.
Actually of consequence? You talk just like a 'real programmer'.
He added:
You mix everything up, confuse everything. There's been millions of programs, and for years they've been running and failing just the same. And people have used them and needed them. And I know of some programs that run nowhere but on a single laptop, and in a single mistake could destroy entire communities, without even noticing. And you think that this is not important?
The person remained silent.
直白版:处理事故的工程师气话说「编程没用」,马上又承认这些烂系统「事关重大」。小 printf:程序会挂,但程序员的努力能帮到真人;小工具也可能影响整个社区。
In plain words: An on-call engineer says programming is useless, then admits these broken systems really matter. Printf: code fails, but effort helps people—even a script on one laptop can matter.
朋友去的第四个工位,电脑贴满贴纸,看不出什么品牌。
motor-mvc、quadrangular JS、GoQuery、cometeor、某个日式 soundy 框架……
嗨,
printf 打断。你在干嘛?
alchemist、bongodb、mochascript、walktime.js、portasql……
那人继续念。
你在干嘛?
他提高音量又问。
哦,在试新框架、工具、数据库、语言。
哇,你好快,像十个程序员加起来!
对!行业动得太快了!
他看了眼手机,补充:看!cardboard.io 框架出了 3.5,和 3.4 不兼容,社区 fork 了四个版本!我得全试一遍才知道选哪个!
(框架名多为恶搞:Rails→cardboard、MongoDB→bongodb 等)
学这些是为了解决什么问题?
我是 early adopter(早期尝鲜者,追逐新技术)。不紧跟潮流,就得一辈子写 COBOL(1960 年代商业语言,常喻「过时技术」) 或 MUMPS(医疗/金融领域老语言)。你要找到下一个风口,乘浪冲到顶!
成功过吗?
当然!Rails 火之前我就知道了,node.js 流行前我就搞懂了,redis、mongodb、riak 第一批 beta 我也用过!第一个用 vagrant,然后推动换 docker——现在当然全是 unikernels(把应用与内核打包成单一镜像的架构 fad)……
酷。你站在潮头的这些,回报如何?
哦,没有;Rails 大火时我已扑向下一波,免得落后。别的也一样。但愿 unikernels 能成吧。
明白了,
小 printf 沉思道。这些框架解决了什么问题?
哦,我确保公司不用注定没前途的技术。很重要——不然只能雇到跟不上时代的老程序员(grey beards,行业刻板印象),而你要的是自驱型猛人(self-motivated go-getters),也是 early adopter。
有意思,
我们的朋友说。
很难的!在创业公司里,要顶尖人才(a-players,硅谷招聘黑话),得用酷技术吸引他们!否则只剩僵化落后的人。没人想当落后者。
小 printf 插话:不,我不是这意思,
又说:有意思的是:工具本该替我们解决问题,对你而言,工具本身成了问题。
(核心讽刺:追逐框架/语言本身成了全职,忘了工具是为业务/用户服务的)
那人默然站着(在那张新潮的 treadmill desk(边走路边工作的跑步机办公桌,一时风尚) 上),小 printf 跳出房间。
The fourth workspace my friend visited had a man whose computer was covered in so many stickers nobody could tell what brand it was.
motor-mvc, quadrangular JS, GoQuery, cometeor, some japanese soundy thing, ...
Hi,
interrupted printf. What are you doing?
alchemist, bongodb, mochascript, walktime.js, portasql, ...
, the man kept going
What are you doing?
, he asked again, louder this time.
Oh, I'm trying out new frameworks, tools, databases, languages.
Whoa, you seem to be going fast, maybe as fast as 10 programmers put together!
yes! well, the industry moves so very fast!
, he looked at his phone for a second, and added there! the cardboard.io framework came up with version 3.5 which broke compatibility with 3.4 and this yielded 4 forks in the community! I have to try them all to know which to choose!
and what do you do learning all of these?
I'm an early adopter. If you don't stay up to date you get stuck writing COBOL or MUMPS for a living. You want to find the next big thing, and ride the wave to the top!
Has it ever worked?
Oh yes! I found out about Rails before it got big, and I figured out node.js before it was popular, and I was on the first beta copies of redis and mongodb and riak! I was the first one to use vagrant and then I got us to switch to docker but of course now it's all about unikernels..
Cool, and all these things you were at the forefront of, how did it pay off?
oh it didn't; by the time rails became huge I had moved on to the next big thing so I didn't get left behind. Similarly for the other ones. Here's hoping for unikernels though
I see
, added little printf, pensively. What problems do you solve with all of these frameworks?
Oh, I make sure we don't use something that is not going to be big, so that this company doesn't get to bet on technologies that have no future. It's very important work, because if you don't do that, you can't find anyone to hire except old grey beards behind the times, and you want self-motivated go-getters, who are also early adopters.
, said the man.
That is funny
, chimed our friend.
It is very hard! in the startup world, if you want a-players, you need good technology to bring them in! Otherwise you're stuck with inflexible laggards. Nobody wants to be an inflexible laggard.
The little printf interjected: No, that's not what I mean,
and he then added I mean it's funny that tools are meant to solve problems for us, but for you, the tools themselves have become a problem.
And while the man stood there in silence (on his new cool treadmill desk), little printf hopped out of the room.
直白版:追每个新框架的人,从没从任何一次「站在潮头」里赚到钱——火之前就换下一个了。他忙的是别用过气技术,不是解决业务问题。工具成了问题本身。
In plain words: The early adopter never cashes in—always jumps to the next hype. He manages tool fashion, not user problems. The tools became the problem.
隔壁办公室坐着疲惫的员工,几十个空咖啡杯,蜷在键盘前,气呼呼地敲字。
嗨,
小 printf 说。
女人没停,疯狂敲键盘。
你好?
他又问。
女人立刻停下,从抽屉掏出扁酒壶(flask,此处像借酒消愁)灌一口。
这工作糟透了,
她说。我做 DevOps(开发+运维:部署、监控、保线上稳定)。起初还行,多半在写代码,偶尔排错。后来越来越糟。开始在技术栈里「救火」(紧急修生产故障,非写新功能),火却越灭越多。我这边那边搞「小奇迹」(勉强撑过去的临时修复),还要赶开发工期。
公司没雇人帮忙?
没有,问题在这:小火不断,我救火占时间,开发就不如以前仔细,又制造新火。现在日夜救火,恨这工作。
雇主怎么不管?
我干得好,撑得够久,大家习惯了。你习惯搞小奇迹,别人就习惯指望奇迹。然后你得一直创造奇迹,否则他们觉得你失职。
(「英雄陷阱」:临时救火救场会被当作常态;公司不扩编,反而加活)
听起来很难过。
确实;因为你最熟悉这些火,你就越来越只干救火,直到雇主雇别人接你原来热爱的开发岗。你若足够在乎工作、愿意干人人嫌的脏活,「感谢」方式就是让你干更多你不喜欢的活,直到只剩这些。然后没什么可享受的了。
(DevOps 常见轨迹:因能扛事被锁死运维,再也写不了新功能)
那你真不走运,
小 printf 说。
她的 pager(寻呼机/告警器,on-call 标配) 又响了。
那女人,
小 printf 自言自语,继续赶路,会被其他人鄙视:被资深专家、摇滚明星式开发者(rockstar developer:自封技术明星,爱炫技、轻视运维)、连环早期尝鲜者。然而她似乎是唯一肯帮忙的。也许因为她想的不仅是自己。
In the next office over sat a tired employee, with dozens of empty coffee cups, slouched over, typing angrily.
Hi,
said little printf.
The woman didn't stop what she was doing. She kept typing furiously.
Hello?
he asked again.
The woman stopped at once, got a flask out of a drawer in her desk, and took a swig.
I have a terrible job,
she said. I do devops. It started okay, where I'd mostly develop and then sometimes debug stuff, but as time moved on, it got worse and worse. I started fighting fires in our stack, and then more fires kept happening. I got rid of most of them, pulling small miracles here and there to then meet the deadlines on dev stuff I also had to do
And did they hire anyone to help?
No, that's the thing. Small fires kept happening here and there, and because of the time I took to fight them, I couldn't be as careful as before with the dev stuff, so I created more fires all the time. Now I'm fighting fires all day and all night and I hate my job
Why doesn't your employer do anything?
I'm good at my job, and I managed to keep things under control long enough that everyone got used to it. When you make a habit of small miracles, people get used to it. Then you're stuck doing miracles all the time or they will think you won't do your job at all.
That sounds very sad
It is; and because you're the most familiar person with these fires, you get to only work on them more and more, until your employer hires someone else to cover your old job, the one you loved. If you care hard enough about your work to be the one doing the stuff everyone else hates, you're thanked by doing more and more of that work you don't like, until that's all you do. And then there's nothing left for you to enjoy.
Then you're unlucky
, said little printf.
And her pager went off again.
That woman,
said little printf to himself, as he continued farther on his journey, that woman would be scorned by all the others: by the senior expert, by the rockstar developer, by the serial early adopter. Nevertheless she is the only one of them all who seems helpful. Perhaps that is because she is thinking of something else besides herself.
直白版:DevOps 女工程师因总能「小奇迹」救火,被永久绑在救火岗;她爱的开发工作被人顶替。别人瞧不起她,她却是唯一在替别人扛事的人。
In plain words: The DevOps engineer is stuck firefighting because she's good at miracles. She lost dev work she loved. Others scorn her; she's the most helpful person there.
大楼角落,printf 找到一间大办公室,大窗视野开阔。一位老先生坐在堆满文档的书桌后。
啊,来了一位开发者!
printf 站在门口时那人说。请进!
小 printf 看窗户,上面写满字。用白板笔,外面的世界被圆圈、箭头、圆柱和云遮住。奇怪的是窗外明明有真云,他却要画云(隐喻:架构师活在抽象图里,与真实用户/代码/性能脱节;窗=本应看见的真实世界)——整体却更令人好奇。
这是什么?
朋友指着窗户问。
这个?这是我们的生产系统(production system,线上真实运行环境)!
那人说,从没想过人家问的是窗外。我是软件架构师。
软件架构师是什么?
主要是懂如何最好地组织、协调大型系统的组件,使它们协调运作。要懂数据库、语言、框架、编辑器、序列化格式、协议,以及封装、关注点分离等概念。
很有意思!
小 printf 说,终于有人能回答我所有问题了!
他瞥了眼架构图。系统很了不起。跑得快吗?
我说不上,
架构师说。应该快吧。
代码呢,好吗?
我说不上。
用户满意吗?
恐怕也说不上。
可你是软件架构师!
正是!但我不是开发者。不是架构师去写模块、类、拼库。软件架构师太重要,不能到处碰代码。
(讽刺「象牙塔架构师」:脱离实现细节,却声称能指导一切)但他和程序员谈话、提问、给指导。问题足够有意思,架构师就接管规划。
为什么?
因为我们更有经验。我们更懂系统和什么行什么不行。开发者可以延伸我们的知识,产出伟大的系统!
不碰代码,怎么知道事情顺不顺?
我们信任开发者。
所以信任他们正确实现你的想法,却不信任他们有自己的想法?
软件架构师明显一震。我想我有点脱节了,
他终于承认。问题是做久了,你整天和想法打交道,没有好办法检验或验证……
他沉思着低头。有时软件架构师既不做软件也不做架构,似乎。
(双关 punchline:只剩头衔和 PPT,既不写代码也不做有效架构决策)
小 printf 离开房间,参观结束,走出大楼。
At the corner of the building, printf found a large office with big windows giving a stunning view of the area. In it sat an old gentleman with reams of documentation on his desk.
Ah, here comes a developer
exclaimed the man, as printf stood in the doorway. Come in!
Looking through the windows, little printf noticed that they were full of writing. With the help of a dry-erase pen, the view to the outside world was masked by tons of circles, arrows, cylinders, and clouds. While it was curious the man needed clouds drawn where real ones could be seen outdoors, the whole ensemble was more intriguing.
What is this?
, asked our friend, pointing at the windows.
Oh this? This is our production system!
Said the man, not once thinking the question was about the outside world. I am a software architect.
What's a software architect?
Mostly, it's someone who knows how to best structure and coordinates the components of a large system so they all fit together well. It's someone who has to know about databases, languages, frameworks, editors, serialization formats, protocols, and concepts like encapsulation and separation of concerns.
That is very interesting!
said little printf, here is someone who can answer all my questions!
He glanced at the architecture diagrams. Your system is very impressive. Is it running very fast?
I couldn't tell you,
said the architect. It should, though
How's the code then, is it good?
I couldn't tell you
Are the users happy about it?
I couldn't tell you either, I'm afraid
But you're a software architect!
Exactly! But I am not a developer. It is not the architect who goes and writes the modules and classes, combines the libraries. The software architect is much too important to go around touching code. But he talks with programmers and developers, asks them questions, provides them guidance. And if the problem is looking interesting enough, the architect takes over the planning.
And why is that?
Because we are more experienced. We know more about systems and what works or not. Developers can then be an extension of our knowledge to produce great systems!
But how do you know if things are going well without getting involved with code?
We trust the developers
So you trust them to implement your ideas correctly, but not enough to come up with their own ideas?
The software architect was visibly shaken by this comment. I guess I might have been a bit disconnected
, he finally admitted. The problem is that after a while you are asked to work with ideas so much you don't have a good way to get them tested or verified...
he stared down, pensively. Sometimes a software architect does neither software nor architecture, it seems.
Little printf left the room, and being done with his visit, exited the building.
直白版:架构师在窗上画系统,却说不清快不快、代码好不好、用户爽不爽。小 printf 戳破:你信他们写你的图,却不信他们有脑子。架构师承认脱离现实。
In plain words: The architect draws on windows but can't say if the system works. Printf: you trust devs to build your vision but not to think. He admits he's disconnected.
小 printf 出门后,遇到为慈善募捐的人。
嗨,
那人说,今天愿意帮帮别人吗?
大概会让我好受点,
小 printf 回,在这栋楼里待了一整天,比来时更糊涂了。
明白了。这些人都是开发者。不太帮得上忙,对吧?他们爱说在改变世界,而且大体上确实在改变。
那为什么感觉这么别扭?
他们做得最好的,往往是把某些人的工作变成程序,或让大家的休闲更休闲。
(软件影响常被夸大:多是自动化岗位或做更省事的娱乐,未必解决深层社会问题)「软件正在吞噬世界」
(Marc Andreessen 2011 名言:各行业将被软件重塑),这确实改变了世界的面貌……但骨子里还是旧世界,只是脸拧歪了。别扭的原因:这样变,不等于变好。我们仍有同样的缺陷和问题,内心深处同样的空洞要填。
那我怎样才能好受点?
小 Printf 明显焦虑。
那人想了一会,请 printf 一起来帮别人——这是他让自己好受的方式。下午 printf 讲了自己的烦恼和经历。长时间沉默后,那人说:
人们玩的身份游戏、追逐的角色与声誉、解复杂难题得到的短暂快感,玩一阵是有趣。但若没解决真正值得的事,若忘了牵涉其中的人,永远不会真正满足。
(技术圈虚荣:解谜题、攒 GitHub star、争头衔,不等于有意义的工作)
这也许可以,也许不行;长大后你也许从工作以外得到满足感,也许得不到。工作可以是工作:为钱、为乐趣。没关系。只要人生某处得到满足感。
归根结底,只有当你解决「带着人脸的问题」(关涉真实的人与生活的难题;亦呼应《小王子》「本质用眼睛看不见」),才能感到真正正确;重要的东西,计算机看不见(化用《小王子》:「重要的东西眼睛看不见」)。
「你在系统上花的时间,让它变得重要,」
(化用《小王子》:「你在玫瑰上花的时间,使她变得重要」——投入本身会让人产生依恋) 那人补充:「当你忘了为何值得花时间,当它变成虚荣的游戏,带来的痛苦多于慰藉。」
开发者常忘这条真理:若失去方向,维护系统本身成了问题,最有效的办法是去掉系统——既然它是问题所在。
(再次呼应《小王子》:忘记本质时,占有物反成负担;该删就删,别为虚荣硬撑烂系统)
只有解决带着人脸的问题,才能感到真正正确,
小 printf 重复,好记住。
Little printf, once outside, met a man collecting money for some charity.
Hi,
said the man. how would you feel about helping someone today?
It would probably make me feel better,
said little printf back. I have been in this office all day, and now I'm more confused than ever.
Ah I see. These people are all developers. They are not really helpful, are they? What they love to say is that they're changing the world, and they pretty much succeed at that, in fact.
Why does it feel so awkward, then?
Asked little printf.
Well, the best they do is often help convert some people's jobs into programs, or make everyone's leisure more leisurely. Software is eating the world and that changes its face for sure... but deep down it's the same old world, with a mangled face. The reason it feels awkward is that changing in that way doesn't mean things are getting any better. We have the same flaws and problems we always had, the same holes to fill deep down inside.
So how can I feel better?
Little Printf was visibly anxious.
The man thought for a while, and offered printf to come help him help others, as this was this man's way of feeling better. During the afternoon, printf told the man about his problems and his adventure. After a long silence, the man said:
The games people play, the roles and reputations they chase and entertain, the fleeting pleasure they derive from solving intricate problems, is all fun for a while. Ultimately though, if you do not solve anything worthwhile, if you forget about the people involved, it's never gonna be truly fulfilling.
And that may be fine, and it might not be, and you may or may not get that from somewhere else than your workplace when you grow up. Work can be work; it can be for the money, it can be for the fun of it. That's okay. As long as you manage to get that fulfillment somewhere in your life.
In the end though, it is only when you solve problems with a human face that you can feel truly right; What is essential is invisible to the computer.
It is the time you have spent on your system that makes it so important", the man added, "and when you lost sight of why it made sense to spend time on it, when it became a game of pride, it caused more grief than relief.
Developers have often forgotten this truth; If you lose sight of things, working on your system becomes its own problem, and the most effective solution is to get rid of the system, given it's the problem.
It is only when you solve problems with a human face that you can feel truly right
, repeated little printf to himself, so he would remember.
直白版:募捐者:开发者确实改变世界,但常是自动化岗位或让娱乐更娱乐,不等于变好。身份游戏、解难题的快感填不满内心。要解决「与人有关的问题」;若系统成虚荣负担,删掉它。
In plain words: Charity worker: devs change the world, often by automating jobs or leisure—not necessarily improving lives. Status games aren't fulfillment. Solve human-facing problems; drop systems that exist for pride.
Printf,此刻就坐我对面,正在回家路上。和他聊让我意识到:我做的事,有多少背离了我喜欢的、我开始编程的初衷(作者自省:最初因「创造」而编程,后来陷入身份游戏)。Printf 遇到的每个人,都是我曾或将成为的角色。有人鼓励我成为他们,我也可能同样去鼓励别人。
我被拖进「成为真正的程序员」的游戏(第一章那条 gatekeeping 链:不断换语言/书/标签证明自己「够格」);Printf 没有。他说可以接受不做「真正的程序员」,更愿做「有人脸的程序员」(关注真实的人与问题,而非技术身份与圈内姿态)。
今天我困在回望里:能否也成为一个「有人脸的程序员」;或我所做的一切只是一份工作。值得追求的中间态,似乎不多(非「技术大神」即「纯打工」——作者在质疑这二元对立是否成立)。
总之,printf 觉得不必做「真正的程序员」;我想,我现在也这么觉得。
Printf, who's now sitting right in front of me, is on his way home. Talking with him made me realize how much of what I do flies in the face of what I liked, what I started programming for. Each of the people Printf met are roles I see myself taking one day or another over time. I was encouraged by them to become them, and probably encouraged people to do the same.
Where I got dragged in the game of trying to become a real programmer, Printf didn't. He said he was okay with not being a real programmer, that he preferred to be a programmer with a human face.
Today I'm stuck in the situation where I look back, and have to figure out if I can, too, become a programmer with a human face; or if everything I do is just a job. There doesn't seem to be too much that's worthwhile in-between.
In any case, where printf felt he didn't need to be a real programmer, I think I feel the same now.
直白版:作者对照小 printf:自己陷进「成为真正程序员」的游戏,小 printf 选择做「有人脸的程序员」——关注人,不追标签。作者自问还能不能回到写代码的初衷。
In plain words: Author reflects: he played the "real programmer" game; printf chose a "programmer with a human face." Can he return to why he started?
直白版:这篇《小王子》式寓言串起编程圈几种典型人:过度设计、门禁式专家、装谦虚的批评家、追框架的尝鲜者、救火 DevOps、脱离代码的架构师……核心就一句:工作可以为钱、为乐趣,但意义来自解决「与人有关的问题」,不是赢得「真正程序员」的身份游戏。重要的东西,计算机看不见。
In plain words: A Little Prince-style fable tours archetypes: over-engineering, gatekeeping experts, performative critics, framework chasers, burned-out ops, paper architects… Core message: work can be for money or fun, but meaning comes from human-facing problems—not winning the "real programmer" status game. What is essential is invisible to the computer.