Unix编程艺术--读书笔记(转)

 

今天扫了一遍Unix编程艺术。很是粗略看了下目录。前端

收获几个名词:模块化、文本化、透明性、正交性、数据驱动、专用代码生成、可配置
--------------------- 
版权声明:本文为CSDN博主「just_record」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处连接及本声明。
原文连接:https://blog.csdn.net/just_record/article/details/79774034git

 

I-场景
1. 哲学
机制而不是策略,自由放纵注意风格,产生了多样性。好比Unix应用程序提供不少的行为选项,让非技术的用户晕头转向,而失去了不少用户;可是策略相对短寿、机制才会长存,具备很大的灵活性。
趣味性是一个峰值效率的标志。对于程序员和开发人员来讲,若是完成某项任务所须要付出的努力对他们是个挑战又刚好还在力所能及的范围,他们就会以为颇有乐趣。 而UNIX有Hack趣味。
UNIX哲学是自下而上的,注重实效,鼓励分清轻重缓急的感受以及怀疑一切的态度,并鼓励你以幽默达观的态度对待这些。
简洁是UNIX程序的核心风格。 UNIX哲学的KISS原则:Keep it simple, stupid!
先制做原型,再精雕细琢。优化以前,先肯定能用。
2. 历史–双流记
本章主要回顾UNIX的历史,来阐明现在的UNIX文化为何呈现当前的状态。 两个历史分别是UNIX的起源和历史以及黑客的起源和历史程序员

UNIX的起源和历史
UNIX的祖辈是CTSS–兼容分时系统,父辈是颇具开拓性的Multics项目(试图创建一个具有众多功能的系统);
创世纪:1969-1971年,UNIX诞生于贝尔实验室;
*出埃及记:1971-1980,C语言的加入,其表述方式带来的可读性、可改性和可移植性,给UNIX带来了必定的成功。
TCP/IP和UNIX内战:1980-1990, TCP/IP的引入,让UNIX更加有活力。 然而微软的兴起和AT&T的拆分,让UNIX进入了炼狱。UNIX的产业化,破坏了UNIX源码的自由交流,而自由交流却正是滋养UNIX系统早期的活力。
反击帝国:1991-1995,Linus Torvalds宣布了Linux项目,依赖分布式开发和patch(补丁)工具,加入了Internet和图形界面,实现了Unix的平价之梦,并拼装了UNIX的传统元素。 1995年以后,UNIX的故事就变成了开源运动的故事。
黑客的起源和历史:1961-1995
游戏在校园的林间:1961-1980年,MIT的人工智能实验室的程序员应该是第一批自称”hacker“的人;
互联网大融合与自由软件运动:1981-1991. 1983年,BSD植入了TCP/IP,UNIX文化和ARPANET文化开始融合。RMS建立了GNU项目,致力于编一个彻底自由的操做系统。自由软件术语的提出,让黑客文化更加有自我意识。
Linux和实用主义者的应对:1991-1998. Linus Torvalds巧妙地跨越了GPL和反GPL的派别之争。他利用GNU工具包搭建了自创的Linux内核,用GPL的传染性质保护它。Torvalds明确的表示他认为自由软件一般很好,但他偶尔也用专有软件,他拒绝成为狂热分子。
开源运动:1998年及以后
一个部落的零距离可能来自他们维护的代码库,或是一个或多个有着超凡影响力的领导者,或是一门语言,一个开发工具,或是一个特定的软件许可,或是一种技术标准,或是基础结构某个部分的管理组织。 1995年以后,Linux扮演了一个特殊的角色:既是社区内多数软件的统一平台,又是黑客中最被承认的品牌。整个黑客文化开始凝聚在一个共同目标:推进Linux和集市开发模式向前发展。
”开源“背后另外一个意图就是但愿将黑客社区的方法以一种更亲和市场、更少对抗性的方式介绍给外部世界。
Unix的历史教训
距开源越近就越繁荣;
过分依赖任何一种技术或者商业模式都是错误的–相反,保持软件及其设计传统的灵活性才是生存之道;
别和低价而灵活的方案较劲;
真正的专业和奉献精神,正是咱们在屈服于世俗观念的”合理商业作法“以前的所做所为。
3. 对比:Unix哲学同其余哲学的比较
操做系统的风格元素
操做系统的统一性理念。好比UNIX系统的”一切皆文件“模型和由此基础上创建的管道概念。
多任务能力。Unix系统拥有抢先式多任务的能力。 多任务和多用户不是一回事。
协做进程:UNIX的IPC(进程间通讯方式)很灵活。
内部边界: Unix是相信程序员的,可是程序员不能破坏其余人的数据,因此Unix设立了内部边界来防范恶意用户或者有缺陷的程序。
开发的门坎: Unix将编译器和脚本工具放在默认安装中,支持了一种跨越众多机器的玩家开发文化。
操做系统的比较
列举了若干操做系统的优缺点。
种什么籽,得什么果
竞争对手的一些缺点: 好比不可移植性、不具有良好的网络支持能力。
而Windows在服务器上的缺陷(安全等缘由),使得Linux取得了重大突破。
就像造房子同样,在坚实的地基上修理上层建筑固然要比更换地基而不破坏上层建筑来得容易。
II–设计
4. 模块化:保持清晰,保持简洁。
早期的Unix程序员擅长模块化是由于他们被迫如此,若是没有良好的架构,操做系统就会崩溃。
封装良好的模块,不会过多向外部披露自身的细节,不会直接调用其余模块的实现码,也不会胡乱共享全局数据。
具备最佳尺寸的模块并不意味着代码有高质量,还得考虑紧凑性和正交性。
紧凑性就是一个设计可否装入人脑。好比一个设计有经验的用户不须要操做手册,这个设计就是紧凑的。
正交性是指任何操做均无反作用,每个动做只改变一件事,不会影响其余。
不要重复自身(don’t repeat yourself)。
软件的分层:自顶向下和自底向上。 当自顶向下和自底向上发生冲突时,顶层的应用逻辑和底层的域原语集必须用胶合逻辑层来进行阻抗匹配。 胶合层是个挺讨厌的东西,必须尽量薄。
OO语言使抽象变得容易,可是过多的层次破坏了透明性,咱们很难看清层次,没法理清代码的运行过程。
单个函数与其说是行数计算问题,不如说是内部复杂度性的问题(好比说局部变量太多、代码存在太多缩进)。
5. 文本化:好协议产生好实践
设计文件格式和应用协议须要考虑的重要方面:互用性、透明性、可扩展性以及经济型。
使用二进制的惟一正当理由:处理大批量的数据集或者关心时间或指令开销。
数据文件元格式有多重不一样的元格式,好比DSV、RFC 82二、Cookie-Jar、Record-Jar、XML、Windows INI等;
应用协议若是是文本格式的,凭肉眼能够很容易地分析,不少事情变得容易。能够看看SMTP、POP3和IMAP三种经典的应用协议。
应用协议元格式:尽管网络带宽比存储昂贵许多,须要重视事物处理的经济性,可是文本格式的透明性和互用性优点仍是十分显著,大多数设计者仍是选择了采用可读性更高的文本格式。好比HTTP协议、BEEP协议、XML-RPC/SOAP/Jabber协议。
6.透明性:来点光
在第五章中,讨论了数据格式和应用协议进行文本化的重要性,文本化让透明性和可显性的品质获得了提高。
* 若是实际上可以预测到程序行为的所有或大部分状况,这个程序就是透明的;
* 若是程序能够帮助人们创建“作什么、怎样作”,这个软件系统就是可显的。好比对用户来讲,文档有助于可显性; 对程序员而言,好的命名规范有助于提升可显性。
* 要追求代码的透明,最有效的方法很简单,就是不要在具体操做的代码上叠放太多的抽象层。
* 透明的系统在bug发做时,更容易实施恢复措施;同时,透明的系统更容易让人理解,从而更加方便维护。github

7. 多道程序设计
UNIX最具特色的程序模块化方法就是将大型程序分解成多个协做进程。
多个并发进程除了带来模块化的好处以外,另外一个缘由是为了更强的安全性。
UNIX IPC:把任务转给专门程序(shell out)、管道/重定向(管道主要缺点是单向性,命名管道能够做为二者间的配接器)、从进程、对等进程(临时文件、信号、套接字、共享内存)。
8. 微型语言:寻找歌唱的乐符
UNIX班有个长期传统,存在小型的、为专门应用领域特制、大量减小程序行数的语言。 好比无数Unix排版语言(troff/pic)、shell使用程序(awk/sed/dc/bc)和软件开发工具(make/yacc/lex等)。 微型语言与脚本语言之间的界限都很模糊。
* 一切可计算的问题均可以计算,叫作图灵完备。
* 明白微型语言在何时什么场景下使用。
* 某些状况下,须要咱们咱们去设计一个微型语言。 首先要尽量保持微型语言的简单(复杂度),思考可否经过扩展或者嵌入现有脚本语言来实现本身的微型语言(这是实现命令性语言的正确方法),慎用宏。shell

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是不会输的。编程

相关文章
相关标签/搜索