分类:资讯

王之浮屠

[墙外的世界 请自备工具观看视频]

“遥想山寺古,看倒影金轮,溯光朱户。暝烟带树,有投林鹭宿。凭楼僧语,可异流年,付与朝钟暮鼓。谩凝伫,步长桥,月明归去。”

一座千年的古老佛塔,在绚烂的晚霞之下,默默地伫立在碧波荡漾的西子湖畔,像一位沧桑的老人,慢慢地诉说着一个古老的故事——

公元前907年,一个意气风发的临安人来到了山水秀丽、景色迷人的江南,创立了一个属于自己的国家——吴越。这个人就是吴越国的第一个统治者、雷峰塔建造者的(祖父)钱镠。

钱镠平定了战乱后,以“保境安民”为治国之本,定都杭州,并且三次扩建,发展经济,让杭州成为了当时江南最繁盛的城市。

这位信奉佛教的临安天子还给自己王权的继承人和子孙后代留下了“尊奉中原,永不称帝”的遗训。放弃称霸中原的机会,在一般人眼中是一件非常愚蠢的事情,因为以当时钱镠的兵力,完全可以与刚登上皇位的梁王抗衡,但为了吴越百姓的安危,钱镠放弃了这个绝好的机会。这条看上去十分愚蠢的遗训,却让治下那些无辜的百姓免除了战乱之苦,为杭州,甚至整个吴越,争取到了难能可贵的和平。

别说是在天下老子最大的封建王朝,就算现在,也未必有人蠢到眼睁睁地看着嘴边的美味溜掉。谁不想贵为天子?谁不想号令天下?谁不想当公司的总经理?谁不想一夜暴富?你不想?鬼才信!

如果不是中央台的纪录片,打死你我也不相信世上竟有那么“笨”的人!

钱镠去世十六年后,他的孙子钱俶被拥立为吴越国王,这位年轻的君王依旧延续、尊守着祖父的治国之本和遗训,勤勤恳恳地工作。钱家信奉佛教,在杭州兴建寺庙、殿宇、佛塔,所以杭州又有“东南佛国”的美誉。钱俶为了保护珍贵的佛祖真身舍利免遭战火毁坏,计划修一座千尺十三层的通天佛塔,用来保护舍利,这座佛塔就是雷锋塔。

但就在钱俶满怀信心准备建造佛塔时,大宋赵匡胤的诏书也已经抵达杭州,邀请钱俶一同联手攻打南唐,与此同时,南唐后主李煜也写信劝说钱俶与南唐结盟,抵抗大宋。南唐,地处北宋和吴越之间,一旦南唐被消灭,吴越国将会处在北宋出鞘的宝剑之下。“今日无我,明日岂有君?”,李煜在信中言辞悲切又直指要害,钱俶也深知唇亡齿寒的道理,但如若不肯与北宋联手,那么北宋充满杀气的矛头将会立马指向吴越。为了吴越国的百姓和江山,无奈之下,钱俶亲自率兵,协助北宋攻打南唐。

975年,南唐灭。

钱俶终于明白,赵匡胤要的不是他的臣服,不是他的进贡,而是要他纳土归宋。最后的一丝希望终究还是破灭了,自己最不愿意的事情发生了。钱俶寝食不安,直到有一天,他在祖父的书房里,见到了一幅西湖山水图,图上的一首诗吸引了他:“牙城旧址扩篱藩,留得西湖翠浪翻。有国百年心愿足,祚无千载是名言。”

原来,吴越国创国不久,钱镠要建新宫殿,一位风水先生告诉他,如只在旧址凤凰山上建造宫殿的话,吴越的基业只能维持一百年,但如果填平西湖建造新的宫殿,就可以延续上千年。钱镠拒绝了:这世上本没有千年的王朝,中国历史上最长的王朝周朝,也只延续了八百年,即使有,我也不愿为了千年王朝毁掉美丽的西子湖,吴越国能够延续百年我已知足了。

祖父宽宏的胸襟让钱俶明白:有民才有国,有民才有吴越,有民才有钱家。如果没有百姓,那自然就没有钱家,也没有吴越。

他改变了雷峰塔原来的设计,佛塔只建到五层就停止。

因为就算修再高的佛塔,如果无法让百姓过上和平的生活,也是徒劳。

978年,五层雷峰塔建成。吴越国王钱俶前往开封,纳土归宋。

纳土归宋,不是因为恐惧,不是因为怕死,不是因为懦弱,也不是因为害怕江山社稷不保,而是因为不想让无辜的百姓受战乱之苦。

吴越,一个小小的国家,没有周的长久,没有唐的繁盛,没有明的强大;治理它的君主,虽没有尧舜禹的仁德,没有周武王卓越的才能,也没有唐太宗的公正英明。但,他们都是伟大的,因为他们可以因为百姓而放弃千年的王朝,放弃原属于自己的秀丽的山河社稷,放弃自己的政权。

“有国百年心愿足,祚无千载是名言。”

火球一般的夕阳将天空染成了橘红色,悠扬而沉雄的钟声在波光粼粼、浮光若金的西湖湖面上回荡着,整座雷峰塔都沉浸在这钟声之中。今天我们所看到的雷峰塔已不是千年前钱俶煞费苦心建造的雷锋塔了,历经千年沧桑的古塔已经倒塌了,直到公元2000年,杭州市政府才重建了一座新塔。“长城万里今尚在,安见当年秦始皇”,浪花淘尽英雄,但钱王宽大、无私的胸怀,将如夕阳下的雷峰塔一般闪闪发光,如高耸的佛塔一般永远矗立在我们的心中。

静夜,仰望寥廓的星空,那当中任意的一点星辉,可能就是万倍亿倍于地球的一个星体,而无言的夜空,却轻松地将他们统统囊括……面对辽阔的星空,我们那些个人的荣誉得失,分数高低、排名先后……什么都不值一提了。

华为荣耀总裁刘江峰着实文艺

华为荣耀总裁刘江峰正式宣告离职,文艺范儿辞别信一起笔就是引用绿妖与米兰·昆德拉

下面是刘江峰的告别信。全信处处皆见大小作家、哈佛校长名言、电影台词……刘江峰着实文艺呀。请调整好心情观看。

liujiangfeng (1).jpg

当你在浏览器中输入 google.com 并且按下回车之后发生了什么?

这个仓库试图回答一个古老的面试问题:当你在浏览器中输入google.com并且按下回车之后发生了什么?

不过我们不再局限于平常的回答,而是想办法回答地尽可能具体,不遗漏任何细节。

这将是一个协作的过程,所以深入挖掘吧,并且帮助我们一起完善它。仍然有大量的细节等待着你来添加,欢迎向我们发送Pull Requset!

这些内容使用 Creative Commons Zero 协议发布。

目录

按下”g”键

接下来的内容介绍了物理键盘和系统中断的工作原理,但是有一部分内容却没有涉及。当你按下“g”键,浏览器接收到这个消息之后,会触发自动完成机制。浏览器根据自己的算法,以及你是否处于隐私浏览模式,会在浏览器的地址框下方给出输入建议。大部分算法会优先考虑根据你的搜索历史和书签等内容给出建议。一些浏览器,例如 Rockmelt ,甚至会根据你的 Facebook 好友给出建议。你打算输入 “google.com”,因此给出的建议并不匹配。但是输入过程中仍然有大量的代码在后台运行,你的每一次按键都会使得给出的建议更加准确。甚至有可能在你输入之前,浏览器就将 “google.com” 建议给你。

回车键按下

为了从零开始,我们选择键盘上的回车键被按到最低处作为起点。在这个时刻,一个专用于回车键的电流回路被直接地或者通过电容器间接地闭合了,使得少量的电流进入了键盘的逻辑电路系统。这个系统会扫描每个键的状态,对于按键开关的电位弹跳变化进行噪音消除(debounce),并将其转化为键盘码值。在这里,回车的码值是13。键盘控制器在得到码值之后,将其编码,用于之后的传输。现在这个传输过程几乎都是通过通用串行总线(USB)或者蓝牙(Bluetooth)来进行的,以前是通过PS/2或者ADB连接进行。

USB键盘:

  • 键盘的USB元件通过计算机上的USB接口与USB控制器相连接,USB接口中的第一号针为它提供了5V的电压
  • 键码值存储在键盘内部电路一个叫做”endpoint”的寄存器内
  • USB控制器大概每隔10ms便查询一次”endpoint”以得到存储的键码值数据,这个最短时间间隔由键盘提供
  • 键值码值通过USB串行接口引擎被转换成一个或者多个遵循低层USB协议的USB数据包
  • 这些数据包通过D+针或者D-针(中间的两个针),以最高1.5Mb/s的速度从键盘传输至计算机。速度限制是因为人机交互设备总是被声明成”低速设备”(USB 2.0 compliance)
  • 这个串行信号在计算机的USB控制器处被解码,然后被人机交互设备通用键盘驱动进行进一步解释。之后按键的码值被传输到操作系统的硬件抽象层

虚拟键盘(触屏设备):

  • 在现代电容屏上,当用户把手指放在屏幕上时,一小部分电流从传导层的静电域经过手指传导,形成了一个回路,使得屏幕上触控的那一点电压下降,屏幕控制器产生一个中断,报告这次“点击”的坐标
  • 然后移动操作系统通知当前活跃的应用,有一个点击事件发生在它的某个GUI部件上了,现在这个部件是虚拟键盘的按钮
  • 虚拟键盘引发一个软中断,返回给OS一个“按键按下”消息
  • 这个消息又返回来向当前活跃的应用通知一个“按键按下”事件

产生中断[非USB键盘]

键盘在它的中断请求线(IRQ)上发送信号,信号会被中断控制器映射到一个中断向量,实际上就是一个整型数 。CPU使用中断描述符表(IDT)把中断向量映射到对应函数,这些函数被称为中断处理器,它们由操作系统内核提供。当一个中断到达时,CPU根据IDT和中断向量索引到对应的中端处理器,然后操作系统内核出场了。

(Windows)一个 WM_KEYDOWN 消息被发往应用程序

HID把键盘按下的事件传送给 KBDHID.sys 驱动,把HID的信号转换成一个扫描码(Scancode),这里回车的扫描码是 VK_RETURN(0x0d)KBDHID.sys 驱动和 KBDCLASS.sys (键盘类驱动,keyboard class driver)进行交互,这个驱动负责安全地处理所有键盘和小键盘的输入事件。之后它又去调用 Win32K.sys ,在这之前有可能把消息传递给安装的第三方键盘过滤器。这些都是发生在内核模式。

Win32K.sys 通过 GetForegroundWindow() API函数找到当前哪个窗口是活跃的。这个API函数提供了当前浏览器的地址栏的句柄。Windows系统的”message pump”机制调用 SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, lParam) 函数, lParam 是一个用来指示这个按键的更多信息的掩码,这些信息包括按键重复次数(这里是0),实际扫描码(可能依赖于OEM厂商,不过通常不会是 VK_RETURN ),功能键(alt, shift, ctrl)是否被按下(在这里没有),以及一些其他状态。

Windows的 SendMessage API直接将消息添加到特定窗口句柄 hWnd 的消息队列中,之后赋给 hWnd 的主要消息处理函数 WindowProc 将会被调用,用于处理队列中的消息。

当前活跃的句柄 hWnd 实际上是一个edit control控件,这种情况下,WindowProc 有一个用于处理WM_KEYDOWN 消息的处理器,这段代码会查看 SendMessage 传入的第三个参数 wParam ,因为这个参数是 VK_RETURN ,于是它知道用户按下了回车键。

(Mac OS X)一个 KeyDown NSEvent被发往应用程序

中断信号引发了I/O Kit Kext键盘驱动的中断处理事件,驱动把信号翻译成键码值,然后传给OS X的WindowServer 进程。然后, WindowServer 将这个事件通过Mach端口分发给合适的(活跃的,或者正在监听的)应用程序,这个信号会被放到应用程序的消息队列里。队列中的消息可以被拥有足够高权限的线程使用 mach_ipc_dispatch 函数读取到。这个过程通常是由 NSApplication 主事件循环产生并且处理的,通过 NSEventTypeKeyDownNSEvent

(GNU/Linux)Xorg 服务器监听键码值

当使用图形化的 X Server 时,X Server会按照特定的规则把键码值再一次映射,映射成扫描码。当这个映射过程完成之后, X Server 把这个按键字符发送给窗口管理器(DWM,metacity, i3等等),窗口管理器再把字符发送给当前窗口。当前窗口使用有关图形API把文字打印在输入框内。

解析URL

  • 浏览器通过URL能够知道下面的信息:
    • Protocol “http”
      使用HTTP协议
    • Resource “/”
      请求的资源是主页(index)

输入的是URL还是搜索的关键字?

当协议或主机名不合法时,浏览器会将地址栏中输入的文字传给默认的搜索引擎。大部分情况下,在把文字传递给搜索引擎的时候,URL会带有特定的一串字符,用来告诉搜索引擎这次搜索来自这个特定浏览器。

检查HSTS列表···

  • 浏览器检查自带的“预加载HSTS(HTTP严格传输安全)”列表,这个列表里包含了那些请求浏览器只使用HTTPS进行连接的网站
  • 如果网站在这个列表里,浏览器会使用HTTPS而不是HTTP协议,否则,最初的请求会使用HTTP协议发送
  • 注意,一个网站哪怕不在HSTS列表里,也可以要求浏览器对自己使用HSTS政策进行访问。浏览器向网站发出第一个HTTP请求之后,网站会返回浏览器一个响应,请求浏览器只使用HTTPS发送请求。然而,就是这第一个HTTP请求,却可能会使用户收到 downgrade attack 的威胁,这也是为什么现代浏览器都预置了HSTS列表。

转换非ASCII的Unicode字符

  • 浏览器检查输入是否含有不是 a-zA-Z0-9- 或者 . 的字符
  • 这里主机名是 google.com ,所以没有非ASCII的字符,如果有的话,浏览器会对主机名部分使用Punycode 编码

DNS查询···

  • 浏览器检查域名是否在缓存当中
  • 如果缓存中没有,就去调用 gethostbynme 库函数(操作系统不同函数也不同)进行查询
  • gethostbyname 函数在试图进行DNS解析之前首先检查域名是否在本地Hosts里,Hosts的位置 不同的操作系统有所不同
  • 如果 gethostbyname 没有这个域名的缓存记录,也没有在 hosts 里找到,它将会向DNS 服务器发送一条DNS查询请求。DNS服务器是由网络通信栈提供的,通常是本地路由器或者ISP的缓存DNS服务器。
  • 查询本地 DNS 服务器
  • 如果DNS服务器和我们的主机在同一个子网内,系统会按照下面的 ARP 过程对 DNS 服务器进行 ARP查询
  • 如果DNS服务器和我们的主机在不同的子网,系统会按照下面的 ARP 过程对默认网关进行查询

ARP

要想发送ARP广播,我们需要有一个目标IP地址,同时还需要知道用于发送ARP广播的接口的Mac地址。

  • 首先查询ARP缓存,如果缓存命中,我们返回结果:目标IP = MAC

如果缓存没有命中:

  • 查看路由表,看看目标IP地址是不是在本地路由表中的某个子网内。是的话,使用跟那个子网相连的接口,否则使用与默认网关相连的接口。
  • 查询选择的网络接口的MAC地址
  • 我们发送一个二层ARP请求:

ARP Request:

Sender MAC: interface:mac:address:here
Sender IP: interface.ip.goes.here
Target MAC: FF:FF:FF:FF:FF:FF (Broadcast)
Target IP: target.ip.goes.here

根据连接主机和路由器的硬件类型不同,可以分为以下几种情况:

直连:

  • 如果我们和路由器是直接连接的,路由器会返回一个 ARP Reply (见下面)。

集线器:

  • 如果我们连接到一个集线器,集线器会把ARP请求向所有其它端口广播,如果路由器也“连接”在其中,它会返回一个 ARP Reply

交换机:

  • 如果我们连接到了一个交换机,交换机会检查本地 CAM/MAC 表,看看哪个端口有我们要找的那个MAC地址,如果没有找到,交换机会向所有其它端口广播这个ARP请求。
  • 如果交换机的MAC/CAM表中有对应的条目,交换机会向有我们想要查询的MAC地址的那个端口发送ARP请求
  • 如果路由器也“连接”在其中,它会返回一个 ARP Reply

ARP Reply:

Sender MAC: target:mac:address:here
Sender IP: target.ip.goes.here
Target MAC: interface:mac:address:here
Target IP: interface.ip.goes.here

现在我们有了DNS服务器或者默认网关的IP地址,我们可以继续DNS请求了:

  • 使用53端口向DNS服务器发送UDP请求包,如果响应包太大,会使用TCP
  • 如果本地/ISP DNS服务器没有找到结果,它会发送一个递归查询请求,一层一层向高层DNS服务器做查询,直到查询到起始授权机构,如果找到会把结果返回

使用套接字

当浏览器得到了目标服务器的IP地址,以及URL中给出来端口号(http协议默认端口号是80, https默认端口号是443),它会调用系统库函数 socket ,请求一个 TCP流套接字,对应的参数是 AF_INETSOCK_STREAM

  • 这个请求首先被交给传输层,在传输层请求被封装成TCP segment。目标端口会会被加入头部,源端口会在系统内核的动态端口范围内选取(Linux下是ip_local_port_range)
  • TCP segment被送往网络层,网络层会在其中再加入一个IP头部,里面包含了目标服务器的IP地址以及本机的IP地址,把它封装成一个TCP packet。
  • 这个TCP packet接下来会进入链路层,链路层会在封包中加入frame头部,里面包含了本地内置网卡的MAC地址以及网关(本地路由器)的MAC地址。像前面说的一样,如果内核不知道网关的MAC地址,它必须进行ARP广播来查询其地址。

到了现在,TCP封包已经准备好了,可以使用下面的方式进行传输:

对于大部分家庭网络和小型企业网络来说,封包会从本地计算机出发,经过本地网络,再通过调制解调器把数字信号转换成模拟信号,使其适于在电话线路,有线电视光缆和无线电话线路上传输。在传输线路的另一端,是另外一个调制解调器,它把模拟信号转换回数字信号,交由下一个 网络节点 处理。节点的目标地址和源地址将在后面讨论。

大型企业和比较新的住宅通常使用光纤或直接以太网连接,这种情况下信号一直是数字的,会被直接传到下一个 网络节点 进行处理。

最终封包会到达管理本地子网的路由器。在那里出发,它会继续经过自治区域的边界路由器,其他自治区域,最终到达目标服务器。一路上经过的这些路由器会从IP数据报头部里提取出目标地址,并将封包正确地路由到下一个目的地。IP数据报头部TTL域的值每经过一个路由器就减1,如果封包的TTL变为0,或者路由器由于网络拥堵等原因封包队列满了,那么这个包会被路由器丢弃。

上面的发送和接受过程在TCP连接期间会发生很多次:

  • 客户端选择一个初始序列号(ISN),将设置了SYN位的封包发送给服务器端,表明自己要建立连接并设置了初始序列号
  • 服务器端接受到SYN包,如果它可以建立连接:
    • 服务器端选择它自己的初始序列号
    • 服务器端设置SYN位,表明自己选择了一个初始序列号
    • 服务器端把 (客户端ISN + 1) 复制到ACK域,并且设置ACK位,表明自己接收到了客户端的第一个封包
  • 客户端通过发送下面一个封包来确认这次连接:
    • 自己的序列号+1
    • 接收端ACK+1
    • 设置ACK位
  • 数据通过下面的方式传输:
    • 当一方发送了N个Bytes的数据之后,将自己的SEQ序列号也增加N
    • 另一方确认接收到这个数据包(或者一系列数据包)之后,它发送一个ACK包,ACK的值设置为接收到的数据包的最后一个序列号
  • 关闭连接时:
    • 要关闭连接的一方发送一个FIN包
    • 另一方确认这个FIN包,并且发送自己的FIN包
    • 要关闭的一方使用ACK包来确认接收到了FIN

UDP 数据包

TLS 握手

  • 客户端发送一个 Client hello 消息到服务器端,消息中同时包含了它的TLS版本,可用的加密算法和压缩算法。
  • 服务器端向客户端返回一个 Server hello 消息,消息中包含了服务器端的TLS版本,服务器选择了哪个加密和压缩算法,以及服务器的公开证书,证书中包含了公钥。客户端会使用这个公钥加密接下来的握手过程,直到协商生成一个新的对称密钥
  • 客户端根据自己的信任CA列表,验证服务器端的证书是否有效。如果有效,客户端会生成一串伪随机数,使用服务器的公钥加密它。这串随机数会被用于生成新的对称密钥
  • 服务器端使用自己的私钥解密上面提到的随机数,然后使用这串随机数生成自己的对称主密钥
  • 客户端发送一个 Finished 消息给服务器端,使用对称密钥加密这次通讯的一个散列值
  • 服务器端生成自己的 hash 值,然后解密客户端发送来的信息,检查这两个值是否对应。如果对应,就向客户端发送一个 Finished 消息,也使用协商好的对称密钥加密
  • 从现在开始,接下来整个 TLS 会话都使用对称秘钥进行加密,传输应用层(HTTP)内容

TCP 数据包

HTTP 协议···

如果浏览器是Google出品的,它不会使用HTTP协议来获取页面信息,而是会与服务器端发送请求,商讨使用SPDY协议。

如果浏览器使用HTTP协议,它会向服务器发送这样的一个请求:

GET / HTTP/1.1
Host: google.com
[其他头部]

“其他头部”包含了一系列的由冒号分割开的键值对,它们的格式符合HTTP协议标准,它们之间由一个换行符分割开来。这里我们假设浏览器没有违反HTTP协议标准的bug,同时浏览器使用 HTTP/1.1 协议,不然的话头部可能不包含 Host 字段,同时 GET 请求中的版本号会变成 HTTP/1.0 或者 HTTP/0.9

HTTP/1.1 定义了“关闭连接”的选项 “close”,发送者使用这个选项指示这次连接在响应结束之后会断开:

Connection:close

不支持持久连接的 HTTP/1.1 必须在每条消息中都包含 “close” 选项。

在发送完这些请求和头部之后,浏览器发送一个换行符,表示要发送的内容已经结束了。

服务器端返回一个响应码,指示这次请求的状态,响应的形式是这样的:

200 OK
[response headers]

然后是一个换行,接下来有效载荷(payload),也就是 www.google.com 的HTML内容。服务器下面可能会关闭连接,如果客户端请求保持连接的话,服务器端会保持连接打开,以供以后的请求重用。

如果浏览器发送的HTTP头部包含了足够多的信息(例如包含了 Etag 头部,以至于服务器可以判断出,浏览器缓存的文件版本自从上次获取之后没有再更改过,服务器可能会返回这样的响应:

304 Not Modified
[response headers]

这个响应没有有效载荷,浏览器会从自己的缓存中取出想要的内容。

在解析完HTML之后,浏览器和客户端会重复上面的过程,直到HTML页面引入的所有资源(图片,CSS,favicon.ico等等)全部都获取完毕,区别只是头部的 GET / HTTP/1.1 会变成 GET /$(相对www.google.com的URL) HTTP/1.1

如果HTML引入了 www.google.com 域名之外的资源,浏览器会回到上面解析域名那一步,按照下面的步骤往下一步一步执行,请求中的 Host 头部会变成另外的域名。

HTTP服务器请求处理

HTTPD(HTTP Daemon)在服务器端处理请求/相应。最常见的 HTTPD 有 Linux 上常用的 Apache 和 nginx,与 Windows 上的 IIS。

  • HTTPD接收请求
  • 服务器把请求拆分为以下几个参数:
    • HTTP请求方法(GET, POST, HEAD, PUT 和 DELETE )。在访问Google这种情况下,使用的是GET方法
    • 域名:google.com
    • 请求路径/页面:/ (我们没有请求google.com下的指定的页面,因此 / 是默认的路径)
  • 服务器验证其上已经配置了google.com的虚拟主机
  • 服务器验证google.com接受GET方法
  • 服务器验证该用户可以使用GET方法(根据IP地址,身份信息等)
  • 如果服务器安装了 URL 重写模块(例如 Apache 的 mod_rewrite 和 IIS 的 URL Rewrite),服务器会尝试匹配重写规则,如果匹配上的话,服务器会按照规则重写这个请求
  • 服务器根据请求信息获取相应的响应内容,这种情况下由于访问路径是 “/” ,会访问首页文件。(你可以重写这个规则,但是这个是最常用的)
  • 服务器会使用指定的处理程序分析处理这个文件,比如假设Google使用PHP,服务器会使用PHP解析index文件,并捕获输出,把PHP的输出结果给请求者

浏览器背后的故事

当服务器提供了资源之后(HTML,CSS,JS,图片等),浏览器会执行下面的操作:

  • 解析 HTML,CSS,JS
  • 渲染——构建 DOM 树 -> 渲染 -> 布局 -> 绘制

浏览器

浏览器的功能是从服务器上取回你想要的资源,然后展示在浏览器窗口当中。资源通常是 HTML 文件,也可能是 PDF,图片,或者其他类型的内容。资源的位置通过用户提供的 URI(Uniform Resource Identifier) 来确定。

浏览器解释和展示 HTML 文件的方法,在 HTML 和 CSS 的标准中有详细介绍。这些标准由 Web 标准组织 W3C(World Wide Web Consortium) 维护。

不同浏览器的用户界面大都十分接近,有很多共同的 UI 元素:

  • 一个地址栏
  • 后退和前进按钮
  • 书签选项
  • 刷新和停止按钮
  • 主页按钮

浏览器高层架构

组成浏览器的组件有:

  • 用户界面 用户界面包含了地址栏,前进后退按钮,书签菜单等等,除了请求页面之外所有你看到的内容都是用户界面的一部分
  • 浏览器引擎 浏览器引擎负责让 UI 和渲染引擎协调工作
  • 渲染引擎 渲染引擎负责展示请求内容。如果请求的内容是 HTML,渲染引擎会解析 HTML 和 CSS,然后将内容展示在屏幕上
  • 网络组件 网络组件负责网络调用,例如 HTTP 请求等,使用一个平台无关接口,下层是针对不同平台的具体实现
  • UI后端 UI后端用于绘制基本 UI 组件,例如下拉列表框和窗口。UI 后端暴露一个统一的平台无关的接口,下层使用操作系统的 UI 方法实现
  • Javascript 解释器 Javascript 解释器用于解析和执行 Javascript 代码
  • 数据存储 数据存储组件是一个持久层。浏览器可能需要在本地存储各种各样的数据,例如 Cookie 等。浏览器也需要支持诸如 localStorage,IndexedDB,WebSQL 和 FileSystem 之类的存储机制

HTML 解析

浏览器渲染引擎从网络层取得请求的文档,一般情况下文档会分成8kB大小的分块传输。

HTML解析器的主要工作是对HTML文档进行解析,生成解析树。

解析树是以DOM元素以及属性为节点的树。DOM是文档对象模型(Document Object Model)的缩写,它是HTML文档的对象表示,同时也是HTML元素面向外部(如Javascript)的接口。树的根部是”Document”对象。整个DOM和HTML文档几乎是一对一的关系。

解析算法

HTML不能使用常见的自顶向下或自底向上方法来进行分析。主要原因有以下几点:

  • 语言本身的“宽容”特性
  • HTML本身可能是残缺的,对于常见的残缺,浏览器需要有传统的容错机制来支持它们
  • 解析过程需要反复。对于其他语言来说,源码不会在解析过程中发生变化,但是对于HTML来说,动态代码,例如脚本元素中包含的 document.write() 方法会在源码中添加内容,也就是说,解析过程实际上会改变输入的内容

由于不能使用常用的解析技术,浏览器创造了专门用于解析HTML的解析器。解析算法在 HTML5 标准规范中有详细介绍,算法主要包含了两个阶段:标记化(tokenization)和树的构建。

解析结束之后

浏览器开始加载网页的外部资源(CSS,图像,Javascript 文件等)。

此时浏览器把文档标记为“可交互的”,浏览器开始解析处于“推迟”模式的脚本,也就是那些需要在文档解析完毕之后再执行的脚本。之后文档的状态会变为“完成”,浏览器会进行“加载”事件。

注意解析 HTML 网页时永远不会出现“语法错误”,浏览器会修复所有错误,然后继续解析。

执行同步 Javascript 代码。

CSS 解析

  • 根据 CSS词法和句法 分析CSS文件和 <style> 标签包含的内容
  • 每个CSS文件都被解析成一个样式表对象,这个对象里包含了带有选择器的CSS规则,和对应CSS语法的对象
  • CSS解析器可能是自顶向下的,也可能是使用解析器生成器生成的自底向上的解析器

页面渲染

  • 通过遍历DOM节点树创建一个“Frame 树”或“渲染树”,并计算每个节点的各个CSS样式值
  • 通过累加子节点的宽度,该节点的水平内边距(padding)、边框(border)和外边距(margin),自底向上的计算”Frame 树”中每个节点首的选(preferred)宽度
  • 通过自顶向下的给每个节点的子节点分配可行宽度,计算每个节点的实际宽度
  • 通过应用文字折行、累加子节点的高度和此节点的内边距(padding)、边框(border)和外边距(margin),自底向上的计算每个节点的高度
  • 使用上面的计算结果构建每个节点的坐标
  • 当存在元素使用 floated,位置有 absolutelyrelatively 属性的时候,会有更多复杂的计算,详见http://dev.w3.org/csswg/css2/http://www.w3.org/Style/CSS/current-work
  • 创建layer(层)来表示页面中的哪些部分可以成组的被绘制,而不用被重新栅格化处理。每个帧对象都被分配给一个层
  • 页面上的每个层都被分配了纹理(?)
  • 每个层的帧对象都会被遍历,计算机执行绘图命令绘制各个层,此过程可能由CPU执行栅格化处理,或者直接通过D2D/SkiaGL在GPU上绘制
  • 上面所有步骤都可能利用到最近一次页面渲染时计算出来的各个值,这样可以减少不少计算量
  • 计算出各个层的最终位置,一组命令由 Direct3D/OpenGL发出,GPU命令缓冲区清空,命令传至GPU并异步渲染,帧被送到Window Server。

GPU 渲染

  • 在渲染过程中,图形处理层可能使用通用用途的CPU,也可能使用图形处理器GPU
  • 当使用GPU用于图形渲染时,图形驱动软件会把任务分成多个部分,这样可以充分利用GPU强大的并行计算能力,用于在渲染过程中进行大量的浮点计算。

Window Server

后期渲染与用户引发的处理

渲染结束后,浏览器根据某些时间机制运行JavaScript代码(比如Google Doodle动画)或与用户交互(在搜索栏输入关键字获得搜索建议)。类似Flash和Java的插件也会运行,尽管Google主页里没有。这些脚本可以触发网络请求,也可能改变网页的内容和布局,产生又一轮渲染与绘制。

 

 

https://github.com/skyline75489/what-happens-when-zh_CN

免费编程电子书(英文)集合

书籍分类:

C、CPP、C# 、Objective-C、Java、Python、PHP、Ruby、HTML/CSS、

JavaScript、SQL、.Net、网络、算法、数据库、图形学

http://www.freeprogrammingbook.com/

 

阿基里斯与乌龟赛跑

 

阿基里斯每跑一步有一个最小步幅,当阿基里斯和乌龟之间的距离小于阿基里斯的最小步幅时,下一步就必然超越乌龟,而不是无限接近乌龟。用量子物理来解释,我们的世界不是连续的,是有一份一份量子组成的,从前一个量子跳到下一个量子,不是平滑过渡的,而是瞬移的。通俗一点解释,我们的世界是有分辨率的,如果我们把世界放大到一定程度,就会出现一个一个四方的晶格,线条不再平滑,这个晶格就是海森堡说的矩阵,就是我们世界的最小单位。同样的理论可以用到股票市场,股票价格精确到0.01元,但是没有0.005元。所以当阿基里斯(买盘心理价)和乌龟(卖盘心理价)之间的距离小于0.01元时,就会成交。

 

高效的在线编程学习网站

对于入门级的程序员和编程爱好者来说,如何快速而简单的提升技能?选择靠谱的网站学习很有必要。今天推荐几家既能在线编程,课程又颇具趣味性的网站。有国外的codecademy、TeamTreeHouse,以及国内与之相似的慕课网。这三家网站类似,也各有其特色,看看究竟该如何选择?

1、Codecademy:互动编程教程

\

网站介绍:Codecademy创建于2011年,它是一种基于网络的互动编程教程。

优点: 免费,使其赢得了很多客户;交互式编程学习,给用户良好的体验,学练结合的方式也比较适合编程语言初学者快速提升编程能力。

缺点:在教学方式上,codecademy网页左方的工具条会指导用户完成每一项任务,虽然简单,但是纯文字的形式在一定程度上容易让用户产生视觉疲劳,缺乏观赏性。另外,对于英文不好的学习者来说,语言是个门槛。

提供课程: HTML、CSS、JavaScript、php、Python、Ruby。

2、TeamTreeHouse:在线网站设计教育平台

\

网站介绍:在线网站设计教育平台,所有授课都是通过视频教学以及在线测试。

优点:超过700个高质量的教学视频,内容风趣直观,可观赏性颇高。在线测试可以使用户获得相应的勋章作为自己取得成就的奖励。

缺点:需要付费;视频内容为英语教学,没有字幕,语言也是一大难题。

提供课程: Web设计(包括CSS3、响应式设计等)、Web开发(HTML5、JavaScript等)、iOS应用开发

3、 慕课网:交互式在线编程

\

关于慕课网:2013年8月上线,聚焦学习过程的互联网IT技能学习社区。

课程介绍:前端开发(HTML、CSS、JavaScript)、PHP开发,每个方向的课程又分为初、中、高三个级别。支持包括Java、Python、Nodejs、C等多种编程语言。

优点:慕课网课程自制,并且全部免费。交互式社交化在线编程学习,用户可以在线讨论,进行代码快照交流;提供实操性强的案例视频,动画元素丰富,趣味性强。同时,也提供iOS、Android应用,用户能随时随地利用碎片时间进行学习。

缺点:课程内容较少,体系有待完善。

综合比较,国外的codecademy和treehouse更为成熟,而慕课网则更像codecademy的国内版。可喜的是,它在继承了codecademy在线编程功能的同时,也融入了自己的特色,加入了视频教学的方式,让课程不再那么沉闷。同时视频教学也能对在线编程一些不太方便演示的地方做到有效的弥补和扩展,例如电商网站等复杂系统、以及涉及环境搭建等需要在多个环境中切换和演示的项目,都可以用视频方式来演示。

但在课程内容及体系上,慕课网作为后起之秀,仍然需要不断加强完善。而treehouse的付费模式及语言关在中国似乎并不接地气,也因此流失了部分初级用户。至于如何选择则是仁者见仁,智者见智。

OneNote免费啦!

微软OneNote免费啦!微软员工辛辛苦苦干了那么多年,OneNote现在单飞而且免费啦!

放眼笔记软件市场,Evernote口碑良好但是在中国市场搞精分,国内有道为知麦库后起,尚有潜力;

微软公司的OneNote,之前一直是office旗下附件,提供了大概是业界最好的手写操作体验的笔记软件,同时还可以通过微软的SkyDrive帐号在多客户端间同步笔记,干脆方便。

现在已经横跨了Win、Win应用商店、WP、Mac、iOS、安卓等平台,为用户在各平台同步自己数据提供了方便的选择。详细介绍可以参见官网

新用户可以考虑在OneNote官网下载体验。

爆料网友还提示,可以在知乎查看大家的讨论。

5329012468b62.jpg_n1

5329029a5ee21.jpg_n1

71f068afcf8b7caa8706b51e373c16d9_m

 

部分摘自知乎的热门回答”

OneNote的免费化,对于Evernote来说是个极大的威胁。这是一款历史比Evernote长,功能比Evernote强(一大大大大大截),理念比Evernote好,编辑比Evernote舒服,界面比Evernote漂亮,UI比Evernote流畅,同步流量无限制,而且现在还免费并且开放了API的笔记神器。可以说,Evernote除了早期利用免费化,获得了大量个人用户外,用户基础比较大以外,在OneNote面前近乎一无是处。

在桌面端上,OneNote几乎把笔记做到了极致。

那么,移动呢?

微软在Office方面的理解一直与其他公司不同。微软始终认为,在移动端上,尤其是手机上,受制于性能和屏幕大小,你所做的应该是比较简单的任务,例如基本的查看、输入(插入图片、录音、视频等)、以及简单的编辑。你可以说是保障用户体验,也可以说是阉割。这只是一种平衡选择而已。

也就是说,OneNote的编辑体验,仍然是在电脑上最爽。在形如Surface Pro这样的、带有电磁屏的电脑上,尤其爽。

其实过去OneNote一直被广泛用于企业市场,在企业市场Evernote被打的毫无还手之力。只是现在微软开始注意到个人笔记这个庞大的市场了而已。

 

借着现在免费的机会,我推荐所有人都去试试OneNote,并且寻找转移平台的方法。因为你一旦学会用了,恐怕就再也不会去用其它的笔记软件了。

———————————-OneNote是许多人爱不释手的工具软件。

谢谢各位点赞。每款软件都有自己的牛逼之处,Evernote也有,例如直接导入PDF,这点OneNote要稍微麻烦些,得要通过send to onenote来实现(尽管也没麻烦多少)。再比如,Evernote开放API很早,所以各种第三方插件、各种机器人也比较多一些。OneNote刚刚开放API,功能还相对不那么完全。不过,我相信很快就会跟上。例如ifttt、邮箱等方式,已经为你制作剪辑或者笔记提供了极大的便利。

 

我选集一些已经开始使用OneNote API的OneNote应用来给各位展示下:

 

feedly(懂的都懂。订阅rss,然后制作简报,非常方便。)

ifttt(这个的玩法太多了,懂的也都懂)

各种便携式/联网式扫描仪的应用或者是iPhone/Android的文档扫描应用,包括:Epson/Brother/Doxie/Genius Scan/JotNot Scanner……

智能笔:Livescribe 3 ←这个我就不多介绍了,答主一直想买但是没钱的东西。。。“只要使用 Livescribe 3 smartpen 和 Livescribe+ 应用,就能轻松地在纸上书写,然后看到内容立即显示在您的移动设备上,您随即可以添加标签和搜索笔记,以及将笔记转换为文本。您可以将所有内容发送到 OneNote。”

OneNote Clipper:网页剪辑的一个强化应用。

Weave Reader:Win8/WP8的一个很赞的新闻阅读器。同样可以直接把新闻发送到OneNote笔记本。

Office Lens,WP专属的一个应用,我使用以后只能说,啊,妈妈再也不用担心我上课拍不好ppt了。。。

Mod Notebooks:将你的实体笔记和数字笔记完美结合的笔记本+服务。很有特色,只是国内使用恐怕不太方便。。。是这样:你先买他们的笔记本(你就当做是个高端版本的Moleskine吧),写好以后,用内置的预付费信封邮寄给ModNote公司,他们会在五天之内免费帮你把笔记本数字化,然后你可以选择回收本子,或者收回本子。每本售价25刀。

 

 

 

 

 

大学四年珍藏的电子和计算机专业资料和专业软件

分享者:
果壳网@斟理 微博@斟理http://weibo.com/131492012 欢迎大家关注我的微博。
武汉理工大学信息工程学院电子科学与技术系本科生
武汉大学计算机科学与技术专业双学位

资料来源:
以下资料是我在大学四年学习经历中在网络上搜罗的经典各科学习资料,其中还有我留下的一些武汉理工大学和武汉大学上课所用的课件。

分享动机:
我估计很多人跟我一样吧,很喜欢在网络上搜索各类资料,但是总有一些网站为了所谓的“注册账号”才让你下载或者什么“回复可见”之类的下流手段来骗取注册,关键有的时候你注册了一大通之后却发现资源很烂。所以我想给大家把这些比较好的资源集中分享。我的百度云账号也是“斟理”,欢迎大家关注我,我还会在研究生阶段继续分享有价值的资料。如果大家不想现在下载这么多资料可以注册一个百度云账号,把需要的资料先保存到自己的云盘。 大家如果觉得不错就多点一下推荐和分享按钮,举手之劳。也可以发表评论帮忙把帖子顶上去,让更多的人看到。

专业软件(适用于32位系统,部分含破解文件)
(1)Adobe AcrobatX:可用来编辑和查看PDF文件,含破解工具和相关文件。
百度云地址:http://pan.baidu.com/s/1i3qlqmD

(2)Multisim 12 :电路仿真分析工具,虚拟仪器这块很牛,含破解工具、安装教程。
百度云地址:http://pan.baidu.com/s/1hq62tP6

(3)Quartus 9.0 :PLD/FPGA开发软件,虽不算最新版本但是很多书以及一些实验室都使用它,含安装破解教程和工具。
百度云地址:http://pan.baidu.com/s/1i34ywwl

(4)Android 开发工具:一套开发所需的全部软件,包括ADT和Eclipse,解压缩后即可运行,前提是你已经安装好JDK
百度云地址:http://pan.baidu.com/s/1jGslgYq

(5)VC++2008学生版下载器:只需注册一个微软账号就可以使用,比什么VC++6.0要高端大气点,大家可以试试。
百度云地址:http://pan.baidu.com/s/1bn7Y0Sf

(6)Photoshop CS4 :已打包,含破解工具和破解方法,功能就不必介绍吧,修图神器嘛。
百度云地址:http://pan.baidu.com/s/1pJlVuOj

(7)Office2010和破解工具:办公神器,无需介绍。以我无数次的安装经验承诺破解工具无毒。(注意:适用密钥在文件名上,请勿修改)
百度云地址:http://pan.baidu.com/s/1mgmbzQC(Office 2010)
http://pan.baidu.com/s/1dDkTI3R(破解工具)

(8)Proteus7.10专业版:单片机仿真神器,含破解方法和汉化包。
百度云地址:http://pan.baidu.com/s/1dD3QAn3

(9)Keil uVision4:单片机C语言编译工具,已打包,含破解工具。
百度云地址:http://pan.baidu.com/s/1pJ4SiFL

课程资料(来自网络高评资源以及武汉理工和武汉大学课程课件)
(1)单片机大量经典资料,点开看列表:http://pan.baidu.com/s/1bnd6sJd

(2)嵌入式开发:书籍
《构建嵌入式Linux系统》:http://pan.baidu.com/s/1gd0yI6B
《嵌入式系统设计与实例开发》:http://pan.baidu.com/s/1dDilVnb
《嵌入式C编程与Atmel AVR》:http://pan.baidu.com/s/1kT0W6t5
《ARM9嵌入式系统设计与开发教程》:http://pan.baidu.com/s/1o6K3oJg

(3)大量Java资料http://pan.baidu.com/s/1bnxjf1H

(4)VHDL相关大量官方资料http://pan.baidu.com/s/1eQd0liE

(5)Proteus教程http://pan.baidu.com/s/1pJBDIt1

(6)电路与系统分析:使用MATLABhttp://pan.baidu.com/s/1jGFRIbO

(7)微机系统与接口技术:武汉大学课件:http://pan.baidu.com/s/1hqp7vrI

(8)计算机图形学:武汉大学课件:http://pan.baidu.com/s/1i3jzGpv

(9)计算机操作系统:武汉大学课件:http://pan.baidu.com/s/1o62mvQM

(10)模拟电子技术:大量书籍、课件和课设:http://pan.baidu.com/s/1jGFlL3o

(11)量子理论:大量书籍资料:http://pan.baidu.com/s/1pJJft8Z

(12)计算机组成与结构:武汉大学课件:http://pan.baidu.com/s/1o62mvRs

(13)计算机网络与通信:武汉理工课件:http://pan.baidu.com/s/1kT0W6wB

(14)复变函数与积分变换:书籍http://pan.baidu.com/s/1kTr3gEj

(15)电子设计大赛:题目和资料:http://pan.baidu.com/s/1jGuSX06

(16)算法分析与设计:武汉大学课件:http://pan.baidu.com/s/1kTkH62F

(17)《程序设计语言编译原理》http://pan.baidu.com/s/1fAmM6

(18)数据结构:武汉大学课件:http://pan.baidu.com/s/1bn8Eyzt

(19)物理光学:三本书籍:http://pan.baidu.com/s/1kT2YzbD

(20)信息理论与编码:武汉理工大学课件:http://pan.baidu.com/s/1qz8Wu

(21)二级C语言上机系统http://pan.baidu.com/s/1nt0S3G1

周鸿祎-天杀的骗子

以独调对周鸿祎和360的了解,下面这个帖子瞄一眼就知道是广告贴:
oMpa1qMHEI
广告帖不稀奇,做生意就靠广告开路。但这个广告贴很稀奇,必须细说。
附信内容:
oMpao4g0Jr
几点硬伤:
1、“天杀的骗子”令其电脑中毒受损,自称小弟直接写信给360老板要施舍一台尚未上市的路由器,够疯狂不?何况他用的根本不是360路由器;
2、2月15日写信,情人节怎么是“前几天”?
3、通常都是电脑 DNS 被劫持,关路由器鸟事?(DNS递归链上任何节点被劫持都有可能,但那是外围的,不予考虑。另外,TP的这款路由器还没有曝什么重大漏洞吧?当然,如果不设防,一切皆有可能。)
4、电脑一直“裸奔”着(未运行任何安全软件)、路由器也不是360产品,怎么成了“360忠实用户”?
以上,小儿科。重点来了……
被锤子“怒砸”的路由器:
oMpLmprWF4
散架的组件毫无破损,除非双眼瞎才看不出这是专业级的正常拆解,绝非锤子砸坏的。
经查,这是 TP-LINK 出品的 TL-WR842N 无线路由器(上图中白色框中有品牌型号,不过需要点眼力):
oMpaomE7RH
看到这里,读者大概心里有数了:360这是在踩着 TP-LINK 上位。话说 TP-LINK 要不要起诉360名誉侵权啊?
接着看快递单:
oMpaoPglGM
额,“360忠实用户小何”竟然知道周鸿祎的手机号码是13701191098(独调证明,此号码属实)。
快递单号不太清晰,扫描条形码确定单号为1035786044707:

oMpaoXshzU

查询EMS官网,无快递单1035786044707的处理记录:
oMpF1B4YXk

确认快递邮包纯属虚构,因此整个事件纯属捏造,属于欺诈性营销行为,诋毁竞争对手产品,同时侮辱广大网民智商,性质恶劣。

在感觉可能露馅后,周鸿祎赶忙删除帖子,涂掉快递单号和手机号码后重发帖子:
oMpao4Ivmv
不好,条形码没有涂掉。哈哈!
该结案了:这个“天杀的骗子”,就是360老板,周鸿祎。

为什么诈骗短信看上去那么弱智?

File

XX集团举行三十周年大庆典,您的手机号码获得了20万大奖。

爸我在外嫖娼被抓手机被没收,快汇5万保释费到XX。

相信用过手机的人都收到过类似的短信,你有没有这样的疑问:这些已经被媒体曝光成千上万次骗术为什么还是一再出现?骗子们看上去实在太不好学了,怎么也不开拓创新一下理念,这么out的东西还有人信吗?最近,微软的研究人员回答了这个问题,骗子才没我们想的那么简单。

从“尼日利亚王子”说起

在英文 Email 里,最流行的垃圾邮件就是“尼日利亚王子”,大体故事情节是尼日利亚几位高官要把巨额资金以“国家秘密”的形式转移到国外,需要使用你的名义和银行账户,转移成功之后你将获得上千万美元中的 10% 作为酬劳。如果答应和这些“高官”合作,过一段时间骗子就会以事情进展不顺利为由,让你先垫付一点“微不足道”的手续费和打点官员的小费,付过几次钱之后,对方就变得无影无踪。“尼日利亚王子”就是这样一种没有任何高明之处的诈骗方式。

File

一封“尼日利亚王子”邮件

这种骗术在之前的纸制信件里就开始流传,后来是通过传真,再到后来的电子邮件,已经有几十年的历史了,可谓“经久不衰”。由于不断被冒用名义,尼日利亚政府在 1991 年不得不公开发表声明不存在这回事,不过这封邮件直到今天依然很流行。微软的研究人员想弄清楚的是,这封文笔都不通顺、谷歌就找到的邮件为什么还一直在被骗子使用。他们为何不写些生动形象、新颖逼真的版本?

依据损失而设定的灵敏度

在回答这个问题前,我们先把目光移向与诈骗邮件风马牛不相及的防火警报器。

在宿舍里,火灾报器常常半夜里叫起来,最后却发现是虚惊一场,它为什么这么不靠谱?这大概是因为警报器的本身“水平有限”,传感器总是不能区分真正的火灾和吸烟产生的烟雾、空气湿度变化、气温过高这些正常情况,因而就会产生两种错误:不应该响的时候乱响(false positive)和该响的时候不响(false negative)。可是 false positive 和 false negative 两种情况总是一个变小另一个就变大。如果把警报器调的灵敏一些,它就会经常没火的时候乱响,但是有火的时候失灵的几率就小了很多;如果让警报器迟钝一些,就不会半夜里总是把人吵醒,可是真着了火它也容易不响。警报器的灵敏度是一把双刃剑,什么样的灵敏度才是适当的,要视 false positive 和 false negative 两种后果造成的损失(即成本)大小而定。对于警报器来说,如果没火的时候乱响,损失不大,可是真有了火灾它没有发挥作用,就会造成巨额财产损失甚至生命危险,权衡利弊,我们宁愿把防火警报器调的灵敏一些,让它乱响几次以防万一。

警报器不该响的时候响、该响的时候不响的困扰也存在于其他很多场景,不过灵敏度却未必总是要越高越好。例如在法庭上,如果对一个嫌疑人的指控证据不充足,处于“半有罪半无罪”的状态,法庭也会像火灾报警器一样犯两个错误:把好人冤枉成坏人(false positive)和把坏人当好人放了(false negative)。这种情况下如果把灵敏度调得高一点,就意味着“宁可错杀一千,不可放过一个”;如果把灵敏度调得低一点,就意味着“永远不冤枉一个好人”。比较一下两种情况的造成的损失,如果把一个好人误判为有罪,这样的冤案哪怕只有几起,也会让法庭的公信力大大下降,比暂时放掉一个坏人的损失要大得多。所以大多数国家在这里会把敏感度调得比较低,这就是所谓的“疑罪从无”。

骗子没有看上去那么笨

File

回到最初的问题上来,灵敏度和诈骗短信有什么关系?微软研究人员认为,骗子发电子邮件和上述情形有共通之处。

对于骗子来说,目标就是在茫茫人群中找到一个受骗者,把钱骗到手。不过,大家要搞清楚的是,仅仅对骗子的电子邮件有兴趣,回复了邮件,只能称得上“上钩”,最后把钱汇到骗子手里才称得上被骗。人群里最后上当的人的比例跟电子邮件内容没很大关系,因为上钩者不会只因为最初的邮件内容就汇钱给骗子,更关键的是接下来与骗子的联系情况,一旦“上钩者”发现不对头的地方,就会中断与骗子的联系。电子邮件的质量相当于“灵敏度”,会先把人群里一部分可能上当的人筛选出来。

骗子们的false positive和false negative就是:

false positive:把人群里本来不容易上当受骗的人钓上来了,进行行骗。

false negative:错过了人群里很傻很天真的人,没有骗到他们。

容易看出,骗子整体的骗术相当低劣,而如今人们警惕性又越来越高,能上当的人的比例少之又少,可能只有万分之一。如果“尼日利亚王子”的邮件写得像福尔摩斯侦探小说一样滴水不漏,相当于把灵敏度调高,false positive会变大,false negative会变小,这就意味着骗子起初需要联系的人变多了,但最后真正上当交钱的人未必会增加多少,结果不见得划算。

那骗子在两种情况下的成本各是什么呢?

false positive:骗子进行这种诈骗也不是没有投资,群发邮件没有多少成本,可是如果跟钩上来的鱼一对一联系起来,成本就变大了。如果联系的人比较多,需要雇用更多的“客服”,需要开更多的银行账户,需要制作更多的假材料,甚至还有把“放蛇”的警察引进来这种风险成本。最后这些不傻也不天真的人会在深入的交流之后发觉真相,拒绝交钱给骗子,那骗子就是白忙了。

false negative:很简单,最后交钱的人少了,骗到的钱也减少了。

综合下来就是,彻底把一个人的钱骗到手概率不大,false positive成本不小,false negative成本没想象的大,三个因素合到一起会迫使骗子降低钓鱼的灵敏度。他们故意发一些很假的邮件,这样上当的都是些“真傻”的受害者,可以减少跟“钓上来的鱼”辛苦联系一番,最后却一分钱没骗到。这一方面说明,现在这年代骗子们行骗的成本越来越高,这个行业越发不景气。另一方面也说明,骗子们其实还是很有商业头脑的。

1 2 3 4