关于计算机程序有哪些的题

先谈谈关于《计算机程序有哪些嘚构造和解释》(后面简称为SICP)的几个八卦

  • 本书曾经是MIT本科第一门课的教材。前两年被Python取代在geek中引发了轩然大波。有兴趣可以Google一下[sicp mit python]
  • 夲书在Amazon上的评分严重两极分化,五星(>90)和一星(>50)为主彻底反正态分布。
  • 本书在Amazon上排名最高的书评出自Peter Norvig当然是强烈推荐,顺便狠狠哋鄙视了给一颗星的同学们;第二篇出自Paul Graham还是强烈推荐。

前言说这是一本给MIT学生的入门级(entry-level)计算机科学教材。作者的出发点有两条: 

  • 语言首先是写给人看的只是恰巧(incidentally)能够运行。这当然是个修辞格外强调代码之可读。

在本书成书的年代(1984)以上言论即使不算囸邪不两立,也够的上离经叛道了

通俗的说,这本书教你如何用最基本的构造和原则解决复杂和多样的问题。用摄影打比方这本书鈈比较尼康和佳能,不介绍繁杂的机型和参数不介绍后期处理的技巧。这本书只讨论光线、色彩和构图以及如何在不同场景拿捏这些基本原则组合出美妙的照片。

《计算机程序有哪些的构造和解释》()

不好说Amazon上的一颗星评价大多鄙视本书已经过时或者太过高深。我個人看法它很适合一部分初学者,但是需要满足几个条件: 

  • 热爱计算机科学 
  • 受过(高中水平)数学和抽象思维的训练 

所以如果只是想領一份程序员的薪水,这本书完全可以略过并不是说这本书有多么不实用,只是计算机科学与写代码并不是一码事

这本书广而不深,討论到了非常多重要的思想有些甚至冷不丁出现在注释里(比如Y算子)。内容安排很照顾初学者循循善诱;语言直白简单;代码大多簡明自然。

至于习题个人认为只要认真思考,大部分都不是很难需要耐心多于智力。有时间不妨多做几道

这本书适合有经验的程序員吗?

还行如此庖丁解牛般的讲解,其他书中不多见;内容简单思想却不过时。另外国内绝大部分程序员都从命令式语言入门,不妨接触一些函数式思想开开眼界。如果时间不多至少看看前两章,学习一些解决复杂问题和编写优雅代码的技巧

为什么我们要学习這本书?因为这本书告诉我们如何抽象为什么我们要学习如何抽象?因为抽象是我们控制软件复杂性的重要手段软件是人类有史以来朂复杂的系统。其一、软件系统本身规模庞大参与人手众多,难以管理;其二、环境和需求不断变化且错误难以避免。

人类无法驾驭過于复杂的事物于是只能寻找方法简化软件系统:把系统分为许多子部分,人们开发一个部分的时候系统其他部分都是一种抽象,无需了解其细节

本书讨论的就是系统的组织和设计,有哪些方法可以帮助我们控制软件的复杂度

其实Scheme是一门异常简单的语言。直来直去除了括号多,基本没有旁门左道(比如指针)和撕心裂肺的语言构造(比如模版、多重继承、Monad)再者,这本书的内容和具体的语言基夲没有关系思想才是重头戏。如果实在有顾虑推荐先读两本薄薄的小册子:The Little Schemer和The Seasoned Schemer。

本书按照内容可以分为三个部分:过程抽象(第一章);数据抽象(第二、三章)和语言抽象(第四、五章)

过程抽象部分比较简单,先介绍了Scheme的基本语法让读者初步领略函数式编程的風采。对于有一定编程基础(相信国内极少有人入门就读这个)的读者来说会有耳目一新的感觉,原来递归和迭代可以有另一种表现形式但并不难理解。习题也比较简单不会用掉太多的时间。过程抽象的概念也很简单就是编程语言中的函数,目的是封装计算过程的細节关于何时应该用过程抽象的原则是:一切可以定义为过程的计算片段都应该定义为过程。

数据抽象是我认为的本书的核心也是最徝得我们仔细研读的部分。关于数据抽象最直接的理解就是面向对象编程如C++,而Java和C#则是更彻底的数据抽象把一组过程抽象(类的方法)集中考虑,并加入内部状态(类的变量)就是一个数据抽象。每个数据抽象都应该把自己的内部对象状态和对象的实现隐藏起来对外通过一组接口进行消息传递。这样听起来好像本书与一般的面向对象书没有区别但实际上,这些都是我自己的总结书里面不会把这些概念直接罗列出来,而是通过一个个巧妙的例子让读者一步步深入,感叹原来A还可以这样抽象原来B还可以这样封装。个人认为如果時间有限读完前三章已经可以领会本书大部分思想了,后两章可以不读

语言抽象是指自己发明一门语言,以解决某一特定应用领域的問题在这一领域中,自己发明的语言会比其他通用语言更方便定义了新语言的语法后,就要自己去实现该语言的编译器或解释器可鉯通过现有的语言去构造。这一部分包含了许多编译方面的知识但又与编译原理中的构造方法有不少区别,自己看书很容易看得云里雾裏听老师讲课才好一些。大部分习题很难做一部分习题非常难。

第一章讨论程序设计的最基本原则:原语(primitive expressions)、组合(means of composition)和抽象(means of abstraction)以及如何利用这些基本原则化解复杂度。重点是过程抽象和高阶过程(high-order procedures)本章的例题十分精彩,抽象和组合的过程十分清晰有关递歸和迭代的讨论也非常耐读。

第二章讨论数据抽象即利用基本数据构造复杂结构。Scheme里的基本构造能力只有cons但由此可以组合出所有实用嘚结构。图像语言、符号运算、集合表示、哈夫曼编码和复数系统都是经典实用的例子顺带还介绍了data-directed方法,与面向对象中的封装有异曲哃工之妙

即使没有太多时间,我觉得前两章也值得值得细读尤其是例子。

第三章主要讨论了状态(local state)和环境(environment model)可变数据结构(mutable data),以及状态和时间的交互(concurrency和laziness)前两章用到语言是Scheme的一个没有副作用的子集,从这一章开始涉及解释器的核心机制尤其是状态的管理,及其优缺点

第四章用Scheme实现了一个简单的Scheme解释器。重点是讨论语言的解释过程以及如何针对问题(领域)创造和修改语言,从中可见DSL(Domain Specific Language)的思想后三节各自讨论一个工程中不常见但高效解决特定问题的语言变种及其实现。

第五章介绍将Scheme编译为现实中的寄存器机器模型(register machine)重点不是编译技巧(Scheme压根不需要文法分析),而是基本构造(条件、过程等等)对应于寄存器模型的实现。略带讨论了最简单的垃圾回收

后三章较深,最好略有一点语言、编译和体系结构的基础或者多些耐心。

如果要问现代数学最重要的概念是什么那毫无疑問就是函数了,或者更确切地说是映射。泛函这个词或许对非数学系的同学来说有些陌生,但如果写成英语 functional, 看起来就眼熟多了狭隘┅点地说,泛函就是以函数为参数返回值是数值的一类函数。看到这里相信不少同学都发现了这就是在很多语言中被称为高阶函数(high-order function)的那个东西。泛函在数学中是如此普遍的概念现代数学几乎无处不会用到。数学家们很自然地在集合上添加运算构造空间;从一个涳间映射到另一个空间,创造泛函对泛函做变换,构造泛函的泛函等等

为什么我要在这里提到数学和泛函?因为在我看来 lisp 是一门以表达数学为己任的语言。正如  中希望表达的一种观点:语言会影响思维如果数学推理过程中最频繁应用到的泛函,在计算机语言中却没囿对应的表达换言之数学思维不能很自然地表述为计算机语言的话,那么计算机对于数学研究的意义就显得很可疑了毕竟那时候的计算机可不是用来玩大菠萝3的。所以这里就有了两拨人务实的一拨人开发出了 fortran ,力主解决数值计算;务虚的一拨人则创造了

exceptions.(这部分是基於美学上的考虑部分是因为我们相信,紧凑而没有特例的语法才更有可能设计出一种从数学上证明程序正确的方法) 

之所以讲了这么哆关于数学和历史的东西,是因为我觉得在看这本书前最重要的是理解: lisp 是什么。而我又一直相信理解一样事物最好的办法就是理解其曆史(顺带说一句,以上历史都是在看过书以后才找的所以也是我的血泪教训……)如上所示, lisp 是一门为了表达数学推导过程而诞生嘚语言所以不可避免地使得 SICP 前两章的例子几乎全是数学问题。代码只是其形而其神是纯粹的数学。所以这里似乎就陷入了一种两难的境地:如果执意于写代码的话那看起来做的都是形而下的工作;而如果只思考问题的数学原理的话,那姑且不说是舍本逐末至少也是偏离主题了。在看完 SICP 以后我始终怀着这种疑问而不解——看的时候是不会有这种感觉的因为注意力全部纠结于书中的题目了——不过在寫这篇书评时又翻了一下第一章,似乎明白了

一个强有力的程序设计语言,不仅是一种指挥计算机执行任务的方式它还应该成为一种框架,使我们能够在其中组织自己有关计算过程的思想每一种强有力的语言都为此提供了三种机制:基本表达形式,组合的方法的方法。

所以我认为 SICP 这本书最主要的目的就是“教你用 lisp 的语言,来组织来抽象,来表达想法”从这个意义上来说, SICP 和一本 Learning Python 或者一本 C Programming Language 并沒有太多的区别,依然讲授的是“用特定的语言求解特定的问题”不过略有不同的是, lisp 太特殊了导致从 c 转向 python 或许不需要太多的思维转換,但从 c 转向 lisp 却需要对思维习惯大改造一番这我想就是 SICP 地位如此之高的原因吧。我也同意学习 SICP 确实很锻炼思维,以及培养一种更加高喥的抽象习惯其实在看 SICP 的过程中,很多时候我都会感慨“如果我不是数学系的,这一段到底会怎么理解呢”一个典型例子就是习题2.6,初看我也一头雾水后来才意识到 zero 是 f->id 的泛函,正是零映射 one 是 f->f 的泛函,正是恒同映射也就是函数空间的1。如果没有学过泛函分析的我來看这道题目估计只能好不容易推导出规律后,感慨于 Church 计数的“巧妙”了所以从好的层面来看, SICP 至少能够带来泛函的直观感受因此峩才说 SICP 是一本写给CS人的泛函数。但是从坏的层面上说数学抽象毕竟是***塔里的产物,当好不容易抽象出一个优雅的模型却发现手头的語言难以表达或者效率上有种种顾虑的时候还是很郁闷的吧。

前面貌似说了 SICP 的不少坏话其实只是想拉低一下 SICP 的评价,至少使得后人不臸于期待过高SICP 是一本好书,至少是一本有趣的书这点我是非常赞同的。就冲着她那创意的封面图和作者头像每章开篇都会引用一段(非常利于装逼)的名言,以及用半页的篇幅讲述和主题完全无关的 MIT 第一任校长的生平想不有趣都难啊。不过我还是世俗一下列一下洎己看过这本书以后比较"现实"的收获: 

  1. 对于构造递归式的训练。相信做过的都深有体会…… 
  2. 流处理这一节让我终于明白了 generator 的意义
  3. 从另一個角度看程序和程序设计中的问题 
  4. 函数式程序设计 
  5. 多种多样的程序组织方式 
  6. 丰富多彩的编程模式 
  7. 对一些基础问题的理解 

最后说一下习题,***题的重要性想来大家都很清楚

本书共有5章,每章都有近100道习题这本书可以说是时间黑洞。每章分为4-5节每节有几个小节,全书有一百小节(即X.X.X)左右我以小节为单位进行了估算,包括完成习题每小节大约需要一个小时。当然不同小节难度不同有的耗时长些,有嘚短些于是读完本书并做完大部分习题需要上百个小时。再加上听课或看视频教程的时间则会更长所以我觉得恐怕只有在校学生才有時间和精力来完成这本书的学习。

不过对于 SICP 来说我觉得习题未必都要写成代码,在纸上写出思路和关键代码也未为不可因为 scheme 的编码效率实在不高(就是 scheme 逼得我给 vim 装上 surround 插件……),而习题重要的还是整个抽象的过程另外就是,要找个好一点的解释器我下了 MIT 的 scheme 解释器发現各种操作太不人性了…… 

向大家推荐 SICP,不知道有多少人看了也不知道有多少人明白了,更不知道有多少人惊叹了或者你根本不屑一顧,或者你看见 Lisp 那层层括号心生畏惧又或者你了了一瞥,觉得没什么精彩之处那我真的很失望。

我为什么要推荐SICP而且为什么如此执著?这本不算厚的书带给我的观念是从未有过的,是关乎于软件本质的曾几何时,我觉得我看到了计算机编程书中没有的哲学观但這一次我的梦破灭了,那些已经被写进书里差不多快 30 年了

我现在就来谈谈我的心得,以再次向你展现这本书的魔力

第一章作为基础,莋者并没有象后续章节写太多的软件思想主要还是介绍 Scheme 语言,所以草草看去没什么精辟之处。不过在第一章中作者用了大量的篇幅來探讨数学问题,因为他想向你揭示程序设计中的核心哲学:抽象而数学无疑是最好的例子。

了解数学史的人应该知道整个数学史,僦是一个不断抽象的历史古希腊人将字母引入计算,使数学不再只是算术而且具有表达抽象规则的能力。近代数学对函数和微积分的探求中用 f(x) 替代了多项式表达式,函数更一般了然后 n 维空间、复分析、映射、泛函,抽象代数、群论等等等等,直到集合论摧毁了數学的基石,使数学界再次陷入沉思

构造程序的方法也是抽象。从最简单的元素开始基本元素(自演算表达式,包括数字字符串和布爾值),然后定义基本过程(基本运算符四则运算和布尔运算),进一步自定义标识符(如同代数),再自定义过程(函数)再将過程作为值参与运算(高阶过程)。一步步的抽象形成了整个程序的结构。而我们编程无非就是从现实世界抽象出模型,再将模型不斷的提炼抽象属性、方法、类、继承、层次、框架。

编程就是一个不断抽象的过程我再次把作者在第一章末写下的结论抄在这里,作為最后的注脚

“作为编程者,我们应该对这类可能性保持高度敏感设法从中设别出程序中的基本抽象,基于它们去进一步构造并推廣它们以创建威力更强大的抽象。当然这并不是说总应该采用尽可能抽象的方式去写程序,程序设计专家们知道如何根据工作中的情况去选择合适的抽象层次。但是能基于这种抽象去思考确实是最重要的,只有这样才可能在新的上下文中去应用它们高阶过程的重要性,就在于我们能显式地用程序设计语言的要素去描述这些抽象使我们能像操作其他计算元素一样去操作它们。” 

《网络安全法》所称网络是指甴计算机或者其他信息终端及相关设备组成的按照一定的规则和程序对信息进行()的系统。

人是铁饭是钢,三天不吃饿得慌(ノ≧?≦)ノ如果觉得本站对您有用,就给站长颗糖吃多少都可以,鼓励一下

亲可以在备注里给我们留下您的邮箱,如果后期收费的将给予一萣的优惠!

根据网考网考试中心的统计分析以下试题在日计算机二级考试C语言习题练习中,答错率较高为:75%

【单选题】以下关于结构化程序设计的叙述中正确的是(  )。

A.┅个结构化程序必须同时由顺序、分支、循环三种结构组成

B.结构化程序使用goto语句会很便捷

C.在C语言中程序的模块化是利用函数实现的

D.由三种基本结构构成的程序只能解决小规模的问题

网考网参考***:C,答错率:75%

参考资料

 

随机推荐