📄 6 basics.txt
字号:
基本Unix哲学
“Unix哲学”起源于Ken Thompson在早期关于如何设计一个小型但是有用而且服务接口清晰的操作系统的思考。随着人们对如何使得Thompson设计发挥最大效力的学习,Unix文化随之诞生并成长,并从各种途径汲取养份。
Unix哲学并不是一个形式化的设计方法。它从不在理论上宣称可以生产出更好的软件。也不能妄想指望它在一个很短的期限里使用糟糕的项目管理和廉价程序员做出一个极俱重新而又可以信赖的软件。
Unix哲学(以及其它领域内被认为是成功的“民间”传统)是自下而上的,而非相反。它注重实效并且基于经验。你不能在正式的方法和标准中找到它们,它们属于隐性、反身性知识。
Doug McIlroy,Unix管道的发明者也是Unix传统的奠基人之一,说
(i)让每一个程序只很好得做一件事情。当出现新工作的时候应该重组已有的程序而不是通过添加新特性使得原有程序变得复杂。
(ii)每个程序的输出应该可以成为另一个程序的输入,甚至一个未知程序。不让让彼此无关的消息混乱你的输出。尽量避免二进制输入格式。不要强求交互式输入方式。
(iii)设计和建造软件,包括操作系统,应尽早规划好。对于拙劣的部分不要犹豫不决甚至重写它们。
(iv)使用工具可以减轻编程负担,即使你可能决定这些工具在建造后只使用几次。
他后来又这样总结:This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a
universal interface.
Rob Pike,一位伟大的C语言大师,从一个略微不同的角度给出了一些C编程的注解:
规则1:你无法预料一个程序在何处花费时间。瓶颈常会发生在出人意料的地方,所以在你能证明瓶颈所在之前,不要做第二次无谓的猜想。
规则2:测量。在你测量之前不要盲目追求速度,除非某个部分的代码淹没了其它的。
规则3:在n很小的时候,一个新异的算法会很慢,而且通常n不会很大。这些算法会有很大的常数。除非你确信n会很大,否则不要使用。(即使n很大,也先适用规则2)
规则4:新异的算法要比简单算法大得多,并且很难实现。尽量使用简单得算法和简单得数据结构。
规则5:数据支配。如果你准确选择了数据结构并正确组织它们,那么算法很可能已经自动构筑完成。数据结构,而不是算法适编程的重点。
规则6:没有其它规则。
Ken Thompson,Unix得设计和缔造者之一,用了禅宗里得一句话进一步描述了上面得规则4:
When in doubt,use brute force(告诉我谁把佛经翻译成了英语,我去杀了他)
更多得Unix哲学隐含在先哲们的行为以及Unix本身,而不是在先哲们留给我们的话语。纵观全局,我们可以总结出一部分思想:
1 模块化原则:编写简单的组件,用整齐的接口让它们互联。
2 清晰性原则:清晰要比灵巧重要。
3 整合化原则: 新设计的程序要考虑和其它程序共同工作。
4 分离性原则: 让机制与策略分离;让接口同引擎分离。
5 简单化原则: 为了简单而设计;只在你确信必要的地方增加复杂度。
6 吝啬性原则: 只有被证明了其它西西无法完成工作时才编写“大”程序。
7 透明化原则: 设计一个高度可见的程序可以使检查及debugging更容易。
8 健壮性原则: 健壮性是透明化以及简单化的产物。
9 Rule of Representation:Fold knowledge into data so program logic can be stupid and robust.
10 最小立异化原则: 在接口设计方面,一定不要总想标新立异。
11 安静性原则: 当一个程序没有什么值得炫耀时,就不要炫耀。
12 修复原则: 是的,一旦当你不得不面对失败时,失败就会变得愈发喧闹。
13 经济性原则: 程序员的时间是宝贵的,把它让度于机器时间。
14 生产化原则: 避免手工hacking操作;尽可能让程序完成编程工作。
15 优化性原则: 先做模具再打磨润色;先让程序工作,然后优化它。
16 多样化原则: 千万不要信赖包治百病的药。
17 控制性原则: 多为将来考虑,因为它会比你预料更快地来到现实。
如果Unix对你还是陌生地,这些原则值得你去沉思。软件工程的教科书会也向你夸耀这里的多数原则;但是大多数操作系统缺少好的工具和传统,所以这些平台上的程序员根本无法应用它们。这些程序员不得不接受生硬的工具,坏的设计,疲劳工作以及过度膨胀的代码,甚至习以为常(他们甚至不知道Unix爱好者为什么如厌恶他们的工作和习惯)。
模块化原则:编写简单的组件,用整齐的接口让它们互联。
Brian Kernighan曾经总结说,“复杂度控制是计算机编程最重要的事情。”测试(debugging)决定了整个开发时间。好的方法可以事半功倍。
汇编器,编译器,流程图,结构化编程,“人工智能”,第四代语言(译者注:指各类*nix脚本语言),面向对象,以及不计其数的软件工程方法都试图并宣称解决这个问题,而然只要提升程序的复杂度,这些方法依然会因为人脑的限制而失败,在Fred Brooks看来,不存在“银弹”。
构筑一个复杂软件的唯一途径就是降整体的复杂性分担到一个个通过良好定义的接口互联的简单模块,多数问题是局域性的,这样完全可以修改出问题的模块而不破坏整体。
清晰性原则:清晰要比灵巧重要
软件的维护是重要的并且昂贵的,写出的程序并是仅仅给执行它的计算机处理,更重要的是要给你的人类朋友看,给那些将来维护软件的人看(这其中也包括你自己)。
Unix传统中,注释你的代码只是一部分。好的Unix方法同样会注重于你的算法和实现是否有利于将来的维护。为了一点点儿性能上的优势,而增加大量的复杂性是一桩糟糕的买卖。复杂的代码容易窝赃bug,更会让维护人员头疼。
优雅而简洁的代码,不易破裂且让修改者很容易维护。这点非常重要,特别是当这个维护者是几年后的你。
不要试图阅读那些复杂的代码超过三次。一次就读懂或许是侥幸,如 果你发现很长一段时间后必须再次看它,而你已经忘记了细节。是时 候为它编写注释了,这会让你第三次阅读时轻松很多。
-- Henry Spencer
整合化原则: 新设计的程序要考虑和其它程序共同工作
如果你编写的程序彼此间不能通讯,那么将无法避免过度的复杂性。Unix传统强烈期望程序可以读、写简单的、基于文本和流式以及设备无关的格式。经典的Unix中,有大量的程序作为过滤器(filter)出现,过滤器从一个程序获得文本输入处理后再将文本输出。
出现这一情况并不是Unix程序员都不喜欢图形用户界面。而是因为如果不用字符流,程序间很难挂钩。
字符流作为消息传递的Unix工具是面向对象的。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -