松本行弘的程序世界——编程语言知多少

第一次读这本书,是我还在读书的时候,那时的我正为C++这样的语言而苦恼,就这样接触了ruby,ruby是一门动态类型的语言,语法优雅,非常灵活,也因为它我开始开发web程序。这本书并不是一本ruby程序指南,而是一本描述程序世界的书籍,虽然讲得不那么深入,却很广泛。

matz

一、我为什么开发Ruby

编程语言的重要性

语言体现了人类思考的本质。因为语言,人与人之间才能传递知识和交流思想,才能做深入的思考。在语言学领域,有一个Sapir-Whirf假说,认为语言可以影响说话者的思想,即语言的不同,造成了思想的不同。在这里,我觉得计算机语言很符合这个假说。程序员由于使用的编程语言不同,他的思考方法和编写出来的代码都会受到编程语言的很大影响。

Ruby的原则

Ruby编程语言的设计目标是轻松编程、提高开发效率。

三个原则:

  • 简洁性
  • 扩展性
  • 稳定性

简洁性

面向对象编程——面向对象的思想只是把数据和方法看作一个整体,当做对象来处理,并没有解决以前解决不了的问题。面向对象的方法并没有实现任何新的东西,却要在运行时判定要调用的方法,倾向于增大程序的运行开销。实现同样的算法,面向对象的程序往往更慢,过去计算机的执行速度不够快,所以不容许这样的浪费。

内存管理,不用的内存现在可用垃圾收集器自动释放,而不用程序员自己去释放。变量和表达式的类型检查,在执行时已经可以自动检查,而不用在编译时检查了。

如果可以把伪代码中非实质性的东西去掉,只保留描述算法的部分就直接运行,那么这种编程语言不就是最好的吗?ruby的目标就是成为开发效率高、“能直接运行的伪码式编程语言”。

扩展性

编程语言作为软件开发工具,其最大的特征就是对要实现的功能没有限制。“如果想到就可以做到”,这听起来像小孩说的话,但这在编程语言的世界里,真的就是这么一回事。不管在什么领域,做什么处理,只要用一种编程语言编写出了程序,我们就可以说这种语言适用于这一领域。

实现扩展性的一个重要方法是抽象化。抽象化是指把数据和要做的处理都封装起来,就像一个黑盒子,我们不知道内部是如何实现的,但是可以用它。ruby在扩展性上看重的是如何最大限度地发挥程序员自身的能力。

稳定性

我相信,作为在世界上广泛使用的编程语言,应该有稳定的语法,不能像随风飘荡的灯芯那样闪烁不定。注:作者以Lisp的宏为例,指出了提供巨大的扩展性的同时也使得程序难以理解和阅读。

二、面向对象

程序员控制计算机,还是在为计算机工作?

阿尔法综合征——指在伺养宠物的时候,宠物狗误解了一直细心照顾它的主人的地位,反而感觉到它是主人,比主人更了不起。

几乎所有的编程语言都具备“图灵完备”的属性,无论何种编程语言都可以实现等价的程序,但这并不是说选择什么样的编程语言都一样。每一种语言都有自己的特征、属性、都各有长处和短处,写程序的难易程度也有很大的不同。

编程技巧:

  • 编程风格
  • 算法
  • 数据结构
  • 设计模式
  • 开发方法

面向对象编程

面向对象的设计方法是20世纪60年代后期,在诞生于瑞典的Simula编程语言中最早使用。Smalltalk编程语言对近代面向对象编程语言影响很大,可以称之为面向对象语言之母。到现在,大多数主流的编程语言使用的都是面向对象的设计方法。

多态性

多态就是可以把不同种类的东西当做相同的东西来处理。各种数据可以统一地处理、根据对象的不同自动选择最合适的方法而程序内部则不发生冲突、具备扩展性。

数据抽象和继承

数据抽象有时也会称为封装,多态性、数据抽象和继承被称为面向对象编程的三原则。

面向对象的历史

Simula语言最早引入了数据和处理数据方法自动结合的抽象数据类型。随后,又增加了类和继承的功能。

Lisp的发展产生了许多很有创新的方法,多重继承、混合式和多重方法等。

C语言是面向过程的语言,在C语言中追加面向对象的功能,产出了C++。

复杂性

虽然计算机的额性能年年在提高,但它的处理能力终究是有限的,而人类的理解力的局限性给软件生产力带来的限制性更大。为了找到迅速开发大规模复杂软件的方法,有时牺牲性能也在所不惜。

结构化编程

结构化编程的基本思想是有序地控制流程,即把程序的执行顺序限制为顺序、分支和循环3种,把共通的处理归结为例程。结构化编程引入了例程的概念,也就是把基本上相同的处理抽象成例程,其中不同的部分由外部传递进来的参数来对应。结构化编程的限制和抽象化是人类处理复杂软件的非常有效的方法。结构化编程的顺序、分支和循环可以实现一切算法,虽然降低了程序的复杂性和灵活性,但是程序的实现能力并没有降低。现在几乎所有的编程语言都支持结构化编程,结构化编程也成为了编程的基本常识。

数据的抽象化

结构化编程降低了程序流程的复杂性,但却不能解决数据的复杂性,面向对象就是为此而出现的。数据抽象是数据和处理方法的结合。对数据内容的处理和操作,必须通过事先定义好的方法来进行。数据和处理方法结合起来成为了黑盒子。

继承

继承就是在保持既有类的性质的基础上而生成新类的方法。原有的类称为父类,新生成的类称为子类。子类继承父类所有的方法,如果需要可以增加新的方法,也可以重写从父类继承的方法。

  • 单一继承
  • 多重继承(一个对象有多个父类,如一个公司员工可能同时是一个父亲、儿子)

单一继承——单一继承关系是单纯的树结构,类之间的关系单纯就不会发生混乱,实现起来也比较简单。
多重继承——继承多个类,程序代码共享。单一继承可以实现的功能,多重继承都可以实现,但是类之间的关系会变得复杂,哪个类的功能继承自哪个类就变得难以理解。

多重继承导致的问题:

  • 结构复杂化
  • 优先顺序模糊
  • 功能冲突

ruby中多重继承的实现——“Mix-in类”,Mix-in类是具有以下特征的抽象类:

  • 不能单独生成实例
  • 不能继承普通类

实现功能共享的方法是把共享的功能放在Mix-in类里面,然后把Mix-in类插入到继承树里面。

Duck Typing

If it walks like a duck and quacks like a duck,it must be a duck(走起路来像鸭子,叫起来也像鸭子,那么它就是鸭子)

动态类型的缺点:

  • 执行时才能发现错误
  • 程序阅读可能不好理解
  • 运行速度会比静态类型慢

元编程

在ruby中可以方便的动态给类增加方法。静态类型的语言中这是很难做到的。

反射

指在程序执行时取出程序的信息或者改变程序信息,实现对程序的动态操作。

元编程和小编程语言

DSL是针对特定领域的语言,小编程语言一般会具备如下功能:

  • 类型
  • 字面量
  • 表达式
  • 运算符
  • 语句
  • 控制结构
  • 声明
  • 上下文相关
  • 单位
  • 词汇
  • 层级数据

程序块

程序块是ruby语言的特色之一,在方法调用时可以追加代码块。

ary.each { |x| puts x}

高阶函数

ruby程序块功能的原理和高阶函数是一样的。高阶函数是指以函数作为参数的函数。为了实现高阶函数,编程语言中必须把函数和方法作为数据来处理。

四、设计模式

设计模式指设计上经常反复使用的模式。在软件中,重用一般是通过库,各种软件共享处理过程、数据结构以及类等。但是只有库还不能达到充分地的共享,软件设计中除了库还有共通的部分即模式。

23种常用设计模式

设计模式

prototype模式

Prototype(原型)模式”明确一个实例作为要生成对象的种类原型”,通过复制该实例来生成新的对象。
相对于类模式的编程,原型模式的编程的构成元素比较少,具有简单实现面向对象功能设计的倾向。

五、Ajax

Ajax的最大特点是进行异步操作。异步意味着,Web浏览器的通信和页面更新是相互独立的。

老式的浏览器通信方式:
每当用户进行操作之后,需要更新页面,在得到服务器的响应之后,下一个页面才能显示出来。
Ajax的通信方式:
Ajax技术中,对于用户进行的操作,基本是由Javascript在Web浏览器中进行响应。仅在数据必须从服务器获取的情况下,才在后台进行异步通信。

http

支撑Ajax的3个主要技术:

  • Javascript
  • XML
  • DHTML

Javascript进行异步通信的对象的名字是XMLHttpRequest.

DHTML:动态的HTML,可以动态地对HTML进行引用、修改和更新。它是利用装载在网页中的Javascript,使用DOM(文档对象模型)对网页数据进行操作。

Ajax网站特点:

  • 没有Web页面跳转
  • 通过异步通信实现快速反应

第六章 Ruby on rails

Web应用的基本是HTTP,一次HTTP处理经过如下的过程:

  • Web浏览器对应于用户的操作,像Web服务器发出HTTP请求
  • web服务器根据请求,准备好发送到Web浏览器的数据
  • Web服务器把数据以HTTP响应的形式送还Web浏览器

MVC模式对应上面的各个部分如下:

  • Web浏览器发送来的HTTP请求通过Web服务器传给控制部分。Web应用框架的分配器(路由)把请求传递给合适的控制部分。
  • 控制部分操作的模型和请求的信息相对应,同时指定显示使用的视图。视图从模型启动,一边引用模型一边准备发送给Web浏览器的数据。
  • Web服务器把数据以HTTP响应的形式送还Web浏览器。

web应用中的MVC

MVC的具体实现可能会有细微的差别,如rails的MVC与传统的MVC就有一些不同。

第七章 文字编码

计算机能够处理图像、动画及各种应用程序固有的、多种多样的数据。但从CPU的层次来看,计算机所处理的各种数据都是用比特所表现的二进制数字。为了让计算机能够处理文字,就必须将文字变换为相应的数字。这种对应于文字的数值就称为文字编码。文字的集合称为字符集;在字符集中,每个字符都分配一个编码,这称为字符编码。计算机上仅仅用整数值来表示文字编码的方式称为文字编码方式。计算机不能处理文字本身,就要让文字与编码对应。与文字相对应的编码就称为文字编码。这样计算机只能处理分配了编码的文字,分配了编码的文字集合就称为文字集。

为什么会发生乱码?

文字乱码最大原因是把程序的字符编码方式搞错了。把一种字符编码方式的数据按另一种字符编码方式来表示,结果就会完全不同。为了在计算机画面上表示文字,还需要文字编码及文字编码以外的东西。与某种文字编码相对应的文字应具备何种字形的信息由计算机掌握,根据需要,必须将字形在画面上表示出来。这样的字形数据称为字体。如果没有对应的字体信息,就会出现乱码。

第八章 正则表达式

正则表达式主要用来处理字符串,是一种描述字符串模式的微语言。

第九章 整数和浮点小数

作为高级程序员,应该有更高的目标。如果计算机中能够自然计算的整数有上限,就要想办法引入多倍长以超越界限;为了能除尽,就引入有理数等。如何权衡计算效率以达到最大限度的平衡技巧。

第十章 高速执行和并行处理

两个法则:

  • 帕累托法则:80:20法则
  • 摩尔法则:即大规模集成电路中的晶体管数每18个月翻一番。

第十一章 程序安全性

4种软件漏洞:

  • DOS攻击
  • 信息泄露
  • 权限夺取
  • 权限升格

DOS攻击:也称拒绝服务攻击,是指妨碍软件正常运行的网络攻击手段。能够引起软件异常终止的程序错误,可以说全部都是引发DOS攻击的安全性程序错误。
信息泄漏:指不愿公开的信息被公开了,比如用户名被公开或密码暴露。

有代表性的攻击手段:

  • 缓冲区溢出
  • 整数溢出
  • 跨站脚本攻击(XSS)
  • SQL注入
  • 跨站点伪造请求(CSRF)
Prev Next