《UNIX编程艺术》-笔记

2016-05-17  本文已影响397人  简单的土豆

I-场景

1. 哲学
2.历史–双流记

本章主要回顾UNIX的历史,来阐明如今的UNIX文化为什么呈现当前的状态。 两个历史分别是UNIX的起源和历史以及黑客的起源和历史

3. 对比:Unix哲学同其他哲学的比较

II–设计

4. 模块化:保持清晰,保持简洁。

早期的Unix程序员擅长模块化是因为他们被迫如此,如果没有良好的架构,操作系统就会崩溃。
封装良好的模块,不会过多向外部披露自身的细节,不会直接调用其他模块的实现码,也不会胡乱共享全局数据。
具有最佳尺寸的模块并不意味着代码有高质量,还得考虑紧凑性和正交性。
紧凑性就是一个设计能否装入人脑。比如一个设计有经验的用户不需要操作手册,这个设计就是紧凑的。
正交性是指任何操作均无副作用,每一个动作只改变一件事,不会影响其他。
不要重复自身(don’t repeat yourself)。
软件的分层:自顶向下和自底向上。 当自顶向下和自底向上发生冲突时,顶层的应用逻辑和底层的域原语集必须用胶合逻辑层来进行阻抗匹配。 胶合层是个挺讨厌的东西,必须尽可能薄。
OO语言使抽象变得容易,但是过多的层次破坏了透明性,我们很难看清层次,无法理清代码的运行过程。
单个函数与其说是行数计算问题,不如说是内部复杂度性的问题(比如说局部变量太多、代码存在太多缩进)。

5. 文本化:好协议产生好实践

设计文件格式和应用协议需要考虑的重要方面:互用性、透明性、可扩展性以及经济型。
使用二进制的唯一正当理由:处理大批量的数据集或者关心时间或指令开销。
数据文件元格式有多重不同的元格式,比如DSV、RFC 822、Cookie-Jar、Record-Jar、XML、Windows INI等;
应用协议如果是文本格式的,凭肉眼可以很容易地分析,很多事情变得容易。可以看看SMTP、POP3和IMAP三种经典的应用协议。
应用协议元格式:尽管网络带宽比存储昂贵许多,需要重视事物处理的经济性,但是文本格式的透明性和互用性优势还是十分显著,大多数设计者还是选择了采用可读性更高的文本格式。比如HTTP协议、BEEP协议、XML-RPC/SOAP/Jabber协议。

6.透明性:来点光

在第五章中,讨论了数据格式和应用协议进行文本化的重要性,文本化让透明性和可显性的品质得到了提升。 * 如果实际上能够预测到程序行为的全部或大部分情况,这个程序就是透明的; * 如果程序可以帮助人们建立“做什么、怎样做”,这个软件系统就是可显的。比如对用户来说,文档有助于可显性; 对程序员而言,好的命名规范有助于提高可显性。 * 要追求代码的透明,最有效的方法很简单,就是不要在具体操作的代码上叠放太多的抽象层。 * 透明的系统在bug发作时,更容易实施恢复措施;同时,透明的系统更容易让人理解,从而更加方便维护。

7. 多道程序设计

UNIX最具特点的程序模块化方法就是将大型程序分解成多个协作进程。
多个并发进程除了带来模块化的好处之外,另一个原因是为了更强的安全性。
UNIX IPC:把任务转给专门程序(shell out)、管道/重定向(管道主要缺点是单向性,命名管道可以作为两者间的配接器)、从进程、对等进程(临时文件、信号、套接字、共享内存)。

8. 微型语言:寻找歌唱的乐符

UNIX班有个长期传统,存在小型的、为专门应用领域特制、大量减少程序行数的语言。 比如无数Unix排版语言(troff/pic)、shell使用程序(awk/sed/dc/bc)和软件开发工具(make/yacc/lex等)。 微型语言与脚本语言之间的界限都很模糊。 * 一切可计算的问题都可以计算,叫做图灵完备。 * 明白微型语言在什么时候什么场景下使用。 * 某些情况下,需要我们我们去设计一个微型语言。 首先要尽可能保持微型语言的简单(复杂度),思考能否通过扩展或者嵌入现有脚本语言来实现自己的微型语言(这是实现命令性语言的正确方法),慎用宏。

9. 生成:提升规格说明的层次

数据比程序逻辑更易驾驭,更加直观,透明性和清晰性方面更胜一筹。
数据驱动编程,将代码和数据结构划分清楚,在改变程序逻辑时,只要改变数据结构而不用修改代码。
专用代码的生成,比如用工具生成HTML代码。尽可能少干活,建设性的懒惰是大师级程序员的基本美德之一。

10.配置:迈出正确的第一步

配置在哪里?在下面这些地方,查询通常按照下面的顺序进行,后面的设置会覆盖前面的设置。
运行控制文件,在/etc/目录下。
环境变量,系统环境变量、用户环境变量。
命令行选项
上述配置是从最不易改变到最易改变的顺序排列的。

11. 接口:Unix环境下的用户接口设计模式

程序的接口就是程序同用户或者其它程序通信的方法总和。
最小立异原则:少来标新立异,是所有接口设计中的通用原则,且并非仅局限于软件设计。一心不能二用,应该把中心放在接口所属的任务上。而这个原则,也不应被理解为机械的保守主义。 如有可能,尽量允许用户将接口功能委派给熟悉的程序来完成,不能委派时就效仿。
Unix程序中存在丰富的接口风格:面向行的、面向屏幕字符阵列的和基于X的,不同的接口风格,适用于不同的任务。
接口的几种度量标准:简洁、表现力、易用、透明性和脚本化能力。
CLI和可视化接口之间的权衡。命令行更具表达力,尤其是针对复杂的任务,同时具有高度的脚本化能力,但是CLI需要费劲地记忆(易用性低),并且透明性也非常低。比如说数据库的SQL语句和图形界面操作来说,可以很明显看出二者之间的差别,同样命令行的计算器和图形界面的计算器对比也比较明显。
Unix接口设计模式。根据输入和输出可以分为这些模式:过滤器模式(比如grep)、Cantrip模式(比如clear)、源模式(不需要输入,比如ls)、接收器模式(只接收不输出,例子较少,比如lpr)、编译器模式(既无标准输入也无标准输出,将错误消息发送到标准错误端)、ed模式(比如ftp、sh)、Roguelike模式(字符阵列比如vi)、“引擎和接口分离”模式(MVC模式作为GUI原型的建议)、CLI服务器模式
网页浏览器作为通用前端,无需编写一个定制的GUI前端。

12. 优化

过早优化是万恶之源
不到万不得已,尽量别去优化一个工作中的系统,而是等上几个月,期待硬件性能更好。
先估量,再优化。通过profiler,去明确瓶颈所在,而profiler本身也是存在工具误差的。
最有效的代码优化方法是保持代码短小简单。目标机器是分层的,将核心的数据结构和指令代码放在快速缓存。
快速处理器的另一个效应是性能经常受限于I/O以及网络事务的开销,要尽量避免协议的往返。
有三种常规策略来减少延迟:批操作、重叠操作、缓存操作结果。

13. 复杂度:尽可能简单,但别简单过了头

“Keep it simple, stupid”, 对于简单的理解其实是很复杂的。
复杂度的三个来源:程序员实现的复杂度、顾客和用户使用的复杂度以及代码量,关于怎么去折中,是没有标准答案的。
通过五个编辑器的故事,了解编辑器在处理更复杂任务时产生的不同程度的选择复杂度。
吝啬原则:只有实证了其它方法不通时才写庞大程序。

III– 工具

14. 语言:C还是非C

Unix下面存在非常多的语言种类。一是因为Unix广泛应用于研究和教学平台,二是因为应用设计和实现语言的合理搭配对生产力有极大促进。
C语言很厉害、很经济。但是要求程序员自己完成内存管理,很复杂,并且随着硬件设备的性能提升,主要瓶颈集中在I/O事件等待、网络延迟以及缓存列填充等限制上,所以Python、Java等语言慢慢兴起。

15. 工具:开发的艺术

本章将介绍Unix下的开发策略–编译代码、管理代码配置、性能分析、调试以及自动完成各种脏活累活。 这一套工具比起IDE更加灵活。 * 编辑器选择:vi和Emacs * 专用代码生成器:yacc、lex * 自动化编译:make。 一个笑话:输入”make love”,输出是“Don’t know how to make love”。 * 版本控制系统 * 性能分析:gprof

16. 重用:论不要重新发明轮子

很多人喜欢自己造轮子,因为库可能不是透明的、充满bug,还不如自己来的痛快。
随着开源的提出,我们应当选择好的轮子,这样可以节省时间,提高效率。
很多开源的网站,如github等。
注意一些许可证的问题。

IV–社区

17. 可移植性:软件可移植性与遵循标准

移植性一直是Unix的主要优势,可移植的戒律往往在架构、接口和实现上施加了一种简单化的影响,提高了项目成功的几率也降低了生命周期的维护成本。
C语言、Unix标准,IETF、RFC标准,一系列的标准和草案让接口更加规范,从而更方便移植。
编程语言的可移植:Java和Python具备良好的可移植性。
可移植工具:autoconf来处理移植问题,configure/make/make install来干净利落的编译。
可移植性需要标准,而开放源代码同样给标准化的过程带来了重要的影响。

18. 文档:向网络世界阐述代码

文档一般分为两类,所见即所得(word)和标记为中心(XML、markdown),各有优缺点;
编写Unix文档最佳实践:信息密度适中、不要过于庞大、也不要省略功能细节和存在的问题、将文档放在网上。

19. 开放源码:在Unix新社区中编程

开源开发的规则很简单:源码公开、尽早发布-经常发布、给贡献以表扬(物质奖励或者精神奖励)
与开源工作者协同工作的最佳实践:版本控制系统(Git、svn等)、良好的代码注释、良好的代码规范和文件命名规范、测试好再发布大妈、良好的交流实践(邮件列表、网站等)。
许可证的逻辑,挑选合适的许可证。

20. 未来:危机与机遇

回顾过去,网络互联、位图图形显示以及个人计算机这三个特殊的技术变化驱动了Unix设计风格的重大变革。
尽管伴随着许多创新,但所有对这三个技术的响应都保持着Unix的设计准则–模块化、透明性、机制同策略分离以及之前提到的品质。
Unix对GUI的支持较弱。Unix的API没有使用异常(C语言缺乏抛出异常的机制)。
从历史来看,我们只要能够从错误中汲取教训,文化薪火相传,Unix是不会输的。


原文地址:http://blog.csdn.net/zy416548283/article/details/50437187

上一篇 下一篇

猜你喜欢

热点阅读