建筑师桌

建筑师桌,小平台适合放文具,小黑板适合画草图(湿布可擦),夹工作台灯也很方便,细圆钢条骨架又不占空间,总体设计简洁适用,Michael Solheim 设计

类别:易用 查看评论

简析搜索引擎中网络爬虫的搜索策略

随着互联网的兴起及发展,人们获取信息的途径由传统方式逐渐被网络替代。 起初人们主要通过浏览网页来获取所需信息, 但随着Web不断庞大用这种方式来寻找自己所需的信息变得越来越困难。现在大多数的人很大程度上依赖于搜索引擎来帮助自己获取有用信息,因此搜索引擎技术作为最典型的Web信息获取技术 其发展直接影响人们获取信息的质量。

自从1994 年4 月世界上第一个Web 检索工具Web Crawler 问世以来, 目前较流行的搜索引擎已有Google、Yahoo、AltaVista、Infoseek、InfoMarket等。出于商业机密的考虑, 目前各个搜索引擎使用的Crawler 系统的技术内幕一般都不公开,现有的文献也仅限于概要性介绍。随着Web 信息资源呈指数级增长及Web 信息资源动态变化, 传统的搜索引擎提供的信息检索服务已不能满足人们日益增长的对个性化服务的需要,它们正面临着巨大的挑战。以何种策略访问Web提高搜索效率 成为近年来专业搜索引擎网络爬虫研究的主要问题之一。

1 网络爬虫的工作原理

网络爬虫出自Sp ider 的意译,具有相同词义的词语还有Crawler、robots、bots、wanderer等等。网络爬虫定义有广义和狭义之分,狭义上的定义为利用标准的http协议根据超链和Web文档检索的方法遍历万维网信息空间的软件程序;而广义则是所有能利用http协议检索Web文档的软件都称之为网络爬虫。

网络爬虫是一个功能很强的自动提取网页的程序, 它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。 它通过请求站点上的HTML 文档访问某一站点。它遍历Web 空间,不断从一个站点移动到另一个站点,自动建立索引并加入到网页数据库中。网络爬虫进入某个超级文本时, 它利用HTML语言的标记结构来搜索信息及获取指向其他超级文本的URL 地址,可以完全不依赖用户干预实现网络上的自动“爬行”和搜索。 网络爬虫在搜索时往往采用一定的搜索策略。

2 宽度或深度优先搜索策略

搜索引擎所用的第一代网络爬虫主要是基于传统的图算法,如宽度优先或深度优先算法来索引整个Web,一个核心的URL 集被用来作为一个种子集合,这种算法递归的跟踪超链接到其它页面,而通常不管页面的内容,因为最终的目标是这种跟踪能覆盖整个Web。这种策略通常用在通用搜索引擎中,因为通用搜索引擎获得的网页越多越好,没有特定的要求. 如图1 所示:

2. 1 宽度优先搜索算法

宽度优先搜索算法(又称广度优先搜索) 是最简便的图的搜索算法之一, 这一算法也是很多重要的图的算法的原型. Dijktra 单源最短路径算法和Prim 最小生成树算法都采用了和宽度优先搜索类似的思想.宽度优先搜索算法是沿着树的宽度遍历树的节点,如果发现目标则算法中止。该算法的设计和实现相对简单属于盲目搜索。 在目前为覆盖尽可能多的网页,一般使用宽度优先搜索方法。也有很多研究将宽度优先搜索策略应用于聚焦爬虫中。其基本思想是认为与初始U RL 在一定链接距离内的网页具有主题相关性的概率很大。 另外一种方法是将宽度优先搜索与网页过滤技术结合使用, 先用广度优先策略抓取网页,再将其中无关的网页过滤掉. 这些方法的缺点在于, 随着抓取网页的增多大量的无关网页将被下载并过滤,算法的效率将变低。

2. 2 深度优先搜索

深度优先搜索所遵循的搜索策略是尽可能“深”地搜索图。在深度优先搜索中,对于最新发现的顶点,如果它还有以此为起点而未探测到的边 就沿此边继续汉下去。当结点v 的所有边都己被探寻过,搜索将回溯到发现结点v […]

长期大量收购BTC

几经思索,我决定从今天开始长期大量收购BTC。

在对Bitcoin的思考上,我早就被身边的朋友认定“是一个疯子”。呵呵,疯就疯吧,我一直就是个很疯的人,只不过,常常想办法让自己显得比较正常而已。

我个人对Bitcoin的所谓“匿名性”并不在意——事实上,Bitcoin只不过在转账那一瞬间比较匿名,一旦“落地”,就很难匿名了。

想要卖我BTC,请在gtalk上与我联络:lixiaolai@gmail.com。按MtGox当前买入价计算。货到即时付款。

街头扑克残局(18张对4张)

甲方:多牌排列为34455667799QQQKKK2,2最大

黑桃:3,4,6,7,Q,K

红桃:2,4,6,Q,K

梅花:5,7,9,Q

方片:5,9,K

乙方:4张牌为A,A,J,J花色随便

我想知道他那4张牌怎么赢18张牌

补充说明:单张能出3 ,对子能出44, 连对不出445566, 三带单张不能出KKK4,三带一对能出KKK44顺子能出34567(最少5张) 同花能出(最少5张)

残局解法~

第一步:

先出一个6,少方PASS。少方只能PASS,否则输。

假设少方不PASS:由于多方出一个6后能保住方块同花457QK和顺子34567(还在手上未出),另外是2KKQQ99。不管少方用A打还是用J打,剩下的牌无非是两种情况:AJJ或者AAJ。明眼人一看便知少方输掉了。不过我可以稍做解释:

如果少方是用A打,剩AJJ。那就很明显了:多方打2,然后同花+顺子+99+QQ+KK,完。

如果少方是用J打,剩AAJ。稍微复杂一点:多方打Q,此时少方只能PASS(对A一拆就输,因为多方这时就单2和Q)。PASS后多方继续打Q(剩 2KK99+同花+顺子),少方更只能PASS。然后多方出单K(剩2K99+同花+顺子),少方还是只能PASS(多方这时只单2和K)。然后多方继续打K(剩2+99+同花+顺子),这时不管少方怎么出,都是一个输字。

以上线内文字是解释给智商一般的人听的,智商高的可以略过。

第二步:

再出一个6,少方还是只能PASS,否则输。

假设少方不PASS:这个时候多方已经保不住顺子34567了,因为没6了。所以排列方式换一下,剩2KKKQQQ997755443。同样也引出一个问题:少方用A打还是用J打。如果少方用J打,剩AAJ。那多方就出Q,少方不敢要,因为A不能拆。多方继续出3,少方更不敢要(这理由就不用说了吧)。直到多方把4给拆开,出一个 4时,少方出J(剩AA),多方用K打(剩2KKQQ9977554),而少方就剩两个A,拆了就输(因为多方只单一个4),不拆就给多方玩死:出另一个 4。于是进入了循环状态,少方输掉。

如果少方用A打,剩AJJ。这看似一个杀手间,其实不然。这时多方剩2KKKQQQ997755443)。

多方PASS,让少方走。少方这时只有一种选择:出JJ。(因为出A和出一个J就等于自杀)。少方出JJ后就剩一个A。这时多方必须要打,用QQ,但不能用草花Q,这是关键。因为多方此时要保住草花的同花:2KQ43,(不能吝啬2,那个9不能拆)。多方的牌则由(2KKKQQQ997755443)减去两个Q,排开要保住的草花2KQ43,剩KK9977554,看到了吗?就单一个4,而此时少方就剩一个A。完。

小结:按照以上两步走,暂时少方只能PASS。

第三步:

出一个3,少方依然只能PASS,否则输。

假设少方不PASS:打A或者打J也是剩AJJ或者AAJ。假设少方打A,剩AJJ,多方PASS。少方只能选择出JJ,剩单A。此时多方的牌为2KKKQQQ99775544,把KK或者QQ随便拆一对去打少方的JJ,多方的牌就只单一个K或者一个Q,少方剩单A,完。假设少方打J,剩AAJ,多方打Q,少方不敢拆A,PASS。然后多方打4,(这时剩2KKKQQ9977554),少方依然不敢拆A,如果拆了,就剩 AJ,多方只单一个4。少方也不敢PASS,如果PASS,将进入循环。所以,这时少方被逼着打J,剩AA。多方则用K干掉,剩2KKQQ9977554

。少方拆A就输。不拆就再打另一个4,由此,进入循环。

第四步:

出方块4,剩2KKKQQQ9977554。

少方这时必须要打,否则输。假设少方PASS,那多方就再出一个4,用2收回,剩KKKQQQ997755,两组三带对:KKK99和QQQ77就跑掉了。所以,少方必须打。但怎么打?假设少方出A,剩AJJ,多方PASS,少方只能出JJ,剩A,否则是自杀。那么多方用QQ去打JJ,(留下草花Q),剩草花同花2KQ94+KK+77+55+9,此时少方剩单A,完。假设少方出J,剩AAJ,多方出Q打。少方依然不敢拆A,PASS。然后多方出另一个4,少方这时不能顺过那个单J,理由不再重复,少方PASS。然后多方开始拆5,剩2KKKQQ99775,少方被逼打J剩AA,多方拿一张K干掉,剩2KKQQ99775,少方剩AA。很明显,又是个循环。完。

总结:

第一步出6,少方必须PASS。(不PASS就直接输)

第二步出6,少方必须PASS。(不PASS就直接输)

第三步出3,少方必须PASS。(不PASS就直接输)

第四步出方块4,少方必须打,不打就输。

(出方块4是为了防止少方用A打,而保住一个草花的同花2KQ94)。但打了也输(详情参见第四步)。

所以:多方必胜!

Related posts:

Python语言蕴含的禅机 PHP 5 curl Class Google蜘蛛UA及IP

[…]

防御工事:星形要塞

星形要塞(star fort)或「意大利式要塞」(trace-italienne),是火炮开始主导战场后的黑火药时代所发展出的一种城塞形式,首见于十五世纪的义大利。中古时代的环形要塞,在遭遇能直接射击其直立城墙的炮火时,已被证明是极其脆弱的。相形之下,星形要塞以平坦的建筑,搭配多个能相互掩护的三角形棱堡以及壕沟。再增置其他如半月堡(ravelin)、角堡(hornwork)、皇冠堡(crownwork),及附属堡垒,形成一个复杂但均衡的建筑。

一整套防御工事:棱堡、半月堡、角堡

在十五十六世纪之交,星形要塞因为法军入侵意大利半岛而得以更进一步发展。法军配备能轻易击毁中古堡垒的先进火炮。为了抵挡新式火炮的威力,城墙变得低矮厚实。城墙需要多种建材,通常是砖块与泥土,因为砖墙在遭受炮击时不如石墙那般严重。另一个重要的新设计,是作为新式要塞特征的棱堡(bastion)。为增强要塞的防御,必须有来自多个角度的掩护火力。这个结果就导致了星形要塞的出现,这些设计即被米开朗基罗(Michelangelo di Lodovico Buonarroti Simonio, 1475年-1564年)用来加强佛罗伦斯(Florence)的防御工事。

稜堡

这种设计在1530至1540年代传布至全意大利,并在此后三百年为全欧各国广泛采用。也因此欧洲各国大力招募意大利工程师前去协助建造新式要塞。十七世纪下半的建筑师柯霍恩(Menno van Coehoorn,1641年-1704年)与路易十四的工程师沃邦(Sébastien Le Prestre de Vauban,1633年-1707年),被公认将星形要塞的发展带向极致。星形要塞也成为文艺复兴时代理想城市的图像。十九世纪后,由于榴弹(explosive shell)的发展,才再度改变了防御工事的性质。

起源

中古的城堡通常建于山上,以防御敌人射来的弓箭,同时地势愈高,己方所射的弓箭能飞得更远。敌军就得用冲车撞开城门,或利用云梯爬上城墙,击退守军。对于攻方而言,自然这些堡垒是相当不易攻克的。因此,城堡自然在战争中占有举足轻重的地位。

愛丁堡城即是典型的中古山城

当十五世纪攻城炮取得战略的一席地位后,工程师则是设法使城墙与具有斜堤的壕沟相配合,使敌人无法进行威力强大的直接射击,并使城墙略微高于能抵销炮火威力的斜堤。倘若条件许可,如在马尔他(Malta)的马诺要塞(Fort Manoel),外壕以开凿天然岩盘而成,而城墙亦属天然岩盘。当城墙愈低,则愈容易受攻击。另一问题则是以往流行的圆形塔楼,相对来说会遮蔽守军火力,造成死角,毕竟由对面城墙直射的火力是不会绕着弧形的墙的。为避免圆形或方形塔楼会产生的问题,因此出现了令攻方士兵无所掩蔽的铲形塔楼。攻方一旦沿壕沟或城墙进入守方精心设计的「死地」时,由于攻方面对守军的火炮无所掩蔽,则守军炮火必将对攻方造成重大打击。

死地在马尔他,开凿岩盘建成的马诺要塞

而一个更深层且更微妙的改变是守方由被动化为主动。矮墙容易突破,而一旦攻方占领壕沟外的斜堤并在此放列火炮时,原先用来抵挡直射炮火的斜堤便会因而失去作用。因此要塞的形制必须能将侧击火力发挥到最大,杀伤任何逼近墙角的敌军。星形要塞的每一角掩蔽放列在此的火炮。这些火炮直射相邻炮台的边缘,单一炮台是受两侧火力掩护的。复杂形制要塞的发展,使炮位形成交叉火网。前方的炮台控制能保护城墙及形制复杂的土坡。守军火炮不仅是用来应付强攻也可对付敌军火炮,使他们无法逼近要塞,以免朝脆弱的城墙行直接射击。守城的关键也因而变成围绕要塞外缘的壕沟。这是既隐蔽又隐密的路径。守军可相对安全地移动到壕沟的掩蔽处,并发动积极的反击手段以控制斜堤,斜坡置于壕沟外侧,借着建造防御工事来拒退敌人接近斜堤或可直射城墙的火力点,并以反地道战反击并瓦解对方试图接近城墙的地道战术。

城墙、壕沟、斜堤的剖面图

与中古堡垒相比,要塞变得低矮,同时占地更广,更具备防御纵深,攻方为了能将火炮施加到内层的守军,则必须先克服层层的防御。守军火炮的炮位严密地防守,可不受外围的炮轰,但对城内则敞开,这不仅减少了攻方突破的可能性,也大大消除守军火炮所产生的大量硝烟。只要攻方配备的是加农炮(cannon),这种形制的要塞就能有效防御,所受损害大多也只是实心弹(solid shot)直接射击造成的。而虽有黑火药制成的低爆弹(low explosives)可用,但对这种要塞的破坏极微。臼炮(mortar)与高爆弹(high explosive)的发展,大大增强榴弹(explosive shell)的破坏力,而曲射(plunging fire)更使得这种要塞的几何型式变得不合时宜。战争因此再度变得更强调机动。然而也过了许多年才扬弃旧的筑城思维。

建造

由于建筑星形要塞所费不赀,故常与旧的防御工事权且凑合。中古时代外侧的幕墙(curtain)被拆毁,同时在外围掘深沟,挖出的土方堆在墙边用以加固城墙。这种建筑通常会有能抵挡炮击的砖墙,但许多为了省钱而略去此道工序,而以更多的泥土替代。而降低的中古圆塔则以泥土加固,也不失为一种权宜办法。

为有效妨碍正面进攻或是地道挖掘,加宽并加深城墙的外壕常是必要的。自1520年开始,筑城工程师即在护城河外筑起大而平缓的土堤,称为斜堤(glacis),这使城墙完全掩蔽于平射炮火之外。斜堤的好处是阻绝了敌人水平射击的能力。斜度愈大,阻挡的力量也就愈低。

一个耗费巨资改建城池的例子就是西亚那城(Siena),为了改建城墙而在1544年破产。义大利式要塞头一个重要例子则是教廷的西维塔维洽港(Port Civitavecchia)的米开朗基罗要塞(Michelangelo’s fort),原有的城墙削低加厚,因为石墙容易被炮击而粉碎。

著名例子

证明义大利是要塞真正有效的第一场大仗是1500年抵抗佛罗伦斯与法国联军的比萨(Pisa)保卫战,在法军加农炮轰击下,原有的中古堡垒被击碎,比萨人在受威胁的防区建了一道朝东的土墙,这道朝东倾斜的土墙可以防御攀登,也比被取代掉的幕墙更能抵御炮火。

第二场围攻是1509年的帕图亚(Padua),一个叫弗拉乔康多(Fra Giocondo)的修士工程师,信赖威尼斯的城市防御,拆除了该成的中古城墙,并以宽沟围绕该城,使之能藉由设置在壕沟的炮眼所发出的侧击火力来歼灭敌人。可知(法军)的炮火对低矮的土墙影响甚微,法军与盟友发动了几次血腥但无决定性的进攻后撤围而去。

影响

根据杰弗瑞帕克(Geoffrey Parker)的〈军事革命,1560年-1660年:一个迷思〉(The Military Revolution 1560-1660: A […]

遭遇工程师

谢谢大家的关心,几个小时前Google Plus恢复了我的帐号,看来暂时我还不用离开。因为前一篇Blog的 缘故,有些网友猜测是因为博文而使得我获释。虚荣心让我想立即承认这一点,但是对不起,真的不是这样的,我的Blog并没有那么大影响力,尤其是在英文世 界里。而且,因为我上次张贴了一张人类进化谱系的漫画,我在国外驻京记者圈里成功赢得了“种族主义者”这一臭名昭著的称号,大概没有什么人愿意帮助一个黄 种人中的“种族主义者”。

为什么Google Plus封杀我的帐号,以及为什么获释,对于我来说这完全是个未解之谜。各位幸运的大多数不会(我也希望大家不会)遇见我遭逢的一切,而我在过去的一周时 间内一共向Google Plus提交了5次申诉表单,并且写了一封英文长信给它的工作组。回想起这一周里的诸多彷徨无策,至今依然让人心悸。

这次经历基本上和一个小偷被抓进不那么规范的警察局的情形一样。小偷进去了,警察叔叔一声怒吼:“给我放老实点!”于是小偷立正站好,结果挨了一耳 光。小偷想了想,又是一声怒吼:“给我放老实点!”于是小偷老老实实坐下,结果又挨了一耳光。小偷很困惑,但是暴喝声又道:“给我放老实 点!”。。。。。。这个循环重复了很多次,最后小偷终于明白,要面对墙蹲下,鼻尖距离墙壁一厘米,这样才不会继续挨打。

倒霉的小偷遇见的是一个典型的“黑盒”,他只能看到电线进出黑盒,控制进线一边的开关,可以看到出线一边的灯闪亮或者关闭。至于说盒子里的线是怎么 接的,他不知道。他只知道简单的肇因,和非常直接的结果,想要建立起这两者之间的关联,是非常困难的事情。而我就是那个小偷,在过去一周里。我反复就看到 两种状态,一种是通知我帐号被停权了,原因是违反了Google Plus的社区规定,不服的话可以申诉;另一种是通知我帐号资料已经被审核过了,认为我的个人资料违反了Google Plus的社区规定,因此停权。因此,我只能像那个小偷反复变换身位一样,一次次提交申诉,一次次修改个人资料。而且,并不清楚我的哪一次申诉材料被驳 回,驳回的具体理由又是什么。最后这一次通过了,我终于面墙蹲下,鼻尖距离墙壁一厘米。下一次会怎样,我不确信。下一次要试多少次才不被驳回,我同样不确 信。

和Google打交道的岁月里,Google Plus这样的待遇并不是我第一次遭遇。上一次是Google的广告系统Google Adsence,我的帐号被停权,原因是系统发现了无效点击。那么,我想问究竟是什么无效点击?Google Adsence不会具体回答我,给我给我一份规定看,同时要我去申诉。我想申诉,但是我根本不知道无效点击的由来,具体是什么东西造成的,所以无法申诉。 事情就卡在那里,一直到今天我的帐号依然被锁。

当然,可以说Google Adsence的这套原则极大地保护的广告商的利益,保护了Google平台的公正性,也是巨额利润的来源。同时,这套方法又不能外泄,否则网络上作弊的 手段会据此进化,影响到Google对欺诈性广告点击的有效判别。那好,对此我可以接受,反正也指望不了Blog真能赚钱,Google黑盒也就只能由它 去了,Google用机器判别点击行为也由它去吧。

问题是,Google Plus是一个完全不同的产品。它不同于Google的搜索,图片,广告,翻译、文档等等工具类服务。这些服务只需要工程师写好一个算法,做好一个框架, 用户的行为就是完全可以预期的。然而Google Plus是一个社交网络,社交网络除了产品本身,运营远远要比网络工具复杂得多。Google Adsence可以用很小的团队就能维持运转,大量的广告招商可以让外部团队和联盟公司去做。但是Google Plus不可以,尤其是按照Google思路制作的这个产品不可以这样。

许多人为Google Plus的圈子功能叫好。我觉得它并没有那么好,而是一种工程师思维的解决方式。圈子就是一系列抽屉,让用户把人际关系拆分,分门别类塞进不同的抽屉里 去。这样的话,每次打开不同的抽屉,里面的人和事丝毫不乱。是的,人们有时候需要这种一丝不苟,毫厘不爽。但是,以人类之复杂,哪里可能会有这么精准的分 类法?哪怕是在同一个圈子里,每个人心里都有一本帐本,能够区分出哪些人近些,哪些人远些。同时,对于这种远近关系的变化非常敏感,随时调节人际关机的张 弛程度。如此复杂而微妙的情感,岂能是几个抽屉所能涵盖的?用抽屉去区分是一种解决方法,但是这种方法未必最优,而其中生硬的部分让人深深感觉到后面冷峻 工程师的存在。

Google Plus的命名也是一样。Google的VP Vic Gundotra 在接受Robert Scoble采访时辩白说,Google并非是要搞实名制, “it is about having common names and removing people […]

MySQL 初级教程(一)

这篇文章主要针对MySQL讲的是SQL的用法,非常基础,比较适合像我这样零基础的学习,这篇文章来源于tutsplus的教程,是看了SQL For Beginners的总结。因为我电脑上先前已经装了XAMPP,所以直接拿来操练。

1、连接上数据库

使用Windows自带的cmd工具,转到mysql.exe所在目录,执行如下命令即可连接MySQL:

其中root为数据库用户名,可以使用其他用户名进行替换。

2、创建数据表

创建数据表的操作比较简单,如下图所示:

上面有两条语句,其中第二是相比第一条进行了默认的字符编码设置。对于编码的支持可以查看这里。

3、显示所有数据库

有时候需要查看电脑中现有的所有的数据库,可以使用如下方式实现:

4、删除某个数据库

同样的SQL支持删除数据库的操作,具体指令相当的简单,需要注意的是这里使用的是DROP DATABASE而不是DELETE DATABASE!

5、使用某个数据库

在真正开始对数据库操作前,需要先使用某个数据库,操作如下:

6、创建数据表

在创建数据表的术后需要创建字段名和字段类型,为了表示每行数据,所以需要为数据表创建一个PRIMARY KEY字段,PRIMARY KEY字段中的值必须唯一,所以一般使用自增长ID。

7、显示所有数据表

8、显示数据表结构

数据表结构包含中的数据表字段名、字段属性等。

9、删除数据表

10、修改表-添加字段

11、修改表-删除字段

12、修改表-修改字段

13、数据表添加数据

需要在数据表中添加数据有多种方法,通常采取的方法有以下三种。

14、显示最后的自增长ID

15、获取当前的时间

16、从所有行中选择所有列

17、从表中选定指定列

 

[…]

JavaScript是Web的汇编语言(二):疯狂,亦或只是精神错乱?

原文地址:JavaScript is Assembly Language for the Web: Part 2 – Madness or just Insanity?

有些人认为“JavaScript是Web的汇编语言”完全是精神病说的话。为此,我询问了几位JavaScript权威,比如Brendan Eich(JavaScript之父)、Douglas Crockford(JSON之父),还有Mike Shaver(Mozilla技术副总裁)。以下都是从个人邮件里摘过来的,得到了以上几位的许可。

Mike Shaver:

以前我就听说过这种比较,我认为很大程度上确实如此。但是,这种说法忽视了JS开发人员与机器之间的人机工程学方面的大量努力,因为汇编语法设计得没有那么人性化(特别是现代的汇编语言)。

Brendan Eich:

几年前,我曾说过“JS是Web的x86”(好像是在一次JSConf上),不过我不敢说我是第一个这么说的。(Nick Thompson今年也在Hacker News中这么说过。)

关键在于,JS确实在按照我们想的,越来越往低级方向发展了。但它也具备高级的特性。

Shaver说得没错,汇编缺少可靠的宏处理器,因此不适合程序员,也不够安全。但JS可不是这样。所以,这个比喻需要加点限制条件,不然就要闹出笑话来了。

无论从高级函数式编程还是内存安全角这个角度看,还是从低级特性,像类型化数组以及即将成为现实的ES中类型化数组的扩展、二进制数据,等等来说,JS都是一个比汇编更加强大的编程语言。当然了,内存安全是首要的区别。

Douglas Crockford:

就这个问题来说,我觉得说JavaScript是Web的虚拟机更接近一些。过去我们一直都把Java的JVM看成是Web的虚拟机,但结果呢,JavaScript才是。

从提供代码安全的角度说,JavaScript的解析器比JVM的字节码验证器更有效。就兑现“编写一次,到处运行”这个诺言来看,JavaScript更出色;这或许正是因为它是在较高层次上运行,才得以避免触及一些底层的棘手问题。因为它把剩下的事儿都交给图灵去解决了。

当然啦,也有不少人始终不肯承认JavaScript能把一切都处理好,我过去就是这样一个人。而现在我则不断地被眼前这种百花齐放的景象震撼着。

Brendan Eich,补充:

Doug说源代码强过字节码,说得太好了。很早以前,我的朋友,加州大学欧文分校的Michael Franz教授就指出了Java验证器O(n^4)级别的复杂性(计算机时钟周期失控,拒绝服务)。精简之后的JS呢,确实传输更便捷,而且词法/语法分析也相当快。

(JS)源代码作为“字节码”同样也避免了Java字节码的一个很傻的问题:冻结设计不良的Java低级形式,导致高级形式的源代码也无法解决这个问题。换句话说,Java唯恐破坏其字节码的兼容性。而这严重影响了Java内部类及其泛型的设计。——不管怎么说,Sun最后还是破坏了字节码的兼容性。

以下是前一段时间Nick Thompson在YCombinator说过的话:

这只是我个人的看法:我花了自己两年时间,想尽可能让JVM能够与JavaScript互通。当时的Netscape有不少人认为字节码作为移动代码的基础比较好。但Sun从头搭建了自己大而全的软件体系,把问题搞得很复杂。他们没有想让Java与其他语言沟通,更别提让Java能嵌入其他软件中了。他们的字符串处理代码都是用一种解释型语言来写,而不肯用C来玷污自己!有什么我就说什么,Netscape,这个当时Java唯一的一个大客户,在Sun眼里无非就是一个用来实现他们取代Windows梦想的工具而已。所有想用Java的人都是自己给自己找罪受。

在此期间,Brendan一个人干了10个工程师,外加3个客户服务人员的活儿,同时还要关注Web作者在乎的一些事,比如把JS代码混合到HTML中、即时加载、与浏览器其他模块的集成等等,此外还要协调其他浏览器厂商,以便让JS成为一个开放标准。

因此,今天的JS作为Web的x86汇编程序,并没有像它本该的那样完美,但你通过它真能把事情稿定(GWT就是一个最明显的例子)。这可以说是一个经典的“更差就是更好”的例子,只不过Java也就是从下往上那么看起来更好罢了。而JS则在此期间取得了相当不错的成就。要想取代它的地位可没那么容易。

当然,这个比喻不一定准确。JavaScript代码无论从外观到行为,肯定不像ASM。但作为一个比喻,至少可以说明:

JavaScript无所不在; 它速度快而且越来越快; JavaScript酷似低级的Web编程语言; 它可以通过手工编写,也可以从另一种语言编译而来。

诸如此类的话题也经常在Hacker News中出现:

“现在的JavaScript其实就是客户端的汇编语言。想改它太难了,所以得想办法开发一些工具来解决这个问题。”—— jonnycat

好啦,能听到如此有见地、有深度,而又详尽的讨论,该满足了吧。亲爱的读者,你们太棒了。

[…]

JavaScript是Web的汇编语言(一):语义Web已死!

原文地址:JavaScript is Assembly Language for the Web: Sematic Markup is Dead! Clean vs. Machine-coded HTML

(更新)有些人认为“JavaScript是Web的汇编语言”完全是精神病说的话。为此,我询问了几位JavaScript权威,比如Brendan Eich(JavaScript之父)、Douglas Crockford(JSON之父),还有Mike Shaver(Mozilla技术副总裁)。他们的评论发表在下一篇文章里。

昨天我跟Erik Meijer聊天,他说:

JavaScript就是一个汇编语言。JavaScript加上生成的HTML就像是.NET汇编一样。浏览器可以执行这些代码,但没人真的关心里面到底写的是什么。 ——Erik Meijer

怎么会说起这件事儿呢?当时我正在试用Google+,就跟上大多数让我印象深刻的网站一样,我立即就查看它的源代码。不看不要紧,一看吓一跳:

咱就将就说吧,我看到了1300行代码,密密麻麻的,大约90KB。上面图片显示的只是最前面的一小部分,基本上都是“瘦身后”的JavaScript代码。再往下看,页面中间呢,全都是像下面这样的span、div以及生成的类和id:

我勒个去,满篇都是GUID(Globally Unique Identifier,全局唯一标识符)。

话又说回来了,http://msn.com、http://www.bing.com、http://.www.facebook.com,全都这样啊。就连http://www.twitter.com也都开始有点“瘦身”的迹象了。所有大点的网站好像都丝毫不在乎什么标记之美。这是为什么呢?

这样有效率啊,性能高啊。Google很多最出色的网站背后都依赖GWT呢。在这种情况下,要是这一类网站的里头和外头全都一样漂亮,你反而会觉得不可思议了。

不能不说这可真有点讽刺的意味。曾几何时,ASP.NET的开发人员对ViewState可是怨声载道啊。“简直太笨了”的意思就是“我看不懂它都干什么了。”ViewState曾经(现在也)是一项让Web开发效率提高很多倍的技术。它跟Google Web Toolkit(GWT)不一样,但GWT与WebForms的出发点也并非完全没有相似之处。看看GWT网站自己怎么说:

Google Web Toolkit(GWT)是一个开发工具包,用于构建和优化基于浏览器的复杂应用。GWT的目标是提高高性能Web应用开发的效率,而且无需开发人员熟悉浏览器的各种怪癖,以及XMLHttpRequest,还有JavaScript。

这个出发点可真是值得赞美,不对?难道不可以这样说(抱歉,开个玩笑而已):

“ASP.NET WebForms”是一个开发工具包,用于构建和优化基于浏览器的复杂应用。它的目标是提高高性能Web应用开发的效率,而且无需开发人员熟悉浏览器的各种怪癖,以及XMLHttpRequest,还有JavaScript。

本文的目的不是想夸奖WebForms,也不是给WebForms正名。WebForms对于某些应用是不二之选,正如GWT对其他一些应用那样。我真正想说的是,使用服务器端的工具包,没有办法像使用jQuery写出清晰的JavaScript,或者使用Razor或HAML写出清晰、清楚的标记一样,给Web开发带来真正的快乐。归根结底,其实就是你选择的抽象级别的问题。

所谓的语义标记在这种情况下仍然是被隐藏的,而诸如http://schema.org之类的站点也仍然非常重要,只不过可别指望你能在心仪的站点里看到缩进得像俳句一样整齐的源代码。

大家知道,精简和压缩属于正交优化。而我要说的是,一点也不在乎标记和脚本发送到客户端之后是否美观,确实太草率了。假如谁都不在乎发送到浏览器的标记,只在乎结果,那谁的标记和JS就那么不值钱啊,谁还愿意主动公开自己的源代码呢?反正,网站不是运行得挺好嘛,谁还在乎其他的?

现在我要给亲爱的读者提个问题,你觉得自己为什么那么在乎点击“查看网页源代码”之后的结果呢?难道HTML5和JavaScript是Web的新汇编语言不成?

(更新)声明一下: 当然,这个比喻不一定准确。JavaScript代码无论从外观到行为,肯定不像ASM。但作为一个比喻,至少可以说明:

JavaScript无所不在; 它速度快而且越来越快; JavaScript酷似低级的Web编程语言; 它可以通过手工编写,也可以从另一种语言编译而来。

作为开发人员或者设计人员,如果有工具提供了你需要的控制和你需要的结果,你最关心哪一个?我认为Rails、ASP.NET,甚至GWT,都没有100%做到这一点。它们都有自己的问题,但我认为将来的Web不会再专注于清晰的标记,而是夺目的用户体验和语言、工具的天下,开发人员会很享受,效率也会更高。

亲爱的读者,你愿意HTML和JavaScript再多抽象一点吗?还是希望它少抽象一点?

(再更新)为了让大家明白,我得再说一遍。本文讨论了两个独立的问题。一个当然就是源代码经过了精简和通常的混淆。但这只是第一个问题。真正的问题在于,JavaScript已经成了其他多种语言的目标语言。GWT是一个用JAVA来写Web应用的框架,它产生的字节码是“JavaScript”。GWT为原来天然的语言(HTML+JS)选择了一个设计好的高级语言,并将整个浏览器当成了一个VM。好,问题来了:我们是在写汇编呢,还是在写某种更高级点的代码?而且,我刚知道Google+是用Closure来写的,但这不影响前面的问题。

[…]

敏捷开发——Programmers(27)

载于《程序员》杂志2011年第7期。

从这一期起,开始在杂志上登出整P的大幅漫画,需要看大图的同学们,讯猛点击下图。

这个系列的漫画讲述程序员——这种神秘人类的囧事,故事多来源于我身边的程序员朋友,且以互联网开发背景为主。

如果你有什么可乐的关于程序员的故事、对话、代码,愿意通过漫画的形式分享,请给我发邮件。arthur369@gmail.com。

Category

Archives