2016年8月26日星期五

阮一峰的网络日志

阮一峰的网络日志


HTTPS 升级指南

Posted: 25 Aug 2016 05:21 PM PDT

上一篇文章我介绍了 HTTP/2 协议 ,它只有在 HTTPS 环境才会生效。

为了升级到 HTTP/2 协议,必须先启用 HTTPS。如果你不了解 HTTPS 协议(学名 TLS 协议),可以参考我以前的文章。

本文介绍如何将一个 HTTP 网站升级到 HTTPS 。

一、获取证书

升级到 HTTPS 协议的第一步,就是要获得一张证书。

证书是一个二进制文件,里面包含经过认证的网站公钥和一些元数据,要从经销商购买。

证书有很多类型,首先分为三种认证级别。

  • 域名认证(Domain Validation):最低级别认证,可以确认申请人拥有这个域名。对于这种证书,浏览器会在地址栏显示一把锁。
  • 公司认证(Company Validation):确认域名所有人是哪一家公司,证书里面会包含公司信息。
  • 扩展认证(Extended Validation):最高级别的认证,浏览器地址栏会显示公司名。

还分为三种覆盖范围。

  • 单域名证书:只能用于单一域名,foo.com的证书不能用于www.foo.com
  • 通配符证书:可以用于某个域名及其所有一级子域名,比如*.foo.com的证书可以用于foo.com,也可以用于www.foo.com
  • 多域名证书:可以用于多个域名,比如foo.combar.com

认证级别越高、覆盖范围越广的证书,价格越贵。

还有一个免费证书的选择。为了推广HTTPS协议,电子前哨基金会EFF成立了 Let's Encrypt,提供免费证书(教程工具)。

拿到证书以后,可以用 SSL Certificate Check 检查一下,信息是否正确。

二、安装证书

证书可以放在/etc/ssl目录(Linux 系统),然后根据你使用的Web服务器进行配置。

如果使用 Let's Encrypt 证书,请使用自动安装工具 Certbot

安装成功后,使用 SSL Labs Server Test 检查一下证书是否生效。

三、修改链接

下一步,网页加载的 HTTP 资源,要全部改成 HTTPS 链接。因为加密网页内如果有非加密的资源,浏览器是不会加载那些资源的。

  <script src="http://foo.com/jquery.js"></script>  

上面这行加载命令,有两种改法。

  <!-- 改法一 -->  <script src="https://foo.com/jquery.js"></script>    <!-- 改法二 -->  <script src="//foo.com/jquery.js"></script>  

其中,改法二会根据当前网页的协议,加载相同协议的外部资源,更灵活一些。

另外,如果页面头部用到了rel="canonical",也要改成HTTPS网址。

  <link rel="canonical" href="https://foo.com/bar.html" />  

四、301重定向

下一步,修改 Web 服务器的配置文件,使用 301 重定向,将 HTTP 协议的访问导向 HTTPS 协议。

Nginx 的写法

  server {    listen 80;    server_name domain.com www.domain.com;    return 301 https://domain.com$request_uri;  }  

Apache 的写法.htaccess文件)。

  RewriteEngine On  RewriteCond %{HTTPS} off  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]  

五、安全措施

以下措施可以进一步保证通信安全。

5.1 HTTP Strict Transport Security (HSTS)

访问网站时,用户很少直接在地址栏输入https://,总是通过点击链接,或者3xx重定向,从HTTP页面进入HTTPS页面。攻击者完全可以在用户发出HTTP请求时,劫持并篡改该请求。

另一种情况是恶意网站使用自签名证书,冒充另一个网站,这时浏览器会给出警告,但是许多用户会忽略警告继续访问。

"HTTP严格传输安全"(简称 HSTS)的作用,就是强制浏览器只能发出HTTPS请求,并阻止用户接受不安全的证书。

它在网站的响应头里面,加入一个强制性声明。以下例子摘自维基百科

  Strict-Transport-Security: max-age=31536000; includeSubDomains  

上面这段头信息有两个作用。

(1)在接下来的一年(即31536000秒)中,浏览器只要向example.com或其子域名发送HTTP请求时,必须采用HTTPS来发起连接。用户点击超链接或在地址栏输入http://www.example.com/,浏览器应当自动将http转写成https,然后直接向https://www.example.com/发送请求。

(2)在接下来的一年中,如果example.com服务器发送的证书无效,用户不能忽略浏览器警告,将无法继续访问该网站。

HSTS 很大程度上解决了 SSL 剥离攻击。只要浏览器曾经与服务器建立过一次安全连接,之后浏览器会强制使用HTTPS,即使链接被换成了HTTP

该方法的主要不足是,用户首次访问网站发出HTTP请求时,是不受HSTS保护的。

5.2 Cookie

另一个需要注意的地方是,确保浏览器只在使用 HTTPS 时,才发送Cookie。

网站响应头里面,Set-Cookie字段加上Secure标志即可。

  Set-Cookie: LSID=DQAAAK...Eaem_vYg; Secure  

六、参考链接

(完)

文档信息

2016年8月19日星期五

阮一峰的网络日志

阮一峰的网络日志


HTTP 协议入门

Posted: 18 Aug 2016 06:46 PM PDT

HTTP 协议是互联网的基础协议,也是网页开发的必备知识,最新版本 HTTP/2 更是让它成为技术热点。

本文介绍 HTTP 协议的历史演变和设计思路。

一、HTTP/0.9

HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。

最早版本是1991年发布的0.9版。该版本极其简单,只有一个命令GET

 GET /index.html 

上面命令表示,TCP 连接(connection)建立后,客户端向服务器请求(request)网页index.html

协议规定,服务器只能回应HTML格式的字符串,不能回应别的格式。

 <html>   <body>Hello World</body> </html> 

服务器发送完毕,就关闭TCP连接。

二、HTTP/1.0

2.1 简介

1996年5月,HTTP/1.0 版本发布,内容大大增加。

首先,任何格式的内容都可以发送。这使得互联网不仅可以传输文字,还能传输图像、视频、二进制文件。这为互联网的大发展奠定了基础。

其次,除了GET命令,还引入了POST命令和HEAD命令,丰富了浏览器与服务器的互动手段。

再次,HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。

其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

2.2 请求格式

下面是一个1.0版的HTTP请求的例子。

 GET / HTTP/1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) Accept: */* 

可以看到,这个格式与0.9版有很大变化。

第一行是请求命令,必须在尾部添加协议版本(HTTP/1.0)。后面就是多行头信息,描述客户端的情况。

2.3 回应格式

服务器的回应如下。

 HTTP/1.0 200 OK  Content-Type: text/plain Content-Length: 137582 Expires: Thu, 05 Dec 1997 16:00:00 GMT Last-Modified: Wed, 5 August 1996 15:55:28 GMT Server: Apache 0.84  <html>   <body>Hello World</body> </html> 

回应的格式是"头信息 + 一个空行(\r\n) + 数据"。其中,第一行是"协议版本 + 状态码(status code) + 状态描述"。

2.4 Content-Type 字段

关于字符的编码,1.0版规定,头信息必须是 ASCII 码,后面的数据可以是任何格式。因此,服务器回应的时候,必须告诉客户端,数据是什么格式,这就是Content-Type字段的作用。

下面是一些常见的Content-Type字段的值。

  • text/plain
  • text/html
  • text/css
  • image/jpeg
  • image/png
  • image/svg+xml
  • audio/mp4
  • video/mp4
  • application/javascript
  • application/pdf
  • application/zip
  • application/atom+xml

这些数据类型总称为MIME type,每个值包括一级类型和二级类型,之间用斜杠分隔。

除了预定义的类型,厂商也可以自定义类型。

 application/vnd.debian.binary-package 

上面的类型表明,发送的是Debian系统的二进制数据包。

MIME type还可以在尾部使用分号,添加参数。

 Content-Type: text/html; charset=utf-8 

上面的类型表明,发送的是网页,而且编码是UTF-8。

客户端请求的时候,可以使用Accept字段声明自己可以接受哪些数据格式。

 Accept: */* 

上面代码中,客户端声明自己可以接受任何格式的数据。

MIME type不仅用在HTTP协议,还可以用在其他地方,比如HTML网页。

 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <!-- 等同于 --> <meta charset="utf-8" />  

2.5 Content-Encoding 字段

由于发送的数据可以是任何格式,因此可以把数据压缩后再发送。Content-Encoding字段说明数据的压缩方法。

 Content-Encoding: gzip Content-Encoding: compress Content-Encoding: deflate 

客户端在请求时,用Accept-Encoding字段说明自己可以接受哪些压缩方法。

 Accept-Encoding: gzip, deflate 

2.6 缺点

HTTP/1.0 版的主要缺点是,每个TCP连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。

TCP连接的新建成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(slow start)。所以,HTTP 1.0版本的性能比较差。随着网页加载的外部资源越来越多,这个问题就愈发突出了。

为了解决这个问题,有些浏览器在请求时,用了一个非标准的Connection字段。

 Connection: keep-alive 

这个字段要求服务器不要关闭TCP连接,以便其他请求复用。服务器同样回应这个字段。

 Connection: keep-alive 

一个可以复用的TCP连接就建立了,直到客户端或服务器主动关闭连接。但是,这不是标准字段,不同实现的行为可能不一致,因此不是根本的解决办法。

三、HTTP/1.1

1997年1月,HTTP/1.1 版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议,一直用到了20年后的今天,直到现在还是最流行的版本。

3.1 持久连接

1.1 版的最大变化,就是引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive

客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接。

 Connection: close 

目前,对于同一个域名,大多数浏览器允许同时建立6个持久连接。

3.2 管道机制

1.1 版还引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。

举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。

3.3 Content-Length 字段

一个TCP连接现在可以传送多个回应,势必就要有一种机制,区分数据包是属于哪一个回应的。这就是Content-length字段的作用,声明本次回应的数据长度。

 Content-Length: 3495 

上面代码告诉浏览器,本次回应的长度是3495个字节,后面的字节就属于下一个回应了。

在1.0版中,Content-Length字段不是必需的,因为浏览器发现服务器关闭了TCP连接,就表明收到的数据包已经全了。

3.4 分块传输编码

使用Content-Length字段的前提条件是,服务器发送回应之前,必须知道回应的数据长度。

对于一些很耗时的动态操作来说,这意味着,服务器要等到所有操作完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用"流模式"(stream)取代"缓存模式"(buffer)。

因此,1.1版规定可以不使用Content-Length字段,而使用"分块传输编码"(chunked transfer encoding)。只要请求或回应的头信息有Transfer-Encoding字段,就表明回应将由数量未定的数据块组成。

 Transfer-Encoding: chunked 

每个非空的数据块之前,会有一个16进制的数值,表示这个块的长度。最后是一个大小为0的块,就表示本次回应的数据发送完了。下面是一个例子。

 HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked  25 This is the data in the first chunk  1C and this is the second one  3 con  8 sequence  0  

3.5 其他功能

1.1版还新增了许多动词方法:PUTPATCHHEADOPTIONSDELETE

另外,客户端请求的头信息新增了Host字段,用来指定服务器的域名。

 Host: www.example.com 

有了Host字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础。

3.6 缺点

虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为"队头堵塞"(Head-of-line blocking)。

为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。如果HTTP协议设计得更好一些,这些额外的工作是可以避免的。

四、SPDY 协议

2009年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。

这个协议在Chrome浏览器上证明可行以后,就被当作 HTTP/2 的基础,主要特性都在 HTTP/2 之中得到继承。

五、HTTP/2

2015年,HTTP/2 发布。它不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3。

5.1 二进制协议

HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。

二进制协议的一个好处是,可以定义额外的帧。HTTP/2 定义了近十种帧,为将来的高级应用打好了基础。如果使用文本实现这种功能,解析数据将会变得非常麻烦,二进制解析则方便得多。

5.2 多工

HTTP/2 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了"队头堵塞"。

举例来说,在一个TCP连接里面,服务器同时收到了A请求和B请求,于是先回应A请求,结果发现处理过程非常耗时,于是就发送A请求已经处理好的部分, 接着回应B请求,完成后,再发送A请求剩下的部分。

这样双向的、实时的通信,就叫做多工(Multiplexing)。

5.3 数据流

因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。

HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。

数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM帧),取消这个数据流。1.1版取消数据流的唯一方法,就是关闭TCP连接。这就是说,HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,可以被其他请求使用。

客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。

5.4 头信息压缩

HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如CookieUser Agent,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。

HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。一方面,头信息使用gzipcompress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

5.5 服务器推送

HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。

常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。

六、参考链接

(完)

文档信息

2016年8月16日星期二

阮一峰的网络日志

阮一峰的网络日志


那些无用的人----《人类简史》读后感

Posted: 15 Aug 2016 05:46 PM PDT

(说明:本文原载2016年第32期《财新周刊》。文后还会介绍一个新网站"海棠学院"。)

1.

最近,我读完了《人类简史》(中信出版社,2014)。

它是以色列学者尤瓦尔·赫拉利写的畅销书,主要讲人类这个物种(即智人)的历史。全书最大特点就是,作者完全用自己的想法解释历史,有大量的独特观点。它不是学术著作,而是表达个人的历史观。

最惊人的一个观点,大概是他对人类的前途相当悲观,认为人类可能即将灭绝。

2.

全书最后一章的标题,叫做《智人末日》。

作者感叹道,人类社会存在了七万年,真正的大发展只是最近两三百年。但是,再过一千年,人类是否还会存在,已经很可疑了。

"今天,人类正在让许多物种灭绝,甚至可能包括自己。如果今天发生核灾而让世界末日降临,人类将毁灭,而老鼠和蟑螂很可能继续生存下去。或许6500万年后,会有一群高智商的老鼠心怀感激地回顾人类造成的这场灾难。"

我们还有多久时间?没有人真正知道。如果智人的历史确实即将谢幕,我们这些最后一代的智人,或许该花点时间回答最后一个问题:我们究竟想要变成什么?"

3.

尤瓦尔·赫拉利认为,人类可能灭绝的根本原因,在于技术的高速发展。

技术带来了现代化生活,也导致了前所未有的危机。别的不说,眼下的危机就是,短期内就会有大量失业出现,许多人将变得毫无用处

"技术造成的人力精简,将在今后5年内,导致全球发达国家失去710万个工作岗位,但在科技、专业服务及媒体领域,将创造210万个工作岗位。两相抵销之下,未来五年内,将会净损失500万个工作岗位,其中以行政工作与白领阶级为主。"

---- 摘自世界经济论坛《未来的工作》,2016

上一次的工业革命,体力劳动被替代了,比如,水车替代了拉磨,汽车替代了马车。这一次的信息技术革命,智力劳动将被替代,计算机替代我们做计算和判断。

体力岗位没了,人类可以从事智力岗位。可是,智力岗位也没了,人类去干什么呢?

4.

今年5月,美国达拉斯发生袭警案,一名狙击手放冷枪,打死了5个警察。最后,他被包围在一片建筑群里面,但不知道他的确切位置。

警方就派出一个遥控机器人,在建筑群里巡查,一发现目标,就扔出一颗炸弹,一下子就把罪犯炸死了。整个行动高效、快速,警方没有任何流血。更重要的是,这是历史上第一次,机器人警察杀死人类。

可以想象,随着犯罪行为的增加,以及罪犯装备的升级,机器人警察将会得到推广,取代人类警察打击犯罪。人类士兵也会被取代,以后的战争就是机器人战争。

《人类简史》作者的公开说:

"未来可能不再需要司机。我们已经有了无人驾驶的汽车。他们不喝酒,不疲惫,比人类驾驶还要安全。当所有的汽车都变成了无人驾驶,我们就可以把所有的车辆联网,形成一个车联网。这样的话,交警可能也不需要了,因为所有的车都可以通过这张网络获取道路信息。"

无人驾驶不仅会让司机和交警失业,而且长远来看,会消灭整个运输物流行业的工作岗位。比如,既然车辆可以自动到达目的地,那么送货的快递小哥也不需要了。

5.

人的价值体现在他/她的工作成果。如果有些人根本找不到工作,他们的价值体现在哪里呢?

过去,工业革命吸收了农业释放的数十亿人力,将人类的劳动形态从田野和作坊,变成了工厂和办公室;现在,工厂和办公室开始释放人力,又有什么行业可以吸收他们呢?

将来越来越多的人会发现,他们根本不可能找到工作。智力和体力两方面,机器都比人类能干。你要么比机器更能干,要么比机器更便宜,否则你怎么跟机器竞争工作岗位呢?

6.

有人说,技术会创造新工作,只要不断学习新的技能,就不用担心自己会被淘汰。这对一部人也许可以,但对大部分人这样要求是不现实的。

"(世界经济论坛统计,目前的小学生长大后,65%会从事现在还不存在的工作。)孩子们在中学或者大学学到的大多数东西,等到40、50岁的时候可能都会变得无足轻重。如果他们还希望继续保住工作,那就得不断地改造自己,而且频率得越来越快才行。"

不是每个人都善于学习,更不是每个人都具有学习的意愿。大多数人只希望生活舒适,不愿意动脑筋,去搞懂那些抽象的公式。而且,要求40、50岁的人跟刚走上社会的年轻人一样拼搏,也不现实。如果终生学习是唯一的就业出路,那对于多数人来说,就是没有出路。

7.

尤瓦尔·赫拉利说,人工智能取代了那些简单技能的工作岗位以后,人类当中会出现一个庞大的、无用的无产阶级。

"未来,人类可能会分化为两个主要的等级:一个全新的更先进的精英阶级,很聪明,很富有,有更好的基因和更长的寿命;还有一个全新的一无用处的无产阶级,他们将越来越穷地等待死亡,可能变成没有工作、没有目标、整日靠吸毒度日、戴着VR头盔消磨时光的乌合之众。"

人类社会的政治和经济结构,都会因此被颠覆。

当代国家建立在人对国家有用的基础上的,大部分人的角色是工人和士兵。如果这些角色被机器取代,那么底层的人们对国家来说,也就不再重要了。国家很可能会忽视他们的需求,只是出于社会稳定的目的,提供基本的生活资料。而人们也比以往更依赖政府,因为如果政府停止救济,他们就无法养活自己。

尤瓦尔·赫拉利将这种情景,列为21世纪最悲惨的威胁之一。

"随着人工智能变得越来越聪明,会有更多的人被挤出就业市场。没人知道大学该学什么,因为没人知道20岁的时候学的东西到了40岁还有没有用。等你知道的时候,已经有数十亿人变得一点用都没有了。这不是偶然,而是必然。"

(全文完)


下面是推广时间。

最近,"海棠学院"上线了。它是一个在线学习平台,如果你希望进入互联网行业、系统学习前端技术,那么我推荐你去看一下。

海棠学院目前提供600课时的前端视频课程,由浅入深、系统讲解各种知识点,每堂课都有课后练习题,保证不同水平的学员都能学会。主讲老师来自百度,有七年开发经验,主导过多个流量过亿的项目。

如果你每天投入两个小时,一周五天,那么大概四个月时间,就可以从零开始,学完所有课程,掌握前端开发技术。

为了保证学习效果,海棠学院采取多种措施。

  • 重视实战。讲课内容和课后作业,紧贴实际业务,并且还有直播课,引导大家现场完成练习。
  • 重视答疑。如果你遇到疑问,可以随时向线上助教求助,也可以把问题提交到QQ群和微信群。
  • 强调纪律。为了保证学员不会半途而废,按时完成进度,每堂课都会线上考勤,并且强制交作业,还会有期中考试。

任何疑问或咨询,可以加创始人微信,直接提问。

当然,最重要的还是课程质量,欢迎点击这里,现在就开始试听。​​

(完)

文档信息

2016年8月5日星期五

阮一峰的网络日志

阮一峰的网络日志


布尔代数入门

Posted: 04 Aug 2016 05:17 PM PDT

布尔代数是计算机的基础。没有它,就不会有计算机。

布尔代数发展到今天,已经非常抽象,但是它的核心思想很简单。本文帮助你理解布尔代数,以及为什么它促成了计算机的诞生。

我依据的是《编码的奥妙》的第十章。这是一本好书,强烈推荐。

一、数理逻辑的起源

18世纪早期,英国数学家乔治·布尔(George Boole,1815-1864)突发奇想:人的思想能不能用数学表达?

此前,数学只用于计算,没有人意识到,数学还能表达人的逻辑思维。

两千年来,哲学书都是用文字写的。比如,最著名的三段论:

所有人都是要死的,
苏格拉底是人,
所以,苏格拉底是要死的。

乔治·布尔认为,这种推理可以用数学表达,也就是说,哲学书完全可以用数学写。这就是数理逻辑的起源。

二、集合论

乔治·布尔发明的工具,叫做"集合论"(Set theory)。他认为,逻辑思维的基础是一个个集合(Set),每一个命题表达的都是集合之间的关系。

比如,所有人类组成一个集合R,所有会死的东西组成一个集合D

所有人都是要死的

集合论的写法就是:

R X D = R

集合之间最基本的关系是并集和交集。乘号(X)表示交集,加号(+)表示并集。上面这个式子的意思是,RD的交集就是R

同样的,苏格拉底也是一个集合S,这个集合里面只有苏格拉底一个成员。

苏格拉底是人
// 等同于
S X R = S

上面式子的意思是,苏格拉底与人类的交集,就是苏格拉底。

将第一个式子代入第二个式子,就得到了结论。

S X (R X D)
= (S X R) X D
= S X D
= S

这个式子的意思是,苏格拉底与会死的东西的交集,就是苏格拉底,即苏格拉底也属于会死的东西。

三、集合的运算法则

前面的三段论比较容易,一眼就能看出结论。但是,有些三段轮比较复杂,不容易立即反应过来。

请看下面这两句话。

"鸭嘴兽是卵生的哺乳动物。鸭嘴兽是澳洲的动物。"

你能一眼得到结论吗?

鸭嘴兽 X 卵生 = 鸭嘴兽
鸭嘴兽 x 澳洲 = 鸭嘴兽

将第一个式子代入第二个,就会得到:

鸭嘴兽 X 卵生 x 澳洲 = 鸭嘴兽
// 相当于
卵生 x 澳洲 = 鸭嘴兽 + 其他

因此,结论就是"有的卵生动物是澳洲的动物",或者"有的澳洲的动物是卵生动物"。

还有更不直观的三段论。

"哲学家都是有逻辑头脑的,一个没有逻辑头脑的人总是很顽固。"

请问结论是什么?

这道题会用到新的概念:全集和空集。集合A和所有不属于它的元素(记作-A)构成全集(I),这时A-A的交集就是一个空集(0)。

A + (-A) = I
A X (-A) = 0

因此,有下面的公式。

B
= B X I
= B X (A + -A)
= B X A + B X (-A)

回到上面那道题。

哲学家 X 逻辑 = 哲学家
无逻辑 X 顽固 = 无逻辑

根据第一个命题,可以得到下面的结论。

哲学家 X 无逻辑
= (哲学家 X 逻辑) X 无逻辑
= 哲学家 X (逻辑 X 无逻辑)
= 哲学家 X 0
= 0

即哲学家与没有逻辑的人的交集,是一个空集。

根据第二个命题,可以得到下面的结论。

无逻辑 X 顽固
= 无逻辑 X 顽固 X (哲学家 + 非哲学家)
= 无逻辑 X 顽固 X 哲学家 + 无逻辑 X 顽固 X 非哲学家
= 0 X 顽固 + 无逻辑 X 顽固 X 非哲学家
= 无逻辑 X 顽固 X 非哲学家
= 无逻辑

也就是说,最终的结论如下。

无逻辑 X 顽固 X 非哲学家 = 无逻辑
// 相当于
顽固 X 非哲学家 = 无逻辑 + 其他

结论就是顽固的人与非哲学家之间有交集。通俗的表达就是:一些顽固的人,不是哲学家,或者一些不是哲学家的人,很顽固。

由此可见,集合论可以帮助我们得到直觉无法得到的结论,保证推理过程正确,比文字推导更可靠。

四、 集合论到布尔代数

既然命题可以用集合论表达,那么逻辑推导无非就是一系列集合运算。

由于集合运算的结果还是集合,那么通过判断个体是否属于指定集合,就可以计算命题的真伪。

一名顾客走进宠物店,对店员说:"我想要一只公猫,白色或黄色均可;或者一只母猫,除了白色,其他颜色均可;或者只要是黑猫,我也要。"

这名顾客的要求用集合论表达,就是下面的式子。

公猫 X (白色 + 黄色)
+ 母猫 X 非白色
+ 黑猫

店员拿出一只灰色的公猫,请问是否满足要求?

布尔代数规定,个体属于某个集合用1表示,不属于就用0表示。 灰色的公猫属于公猫集合,就是1,不属于白色集合,就是0

上面的表达式变成下面这样。

1 X (0 + 0)
+ 0 X 1
+ 0
= 0

因此,就得到结论,灰色的公猫不满足要求。

这就是布尔代数:计算命题真伪的数学方法。

五、布尔代数的运算法则

布尔代数的运算法则与集合论很像。

交集的运算法则如下。

1 X 1 = 1
1 X 0 = 0
0 X 0 = 0

并集的运算法则如下。

1 + 1 = 1
1 + 0 = 1
0 + 0 = 0

集合论可以描述逻辑推理过程,布尔代数可以判断某个命题是否符合这个过程。人类的推理和判断,因此就变成了数学运算。

20世纪初,英国科学家香农指出,布尔代数可以用来描述电路,或者说,电路可以模拟布尔代数。于是,人类的推理和判断,就可以用电路实现了。这就是计算机的实现基础。

六、布尔代数的局限

虽然布尔代数可以判断命题真伪,但是无法取代人类的理性思维。原因是它有一个局限。

它必须依据一个或几个已经明确知道真伪的命题,才能做出判断。比如,只有知道"所有人都会死"这个命题是真的,才能得出结论"苏格拉底会死"。

布尔代数只能保证推理过程正确,无法保证推理所依据的前提是否正确。如果前提是错的,正确的推理也会得到错误的结果。而前提的真伪要由科学实验和观察来决定,布尔代数无能为力。

(完)

文档信息