10 types of programmers you’ll encounter in the field

10 types of programmers you’ll encounter in the field
by Justin James

Programmers enjoy a reputation for being peculiar people. In fact, even within the development community, there are certain programmer archetypes that other programmers find strange. Here are 10 types of programmers you are likely to run across.

#1: Gandalf
This programmer type looks like a short-list candidate to play Gandalf in The Lord of the Rings. He (or even she!) has a beard halfway to his knees, a goofy looking hat, and may wear a cape or a cloak in the winter. Luckily for the team, this person is just as adept at working magic as Gandalf. Unluckily for the team, they will need to endure hours of stories from Gandalf about how he or she to walk uphill both ways in the snow to drop off the punch cards at the computer room. The Gandalf type is your heaviest hitter, but you try to leave them in the rear and call them up only in times of desperation.

#2: The Martyr
In any other profession, The Martyr is simply a “workaholic.” But in the development field, The Martyr goes beyond that and into another dimension. Workaholics at least go home to shower and sleep. The Martyr takes pride in sleeping at the desk amidst empty pizza boxes. The problem is, no one ever asked The Martyr to work like this. And he or she tries to guilt-trip the rest of the team with phrases like, “Yeah, go home and enjoy dinner. I’ll finish up the next three week’s worth of code tonight.”

#3: Fanboy
Watch out for Fanboy. If he or she corners you, you’re in for a three-hour lecture about the superiority of Dragonball Z compared to Gundam Wing, or why the Playstation 3 is better than the XB 360. Fanboy’s workspace is filled with posters, action figures, and other knick-knacks related to some obsession, most likely imported from Japan. Not only are Fanboys obnoxious to deal with, they often put so much time into the obsession (both in and out of the office) that they have no clue when it comes to doing what they were hired to do.

#4: Vince Neil
This 40-something is a throwback to 1984 in all of the wrong ways. Sporting big hair, ripped stonewashed jeans, and a bandana here or there, Vince sits in the office humming Bon Jovi and Def Leppard tunes throughout the workday. This would not be so bad if “Pour Some Sugar on Me” was not so darned infectious.

Vince is generally a fun person to work with, and actually has a ton of experience, but just never grew up. But Vince becomes a hassle when he or she tries living the rock ‘n roll lifestyle to go with the hair and hi-tops. It’s fairly hard to work with someone who carries a hangover to work every day.

#5: The Ninja
The Ninja is your team’s MVP, and no one knows it. Like the legendary assassins, you do not know that The Ninja is even in the building or working, but you discover the evidence in the morning. You fire up the source control system and see that at 4 AM, The Ninja checked in code that addresses the problem you planned to spend all week working on, and you did not even know that The Ninja was aware of the project! See, while you were in Yet Another Meeting, The Ninja was working.

Ninjas are so stealthy, you might not even know their name, but you know that every project they’re on seems to go much more smoothly. Tread carefully, though. The Ninja is a lone warrior; don’t try to force him or her to work with rank and file.

#6: The Theoretician
The Theoretician knows everything there is to know about programming. He or she can spend four hours lecturing about the history of an obscure programming language or providing a proof of how the code you wrote is less than perfectly optimal and may take an extra three nanoseconds to run. The problem is, The Theoretician does not know a thing about software development. When The Theoretician writes code, it is so “elegant” that mere mortals cannot make sense of it. His or her favorite technique is recursion, and every block of code is tweaked to the max, at the expense of timelines and readability.

The Theoretician is also easily distracted. A simple task that should take an hour takes Theoreticians three months, since they decide that the existing tools are not sufficient and they must build new tools to build new libraries to build a whole new system that meets their high standards. The Theoretician can be turned into one of your best players, if you can get him or her to play within the boundaries of the project itself and stop spending time working on The Ultimate Sorting Algorithm.

#7: The Code Cowboy
The Code Cowboy is a force of nature that cannot be stopped. He or she is almost always a great programmer and can do work two or three times faster than anyone else. The problem is, at least half of that speed comes by cutting corners. The Code Cowboy feels that checking code into source control takes too long, storing configuration data outside of the code itself takes too long, communicating with anyone else takes too long… you get the idea.

The Code Cowboy’s code is a spaghetti code mess, because he or she was working so quickly that the needed refactoring never happened. Chances are, seven pages’ worth of core functionality looks like the “don’t do this” example of a programming textbook, but it magically works. The Code Cowboy definitely does not play well with others. And if you put two Code Cowboys on the same project, it is guaranteed to fail, as they trample on each other’s changes and shoot each other in the foot.

Put a Code Cowboy on a project where hitting the deadline is more important than doing it right, and the code will be done just before deadline every time. The Code Cowboy is really just a loud, boisterous version of The Ninja. While The Ninja executes with surgical precision, The Code Cowboy is a raging bull and will gore anything that gets in the way.

#8: The Paratrooper
You know those movies where a sole commando is air-dropped deep behind enemy lines and comes out with the secret battle plans? That person in a software development shop is The Paratrooper. The Paratrooper is the last resort programmer you send in to save a dying project. Paratroopers lack the patience to work on a long-term assignment, but their best asset is an uncanny ability to learn an unfamiliar codebase and work within it. Other programmers might take weeks or months to learn enough about a project to effectively work on it; The Paratrooper takes hours or days. Paratroopers might not learn enough to work on the core of the code, but the lack of ramp-up time means that they can succeed where an entire team might fail.

#9: Mediocre Man
“Good enough” is the best you will ever get from Mediocre Man. Don’t let the name fool you; there are female varieties of Mediocre Man too. And he or she always takes longer to produce worse code than anyone else on the team. “Slow and steady barely finishes the race” could describe Mediocre Man’s projects. But Mediocre Man is always just “good enough” to remain employed.

When you interview this type, they can tell you a lot about the projects they’ve been involved with but not much about their actual involvement. Filtering out the Mediocre Man type is fairly easy: Ask for actual details of the work they’ve done, and they suddenly get a case of amnesia. Let them into your organization, though, and it might take years to get rid of them.

#10: The Evangelist
No matter what kind of environment you have, The Evangelist insists that it can be improved by throwing away all of your tools and processes and replacing them with something else. The Evangelist is actually the opposite of The Theoretician. The Evangelist is outspoken, knows an awful lot about software development, but performs very little actual programming.



作者: Justin James
译者: 来自网络,抱歉没查到准确出处




小心玩家。如果他或者是她注意到了你,你很有可能就要接受3至4个小时关于龙珠z与高达谁更强、或者是playstation 3 与xbox 360哪个更好的演讲。玩家的桌子上总是堆满了明信片、动作人偶、以及其他各种各样相关的装饰品,大部分可能都是从日本进口的。玩家们不光是很难相处,他们有的时候实在是太多时间在这些东西上(无论是在办公室内外),以至于他们根本就不明白他们什么时候该干老板雇他们做的工作。

#4:文斯 内尔(一个比较有名的摇滚歌手)
这个40岁的家伙就像是颠三倒四的回到了1984.运动型爆炸头,发皱泛白的牛仔裤,还有一条大围巾。文斯还会在工作时间坐在办公室哼着Bon Jovi 和 Def Leppard的歌,这本来也不是很糟,如果《Pour Some Sugar on Me》不是如此的有感染力的话。














Stiff 对九位卓越程序员的采访

Stiff 对九位卓越程序员的采访

前言:2006 年,波兰程序员Jaroslaw “sztywny” Rzeszótko (亦称 Stiff)写了一篇文章《Stiff asks, great programmers answer》,不过原英文链接已挂。Dodgy Coder 的博主近期从 Stiff 那得到允许,把文章转发布在他的博客中《Q&A With Nine Great Programmers》。以下为全文:

在一个炎热无聊的下午, 我突发奇想。 我通过公众可以取得的电子邮件地址列表, 向一干牛人们提了 10 个问题, 他们都是我认为很有趣, 而且很佩服的人, 都干了很多大事。 我只用了 5 分钟来准备这些问题 — 这些问题是我打算私底下如果有机会和牛人们说话, 就说谈个 10 分钟吧, 就会问到的, 那时候我也不会有时间去想那么多。 最后的两个问题其实跟编程无关, 只是我碰到谁都会问他的, 算是我个人的爱好好了。 不是人人都想回答这些问题, 没有关系。 这是我第一次”采访”别人, 难免犯了一些小错, 当别人开始回答问题时, 我自己却跑开了…… 但先别管这个, 我从这些东东里学到很多东西, 这绝对是一次价值非凡的体验。

不是每个人都答复了我的邮件, 也不是所有的人都想回答这些问题的, 可能以后我还会收到, 但我实在等不及了, 现在发表的这些可能随时都会更新的哦。(更新:Bjarne Stroustrup 的回复内容于 03.08.2006 补上 —— Jaroslaw)

●Linus Torvalds :Linux kernel作者。
●Dave Thomas:《Pragmatic Programmer | 程序员修炼之道》和《Programming Ruby》和其他优秀书籍的作者。 你可以到这里来了解他的编程思想。
●David Heinemeier Hansson:写了 Rails Framework- 新鲜热辣的 web 开发框架。他的博客在这里。
●Steve Yegge:可能是最不为人所知的, 但也是回答得最有趣的一个, 他的博客很有名, 也是关于编程的。 他也是游戏 “Wyvern” 的作者。
●Peter Norvig:Google 的研究部主管, 著名的 Lisper, 写过很著名的 (至少在某些圈子里) AI 方面的书。 他的博客。
●Guido Van Rossum:Python发明者。
●Bjarne Stroustrup:C++ 之父,个人主页。
●James Gosling:Java 之父。(个人博客)
●Tim Bray:XML 与 Atom 规范缔造者之一,他的博客。


1. 您如何学的编程? 上过什么学校? 有用吗? 还是您根本就不鸟学校的事 :) ?

Steve Yegge:

我自己在一台 HP 计算器上开始编程的, 用他们的 RPN 堆栈语言, 当时 17 岁。 之前也学过几次编程, 但都没有真正去学。 HP 的 28c 和 48g 科学计算器性能强劲, 文档也齐全。 我在 48g 上写了一个 3D 线框查看器 — 我有一本 3D 图形编程的书, Pascal 的, 花了好大力气把书里的例程转成 RPN 堆栈语言。 最后它成功运行了, 真是甜蜜的回忆。 之后我就买了一台 PC 还有 Turbo Pascal, 努力地学习编程。 当我去大学读 CS 时我已经是个象模象样的程序员了。 (注意: CS 不是 Counter-Strike)

后来我去了 University of Washington 并在那里得到 CS 学位。 这是绝对值得努力的, 我建议所有的程序员在条件允许的情况下都要尽力攻读 CS 学位。

Linus Torvalds:

我没在学校里学编程, 大部分是我自己看书然后就动手干了起来(一开始在 Commodore VIC-20 上, 后来在 Sinclair QL 上)。

这么说吧, 我尤其认为大学是非常有用的。 我没有选择上技工学校, 而是上了 Helsinki University, 那里偏重理论, 所以那里的教学并不集中在编程上面(编程只是一小部份, 总之我算是很”不务正业”的), 大部分课程集中在基本概念和诸如复杂度分析上面。

那些东西看起来很闷甚至是在浪费精神, 但我认为很有用, 我非常喜欢它们。 我认为我可能是那方面会做的更好。

David Heinemeier Hansson:

我从建立自己的个人主页开始学习编程。 后来我又想增加一些动态的内容, 就先学了 ASP 再后来学了 PHP。 当我知道怎样编程以后, 我就去攻读一个计算机科学与工商管理的交叉学位。

Peter Norvig:

我在高中和大学里都学过编程, 但总觉得自己是自学的多。

Dave Thomas:

读中学时我在当地一间专科学院上过电脑课。 我整个儿被迷住了: 我爱上了编程, 并四处找开设有软件课程的学校。 后来我上了 Imperial College, London University 的分部。 当时他们才刚开设软件课程第二年, 说起来很难相信: 教职员工和和学生们一起工作, 把那些东西弄好, 大家从中都获益匪浅。 在那里读的本科课程给我打下了强大的软件开发基础。 我本想呆到博士毕业, 但还没等到开始读博士就被人挖走了。

但是问题的重点是”你怎样学的编程?” 真正的答案是”我还在学编程。” 我想优秀的开发者整个生涯都不断在学习。 这可不仅是学习新语言和新库的问题: 优秀的开发者经年不断的磨练自己的技术, 提升自己的体验。

Guido Van Rossum:

我上了大学, 那里有一台大型主机, 很多计算机课程。 这(上学校)很重要。

James Gosling:

最初我是自学的。 上大学之前我就得到第一份编程工作了。 但我很高兴我上了(大学)。 其乐无穷。 我一直读到拿到了博士学位。

Bjarne Stroustrup:

现在?Aarhus ,后去了剑桥大学。学校教给我很多实用的东西,包括我未来工作中用到的基础。此外,我也从为钱而编程中学到东东,理解了现实世界中的问题,正确性、可维护性、实时交付等等。

Tim Bray:

我原来想当数学教师来着。 数学教学大纲里要求学生研修几门计算机课程。 (结果就糊里糊涂成了计算机科学家?)

2. 您认为程序员最应该拥有什么样的技能?

Steve Yegge:

笔头和口头沟通的技能。 除非你事先把自己的意见清楚地传达给每一个人, 否则当程序员们开始工作时, 你说什么他们都听不见。 程序员应该不倦阅读, 赋诸文字, 上写作课, 甚至学会公开演讲。

Linus Torvalds:


我向来不以”有多专业”为标准来评价与我共事的人: 有的人很会写代码, 一下就能弄出一大坨, 但他们给别人代码造成的影响则还要大坨, 而这显然是由他们自己的代码风格, 和他们选择的解决方法所造成的。 这就能告诉我他们有没有”品味”, 而真相就是, 没”品味”的人通常也不太好让他去判断别人代码的好坏, 而他自己的代码到最后也不会是十分的好。

但是, 还有。 有一件事非常重要, 特别是在开源的项目里, 那就是沟通好你想干什么, 怎么干的能力。 向别人解释清楚你为什么非要用某种方式干某些事情的能力十分重要, 并非人人有这个能力。

这么说吧, 到最后也会有人搞出好的代码来。 他们可能解释能力不行, 也没什么品味, 但是代码是可以正常工作的。 这是你往往会需要另一个人(一个”品味”特殊的人)去整理那些代码, 使它的适用范围更广, 而仅仅是写出干净的代码, 解决难题不过是作为程序员必需有的最基本的能力而已。

David Heinemeier Hansson:

强烈的价值观。 有能力问自己: 我做的事情有价值吗? 太多太多的程序员把太多太多的精力浪费在无关痛痒的事情上面。 却忽略了那些真正重要的事情。

Peter Norvig:

我觉得没有, 专注算是吧。

Dave Thomas:


Guido Van Rossum:

你的问题问得太泛, 无法回答。 :-) 我想有能力煮个鸡蛋当早餐就是无价。

James Gosling:

会自我鞭策。 想真正做得好, 你得热爱你所做的东西。

Bjarne Stroustrup


Tim Bray:

以事实为依据, 不跟着感觉走。

3. 您觉得数学和物理对程序员重要吗? 为什么?

Steve Yegge:

数学上有一个分支对程序员非常重要, 它叫”离散数学”或”具体数学”。 包括概率学, 组合学, 图论, 归纳证明和其它有用的东西。 我会鼓励所有程序员去学离散数学, 无论他们能学多少。 即使一点点也比完全不会强。

至于传统数学, 我倒不常用到, 但当我需要用到它就会很方便。 举例来说, 之前我只在工作中用到过一次微积分。 我必需为某个服务从象正弦波那样的曲线图中计算出每日交通高峰期负载。 最简单的方法就是求出特定时间内 1/24 曲线的积分。 如果我不懂微积分, 我就做不出合理正确的估算。

在我写 Wyvern 游戏的时候, 我扎实的平面几何知识作用极大。 日常基本工作中用得更多的是代数和线性代数。 但是很少用到三角学和微分方程, 微积分也很少用。

我会说我的数学基础带给我 5% 至 10% 的进步。 如果我懂的更多, 毫无疑问我会变得更好, 所以每个星期我都抽出几个钟头来学习数学。

我喜欢物理, 毕生都在探索尝试掌握量子力学的基本结构。 但我没觉得物理对我作为一个程序员的工作有任何帮助。 当然了, 如果我在物理领域工作, 象 3D 游戏编程, 或某种类型的模拟, 那就不同了。

Linus Torvalds:

我个人认为扎实的数学基础是好事情。 我不大清楚物理会如何, 但我深信懂数学, 有良好的数学基础有助于使你成为更好的程序员。 如果只是因为它们的思维模式相近似 — 你可以建立起自己想要的法则, 但它必须和自我一致。

David Heinemeier Hansson:

一点用都没有。 至少在商业目的的 web 编程上。 我考虑一个人的笔头功夫好会比这重要的多。

Peter Norvig:

是的, 电脑的很多方面来自数学: 归纳, 递归, 逻辑等。

Dave Thomas:

也许吧。 但是老实说, 我没见到他们之间有多大的关联。

然而, 我的的确确发现一个人的音乐才华与他的编程技能有很大的关联。 我也不知道为什么, 我怀疑大脑的某个区域在提升你音乐才能的同时也会提升你的软件开发技巧。

Guido Van Rossum:

数学, 是的(是一部分; 我不管微分方程, 但是代数和逻辑就很重要)。 物理嘛, 我认为没有, 但保持对不同事物的兴趣是一件好事。

James Gosling:

是的! 它们教会你逻辑和推理。。。 。 拥有火眼金睛。 在分析算法时数学无物可替。

Bjarne Stroustrup:


Tim Bray:

就我个人来说, 我几乎从没用过我大学学到的数学知识。

4. 您认为计算机编程的下一个热点是什么? 面向 X 编程, y 语言, 量子计算机, 还是?

Steve Yegge:

我认为 web 应用正逐渐在变成最重要的客户端形式。 它将会逐步淘汰其它的客户端技术: GTK, Java Swing/SWT, Qt, 当然还有 Cocoa 和 Win32/MFC/等那些依赖平台的技术。

这不会在一夜之间发生。 它会在今后十年里慢慢地朝那个方向前进, 可能到 web 应用完全”取得胜利”之前还需要另一个十年。 工具, 语言, API, 协议, 浏览器技术的发展会远远超过今天你所用到的。 这个差距每年都在缩小, 而我则决定从现在起把我所有的开发工作转移到浏览器上来。

Microsoft 和 Apple 当然不愿意看到这些了, 所以至关重要的第一步就是要使一个象 Firefox 那样的开源浏览器取得统治性的市场份额, 然后还需要一些 Firefox-only 的杀手级应用。 (杀手级应用会象 iTunes, 人人都想用它, 会为了它去下载 Firefox。)

Linus Torvalds:

我不认为会有什么”巨大的飞跃”。 我们已经看到很多可以帮助我们减轻日常工作压力的工具 — 高阶语言或者把简单数据库集成到语言里面可能会是主要的一个。 但大部分喋喋不休基本上没起什么作用。

举例来说, 我个人相信 “Visual Basic” 比”面向对象语言”作用更大。 虽然人们嘲笑 VB, 说它是烂语言, 而他们谈论 OO 语言谈了几十年。

是的, VB 不是很好的语言, 但是我认为象 VB 集成的简单 DB 接口基本上比面向对象重要得多。

所以我想会有很多逐步的改进, 硬件性能的提升也会有助于编程, 但我不指望有什么东西会使生产力大幅度提升或者出现什么革命。

至少当真正的 AI 出现时, 我不认为真正的 AI 还需要你去搞什么编程。

David Heinemeier Hansson:

我尽量不去预言未来。 也不怎么相信运气。 预见未来的最好方法就是实现它。

Peter Norvig:


Dave Thomas:

电脑编程的下一个热点会被下下一个热点吞掉, 周而复始。 我对不停地寻找热点有点反感, 因为当这样会使人们忘记真正的重点: 打好基础。 我们必需更好地和我们的客户交流, 关注所提供的价值, 并为此而自豪。 做到了这些那开发者就能提供更好的软件更好的工具, 而不需要去担心自己是否跟得上潮流。

Guido Van Rossum:

Sorry, 我对水晶球不敏感。 我曾经在 CGI 发明的 5 年后预言了它。 :-)

James Gosling:


Bjarne Stroustrup:


Tim Bray:


5. 如果您有三个月去学一门新技术, 您会选什么?

Steve Yegge:

我刚好有 3 个月时间(作兼职), 我正在学 Dojo (http://dojotoolkit。org ) 和高级 AJAX 和DHTML。 我在做一个巨 NB 的 web 应用, 边做边学。 Dojo 真的很酷, 它也一定会与时俱进。

Linus Torvalds:

唔,我真的很喜欢 FPGA 的, 就是一直没有时间坐下来好好地学。 我喜欢直接和硬件对话的感觉: 这说明我为什么最后选择了做 OS, 因为那样(和编译器呆在一起)和硬件的距离最近, 就差你不能亲自去设计和制造它了。

David Heinemeier Hansson:

Mac 上的 Cocoa 编程。

Peter Norvig:

我想多学一点 Javascript。 还有 Flash。

Dave Thomas:

如果”新”指的是 Dave Thomas 的新, 我想去上高强度的钢琴课。

如果”新”指那些技术玩意, 我会选择可帮助残疾人的相关技术。

Guido Van Rossum:


James Gosling:

为了乐趣, 我想学最新的 3D 渲染技术。 我可能会写一个照片-地图渲染器。

Bjarne Stroustrup


Tim Bray:

安全, 加密, 数字签名, 身份验证等。 麻烦的是这些东东我从来没学过。

6. 您认为是什么使得有的程序员比别人高效 10 倍甚至 100 倍?

Steve Yegge:

我想如果你停下来想一下为什么运动员不是都一样好的话, 你就会知道答案的。 爱迪生关于天才的那段话也会给你启示。

Linus Torvalds:

我真的不知道。 我想有些人就是能够更好地把精力集中在那些有用的事情上, 我想他们天生就是会这样。 我认识的很多程序员从小就这样。

David Heinemeier Hansson:


Peter Norvig:


Dave Thomas:


Guido Van Rossum:


James Gosling:

他们深思熟虑。 他们不会仓促行事, 七拼八凑。 他们对结果胸有成竹。

Bjarne Stroustrup:


Tim Bray:


7. 您最喜爱的工具(操作系统, 编程/脚本语言, 编辑器, 版本控制系统, shell, 数据库引擎, 其它您赖以生存的工具)以及您喜欢它们的理由?

Steve Yegge:
操作系统: Unix! 我用 Linux, cygwin, 现在也用经常用 darwin。 它是无法代替的生产工具。 每个程序员必须学会用 /bin 和 /usr/bin 目录里的所有工具。

脚本语言: Ruby。 我精通所有主流脚本语言: Perl, Python, Tcl, Lua, Awk, Bash, 还有一些已经忘了。 但我是个懒人, 而 Ruby 是目前为止最轻松的, 这是天堂里才有的比赛。

编程语言: 没有我最喜爱的; 它们都不好。 我会选择 Java, 因为它强壮, 可移植, 有好工具和库。 但 Java 不进化就得死; 照现在的样子它不足以长期掌握领导地位。

编辑器: Emacs, 因为当前没用比它更好的。

版本控制: SVN。 Perforce 更好, 但很贵。

Shell: Bash, 因为我实在懒得去学其它的。

数据库引擎: 当然是 MySQL, 没有更合适的了。

其它: 我发现 GIMP 无法评价, 它的不直观也令人抓狂。 我用它多年却总是干不成什么。 但我又离不开它, 真是讽刺。

Firefox 是我工具库阵容中日益重要的一员。 当不得已去用 IE 或 Safari 时我会觉得自己就快死了。

注意这些工具(Unix, Emacs, Firefox, GIMP, MySQL, Bash, SVN, Perforce)都有一个共同点: 它们可以扩展; 也就是, 它们都有 API 可以编程。 优秀的程序员懂得如何给它们的工具编程, 而不仅是用它们。

Linus Torvalds:

实际上我没用那么多工具, 我花了些时间写了我自己的工具。 操作系统这块最大, 还有我自己的版本控制系统(Git), 我用的编辑器(micro-emacs)也是经过我定制和扩展的。

除了那三块, 我最关心的是邮件阅读器。 我一直用 Pine — 不是因为它最好, 而是因为我习惯了, 它也提供了我所需要的一切而且没什么毛病。

David Heinemeier Hansson:

OS X, TextMate, Ruby, Subversion, MySQL。 这就是我当前的组合。 我喜欢那些漂亮而且专注于自己职责的那些工具。

Peter Norvig:

不喜欢全部主流的 OS – Windows, Mac, Linux。 喜欢 Python, Lisp 和 Emacs。

Dave Thomas:

用了 Linux 10 年, 几年前改用 Macs 了。 工具不需要好到特别好, 但不能是需要经常去维护的, 而必须是能让人用的。

我不会永远只用一种工具: 我经常尽可能地切换不同的工具以获得更好的体验。 目前我用的是 OSX, Emacs, TextMate, Rails, Ruby, SVN, CVS, Rake, make, xsltproc, TeX, MySQL, Postgres, 还有一大堆小工具。 谁知道明年我会用什么。

Guido Van Rossum:

Unix/Linux, Python, vi+emacs, Firefox。

James Gosling:

这些天来我住在 NetBeans 里面。 他帮我做了我想要的一切, 非常清晰直接和有效。 这是我住过的最舒服的环境。

Bjarne Stroustrup:

Unix、sam(一个极简的文本编辑器),当然还得有一个出色的 C++ 编译器。

Tim Bray:

我喜欢类 Unix 操作系统, 象 Python 和 Ruby 那样的动态语言跟象 Java 那种静态类型语言(特别是 Java 的 API), Emacs, 随便, bash, 随便, NetBeans。

8. 您最喜爱的电脑编程方面的书是哪一本?

Steve Yegge:

老兄, 这问题真要命。 也许是 GEB(《哥德尔、艾舍尔、巴赫书:集异璧之大成》) 吧, 虽然这本书不是严格的编程类书籍。 如果你特指”最喜爱的编程书”, 那也许就是 SICP (mitpress。mit。edu/* sicp*/) 了。

Linus Torvalds:

呃。 我最近喜欢读幻想小说, 或非电脑类的书(旧书一本: Richard Dawkins 的 “The Selfish Gene”)

说到编程方面, 跃然脑海的唯一真正编程书就是 Kernighan 和 Ritchie 经典的 “The C Programming Language”, 因为它实在是太有用了, 而且又薄又耐读。 想想你基本能从这本书中学会我们这个时代最重要的编程语言之一, 而它又是那么薄那么耐读, 这不能不说是一个奇迹。

还有很多我喜爱的书是跟编程本身无关的, 而是关于计算机结构和硬件方面的。 这里面当然有 Patterson 和 Hennessy 关于计算机结构的书, 对我个人而言可能还应该包括 Crawford 和 Gelsinger 的 “Programming the 80386″, 它是我刚开始 Linux 时的工具书。

基于相同的原因, 我还喜欢 Andrew Tanenbaum 的 “Operating Systems: Design and Implementation”。

David Heinemeier Hansson:

我喜欢 《Extreme Programming Explained | 解析极限编程》, 因为它反传统的思想; 《Patterns of Enterprise Application Architecture》, 因为它打破抽象与具体之间的平衡。

Peter Norvig:

《Structure and Interpretation of Computer Programs | 计算机程序的构造和解释》

Dave Thomas:

这取决于你如何定义”最喜爱”。 可能这方面我读过的最好的书是 IBM 的 “IBM/360 Principles of Operation”。

Guido Van Rossum:

Neil Stephenson 的 “Quicksilver”。

James Gosling:

Jon Bentley 写的《编程珠玑》。

Bjarne Stroustrup:

K&R 的《C程序设计语言》

Tim Bray:

Bentley 的《编程珠玑》

9. 您最喜爱的非电脑编程类书籍?

Steve Yegge:

只有一本? 这不可能。 太多了, 太难选。

这个月我读过的好书有 “Stardust” (Neil Gaiman) 和 “The Mind’s I” (Hofstadter/Dennet)。

我最喜爱的作家是 Kurt Vonnegut, Jr。 和 Jack Vance。

Linus Torvalds:

嗯, 我已经提到过 Dawkins 的 “The Selfish Gene”。 在幻想小说方面, 我读过很多, 都很好, 但是很少有称得上”最喜爱的”。 我很少再去读读过的书, 选择也会随时间改变。 多数是科幻类的, 象 Heinlein 的 “Stranger in a Strange Land” 就是我少年时期最喜爱的, 但现在也渐渐淡忘了……

David Heinemeier Hansson:

“1984″, George Orwell。

Guido Van Rossum:

Neil Stephenson 的 “Quicksilver”。

James Gosling:

“Guns, Germs & Steel”, Jared Diamond

Bjarne Stroustrup:

一直在变化。目前喜欢?O’Brian’s Aubrey/Maturin 系列书

Tim Bray:

Ivan Denisovich 的 “One Day in the Life”

10. 您最喜爱的乐队/歌手/组合?

Steve Yegge:

最喜爱种类: 古典, 动漫音乐, 游戏音乐
最喜爱作曲家: Rachmaninoff, Chopin, Bach
最喜爱歌手/演奏家: David Russell (classical guitar), Sviatoslav Richter(piano)
最喜爱动漫音乐: Last Exile, Haibane Renmei

Linus Torvalds:

我不常听音乐, 要是听的话, 我会听老摇滚歌曲, 范围从 Pink Floyd 到 Beatles 到 Queen 到 The Who。

David Heinemeier Hansson:

种类很多。 Beth Orton, Aimee Mann, Jewel, Lauryn Hill。 其实, 你看看我举的例子她们都是弹吉他的女孩 ;)。

Guido Van Rossum:

Philip Glass。

James Gosling:

我比较喜欢民谣歌手: Christine Lavin, Woody Guthrie, Pete Seeger…

Bjarne Stroustrup:

乐队: The Dixie Chicks;作曲家:贝多芬

Tim Bray:



The Humble Programmer

The Humble Programmer
by Edsger W. Dijkstra

As a result of a long sequence of coincidences I entered the programming profession officially on the first spring morning of 1952 and as far as I have been able to trace, I was the first Dutchman to do so in my country. In retrospect the most amazing thing was the slowness with which, at least in my part of the world, the programming profession emerged, a slowness which is now hard to believe. But I am grateful for two vivid recollections from that period that establish that slowness beyond any doubt.

After having programmed for some three years, I had a discussion with A. van Wijngaarden, who was then my boss at the Mathematical Centre in Amsterdam, a discussion for which I shall remain grateful to him as long as I live. The point was that I was supposed to study theoretical physics at the University of Leiden simultaneously, and as I found the two activities harder and harder to combine, I had to make up my mind, either to stop programming and become a real, respectable theoretical physicist, or to carry my study of physics to a formal completion only, with a minimum of effort, and to become….., yes what? A programmer? But was that a respectable profession? For after all, what was programming? Where was the sound body of knowledge that could support it as an intellectually respectable discipline? I remember quite vividly how I envied my hardware colleagues, who, when asked about their professional competence, could at least point out that they knew everything about vacuum tubes, amplifiers and the rest, whereas I felt that, when faced with that question, I would stand empty-handed. Full of misgivings I knocked on van Wijngaarden’s office door, asking him whether I could “speak to him for a moment”; when I left his office a number of hours later, I was another person. For after having listened to my problems patiently, he agreed that up till that moment there was not much of a programming discipline, but then he went on to explain quietly that automatic computers were here to stay, that we were just at the beginning and could not I be one of the persons called to make programming a respectable discipline in the years to come? This was a turning point in my life and I completed my study of physics formally as quickly as I could. One moral of the above story is, of course, that we must be very careful when we give advice to younger people; sometimes they follow it!

Another two years later, in 1957, I married and Dutch marriage rites require you to state your profession and I stated that I was a programmer. But the municipal authorities of the town of Amsterdam did not accept it on the grounds that there was no such profession. And, believe it or not, but under the heading “profession” my marriage act shows the ridiculous entry “theoretical physicist”!

So much for the slowness with which I saw the programming profession emerge in my own country. Since then I have seen more of the world, and it is my general impression that in other countries, apart from a possible shift of dates, the growth pattern has been very much the same.

Let me try to capture the situation in those old days in a little bit more detail, in the hope of getting a better understanding of the situation today. While we pursue our analysis, we shall see how many common misunderstandings about the true nature of the programming task can be traced back to that now distant past.

The first automatic electronic computers were all unique, single-copy machines and they were all to be found in an environment with the exciting flavour of an experimental laboratory. Once the vision of the automatic computer was there, its realisation was a tremendous challenge to the electronic technology then available, and one thing is certain: we cannot deny the courage of the groups that decided to try and build such a fantastic piece of equipment. For fantastic pieces of equipment they were: in retrospect one can only wonder that those first machines worked at all, at least sometimes. The overwhelming problem was to get and keep the machine in working order. The preoccupation with the physical aspects of automatic computing is still reflected in the names of the older scientific societies in the field, such as the Association for Computing Machinery or the British Computer Society, names in which explicit reference is made to the physical equipment.

What about the poor programmer? Well, to tell the honest truth: he was hardly noticed. For one thing, the first machines were so bulky that you could hardly move them and besides that, they required such extensive maintenance that it was quite natural that the place where people tried to use the machine was the same laboratory where the machine had been developed. Secondly, his somewhat invisible work was without any glamour: you could show the machine to visitors and that was several orders of magnitude more spectacular than some sheets of coding. But most important of all, the programmer himself had a very modest view of his own work: his work derived all its significance from the existence of that wonderful machine. Because that was a unique machine, he knew only too well that his programs had only local significance and also, because it was patently obvious that this machine would have a limited lifetime, he knew that very little of his work would have a lasting value. Finally, there is yet another circumstance that had a profound influence on the programmer’s attitude to his work: on the one hand, besides being unreliable, his machine was usually too slow and its memory was usually too small, i.e. he was faced with a pinching shoe, while on the other hand its usually somewhat queer order code would cater for the most unexpected constructions. And in those days many a clever programmer derived an immense intellectual satisfaction from the cunning tricks by means of which he contrived to squeeze the impossible into the constraints of his equipment.

Two opinions about programming date from those days. I mention them now, I shall return to them later. The one opinion was that a really competent programmer should be puzzle-minded and very fond of clever tricks; the other opinion was that programming was nothing more than optimizing the efficiency of the computational process, in one direction or the other.

The latter opinion was the result of the frequent circumstance that, indeed, the available equipment was a painfully pinching shoe, and in those days one often encountered the naive expectation that, once more powerful machines were available, programming would no longer be a problem, for then the struggle to push the machine to its limits would no longer be necessary and that was all what programming was about, wasn’t it? But in the next decades something completely different happened: more powerful machines became available, not just an order of magnitude more powerful, even several orders of magnitude more powerful. But instead of finding ourselves in the state of eternal bliss of all programming problems solved, we found ourselves up to our necks in the software crisis! How come?

There is a minor cause: in one or two respects modern machinery is basically more difficult to handle than the old machinery. Firstly, we have got the I/O interrupts, occurring at unpredictable and irreproducible moments; compared with the old sequential machine that pretended to be a fully deterministic automaton, this has been a dramatic change and many a systems programmer’s grey hair bears witness to the fact that we should not talk lightly about the logical problems created by that feature. Secondly, we have got machines equipped with multi-level stores, presenting us problems of management strategy that, in spite of the extensive literature on the subject, still remain rather elusive. So much for the added complication due to structural changes of the actual machines.

But I called this a minor cause; the major cause is… that the machines have become several orders of magnitude more powerful! To put it quite bluntly: as long as there were no machines, programming was no problem at all; when we had a few weak computers, programming became a mild problem, and now we have gigantic computers, programming had become an equally gigantic problem. In this sense the electronic industry has not solved a single problem, it has only created them, it has created the problem of using its products. To put it in another way: as the power of available machines grew by a factor of more than a thousand, society’s ambition to apply these machines grew in proportion, and it was the poor programmer who found his job in this exploded field of tension between ends and means. The increased power of the hardware, together with the perhaps even more dramatic increase in its reliability, made solutions feasible that the programmer had not dared to dream about a few years before. And now, a few years later, he had to dream about them and, even worse, he had to transform such dreams into reality! Is it a wonder that we found ourselves in a software crisis? No, certainly not, and as you may guess, it was even predicted well in advance; but the trouble with minor prophets, of course, is that it is only five years later that you really know that they had been right.

Then, in the mid-sixties, something terrible happened: the computers of the so-called third generation made their appearance. The official literature tells us that their price/performance ratio has been one of the major design objectives. But if you take as “performance” the duty cycle of the machine’s various components, little will prevent you from ending up with a design in which the major part of your performance goal is reached by internal housekeeping activities of doubtful necessity. And if your definition of price is the price to be paid for the hardware, little will prevent you from ending up with a design that is terribly hard to program for: for instance the order code might be such as to enforce, either upon the programmer or upon the system, early binding decisions presenting conflicts that really cannot be resolved. And to a large extent these unpleasant possibilities seem to have become reality.

When these machines were announced and their functional specifications became known, quite a few among us must have become quite miserable; at least I was. It was only reasonable to expect that such machines would flood the computing community, and it was therefore all the more important that their design should be as sound as possible. But the design embodied such serious flaws that I felt that with a single stroke the progress of computing science had been retarded by at least ten years: it was then that I had the blackest week in the whole of my professional life. Perhaps the most saddening thing now is that, even after all those years of frustrating experience, still so many people honestly believe that some law of nature tells us that machines have to be that way. They silence their doubts by observing how many of these machines have been sold, and derive from that observation the false sense of security that, after all, the design cannot have been that bad. But upon closer inspection, that line of defense has the same convincing strength as the argument that cigarette smoking must be healthy because so many people do it.

It is in this connection that I regret that it is not customary for scientific journals in the computing area to publish reviews of newly announced computers in much the same way as we review scientific publications: to review machines would be at least as important. And here I have a confession to make: in the early sixties I wrote such a review with the intention of submitting it to the CACM, but in spite of the fact that the few colleagues to whom the text was sent for their advice, urged me all to do so, I did not dare to do it, fearing that the difficulties either for myself or for the editorial board would prove to be too great. This suppression was an act of cowardice on my side for which I blame myself more and more. The difficulties I foresaw were a consequence of the absence of generally accepted criteria, and although I was convinced of the validity of the criteria I had chosen to apply, I feared that my review would be refused or discarded as “a matter of personal taste”. I still think that such reviews would be extremely useful and I am longing to see them appear, for their accepted appearance would be a sure sign of maturity of the computing community.

The reason that I have paid the above attention to the hardware scene is because I have the feeling that one of the most important aspects of any computing tool is its influence on the thinking habits of those that try to use it, and because I have reasons to believe that that influence is many times stronger than is commonly assumed. Let us now switch our attention to the software scene.

Here the diversity has been so large that I must confine myself to a few stepping stones. I am painfully aware of the arbitrariness of my choice and I beg you not to draw any conclusions with regard to my appreciation of the many efforts that will remain unmentioned.

In the beginning there was the EDSAC in Cambridge, England, and I think it quite impressive that right from the start the notion of a subroutine library played a central role in the design of that machine and of the way in which it should be used. It is now nearly 25 years later and the computing scene has changed dramatically, but the notion of basic software is still with us, and the notion of the closed subroutine is still one of the key concepts in programming. We should recognise the closed subroutines as one of the greatest software inventions; it has survived three generations of computers and it will survive a few more, because it caters for the implementation of one of our basic patterns of abstraction. Regrettably enough, its importance has been underestimated in the design of the third generation computers, in which the great number of explicitly named registers of the arithmetic unit implies a large overhead on the subroutine mechanism. But even that did not kill the concept of the subroutine, and we can only pray that the mutation won’t prove to be hereditary.

The second major development on the software scene that I would like to mention is the birth of FORTRAN. At that time this was a project of great temerity and the people responsible for it deserve our great admiration. It would be absolutely unfair to blame them for shortcomings that only became apparent after a decade or so of extensive usage: groups with a successful look-ahead of ten years are quite rare! In retrospect we must rate FORTRAN as a successful coding technique, but with very few effective aids to conception, aids which are now so urgently needed that time has come to consider it out of date. The sooner we can forget that FORTRAN has ever existed, the better, for as a vehicle of thought it is no longer adequate: it wastes our brainpower, is too risky and therefore too expensive to use. FORTRAN’s tragic fate has been its wide acceptance, mentally chaining thousands and thousands of programmers to our past mistakes. I pray daily that more of my fellow-programmers may find the means of freeing themselves from the curse of compatibility.

The third project I would not like to leave unmentioned is LISP, a fascinating enterprise of a completely different nature. With a few very basic principles at its foundation, it has shown a remarkable stability. Besides that, LISP has been the carrier for a considerable number of in a sense our most sophisticated computer applications. LISP has jokingly been described as “the most intelligent way to misuse a computer”. I think that description a great compliment because it transmits the full flavour of liberation: it has assisted a number of our most gifted fellow humans in thinking previously impossible thoughts.

The fourth project to be mentioned is ALGOL 60. While up to the present day FORTRAN programmers still tend to understand their programming language in terms of the specific implementation they are working with —hence the prevalence of octal and hexadecimal dumps—, while the definition of LISP is still a curious mixture of what the language means and how the mechanism works, the famous Report on the Algorithmic Language ALGOL 60 is the fruit of a genuine effort to carry abstraction a vital step further and to define a programming language in an implementation-independent way. One could argue that in this respect its authors have been so successful that they have created serious doubts as to whether it could be implemented at all! The report gloriously demonstrated the power of the formal method BNF, now fairly known as Backus-Naur-Form, and the power of carefully phrased English, a least when used by someone as brilliant as Peter Naur. I think that it is fair to say that only very few documents as short as this have had an equally profound influence on the computing community. The ease with which in later years the names ALGOL and ALGOL-like have been used, as an unprotected trade mark, to lend some of its glory to a number of sometimes hardly related younger projects, is a somewhat shocking compliment to its standing. The strength of BNF as a defining device is responsible for what I regard as one of the weaknesses of the language: an over-elaborate and not too systematic syntax could now be crammed into the confines of very few pages. With a device as powerful as BNF, the Report on the Algorithmic Language ALGOL 60 should have been much shorter. Besides that I am getting very doubtful about ALGOL 60’s parameter mechanism: it allows the programmer so much combinatorial freedom, that its confident use requires a strong discipline from the programmer. Besides expensive to implement it seems dangerous to use.

Finally, although the subject is not a pleasant one, I must mention PL/1, a programming language for which the defining documentation is of a frightening size and complexity. Using PL/1 must be like flying a plane with 7000 buttons, switches and handles to manipulate in the cockpit. I absolutely fail to see how we can keep our growing programs firmly within our intellectual grip when by its sheer baroqueness the programming language —our basic tool, mind you!— already escapes our intellectual control. And if I have to describe the influence PL/1 can have on its users, the closest metaphor that comes to my mind is that of a drug. I remember from a symposium on higher level programming language a lecture given in defense of PL/1 by a man who described himself as one of its devoted users. But within a one-hour lecture in praise of PL/1. he managed to ask for the addition of about fifty new “features”, little supposing that the main source of his problems could very well be that it contained already far too many “features”. The speaker displayed all the depressing symptoms of addiction, reduced as he was to the state of mental stagnation in which he could only ask for more, more, more… When FORTRAN has been called an infantile disorder, full PL/1, with its growth characteristics of a dangerous tumor, could turn out to be a fatal disease.

So much for the past. But there is no point in making mistakes unless thereafter we are able to learn from them. As a matter of fact, I think that we have learned so much, that within a few years programming can be an activity vastly different from what it has been up till now, so different that we had better prepare ourselves for the shock. Let me sketch for you one of the possible futures. At first sight, this vision of programming in perhaps already the near future may strike you as utterly fantastic. Let me therefore also add the considerations that might lead one to the conclusion that this vision could be a very real possibility.

The vision is that, well before the seventies have run to completion, we shall be able to design and implement the kind of systems that are now straining our programming ability, at the expense of only a few percent in man-years of what they cost us now, and that besides that, these systems will be virtually free of bugs. These two improvements go hand in hand. In the latter respect software seems to be different from many other products, where as a rule a higher quality implies a higher price. Those who want really reliable software will discover that they must find means of avoiding the majority of bugs to start with, and as a result the programming process will become cheaper. If you want more effective programmers, you will discover that they should not waste their time debugging, they should not introduce the bugs to start with. In other words: both goals point to the same change.

Such a drastic change in such a short period of time would be a revolution, and to all persons that base their expectations for the future on smooth extrapolation of the recent past —appealing to some unwritten laws of social and cultural inertia— the chance that this drastic change will take place must seem negligible. But we all know that sometimes revolutions do take place! And what are the chances for this one?

There seem to be three major conditions that must be fulfilled. The world at large must recognize the need for the change; secondly the economic need for it must be sufficiently strong; and, thirdly, the change must be technically feasible. Let me discuss these three conditions in the above order.

With respect to the recognition of the need for greater reliability of software, I expect no disagreement anymore. Only a few years ago this was different: to talk about a software crisis was blasphemy. The turning point was the Conference on Software Engineering in Garmisch, October 1968, a conference that created a sensation as there occurred the first open admission of the software crisis. And by now it is generally recognized that the design of any large sophisticated system is going to be a very difficult job, and whenever one meets people responsible for such undertakings, one finds them very much concerned about the reliability issue, and rightly so. In short, our first condition seems to be satisfied.

Now for the economic need. Nowadays one often encounters the opinion that in the sixties programming has been an overpaid profession, and that in the coming years programmer salaries may be expected to go down. Usually this opinion is expressed in connection with the recession, but it could be a symptom of something different and quite healthy, viz. that perhaps the programmers of the past decade have not done so good a job as they should have done. Society is getting dissatisfied with the performance of programmers and of their products. But there is another factor of much greater weight. In the present situation it is quite usual that for a specific system, the price to be paid for the development of the software is of the same order of magnitude as the price of the hardware needed, and society more or less accepts that. But hardware manufacturers tell us that in the next decade hardware prices can be expected to drop with a factor of ten. If software development were to continue to be the same clumsy and expensive process as it is now, things would get completely out of balance. You cannot expect society to accept this, and therefore we must learn to program an order of magnitude more effectively. To put it in another way: as long as machines were the largest item on the budget, the programming profession could get away with its clumsy techniques, but that umbrella will fold rapidly. In short, also our second condition seems to be satisfied.

And now the third condition: is it technically feasible? I think it might and I shall give you six arguments in support of that opinion.

A study of program structure had revealed that programs —even alternative programs for the same task and with the same mathematical content— can differ tremendously in their intellectual manageability. A number of rules have been discovered, violation of which will either seriously impair or totally destroy the intellectual manageability of the program. These rules are of two kinds. Those of the first kind are easily imposed mechanically, viz. by a suitably chosen programming language. Examples are the exclusion of goto-statements and of procedures with more than one output parameter. For those of the second kind I at least —but that may be due to lack of competence on my side— see no way of imposing them mechanically, as it seems to need some sort of automatic theorem prover for which I have no existence proof. Therefore, for the time being and perhaps forever, the rules of the second kind present themselves as elements of discipline required from the programmer. Some of the rules I have in mind are so clear that they can be taught and that there never needs to be an argument as to whether a given program violates them or not. Examples are the requirements that no loop should be written down without providing a proof for termination nor without stating the relation whose invariance will not be destroyed by the execution of the repeatable statement.

I now suggest that we confine ourselves to the design and implementation of intellectually manageable programs. If someone fears that this restriction is so severe that we cannot live with it, I can reassure him: the class of intellectually manageable programs is still sufficiently rich to contain many very realistic programs for any problem capable of algorithmic solution. We must not forget that it is not our business to make programs, it is our business to design classes of computations that will display a desired behaviour. The suggestion of confining ourselves to intellectually manageable programs is the basis for the first two of my announced six arguments.

Argument one is that, as the programmer only needs to consider intellectually manageable programs, the alternatives he is choosing between are much, much easier to cope with.

Argument two is that, as soon as we have decided to restrict ourselves to the subset of the intellectually manageable programs, we have achieved, once and for all, a drastic reduction of the solution space to be considered. And this argument is distinct from argument one.

Argument three is based on the constructive approach to the problem of program correctness. Today a usual technique is to make a program and then to test it. But: program testing can be a very effective way to show the presence of bugs, but is hopelessly inadequate for showing their absence. The only effective way to raise the confidence level of a program significantly is to give a convincing proof of its correctness. But one should not first make the program and then prove its correctness, because then the requirement of providing the proof would only increase the poor programmer’s burden. On the contrary: the programmer should let correctness proof and program grow hand in hand. Argument three is essentially based on the following observation. If one first asks oneself what the structure of a convincing proof would be and, having found this, then constructs a program satisfying this proof’s requirements, then these correctness concerns turn out to be a very effective heuristic guidance. By definition this approach is only applicable when we restrict ourselves to intellectually manageable programs, but it provides us with effective means for finding a satisfactory one among these.

Argument four has to do with the way in which the amount of intellectual effort needed to design a program depends on the program length. It has been suggested that there is some kind of law of nature telling us that the amount of intellectual effort needed grows with the square of program length. But, thank goodness, no one has been able to prove this law. And this is because it need not be true. We all know that the only mental tool by means of which a very finite piece of reasoning can cover a myriad cases is called “abstraction”; as a result the effective exploitation of his powers of abstraction must be regarded as one of the most vital activities of a competent programmer. In this connection it might be worth-while to point out that the purpose of abstracting is not to be vague, but to create a new semantic level in which one can be absolutely precise. Of course I have tried to find a fundamental cause that would prevent our abstraction mechanisms from being sufficiently effective. But no matter how hard I tried, I did not find such a cause. As a result I tend to the assumption —up till now not disproved by experience— that by suitable application of our powers of abstraction, the intellectual effort needed to conceive or to understand a program need not grow more than proportional to program length. But a by-product of these investigations may be of much greater practical significance, and is, in fact, the basis of my fourth argument. The by-product was the identification of a number of patterns of abstraction that play a vital role in the whole process of composing programs. Enough is now known about these patterns of abstraction that you could devote a lecture to about each of them. What the familiarity and conscious knowledge of these patterns of abstraction imply dawned upon me when I realized that, had they been common knowledge fifteen years ago, the step from BNF to syntax-directed compilers, for instance, could have taken a few minutes instead of a few years. Therefore I present our recent knowledge of vital abstraction patterns as the fourth argument.

Now for the fifth argument. It has to do with the influence of the tool we are trying to use upon our own thinking habits. I observe a cultural tradition, which in all probability has its roots in the Renaissance, to ignore this influence, to regard the human mind as the supreme and autonomous master of its artefacts. But if I start to analyse the thinking habits of myself and of my fellow human beings, I come, whether I like it or not, to a completely different conclusion, viz. that the tools we are trying to use and the language or notation we are using to express or record our thoughts, are the major factors determining what we can think or express at all! The analysis of the influence that programming languages have on the thinking habits of its users, and the recognition that, by now, brainpower is by far our scarcest resource, they together give us a new collection of yardsticks for comparing the relative merits of various programming languages. The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague. In the case of a well-known conversational programming language I have been told from various sides that as soon as a programming community is equipped with a terminal for it, a specific phenomenon occurs that even has a well-established name: it is called “the one-liners”. It takes one of two different forms: one programmer places a one-line program on the desk of another and either he proudly tells what it does and adds the question “Can you code this in less symbols?” —as if this were of any conceptual relevance!— or he just asks “Guess what it does!”. From this observation we must conclude that this language as a tool is an open invitation for clever tricks; and while exactly this may be the explanation for some of its appeal, viz. to those who like to show how clever they are, I am sorry, but I must regard this as one of the most damning things that can be said about a programming language. Another lesson we should have learned from the recent past is that the development of “richer” or “more powerful” programming languages was a mistake in the sense that these baroque monstrosities, these conglomerations of idiosyncrasies, are really unmanageable, both mechanically and mentally. I see a great future for very systematic and very modest programming languages. When I say “modest”, I mean that, for instance, not only ALGOL 60’s “for clause”, but even FORTRAN’s “DO loop” may find themselves thrown out as being too baroque. I have run a a little programming experiment with really experienced volunteers, but something quite unintended and quite unexpected turned up. None of my volunteers found the obvious and most elegant solution. Upon closer analysis this turned out to have a common source: their notion of repetition was so tightly connected to the idea of an associated controlled variable to be stepped up, that they were mentally blocked from seeing the obvious. Their solutions were less efficient, needlessly hard to understand, and it took them a very long time to find them. It was a revealing, but also shocking experience for me. Finally, in one respect one hopes that tomorrow’s programming languages will differ greatly from what we are used to now: to a much greater extent than hitherto they should invite us to reflect in the structure of what we write down all abstractions needed to cope conceptually with the complexity of what we are designing. So much for the greater adequacy of our future tools, which was the basis of the fifth argument.

As an aside I would like to insert a warning to those who identify the difficulty of the programming task with the struggle against the inadequacies of our current tools, because they might conclude that, once our tools will be much more adequate, programming will no longer be a problem. Programming will remain very difficult, because once we have freed ourselves from the circumstantial cumbersomeness, we will find ourselves free to tackle the problems that are now well beyond our programming capacity.

You can quarrel with my sixth argument, for it is not so easy to collect experimental evidence for its support, a fact that will not prevent me from believing in its validity. Up till now I have not mentioned the word “hierarchy”, but I think that it is fair to say that this is a key concept for all systems embodying a nicely factored solution. I could even go one step further and make an article of faith out of it, viz. that the only problems we can really solve in a satisfactory manner are those that finally admit a nicely factored solution. At first sight this view of human limitations may strike you as a rather depressing view of our predicament, but I don’t feel it that way, on the contrary! The best way to learn to live with our limitations is to know them. By the time that we are sufficiently modest to try factored solutions only, because the other efforts escape our intellectual grip, we shall do our utmost best to avoid all those interfaces impairing our ability to factor the system in a helpful way. And I cannot but expect that this will repeatedly lead to the discovery that an initially untractable problem can be factored after all. Anyone who has seen how the majority of the troubles of the compiling phase called “code generation” can be tracked down to funny properties of the order code, will know a simple example of the kind of things I have in mind. The wider applicability of nicely factored solutions is my sixth and last argument for the technical feasibility of the revolution that might take place in the current decade.

In principle I leave it to you to decide for yourself how much weight you are going to give to my considerations, knowing only too well that I can force no one else to share my beliefs. As each serious revolution, it will provoke violent opposition and one can ask oneself where to expect the conservative forces trying to counteract such a development. I don’t expect them primarily in big business, not even in the computer business; I expect them rather in the educational institutions that provide today’s training and in those conservative groups of computer users that think their old programs so important that they don’t think it worth-while to rewrite and improve them. In this connection it is sad to observe that on many a university campus the choice of the central computing facility has too often been determined by the demands of a few established but expensive applications with a disregard of the question how many thousands of “small users” that are willing to write their own programs were going to suffer from this choice. Too often, for instance, high-energy physics seems to have blackmailed the scientific community with the price of its remaining experimental equipment. The easiest answer, of course, is a flat denial of the technical feasibility, but I am afraid that you need pretty strong arguments for that. No reassurance, alas, can be obtained from the remark that the intellectual ceiling of today’s average programmer will prevent the revolution from taking place: with others programming so much more effectively, he is liable to be edged out of the picture anyway.

There may also be political impediments. Even if we know how to educate tomorrow’s professional programmer, it is not certain that the society we are living in will allow us to do so. The first effect of teaching a methodology —rather than disseminating knowledge— is that of enhancing the capacities of the already capable, thus magnifying the difference in intelligence. In a society in which the educational system is used as an instrument for the establishment of a homogenized culture, in which the cream is prevented from rising to the top, the education of competent programmers could be politically impalatable.

Let me conclude. Automatic computers have now been with us for a quarter of a century. They have had a great impact on our society in their capacity of tools, but in that capacity their influence will be but a ripple on the surface of our culture, compared with the much more profound influence they will have in their capacity of intellectual challenge without precedent in the cultural history of mankind. Hierarchical systems seem to have the property that something considered as an undivided entity on one level, is considered as a composite object on the next lower level of greater detail; as a result the natural grain of space or time that is applicable at each level decreases by an order of magnitude when we shift our attention from one level to the next lower one. We understand walls in terms of bricks, bricks in terms of crystals, crystals in terms of molecules etc. As a result the number of levels that can be distinguished meaningfully in a hierarchical system is kind of proportional to the logarithm of the ratio between the largest and the smallest grain, and therefore, unless this ratio is very large, we cannot expect many levels. In computer programming our basic building block has an associated time grain of less than a microsecond, but our program may take hours of computation time. I do not know of any other technology covering a ratio of 1010 or more: the computer, by virtue of its fantastic speed, seems to be the first to provide us with an environment where highly hierarchical artefacts are both possible and necessary. This challenge, viz. the confrontation with the programming task, is so unique that this novel experience can teach us a lot about ourselves. It should deepen our understanding of the processes of design and creation, it should give us better control over the task of organizing our thoughts. If it did not do so, to my taste we should not deserve the computer at all!

It has already taught us a few lessons, and the one I have chosen to stress in this talk is the following. We shall do a much better programming job, provided that we approach the task with a full appreciation of its tremendous difficulty, provided that we stick to modest and elegant programming languages, provided that we respect the intrinsic limitations of the human mind and approach the task as Very Humble Programmers.



Edsger W. Dijkstra


在有了三年编程经验后,我和当时我在阿姆斯特丹数学中心的老板 A. Van Wijngaarden(译注:荷兰数学家和计算机科学家),进行了一场讨论,关于这场讨论我在有生之年都会感激他。讨论的焦点在于,我本来是要在编程的同时,在莱顿大学学习理论物理,但是当发现鱼和熊掌不可兼得时,我不得不做出选择,要么停止编程,成为一个名符其实的可敬的理论物理学家;或者把我的物理学研究敷衍了事,而成为一个…那个叫什么?程序员?但那是个受人尊敬的职业么?什么又是编程呢?它作为一门学科所需要的完备知识体系又在哪里呢?我非常清晰得记得自己有多嫉妒我从事硬件的同僚们,因为当被问到专业技能时,他们至少可以谈自己所知道关于真空管,放大器,和其他一些硬件的一切;而被问到这个问题时,我只能茫然无措。满心焦虑,我敲开了 van Wijngaarden 的办公室大门,问道:“是否能占用他一点时间”;而在几个小时后离开他办公室时,我整个人焕然一新。在耐心听完我的问题后,他同意当时并没有学科是关于编程的,但是他接下来解释说,自动化电脑会继续发展,而我们正处于摸索阶段,那我能不能成为先驱者之一,使编程在未来成为一个受人认可的学科呢?这成了我人生中的一个转折点,促使我尽快完成了我的物理学研究。上述故事的寓意是,我们必须谨慎地向年轻人提供意见,因为有时他们真的会听的!















刚开始的时候,EDSAC 在英国的剑桥兴起,我对其起初让子程序库在机器设计和使用方法中发挥主要作业的观点印象深刻。接近25年后的今天,计算领域彻底的变化了,但是软件的基本观念还伴随着我们,闭合子程序的观念也还是我们编程的核心概念之一。我们应该认可闭合子程序作为最伟大的软件发明之一,它经历了三代计算机的发展并且仍将继续存活几代,因为它迎合了我们基本抽象模式的接口思想。遗憾的是,在第三代计算机的设计中,它的重要性被低估了,而这个设计中,大量明确命名为寄存器的算术计算单位揭示了子程序机制的广泛使用。尽管如此,也没有让子程序的概念就此消失,我们只能祈祷这种变化不会在下一代的计算机中被遗传。



第四个要提到的就是 ALGOL 60。到目前为止,FORTRAN程序员仍然倾向于从他们的开发中了解他们的编程语言——八进制的兴起和十六进制的衰落;而LISP的定义依然是一种令人好奇的混合体,其中包括这门语言意味着什么和这门机制是怎么工作的,《算法语言》那篇著名的报告中说道,ALGOL 60是真正努力去承载抽象概念至关重要的一步,再加上通过独立于语言之外的方法定义一门编程语言的成果。有人会说,ALGOL 60的作者们已经如此的成功,以至于他们自己引出这门语言是否可以实现产生的严肃疑问!那篇报告冠冕堂皇地展示了BNF范式(即现在人尽皆知的Backs-Naur-Form)的作用,和英语谨慎措辞的力量,至少是像Peter Naur一样聪明的人使用时。我觉得可以负责任地说,基本没有像它这么短而在计算机界有相同影响力的文档存在。人们习惯于使用用“ALGOL”或者是“类ALGOL”这样未经保护的标签,向大量基本不相关的年轻语言分享ALGOL的荣耀,这本身某种程度上就是对ALGOL惊人生命力的极大致敬。BNF作为一种严格定义的语言,它的长处导致了我个人认为是这门语言的缺点——过分精心制作并且语法定义不规则,很难在几页纸中完全说明。如果有个BNF般强大的设备,《算术语言》中那篇关于ALGOL60的报告可以变得更短很多。除此以外,我对ALGOL60的参数机制表示怀疑,它赋予程序员如此多的组合自由,以至于要求程序员更自律。除了开发成本外,它使用起来似乎也很危险。




在如此短的一段时间内发生如此激烈的变革,这会是一场革命,对所有人来说,基于他们对未来的期望,对过去(诉诸不成文的社会,文化惰性的法律)做出的和平推断,这种巨大变革会发生的机会几乎微不足道。但我们都知道有时候革命真的发生了。 那么这次变革我们的机遇是什么呢?


谈到对软件更为可靠的需求,我表示完全同意。在几年前,就不一样了——讨论软件危机是对上帝的亵渎。转折点是 1968年十月在Garmisch举行的软件工程的学术会议,一次萌生了知觉承认软件危机的回忆。到目前为止,普遍认为任何大型系统的设计都是一项十分困难的工作,无论何时,人们遇到负责这样工作的人,都会发现他们非常关心可靠性问题。简而言之,我们第一个条件似乎满足了。

现在说到经济需求。现在人们总是遇到说六十年代编程是一个薪酬过高的职业的观点,并且说未来几年内,程序员薪酬希望可以下降。通常,这种观点的表述与经济衰退有关,但这是一种不同,健康的事物的征兆——也许过去几十年里程序员没有很好完成他们应该完成的工作。社会对程序员的表现和他们的产品感到不满意。但还存在另外一种导致重担的因素。现在的情况是,对于特定的系统,为软件升级的价格和升级硬件的价格在同一个数量级,社会或多或少接受了这一点。但硬件制造商告诉我们说在接下来数十年,硬件价格将会以十倍速度下降。如果软件发展还是一如既往的笨拙,程序一如既往的昂贵,局势将失去平衡。你不能指望社会接受这一点,因此我们必须学会有效的编程。 换句话说,只要机器还是预算中的大项,那么笨拙的编程技术还能侥幸逃脱,但是保护伞会快的折起来。总之,我们的第二个条件似乎也能满足。


一份程序结构的研究表明程序,即便是同一个任务的替补程序和有着相同的数学内容,在程序管理方面都有着巨大的差异。研究发现许多规律,违反任何一条规律要么局部或者整体的破坏程序的人为管理。这些规律不外乎两种。第一种容易在物理上加以利用,即选用合适的编程语言。Goto语句的和多输出参数的程序的剔除是很好的佐证。对于第二种,我至少看不到物理上使之暴露的方法(可能是我能力不足),好像需要一些我没有证明存在的自动化的定理证明程序。因此,第二种规律时不时作为程序员训练的要素之一出现。有些规律我清楚的知道以至于可以教给他人和不需要判断一段给定的程序是否违反了。 我们给出必要的例子——任何循环需要给出终止条件或者声明不变量之间的关系保证不变量不会被程序的循环语句执行而破坏。




论据三是建立在程序正确性问题的建设性方法上的。今天,一项普通的技术就是写一个程序,然后去测试。 尽管,程序测试是一种非常有效的方法去暴露bugs,但对证明不存在bugs几乎是完全没用的。显著提高程序可信度唯一有效的方法是给出一个令人信服的关于正确性的证据。但是我们不应该首先写出程序,然后去证明它的正确性,因为要求证明只会增加苦逼程序员的负担。相反,程序员应该让正确性证明和程序相互验证,发展。论据三本质上是从以下的观察得来的。如果一个人问自己一个令人信服的证据应该具备什么,他了解后,写了一个很好的满足了证明要求的程序,然后这些关于正确性的担心变成一种有效的启发式的指导。当我们把自己限制在智能可控程序时,按照定义,只有这种方法是可行,但这种方法也提供许多有效的方法,让我们从中挑选一个满意的。

设计一个程序需要多少人力根据程序的长度判断,论据四与此相关。曾经有人指出存在一种自然法则告诉我们耗费人力是程序长度的平方。但是谢天谢地,还没有人能够证明这种法则。这是因为它需要是假的。我们都知道能够解决很多问题的推理论证工具称之为抽象,抽象能力的有效开发可以被认为一个有能力的程序员至关重要的敏捷之一。关于这一点,值得指出抽象的意图并不是为了模糊本身,而是去创造新的准确语义水平。当然,我曾经尝试去找到能够阻止我们抽象机制起作用的基础原因。但不管我多么努力,我都找不到任何一个原因。最后,我倾向于假设(直到现在未通过经验证明)我恰当的抽象化能力,也就是人力需要想象或者理解一个程序的耗费不会根据程序长度按照超过正比例的速度增长。但是这些调查的一个衍生品更有实际意义,实际上,它是我论据四的基础。衍生品是许多在整个编程过程中扮演重要角色的抽象模式的识别。你了解这些抽象模式足够多,你就可以就每个模式作报告。这些抽象模式的熟悉和了解让我幡然醒悟,例如从BNF到方向句法编译,可以用几分钟代替几年的花费。 因此,我把我们最近对重要抽象模式的理解作为论据四。

现在说到论据五,它和我们建立在我们思考习惯上的工具的影响有关。我观察到一种十有八九来源于文艺复兴的文化传统,为了忽略这种影响,需要把人心视为肉体最高自主的主人。 但我一开始分析我和同类的思考习惯时,我得到一个完全不同的结论,不管我喜欢与否,即我们使用的工具和我们用来表达或者记录我们想法的语言或记号,是决定我们能够想到什么的主要因素。对编程影响程序员的思考习惯的分析和脑力是我们几乎不曾使用的资源的认识,它们给出了从多方面给出不同编程语言优缺点的尺度。一个有能力的程序员能够意识到他自己脑容量的严格尺寸,因此,他谦逊的完成编程任务,牵涉到其他事情时,他避免小聪明像躲避瘟疫一样。说到一种著名的会话式程序设计技术,我从不同渠道被告知说如果一个计算社区一旦装备终端,一种特殊的现象就会发生,这种现象甚至有了一个被广泛接受的名称——打趣的人。它有一到两种不同的形式,一个程序员在别人桌面放了一个调侃的程序,他要么骄傲的展示它的用途并问别人你能用更少的字符写完吗(好像有任何概念的相关性一样),要么就问说猜猜这是用来干嘛的。通过这个观察,我们必须总结说这门语言是一种宣扬奇技淫巧的工具,同时这会是它的一些诉求的解释,例如说那些喜欢展示他们有多聪明的人,对不起,但是我必须把它视作关于编程语言最令人恶心的地方。我们必须从过去学到的另外一课是所谓功能强大,丰富的编程语言的发展是一种错误,就像这些奇怪庞然大物,某人特有的气质的聚集,都是心灵上,肉体上不可控的。我从系统的谦逊的编程语言上看到很美好的未来。 当我说谦逊时,我的意思是,例如,不仅是ALGOL60的for分支语句,还有FORTRAN的DO循环语句发现因为变得过于怪异而被淘汰。我曾经和一些有经验的志愿者做过一点编程实验,但有些不期望发生和预料不到的事情发生了。我的志愿者没有一个找到明显而漂亮的解决方法。通过更为细致的观察,我们找到相同的源头:他们对与重复的概念与用于加速的联合控制变量的联系过于紧密,以至于他们被蒙蔽了完全看不到明显的方法。他们的方法低效,晦涩难懂,并且耗费了大量时间。这是一段对我来说具有启示作用,和令人震惊的经历。最后,从某个方面上来讲,如果一个人希望明天的编程语言和现在的大为不同,很大程度的优于现在的,他们应该邀请我们在我们写下的所有需要用来应付概念上我们如今设计的抽象结构中思考。关于我们未来工具的优越性,也就是我们第五个论据的基础,就讲到这里。





让我总结一下。计算机已经伴随我们走过一个世纪的四分之一了。它们以工具的身份对我们社会产生了深远的影响,但是和在人类历史上史无前例的以智力挑战的形式产生深远的影响相比,它们只能以波浪的形式影响我们文化的表面。似乎拥有决定在某种程度上将物体视作一个不可分割整体的权利的分层系统,被视作一个级别更低,细节更多的混合物,最后,当我们将注意力从一级转向更低一级时,时空的天然粒面会以合适的数量级减少。 我们知道墙以砖为单位,砖以结晶体为单位,结晶体以分子为单位,等等。在分层系统中,许多级别可以有意义的区分出来,这和最大与最小粒度的比率的对数成正比,因此,除非比率很大,我们不能指望能够分很多层。在计算机编程中,我们基本的编程语句有低于一微秒的时间粒度,但我们的程序却可能花费几小时的计算时间。我不知道任何一种超过10的10次方的比率的技术,以它超凡速度为优点的计算机,似乎是第一个给我们提供需要分层粒度大和实现它的环境的。这样的挑战,即面对编程任务,是独一无二的,因此这样小说一般的经历可以教会我们很多关于自己的知识。它加深了我们对设计和创造程序的理解,它帮助我们更好的完成想法条理化的任务。如果它没有这样做,对我来说,我们根本不值得拥有计算机。



Linux kernel management style

Linux kernel management style
by Linus Torvalds

This is a short document describing the preferred (or made up, depending on who you ask) management style for the linux kernel. It’s meant to mirror the CodingStyle document to some degree, and mainly written to avoid answering (*) the same (or similar) questions over and over again.

Management style is very personal and much harder to quantify than simple coding style rules, so this document may or may not have anything to do with reality. It started as a lark, but that doesn’t mean that it might not actually be true. You’ll have to decide for yourself.
Btw, when talking about “kernel manager”, it’s all about the technical lead persons, not the people who do traditional management inside companies. If you sign purchase orders or you have any clue about the budget of your group, you’re almost certainly not a kernel manager. These suggestions may or may not apply to you.

First off, I’d suggest buying “Seven Habits of Highly Successful People”, and NOT read it. Burn it, it’s a great symbolic gesture.

(*) This document does so not so much by answering the question, but by making it painfully obvious to the questioner that we don’t have a clue to what the answer is.

Anyway, here goes:

Chapter 1: Decisions

Everybody thinks managers make decisions, and that decision-making is important. The bigger and more painful the decision, the bigger the manager must be to make it. That’s very deep and obvious, but it’s not actually true.

The name of the game is to _avoid_ having to make a decision. In particular, if somebody tells you “choose (a) or (b), we really need you to decide on this”, you’re in trouble as a manager. The people you manage had better know the details better than you, so if they come to you for a technical decision, you’re screwed. You’re clearly not competent to make that decision for them.
(Corollary:if the people you manage don’t know the details better than you, you’re also screwed, although for a totally different reason. Namely that you are in the wrong job, and that _they_ should be managing your brilliance instead).

So the name of the game is to _avoid_ decisions, at least the big and painful ones. Making small and non-consequential decisions is fine, and makes you look like you know what you’re doing, so what a kernel manager needs to do is to turn the big and painful ones into small things where nobody really cares.

It helps to realize that the key difference between a big decision and a small one is whether you can fix your decision afterwards. Any decision can be made small by just always making sure that if you were wrong (and you _will_ be wrong), you can always undo the damage later by backtracking. Suddenly, you get to be doubly managerial for making _two_ inconsequential decisions – the wrong one _and_ the right one.

And people will even see that as true leadership (*cough* bullshit *cough*).
Thus the key to avoiding big decisions becomes to just avoiding to do things that can’t be undone. Don’t get ushered into a corner from which you cannot escape. A cornered rat may be dangerous – a cornered manager is just pitiful.

It turns out that since nobody would be stupid enough to ever really let a kernel manager have huge fiscal responsibility _anyway_, it’s usually fairly easy to backtrack. Since you’re not going to be able to waste huge amounts of money that you might not be able to repay, the only thing you can backtrack on is a technical decision, and there back-tracking is very easy: just tell everybody that you were an incompetent nincompoop, say you’re sorry, and undo all the worthless work you had people work on for the last year. Suddenly the decision you made a year ago wasn’t a big decision after all, since it could be easily undone.

It turns out that some people have trouble with this approach, for two reasons:

– admitting you were an idiot is harder than it looks. We all like to maintain appearances, and coming out in public to say that you were wrong is sometimes very hard indeed.

– having somebody tell you that what you worked on for the last year wasn’t worthwhile after all can be hard on the poor lowly engineers too, and while the actual _work_ was easy enough to undo by just deleting it, you may have irrevocably lost the trust of that engineer. And remember: “irrevocable” was what we tried to avoid in the first place, and your decision ended up being a big one after all.

Happily, both of these reasons can be mitigated effectively by just admitting up-front that you don’t have a friggin’ clue, and telling people ahead of the fact that your decision is purely preliminary, and might be the wrong thing. You should always reserve the right to change your mind, and make people very _aware_ of that. And it’s much easier to admit that you are stupid when you haven’t _yet_ done the really stupid thing.

Then, when it really does turn out to be stupid, people just roll their eyes and say “Oops, he did it again”.

This preemptive admission of incompetence might also make the people who actually do the work also think twice about whether it’s worth doing or not. After all, if _they_ aren’t certain whether it’s a good idea, you sure as hell shouldn’t encourage them by promising them that what they work on will be included. Make them at least think twice before they embark on a big endeavor.
Remember: they’d better know more about the details than you do, and they usually already think they have the answer to everything. The best thing you can do as a manager is not to instill confidence, but rather a healthy dose of critical thinking on what they do.

Btw, another way to avoid a decision is to plaintively just whine “can’t we just do both?” and look pitiful. Trust me, it works. If it’s not clear which approach is better, they’ll eventually figure it out. The answer may end up being that both teams get so frustrated by the situation that they just give up.

That may sound like a failure, but it’s usually a sign that there was something wrong with both projects, and the reason the people involved couldn’t decide was that they were both wrong. You end up coming up smelling like roses, and you avoided yet another decision that you could have screwed up on.

Chapter 2: People

Most people are idiots, and being a manager means you’ll have to deal with it, and perhaps more importantly, that _they_ have to deal with _you_.

It turns out that while it’s easy to undo technical mistakes, it’s not as easy to undo personality disorders. You just have to live with theirs – and yours.

However, in order to prepare yourself as a kernel manager, it’s best to remember not to burn any bridges, bomb any innocent villagers, or alienate too many kernel developers. It turns out that alienating people is fairly easy, and un-alienating them is hard. Thus “alienating” immediately falls under the heading of “not reversible”, and becomes a no-no according to Chapter 1.

There’s just a few simple rules here:

(1) don’t call people d*ckheads (at least not in public)
(2) learn how to apologize when you forgot rule (1)

The problem with #1 is that it’s very easy to do, since you can say “you’re a d*ckhead” in millions of different ways (*), sometimes without even realizing it, and almost always with a white-hot conviction that you are right.

And the more convinced you are that you are right (and let’s face it, you can call just about _anybody_ a d*ckhead, and you often _will_ be right), the harder it ends up being to apologize afterwards.

To solve this problem, you really only have two options:
– get really good at apologies
– spread the “love” out so evenly that nobody really ends up feeling like they get unfairly targeted. Make it inventive enough, and they might even be amused.

The option of being unfailingly polite really doesn’t exist. Nobody will trust somebody who is so clearly hiding his true character.

(*) Paul Simon sang “Fifty Ways to Lose Your Lover”, because quite frankly, “A Million Ways to Tell a Developer He Is a D*ckhead” doesn’t scan nearly as well. But I’m sure he thought about it.

Chapter 3: People II – the Good Kind

While it turns out that most people are idiots, the corollary to that is sadly that you are one too, and that while we can all bask in the secure knowledge that we’re better than the average person (let’s face it, nobody ever believes that they’re average or below-average), we should also admit that we’re not the sharpest knife around, and there will be other people that are less of an idiot that you are.

Some people react badly to smart people. Others take advantage of them.
Make sure that you, as a kernel maintainer, are in the second group. Suck up to them, because they are the people who will make your job easier. In particular, they’ll be able to make your decisions for you, which is what the game is all about.

So when you find somebody smarter than you are, just coast along. Your management responsibilities largely become ones of saying “Sounds like a good idea – go wild”, or “That sounds good, but what about xxx?”. The second version in particular is a great way to either learn something new about “xxx” or seem _extra_ managerial by pointing out something the smarter person hadn’t thought about. In either case, you win.

One thing to look out for is to realize that greatness in one area does not necessarily translate to other areas. So you might prod people in specific directions, but let’s face it, they might be good at what they do, and suck at everything else. The good news is that people tend to naturally gravitate back to what they are good at, so it’s not like you are doing something irreversible when you _do_ prod them in some direction, just don’t push too hard.

Chapter 4: Placing blame

Things will go wrong, and people want somebody to blame. Tag, you’re it.
It’s not actually that hard to accept the blame, especially if people kind of realize that it wasn’t _all_ your fault. Which brings us to the best way of taking the blame: do it for another guy. You’ll feel good for taking the fall, he’ll feel good about not getting blamed, and the guy who lost his whole 36GB porn-collection because of your incompetence will grudgingly admit that you at least didn’t try to weasel out of it.

Then make the developer who really screwed up (if you can find him) know _in_private_ that he screwed up. Not just so he can avoid it in the future, but so that he knows he owes you one. And, perhaps even more importantly, he’s also likely the person who can fix it. Because, let’s face it, it sure ain’t you.

Taking the blame is also why you get to be manager in the first place. It’s part of what makes people trust you, and allow you the potential glory, because you’re the one who gets to say “I screwed up”. And if you’ve followed the previous rules, you’ll be pretty good at saying that by now.

Chapter 5: Things to avoid

There’s one thing people hate even more than being called “d*ckhead”, and that is being called a “d*ckhead” in a sanctimonious voice. The first you can apologize for, the second one you won’t really get the chance. They likely will no longer be listening even if you otherwise do a good job.

We all think we’re better than anybody else, which means that when somebody else puts on airs, it _really_ rubs us the wrong way. You may be morally and intellectually superior to everybody around you, but don’t try to make it too obvious unless you really _intend_ to irritate somebody (*).
Similarly, don’t be too polite or subtle about things. Politeness easily ends up going overboard and hiding the problem, and as they say, “On the internet, nobody can hear you being subtle”. Use a big blunt object to hammer the point in, because you can’t really depend on people getting your point otherwise.

Some humor can help pad both the bluntness and the moralizing. Going overboard to the point of being ridiculous can drive a point home without making it painful to the recipient, who just thinks you’re being silly. It can thus help get through the personal mental block we all have about criticism.

(*) Hint: internet newsgroups that are not directly related to your work are great ways to take out your frustrations at other people. Write insulting posts with a sneer just to get into a good flame every once in a while, and you’ll feel cleansed. Just don’t crap too close to home.

Chapter 6: Why me?

Since your main responsibility seems to be to take the blame for other peoples mistakes, and make it painfully obvious to everybody else that you’re incompetent, the obvious question becomes one of why do it in the first place?

First off, while you may or may not get screaming teenage girls (or boys, let’s not be judgmental or sexist here) knocking on your dressing room door, you _will_ get an immense feeling of personal accomplishment for being “in charge”. Never mind the fact that you’re really leading by trying to keep up with everybody else and running after them as fast as you can. Everybody will still think you’re the person in charge.

It’s a great job if you can hack it.



Linus Torvalds


(*) 这个文档不见得”回答”多少问题,更大程度上是展示我们的无知,让提问者死了这条心。







顺便说一下,另外一个避免决定的办法是装可怜,简单地问”我们为什么不能两个都做呢?” 相信我,这个有用。如果不清楚哪条路子更好一些,他们最终会整明白的。答案或许是两帮人都挫败灰心,双双放弃。