聚合国内IT技术精华文章,分享IT技术精华,帮助IT从业人士成长

《Linux/Unix设计思想》读书笔记

2022-08-06 19:37 浏览: 2906984 次 我要评论(0 条) 字号:

《Linux/Unix设计思想》是一本关于Linux/Unix设计思想的书,书中很多思想和方案值得在日常的项目推进中采用与学习。

第一章 Linux哲学:集思广益的智慧

NIH综合症

NIH是英文Not Invented Here(非此创造)的缩写。在软件开发中即为常见。日常工作中,我们常常遇到项目交接的场景,作为接手项目的开发人员,常常做的是“重构”,重构的最主要原因是不愿意阅读别人写的代码,与其阅读别人代码,不如自己重新实验一遍,即为NIH综合征的表现形式。

NIH综合征的特点就是人们会为了证明自己能够提供更加卓越的解决方案而放弃其他开发人员已经完成的工作。

当一个团队拒绝承认另外一个团队开发的应用程序价值时,当人们宁可自己从头编写程序,而不是使用“现成”代码时,当人们压根不愿意使用其他软件,只因为他们是有别人编写的时候,就是NIH综合征在其中作怪。

哲学中的自我与非我

自我与非我是德国费希特用语。在《知识学基础》一书中提出,是其哲学体系的核心概念。“自我”指认识主体和意志主体,是唯一的实在;“非我”指客观存在的一切事物,是由“自我”设定的。

在费希特哲学中,自我经历了三个发展阶段:

  • 自我设定自身.产生不依赖客观物质世界的绝对自我;
  • 自我设定非我,因为活动是自我的本性,但无障碍则活动无以表现,自我为了活动,就创造跟自己对立的障碍物一一客观世界,即“非我”;
  • 自我与非我的统一.自我通过克服非我的过程而丰富、实现自身,两者在自我意识中复归于统一。

这一自我发展的过程是“自由”的体现,亦即道德活动。费希特本人没有把自我和非我的概念直接运用于美学。但这一概念对19世纪初期德国浪漫主义美学产生直接影响,是这一运动的出发点和理论基础。

如果我们一定要将世界一分为二的话,那么其中的一部分必然是我,而另一部分则会是非我。 我+非我=1,我属于(0,1)。 我可以无限趋近于 0,但不能等于 0,我可以无限逼近于1,但不能等于 1。 零为无,一为全,两者之间为存在。 我若为无,世界于我而言,毫无意义。

艺术是对我的展示,科学是对非我的研究,而哲学则是将我与非我联系在一起。

功成不必在我,功成必定有我

功成不必在我,亦可为功不必在我,是指功绩、事情、事业的成功,没有必要看我一个人。可以理解这件事不是非我不可,也可以理解为一件事情的成功的必然因素不在于我,体现了一种宽广大度和高尚情怀。

这句话的来源是胡适1932年的《致毕业生》,原有的句子是:“天下没有白费的努力。成功不必在我,而功力必不唐捐(意味为虚耗。”

第二章 人类的一小步

小即是美

小巧的事物能够已独特有效的方式结合其他小事物。简化软件工程:

  • 小程序易于理解
  • 小程序易于维护
  • 小程序消耗的系统资源较少
  • 小程序容易与其他工具相结合

投射到产品领域。笔记本相比台式电脑更小,使用场景也相对更多。而手机相比笔记本电脑更小,适应的场景更多。

Less is More

Less is More这是著名的建筑师米斯·凡德洛说过的一句话,意思是“少即多”这是一种提倡简单,反对过度装饰的设计理念。简单的东西往往带给人们的是更多的享受。

苹果创始人乔布斯一生奉行着极简主义:less is more,少即是多,他的苹果手机就是最好的证明。

相比一直堆feature、堆复杂度,或许砍掉或简化内容是最好的选项。

让每一个程序只做好一件事

这个小即是美表达的意思一致,只做好一件事,说明足够小。越是大型的系统,这个原则越重要,否则越大就越乱。

单一功能原则

在面向对象编程领域中,单一功能原则(Single responsibility principle)规定每个类都应该有一个单一的功能,并且该功能应该由这个类完全封装起来。所有它的(这个类的)服务都应该严密的和该功能平行(功能平行,意味着没有依赖)。

这个术语由罗伯特·C·马丁(Robert Cecil Martin)在他的《敏捷软件开发,原则,模式和实践》一书中的一篇名为〈面向对象设计原则〉的文章中给出。 马丁表述该原则是基于的《结构化分析和系统规格》一书中的内聚原则(Cohesion)上。

马丁把功能(职责)定义为:“改变的原因”,并且总结出一个类或者模块应该有且只有一个改变的原因。一个具体的例子就是,想象有一个用于编辑和打印报表的模块。这样的一个模块存在两个改变的原因。第一,报表的内容可以改变(编辑)。第二,报表的格式可以改变(打印)。这两方面的改变会因为完全不同的起因而发生:一个是本质的修改,一个是表面的修改。单一功能原则认为这两方面的问题事实上是两个分离的功能,因此他们应该分离在不同的类或者模块里。把有不同的改变原因的事物耦合在一起的设计是糟糕的。

保持一个类专注于单一功能点上的一个重要的原因是,它会使得类更加的健壮。继续上面的例子,如果有一个对于报表编辑流程的修改,那么将存在极大的危险性,因为假设这两个功能存在于同一个类中,修改报表的编辑流程会导致公共状态或者依赖关系的改变,打印功能的代码会因此不工作。

第三章 快速建立原型的乐趣和好处

学习曲线

学习效果不是一条直线,笔直向前,而往往是曲线前进。也就是说:努力与时间未必成正比,是非线性关系。典型的学习曲线,学习成果随着学习时长增加的变化情况,如下图所示:

缓慢开始区

所谓的缓慢开始区,就是变化不大,观察不出,觉得学习上的投入,没有什么产出。大部分人在“缓慢开始区”放弃。

为什么会缓慢?原因有很多,比如说,没有获取到优质的、合适的学习资源,也可能是阅读质量不高,理解不到位,还可能是没有整合到自身知识体系中。

对于“缓慢开始区”的缓慢,要有清晰的认识,保持信心,坚持到通过进入“加速提高区”的关键转折点。总的来说,身处“缓慢开始区”,我们要遵守的原则就是:“学,就对了;做,就对了。”

高原区

高原区是普通人才与一流人才的区分点。进入加速提高区时,很多人都能体会到成就感,有点欣欣然,但很快就会碰到高原区。因为容易掌握的已经掌握,只留下难啃的骨头,如果没有目标感和系统观,容易骄傲自满,自我感觉良好,于是止步不前。克服高原反应,才能成为人才;能够连续通过多个高原区的人,才能成为一流人才。

软件工程师尤其需要高强度持续不断的学习,软件很难一蹴而就。

为什么软件被称为“软件”

相比硬件,软件可以时刻发布新版本。

人类创造的“三个系统”

第一个系统

  • 在背水一战的情况下,人类创建了“第一个系统”
  • 没有足够的时间将事情做好
  • 单枪匹马或是一小群人开发的

第二个系统

  • 使用“第一个系统”验证过的想法来创建“第二个系统”
  • 由委员会设计的
  • 臃肿而缓慢
  • 被大张旗鼓地誉为伟大的成就

第三个系统

  • 由被“第二个系统”所累的人创建
  • 通常会改变“第二个系统”的名称
  • 最初的概念保持不变并显而易见
  • 结合“第一个系统”和“第二个系统”的最佳特性
  • 设计者有“充裕的时间”将任务做好

“三个系统”理论,在我们的工程实践中,随处可以看到这三个系统的身影。第一个系统通常是刚刚发布上线的新系统,这类系统往往功能精简,但又恰好满足需求,虽然偶尔出些小错,但无伤大雅。因为逻辑精简,所以也易于修改和部署,目前,生活还算美好。

随着业务的发展,逻辑也变得无比的复杂,第一系统正逐渐朝着第二系统的方向演进。而更为糟糕的是,无数Boss本着关心业务的态度,不断挑战,不断进行所谓的迭代改进,第一系统终于不可避免地变成了第二系统,臃肿而缓慢,每次一发布新版本,系统就问题不断。

终于,在某次重大故障发生之后,有人站了出来说,不能再这样下去了,我们优化逻辑,调整架构吧。在砍掉过于复杂却无太大作用的逻辑,优化架构之后,第二系统也得以朝着第三系统的方向继续演进。值得庆幸的是,持续恶化的情况终于得到了遏制,生活又重回美好。但此时,仍需保持警惕,防止重回第二系统。

“三个系统”的理论,告诉了我们一个道理:应当尽早建立第一系统,然后,尽量让系统保持在第二系统和第三系统之间。

第四章 可移植性的优先权

最强大的计算机并不是那一款有着较快CPU、最大磁盘或安装了最强大软件的机器,使用最频繁的那台计算机才最为强大。

舍高效率而取可移植性

  • 下一代硬件会跑的更快
  • 不要花太多时间去优化程序
  • 最高效的方法通常不可移植
  • 可移植的软件还减少了用户培训的需求
  • 好的程序永不会小时,而会被移植到新平台

采用文本来存储数据

  • 文本是通用的可转化格式
  • 文本文件易于阅读和编辑

第五章 软件的杠杆效应

一个人的精力就只有这么多。如果想取得非凡成就,你就必须 放大自己对这个时间的影响力。如果仅凭一己之力,能做的事情只有那么多。关键词是“杠杆”。

想编写大量软件,最好的办法就是借用别人的成果。这里所说的“借用别人的成果”是指将他人的软件模块、程序和配置文件集成到自己的应用程序中。通过制作衍生品,你成倍放大了前任开发人员的努力,将他们的成果发扬光大到新的高度。他们软件变得更有价值,因为它们的身影出现在更多应用程序中。

我们生活在一个最好的时代,同时,我们生活在一个最坏的时代。

说是最好的时代,是因为无论我们面对的是怎么的需求,所处怎样的领域,有太多太多的工具(大多数都是免费的)可供我们挑选,有些甚至理想到无须编写任何代码,只需简单配置即可。软件的杠杆效应使我们受益良多,真可以说是站到了巨人的肩膀上。

同时,也请警惕这个最坏的时代,如果我们仅仅满足于会使用工具,仅仅满足于复制+粘贴的话,那我们也就是个“人肉编码机”,编程技艺也无从提高。有太多现成的软件可以使用了,又何必再费力思考呢,一旦产生了类似的想法,是非常危险的,它会让我们满足于现状,止步不前,而终有一天你会发现自己和一台机器又有什么区别呢。

  • 良好的程序员编写优秀代码,优秀的程序员借用优秀代码
  • 避免NIH综合征
  • 允许他人使用你的代码来发挥软件杠杆效应
  • 将一切自动化
  • 使用shell脚本来提高杠杆效应和可移植性

第六章 交互式程序的风险

一旦物体缩小到一定程度,人们就无法掌控它们,人类必须依靠工具来提高正常的身体感官技能。

小型事物与人交互性变差的同时,它们之间的交互性会大大增强。小尺寸赋予了它们极大的灵活性。在很多情况下,它们能轻而易举地整合在一起。

你拥有的小物件越多,操控它们就越难。管理这些小物件就成为一个严重的问题。

CUI与GUI

CUI

CUI 代表字符用户界面。它是一种用户界面,用户仅通过键盘与计算机进行交互,并且需要命令来执行任何任务。CUI 是 GUI 的前身,并在大多数早期计算机中使用。大多数计算机使用 GUI 而不是 CUI。它通过允许用户在多个文本行(命令行)中向程序提供命令来工作。CUI 的基本实例是MS-DOS和Windows 命令提示符。CUI 的应用之一是它简化了编程脚本的创建。

优点

  • CUI 界面不太吸引人。
  • CUI 不提供相同的使用简单性或在一个屏幕上操作各种程序的能力。
  • CUI 中没有明显的反馈。在相同的情况下,将需要多个附加命令来确认文件传输操作。
  • 用户必须记住各种命令来操作和管理 CUI。
  • 在 CUI 中,一次只能完成一项任务。
  • CUI 仅支持使用键盘。

缺点

  • 与 GUI 相比,CUI 使用的内存更少。
  • 使用成本较低,因为可以使用较低分辨率的屏幕。

GUI

GUI 代表图形用户界面。GUI 使用户能够与操作系统或应用程序进行交互。它执行算术的快速计算并释放 CPU 来执行其他任务。它提供按钮、窗口、滚动条、标志性图像、向导和其他图标来方便用户。它为初学者提供了一个用户友好的界面。它易于使用、学习,也减少了认知负担。

优点

  • GUI 是一种更易于使用的用户界面。由于数据以符号、表格和图标的形式表示,因此用户可以对选项进行分类和导航。用户只需点击它们即可获取其功能。
  • 使用 GUI 管理多个作业也很容易。用户可以同时工作和观看多个节目。例如,当电影文件在后台播放时,可以使用网络浏览器浏览互联网。
  • 快捷键的使用是图形用户界面最重要的功能之一。如果您需要执行需要几个操作的工作,快捷键非常有用。

缺点

  • 尽管图形用户界面易于使用,但它们在创建时并不相同。GUI 有很多文本解释,需要花费大量时间和精力来创建。程序员必须创建、链接,然后为图像分配特定的功能,这需要很长时间。
  • GUI 实现并不像使用它时看起来那么简单。程序员必须注意正确创建函数,以便用户可以更轻松地使用此接口。编码人员的一个错误可能会使他们的所有努力都付诸东流。
  • 由于所有图形表示,它通常比其他界面使用高功率和计算机内存。它不节省资源。结果,它将使用大量的计算机资源。
  • 图形用户界面的设计使开发更加复杂和昂贵。此外,GUI 必须与附加硬件链接,这可能会增加总体成本。

CUI 和 GUI主要区别

  • CUI是一种用户界面,用户仅通过键盘与计算机进行交互,并且需要命令来执行任何任务。相反,GUI 允许用户与操作系统或应用程序进行交互。
  • CUI 是 GUI 的前身,用户必须在键盘上键入才能继续 CUI。相比之下,GUI 使得使用鼠标代替键盘成为可能。
  • DOS,Windows 命令提示符是 CUI 的一个实例,而 Windows 是 GUI 的一个示例。
  • GUI 比 CUI 更易于使用。
  • CUI 只有文本,相比之下,GUI 有图形和其他视觉线索。
  • CUI 和 GUI 是与计算机结合使用的用户界面。

避免强制性的用户界面

  • CUI假定用户是人类
  • CUI命令解析器的规模庞大且难以编写
  • CUI偏好“大即是美”的做法
  • 拥有CUI的程序那一与其他项目相结合
  • CUI没有良好的扩展性
  • CUI无法利用软件的杠杆效应
  • GUI不过是CUI的可视化形式

个人的理解是,程序开发过程中切勿开发不同的后台,而是以接口形式交互数据会更有利。

让每个程序都成为过滤器

  • 人们编写的每一个程序都是过滤器
  • 程序不创建数据,只有人类才会创建数据
  • 计算机将数据从一种形式转换成领一种

第七章 十条小准则

  • 允许用户定制环境
  • 尽量使操作系统内核小而轻量化
  • 使用小写字母并尽量简短
  • 保护树木(谨慎使用纸张)
  • 沉默是金(执行正常,不反馈任何信息)
  • 并行思考
  • 各部分之和大于整体( 小型组件的排列组合)
  • 寻求90%的解决方案(我们需要故意忽略那些代价昂贵、费时费力或难以执行的项目)
  • 更坏就是更好(更差的事物的生命力反而比那些正确或错误的事物高)
  • 层次化思考

第八章 让UNIX只做一件事

第九章 UNIX和其他操作系统的哲学

  • 雅达利家用电脑:人体工程的艺术
    • 强调软件如何与人沟通,Unix强调软件与软件之间如何沟通
    • 不给用户留出犯错空间,只提供有限的选择权
    • 现代游戏机的实现方法与 雅达利家用电脑的理念相同
  • MS-DOS:七千多万用户选择不会错
    • MS-DOS易于使用,简洁有限的命令语言,详细的帮助和错误消息,在限制用户输入的同时增加系统的输出信息,
    • Unix有一个相当强大的命令语言集,错误信息非常简洁,让人头痛不已。
  • VMS 系统:UNIX的对立面
    • 将用户完全屏蔽在系统内各种变幻莫测的情况之外,只给用户提供单一的解决路径。
    • 采用“大即是好”的策略,使用规模宏大的单一化程序来满足众多用户的需求。
    • 人们购买VMS是因为需要完成某项确定的任务
    • 基本信念:用户害怕计算机
    • 让需要条条框框的人们易于使用,而不是编写那些让用户DIY的工具包。

第10章 拨开层层迷雾:Linux与Windows的比较

  • Windows 背后设计理念类似VMS操作系统。奉行越大越好的软件设计方法。类似Office启动的时候就加载一切。
  • 基于同样的设想,即用户害怕使用计算机。系统的软件开发人员不遗余力的想让操作系统能够更易于新人使用。

功能与形式

  • 功能:整个系统的内容(用户所需要的)
  • 形式:如何将功能呈现给用户

形式很重要,因为它通过赏心悦目的方式传递给用户,单如果信息里没有任何功能和内容,形式只不过空洞无物。

形式追随功能

形式追随功能(英语:Form follows function,又译“形式服从功能”“形式跟随功能”等)是一项与19世纪末至20世纪初的建筑和工业设计相关的原则,它意味着建筑物或物体的形状应基本与其预期的功能或目的相关。

软件工程

有人主张,工作的、非琐细的软件构件(working, non-trivial software artifact)的结构和内部质量属性,首先代表其建构的工程要求,而过程的影响是微不足道的。这并不意味着该过程无关紧要,但与构件要求兼容的过程会产生大致相似的结果。

该原则也可以应用于现代企业的企业应用架构(Enterprise Application Architectures),其中“功能”是应由企业架构或“形式”协助的业务流程。如果架构决定了业务如何运作,那么业务可能会因不能适应变化而僵化。SOA(面向服务的体系结构)使企业架构师能够通过采用基于标准的通信协议来重新安排体系结构的“形式”,以满足业务的功能需求,从而实现互通性。

此外,领域驱动设计假定结构(软件架构、设计模式、实现)应来自建模域的约束(功能需求)。

虽然“形式”和“功能”对许多工程学说可能或多或少是明确和不变的概念,但元编程和功能编程范式非常适合探索、模糊和颠倒这两个概念的本质。

敏捷软件开发运动支持诸如测试驱动开发之类的技术,其中工程师从最小的用户导向功能单元开始,为此创建一项自动化测试,然后实现功能并迭代,重复此过程。该准则的结果和论点是结构或“形式”从实际功能中产生,并且实际上因为有机地实现,使得项目由于自动化测试的功能基础而具有更长的适应性以及更高的质量。

内容为王

Windows的作用是给内容提供传输的载体。

有没有图形界面并不重要,真正重要的是那些被传达的信息。如果你对看到的内容不感兴趣,就会对它们置之不理并寻找下一条信息。

三种信息传输的机制:

  • 视觉
    • 图像:如果没有关于其内容的一些文字说明,它们可能很难进行归类和检索。
    • 视频:同上。
  • 听觉
    • 无法单独存在
  • 文本
    • 文字内容吸引我们取了解更多信息。
    • 文本是一种用来存储和传播思想的廉价方式。
    • 人们可以高效的对文本进行索引和搜索
    • 通过机器将文本翻译成其他语言的花费并不高
    • 文本可以非常准确的传达思想。
    • 由于数据抽象这个概念,因此文字在处理大量内容时更为高效。

第11章 大教堂?多怪异

  • 滚石乐队的音乐是在大教堂完成的
  • 猫王的歌曲借鉴了美国音乐集市的种种元素

第12章 Unix的美丽新世界

  • JAVA:舍高效而取可移植性
  • 面向对象:充分利用软件的杠杆效应
  • 极限编程:尽快建立原型,从而与客户一并开展迭代开发工作
  • 重构:简化再简化
  • 互联网:如果更坏就更好,那么充斥在互联网上的烂网页恰恰证明网络会持续存在
  • 无线通信:廉价、高效、移动的通信可谓是下一个杀手级应用
  • Web应用:在网络上实时Unix哲学。


网友评论已有0条评论, 我也要评论

发表评论

*

* (保密)

Ctrl+Enter 快捷回复