The Art of Unix Programming
1.2 性能-时间的指数曲线对软件开发过程所引起的结果,就是每过18个月,就有一半知识会过时。Unix 并不承诺让你免遭此劫,只是让你的知识投资更加稳定。
1.4 行为的最终逻辑尽可能被推后到使用端。
最终用户永远比操作系统设计者更清楚他们究竟需要什么。
1.6 哲学
每个程序只做好一件事
假定每个程序的输出都会成为另一个程序的输入
优先使用工具而不是拙劣的帮助来减轻编程任务的负担
编程的核心是数据结构,而不是算法
策略同机制分离,接口同引擎分离
1.6.3 把复杂的交互程序跟干粗活的算法程序分离
1.6.11 设计良好的程序将用户的注意力视为宝贵的资源,只在必要时才使用
1.7 Keep It Simple, Stupid!
2.4 过分依赖任何一种技术或者商业模式都是错误的——相反,保持软件及其设计传统的灵活性才是长存之道
4.1 200-400行之间的逻辑行代码是“最佳点”
4.2.2 正交性:每一个动作(无论是API调用,宏调用,还是语言运算)只改变一件事,不会影响其它
4.2.3 不要重复自身
4.2.5 依附于被人忽略的假定将导致非正交、不紧凑的设计,项目不是失败就是成为维护的梦魇
4.3.2 薄胶合层原则可以看做是分离原则的升华
4.5 OO语言鼓励“具有厚重的胶合和复杂层次”
过多的层次破坏了透明性
就算用OO,他们(Unix程序员)也尽可能保持对象设计的整洁清晰
4.6 全局变量同时也意味着代码不能重入;也就是说,同一个进程的多个实例可能彼此干涉
API的接入点是不是超过七个?有没有哪个类有七个以上的方法?数据结构的成员是不是超过七个?
5.27 Unix 文本文件的约定 P120
6 透明性和可显性
6.1.7 把文本串放到游戏服务器内部列表中。根本不需要改动服务器代码,只要简单地在数据文件中声明就可以定义新的民族和装备。
6.2.1 太多的OO设计就像是意大利空心粉一样,把“is-a”和“has-a”的关系弄得一团糟
7 在所有种类的软件系统中,接口都是bug聚集之地
7.1 线程不是降低而是提高了全局复杂度
7.2.5 为什么fetchmail不能用管道?
因为管道是单向的。取信程序需要一个反馈来改变服务器中信的状态
7.2.6.5 本地 I/O 就是“是/否”的判断,而套接字 I/O 则是“是/否/也许”的判断。而且没有任何东西能确保交付——远端的机器说不定已经被彗星撞毁了
7.3.3 尽管线程没有快速转换进程上下文的开销,但是锁定共享数据结构以防互相干涉的开销同样昂贵
7.4 把大型程序分解为更简单的协作进程时,在进程内使用线程应该是最后一招而不是第一招。如果能使用有限的共享内存和信号量、使用 SIGIO 的异步IO或 pull/select ,而不是使用线程,就这样做吧
8.2.11 Emacs是围绕 Lisp 的语言构建而成的
8.3.1 如果我们对微型语言设计的本身采用自底向上的方法,则最终我们可能得到一种丑陋的语法,反映出一种薄弱的语言和未经仔细考虑的实现
8.3.4 宏-慎用,产生的问题比解决的问题多
10.1 对于能够可靠地进行自动检测的东西,就不要提供配置开关
11.1 最小立异原则
接口设计者(像其他程序员一样)总是不自觉地在为用户着想时聪明过头
11.2 机制,而非策略
11.4 商业世界通常一窝蜂地支持初学者模式
11.9 任何确认提示本质上也许就是接口实际上需要一个撤销命令的标志
12.2 Unix 通常带有性能剖析程序(profiler),要善加利用
12.4 往返请求的代价比计算昂贵的多。如果任何时候能让客户端不用连接服务器就可以工作,你就成功了
13.1.4 复杂度种类
偶然复杂度:违反 SPOT 原则、过早优化、非正交性
选择复杂度:方法学开销、别的一切、有效功能
本质复杂度:开发工具、核心数据结构、功能要求
14.4.2 C++的使用仍然大量集中于GUI、多媒体工具包和游戏(OO设计的主要成功领域)
C++的最佳之处是编译效率以及面向对象和泛型编程
14.4.6 Python 是主要脚本语言中效率最低,速度最慢,这是它为运行期类型多态付出的代价
Python 特别容易和 C 结合起来
对于小型项目和大量依靠正则表达式的脚本, Python 不如 Perl 表达力强,对于太小的项目,Python太过大材小用了
14.4.7 Java 程序员掉进过度OO分层这一问题的可能性似乎小一点,尽管这仍是个大问题
15.3.1 yacc 和 lex 是用来生成语言词法分析器的工具
16 Reuse: On Not Reinventing the Wheel
系统级的重用是 Unix 程序员区别于其他程序员的最重要行为特征