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.

原文地址:
http://www.techrepublic.com

10种你会遇到的程序员


10种你会遇到的程序员
作者: Justin James
译者: 来自网络,抱歉没查到准确出处

程序员素来就被认为是一个奇特的人群。实际上,就算在程序开发者社群本身之中,也有一些特别的人群能让其他程序员觉得很奇怪。在这我列出10种你可能遇到过的程序员,你能想出更多么?

#1:甘道夫
这种程序员看起来,就像是在《指环王》里扮演甘道夫的最佳候选人。他(甚至是她)有着快要到膝盖的胡子,一顶看起来傻傻的帽子,在冬天可能还会穿一件披风或者是斗篷。对于团队来说幸运的是,此人对自己工作的熟练程度就像甘道夫一样。但不幸的是,他们要经常忍受甘道夫长达数个小时的故事的折磨,而内容主要是关于他或者是她是如何不得不在雪地中上山下山,以把打好孔的纸带送到计算机房。甘道夫类型的程序员是你的究极武器,但是你会总是希望能把他们排到后面,只在快要绝望的时候才向他们寻求帮助。

#2:烈士
对于任何其它职业来说,烈士其实就是一个工作狂而已。但是在开发者的领域,烈士完全进入了另外一个范畴。工作狂至少会回家洗澡睡觉,而烈士们却会以睡在桌子底下的空皮萨盒子堆之中为荣。而问题是,根本就没人要求烈士们像这样工作。而且他或者她总是想用这样的措辞来使团队中的其他人感到内疚,“好的,你们回家吃完饭吧。我会在今晚会完成相当于3个星期的工作量的。”

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

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

总体来说,和文斯一起工作是很有趣的,实际上他有丰富的经验,只是永远长不大而已。但是如果文斯决定用他或者是她的摇滚风格来处理自己的头发和生活的时候,情况就会变得很棘手。因为和一个每天都带着宿醉未醒的人一起工作,相当困难。

#5:忍者
忍者是你们团队当中的重要人物,但是却没人能意识到这点。就好象传奇刺客一样,你不知道忍者是什么时候工作的,但是你总是在第二天早晨发现他们的成果。于是你急忙打开源代码控制系统,然后发现在临晨4点,忍者提交了一份代码,解决了一个你已经研究了一个星期的问题,而你之前甚至都不知道忍者大人知道你所作的项目的存在。明白了吧,当你还在一次次的开会的时候,忍者一直在工作。

忍者是如此的隐蔽,你甚至都不知道他们的名字,但是你知道每一个他们参与的项目都进行的更顺利。不过,注意点,忍者是孤胆战士,不要试图强迫他们在一个严格的等级和文档制度下工作。

#6:理论家
理论家知道一切编程需要知道的东西。他或者是她可以花4个小时去探讨一个很冷僻的语言,或者去证明你写的代码是如何的不完美并且有可能会在运行的时候多花3纳秒。问题在于,理论家根本就不知道什么叫软件开发。当理论家写代码的时候,他的代码是如此的“优美”,以至于我们这些凡人根本就看不懂。他或者她最喜爱的技术就是递归,每一个代码块都被使用到了极致,而代价就是工程进度和可读性。

理论家还很容易分心。一个花一个小时就能完成的工作,理论家们往往需要三个月。因为他们认为当前的开发工具不够好,所以他们必须开发一些新的工具来构建新的库从而构建一个全新的系统来迎合他们的高标准。理论家可以成为你最好的团队成员,前提是你能让他专注于你们所做的工程本身,而不是把时间都花在究极排序算法上。

#7:代码牛仔
代码牛仔是一种无法阻止的天性。他或者她几乎总是一个厉害的编程者,并且总是能以别人2至3倍的速度完成工作。问题是,这些代码至少有一半都靠偷工减料得来的。代码牛仔认为把代码提交到源码控制系统太麻烦,把配置信息存贮在代码之外太麻烦,和其它人交流太麻烦……你懂我的意思吧。

代码牛仔的代码就好像意大利面条一样搅在一起,因为他或者她工作的事如此之快,以至于必要的重构都没有做到。很有可能的是,七页长的核心功能代码也许看起来就像是教科书上关于“不要这么做”的示例,而这些代码居然还神奇的可以运行。代码牛仔绝对没办法和别人一起工作。而且,如果你让两个代码牛仔进入同一个工程,那这个工程一定会失败,因为一个总是被另一个人对代码做的修改而干扰,他们总是拼命的在开枪射击自己搭档的脚。

当按时完成一个工程比把这个工程做好更重要的时候,把一个代码牛仔加入进去吧,这个工程会在截至日期之前完成的。代码牛仔其实就是一个吵闹版的忍者。只是忍者像做外科手术一样精准的编码,而代码牛仔像一只难以控制的公牛,会把所以挡在它面的东西顶翻。

#8:伞兵
你知道那些电影吧,就是指挥官带着机密作战计划被空降到敌人战线之后。在软件开发中,这样的人叫伞兵。伞兵是你对一个将要失败的工程的最后援助。伞兵们缺乏在一个长期任务上工作的耐心。他们最大的价值是拥有快速学习一堆完全陌生的代码并且使用它们工作的惊人能力。其他程序员也许要花几个星期或者其几个月来熟悉一个工程,以便可以有效的参与其中;伞兵们只需要几个小时或者几天。伞兵快速学会的东西也许不能让他们编写核心代码,但是,没有足够的时间形成一个固定的见解可能会帮助他在整个团队失败的地方取得成功。

#9:庸才
“足够好了”,这就是你从一个庸才那能听到的最好的话。他或者是她总是花更多的时间写出比团队中其他任何人都更差的代码。“缓慢,刚刚符合要求”就是对庸才所作的项目的描述。但庸才们总是能做的“足够好”,以至于刚好不会被解雇。

当你面试这种人的时候,他可以告诉你很多他到参与过的项目,但却很少提到他们到底在这些项目里做了什么。筛出这些庸才的方法很简单:问一下他所做工作的细节,他们会突然得了健忘症。但是,一旦让这种人进入你的组织,你可能要花好几年才能再摆脱他们。

#10:传教士
无论你在用哪种编程环境,传教士总会坚持认为如果你把现有的工具和工序抛弃掉并换成其它的一些东西,会对你有很大的帮助。传教士实际上就是理论家的反面。传教士总是直来直去,对软件开发很了解,但却很少真正的去编码。

传教士有一颗项目经理或者部门经理的心,但却缺乏足够的知识或者经验来完成这个跳跃。所以在传教士最终成为一个纯管理者角色之前,其他人不得不一直忍受传教士们对于彻底革新工作环境的尝试。

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


Stiff 对九位卓越程序员的采访
作者:Stiff
译者:flynetcn

前言: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:

去看我的博客。

注:原文中有些链接已经失效了,如果大家对大神的博客感兴趣的话,自己google一下吧,很容易找到的。如果对原文感兴趣的话,可以点击下面的地址哦。
英文原文
译文原文

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
黄索远(译)

1952年初春的早晨,由于一系列巧合,我正式进入了编程界,成为了程序员历史上第一位荷兰人。回想起来,程序员作为一种职业,是以现在很难相信的缓慢速度出现的,至少在我所了解的范围内是这样,这让人非常惊奇。那个缓慢时期的两段清晰回忆让我心存感激。

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

荷兰婚礼仪式上有要求新人陈述职业的传统,而两年后的1957年,当我结婚时我宣告自己是一名程序员。但是阿姆斯特丹的市政当局没有接受,理由是并不存在程序员这样一种职业。不管你信不信,在我婚姻证书上“职业”这一栏里,可笑的写着“理论物理学家”!

关于程序员作为一种职业在我国的缓慢出现,就说这么多了。从那时起,我见识到了外面的世界,留下的总体印象是,尽管起步的时间不同,但是其他国家的发展模式是大同小异的。

让我尝试更多地回顾下昔日的一些细节,以期更好地理解现在的情况。现在我们对问题进行分析时,应该知道,关于编程任务很多常见误解是可以追溯到很久以前的。

第一代的电子计算机是独特的机器,并且只能在各种进行开拓性试验的实验室里被找到。从人类见识了自动化计算机那天起,实现它就是对当时现有的电子技术一个巨大挑战,不过有一件事很确定,那就是我们不能否认那些致力于开发这些设备先驱们的勇气。这些设备是如此的令人惊奇,回想起来,至少是有时候,人们只能怀疑,这些机器是否真的运行起来了。最难解决的问题就在于让机器跑起来并让其保持工作秩序。一些较老的计算机科学学会的命名中依然反映着自动计算机硬件方面的当务之急,如美国计算机协会(ACM)和英国计算机协会,这些协会的名称中明确提到了物理设备。

那么可怜的程序员又是什么样的处境呢?实情是:他根本没有被人注意。一方面,第一代计算机是如此得笨重,以至于无法搬来搬去,同时,它们又需要大规模的维护,因此很自然的,人们就在发明这些计算机的实验室里使用它们。另一方面,程序员的工作既不为人所知又缺少魅力,在打动参观者的程度上,展示机器比展示几页代码要高出几个数量级。但是最重要的是,程序员以非常谦逊的眼光看待自己的工作:程序员工作的所有重要性都继承自硬件设备。因为每一台计算机都是不同的,程序员非常清楚,他的程序只有在特定计算机上才能运行,并且由于计算机的寿命有限,导致他的工作会随着机器的老化而丧失价值。最后,还有一种情况对程序员的工作态度产生了深远的影响:一方面,除了不稳定,他工作的机器一般还存在运行缓慢、内存太小等问题,这让巧妇难为无米之炊;另一方面,程序中通常又会存在少量古怪代码来应对突发的状况。在那些日子里,有很多聪明的程序员通过一些巧妙的方法,使他的设备可以完成一些本来不可能完成的任务,以这样的方式来获得智力上的巨大满足感。

关于编程的两种观点就起源于那个时期。我现在提下这件事,等下会回到这个话题。一种观点认为真正专业的程序员应该具有解决问题的头脑,并且非常喜欢聪明的伎俩;另一种观点认为,编程就是在某个方向上优化计算效率的过程。

后一种观点源自于设备落后的年代,那时候有些人简单的期望着,一旦机器变得更为强大,编程将不会成为难题,到那时想尽办法榨干机器的性能将不再有必要,这就是编程的目的,难道不是吗?但是下一个十年里发生了巨变,更为强大的机器被造出来了,不是一个数量级的强大,而是好几个数量级的强大。但是出人意料的是,我们并没有一劳永逸地解决所有的问题,反而发现自己处在了软件危机中!这是怎么回事呢?

一个小小的原因是:现代计算机在一个或两个方面比老式的计算机更难以操作。首先,现代计算机有I/O中断,中断的发生不可预知也不可重现,这个特性与能完全掌控运行过程的旧式计算机相比,是一个巨大的变化,但是这个特性会产生难以预料的逻辑错误,很多程序员花白的头发见证了这一点。第二,现在的计算机配置了多级存储设备,关于设备管理的策略,虽然已经有大量的文献,但是对我们来说仍然相当难以捉摸。关于计算机结构的变化所增加的复杂性就讲这么多了。

但是上面所举的只是“小”原因,真正大的原因是…现代计算机性能比原来强大了好几个数量级!可以不客气的说:当世上没有计算机的时候,根本就不会有编程问题;当我们有了几台性能弱小的计算机后,编程就出现小问题了,现在我们有了性能强大的计算机,编程自然变成了巨大的问题。在这样的发展过程中,电子产业非但没有解决一个问题,而是产生了问题,即使用产品所带来的问题。换种方式说,如果现有计算机性能增长了千分之一,那么社会对于使用这些机器的期望也会以同样的比例增长,而可怜的程序员会发现自己处于到底是目的优先还是方式优先的紧张选择中。硬件性能的提升,加上其可靠性甚至更急剧的提升,使得几年前程序员做梦都不敢想的问题变得可以实现。而几年后,他不得不梦见这个问题,更糟的是,他不得不将这样的梦变成现实!那么我们发现自己仍身处于软件危机中是不是一个奇迹呢?当然不是了,正如你猜测的那样,这些甚至是可以提前预知的,只不过这种小众预测的问题在于五年后你才能知道它是正确的。

接着在六十年代中期,有一件可怕的事情发生:所谓的第三代计算机出现了。官方的文献表示,性价比一直是他们主要的设计目标之一。但是如果你将机器众多组件的占空比作为“表现”的衡量标准,你会看到一个内存被必要性存疑的内部常驻活动所占据的设计。如果你对于价格的定义是硬件的价值,你会看到一个对其编程极其困难的设计:举个例子,无论对于程序员还是系统,用于执行的指令码早期绑定所带来的问题都不能真正得到解决。并且在很大程度上,这些令人不快的可能性看起来已经成为了现实。

当这样的机器宣布发售,其功能规格为人所知后,我们之中的不少人肯定相当难受,至少我是这样。第三代计算机的发行肯定会席卷计算机界,而人们更加期待它的设计能够尽量健全。但是因为这样一个有着如此严重缺陷的设计,让我感觉到计算机科学至少退步了十年:这也让我的职业生涯经历了最为黑暗的一个星期。也许最可悲的事情是,即使有了这么多年令人沮丧的经验,依然有如此多的人天真的相信计算机必须是这样。他们用机器的销量来打消自己的疑虑,并且从这种观察中得到使用这些机器是安全的错觉,毕竟,机器的设计不可能那样糟糕。但是仔细想想,这种被销量欺骗的安全感就和吸烟必须是健康的说法相差无几,因为吸烟的人很多。

正是这方面,我很遗憾,在发表对最新公布的计算机的评论时,计算机领域的科学期刊并没有习惯像其他科学出版物那样做出复查:对机器的复查至少应该同样重要。这里我要检讨:在六十年代早期,我写过这样的评论并准备提交给CACM,尽管我没有向同事们寻求建议,但他们极力主张我这样做,可我还是不敢,因为担心这样无论对我还是对编委会来说,困难都太大。是懦弱没有让我提交这样一份报告,对此我越来越自责。我预见到的困难是当时缺乏普遍接受的标准,虽然确信自己的标准是正确的,但我还是担心我的报告会被拒绝,或者被贴上“个人口味问题”的标签。我仍然认为这样的报告是及其有用的,并且渴望着它们的出现,因为它们的出现将代表着计算机界的成熟。

之所以对硬件保持上面提到那样的关注,是因为我相信影响那些使用者的思考习惯是任何计算工具最重要的作用之一,并且我有理由相信,这种影响力比预期的更为强烈。现在让我们的注意力回到软件上。

由于软件具有显著的多样性,我必须将自己限制在几个立足点上。这使得我做出的选择显得很武断,也让我觉得很痛苦,希望大家不要因此怀疑我对其他没有提到的努力的欣赏。

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

我要讲的第二个软件业的主要发展是FORTRAN的诞生。在当时这是一个伟大而冒失的计划,负责这个计划的人们值得我们大声地赞美。因为大约10年后才日渐明显的外延错误用法而去责备他们是显然不公平的:能够成功预测十年后的团队相当罕见。当我们回顾过去时,必须把FORTRAN看做一项成功但是对其产生概念基本没啥帮助的编码技术,在需求如此迫切的现在,这项技术已经过时了。我们应该尽快忘记FORTRAN,对于思想的马车而言,它不再胜任:它浪费了我们的脑力,使用它过于冒险,因此也太过奢侈。FORTRAN的悲惨命运已经因为它广泛的接受度,影响了数以千计的程序员为我们过去的错误买单。我每天都祈祷,会有更多程序员小伙伴找到从通用性的祸害中解脱出来的方法。

第三个不能忽略的就是LISP,一个完全与众不同的迷人设计。基于LISP的几个基本原则使得LISP展示出了非凡的健壮性。除此以外,LISP成为了相当多的复杂计算机载体。LISP曾经被调侃为滥用电脑的最智能方法。我想这种描述是一种很高的赞美,因为它传递了解放的气息——它已经帮助我们之中最有天赋的人思考了之前不可能思考的东西。

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

最后,尽管令人不太愉快,但我必须提及——PL/1,一门描述文档非常庞大而且复杂的编程语言。使用PL/1就像开着一架有着7000个按钮,使用开关和扳手操作的飞机。我完全不能理解怎么靠智力来把握这种完全怪异的编程语言(我们的基本工具),使之保持稳定的发展,提醒你,这已经脱离我们智力的掌控了。还有如果非要描述PL/1对其用户的影响,我脑海中最为形象的隐喻就是毒品。我记得这个出自一个自称是PL/1的忠实用户在一个高级语言的专题讨论会上做的一个演讲。但是,在这个为期一小时充满对PL/1赞美的演讲中,他希望大家添加50种新特性,却没有想过他问题的源头是这门语言已经包含了太多的特性。演讲者展示了所有令人沮丧大的症状,他陷入内心停滞,但是渴求更多。当FORTRAN被称为婴儿期的凌乱时,完整的PL/1却是危险的肿瘤,最后成长为了一种致命病毒。

关于过去的事,就讲这么多吧。但是如果我们不能从中汲取教训的话,制造错误是没有任何意义的。事实上,我觉得我们学习了如此多的错误,以至于几年后的编程可以和之前截然不同。让我简述下你们可能的未来。乍看一下,这种编程的想象也许会让你不久的将来变得非常的不切实际。所以也允许加上也许会让人得出“这个人的想象相对实际”的结论的考虑吧。

这种想象就是,在七十年代结束之前,我们有可能设计和实现那种尽量利用编程能力,开支是许多年前百分之几的系统。此外,这些系统可以几乎摆脱bug。这两项提升相辅相成。在后一个方面,软件看上去和许多其他产品不同,很多产品质量和价格是成正比的。那些想要真正有效的软件的人将会发现他们必须从找到避免大多数bug的方法开始,最后,编程过程将变得便宜。如果你想要一些有能力的程序员,你将发现他们不会浪费时间在调试上,他们不应该以调试bug作为开始。换句话说,两种目标指向同样的变化。

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

似乎有三个主要条件需要满足。一般来说,世界必须承认需要变化,第二经济需求十分强烈,还有第三,变革在技术上是可行的。让我讨论按顺序讨论一下上述三个条件。

谈到对软件更为可靠的需求,我表示完全同意。在几年前,就不一样了——讨论软件危机是对上帝的亵渎。转折点是 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.

参考:原文地址

Linux内核管理风范


Linux内核的管理风格
Linus Torvalds

这个简单文档描述Linux内核偏爱的(或编造的,取决于你问谁)管理模式。它在一定程度上是编码风格文档的影子,主要写来避免一遍又一遍回答同一类问题*。

管理风格是很个人化的,比起简单的编码风格条例更难量化,所以这个文档跟现实可能沾边也可能不沾边。它开始于游戏,但是不见得就不作数。你只有自个儿决定。
顺便说一下,我们说到”内核管理者”的时候,完全是说技术带头人,不是公司里那些作传统管理工作的人。如果你是在订单上签名的人或者对你们组的预算知道一丁半点,你几乎一定不是个”内核管理者”。这些建议对你可能适用也可能不适用。
首先,我建议你买一本《高度成功人士的七个习惯》,不-要读它,烧了。表一下决心。
(*) 这个文档不见得”回答”多少问题,更大程度上是展示我们的无知,让提问者死了这条心。

不管怎样,开讲了:

第一章:决定

每个人都觉得管理者是作决定的,作决定是很重要的。决定越大、越艰难,管理者就越伟大。这一点很深刻、很明显,但不见得正确。

事情的要义是避免-作决定的必要性。特别是,当有人告诉你”是甲还是乙,我们需要你来作决定”,你作管理的麻烦就来了。你手下的人一般比你更懂具体问题,所以要是他们找你作一个技术性的决定,你死定了。要替他们作决定,你显然水平不够。

(推论:如果你手下的人不比你更懂具体问题,你还是死定了,尽管出于完全不同的原因。说白了就是你站错了岗位,应该他们-来管理你的才华才对。)

所以要义是避免-决定,至少避免大的和艰难的决定。作小的、不重要的决定还好了,而且让你挺挺板板、面上有光。所以一个内核管理者需要的是把大的艰难的决定变成没人在乎的小事情。
帮你点拨一下,大决定和小决定的区别在于你能否事后修补得了。如果你犯错了的时候(而且你会-犯错),你能返回来弥补损失,那么你可以把任何的决定变成”小决定”。一下子,你的表现机会多了一倍:你要作两-个不重要的决定,错误决定”加上”正确决定。
而且大家甚至会认为这是领导才能(咳咳,狗屁,咳咳)。因此避免作重大决定的要点成了仅仅避免做不可逆反的事情。不要被牵引到一个无路可逃的角落里。困在角落里的耗子或许是危险的,困在角落里的管理者不过是个可怜虫。
事实上,不管怎样-,没有人会愚蠢到让一个内核管理者承担太大的财政责任,所以纠正错误一般不是多难。既然你没有机会浪费掉你倾家荡产也还不清的巨额经费,你要纠正的不过是一个技术性的决定。那就好办了:告诉每个人你是个不称职的白痴,说对不起,把你让大家上一年作的无用功都扔掉。一下子,你一年前作的决定也不见得是什么重大决定,既然能简单的撤销掉。
然而事实上,有些人搞不来这个办法。有两个原因:
(一)承认自己是傻瓜做起来蛮难的。我们都喜欢保持形象,公开认错有时候是很困难。
(二)对下级的工程师来说,被人告知自己上一年的工作落得一文不值,也是很恼火的。实际的工作结果-可以删除了事,但你可能就永久性的失去了这个工程师的信任。记住,”永久性”是我们要避免的第一件事,这样你的决定最终还是一个重大决定。
所幸的是,你对两个原因都可以棋高一着,未雨绸缪,防患未然。办法是:事先就承认你狗屁不懂,告诉大家你的决定不过是摸着石头过河,说不定就掉河里了。
你应该永远保留改变决定的权利,而且要让大家明白-这一点。而且在你做了真正的傻事之前承认你是个傻瓜要容易的多。
这样,当事情真的到了傻冒的地步,人们不过是翻下眼皮,说:”唉……真是灵验啊……”
这种事先承认不足的做法可能还会让下面真正做事的人三思而后行,想一下值不值。说回来,如果他们-都不确定是个好主意,你铁定了不应该给他们开绿灯,煽风点火。至少要让他们在开始大动作之前好好想一下。

记住:他们在细节上应该知道的比你多,而且他们一般觉得一切已在掌握之中。作为管理者,你能做的最好的事情不是给他们填充信心,而是给他们适量的批判理性。
顺便说一下,另外一个避免决定的办法是装可怜,简单地问”我们为什么不能两个都做呢?” 相信我,这个有用。如果不清楚哪条路子更好一些,他们最终会整明白的。答案或许是两帮人都挫败灰心,双双放弃。
这听起来像是个失败,但它一般是两个项目都有问题的迹象,大家无法决定的原因是双方都错了。结果是你成了智慧的舵手,而且你又避免了一个本来会死得很难看的决定。

第二章:人

大多数人都是傻瓜,当管理者就意味着你不得不和这一点打交道。或许更重要的是,他们-不得不和你-打交道。

事实证明,消除技术性问题还是容易的,消除人脑筋里的问题就没那么容易了。你就不得不忍受这些问题,他们的还有你自个儿的问题。

然而,为了做好内核管理者,最好记住不要自绝后路,伤及无辜,或树敌过众。现实是,疏远人们是蛮容易的,把他们拉拢回来就难了。因此”疏远”直接归类到”不可逆反”的事情里,就是第一章里说的大忌。

这里只有两条简单的规则:
(一)不要骂人猪头(至少不要在公开场合下)
(二)要是你忘了第一条,学会怎样道歉
第一条的问题是太容易违反,因为你有一万种骂人猪头的办法*,有时不自觉就骂了,而且几乎总是义愤填膺、义正严词。
而且你越是骂的热血沸腾(让我们来面对事实,你可以骂几乎任何-人猪头,你往往不-会骂错),事后你越难道歉。
要解决这个问题,你其实只有两条路子:
(一)成为道歉专家
(二)”遍洒博爱,处处留情”,这样没有人会觉得受到了特殊待遇。骂出新意,骂出水准,他们没准会找到艺术的享受。
第三条路子,始终如一的作谦谦君子,是行不通的。没有人会信任城府太深的人。
*保罗西蒙的歌唱道”失恋五十种”,是因为老实说,”骂一个程序员猪头一万种”没有那么押韵。不过我相信他肯定考虑过这个。

第三章:能人

尽管现实是大多数人都是傻瓜,不幸的推论包括你也是傻瓜之一,尽管我们都心安理得的自认比傻瓜高明(让我们来面对事实,没有人自认傻瓜或不如傻瓜),我们还是应该承认我们不是独步江湖,总会有一些人不像我们一样的傻瓜。一些人嫉贤妒能,另一些人从善如流。

确定你,作为一个内核管理者,属于第二种。贴紧了高手能人,因为他们会使你的工作变容易。特别是,他们将能够替你作决定,这正是事情的要义。
所以你要是发现了比你聪明的人,顺水推舟好了。你的管理职责很大程度上就成了说一下”听起来是个好主意,放手去干吧”,或者”这个不错,那个XXX怎么样呢?”。第二个版本尤其有效:你要么学到一些关于”XXX”的新东西,要么指出了聪明人都没想到的东西,表现得胸有-韬略。随便那种情况,你都是赢家。
另外一件要小心的事情是,一个人在一方面厉害不见得在其他方面也厉害。你或许煽动谁做什么,但是让我们来面对事实,他或许精通自己的一亩三分地却其他什么都做不来。好的消息是,人们自然而然的倾向于选择自己擅长的事情来做。所以你真的-煽动一下,一般不见得会造成什么不可逆反的后果,只是不要用铁扇公主的芭蕉扇来煽。

第四章:担当

事情总会出错的,大家会找人来责怪。哈,就是你了。

担当责任其实不是那么难的,尤其是当大家心里也有数,不全-是你的错的时候。这带来了担当责任的最好的方式:代人受过。你会因为挑起了担子而心安,那个真正搞砸了的家伙不会成为众矢之的而颓废,至于那个因为你的失职而丢失了半个硬盘的A片的家伙,也会嘟嘟囔囔的承认你至少没有猥猥琐琐的推卸责任。
然后,私下-告诉那个搞砸了的家伙是他搞砸了(如果你能发现他的话)。这样不仅让他以后避免重犯,而且让他知道他欠你一个人情。而且,或许更重要的是,他可能就是那个能修补事故的人。因为,让我们来面对事实,你肯定不行。
担当责任也是最初你来作管理者的原因。这是领导者的本分。大家能信任你,给你荣誉,是因为你在必要的时候能说”是我不好”。而且如果你已经遵循了前面的规则,你现在说这个应该很在行了。

第五章:禁区

比骂人”猪头”更招人恨的是用挖苦的语调骂人”猪头”。你可以为前一个道歉,后一个你都不会有道歉的机会。即使你其他方面都做的很好,他们可能也不会再听你的了。

我们都自我感觉良好,就是说当别人指手划脚的时候,真的-是可忍孰不可忍。你可能在才智品行上超出你周围所有的人,但是你要不是真的想-招惹谁的话*,不要”表现”得太明显。类似的,处理问题不要太客气或微妙。客气往往会隔靴搔痒,不得要害。就像人家说的,”在互联网上,没有人听得到你微妙”。大张旗鼓、锣鼓喧天的把你的意见摆出来,不然你没法指望大家领悟到。
一点幽默可以帮助润滑你的蛮横和说教。过分夸张到荒诞的地步,既能充分表达你的观点,又不至于让对方难堪,因为他只会认为你在发疯。这样就可以绕过我们每个人都有的、抵制批评的心理盲区。
*支一招:和你的工作不直接相关的网络论坛(译者按:Linus是说新闻组。没看到西方国家的论坛事业有中国这么发达。)是发泄的好地方。隔三岔五的,狞笑着写点侮辱人的帖子来点燃战火,会让你再次焕发青春。只是不要把战火烧到自己的老巢。

第六章:为什么是我?

既然你的主要职责好像就是代人受过,赤裸裸的展示自己如何不称职,显然的问题是:那你为什么还要做呢?
首要的是,可能有也可能没有尖叫着的小女生(或者小男生,我们不要作道学家或性别岐视)来敲你更衣室的门,作”负责人”会-给你带来巨大的个人成就感。不用说你的”领导”其实是拼命从后面追赶大家、努力跟上大家的步伐。每个人还是会认为你是”负责人”。

如果你能驾驭得了,这是一项伟大的工作。

参考:原文地址