首页 存档 技术 查看内容

来自Unix/Linux的编程启示录 从女娲造人说起 来自Unix/Linux的编程启示录 总结

2018-3-30 13:00 |来自: 互联网 414 0

摘要: 作者:江湖人称小白哥 原文:http://blog.csdn.net/dd864140130/article/details/54922319 写本文的最初灵感源于16年11月份我将工作环境切换到Mac OS上,其中一些使用"差异"让我开始对Unix/Linux中设计产生了浓 ...

作者:江湖人称小白哥

原文:http://blog.csdn.net/dd864140130/article/details/54922319

写本文的最初灵感源于16年11月份我将工作环境切换到Mac OS上,其中一些使用"差异"让我开始对Unix/Linux中设计产生了浓厚的兴趣.

在整个探究过程中,那些经典的著作再次让我获益匪浅:C和指针C专家编程深入理解计算机系统(原书第3版)Linux/Unix设计思想Linux Shell脚本攻略.前两本书购于13年,断断续续的读了许久,这一次重读令人豁然开朗,其中许多不解之处在深入理解计算机系统一书得到答案,而后两本则是年前有幸读到.其中Linux/Unix设计思想不谈技术细节,却揭示了Linux/Unix隐含的指导思想,最后一本则是从Shell出发,以实践的角度教你如何利用Shell(Bash)在Linux/Unix平台上构建有效的解决方案,实乃入门进阶必备啊.


从女娲造人说起

俗说天地开辟,未有人民,女娲抟黄土作人。剧务,力不暇供,乃引绳于泥中,举以为人。故富贵者,黄土人;贫贱人,引绳人也…

神一样的程序员

"女娲造人"可谓人人皆知,女娲是神,而程序员是能力上最接近女娲的存在。如果说女娲创造的是真实的世界,那么程序员是创造数字的世界,我们所写下的每行代码,所构建每个程序,都在让这个数字世界变得丰富多彩。

没有哪个职业可以像程序员:赋予代码以生命,创造数字世界中的花花草草 \ !尽管我们拥有近乎神的能力,本身却也受着 NIH 综合征的困扰。

程序员之殇

NIH 综合征是什么?

Not invented here \ ( NIH\ ) is a stance adopted by social ,corporate , or institutional cultures that avoid using or buying already existing products , research , standards , or knowledge because of their external origins and costs.

我们经常为 NIH 所困:在求解解决方案时,经常自认为可以做得更好或者在看到别人的解决方案会提出各种质疑。这大都是我们缺乏对当时问题解决者所面临限制的认识所造成:可能迫于时间或者预算的限制,也可能受限于当时物理资源的限制。

穿着衣服的猴子

NIH 综合征的特点就是人们会为了证明自己能够提供更加卓越的解决方案而放弃其他开发人员已经完成的工作。这种狂妄自大的行径说明此人并无兴趣去维护他人竭尽全力提供的最佳成果,也不想以此为基础去挑战新的高度。NIH 综合征本质上是动物天性-"嘿,我更好"的体现,就像所有的公猴都会向母猴证明"我更好"一样。

放弃已有工作成果而另起炉灶的做法无形之间浪费了大量时间。有一些技术人员在入职新公司后,往往有想推倒一切重来的欲望。我曾经有位朋友连续跳槽很多家公司,每次入职之前都信心满满,不就后就黯然离开。朋友能力很不错,但每次入职后总是急于通过推倒重来来证明自己的能力。

更糟的是,新的解决方案往往只是做了一些改进,和之前并无本质区别,再加上现代的应用往往动辄十几万行,远超出每个人所能注意的极限,这也会让程序员产生疏漏,从而使得这个问题变得更糟糕。

当然,少数情况下,新的解决方案更好,这只是因为技术人员早已了解做过的工作,从而针对问题可以提出更高的解决方案。站在现在的角度看历史,还看不出对错的话,除非你对历史一无所知。

为什么 Linux 会成功

Linux 为什么会成功有很多的的因素,除却当时环境因素外,其成功之处在于开源的世界让每个人都能得到 Linux 源码,从而使得经验可以被借鉴。事实上,在原有软件基础上进行扩展是 Unix 的核心概念之一。当然,在 Linux 出现之前,借鉴他人编写的软件已成为相当普遍的做法,这也是 GUN 宣言中的 GPL 下所阐释的思想。


来自Unix/Linux的编程启示录

现在我们来看看Unix/Linux中那些隐藏的编程哲学,需要说明的是Unix/Linux中的编程哲学非常通俗易懂,他们大多是你已知的,更多的时候是我们不曾注意到.

无论你现在负责的系统多么复杂,这总有可以帮助你的地方。(要说复杂,还有什么比Unix/Linux更为复杂的应用。)

原则一:小既是美

我猜当你看到"小既是美"一词时会首先想到一句谚语"麻雀虽小,五脏俱全"。那就用麻雀做引子来说说为什么小即是美。

大凡生物,无论形体如何,愈小愈稳定。麻雀相对人而言,出现脑残鸟的几率要小的多,而单细胞生物相对多细胞生物产生显著变异体的概率也要小的多…在软件工程中,同样如此。 Unix 中的程序大凡遵循这条准则,小带来的显著优点如下:

  1. 易于编写

  2. 易于理解

  3. 易于维护

  4. 消耗更少的系统资源

  5. 容易与其他工具组合

尽管我知道你已经对其有过了解,我还是例行的嗦一下。

每个程序员心中都有编写一个万能软件的想法,渴望像上帝一样创世,能够名垂青史,但这实在是太难了。越是复杂的问题越令人畏缩不前,想想在上学期间,你是更乐于立刻开始做一道题还是一套题呢?不出意外,我们大都喜欢从一道题开始。编写小程序同样如此:我们能够尽快的动手去做,并且针对某个点找出更合理的解决方案。另外,由于大脑的结构,我们无法同时关注超过四个以上的点,而复杂的程序需要被关注的点却远大于四个,这就意味着我们可能会犯更多的错误。

小程序带来的另一个好处就是容易理解,一个100行的程序比一个1000行的程序要容易理解的多(复杂度相同的情况下).

当程序足够小的时候它就是函数,还有什么比函数更灵活地自由组合呢?当然大多数小程序不能够小到只有一个函数,但尽可能的减小程序大小仍然很重要,unix/linux中的命令便是最佳的示例:cp用来拷贝,rm用来删除,组合起来就可以实现移动,简直棒呆了。

我想,没人会认为麻雀每天摄入的能量会比人多吧?换到程序当中就是越小的程序消耗的系统资源会更少,大多数情况下如此。

原则二:让每个程序只做好一件事情

程序员也许只想编写一个简单的应用程序,但是随着他的创新精神占据上风,促使他在会在这里添加一个功能,在那里添加一个选项,很快你就发现本来你只想要一个文本编辑器,但是他却给你一个 IDE ,最终他给你的往往不是惊喜而是大杂烩。这个问题不但在程序员身上体现出来,同样也会出现在产品经理上:想要一个计算器对么,我这里有个超级计算机可以给你用?现在你只能面对这这么一个庞然大物了。

该思想和"小即是美"相辅相成,"专注一件事"的应用最终会产生一个较小的程序,而小程序往往只有单一的功能,单一功能的程序往往也会很小。另外,每个程序只做一件事情也意味着我们可以集中精力去解决当前任务,全新全意做好本职工作。

原则三:建立原型

原型的建立是学习的过程:在该过程中可以知道哪些想法可行,哪些不可行。每一个正确设计的背后都有数百个错误的设计方案,通过建立原型,我们可以在早期剔除掉不良的设计方案,以此来降低风险。换句话说,越早的建立原型,离你的软件发布的时间越近。

你的软件发布了吗?

从开始接触软件工程开始起,我们的前辈就告诉我们:"软件永远不会有开发完的时候,记住,是永远!".

"怎么会完不成呢,我只要不做了不就行了么?",现在想想,这比让一个沉迷在购物中的女人停下脚步更难(如果钱是无尽的话).编写软件亦如此,你永远都会想要加入的更多的功能。想加入的更多功能的可能不是你,或者是你的产品经理,当然你的 boss 也会掺一脚。

我一直在向周围的朋友传递这么一种观点"世界上唯有不变的事物那就是变",对于软件工程同样如此。既然变化无可避免,那软件是怎么完成的?尽管我们做事都希望看到最后的结局,但是对于软件而言并非如此。可以说,没有做完的软件,只有发布的软件。

我曾犯过类似的错误。16年我在负责一款移动端产品的开发,希望在一个月内上线第一个版本。由于个人疏忽,当我着手原型工作时离发布时间只有20天的时间了,在这期间发现原有的一些方案无法奏效,我不得不临时更改一些既有的设计。最终导致第一个版本正式发布的时间超出15天。我也曾因此被认为是个糟糕的工程师。在团队没有任何移动应用产品开发的经验下,及早的开始建立原型或许不会导致如此后果。在离开这家公司之后,我仍倍感惭愧。

原则四:舍弃高效率而取可移植性

偏向高效率往往会导致代码不可移植,而选择可移植性往往会让软件的的性能不那么尽如人意。每当有为了追求高效率而放弃移植性的想法的时候,请在心中默念以下两句话:

  1. 速度欠佳的缺点会被明天的机器克服

  2. 好程序不会消失,而被移植到新平台。

关于优化的两点建议

在 unix 环境中,可移植性的含义通常意味着人们要转而采用 shell 脚本来编写软件。抛开平台不谈,关于优化,我有以下两点建议:

  • 不要立刻优化:如无必要,无须优化。换句话说,不要想当然的优化,尤其是在用户无感觉的情况下。

  • 关注微优化:影响性能的往往只有几处,在需要优化的时候只要解决这几处就好,切莫以优化的名义重构全部。

原则五:使用纯文本来存储数据

文本不一定是性能最好的格式,但却是最通用的。另外,文本文件易于阅读和编辑:在任何平台上我们可以轻松的阅读文本数据,或使用标准文本编辑器对其进行编辑。

你可能会考虑到使用纯文本文件拖慢了系统的处理速度,并会找出一系列的证据来证明处理字符串的性能更低。我们承认文本文件确实拖累了系统的性能,但是记住明天系统的机器的性能必将有大幅度的提高。

原则六:利用软件的杠杆效应

给你一个杠杆,在不考虑杠杆质量的前提下,你真的可以撬动地球。一个人精力只有这么多,如果想要取得非凡的成就,你就必须放大自己对这个世界的影响力,这就需要你找到其中的"杠杆点",也就是关键点。

君子性非异也,善假于物也

软件中的杠杆效应就是要善于利用他人已有成果,具体点就是学会利用他人写的代码。在早期,我希望每一行代码都是从自己手中出来,并以为为傲,并认为这就是所谓的优秀的程序员。多年之后,我才明白成为一个优秀程序员的关键却和手敲每行代码并无必要联系。

善于利用他人的代码会给程序员自身增加砝码。这可能和很多人的认知相违背。查看别人工作并夸口说自己做的更好,不代表你能力更强;推导现有的方案在重来,那只是模仿不是创造。想要解决掉你手中的任务,编写更多软件的最好方法就是善于借用别人的成果。和大多程序员一样,我曾认为亲自编写代码能带来"就业保障",并将这种做法视为核心竞争力。但实际工作中却是相反,在实现功能的前提下,企业往往认为花费时间更少的程序员更具有高效的生产了,你可能对此感到委屈和不解。这里,我想要说的是:认识企业对你的认识和你对自己认识之间的差异是非常重要的。

如果有可能,请尽量让你的工作自动化。通过加强自动化工作来利用软件的杠杆效应能产生巨大的生产力,并且能够更充分的利用好时间。如果你是个 linux 开发者, shell 脚本便是你在寻找的杠杆点。

化作春泥更护花

从另外一个角度来说,允许他人使用你的代码来发挥杠杆作用。大部分工程师喜欢私藏自己的源代码,并视为独一无二,举世珍宝,仿佛自己的"核武器"。他们认为公开自己的源代码,自己就失去地位,会被公司所抛弃。

哪些你以为是"核武器"的代码真的就有如此威力么?要记住:任何一个有着合理思维的正常人都可以编写出像样的代码。更何况,一个有耐心的程序员完全可以将程序反汇编出来,通过一步一的分析,最终发现其中的蛛丝马迹。

Linux 的开发人员认为执意保留源码的控制权并无太大必要。现在你发现,尽管你拥有全部的源码,但却仍然不能创造出比 Linux 更成功的操作系统。我想这足打消你心中哪点忧虑了。

重新认识自豪感

现在重新认识所谓的自豪感。很多程序员将写出优秀的代码,使用先进的技术视为自豪感,但我们最终的产出是用来服务用户的,如果用户不能满意,那么我们所谓的自豪感不过是"孤芳自赏".

原则七:使用 shell 脚本来提高杠杆效应和可移植性

谈起脚本语言,很多工程师觉得脚本太弱了,只能用来编写简单的应用无法工程化,并且不少程序员更乐于哪些看起来宏大的 java 或者 net 应用,甚至有些程序员认为脚本语言算不上一门语言。现实给了我们一巴掌:我们从来没有想象过 javascript 会有如此发展,以 node 为代表的新型开发平台,让整个 JavaScript 语言变得非常有活力。

那么我们是否也小觑了 shell 这种简单的脚本语言呢?有很长一段时间我不能正确的认识 shell 是什么,甚至觉得"嗨,这东西好像对我没什么用,它能用来干什么".让我改变想法的恰好是15年的工作经历。

和其他脚本语言(如:python,JavaScript)一样,shell脚本同样由一个或者多个语句组成,通过调用本地程序,解释程序和其他脚本来执行任务。shell脚本将每条指令加载到内存执行。大部分情况下,这些指令是由无数的unix/linux开发者事先编写完成,我们要做的就是用shell来间接的利用这些高效,安全的代码。

比如在shell中使用wget命令来下载文件时,我们实际书写的不过几行语句,背后支撑我们的确有数万行的代码,如果让你来用java写一个下载器会需要多少工程量呢,又需要耗费多少时间?现在有些程序员会反驳我:我用python写起来也很快,代码也不多?那问题来了,python的运行环境可不是先天就存在unix/linux中的,但是大部分unix/linux却都是支持shell的。如果编写的脚本程序要运行在不同的系统中或者运行在许多设备中,shell无疑具有更好的移植性,不是么?

如你所想,及时运行

脚本语言有一个先天的优势就是他们是解释型的语言,运行前不需要事先编译。先来看看以 C 语言为代表的编译型语言,要构建一个程序的基本流程如下:思考

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部