算法是计算机科学中最重要的基石之一,但是,国内多家程序猿冷落。
很多学生看到一些公司在招聘时要求的编程语言五花八门就产生了一种误解, 觉得学计算机就是学各种编程语言,或者觉得,学习最新的语言、技术、标准就是最好的铺路方法。
事实上大家都被这些公司误导了。
编程语言尽管该学,可是学习计 算机算法和理论更重要。由于计算机算法和理论更重要。由于计算机语言和开发平台日新月异,但万变不离其宗的是那些算法和理论,比如数据结构、算法、编译原 理、计算机体系结构、关系型数据库原理等等。
在“开复学生网”上,有位同学生动地把这些基础课程比拟为“内功”,把新的语言、技术、标准比拟为“外功”。 整天赶时髦的人最后仅仅懂得招式。没有功力,是不可能成为高手的。
算法与我
当我在1980年转入计算机科学系时,还没有多少人的专业方向是计算机科学。有更多系的人嘲笑我们说:“知道为什么仅仅有你们系要加一个‘科 学 ’,而没有‘物理科学系’或‘化学科学系’吗?由于人家是真的科学。不须要画蛇添足。而你们自己心虚。生怕不‘科学’,才这样欲盖弥彰。”事实上。这点他们 彻底弄错了。真正学懂计算机的人(不仅仅是“编程匠”)都对数学有相当的造诣,既能用科学家的严谨思维来求证。也能用project师的务实手段来解决这个问题——而这样的 思维和手段的最佳演绎就是“算法”。
记得我读博时写的Othello对弈软件获得了世界冠军。当时,得第二名的人觉得我是靠侥幸才打赢他,不服气地问我的程序平均每秒能搜索多少步 棋。当他发现我的软件在搜索效率上比他快60多倍时。才彻底服输。为什么在相同的机器上,我可以多做60倍的工作呢?这是由于我用了一个最新的算法。可以 把一个指数函数转换成四个近似的表,仅仅要用常数时间就可得到近似的答案。
在这个样例中。是否用对算法才是是否能赢得世界冠军的关键。
还记得1988年贝尔实验室副总裁亲自来訪问我的学校,目的就是为了想了解为什么他们的语音识别系统比我开发的慢几十倍。并且,在扩大至大词汇 系统后,速度差异更有几百倍之多。他们尽管买了几台超级计算机。勉强让系统跑了起来,但这么贵的计算资源让他们的产品部门非常反感,由于“昂贵”的技术是没 有应用前景的。
在与他们探讨的过程中,我吃惊地发现一个O(n*m)的动态规划(dynamic?programming)竟然被他们做成了O (n*n*m)。
更吃惊的是,他们还为此发表了不少文章,甚至为自己的算法起了一个非常特别的名字,并将算法提名到一个科学会议里,希望能得到大奖。
当时。 贝尔实验室的研究员当然绝顶聪明,但他们全都是学数学、物理或电机出身,从未学过计算机科学或算法,才犯了这么主要的错误。
我想那些人以后再也不会嘲笑学 计算机科学的人了吧!
网络时代的算法
有人或许会说:“今天计算机这么快。算法还重要吗?”事实上永远不会有太快的计算机,由于我们总会想出新的应用。尽管在摩尔定律的作用下。计算机 的计算能力每年都在飞快增长。价格也在不断下降。可我们不要忘记,须要处理的信息量更是呈指数级的增长。
如今每人每天都会创造出大量数据(照片,视频。语 音。文本等等)。日益先进的纪录和存储手段使我们每一个人的信息量都在爆炸式的增长。互联网的信息流量和日志容量也在飞快增长。在科学研究方面,随着研究手 段的进步,数据量更是达到了前所未有的程度。不管是三维图形、海量数据处理、机器学习、语音识别,都须要极大的计算量。在网络时代。越来越多的挑战须要靠 卓越的算法来解决。
再举还有一个网络时代的样例。在互联网和手机搜索,假设要找附近的咖啡店,那么搜索引擎该怎么处理这个请求呢?最简单的办法就是把整个城市的咖啡 馆都找出来。然后计算出它们的所在位置与你之间的距离,再进行排序,然后返回近期的结果。但该怎样计算距离呢?图论里有不少算法能够解决问题。
这么做或许是最直观的,但绝对不是最迅速的。
假设一个城市仅仅有为数不多的咖啡馆,那么这么做应该没什么问题,反正计算量不大。
但假设一个城市里有非常多咖啡馆,又有非常多用户都须要类似的搜索,那么server所承受的压力就大多了。
在这样的情况下,我们该如何优化算法呢?
首先,我们能够把整个城市的咖啡馆做一次“预处理”。
比方,把一个城市分成若干个“格子(grid)”,然后依据用户所在的位置把他放到某一个格子里。仅仅对格子里的咖啡馆进行距离排序。
问题又来了,假设格子大小一样。那么绝大多数结果都可能出如今市中心的一个格子里,而郊区的格子里仅仅有极少的结果。
在这样的情况下,我们应该把市 中心多分出几个格子。更进一步,格子应该是一个“树结构”,最顶层是一个大格——整个城市,然后逐层下降,格子越来越小。这样有利于用户进行精确搜索—— 假设在最底层的格子里搜索结果不多,用户能够逐级上升,放大搜索范围。
上述算法对咖啡馆的样例非常有用。可是它具有通用性吗?答案是否定的。把咖啡馆抽象一下。它是一个“点”,假设要搜索一个“面”该怎么办呢?比 如,用户想去一个水库玩。而一个水库有好几个入口,那么哪一个离用户近期呢?这个时候,上述“树结构”就要改成“r-tree”,由于树中间的每个节点 都是一个范围,一个有边界的范围(參考:http://www.cs.umd.edu/~hjs/rtrees/index.html )。
通过这个小样例。我们看到。应用程序的要求千变万化,非常多时候须要把一个复杂的问题分解成若干简单的小问题,然后再选用合适的算法和数据结构。
并行算法:Google的核心优势
上面的样例在Google里就要算是小case了!
每天Google的站点要处理十亿个以上的搜索。GMail要储存几千万用户的2G邮箱, Google?
Earth要让数十万用户同一时候在整个地球上遨游。并将合适的图片经过互联网提交给每一个用户。假设没有好的算法。这些应用都无法成为现实。
在这些的应用中。哪怕是最主要的问题都会给传统的计算带来非常大的挑战。比如,每天都有十亿以上的用户訪问Google的站点。使用Google 的服务,也产生非常多非常多的日志(Log)。
由于Log每份每秒都在飞速添加,我们必须有聪明的办法来进行处理。我以前在面试中问过关于怎样对Log进行一 些分析处理的问题,有非常多面试者的回答尽管在逻辑上正确。可是实际应用中是差点儿不可行的。依照它们的算法。即便用上几万台机器。我们的处理速度都根不上数 据产生的速度。
那么Google是怎样解决这些问题的?
首先,在网络时代,就算有最好的算法,也要能在并行计算的环境下执行。在Google的数据中心。我们使用的是超大的并行计算机。但传统的并行 算法执行时,效率会在添加机器数量后迅速减少,也就是说,十台机器假设有五倍的效果。添加到一千台时或许就仅仅有几十倍的效果。这样的事半功倍的代价是没有哪 家公司能够负担得起的。并且,在很多并行算法中,仅仅要一个结点犯错误,全部计算都会前功尽弃。
那么Google是怎样开发出既有效率又能容错的并行计算的呢?
Google最资深的计算机科学家Jeff?Dean认识到。Google所需的绝大部分数据处理都能够归结为一个简单的并行算法:Map?
and?Reduce(http://labs.google.com/papers/mapreduce.html )。 这个算法可以在非常多种计算中达到相当高的效率,并且是可扩展的(也就是说,一千台机器就算不能达到一千倍的效果,至少也可以达到几百倍的效果)。 Map?and?
Reduce的另外一大特色是它可以利用大批便宜的机器组成功能强大的server?
farm。最后,它的容错性能异常出色。就算一个 server?farm宕掉一半,整个fram依旧可以执行。
正是由于这个天才的认识。才有了Map?and?
Reduce算法。借助该算法。 Google差点儿能无限地添加计算量。与日新月异的互联网应用一同成长。
算法并不局限于计算机和网络
举一个计算机领域外的样例:在高能物理研究方面,非常多实验每秒钟都能几个TB的数据量。
但由于处理能力和存储能力的不足。科学家不得不把绝大部 分未经处理的数据丢弃掉。可大家要知道,新元素的信息非常有可能就藏在我们来不及处理的数据里面。相同的,在其它不论什么领域里。算法能够改变人类的生活。比如 人类基因的研究。就可能由于算法而发明新的医疗方式。在国家安全领域。有效的算法可能避免下一个911的发生。
在气象方面,算法能够更好地预測未来天灾的 发生,以解救生命。
所以,假设你把计算机的发展放到应用和数据飞速增长的大环境。你会找到。该算法的重要性不是在日益减少,但在日益加强。
版权声明:本文博客原创文章。博客,未经同意,不得转载。