从SICP里学到的

这是一本能陪你走到职业生涯终点的书籍。

概述

一般而言,相比较"术"而言,讲述"道"的书才可能成为经典。而这本成书于1986年的紫色书籍,恰好是这样一部经典之作。这里只是记录笔者一些个人的思想总结。虽然粗浅,但贵在真实。

代码是供人读的

很多推荐本书的人在总结本书的核心思想时候都会提及以下两个观点:

  1. 程序首先是给人读的,只是恰好可以被机器执行。
  2. 与程序而言,最最重要的是控制软件的复杂度;相比较之下,算法和数据结构在此之后。

借SICP视频里的一句话: “machine does not care, i care!”。所以代码规范真的不能只落在口头上啊。

wishful thinking(按愿望编程)

  1. 书写递归的必备思想。
  2. 真正接受这个思想时候,你的设计自然就会变成依赖于抽象,自然而然达到松耦合。
  3. 经典例子就是三步实现汉诺塔,我们以四阶举例:
    1. 先将前三个移动到中转位置;
    2. 再将最后一个移动到目标位置;
    3. 最后将前三个移动到目标位置;
  4. 这里面还有一个非常重要的疑问:为什么我们可以这么做? 为什么我们可以这么去假设,这么去wishful thinking?
    • 因为我们在减小问题的规模
    • 我们将问题从移动四个,变成了移动三个;
    • 依此递归下去,我们最终就能将问题减小到可以一步解决;
    • 最终实现整个问题的解决。

layer system(按层次划分系统)

  1. 应对需求变更的终极大招。
  2. 我们将系统构建成一个layer system的目的就是为了当外界需求发生变化时, 我只需要修改某一层的某一部分, 而这一层的上下层都对这个变化没有感知。
  3. layer system的基本思想是上面一层完全依托于下面一层的api进行构建, 也就是说,其实在layer system中每一层都是拥有构建完整系统的能力的。
  4. 当新需求到来时,如果发现在上一层无法被解决, 我们就可以进行降层, 在下面一层尝试进行解决. 最终将需求就被限定到一个尽量小的范围。
  5. 这种思路在所有的大型软件中都能看到, linux就是最好的例子。

Abstract(抽象)

  1. it is not for machine, it is for human. because our brain can not put all things in it at once。好吧, 这句英文是我自己的总结。
  2. 很早以前开始软件的复杂度就已经大大超出了人类大脑所能控制的范围,再明确一些就是如果你想将这些软件的细节一次性地都放进你的大脑,这是绝无可能。
  3. 所以我们需要一些方法, 而这些方法并不是软件行业独创的, 而是人类使用大脑思考以来就一直在使用的方法. Abstract就是这其中非常关键的一种.
  4. 正是有了Abstract, 在软件规模继续保持暴增的情况下, 人类依然牢牢掌握着主动权。
  5. 抽象其实无处不在, 一提到抽象就想到接口, 抽象类。其实变量名,方法就是一种抽象。抽象的另外一层意思就是要学会去忽略细节。就像上面提到的, 软件里最终是要构建一个layer system, 这样就能做到最小化改变适用新需求. 而这个layer system的表现就是:
    1. 不论你处在抽象层次中的哪一层 ,当你对底层进行分析查看 ,就会发现依然无数的抽象层次的存在。
    2. 所以你需要做的事情之一就是学会忽略某些细节。
    3. 理解复杂事物的关键之一就在于:你需要清楚知道应该忽略掉那些次要的东西,而将注意力集中到那些真正需要考虑的事物上。

推迟作决定的时机

单看这句话会比较玄幻, 其实举几个例子就理解了。

  1. 很多时候我们不想要被此时的决定束缚住手脚,导致之后的工作因当前的决定而步履维艰。但我们又必须作出某种决定以便让接下来的工作得以进行,于是我们可以假装实现了这个功能(假装已经做出了这个决定,Wishful Thinking)来让工作得以继续;待到真正需要这个功能时,才去实现它(真正地做出来决定)。使用这种方法可以让我们的程序变得非常稳固,能够自如地应对外界的变化。
  2. “面向接口编程”,相信此类言论已经被你们听烂了吧。那我给一种新的解释,希望能带来一点不一样的感悟 —— 建立接口的目的就是为了推迟作决定的时机
    1. 定义接口就是假装作出了这个决定。
    2. 而实现接口则是真正地作出这个决定。
    3. 上面两个行为是有时间差的。而且这个时间差越大,你的程序就越灵活
    4. 熟悉Java的同学应该都知道多态属于一种"动态绑定"吧。所谓的动态绑定不就是到真正需要的时候才去找实现者吗?
    5. 而我们所熟悉的反射也是“推迟作决定的时机” 又一佐证。

高阶函数

接受这种思想的结果就是极度模糊化 data与function之间的界限

直接看例子

  var consResult = cons(34,35);
  car(consResult);   // 34 ; 获取第一个参数
  cdr(consResult);   // 35 ; 获取第二个参数

看到以上的结果, 出现在你大脑中的实现过程大概应该是这样的:

    function cons(x, y) {
        return [x,y];
    }

    function car(p) {
        return p[0];
    }

    function cdr(p) {
        return p[1];
    }

但是其实我们可以在只使用Process的情况下实现同样的效果.

    function cons(x, y) {
        return function (z) {
            if (z === 1) {
                return x;
            } else {
                return y;
            }
        };
    }

    function car(p) {
        return p(1);
    }

    function cdr(p) {
        return p(2);
    }

模糊化data与function的好处:

  1. 高阶函数让我们拥有了更高的抽象层次。
  2. 通过接收function, 我们即可以实现多态的功能。这也符合OOP指导思想中的"使用组合代替继承"。
  3. 在下面要讲到的Stream Process中你会发现, 为了达到和命令式编程一样的性能,我们就需要求助于这种思想。

Stream Process(流式处理)

按照书中作者的介绍,这种处理思路是从电气化工程师那里学来的。这里我们不去八卦这些趣闻,直接以一个例子"遍历一颗正整数组成的树,获取其中所有的奇数,并取它们的平方和?"来开始本小节的讨论。

一般方式是使用递归,其中包含了遍历,树节点类型判断,奇偶判断, 平方计算,和的计算等,这些操作被糅合在一起循环往复,我们的大脑需要在这些操作中不断地进行跳跃并时刻警惕自己当前所处的环节以及上下环节的影响乃至当前操作对全局的影响,说得高深一些就是我们要时刻警惕时间因素的影响。我们要时刻记住自己当前在处理什么,在进行何种操作。

而使用流处理, 你就能将它们拆解出来, 这样处理过程就变得非常清晰:

  1. 遍历出树中所有的数据;
  2. 过滤出其中的所有奇数;
  3. 将上面过滤出来的奇数进行平方的映射操作;
  4. 将上一步的结果进行求和;

以上的流处理过程,非常符合人类大脑的思维习惯。使用Stream Process之后, 我们就将问题拆解为一系列协议接口(Convention Interface)的顺序调用,只要遵从了彼此间的这些协议, 上面步骤中的每一步都是可以被替换的,这样系统就天然具有了松耦合的特性。

对于接触过.NET,Java的研发人员,以上思想是不是非常熟悉?

结语

  1. SICP这本书在专业书籍里一直被笔者放在第一的位置,从未动摇。
  2. 这本书的吞噬时间的能力真是非常恐怖,导致笔者这种半路出家,大学毕业之后三年才转入IT行业的,最终选择了视频的方式来接受两位作者的教诲。
  3. 非常感谢LearningSICP群主的努力,无法直接分担汉化的工作,就只能做一些小的捐助聊表心意了。
  4. 最近才知道两位教授还健在,祝愿他们身体健康吧。其实我蛮想要一本有着他们签名的英文版SICP。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342