一个 Perl 程序员职业生涯的中年危机


意外地读到这篇文章,正在找工作的自己略有感触但不知从何说起。不过至少我想要把它翻译出来,给更多的人看到。

原文发布于 2014 年 2 月份发布在《Modern Perl》一书的配套网站上。 链接是:http://www.modernperlbooks.com/mt/2014/02/the-mid-career-crisis-of-the-perl-programmer.html。作者 chromatic。

原文与本文均以 CC-BY-NC-SA 3.0 许可发布。


HN 网友总结: 建个面向土拨鼠的匿名社交网,卖给硅谷大公司挂广告或者挖掘用户数据,这就是一〇年代的创新。

proggit 网友总结: 与其熟练掌握一种编程语言,并精通解决问题的思维方式,不如花时间用 Haskell Rails Erlang Scala Rails Python Node Clojure Julia 语言写个 CRUD 软件,模板系统,依赖注入框架,还有 ORM。

起点

1998 年,我放弃了自己的音乐人职业生涯。说是“职业生涯”有点夸大了。虽然我做音乐的时候赚过钱,但还没做到能自称专业的程度,更枉谈交得起房租还要果腹。于是我在惠普彩色激光打印机部门给自己谈到了一份工作。

我在打印机团队里写代码,就是因为自己想写。我拿 AWT (当时 Swing 刚出来,在 Linux 上好一阵子都不能用)给客服写了个小软件,专门做客户问题详情记录。后来网络团队想要在网站发新技术文章的时候给客户自动发邮件,也找我写程序。当时只写了十行的 Shell 脚本(版本是 HP-UX 9.几自带的那个,记不清了)。后来我想改写成 Java 版,但代码要多出几个数量级,我也就没能坚持写完。

后来我发现自己还是喜欢折腾 HP-UX 跟桌子底下那台 Linux 服务器。相比之下,研究打印机卡纸,或者 PostScript 驱动渲染出错,我就没那么上心。于是我转职去当了个 SA。(想转到开发方向的工作得搬去别的州,而且人家要求得有 CS 学位,但我只有音乐学位。)

新工作的前三个月,我一边要响应紧急故障,一边要把手上的问题尽量自动化解决掉。之后我就开始闲了下来。这个时候我就看上了互联网。当时 mod_perl 刚出来,Java applets 不怎么好用。我就开始学 Perl。

一开始我自己写了几个免费小软件,后来这些项目都没什么进展。当时人人都写过自己的模板系统。但我找到了 Everything 2 的文本预处理模块源码,就给这个项目写了点代码。再后来(Carly Fiorina 为了省钱,把 SA 都给裁了),我去了一家互联网公司上班,这家公司做了 Perl Monks,很快就火了。

后来我写了本书。书的封面很帅,不过估计你也没机会看。(那本书是英语世界里第一本谈博客的书,但不知道怎么搞的,书的标题印错了。这时候第一批互联网热潮只剩下尾声。在那个年代,只要找好角度去吹,随便一个点子都能吹成金点子。就差把交管局也说成好东西了。)

写书这件事,一半要疯狂钻研,另一半是繁琐劳动。为了说服自己“我的所作所为对这个残酷冷漠的宇宙还是有积极意义的”,我应 Michael Schwern 所求,将 Test::SimpleTest::More 的内部架构统一了,这就是后来的 Test::Builder

这个项目当时在 perl-qa 邮件列表的眼里,可以说是个革命。对整个 Perl 社区来说也是。但现在回头再看它,你会觉得“这不明摆的吗?”,“这也算革命?”。因为它貌似于尽人皆知的常识,比如“多喝水”,“吸烟有害健康”这种。

之所以说这是革命,是因为在它的基础上,雨后春笋般地出现了上千个测试模块(为解决各种不同的测试问题),并且为这些模块提供了共同的生长土壤(测试模块间可以协同工作,但模块作者不必为此劳神)。这是 API 设计中的一个重要原则:把困难、繁琐、蹊跷的部分自己处理好,让别人不会重复踩坑,但又不限制调用方的自由使用。如果你想到了分层设计,没错就是那个意思。

藉由我在开源 Perl 项目中的贡献,我去做了一阵子的软件咨询工作。(在网站上靠回答问题出点名,确实能让你在社区里建立名望与人脉关系。给知名项目提交代码也很有用)

后来我的事业就受挫了,我改行去做了一段时间的编辑,关注点是开源软件与技术。

业余参与开源

我觉得不让自己的编程技能生疏还是很重要的。于是我投入开源项目(包括开发和写书)的时间比以往更多了。在 Parrot 项目上投入了不少精力

(2007 年起,在各种场合,总有 Parrot / Rakudo / Perl 6 开发者跟我说“确实,这个项目拖得太久了,而且大家都没拿到好处。但是再等 18 个月到发布,出书 / 培训 / 咨询的市场就能做起来,到时候我们就好过啦!”)

那段日子是 Perl 程序员的困难时期。Perl 助推了 Ruby / Rails像滚雪球一样壮大(距今已经满九年了),Perl 自己卡在 5.8 版本,三年没有进步。人们仍然把希望寄托在 Perl 6 身上,希望这个语言能时来运转。另一方面,测试文化已经像看不见的有益肠道种群(饭后一定要染上的那种)一样感染了语言核心与 CPAN。文化有土壤,有根基,也见了成长,但仍需要时间积累。

Pugs 项目也对 Perl 有点助推作用,但 Pugs 已经成为历史趣闻许久了。

悄然复兴的 Perl

虽然全世界都已经不再指望 Perl 能出新版,Perl 5 还是出了几个新版本。再加上 CPAN 的存在,我依然坚持 Perl。还好在这件事上我并不孤独,2014 年 Perl 能新出大项目,全靠 Moose 项目的助推。当然我不能否认 DBIx::ClassMojoliciousCatalyst 等项目也有功劳,不得不提。但 Moose 带来的革命是大张旗鼓地推翻既有范式的革命。如果说 Moose 是古巴革命的卡斯特罗,其他 CPAN 上的项目就像切・格瓦拉一样抢了功名。除非你觉得给垄断企业送钱把你的偶像照片印T恤上就算是文化叛逆了。(这个类比跑偏了,它自己骑摩托游南美去了。抱歉。)

这次革命需要师出有名。

现代 Perl

JavaScript 也迎来了复兴:以前它是“没人喜欢但又不能不用的语言”,复兴之后它成了“睁只眼闭只眼无视语言缺陷再加上严守恪守戒律就能写出不那么太烂的代码的语言”。(如果这个辩解让你觉得似曾相识又心里一酸,别忘了JavaScript 是你在 Web 客户端的唯一选择,Perl 就没这个限制。)

我觉得这是个机会,我应该离开这个越发压抑的企业技术出版界,自己去办一家技术出版社。跟企业级出版社不同的是,我们第一本书从开始做到开印也没花到上万美元。虽然写出一本《Modern Perl》 这样能赚钱的书总归是好事,但写书与出版这件事最好还是看作“一种爱好,能给你赚点小钱,够你时不时下顿馆子”,而不是“这辈子再也不用工作啦。除非你硬要把躺在金山上睡觉说成是工作”。

出版业也是个吃爆款的行业。但想要出一本畅销书就像是半随机遭雷劈,你得在正确的时间出现在正确的地点。你还得学德州扑克牌手那样,懂得什么时候该全押上,更要知道什么时候该抽身。技术出版市场做成现在这么烂,就是因为很多人不懂这一点。Ruby on Rails 是 2005 - 2006 年最火的技术话题,火爆程度可比当年的 JSP。它的出版市场在 2007 年就已经到达顶峰,然而时至今日,会说话的人偶,餐桌上的竹蛏,快递新鲜蔬菜的无人机已经司空见惯,出版商还在大量围绕 Rails 出书。一如它们在 1998 - 2001 年间为 Perl 疯狂出书。尽管当时一键下单这个泡沫已经濒临破灭,无数人因此丢了工作,或者放在过热股市里的纸钱就没了。(你从权力幻想小说邪教里招个青春期来经营世界最大经济体,就必然是这个下场。当然了,我把话说成这样,是因为我只有音乐学位,没有经济学学位,再就是还有事后诸葛亮的成分。)

如果你要问我为什么没去写一本《Modern Perl Testing》的书,那么这就是原因之一。在越发难得的周末,我宁愿干点放松的事(陪陪家人和朋友),更健康的事(烹饪,锻炼),或者能赚外快的事(投资),也不想劝自己写书。也许以后,我对 Rust 语言的有所为,有所不为能感兴趣的话,兴许我会写一本《Rust 编程》的书。这么一说,我有点后悔十年前没能给 Parrot 写这么一本书。

即便如此,《Modern Perl》这本书的写成,出版,以及在网上的免费发布,终究是件好事。也许同样花那么多时间,写这本书赚到的钱还不如在星巴克给人兑奶昔赚得多。但这本书的 PDF 的免费发布,与书的配套网站上的内容所制造的社会公益,是我职业生涯中收获的最高成就感。(也许从代码的角度来说,Test::Builder 项目造成的影响更深远。但是一旦我开启这个思考方式,再想起我搞过的那些个当时看上去挺有影响但其实没什么实质发展的大项目,就打心眼觉得(此处插入超长的德语哲学概念组合名词)。)

《Modern Perl》这本书,往小了说,它给 2010 年代顶尖 Perl 程序员所实践的代码风格起了个具体的名字。往大了说,它帮现存的 Perl 程序员(和新学 Perl 的人,如果还有的话)对 Perl 做到取其精华,去其糟粕。

某现代 Perl 咨询师的金手铐

后来我稍微尝试了一下自己开个反正不是出版界的公司(对了,你要是能把这篇写给个人投资者的价值投资指南或者怎样做一杯果昔的链接给推一推,那就多谢了),才发现从零开始办公司实在是太难,太难。

我觉得,很多小咨询公司固守着咨询业务,而不去把自己的创意做成产品,其中一个原因就在于做实业难。咨询的钱太好赚,下本钱去做前景不明的产品太难。而且这事我也不是第一次经历。如果我的第一份工作能在第一轮互联网泡沫破灭时,坚持把自己的产品做出来,就能占领一块肥厚的垂直市场。然而不幸的是,等做咨询赚的钱都花完了,也没做出一个验证概念的原型来。手上没有原型,连预售也搞不起来。(当然,投资人还要求说要用 Java 统一重写 Perl 的后端和 Python/Wx 的客户端,虽然那一年是 2002。然后还说程序要跑能在小商户的零售终端上,虽然那都是 2002 年的硬件水平。)

做咨询行情好的时候,来钱确实快得诱人。咨询师比普通程序员的时薪要高,是因为你得自行承担开销:合同需要自己去谈,而且还不一定谈得成,没合同的时候只能闲着,还没有带薪休假,还没有免费福利。

如果你能找到个优质客户,你肯定得拿人家当教皇、女王、活佛三者叠加的标准供起来。像这种说话算话,按时给钱,又不计较合同细节的客户真是千金不换。

假设说,你要连续八九个月勒紧裤腰带,然后运气好一点,又接了个两倍于此的单子。这种饥一顿饱一顿的经济周期,有些人能接受,有些人就不一定受得了。(对我来说,收紧预算在公司制度上还好办,但心理上的起伏就不好受。)做咨询能赶上个好合同,不仅钱多,自由度也高。但合同太烂或太少,日子就难过。相比之下,按月拿薪水能带来太多的安全感,再看别的赚钱机会都很难保持客观心态。

找个写 Perl 的工作吧

我是不是个 Perl 程序员?

我很幸运 16 年来能在多个项目、工作、领域里深层运用 Perl。我也做过写 Python,SQL,shell,Ruby,C,C++,JavaScript,assembly,Java,SQL,PL/pgSQL,Visual Basic,PHP,LaTeX 的工作。而且应该还有一两个语言是我用过但想不起来的。

作为一个有志于职业成长,但除了朝九晚五之外在生理上写不下去代码的程序员,我对 Perl 之外的技术也有所涉猎。虽然没达到我对 Perl 这么专精的水平,但跟人聊天的时候,还不至于完全说不上话那么尴尬。(有一次 Chuck Moore 跟我聊起自己写一个操作系统的重要意义,那次对话被我录成 MP3 了。)

然而在我的简历上,Perl 这个技术名词反复出现。

我确实喜欢这门语言。我习惯了它的缺陷(尽管在这个网站上的几百篇文章里,你肯定能找出那么几篇写出了我对某些缺陷有多讨厌)也懂得怎样发挥它的长处。我喜欢它的社区(像 Tim Bunce,Karen Etheridge,Rik Signes,Andreas König,Jess Robinson,Tatsuhiko Miyagawa 这样的人,真心都是无可替代的)。我在写 Perl 时的效率太高,去写别的语言短时间内根本达不到同等水平。毕竟这是十六年积累下来的经验。毕竟这是两万小时的练习成果。

那你学会编程了没?

我能找到推荐人对我的编程水平给予高度评价。我帮人解决过问题,我也教过别人解决问题的思维方式,你说我学没学会。

(当然你也能找到有些人说我说话尖酸刻薄情绪化。不论如何,既然你都读到这了,我也不用假装自己有多完美。)

才是评价一个程序员的重点,但这不是一纸简历就能体现出来的。我在 GitHub 或 CPAN 上的代码只占我工作成果的一小部分,光看这些代码也回答不了这个根本问题。你在代码里肯定也看不出我犯过的错误(假如我确实犯过的话)。代码也不会显示我在提交之前被 git squash 抹去的纠结过程(也许纠结过,也许没有)。假如有 1400 来行代码是我一个下午一口气堆出来,再修改过一次就编译成功,然后这段代码运行顺利,也不需要再改,我也再就没去动过。这样的故事你从代码里也看不出来。

如果你让我在白板上写个排序算法,这最多只能考察到“这个人到底有没有一丁点的编程知识”的程度,再多的你也考不出来。然而在程序员面试时,这依然是个常见环节。

光看一张简历,你根本看不出我是那种不满足于按照既有计划来堆砌代码的人,即使这个计划仅仅是架构师制定的、项目经理透露给销售主管的、销售主管要求企业销售代表承诺给客户的新版必然会有的东西。(这种工作环境能窝囊死人)从简历上一两页的文字,你根本看不出我为了写出最完美的医疗保险帐务代码能付出多少热情,看不出这份热情能否转化成最终的用户体验,哪怕用户根本感受不到我们在代码上线之前就剔除了多少 bug 和设计缺陷。

虽然我的简历上写着 PerlRubyPostgreSQL 这些关键字,但你读过之后还是不会了解我的这些特质。甚至读代码也读不出。虽然这是你招人时要冒的风险,但相比之下,这个问题的分量不亚于“你觉得自己能融入我们的团队吗?”,更不亚于“看你作为一个专业程序员,对开发工具与自动化还挺重视的,也有挺多年的 Vim 使用经验。那你能在白板上手写代码吗?”

但哪有写 Perl 的工作?

我不觉得自己是个独一无二的存在。程序员并不是轻易可以替换的,但世界上也没那么多编程问题需要找屈指可数的顶尖专家来解决。(虽然我修的学位是音乐方向,而不是斯坦福、伯克利、MIT、CMU 的“计算机科学”,导致我再无缘涉足计算机视觉,AI 研究,编译器设计领域。然而就因为这个音乐学位的事,Google 的面试官就觉得我能在几周间回答乒乓球问题,还要设计什么电话本排序算法,都应该心存感激。就为了能有一份在数据中心里的工作,给他们的广告服务器端茶倒水而已。

很明显,如果我还想继续写代码,我更愿意使用自己熟悉和喜欢的语言。我相信盲目追逐流行技术对公司和程序员都有害处,但这种趋势一时也改不了。

照我看来,有这么几种方法能让你找到写 Perl 的工作:

大概十四、五年前,甚至到十年前,我可能还指责过这个残酷冷漠的技术圈的赶时髦,重视宣传造势而非技术优越性,是多么不公平。但我自己也不是没追过时髦。我在考虑自己职业生涯的转折点时,(当时我问自己“是不是该去考个 CS 学位?”,“考个财经学位,再办个行业法务咨询公司,是不是来钱更快?” —— 这个真不是我瞎编的,几年前我甚至还想去盘一家面包房,但 Robert Buels 几分钟就把我劝住了。)想到了下面这个质问技术流行趋势的大问题:

什么技术能免于过气

除了 COBOL,再除了 MUMPS,无一幸免。

我愿意这辈子一直写 COBOL 或者 MUMPS 吗?或者就写一下午呢?不要。

这么说吧。我是个一般意义上的程序员。我能够解决问题。我带过团队,也当过螺丝钉。我写过文档,写过测试。有时候我删掉的代码比新写的都多,但这种时候我更开心。有时我为客户解决问题的方案是写代码。有时我在调试分析报告里折腾好几天,最后给数据库一个列加上缓存就万事大吉。但只要最终找到了解决方案,之前为了钻研的努力就都值了。

我在技术选型上确实有个人偏好。我也有积累下来的工作经验。你想招一名程序员,你就得承认他/她的偏好,经验,乃至偏见。

也许是我太挑剔。也许事业进入中年危机,并承认“在网上跟人吵哪种语法好太浪费时间了,我还不如去遛个狗,陪上小学的侄子玩玩,或者跟朋友们开暖房趴去”是个自然过程。也许变得犬儒也未尝不可,并且认为“我毕竟是专业人士,哪怕我对管理临床研究记录没半点兴趣,只要你给钱给够了,我就能把自己难得的判断力与知识、经验贡献出来,为你高效可靠地解决问题。”但我肯定不会再在下班之后还惦记着代码。

要不,我当年就该把那家面包房盘下来。虽说那么一来,我就得招几个靠谱的人干活,分一大块利润给他们开工资,还得每天早上四点起床,还得应付卫生督查员,还得关注土地用途分区,还得紧盯奶制品市场价……

……但我至少不用应付着风投一边给我少开工资,一边用轮轮被稀释的受限股份提醒着我有百分之一的可能会被人才收购,然而被收购之后到手的钱比全程拿标准薪水也高不到哪去。也不用应付陪客户做异想天开项目,但人家一小时只愿意给 $20。这还是因为找我能用英语沟通,要不然人家就找阿尔巴尼亚的高中生去了,那边一小时只要 $8。也不用应付那种 HR:他们一看简历上有 “Perl” 这个关键字,就默认我肯定还是 1998 年的那个入门级 SA,或者是从 1999 年时间穿越过来的。今年电脑都联因特网儿了知道不啊,呵呵。JS 都成正经语言了,要不你先来看看我们春季新品发布会吧?

根本问题

如果你因为生活上要担着责任,没法变卖全部家当,去泰国或者伯利兹城的海滩上住上一年,那么对于已经步入中年的事业,你自己是怎么看的?你是如何维持编程的新鲜感的?你是如何把自己标榜成有能力解决问题的人,而不是仅仅把想法翻译成时髦编程语言的人?抑或你已经彻底告别了编程?

这些问题我也给不出答案。但至少,十六年的工作经验让我终于有能力问得出来。