logo资料库

Unix编程艺术.pdf

第1页 / 共513页
第2页 / 共513页
第3页 / 共513页
第4页 / 共513页
第5页 / 共513页
第6页 / 共513页
第7页 / 共513页
第8页 / 共513页
资料共513页,剩余部分请下载后查看
前言
谁应该看这本书
如何使用这本书
相关引文
本书的习俗约定
所用案例
作者致谢
目录
I Context
哲学
文化?什么文化
Unix的生命力
反对学习Unix文化的理由
Unix之失
Unix之得
开源软件
跨平台可移植性和开放标准
Internet和万维网
开源社区
从头到脚的灵活性
Unix Hack之趣
Unix的经验别处也可适用
Unix哲学基础
模块原则:使用简洁的接口拼合简单的部件
清晰原则:清晰胜于机巧
组合原则:设计时考虑拼接组合
分离原则:策略同机制分离,接口同引擎分离
简洁原则:设计要简洁,复杂度能低则低
吝啬原则:除非确无它法,不要编写庞大的程序
透明性原则:设计要可见,以便审查和调试
健壮原则:健壮源于透明与简洁
表示原则:把知识叠入数据以求逻辑质朴而健壮
通俗原则:接口设计避免标新立异
缄默原则:如果一个程序没什么好说的,就保持沉默
补救原则:出现异常时,马上退出并给出足量错误信息
经济原则:宁花机器一分,不花程序员一秒
生成原则:邂免手工hack,尽量编写程序去生成程序
优化原则:雕琢前先得有原型,跑之前先学会走
多样原则:决不相信所谓“不二法门”的断言
扩展原则:设计着眼未来,未来总比预想快
Unix哲学之一言以蔽之
应用Unix哲学
态度也要紧
历史——双流记
Unix的起源及历史,1969—1995
创世纪:1969-1971
出埃及记:1971-1980
TCP/IP和Unix内战:1980-1990
反击帝国:1991-1995
黑客的起源和历史:1961-1995
游戏在校园的林间:1961-1980
互联网大触合与自由软件运动:1981-1991
Linux和实用主义者的应对:1991-1998
开源运动:1998年及之后
Unix的历史教训
对比:Unix哲学同其他哲学的比较
操作系统的风格元素
什么是操作系统的统一性理念
多任务能力
协作进程
内部边界
文件属性和记录结构
二进制文件格式
首选用户界面风格
目标受众
开发的门坎
操作系统的比较
VMS
MacOS
OS/2
Windows NT
BeOS
MVS
VM/CMS
Linux
种什么籽,得什么果
II Design
模块性:保持清晰,保持简洁
封装和最佳模块大小
紧凑性和正交性
紧凑性
正交性
SPOT原则
紧凑性和强单一中心
分离的价值
软件是多层的
自顶向下和自底向上
胶合层
实例分析:被视为薄胶合层的C语言
程序库
实例分析:GIMP插件
Unix和面向对象语言
模块式编码
文本化:好协议产生好实践
文本化的重要性
实例分析:Unix口令文件格式
实例分析:.newsrc格式
实例分析:PNG图形文件格式
数据文件元格式
DSV风格
RFC 822格式
Cookie-Jar格式
Record-Jar格式
XML
Windows INI格式
Unix文本文件格式的约定
文件压缩的利弊
应用协议设计
实例分析:SMTP,一个简单的套接字协议
实例分析:POP3,邮局协议
实例分析:IMAP,互联网消息访问协议
应用协议元格式
经典的互联网应用元协议
作为通用应用协议的HTTP
实例分析:CDDB/freedb.org数据库
实例分析:互联网打印协议
BEEP:块可扩展交换协议
XML-RPC,SOAP和Jabber
透明性:来点儿光
研究实例
实例分析:audacity
实例分析:fetchmail的-v选项
实例分析:GCC
实例分析:kmail
实例分析:SNG
实例分析:Terminfo数据库
实例分析:Freeciv数据文件
为透明性和可显性而设计
透明性之禅
为透明性和可显性而编码
透明性和避免过度保护
透明性和可编辑的表现形式
透明性、故障诊断和故障恢复
为可维护性而设计
多道程序设计:分离进程为独立的功能
从性能调整中分离复杂度控制
Unix IPC方法的分类
把任务转给专门程序
实例分析:mutt邮件用户代理
管道、重定向和过滤器
实例分析:为分页程序建立管道
实例分析:制作单词表
实例分析:pic2grap
实例分析:bc(1)和dc(1)
反例分析:为什么fetchmail不是管线
包装器
实例分析:备份脚本
安全性包装器和Bernstein链
从进程
实例分析:scp和ssh
对等进程间通信
临时文件
信号
系统守护程序和常规信号
实例分析:fetchmail的信号使用
套接字
共享内存
要避免的问题和方法
废弃的Unix IPC方法
System V IPC
Steams
远程过程调用
线程——恐吓或威胁
在设计层次上的进程划分
微型语言:寻找歌唱的乐符
理解语言分类法
应用微型语言
案例分析:sng
案例分析:正则表达式
案例分析:Glade
案例分析:m4
案例分析:XSLT
案例分析:The Documenterls Workbench Tools
案例分析:fetchmail的运行控制语法
案例分析:awk
案例分析:PostScript
案例分析:bc和dc
案例分析:Emacs Lisp
案例分析:JavaScript
设计微型语言
选择正确的复杂度
扩展和嵌入语言
编写自定义语法
宏——慎用
语言还是应用协议
生成:提升规格说明的层次
数据驱动编程
实例分析:ascii
实例分析:统计学的垃圾邮件统计
实例分析:fetchmailconf中的元类改动
专用代码的生成
实例分析:生成ascii显示的代码
实例分析:为列表生成HTML代码
配置:迈出正确的第一步
什么应是可配置的
配置在哪里
运行控制文件
实例分析:.netrc文件
到其它操作系统的可移植性
环境变量
系统环境变量
用户环境变量
何时使用环境变量
到其它操作系统的可移植性
命令行选项
以-a到-z的命令行选项
到其它操作系统的可移植性
如何挑选方法
实例分析:fetchmail
实例分析:XFree86服务器
论打破规则
接口:Unix环境下的用户接口设计模式
最小立异原则的应用
Unix接口设计的历史
接口设计评估
CLI和可视接口之间的权衡
实例分析:编写计算器程序的两种方式
透明、表现力和可配置
Unix接口设计模式
过滤器模式
Cantrip模式
源模式
接收器模式
编译器模式
ed模式
Roguelike模式
“引擎和接口分离”模式
配置者/执行者组合
假脱机/守护进程组合
驱动/引擎组合
客户端/服务器组合
CLI服务器模式
基于语言的接口模式
应用Unix接口设计模式
多价程序模式
网页浏览器作为通用前端
沉默是金
优化
什么也别做,就站在那儿
先估量,后优化
非定域性之害
吞吐量和延迟
批操作
重叠操作
缓存操作结果
复杂度:尽可能简单,但别简单过了头
谈谈复杂度
复杂度的三个来源
接口复杂度和实现复杂度的折中
本质的、选择的和偶然的复杂度
映射复杂度
当简洁不能胜任
五个编辑器的故事
ed
vi
Sam
Emacs
Wily
编辑器的适当规模
甄别复杂度问题
折中无用
Emacs是个反Unix传统的论据吗
软件的适度规模
III Implementation
语言:C还是非C
Unix下语言的丰饶
为什么不是C
解释型语言混合策略
语言评估
C
C实例分析:fetchmail
C++
C++实例分析:Qt工具包
Shell
案例分析:xmlto
实例分析:Sorcery Linux
Perl
小型Perl程序案例分析:blq
大型Perl实例分析:keeper
Tcl
实例分析:TkMan
Moodss:大型Tcl案例分析
Python
小型Python案例分析:imgsizer
中型Python案例分析:fetchmailconf
大型Python案例分析:PIL
Java
案例分析:FreeNet
Emacs Lisp
未来趋势
选择X工具包
工具:开发的战术
开发者友好的操作系统
编辑器选择
了解vi
了解Emacs
非虔诚的选择:两者兼用
专用代码生成器
yacc和lex
实例分析:fetchmailrc的语法
实例分析:Glade
make:自动化编译
make的基本理论
非C/C++开发中的make
案例分析:make用于文档转换
通用生成目标
生成Makefile
makedepend
Imake
autoconf
automake
版本控制系统
为什么需要版本控制
手工版本控制
自动化的版本控制
Unix的版本控制工具
源码控制系统(Source Code Control System, SCCS)
修订控制系统(Revision Control System, RCS)
并发版本系统(Concurrent Version System, CVS)
其它版本控制系统
运行期调试
性能分析
使用Emacs整合工具
Emacs和make
Emacs和运行期调试
Emacs和版本控制
Emacs和Profiling
像IDE一样,但更强
重用:论不要重新发明轮子
猪小兵的故事
透明性是重用的关键
从重用到开源
生命中最美好的就是“开放”
何处找
使用开源软件的问题
许可证问题
开放源码的资格
标准开放源码许可证
何时需要律师
IV Community
可移植性:软件可移植性与遵循标准
C语言的演化
C语言标准
Unix标准
标准和Unix之战
庆功宴上的幽灵
开源世界的Unix标准
IETF和RFC标准化过程
规格DNA,代码RNA
可移植性编程
可移植性和编程语言选择
C的可移植性
C++的可移植性
Shell的可移植性
Perl的可移植性
Python的可移植性
Tcl的可移植性
Java的可移植性
Emacs Lisp的可移植性
避免系统依赖性
移植工具
国际化
可移植性、开放标准以及开放源码
文档:向网络世界阐释代码
文档概念
Unix风格
大文档偏爱
文化风格
各种Unix文档格式
troff和Documenter's Workbench Tools
TEX
Texinfo
POD
HTML
DocBook
当前的混乱和可能的出路
DocBook
文档类型定义
其它DTD
DocBook工具链
移植工具
编辑工具
相关标准和实践
SGML
XML-DocBook参考书籍
编写Unix文档的最佳实践
开放源码:在Unix新社区中编程
Unix和开放源码
与开源开发者协同工作的最佳实践
良好的修补实践
发送补丁而不是完整档案包或文件
发送针对当前版本代码的补丁
不要包含可生成文件的补丁
不要发送与只是优化RCS或者的补丁段
使用-c或-u格式而不是缺省的(-e)格式
在补丁中包含文档
在补丁中包含解释
在代码中包含有用的注释
如果补丁被拒绝,别往心里去
良好的项目、档案文件命名实践
使用GNU风格的命名法:主干加major.minor.patch的编号法
尊重适当的本地约定
努力选择唯一且容易键入的名称前缀
良好的开发实践
不要依赖专有代码
使用GNU自动工具
先测试再发布代码
发布前对代码进行健全检查
发布前对文档和README进行拼写检查
推荐的C/C++移植性实践
良好的发行制作实践
确保打包文件总是解包到单一的新目录下
包含README文件
尊重和遵从标准文件命名实践
为可升级性设计
在Linux提供RPM
提供校验和
良好的交流实践
在Freshmeat上发布通告
在相关的主题新闻组上发布通告
建立一个网站
提供项目邮件列表
发布到主要的档案站点
许可证的逻辑:如何挑选
为什么应使用某个标准许可证
各种开源许可证
MIT或者X Consortium许可证
经典BSD许可证
Artistic许可证
通用公共许可证
Mozilla公共许可证
未来:危机与机遇
Unix传统中的本质和偶然
Plan 9:未来之路
Unix设计中的问题
Unix文件就是一大袋字节
Unix对GUI的支持孱弱
文件删除不可撤销
Unix假定文件系统是静态的
作业控制设计拙劣
Unix API没有使用异常
ioctl(2)和fcntl(2)是个尴尬
Unix安全模型可能太过原始
Unix名字种类太多
文件系统可能有害论
朝向全局互联网地址空间
Unix的环境问题
Unix文化中的问题
信任的理由
附录
参考文献
unix 编程 艺术 OCR 识别 + 精确校对版 Eric S. Raymond1 德山书生2 版本: 0.02 1 作者:埃里克·斯蒂芬·雷蒙(Eric Steven Raymond,著名黑客。) 2 官方英文网站,姜宏 2005 年翻译,有些小地方修改,以官方英文网站为准。编者邮 箱:a358003542@gmail.com。
前言 与其说 Unix 是个操作系统,不如说是一部口 述历史。 —NeaJ Stephenson 知识和专能差异巨大,凭借知识可以推断出该做什么,而专能让你甚至在无意之 间,条件反射似的把事情做好。 这本书确实有关“知识”,但更着眼于“专能”。你将学到那些 Unix 专家们都 不自知的 Unix 开发知识。少一点技术,多一些共享文化:显见和隐微的,直观和潜 流的——这是本书和大多数 Unix 书籍不同的地方——不止于方法,更重乎理念。 理念于实用大有裨益,有太多设计不良的软件:体积臃肿,难于维护、移植和扩 展——这些都是蹩脚设计的症候。我们希望本书的读者能品出什么是 Unix 所教示的 良好设计。 本书分为四部分:场景、设计、工具和社群。第一部分(场景)涉及哲学和历 史,为后续内容埋下伏笔。第二部分(设计)将 Unix 哲学的原理细分为有关设计与 实现的、更专门的建议。第三部分(工具)着眼于 Unix 所提供的工具,可助你解决 问题。第四部分(社群)则讲述人与人之间的事务与约定,而这正是 Unix 文化拥有 高效能的原因。 这本书是关于共享文化的,我从未想像过独自完成它。你会发现正剧中包含数位 Unix 资深专家的客串演出,正是这些人塑造了 Unix 的习俗。本书曾有过公开大范围 的审阅过程,这期间我邀请这些明星人士对书稿进行评审与研论。这些意见没有湮没 在本书定稿中,而你可以在书中聆听到他们的真实声音:无论是为本书呐喊助阵、还 i
第一节 谁应该看这本书 是摇头反对。 本书中用到人称“我们”时,我并不是虚张声势,仅以此说明这是整个社群都清 楚明了的事实。 因为本书着力传递文化,因此加入了很多野史和坊间传说,这在技术书中并不多 见。希望你喜欢,这些东西其实是 Unix 程序员的教养。须弥不重,芥子不轻。我们 希望以这种方式更好地讲述故事。了解 Unix 的由来和变迁,会培养你对 Unix 风格 的直觉。 同样地,基于此,我们不打算使用回述历史的腔调。你会发现本书参考了众多时 下信息。我们不希望给你一种错觉:书里说的都是亘古不变的终极真理。参考时下的 信息这一做法,也提醒读者,三十年河东,三十年河西,眼前所见,也许过不了多久 就会过时,而需要重新检省。 另外,本书不是 C 教程,不是 Unix 命令和 API 的手册,不是 sed/yacc/Perl/Python 的语言参考,也不是网络编程入门,更不是巨细靡遗的令人 费解的 X 指南。本书也不打算带你巡游 Unix 内幕和体系。有很多其它的好书涵盖这 些领域,本书会在适当的时候告诉你该看哪些。 在这些技术细节外,Unix 文化有一个未见诸笔端的行工传统,以熟练工的考量, 它已经有几百万人年的发展3。本书即立足于这样一个信念:领会此传统,并将它的设 计手法应用到手边,你将成为更好的程序员和设计师。 构成文化的是人,一直以来,获知文化的方式大约是口口相传、潜移默化。本书 不打算取代人际的文化传播,但可以促进这一过程,使你能俯耳倾听他人的心声。 0.1 谁应该看这本书 如果你是个 Unix 编程老手,经常教导菜鸟,或者与人进行操作系统论战时无法 阐明使用 Unix 方案所带来的好处时,可以看看这本书。 3 从 1969 到 2003 年,35 年时间可不算短。以这期间 Unix 站点数量的年度曲线计算, 人们在 Unix 上耕作了约有 5000 万人年。 ii
第二节 如何使用这本书 如果你是个 C、C++ 或者 Java 程序员,有其它操作系统的开发经验,现在轮到 你开展一个 Unix 项目时,可以看看这本书。 如果你是个初级或者中级水平的 Unix 用户,但是没什么开发经验,想学习在 Unix 下如何高效地设计软件时,可以看看这本书。 如果你不在 Unix 下编程却发觉 Unix 的传统给你带来某种启迪,那你就对了, Unix 哲学适用于其它的操作系统。因此我们会花比其它 Unix 书籍更多的篇幅关注非 Unix 环境(特别是微软的操作系统);当所用到工具或者案例可用于其它操作系统 时,我们会告诉你。 如果你是一个系统架构师,正为通用市场或垂直应用准备平台方案或实现策略时 可以看看这本书。本书将帮助你了解 Unix 作为开发平台的强大功能,以及开放源码 这个 Unix 的传统所带来的开发方式。 如果你想学到 C 编程的细节或者想知道怎么用 Unix 内核 API,本书可能不适合 你。Advanced Programming in the Unix Envirortment [Stevens92] 是探究 Unix API 的经典名著;The Practice of Programming [Kernighan-Pike99] 是每个 C 程序员的必读书目(任何语言的程序员都该看看这本 书)。 0.2 如何使用这本书 这本书既重实践,更富理念:既包含警世格言,又不忘检点 Unix 开发中的特殊 案例。在每个警句前后,都有生动实例阐明其由来,这些例子绝不来自小儿科式的示 例程序,而均出自真实世界满眼所见的运行代码。 我们着力避免以大量代码或者规范文件来胡乱凑数,当然这么做会让本书的写作 轻松许多(某些地方或许读起来也更轻松)。绝大多数编程书籍只授你以鱼,而本书 避免这种做法,力求培养读者“探求事情何以如此”的感知力。 正由于此,本书会时常请你阅读代码与规范文档,它们中极少量的内容会附在书 中,其余部分我们会在举例时告诉你如何从网上获取。 从这些范例中汲取养分,将有助你将所学原则消化变为疱丁之技。如果你能就着 一部跑在 Unix 系统上的网页浏览器来读书,是再理想不过的了。任何 Unix 系统都 iii
第三节 相关引文 适合,但是我们将要研究的案例大多都会预装在、或者可以从 Linux 系统上获得,书 中会提示请你浏览或亲身感受它们。这些提示通常是按部就班的,跑开玩一会儿并不 会打散整个讲述过程的连续性。 注意:我们虽力求,但无法给你打保票,声称我们所引用的 URLs 稳定可用。如 果你发现某个引用连接已陈旧过时,来点常识,用你喜爱的搜索引擎来个短语搜索。 如有可能,我们会在所引用的 URLs 附近给出如何搜索的提示。 大多数缩写形式会在首次出现时伴随其全称。为方便起见,我们在附录中提供了 名词对照表。 交叉索引通常以作者名字为主导词。带编号的脚注是那些可能会扰乱你阅读正 文,或者是易变的 URLs; 也可能是旁征博引的战争故事或者笑话4。 为了使这本书不至于让非技术人员太过难读,我们邀请了一些非程序员试读,并 指出一些晦涩但起贯穿作用的词汇。我们把那些编程老手不太会需要的名词解释也放 在脚注中。 0.3 相关引文 一些 Unix 早期拓荒者的著名论文和书籍,比如 Kernighan 和 Pike 的《The Unix Programming Environment》[Kernighan-Pike84] 就是其中佼佼者,被世 人尊为圭臬。而今看来此书廉颇老矣,它没提到 Internet、万维网以及诸如 Perl、 Tcl 和 Python 这些解释型语言的新秀。 写 作 本 书 的 中 途 我 们 借 鉴 了 Mike Gancarz 的 《The Unix Philosophy》 [Gancarz]。这本书在它的覆盖范围内极其优秀,但是我们觉得需要更多内容才能反 映出事情的全貌。尽管如此我们仍对此书作者心存感激,他愈发使我们知道最简单的 Unix 设计手法就是最持久耐用的。 《The Pragmatic Programmer》[Hunt-Thomas] 是 一 本 关 于 良 好 设 计 的 书,文风机智诙谐,它与本书相比,倾向于软件设计工艺的另一个层面(更注重编 4 这个特别的脚注献给 Terry Pratchett,他对脚注的用法简直是……绝了。 iv
第四节 本书的习俗约定 码,而少着墨于高层面的问题划分)。作者的哲学是其 Unix 领域耕耘的成果,也是 本书内容极好的补充。 《The Practice of Programming》[Kernighan-Pike99] 包含了一些与《The Pragmatic Programmer》共通的内容,但更钻入 Unix 传统的深处。 最后(明知道会激怒你),我们推荐《Zen Flesh,Zen Bones》 [Reps-Senzaki],一部重要的佛教禅宗本源的合集。对禅的引用书目遍布全书。我们 将这些书目包含进来,是因为禅为表达某种想法提供了丰富的语汇,而在软件设计中 却很难烂熟于心。信奉宗教的读者,请您不要把禅当成宗教,它是一种心灵鸡汤似的 东西,纯净而没有神灵的干扰——此即是禅。 0.4 本书的习俗约定 术语“UNIX”技术上和法律上讲,是 The Open Group 的商标,并且应该仅 限于那些通过 The Open Group 严格的“符合标准”认证的操作系统。本书中我们 使用其较宽松的定义,即大多数程序员所指的,Bell 实验室 Unix 代码的后裔或旁 支。在这个意义下,Linux(大多数例子都举自它)也算是一种 Unix。 本书也使用了 Unix 手册页 (manual page) 的传统,即以括号括起来的手册节 号来标记 Unix 设施。通常用于强调一个 Unix 命令首次出现。比如“munger(1)” 可解读为“munger 程序加入存在于你的系统中,其文档位于 Unix 手册页的第 1 节”。第 2 节是 C 的系统调用,第 3 节是 c 的库函数调用,第 5 节是文件格式与协 议,第 8 节是系统管理工具。其它节号本书未曾用到,其定义在各个 Unix 系统各有 不同。在你的 Unix 外壳提示符下输入man 1 man(老式的 System VUnix 系统可 能要输入man -s 1 man)以获得更多信息。 有时我们会提及某个 Unix 程序(比如 Emacs),后面没有手册节号而且首字母 大写。这意味这个名字代表一族 Unix 程序,其基本功能相同,而我们将讨论其通用 特性。比如 Emacs,就包含了 xemacs。 本书很多地方我们同时给出了老式 (old school) 和新式 (new school) 解法。 new-school 和 rap 音乐一样,开始于 1990 年前后。在这个含义下,我们往往把它 与脚本语言、图形用户界面、开放源码的 Unix 和万维网联系起来。Old-school 指代 1990 年以前(特别是 1985 年以前)的世界:昂贵的共用计算机、专属的 Unix, v
第五节 所用案例 shell 脚本和无所不在的 C。值得指出这些差异,机器越来越便宜,内存多了起来, 这些有如暗流,渐渐影响着 Unix 编程的风格。 0.5 所用案例 很多编程书籍为证明某一观点而特地造出一个范例,你手中这本书不这么干。我 们的案例研究均来自真实世界,在生产环境中工作已久。下面是一些主要案例: cdrtools/xcdroast 这两个独立的项目通常被一并使用。cdrtools 是一组刻盘工具 (用关键字”cdrtools” 可以在网上找到)。xcdroast 是 cdrtools 的图型界面 前端,其项目网站在这里。 fetchmail fetchmail 用于从远程邮件服务器上收信,支持 POP3 和 IMAP 邮箱协 议。这是它的主页,也可以用关键字”fetchmail” 从网上找到。 GIMP GIMP(GNU Image Manipulation Program,GNU 图像处理程序)是 一个全特性的绘画和图像处理程序,可对多种图像格式进行复杂处理。其源码可 从GIMP 主页获得(也可以通过关键字”GIMP” 从网上搜到)。 mutt mutt 邮件客户端是目前各类基于文本的邮件客户端程序中的翘楚,提供对 MIME(Multipurpose Internet Mail Extensions)、个人隐私辅助程序,如 PGP(Pretty Good Privacy) 和 GPG (GNU Privacy Guard) 等特性的绝佳支 持。其源码和二进制可执行文件可以从Mutt 项目主页获得。 xmlto xmlto 可 将 DocBook 和 其 它 XML 文 档 以 多 种 格 式 渲 染 输 出, 包 括 HTML、纯文本和 PostScript。其源码和文档可在xmlto 主页获得。 为了将读者理解本书例子所要阅读的代码量降低到最小程度,我们尽量挑选那些 可重复使用、并能体现多种不同设计原理和设计实践的案例。出于同样原因,很多示 例来自于我本人的项目。我没想说这些例子最为恰当,只是我觉得它们对阐述我的观 点非常有用。 vi
第六节 作者致谢 0.6 作者致谢 各位客串贡献者 (Ken Arnold, Steven M. Bellovin, Stuart Feldman, Jim Gettys, Steve Johnson, Brian Kernighan, David Korn, Mike Lesk, Doug McIlroy, Marshall Kirk McKusick, Keith Packard, Henry Spencer, and Ken Thompson) 为本书增添极大价值。特别是 Doug McIlroy,给予本书恪尽职责、鞭 辟入里的评注的同时,也展现了他在 30 年前管理最原始的 Unix 研究组时鞠躬尽瘁 的高风亮节。 我要对 Rob Landley 和我的妻子 Catherine Raymond 致以特别感谢,他们都 不厌其烦地逐行对本书手稿进行审阅。Rob 的深富洞察力的细致评述激励我在最终 稿中加入了一整章内容,他为本书的组织结构和取材范围贡献极多。如果他把所给予 的改进意见落在笔端,那他无愧于本书的合著者。Cathy 代表读者中非技术人员的一 群,如果那些非程序员读者觉得本书并不难读,那全是她的功劳。 写作的五年间,本书从不少人的讨论意见中获益良多。Mark M. Miller 使我对 线程有了更深的认识。John Cowan 教给我不少接口设计方式,并起草了 wily 和 VM/CMS 的学习案例。Jef Raskin 告诉我 the Rule of Least Surprise 的由来。 The UIUC System Architecture Group 对前几章给出的反馈弥足珍贵,What Unix Gets Wrong 和 Flexibility in Depth 两节是他们直接激励的结果。Russell J. Nelson 提供了 Bernstein chaining 的素材。第三章中 MVS 学习案例大部分材 料来自 Jay Maynard。Les Hatton 对语言一章给出很多有益的建议,并促使我写成 第 4 章中 Optimal Module Size 的部分内容。David A. Wheeler 贡献了很多发人 深省的批判,以及一些学习案例(特别是设计部分中的)素材。Russ Cox 帮助我对 Plan 9 的调查。Dennis Ritchie 纠正了我的一些错误的 C 历史观念。 成百上千的 Unix 程序员,人数太多以至于无法在此列出他们的名字,在 2003 年 1 月到 6 月间的公开审阅过程间给了我建议和评论。开放的同级复审这一过程让我 觉得紧张刺激而回报极多。当然,任何最终书稿中残留的错误都是我自己的责任。 “把事情说透”的风格,以及其它一些考虑因素,是受到了“设计模式运动”的 影响;说实话,我对到处堆砌 Unix 设计模式这种做法深不以为然。我对此运动的 中心教条不敢苟同,并且没觉得把设计模式严格付诸实用有什么必要,也不想背上 这种思想的包袱。尽管如此,我的行事方法仍然受到 Christopher Alexander 工作 vii
分享到:
收藏