2002年1月6日,星期天

有时候,我什么也干不下去。

当然了,我还是会去上班,走进办公室,到处看看,隔不了几秒钟就查收下邮件,看看网站,甚至还干点不怎么费脑子的活儿,譬如付付信用卡账单什么的。但就是找不到写代码的状态。

Tetris

这种“不务正业”综合症常常会持续一两天。不过,在我的程序员职业生涯中,确实出现过很多次连续几周都无所事事的情况。就像他们说的那样,我不在状态,不专心。我不知道自己在干什么。

每个人都有情绪波动的时候,但有些人波动小,有些人很明显,甚至很病态。而没心思干活好像确实跟情绪低落有关。

这让我想起来那些研究人员说的,人本质上不能控制自己吃什么,因此节食减肥注定不是长久之计,最终肯定会晃晃悠悠地恢复成自然体重。也许,作为一名软件开发人员,我其实也不可能控制自己什么时候工作效率高。我只能接受工作效率时高时低的现实,寄希望于快慢相抵,也能写出足够多的代码而让自己不至于失业。

Go read the onion for a while

让我感到兴奋的是,自从进入职场的那一刻起,我就知道,身为一名程序员,平均一天下来,有效编码时间通常只有两三个小时。当初我在微软暑期实习的时候,有个实习生告诉我,他每天只有12点到5点这段时间干活儿。5个小时,还包括午餐时间,但他所在的团队却很喜欢他,因为他完成的工作量还是大大超过一般人。我发现自己也是如此。每当看见大家都在那努力工作,而自己一天只努力干两三个小时,自己心里就会感到一丝不安,可我却一直是团队中效率最高的成员之一。恐怕这正是《人件》1和XP(eXtreame Programming,极限编程)理论都强调不要加班,每周只工作40小时的原因,他们非常清楚这么做并不会降低团队效率。

1.

一天“只”干两个小时的活儿不是问题,什么都不干才是问题。

我反复想过这个问题。我想起了自己职业生涯中产出最丰硕的那段日子。那时候,微软让我搬到了一间漂亮、豪华的新办公室,透过大落地窗可以俯瞰美丽的石砌天井,天井里满是鲜花盛开的樱桃树。所有事情都有条不紊地进行着。一连几个月,我马不停蹄地编写Excel Basic的详细设计规范,堆积如山的稿纸巨细靡遗地涵盖了庞大对象模型和复杂编程环境的方方面面。毫不夸张地说,我从头到尾就没歇息过。即使去波士顿参加MacWorld大会,我也随身带着笔记本,坐在哈佛商学院怡人的游廊中,继续编写Window类的相关文档。

一旦进入状态,坚持下去就不难了。我的一天往往是这样过来的:

  1. 打卡上班;
  2. 收收邮件,上上网,……
  3. 决定最好在开工之前先解决午饭问题;
  4. 吃完午饭,回到办公室;
  5. 收收邮件,上上网,……
  6. 终于决定,我得马上开始工作了;
  7. 收收邮件,上上网,……
  8. 再次下决心,这次真的必须开工了;
  9. 启动那该死的编辑器;
  10. 不停地写代码,写着写着才发现已经晚上7:30了。

bike trip

在第8步和第9步之间,好像有个地方有bug,因为我并不是每次都能顺利地跨越那道鸿沟。对我而言,“唯一的”难题就是开始工作。静止的物体有保持静止的惯性。我脑子里好像有个异常沉重的东西,给它一个初速度很难,可它一旦全速前进起来,再维持其运动就不费吹灰之力了。这就像全副武装自助骑行全国的背包客2,刚跨上满是装备的自行车,不知道得费多大劲才能蹬转它,可一旦转起来,就好像根本没有负重一样轻松了。

2.

或许高效的秘诀就是马上开始!如果说结对编程行之有效,那原因就在于你和搭档一旦说好结对编程,两个人必须马上开始。

![Joel in the army][4]

还在以色列当伞兵的时候,有位将军顺道给我们上了一堂简短的战术课。他告诉我们,步兵作战只有一个战术:边打边跑。手里的武器不要停止射击,同时跑步冲向敌人。持续的火力压住敌人不敢抬头,他们就不可能还击。(战士冲锋时大喊“掩护我”,也是这个意思。那相当于说:“用火力压制敌人,在我跑过街道时,别让他们抬头朝我开枪。”这招确实管用。)跑步冲锋能让我们攻城掠地,并且更接近敌人,也就更容易击中目标。如果你不跑,敌人就会有余裕审时度势,那就不妙了。如果不开火,敌人就会反过来打你,把你干翻在地。

这段话深深地刻在我的脑海里。我发现,几乎所有的军事战术都植根于“边打边跑”的理念,从空军遭遇战到大规模海军演习,都不例外。15年后,我才认识到“边打边跑”也是高效工作的至理名言。你每天都必须前进,哪怕只前进一点点。至于你的软件写得好不好、bug多不多,甚至有没有人要,都没有关系。只要你向前冲,坚持不懈地写代码、捉虫子,时间就会站在我们这一边。同时当心你的竞争对手朝你射击。他们是不是就想逼迫你疲于应对他们射出的弹雨,从而让你止步不前呢?

想想微软捣鼓出来的那些数据存取策略吧。ODBC、RDO、DAO、ADO、OLEDB,现在又是ADO.NET,全都是新名词!这些东西从技术层面上看,真的都有必要么?还是说微软的设计团队太无能了,无能到每他妈12个月就得重新发明一次“数据存取”这只轮子?(事实有可能就是这样。)但最终结果则是“火力压制”。竞争对手别无选择,只能亦步亦趋,时间全都浪费在移植、更新上,却没有时间实现自己的新功能。仔细看看软件业的局势吧。那些干得好的公司都极少依赖大公司,他们不需要整天算计着如何保持技术先进性、如何推倒重来、如何修补那些只有在Windows XP中才会孳生的程序错误。那些步履维艰的公司则把太多的时间浪费在了通过茶叶问卜微软的未来动向上。这些人听到.NET就心急,就决定用.NET重写整个架构,在他们看来这是必须的。岂不知,微软是想干掉你,而这些火力就是为了压制你,好让他们向前冲,而你却寸步难行。游戏规则就是这样,哥们儿!你打算支持HailStorm3?SOAP4?RDF5?是因为客户需要它吗?还是因为有人想攻击你,而你觉得自己必须应战?大公司的销售人员非常了解“火力压制”。他们一拜访客户就会说:“好吧,您可以不从我们这里买。去找最好的供货商买吧。但一定要保证您买的产品支持XML/SOAP/CDE/J2EE/……否则您会被捆住手脚6。”然后,小公司再找这个客户推销时,只会听到他们的CTO鹦鹉学舌般地问:“你们支持J2EE吗?”于是这些小公司不得不把全部的时间都浪费在支持J2EE平台上,尽管完事儿后照样卖不动,照样毫无特色可言。这些功能仅仅是做给人看的,就像得有个复选框,打上勾就表示我们有,可谁会用,谁又需要它呢?这就叫“火力压制”。

3.
4.
5.
6.

对于我的这家小公司来说,“边打边跑”战术意味着两件事:第一,必须争取时间7;第二,必须每天都要向前冲。那么胜利就是迟早的事。我昨天的工作就是让FogBUGZ的配色方案好看了一点儿,这就挺好啊,它每天都在变好。我们的软件每天都在变好,我们的客户也越来越多,这才是我们关心的!在达到Oracle那样的规模之前,我们不用操心那些宏大的战略。我们只要每天早上到公司来,想办法启动那个编辑器就好了!

7.

[4]: http://www.joelonsoftware.com/pictures/ARMY-wee.JPG 第15篇 边打边跑