英文原文:Why Programming is Difficult
我曾经认为编程很容易, 但多年之后我慢慢意识到我错了: 一份程序员的工作和我理解的"写程序"是不同的。
起初我觉得编程无非就是命令计算机工作, 而这相对来说并不算难。 在工作了二十多年之后,我愈发觉得这实在是非常容易的事情。
定义1:程序是一种由输入到输出的变换。
程序员即是写程序的人,编程即是写程序的过程。
现在再让我们为上面的定义加上一些限制条件。
定义2:程序是一种满足以下条件的,由输入到输出的变换:
当添加了这些限制之后,编程就变得非常困难了。对于一些特定的情况,我们可以适当放宽以上的限制条件。下面就来介绍几种典型的情况:
我们写程序常常只是为了输出。这种情况下,输入和程序本身并不一定要考虑未来维护的问题,也不必一定要写得那么优雅并配备详尽的文档。
我写过的一本关于 Erlang 的书的排版程序就是这种情况。当这本书发表之后,再维护输入和排版程序就显得没什么必要了。只要输出看起来不错就可以了,杂乱的 XML 输入文件和测试程序不需要维护。
如果这本书再版,订正只需要稍微更改一下输入就可以了。即使输入文件没有详细的文档,这件事做起来也非常容易。
需要被维护的程序刚好和上面的情况相反。输入和程序本身要优雅,相关文档也要详尽。
我前些天和一个写网络应用的顾问聊天,他说只要程序的输出了正确的结果(网站看起来没什么问题各种功能也能正常工作),用户就认定这个项目已经完成了然后项目经理就把他加进下一个项目组里。
他们不明白对于网站来讲仅仅看起来 OK 是不够的,也根本没有预留时间给整理代码,编写文档这些对未来网站维护有帮助的事情,下一个项目就开始了。
还有三件事会使编程变得困难:
就让我们来看看程序员的时间是怎样被这些家伙吃掉的吧。
我经常要用一些别人编写的软件来解决问题,但我往往并不能够很好地理解这些程序。
一款优秀的软件有准确的文档告诉我如何使用它,但真实世界中的情况常常要糟糕得多:不是没有文档就是文档写得不准确。
文档这样写道:“依次执行 XYZ 命令,就会得到结果 PQR。”而你执行 XYZ 之后得到的结果根本不是 PQR!这种情况下你要怎么办?如果你足够走运,写这个程序的老兄就在附近,你大可以走上去掐死他;大多数人只能去 Google 一下试试运气,或者试着读一下源代码看看能否找到答案。
利用 Google 搜索一个 bug 的解决方案简直像赌博一样令人沮丧。我用 Google 搜索了半天终于发现了一个倒霉蛋也遇到和我一模一样的问题,哈哈哈哈哈。但是当我满怀期盼地点开链接的时候。。。什么都没有,这个问题还没有人解答。
为什么这个补丁别人可以用我就不行,是因为我衰神附体了吗?还是我所处的空间扭曲到正常人类世界的物理定律已经失效的地步?虽然这很令人沮丧,但不同的机器初始状态会不一样也很正常,因此能够解决别人 bug 的补丁在我的机器上可能并不适用。
有时我会这样想:要是我们都用 Smalltalk 编程,都从同样的起始状态开始运行就好了。Smalltalk 程序员一定生活在一个根本不用担心这种问题的美好的世界里,但那也只是暂时的,当他们的程序和其他语言编写的程序通讯的时候,他们终究会明白这个世界有多么的残酷。
排查程序的错误也是令人沮丧的,因为你并不清楚 bug 最后到底为什么消失了,是因为你最后一次的改动吗?还是因为你之前所有改动效果的总和?
问题的关键在于诸如此类的事情占据了程序员 60% 到 70% 的时间。我曾经花了一周才让一个出问题的 LDAP 服务器重新工作了,因为老大不让我自己写这个服务器。我在折腾了一周这个用C语言开发的,文档写得很烂的破玩意之后,终于决定把老大的话抛在脑后,用中午吃饭的时间自己写了一个 Erlang 的版本,问题才终于解决了。
我承认我写的并不是一个完整的 LDAP 服务器,但我也不需要一个完整的 LDAP 服务器,只要其中的一些命令行可以工作就可以了,这解决起来非常容易。
现在我已经不会对实现那些古董级的协议感到兴奋了,但一般说来和用别人的代码相比自己重新实现往往会节省更多的时间。
解决问题和学习是不同的
我是一个彻头彻尾的懒鬼。当我想用 Latex 插入一个图表的之前我不想先看完 391 页文档。你当然可以指责我懒惰,我也明白照理来说我应当先把那篇热情洋溢的文档读完,但我只有十分钟,根本没法读完那篇文档。
当我需要解决问题的时候,我需要的是快速的解决方案,这个时候过于冗长的说明文档对我我来说就是灾难。
以排版程序为例,我曾经在这三款软件面前摇摆不定:Tex/Latex,XSLT-FO,Erlguten。
差不多每三年我都会强烈地想使用 postscript 来写文档,每当我有这种感觉的时候,我都会深吸一口气,然后静静地等待这种感觉自己消失。
我猜詹巴蒂斯塔波多尼在 1818 年制作他的 Manuale Tipografico (詹巴蒂斯塔波多尼的 Manuale Tipografico 被称为最伟大的模式标本的书的印刷。发行追授于 1818 年在帕尔马由波多尼的忠实遗孀玛格丽特,两卷本著作中包含的 142 罗马字母琳琅满目相应斜体,许多脚本和异国情调的字体,以及鲜花和装饰品惊人的集合)无人问津,可能排版一页都要耗时一周,让机器完成枯燥而危险的任务可以使我们解放出更多的时间
我问过我的老板,他是否需要漂亮的幻灯片来演讲。他说需要,但要我明天之前给他。这让我没有合适的时间来学习 TeX (我猜可能需要一两年),没时间实现自己的排版语言(我猜需要5-10 年),没时间把它记载到附录中,我权衡了需要时间去学习的几个方案,最终选择了 PowerPoint。
恶劣的编程环境
有些工作场所的设计使编程更加困难,无隔板开放式办公室那嘈杂的环境,破坏了我们的注意力,移动电话的打扰,以及互联网都会分散我们的注意力。
幸运的是我们还有可去的地方,那就是睡觉。很多编程问题是在睡觉过程中解决的。
有两种方法:首先将考虑的问题记住,然后睡觉,第二天醒来一些问题就被解决了,So Easy;
另一种方法是睡觉前在一些论坛或者用 tweet 发个帖子,第二天已经有人将解决方法发给你了。
做一名优秀程序员需要很长的时间,你需要学习很多东西,当遇到问题的时候,你需要知道向谁请教。
惊人但是事实
当我完成本文检查内容的拼写时,但我使用 emacs-ispell 模式检查拼写,它罢工了,并显示没发现 aspell
我的 emacs 拼写检查器在本地忠实的工作了好几年。就在我抱怨生活一成不变时,它跌破我的眼镜。
我不相信上帝有恶意,也不相信我房间里左手沙发的物理定律和我右手的不同,但有间接证据表明正好相反。
我不明白我明明什么都没做,我的拼写检查器就出了问题。为了检查上次文档的拼写,我安装一个 Erlang 新版本和 Julia,并写下了一些讲义
幸运的是,11 分钟如同在 Google 赌场工作。 第二个建议性的工作:我不知道问什么我的 emacs 不能找到 aspell-生命太短,问题太莫名。
我猜有些事我们永远不知道答案。