85.电脑原理03:布尔和布尔代数

软件那些事儿

1 翠花,上干货 开始之前,先讲一句干货,以满足一下在后台留言的一些同学,每一期都有人留言说讲的不通俗,没有干货,作为一个负责任的播主,还是听取听众的意见,先把干货端出来,这次音频的内容是讲布尔代数很重要。就这样,布尔代数很重要,只需要知道布尔代数很重要就可以了,至于为啥重要,根本没必要知道,好了,干货结束了,想听干货的同学可以换个电台了,接下来的时间开始吐槽。 2 布尔变量无处不在 如果听众中有程序员或者计算机系的学生,一定知道几乎所有常用的编程语言中,不管是C还是C++,还是Java,还是Python,Ruby,在这些编程语言里,常用的数据类型中,一定有个非常重要的类型叫布尔类型。布尔类型里面就是两个值,一个是0,一个是1,或者一个是True,一个是False。有些同学可能会觉得,这简直太无聊了,谁会搞这个发明呢?有这种想法的人并不奇怪,搞出这个发明的人叫乔治•布尔,他发明了一种数学,叫布尔代数。布尔代数发明以后的接近100年中,几乎所有的地球人也是这个想法,谁会用这种发明呢?因此,布尔同学这么出名,并不是因为布尔代数,而是因为微积分以及差分方程这两个数学的分支,只是到了最近,尤其是在1937年一位伟大的计算机先驱香农发现了布尔代数的巨大作用,布尔代数这才开始传播到朋友圈里,然后每个人都开始谈论布尔代数,就好像他们一直以来就很懂一样。 说起来有点讽刺,布尔先生在代数,微积分以及连续数学方面取得的成就当然也是无可比拟的,但是和他在布尔代数方面所取得的成就比起来,还是要黯然失色许多,但是,这么伟大的成就,竟然被埋没了接近100年才被人所发现。 有这样一种可能,在计算机领域,所有的量都可以转换为简单的枚举,只是今天人的认识,还不够深入,有一些已经实现了,有一些还没有实现。不过呢,我认识水平也是非常的有限,不敢对未来做出判断。作为我这个公众号——软件那些事儿——我也只敢光讲一讲布尔先生的生平事迹,对我来说,这些故事已经非常非常的精彩了,尤其是布尔代数如何从默默无闻到现在在计算机领域的无所不能,这个故事起码给我无限的感慨,如果没有香农慧眼识珠,布尔代数也许还要被埋没多少年也不一定,我们这个世界上绝大多数的人都没有什么眼光和远见,大部分人只是跟跟风,发发朋友圈。 布尔先生还算不错了,毕竟他生前也算风光,另一个非常非常悲惨的数学家,就是创立了现代集合论,也就是今天我们微积分的基础,或者说是实数理论的基础,这个人的名字叫康托尔。他提出了集合的等势概念,包括无穷,可数无穷等一系列概念,并且给出了严格的证明。他运气不太好,像布尔代数无人问津,他的无穷概念有人问津。他的理论被喷子盯上了,当时数学界的网红叫克罗内克,由众多的粉丝,当然,他的理论在今天来看是错误的,但是当时来看,他是正确的。现在,我们仍然可以看到克罗内克的名字,就是在线性代数的课本上,我们会学到一个叫克罗内克积的东西,就是这个当年喜欢攻击别人的数学家。克罗内克发动了一波又一波的喷子大军,在媒体,报纸杂志上对康托尔口诛笔伐。 结果康托尔同学的心理素质不是很好,而且反击的手法也不够简单粗暴有效,喷子们对康托尔采取的是谩骂和讥讽,结果康托尔同学竟然公开发论文,对他的理论进行严格证明,,使用了归纳反证法来论证他的理论是正确的,然后让喷子们来找出逻辑漏洞。人家是喷子,哪管什么逻辑漏洞,反正也看不懂啥叫归纳反证法,继续喷。康托尔最后患上了严重的抑郁症,最后精神失常了,最后在一个精神病医院很凄惨的死去了。然后,又过了很多年,喷他的人也都死了以后。后人才发现,康托尔是正确的,然后我们整个现代的数学大厦的根基,康托尔的集合的理论功不可没。好了,我又跑题了,强行拐弯拐回来,继续讲布尔先生。 3 布尔的生平 国内喜欢找一些人当励志的典型,但是励志的典型并不多,尤其是中国几千年延续到今天所采用的都是皇帝说了算,很难找到励志的典型,尤其是中国除了四大发明,也确实没啥可以拿得出手的东西,而且四大发明这个说法,只广泛的影响了中国,你去问一个外国人,90%的可能,他们不知道啥叫四大发明。本文的主角,布尔先生,也算是个励志的典型,和上一次所说的法拉第,是为数不多的穷小子成为世界顶级科学家的人之一。 法拉第的老爸是铁匠,布尔的老爸是鞋匠。他所受的正规教育也非常的少,标准的小学生水平,但是,他一直自学数学,完全凭兴趣爱好来学习数学。他是一个老师,大家不要怀疑为啥一个小学毕业生还能当老师呢?难道没有教师资格认证考试么?有没有我不知道,反正,这个学校是布尔自己的学校,非常非常小的一个学校,类似于现在的补习班的规模,最初的老师就是他自己一个人,教几个小孩,最后这个学校成了一个规模不大的中学,老师仍然不多,学校的规模依然不大。布尔就这么一个数学爱好者吧,他生前的公认是个老师,后来由于交友广泛,外加老师当的不错,就去大学当老师了,科克大学的老师。 他自认为自己不是学术精英,而是一个自学成才的老师。这个评价并不是可以的谦虚,应该还算是比较公道的一个自我评价,因为他生前布尔代数并没有像今天这么火热,而是无人问津的一个科学,而他擅长的领域,微积分以及连续数学,差分方程领域,他又不是开创者,因此,我猜测这个自我评价应该还是很严谨的。因为布尔的传记里,对布尔的评价就是一个严谨并且极其认真,工作非常努力的一个人。布尔这个人其实人生的大部分时间都是单身,痴迷于研究数学和教别人数学,因此在40岁的时候,才脱单,结婚了,娶了一个比他小17岁的女孩为妻,然后他们两个人共同生活了9年,在49岁的时候,布尔冒着大雨去教课,结果淋病了,得了肺炎,就去世了。布尔的生平,很多信息都是他的妻子和他的姐姐整理出来的。 再多说一句,布尔虽然只和他的妻子生活了9年,但是,在这9年中,他们生了5个女儿,然后,他的5个女儿每一个都是非常有影响力的人,如果自己没有影响力,自己的后代就有影响力,就是布尔的孙子孙女辈,布尔的妻子非常的长寿,布尔去世52年以后,她才去世。 布尔的大女儿生的两个孩子,如果年龄稍大的中国人应该知道,老大儿子和女儿,应该喊布尔外祖父,这两个人的中国名字叫韩丁和寒雪,是毛泽东的崇拜者,也是中国绿卡获得的第一人,两人都有在中国长期生活的经历,在70年代,是中国家喻户晓的“老朋友”。周恩来多次接见他们,寒雪在中国逝世,寒雪的子女目前都在中国的大学里当教授,大家有兴趣可以搜搜看看。他们都还健在,对于他们的选择,我们也不能说啥,是非常非常靠谱的,非常非常坚定的共产主义者。寒雪是美国的核物理专家,依然放弃美国的事业,来到中国北京养奶牛,她们两口子为了共产主义在中国养了一辈子牛,而且,对母牛的血统非常的执着,一定要是从革命圣地延安引进的母牛,这位有理想的老人去世了,她最大的担忧是怕她的农场被拆迁了,她养的那些牛就没有地方可去了。她最大的遗憾是现在的人都忙着赚钱,都不去革命了!我都不好评价什么。寒雪的老师是费米,他的同学是杨振宁, 布尔的后代好多牛人,包括流体力学,四纬几何的重要贡献者,还有作家,牛氓的作者伏尼契也是布尔的后代。现在人工智能特别的流行,深度学习之父的名字叫杰弗里•辛顿,按照辈份的话,是布尔的重孙辈。 4 跑个题 好像又跑题了,又不是干货了,既然跑题了,我就谈一下干货这个事儿。我觉得想听干货的人,脑袋是有问题的人,只想走个捷径,最好是把一门科学几句话讲出来,类似于考试的划重点,其实,我挺瞧不起天天嚷着让我讲干货的人,爱听不听,别给我提意见。一门科学,比如说本文所讲的布尔代数,是离散数学的一个分支,离散数学又是当代数学最重要的一个分支,或者不能说最重要,我个人认为的最重要吧,离散数学是计算机科学的数学基础,所以我觉得非常重要。如果仔细划分的话,数理逻辑,集合论,图论和近世代数是离散数学的四个分支,其中数理逻辑是基于布尔运算的。我认为任何有用的知识,都不太可能在60秒之内学会的。因为有个关注者,希望我能做一个60秒的版本,而且说,如果一个想法不能在60秒之内讲清楚,这个想法就不值得去了解。 由于微信后台包括喜马拉雅骂我的人已经太多了,每天都有,集中在口音和没有干货上,还有不爱祖国上,我一般是不回复的,如果喷我两三次,我就把它拉黑。我个人觉得数理逻辑也好,人工智能也好,甚至学习一种系鞋带的方法,60秒都不太够。人生说长不长,说短不短,反正到时间了,咱们都不太可能活着和这个世界说再见。那么着急干啥呢,如果有人对布尔代数感兴趣,可以买一本数理逻辑研究一下,里面的公式非常的多,60秒远远不够,仔细研究的话,600天也不是很够。我这个节目里,只能讲其中的一点点,对计算机的原理有点帮助就行,我也没打算把数理逻辑讲清楚,首先我没有这个能力,因为数理逻辑仍然在进化,虽不能说突飞猛进,但是依然慢慢吞吞的影响着这个世界。 5 布尔代数和逻辑和人工智能 还有人建议我讲人工智能,可能觉得这玩意先进,其实,人工智能并没有多么神奇,就是基于布尔代数的一些运算,等我讲完电脑原理以后,会涉及到人工智能的发展历史,其实如果追本溯源的话,布尔代数就是试图模拟人脑的思维。人类想制造出人工智能,早在几千年前就开始尝试了,因为人类对大脑的理解非常的不够,包括今天,也没有搞定大脑是如何运行的。如果人类能理解大脑的话,早就反编译一个大脑出来了,逆向工程造一个大脑帮我们想问题。但是,搞不定,于是才退而求其次,打算研究一下逻辑,按照大脑的工作方式来研究大脑。早在亚里士多德的年代,亚里士多德就已经开始研究大脑了,他觉得大脑和逻辑有密切的联系。证据就是亚里士多德逻辑学基础的三段论法,这个我就不展开了。 再后来包括莱布尼兹,和牛顿独立发明了微积分的那个家伙,也曾经试图对大脑的思考方式进行研究,他在逻辑学上也有重大的贡献,但是,后来没搞定。再后来就是布尔同学的《逻辑的数学分析》《思维的规律》这两本书的出现,算是搞定了如何用数学把逻辑定义出来。但是,当时的人根本没有注意到这个伟大的成果,很可能布尔同学自己也没有注意到这方面的巨大应用,所以,在布尔代数上,他花费的精力并不是特别多。 我们只看看书名的话,《思维的规律–逻辑与概率数学理论的基础》,因为内容看不懂啊,所以,只看书名的话,我们就知道,布尔同学起码已经意识到了,如果用数学来描述大脑的工作方式,也许,我们就真的可以了解大脑的思维,现在来看,可能觉得这有点不靠谱,但是,人类总是这样啊,总觉得这事儿能搞定。既然大脑的思维方式能用数学搞定,那制造出一个大脑,还不简单啊!实际上,就是不简单! 我个人认为,我们离搞清楚大脑的原理还有很大的路要走,离人工智能有更远的路要走,可能人工智能会在围棋上赢人类。但是,我们如何告诉人工智能以下的事情呢?为什么我们去健身房,经常是跑步5分钟,自拍1小时,还要把照片美颜一下发到朋友圈里呢?这个人工智能很难想明白啊。为什么人类去吃个日本料理会拍个照片,去沙县小吃吃个5块钱的炒河粉就不拍照片呢?为什么发生了矛盾,男人之间是撸起袖子干一架,而女人是在背后散播谣言?这个事情在完全搞明白之前,我觉得人工智能还是需要走很长的一段路的。 6 布尔代数和传统代数的区别 传统代数就是我们上街买个菜,然后算一下给多少钱,或者时间一分等于60秒,60分钟等于1小时,传统的数学给我们的感觉,是连续的,所以,我们才能在谈恋爱的时候说出我永远爱你这种肉麻的话,永远有多远我们不知道,但是,肯定是连续的。布尔代数的出现,一下子改变了这种状态,类似于量子力学的出现,把我们对世界的的认识从连续的状态一下子扩展到离散的状态,比如说我们在炉子边上烤火,能量并不是连续的,而是一份一份的能量过来,能量是可以分成一块一块的不可细分的单位。在布尔代数里,更是这样,什么东西都是可以量子化的,从连续的,变成一个一个的。就像前面我说的,当你对你女朋友说永远爱她的时候,这个永远是可以分成一个一个的不可细分的小永远,最后才组成了一个大永远。这就是布尔代数的方法,因此,这门课的名字叫离散数学,万物都是离散的,否则为啥不叫整体数学呢? 只有把万物都想像成离散的,从连续的变成一个一个不连续的,也就是全都量子化,才能用到布尔代数里的运算,布尔代数里最重要的三个运算,与或非。说来很奇怪,我们的计算机,无论多么复杂,无论多么的智能,最后就是做这三个运算,与或非。在计算机中,只需要两个数字,0和1来表示布尔代数中的两个值。布尔代数的伟大在于,把数学和逻辑结合在了一起,而且只要两个状态就可以,在电脑中,就是高电平和低电平,电压高一点还是低一点。同样,我们也可以用继电器来表示这两个状态,当弹簧弹开的时候,代表数字0,当弹簧片闭合的时候,代表数字1。就是这么简单直接粗暴。 7 布尔代数的运算 布尔代数的三个基本的运算,与或非。比如我们有一个集合代表所有的人类,用数字1来表示,有一个集合M代表所有的男人,有一个集合F代表所有的女人,这时候,M + F = 1。因此在布尔代数里的加号和数字1和传统代数里的加号以及数字1表示的意义并不相同。这一点,以后我可能会用到公式,希望大家明白这一点。 还是上面这个例子,M代表所有的男人,F代表所有的女人,那M和F的并集就是0,因为人就是分为女人和男人,不可能一个人同时是女人又同时是男人,当然现在科技发达了,凡事都有可能,但是在布尔代数里,我们认为是不可能的,公式是这样写的 M X F = 0。在这里,乘号和数字0的意义和传统代数里的意义也不同。 我为什么要强调呢,那是因为上一次节目里,我画了一个电磁铁的电路图,有个互联网思维的哥们跑过来跟我说我说错了,电磁铁画错了,一段导线缠在一个铁棍上通电,怎么可能产生磁力呢?不管怎么说了,这件事情是我做公众号以来收到的最好的留言。 好了,电脑的数学基础就稍微的讲一点点,布尔代数,然后,接下来就用继电器去实现这个布尔代数的理论。至于用布尔代数和基于布尔代数的电路能不能实现人工智能,这个我也不好说。有时候我老婆在看包,我就问她,别看了,直接买下来吧,然后她说不用,这个时候,基于我经常判断错,她说的不买有时候是买,我就会确认以下,到底买不买?她会说:废话!这个时候,我就更疑惑了,这个废话,是说买还是不买呢? 我想知道的是,你人工智能这么牛,又会开车又会下棋,什么时候,人工智能可以帮我判断一下,我老婆要买包,到底买还是不买呢? 好了,这期就到这里,下期再见!

27分钟
99+
9年前

83. 电脑原理01-从继电器开始

软件那些事儿

1 几个故事 从这一期节目开始,一直到第100期,也就是这18期节目里,我只讲一个内容,就是电脑的工作原理。希望能把我所知道的工作原理讲清楚。现在就开始正式开讲。首先,讲几个小故事来引出今天的话题。 1.1 烽火戏诸侯 我们都知道烽火戏诸侯的故事,讲的是西周时期,周幽王为了逗他老婆开心,他的老婆褒姒(bao si)有个特点,特别的高冷,不爱笑。然后周幽王为了让这个女人开心,就点燃烽火台,诸侯看到烽火台冒烟了,就以为是西边的犬戎打过来了,然后纷纷的出兵。结果这个女人看到以后,特别开心,哈哈大笑。这个周幽王一看,这不错啊,就多次点燃烽火台,结果每次都是妃子笑,诸侯哭。搞多了,诸侯干脆不来了。结果犬戎真的打过来了,然后把这次周幽王又点燃了烽火台,结果,诸侯没有出兵。这就是狼来了的中国古代版本。周幽王被杀死。 烽火戏诸侯也是周幽王自己作死,作为政府的最高首脑,频繁的发假消息,首先是天子失信,下面就是诸侯失信,反正总体上来说,西周灭亡的一点都不冤枉。再多说一句,西周灭亡以后,周平王即位,然后把都城东迁到今天的河南洛阳,也就是历史上的东周。在这里,立下赫赫战功的人中有一个叫秦襄公的,就是因为烽火戏诸侯这件事情,间接导致了秦襄公被允许建国,也就是秦国,然后天子把封地分封给秦国,反正分封的土地都是犬戎的,基本上就是送个人情。就是这个养马养了几百年的秦始皇的祖先,因为烽火戏诸侯,得以建立秦国,随后,就是这个国家,统一了中国。 当然,这个故事是史记上记载的,在同期其它的史书上,有另外的记载,说不是烽火台,是敲鼓。不过,我这个电台里不追究历史的真伪,不管是烽火台也好,还是敲鼓也好。这里又一个重要的信息是,古人是如何传递信息的?姑且就认为是烽火台吧。烽火台上有干草,干草上面盖着一层狼的粪便,据说,狼的粪便燃烧起来,会有巨大的浓烟,所以有个成语叫狼烟滚滚,狼烟四起。当然,我没见过,别说狼烟,就是狼我也只是在动物园见过,倒是见过不少色狼。 这个故事告诉我们: 信息是可以通过媒介传递的,通过狼烟来传递 1.2 易北河会师 上一个故事讲的是古代中国的故事,第二个故事,我来讲一个现代的外国的故事。要给外国人一个露脸的机会。如果大家对二战比较熟悉的话,应该看过一张出名的照片,在一个断桥上,三个美国士兵和四个苏联的士兵在握手。这就是二战中非常著名的易北河会师。这张照片实际上是摆拍的,真实的情况我们已经没法知道,有一种说法是一名美国士兵和一名苏联士兵,由于语言不通,彼此拍了拍肩膀。这个,我们暂时不去追究了,毕竟对我们这个节目的意义并不大。 易北河会师发生在1945年4月24日,在此之前,希特勒已经是强弩之末,失败已经无法避免。早在易水河会师之前的两个月,也就是雅尔塔会议上,美国,英国和苏联已经在讨论胜利以后如何分配利益。在这个会议上,也制定了易北河会师的规则,美国和苏联分别从两个方向进攻德国,把德国切分成两部分。但是毕竟战场上没法分辨敌我,所以就规定了接头暗号。当两个国家推进到易北河的时候,就停止继续进攻,以信号弹来作为接头信号。会议上决定,苏联放红色信号弹,美国放绿色信号弹。 首先推进到易北河的是苏联的乌克兰第一军,然后静静的等候美军的到来。在4月25日的时候,美国的一个步兵巡逻部队首先到达易北河边。然后,发现自己忘了带绿色的信号弹。这时候,对面的苏联红军发现河对岸有情况,并且没有释放信号弹,就以为是德军,因此开始了猛烈的攻击。美军这边没有还击,因为是他们忘记带信号弹了,苏联红军一看对方没有还击,火力也停止了,决定首先释放信号弹。可惜的是,苏联带了信号弹,但是带错了。本来雅尔塔会议上决定的是苏联红军释放红色信号弹,结果带来的是绿色的。因此,苏联就释放了一个绿色的信号弹。当美军看到释放的是绿色信号弹以后,以为这尼玛咋搞的?不会是德军吧。然后,双方竟然打起来了!后来打的毕竟很心虚,美军就从战俘营里找来了一个会俄语的士兵,对着河对岸喊话。这才搞清楚,原来是盟军的部队。 Figure 1:栋哥亲自绘制的“优美”插画 这个故事告诉我们, 信号一定不能放错,不管是打仗还是搞电脑,一旦发出的信号有错误,后果不堪设想。 1.3 手电筒传情 第三个故事呢,是我瞎编的,只是为了引出如何设计一个传递信号的机制。比如说,我们和青梅竹马的女生住在一个小区里,没有电话可以联系,只有一个手电筒可以使用,在没有雾霾的黑夜里,实际上,我们可以通过手电筒来传递某种信息。就是两人分别拿着手电筒,可以在空中写字,但是,实际上,那些字是非常难以辨认的,这个方法根本不行。我们可以通过拼音的方法来实现通讯,最简单的方法是这样:用汉语拼音来实现通讯,从A-Z这26个字母,A按一下手电筒,B按两下手电筒,C则按三下手电筒…一直到Z,按26次手电筒。虽然效率比较慢,但是在没有雾霾的黑夜,一天晚上还是能够发一个一句两句话的。当然了,这个方法肯定没人去用,因为不但你自己累,接收的一方,也非常累,一旦数错了手电筒的闪光次数,那就非常崩溃了。不管如何,这也算是一种方法,只是很粗糙。 Figure 2: 以后插画都是这个风格,提前预警 我杜撰的这个故事呢,起码告诉我们,作为一个啥经验都没有的人,也是可以尝试设计一种系统,来通讯的。 1.4 莫尔斯码 第四个故事,摩尔斯码。摩尔斯是谁呢?大家应该都知道,他是电报之父,就是他,发明了电报这个东西。摩尔斯这个人,和我们课本上学的有点不同,我记得我上学的时候,说摩尔斯家境贫寒,由于某种原因,他不怕辛苦,不怕困难,终于研制出了电报。我小时候经常是这么被洗脑的。后来我才知道,摩尔斯不但家境不贫寒,而且老爹是个超级大富豪。摩尔斯本人呢,衣食无忧,是个画家,而且是个很出名的画家,每天的生活主要是想着能去哪里旅个游。而且,他在41岁以前,只会两件事情,花钱和画画,一点科学家的样子都没有。结果,有次,在旅游途中,在一艘轮船上,他的医生也很无聊,就和他展示了一个技术,电磁铁,一通电,铁棍就能产生磁场。这件事情,让摩尔斯产生了巨大的兴趣。41岁以前,他只会画画,电磁学的只是为0,远远不如他的医生懂得多。 然后,他回美国以后,才第一次买了一些实验仪器,开始自学电磁学的知识。刚开始的时候,纯粹是觉得这玩意好玩,他也没打算设计个啥东西出来,毕竟一个画家,到了后来,他才决定也搞一个通信系统出来。为什么呢,因为当时一大批人都试图搞一个通信系统,他不是第一个,也不是最后一个,确切的说,电报这东西的编码,根本不是他发明的,而是他的助手发明的。不管怎么说了,这个有钱的富二代,成功的画家,发现了一个有趣的现象,电流停止的片刻,导线上会出现电火花。 在这里多说一点,非常希望大家做一下这个实验,晚上把灯关了,用一节干电池,把正负极短路,也有轻微的电火花产生,这个我做过,只是电火花非常的微弱。我觉得吧,这个现象肯定不是摩尔斯第一个发现的,只是他第一个想到这个现象可以用来通信。因此,他的方法是这样的,有火花的时候看作是一种符号,没有电火花的时候看作一种符号,然后没有电火花的时间长度又是一种符号。这三种符号组合起来,就可以表示字母和数字了。 莫尔斯码其实和计算机关系不大,主要是和电报关系很大。有人说莫尔斯码是二进制的,这也是不对的,莫尔斯码是三种状态的组合,不是二进制。然后,摩尔斯很兴奋,就决定继续搞下去。然后,他花了很长的时间,设计了很多的编码,毕竟自己是个画家,经过了不懈的努力,他发现自己搞不定编码!有些事情,不努力一下,是发现不了自己不行的。如果有人不相信,你自己设计一下编码试试。反正我试了好几次,很难做出自己的编码。 然后摩尔斯就去找一个能搞定编码的人,他的名字叫艾尔菲德•维尔,美国人,是他发明的莫尔斯码。这个编码就是我们今天所知道的通过点,划和中间的停顿。不过,这个维尔同学,基本上没有什么名声,大家只知道摩尔斯这个人,并不知道摩尔斯码其实并不是摩尔斯设计的。其实莫尔斯码有好几种,比较出名的包括美式摩尔斯电码,还有国际摩尔斯电码等等,现在如果有人喜欢玩摩尔斯电码的话,也可以去玩,如果每分钟能发送20多个单词,还能获得业余无线电证书。 发送SOS的信号是三短,三长,三短。现在好像很多手机上的手电筒应用都有默认的设定,可以发送SOS的信号。我们可以看出来,因此摩尔斯码可以通过任何的媒介发送出去,不止是电线,也可以通过无线电,也可以通过手电筒。编码是相同的编码,发送的媒介可以与时俱进。 还有一个故事是,二战结束以后,很多的军人是会莫尔斯码的,然后两个退伍军人就去面试,面试的时候,有考题,笔试题。然后两个军人就通过铅笔敲桌子的方式来作弊,根据声音。结果,没想到监考的人也是个退伍军人,也通过敲桌子的方式发送莫尔斯码,来警告两位,不要作弊了! 这个故事告诉我们,当我们想传递信息的时候,编码搞定了,其实通过很多的媒介都是可以把信息传递出去的。可以通过手电筒,可以通过铅笔敲桌子,可以通过电线,或者通过无线电。比如说,在长征期间,红军的电报就坏了,主席非常开心,因为共产国际管不到他们了。那个电报,是通过无线电来传播的。 2 本系列的大体的脉络 2.1 巴贝奇计算机 如果大家以前听过我的音频的话,有两期我是做的人类历史上的第一个程序员,在里面着重说了几位人物,除了Ada,花费时间最多的人叫巴贝奇,巴贝奇试图用齿轮造出一台计算机,最终他没有做出来,但是后人使用他留下来的设计图,真的造出了那台机器,非常原始,但是能够工作的一台计算机。 2.2 继电器 在前面我刚刚提过,41岁的摩尔斯,在他的医生的展示下,第一次对电和磁产生了兴趣,然后,他花了很多的时间,由一个出色的画家,自学成才,成了一个伟大的工程师,并且拜著名的电磁学家亨利为师。我们初中物理的电学里,有这个人,亨利,电感的单位就是这个人的名字。在美国,他被认为是富兰克林以后最伟大的科学家之一。 摩尔斯是他的学生,前面我提到过,摩尔斯家族非常的厉害,他爸就是个学术界以及宗教届的牛人,具体牛到什么程度呢,大概是现在中科院院长,至少是个院士的地步。他爸爸是美国的“地理学之父”,在学术界和宗教界是不可忽视的力量,所以,摩尔斯才能够拜亨利为师,也是靠他老爸的关系。摩尔斯是耶鲁大学毕业的。 摩尔斯的发明,很大的一个推动力,就是他拜的这个老师,电感单位的牛人,亨利。电感的定义是这样的,虽然我们初中学过,我怕有些人忘记了,就提一下,因为这个定义非常的重要,以后我的课程里,要多次用到这玩意。电感是这样的,如果电路中电流每秒变化1安培,则会产生1伏特的感应电动势,此时电路中的电感定义为1亨利。这里的安培和伏特我就不多说了,安培是电流的单位,伏特是电压的单位。如果再解释,就没法讲了。再来说一下亨利的一个发明,他发现了电磁感应现象,比法拉第要早,但是,他没有法拉第有名气,因为法拉第确实更厉害吧,电容的单位就是纪念法拉第,我顺便提一下电容,是因为以后的节目里,也要用到电容这个东西。 摩尔斯的老师亨利先生,还有一个特别重要的发明,就是继电器。我这里说的继电器是最古老的那种继电器,电磁继电器。现在可能有同学说,继电器太多了,有固态继电器,磁簧继电器,还有热敏继电器… 这些继电器太先进了,我们不涉及。 我这里所说的继电器,就是最早的继电器,初中物理上的那个继电器,一个铁棍,一个线圈,一块电池,再加上一个弹簧片。这种最简单的继电器。使用这种最简单的继电器,使用一个或者两个,再加上一个弹簧片,就可以构建出我需要的各种逻辑门。然后再使用逻辑门,然后再使用逻辑门构建我需要的半加器。 2.3 为什么从继电器开始构造? 可能有同学会有疑问,为什么用这么落后的设备来构造计算机呢,现在都用晶体管了。是的,如果大家对计算机的历史有理解的话,第一台计算机再1930年代被制造出来,里面的设备就是继电器,这台计算机的名字叫机械式继电器计算机,这台计算机通过继电器里面的弹簧片的接通和断开来表示二进制的0和1,后来由于继电器的性能不能保障,因为里面有弹簧片,弹簧片这种东西,弹多了,就失效了,而且使用的能量也太多了。继电器中有弹簧,我们知道,弹簧的速度是不够快的,最快的弹簧片,需要1/100秒改变一下状态,而且,弹簧片不可靠,因此,并没有大规模的应用。但是德国的科学家朱塞就是使用继电器制造出了一台全自动的计算机,速度肯定不快,但是已经具有现在计算机的一些特征了,能够计算浮点数,二进制计算等等。后来才使用电子管代替了继电器,后来又用晶体管代替了电子管,但是,基本的原理并没有发生翻天覆地的变化。 今天我们使用的晶体管计算机,速度更快,能耗更低,也更便宜。但是,里面的工作原理和继电器的计算机并没有任何区别,今天的一个8位的加法器需要144个晶体管,同样,当年构造一个8位的加法器,需要144个继电器。只是现在科技发达了,由于集成电路的突飞猛进,144个晶体管,尤其是现在intel有10纳米的工艺,144个晶体管可能需要用电子显微镜才能看清楚。但是继电器的话,144个继电器,可能得一大坨。但是,我们要知道,里面的原理是一模一样的。 好了,下一次开始讲继电器的工作原理,如何用一个铁棍,一根导线,一个电源再加上一个弹簧片,构造出一个继电器出来。谢谢大家。

26分钟
99+
9年前

82. 钻钻牛角尖:为什么开发浏览器引擎这么难?

软件那些事儿

这一期的内容继续讲浏览器的工作原理,以及一些吐槽,或者这期的内容继续吐槽,顺便讲一点浏览器的工作原理。因为有些听众希望听到干货,不想听吐槽,对这些听众我想说的是,进错剧场了,我这个节目主要是吐槽,没有啥干货,并且,我始终认为,如果想学编程,希望通过睡前听不到半小时的音频,这是缘木求鱼。编程这个东西,是通过编译器以及无数次痛苦的调试才能掌握的技术,我不认为有什么灵丹妙药,可以让人通过每天半小时,或者每天7分钟能学会的。每天7分钟,让你成为编程高手,这就是扯淡啊!我觉得别说每天7分钟,我觉得0基础程序员的话,每天7小时,也得一年才能入门。 说实在的,我倒是看到过不少音频节目是这样宣传的,比如说,每天5分钟,让你实现财务自由,但是,如果要想听每天5分钟,得先付出199元钱,然后才能财务自由。然后,很多人就付了199元,结果让人家主播财务自由了。大家可能觉得我吃不到葡萄说葡萄酸,讲真,你们猜对了!我真的想不懂,真的有人觉得每天听5分钟,就能财务自由,这是不太可能的。我觉得任何有价值的技术,包括忽悠这门技术,绝对不会是每天5分钟,听半年就学会的,一定需要不停的锻炼才可以掌握。编程也是这样,可能相对于其它的一些技巧,编程算不上特别复杂的技术,但是,大家也不要认为通过听电台就能学会编程。如果想学编程,听我这个电台是不合适的,所以,大家也不要总是留言说要干货,我这里没有干货,只有吐槽。不要幻想通过听广播学编程,学编程只有一条路,就是打开你的电脑,打开编译器,要么阅读别人的源代码,要么调试自己的项目。其它的途径,都是效果很差的。 开始吐槽了,当浏览器拿到了HTML文档,需要解析,解析的最终结果是一棵二叉树,二叉树的每一个节点都是一个文档的结构。这棵树的名字叫解析树或者语法树。这两种叫法我都看到过,但是说的都是一回事儿,在数据结构的教材上,叫语法树的时候比较多。那什么是语法呢?这个语法和我们英语课上学的语法是不同的。我要开始讲编译原理的知识了。而且我没法用通俗易懂的语言讲编译原理的知识。我慢慢的发现,如果要讲清楚,或者说我自己思考清楚一件事情,唯一的方法就是从头讲起,比如说,我们很难让一个没有学过电路知识的人明白,一个电路是怎么工作的,如果真的要讲清楚,只有一个办法,就是从晶体管那个地方开始讲,否则,肯定是不清楚的。但是,如果从晶体管开始讲,那时间可就太长了,得讲好几天。还有一种办法,虽然讲不清楚,但是可以让听的人或者看的人,觉得自己清楚了,这种方法就是基本上所有的科普读物所采用的方法,类比的方法。这种方法其实只是好像清楚了,实际上根本没清楚。 我可以举个例子,比如说,现在的手机都是32G存储或者128G存储,但是,手机里还有个存储器,也就是内存,是2G或者4G。一方面是一个32G或者128G的存储器,另一方面是一个2G或者4G的内存,如果想对一个没有搞过计算机的人讲清楚这两个东西,是非常困难的,甚至,可能就是徒劳的。因此,我听过一个节目,就是试图讲清楚这两个东西是不同的。最后,不得不用了类比的方法,这也是几乎所有的科普书籍所采用的方法,类比。他把手机内存比做超市里的货架,把外存比作超市的仓库,然后说这两个是不同的,为什么不同呢?讲不清楚么,最后,不懂的人觉得手机里有一个超市的货架,还有一个超市的仓库,至于到底有什么不同,也就不去深究了。毕竟,手机里有有两个东西,一个是货架,一个仓库,这代表着两种存储器。这算不算是个方法呢?说实在的,我觉得也算是个方法,因为我也很喜欢看科普的读物,对个外行来说,知道一点总比啥也不知道强。但是,类比实际上对理解真正的原理没太多的帮助。 我得再狡辩一下,我对科普并没有任何批评的意思,因为面向大众的科普,比如说,我如果想了解黑洞,想了解微观可逆性,只能看面向我这种档次的人的科普,也就是大众科普。大众科普其实就是在非常浅显的面向大量的读者;如果读博士了,就是在很深的层次上面向很少的人,博士生的论文,肯定不会出现很业余的类比,人家都是直接上数学公式。 所以,我打算以不用类比的方法开始讲编译原理的知识。即使这样可能会有点枯燥无味。因为我的观点是这样的,计算机这个东西,总共发展了就这么多年,不用类比的方法,我觉得大部分人还是能理解计算机的美丽的,尤其是程序员。就像我们看到一个美女,就知道她是美女。根本不用类比的方法,说她像西施或者像仙女,比如说,汤唯就是汤唯,高圆圆就是高圆圆,不用类比,我也觉得她们是美女。编译原理就是编译原理,不用类比,我觉得也可以领略编译原理的美。 首先,讲词法分析器,这个玩意也叫词法扫描器。当我们拿到一个HTML文档的时候,尤其是可以把语法高亮显示的时候,我们一眼就可以看出,不同的颜色,代编不同的含义。比如说有HTML的各种标签,显示的颜色就和其他的文字的颜色不同。然后,我上一期节目提到的那几个引擎webkit开始进入语法分析阶段,在术语上把单词叫做token,也有翻译为令牌,记号等等,在这里我把这个token翻译为单词,因为HTML文件分解后的东西,的确非常像一个一个的单词。然后,用相对简单的规则,就把从网络上下载下来的文本文件,分解为一串一串的单词流,这样,为了下一步的词法分析做准备。很可惜,这一段话仍然是白话,对计算机来说,这段话就是废话,他根本不懂。为了让计算机能理解上面我说的这段话,需要用计算机才能理解的语言。比如说,正则表达式就是一个比较理想的选择。 如果是程序员,我就默认大家知道啥是正则表达式,程序员经常用正则表达式匹配字符串等等,我也默认大家已经是个正则表达式高手了。尤其是大家可以在脑子里默念一下正则表达式的规则,两个正则表达式的并,两个正则表达式的连接以及一个正则表达式的克林闭包,这三个表达式在心里想几秒钟,其实用这三种正则表达式的运算,就可以把文件给分离的差不多了。尤其是能完全用正则表达式表达的语言,比如说C#就是,这种语言也被称为正则语言。但是,很可惜,我们这个音频里讲的是怎么处理HTML和CSS,恰好,HTML和JSON都不是正则语言,那怎么搞呢?我当然是搞不定的!但是,因为这个世界上有不少默默无闻的科学家,数学家,他们能搞定。既然讲到了数学家,我个人心里还是挺佩服数学家的,因此,我本科在理学院中混,算是学了4年数学吧,当然,这句话说的有点儿心虚,因为我逃了好多课,然后就找不到工作了,幸亏学数学的时候,老师未雨绸缪,知道天天让我们学微分几何,偏微分方程或者拓扑学,是找不到工作的,所以,我们系允许去计算机那里学点编程,以防止毕业以后因为找不到工作,给饿死了,所以我学了一些C++编程,然后我就当了程序员,来填饱肚子。 因为我们所熟知的一些语言,是有递归的性质,比如数学运算也有递归的性质,尤其是我们小学三四年级所进行的加减乘除四则运算,有好几个括号的那种运算,实际上是可以通过递归的方法来算出来。可惜的是,我们三四年级的时候,根本不懂这个。在递归的语言中,我们没法用DFA来解释,因为,DFA只有有限个状态,是没办法追溯无限递归的。比如说,我们写网页的时候,可以在一个列表里包含另一个列表,在另一个列表里又包含另一个列表,理论上,只要足够闲的蛋疼,我们可以无穷的包含下去,这个时候,就是我前面所说的,使用正则表达式,正则语言还有DFA工具,都搞不定的状态。幸亏,有一些数学家,又搞出来了一个语言,他的名字叫上下文无关语言。英文叫做Context-Free Grammar。依靠这个工具,我们才可以愉快的上网看网页,当然了,绝大部分的网友根本不用关心上下文无关语言到底是个什么东西,这也是科学的神奇之处。我们不用懂空调的工作原理,只需要按几个按钮,就可以使用空调了。 开源的伟大之处在于,并不是所有的东西都要从零开始,因为有了各种解析器了,毕竟创建一个解析器并不容易,尤其是能兼顾效率和精确的解析器更是难上加难。webkit使用了两种非常著名的解析器生成器,第一个叫Flex用来创建词法分析器,还有Bison用来创建解析器。他们也有其他的名字,比如叫Lex或者Yacc,不过,大家很少能用到这两个东西,除非真的去做浏览器或者做编译器。Flex处理的是包含编辑的正则表达式定义的文件,Bison处理的则是BNF格式的语法规则。接下来再说说HTML解析器,很可惜的是,常规的解析器都不能解析HTML,为什么呢? 为什么呢?HTML和XML差不多样子,解析XML的解析器多如牛毛,为啥解析HTML的解析器就寥若晨星呢?那是因为XML是一种非常严格的语言,HTML是一种非常宽容的语言。简单来说,XML不允许存在一点错误,HTML则是差不多就行。HTML可以随便写写,比如说,HTML可以随便省略一些标记,也可以省略开始或者结束的标记,反正HTML简直就是最宽容的语言,写错了问题不大,只要是能显示出来,前端的同学也懒得去修改,即使知道这玩意有错误。这样的后果就是,HTML的解析器能容忍错误,不能说一个错误,浏览器给崩溃了。一个错误导致崩溃,大部分编程语言都是这样的,比如说闪退啥的,很可能是一个小错误。但是由于HTML处理的网页是各种各样水平的程序员写的,网页里面的错误肯定是五花八门,如果一个错误就让浏览器崩溃,那就不用上网了。所以,这也就是HTML的难点所在,得和错误共存。稍微总结一下开发一个浏览器引擎的难点,正是因为这些难点,所以才导致世界上可能有几百种浏览器,但是核心的引擎,就那么三四种: 1. HTML语言宽容的本质。所以,我们程序员真的要感谢那么多人默默的付出,才让我们写的那些垃圾代码能显示出来,即使我们写的HTML像一坨屎,浏览器的引擎也默默的帮我们处理成我们想要的样子。 2. 浏览器能处理很久远的网页,即使一些无效的HTML标签,他也知道什么时候该忽略掉。尤其是浏览器大战的年代,各家浏览器搞创新,每家都有一些独特的创新,可以显示在自己的浏览器上,那些创新尽量不让他们正确的显示在别人家的浏览器上。嗯,人类这个物种,有时候挺恶心的。 3. 解析的过程需要不停的反复。为什么这么说呢,举例来说,如果在HTML中,有可以写入的选项,这个时候,因为用户要不停的写入内容,因此,这个浏览器要反复的解析,写入一点,解析一点。这也是非常棘手的一个问题。 这三个难点是表面上就能看出来的,具体还有什么更多的难点,我想,也许只有开发引擎的程序员能体会了。现在已经是HTML5的年代了,HTML5规范则详细的描述了解析算法。HTML5的解析算法主要分为两个阶段,第一个阶段叫标记化阶段,第二个阶段则是构建树的阶段。如果大家有兴趣的话,可以google搜索关键字HTML 5 Parsing,就可以找到链接。或者,你可以输入HTML在百度搜索引擎里,你可以找到相关的培训班,然后交钱参加培训班以后,可以去问老师HTML5的解析算法是什么。这一点,不得不服百度呢,我一搜HTML,先给我搞了四个网站开发培训班的广告。这一点,百度的人性化特别好。 如果你不想搜索的话,可以关注我的微信公众号——软件那些事儿——我把HTML 5 parsing的链接放在这里,还是挺有趣的。 https://www.w3.org/TR/2011/WD-html5-20110113/parsing.html 我简要的把这个链接的意思概括一下,不过呢,还是建议大家去读一下,还算有趣,单词量也不大。技术文章的单词量不大,这一点让我这个英语渣感觉有点幸福。竟然抱着一本字典,能读懂。 第一个阶段叫标记化阶段,讲输入的内容,也就是HTML文件,解析成多个HTML的关键字,也就是标记。这些标记包括HTML的起始标记,也就是这个东西,结束标示,还有属性的名称,以及属性的值,这些都是在第一个阶段完成的。 第二个阶段叫构建树的过程,由第一个阶段生成的那些标记,传递给构造器,然后反复执行,直到第一个阶段生成的标记都完成了,这是个循环的过程。最后,生成一刻HTML解析树。这个流程呢,我把解析图放在这里,这个图也是在w3那个链接里的,如果有人去读一下原文,就不用看这个图了,这个图解释了整个过程。HTML的解析流程。 HTML解析流程 好吧,这一期就到这里,下一期继续讲浏览器的工作原理。

26分钟
99+
9年前

81. 钻钻牛角尖:浏览器的工作原理(1)

软件那些事儿

文 | 刘宝辰 我们每天上网,用的最多的应用软件之一是浏览器,我们用浏览器看新闻,看视频,基本上,只要是现在上网,大部分人都是使用浏览器。浏览器也有很多,但是,总体上分为四个半流派,第一个是微软公司出的Intenet Explore, 这个占有率很高,尤其是中国的市场上;第二个流派是谷歌公司出的Chome浏览器;第三个流派是Mozilla公司出的Firefox流派;第四个流派是苹果公司出的Safari;第五个流派是Opera基本上就是这些吧。 有同学可能问,我从来不用上面这些浏览器,我用的是360浏览器,QQ浏览器或者各种百度全家桶浏览器,其实,这些有中国特色的自主研发的软件,都是基于以上我说的那些浏览器来改版的。比如说加了一个外壳,让浏览器可以记录密码,同步书签等功能。我这次节目不做浏览器的测评,不评价哪个浏览器好用,主要是讲浏览器的一个工作原理。以前我做过一期,名字叫钻钻牛角尖,电脑开机开了啥。那一期是研究电脑开机的,结果,有人告诉我没必要这么复杂,装个360软件,就能加速电脑开机。而且我还和那个朋友争吵了一下,最后不欢而散吧。我这一期节目,没啥用处,即使研究浏览器的原理,也不会让上网速度变快。这只是一个程序员的怪癖,我就是喜欢研究这种东西。以后我还会讲各种音频格式之间的差别,各种图片格式之间的差别,各种视频格式之间的差别,还有各种自拍加的滤镜的工作原理等等,怎么说的,研究这个并没有卵用,只是我自己的业余爱好,希望不喜欢听的同学不要去留言说,你研究这个有啥用了,我也知道,真的没啥用。因为我上一次做电脑开机的那个音频,非得有人去问研究这个能让电脑变快么?如果不能,还不如装个360一键加速呢... 在这个节目里,主要讲两个浏览器,一个是Firefox,一个是chrome和safari和Opera。至于为什么把chrome和safari还有Opera放在一起讲呢?那是因为这三个浏览器用的是相同的排版引擎,是苹果的WebKit,是开源的。其实这个项目最初也不是苹果原创的,而是苹果基于另一个开源项目,那个开源项目是KDE的HTML排版引擎,名字叫KHTML,还有一个KDE的另一个Javascript引擎,名字叫KJS。苹果公司开始的时候是基于这两个开源项目,做出了自己的项目,名字分别是WebCore,这个对应于KDE的KHTML,另一个项目叫JavascriptCore,这个对应于KDE的KJS这个项目。这个两个项目的目的是可以移植到OS X系统上,毕竟人家苹果是商业公司,而且苹果做的事情非常的合乎法律,给KDE的KHTML和KJS也作出了不少的技术改进,然后KDE的这两个项目,也获益匪浅吧,起码开始的时候是这样。 如果用过苹果电脑的同学,尤其是早期的苹果电脑,苹果电脑上是没有一个特别靠谱的浏览器,这东西可能是不太容易做。苹果电脑上一度装微软出的InternetExplore 5浏览器,其实微软和苹果之间,有说不清道不明的爱慕关系,经常互相帮助,相爱相杀。苹果公司就基于这两个东西,然后就推出了自己的浏览器,也就是safari浏览器,,2003年发布的,safari浏览器。这个浏览器我用过,因为那时候我正在读本科,要去做实验,学校的实验室里新买了一批设备,这批设备需要处理数据的就是一台iMac,当年是新款的,那也是我第一次使用苹果电脑。刚开始感觉并不好用。现在记忆最深刻的就是这台苹果电脑,还有一台离心机,非常大的离心机,可能得有直径1米多,然后我有个同学突发奇想,把刚洗过的衬衫塞进去,想看看能不能把衣服甩干,然后甩了10来分钟,衬衫甩成了破布,已经不能穿了。实验室去了好几年,结果,就记住了这两件事情,一台苹果电脑,一个离心机,其它的都忘记了。 继续来说苹果,然后苹果对webkit的改进越来越多,和开源社区也就越走越远,再后来,就彻底分手了。这个分手只是和KHTML那个项目分手了,具体的分手过程,我记得KDE的一个开发者曾经写过一个文章,来吐槽这件事情,当年在开源届也算引起过不大不小的轰动,甚至让Apple公司吓得赶紧联系KHTML的开发者,看看还能不能复婚,别那么快离婚。后来KHTML这个项目确实又从Apple中接受了不少新的特性,来改进KHTML的渲染速度。但是,我猜测的一个原因,Apple是商业公司,KDE是开源组织,商业组织是向钱看,我说的向钱看是金钱的钱,开源组织是不太注重金钱驱动的,结果呢,这些开源的项目因为不赚钱,大家紧张了一阵子,又开始跟不上苹果的节奏了,因为商业公司的项目推进能力,远远高于开源组织,结果,最后还是闹分手了。其实,开源组织有时候吧,赚不到钱,只能兼职做做,很多时候项目的质量并没有商业公司高,在后来,Apple的webkit在很多方面全面超越了KHTML。当然,KDE也知道这件事儿,从KDE4.5开始,KDE就已经使用苹果的webkit这个开源组件,当然了,开源的那个KHTML还是继续开发,也继续用在KDE上吗。 苹果也在继续开发webkit,开发的成果也继续开源。可能有很多人觉得,苹果太尼玛封闭了,其实不是的,苹果是个商业公司,他肯定首先考虑的是商业利益,如果开源能获得巨大的商业利益,他肯定开源,所以,苹果开源了几个大杀器,黑科技。其中我知道的几个有前面我说的这个webki,还有一个大杀器是llvm,这个项目也极其重要,既然说到这里了,我就稍微的说一下,llvm呢,是一个开源的编译器项目,是C++写的。以前,包括现在,最重要的开源的编译器是gcc,就是理查德斯托曼做的那个gcc项目,曾经,gcc是开源届的核心地位,现在也差不多,因为几乎所有的开源软件,都需要使用gcc来编译成二进制代码,然后,这个组织脾气不太好,基本上处于那个地位,可能总是有缺点吧,而且处于核心地位,缺点也容易被放大,gcc可以说是在所有开源项目中,受到的批评最多的一个,比linux都多。但是,即使收到批评,你还不得不用它,苹果就是这样,给gcc捐献了大笔的钞票,没啥效果,因为有求于gcc的,可不止苹果一家。然后,苹果公司就搞了一个LLVM项目,来代替gcc在开源中的地位,LLVM是一个简称,全称是Low Level Vitual Machine,全称没啥人知道,我也是google一下,才敢写在这里。然后,LLVM太重要了,还获得了ACM颁发的一个大奖,来奖励Apple开源的这个LLVM项目。然后Apple率先垂范,把Gcc从默认编译器的位置拉了下来。因为Gcc这个项目组,和其它大的开源项目组,之间的龌龊事情也不少,比如FreeBSD项目也是早就看Gcc不爽了,但是,苦于自己没有编译器,只能忍气吞声,结果LLVM一出来,FreeBSD马上就把GCC给集成进来的,然后,一个以前看起来非常狂妄自大的计划被FreeBSD提上了日程,不光gcc,而是要把所有GNU组件都替换出来,然后就有了lldb, libc,compiler-rt这一系列项目,个人觉得,以FreeBSD社区那种比较高贵的气质,完全替换掉GNU项目,是有很大可能的。这一切,都是Apple花了5年时间,搞出来了一个LLVM,然后把这个编译器项目开源的原因。 llvm的logo是我最喜欢的logo 稍微跑了一下题,拐到编译器上了,再强行拐回来,继续说Apple这个webkit。苹果继续改进webkit,然后webkit也就越来越好用,速度越来越快,然后呢,另一家公司叫Google,也打算做个浏览器,二话不说,直接把苹果开源的这个引擎webkit拿过来就用,这是合乎法律的,因为开源么。然后一贯嘴上说不作恶的google公司实际上恶心事儿也干过不少的google和一贯表面非常高冷但是私底下对政府部门低三下四的apple公司又杠上了。chrome继承了apple公司的webkit,然后加以改进,把认为不行的代码丢了,尤其是javascript的部分,用了自己引以为豪的v8引擎,这个v8引擎的横空出世,让很多人也是惊讶的不行,然后javascript开始从前端到后段,差点儿通吃。让不少程序员惊呼,我操,js这是要上天么?然后,后来发现这种担心是多余的,因为前段进入了百花齐放的时代,每年都会出现至少365个javascript写的库,每天一个吧,然后循环往复,至今已经持续了好几年了。这个话题太容易引起争端,那个前端库更好呢?这个得看情况,因为一旦争论结束,又会出现更多新的js库,没办法,程序员就是这么搞笑,还是老老实实的用php这个世界上最好的语言靠谱。 然后google的chrome是世界上占有率第一的浏览器,由于在中国某种神秘的力量,chrome的占有率很可能是倒数第一,如果你看到有人用chrome,很可能他就是个程序员。接下来,还有一个更小众的浏览器,他的名字叫Opera,据说已经被中国的360公司收购了,这家公司浏览器的引擎,也是webkit。因此,chrome/safari/opera,这三个浏览器,在渲染方面,大同小异,来自一个妈。 另外一个分支就是大名鼎鼎的火狐浏览器,Firefox,这个在国内可能用的人也不多,如果你看到有人用firefox,可能,也是个程序员,如果你看到桌面上有三四个浏览器,并且同时使用,那100%是个前端程序员,尤其是你看到有人还在测试Internet Explorer 6这个浏览器,那100%是个给中国国企开发软件的前端程序员,中国国企和IE6这个浏览器,已经水乳交融,今生今世都不再分离了,即使这个浏览器已经15岁了,15岁,在IT行业,和永远一样远。但是,大型国企爱IE6,比如说,在2016年,我看到过某大型钢铁企业,赫然写着网站要支持IE6,真是让我百思不得其解的一件事情。火狐浏览器用的引擎的名字叫Gecko, 这个软件,曾经一度讨论要不要也把引擎换成webkit,最后,还是继续用这个Gecko,在英语中是壁虎的意思。好了,背景就介绍到这里,微软的不考虑了,他有自己独特的渲染引擎,但是,可以研究他家引擎源代码的,就是微软的人,网上可以找到的材料并不多。这里只讲这两个引擎,一个是webkit,用这个引擎的有三个浏览器,chrome,safari和opera;还有一个是Gecko,用这个引擎的是Firefox。· 这些浏览器虽然各不相同,但是作用是类似的,就是能把你要求的东西显示出来,并且,不同的浏览器,显示的样子大同小异,稍微的有一些不同。因为不同的厂商出品的浏览器,是有一些细微的不同。之所以能显示的大同小异,是因为,这些厂商都要遵守一个协议,这些标准就是HTML和CSS,这些标准由一个公益组织来管理,这个公益组织的名字叫W3C,中文名叫万维网联盟来维护。我们上网的过程,就是把HTML和CSS的内容从网站上下载下来,然后将这些内容解析以后,显示在屏幕上。这个过程,需要用到的核心技术就是我上面所提到的两个引擎,webkit和Gecko的工作。负责显示请求的内容,把网站上下载下来的HTML和CSS,解析以后,展现出来。我对这个过程非常的好奇,好多年前,我就对浏览器是如何工作的非常的好奇,然后就研究了一下,自以为可以把自己给糊弄过去了,因此,我就说一下那两个引擎的工作原理。 主要的流程是这样的,显示引擎会从网络层请求需要显示的文档,然后引擎开始工作。因为所有的网页都是HTML和CSS文档,引擎开始解析这个HTML文档,将整个文档解析成两棵树,一棵树叫内容树,这棵树上的节点是HTML的标记。还有一棵树叫呈现树,这棵树势解析样式元素,呈现树是节点的样式,比如字体的大小,颜色等等。呈现树主要是带有视觉属性比如颜色啊,尺寸啊,背景等等的一些矩形,这些矩形呢,就按照一定的顺序显示在屏幕上。当这个视觉效果显示出来以后,也就是一些矩形。再进入下一个阶段,就是将内容树的节点,计算一个坐标,每个节点都有一个独一无二的位置。有了这两个信息,再然后就是根据这两个信息,把内容绘制到屏幕上,引擎会遍历整棵树,然后将树上的每个节点,都画在屏幕上。 web browser architecture 为了能有更好的用户体验,引擎肯定是将内容以最快的速度画到屏幕上,而不是等所有的内容都下载完毕,才开始绘图,那样是非常影响用户体验的。所以,我们经常会碰到这种情况,某个地方的图片还没有显示出来,只显示一个空白,文字比图片更快的显示出来。这是一种特征,不是bug。引擎不是等所有的HTML文档都解析完毕以后,才开始绘制,如果那样,碰到一个网速很慢的,网页很大的,黄花菜都凉了,那样会非常的影响用户体验。正确的展示流程是,有多少显示多少,只要有内容过来,就赶紧的先给用户看一点,不必等所有内容都下载完成。 那是不是webkit和Gecko是一样的呢?当然不是一样的,如果是一样的,那何必还要两个引擎呢?但是这两个引擎所采用的方法肯定不会有质的差别,如果有质的差别,两个都是开源的项目,那开发人员早就抄袭了,显然,这两个引擎所采用的方法大同小异。接下来呢,我要具体的描述这两个引擎所采用的方法。 在讲技术之前,先得讲一个网页的技术,叫DOM,这个做前端的程序员肯定都是知道的,Web就是基于DOM的,比如说现在前端用的最多的一个javascript库叫jQuery,这个库本质上就是一个操作DOM的工具,这个库现在是越来越大,1.8的时候,原始大小200多K,优化以后也得100来k,其实这样挺大的,尤其是考虑到大部分人用jQuery就是实现了1-2个效果,结果让自己的网页增加了100多K,想想我这个不是前端的程序员,就很不爽,当然也有解决方案,比如zepto.js就是解决这个问题的,只增加了20多k。那唠叨了这么多,到底什么是DOM呢?这是一个英文的缩写,全称是Document Object Model。我们可以把DOM看作是节点,每个节点就是一个HTML的标签,那如何解析成树呢? 这就是一个编译原理的问题了。还记得前面我讲苹果开源的那个LLVM么?那就是编译器,因为我试图把这个问题讲清楚,起码能加深我自己的印象,这次的时间又到了,下次,我要讲如何把HTML文档解析成一棵树,期间会用到编译器的知识,就是解析器和词法分析器。好了,下次再见。如果你喜欢我讲的这种钻牛角尖的内容,欢迎关注我的微信公众号——软件那些事儿——我这个公众号不扰民,每周推送一次,每次的观看量大概是300次左右。

25分钟
99+
9年前

加入我们的 Discord

与播客爱好者一起交流

立即加入

扫描微信二维码

添加微信好友,获取更多播客资讯

微信二维码

播放列表

自动播放下一个

播放列表还是空的

去找些喜欢的节目添加进来吧