转载:http://www.cnblogs.com/xgyb12458
算法的力量
李开复
真正学懂计算机的人(不只是“编程匠”)都对数学有相当的造诣,既能用科学家的严谨思维来求证,也能用工程师的务实手段来解决问题——而这种思维和手段的最佳演绎就是“算法”。
虽然在摩尔定律的作用下,计算机的计算能力每年都在飞快增长,价格也在不断下降。可我们不要忘记,需要处理的信息量更是呈指数级的增长。
应用程序的要求千变万化,很多时候需要把一个复杂的问题分解成若干简单的小问题,然后再选用合适的算法和数据结构。
在网络时代,就算有最好的算法,也要能在并行计算的环境下执行。
传统的并行算法运行时,效率会在增加机器数量后迅速降低,也就是说,十台机器如果有五倍的效果,增加到一千台时也许就只有几十倍的效果。这种事倍功半的代价是没有哪家公司可以负担得起的。而且,在许多并行算法中,只要一个结点犯错误,所有计算都会前功尽弃。
那么Google是如何开发出既有效率又能容错的并行计算的呢?Google最资深的计算机科学家Jeff Dean认识到,Google所需的绝大部分数据处理都可以归结为一个简单的并行算法:Map and Reduce(http://labs.google.com/papers/mapreduce.html)。这个算法能够在很多种计算中达到相当高的效率,而且是可扩展的(也就是说,一千台机器就算不能达到一千倍的效果,至少也可以达到几百倍的效果)。Mapand Reduce的另外一大特色是它可以利用大批廉价的机器组成功能强大的server farm。最后,它的容错性能异常出色,就算一个server
farm里面的机器宕掉一半,整个farm依然能够运行。正是因为这个天才的认识,才有了Map and Reduce算法。借助该算法,Google几乎能无限地增加计算量,与日新月异的互联网应用一同成长。
李开复给程序员的七个建议
1. 练内功
不要只花功夫学习各种流行的编程语言和工具,以及某些公司招聘广告上要求的科目。要把数据结构、算法、数据库、操作系统原理、计算机体系结构、计算机网络,离散数学等基础课程学好。大家不妨试试高德纳所著The Art of Computer Programming里的题目,如果你能够解决其中的大部分题目,就说明你在算法方面有一定的功力了。
2. 多实战
通过编程的实战积累经验、巩固知识。很多中国大学毕业生缺乏编程和调试经验;学习C语言,考试过关就算学会了;课题项目中,只要程序能够编译,运行,并且输入输出满足要求就算了事。这些做法是不行的。写程序的时候,大家必须多想想如何把程序写得更加精炼、高效、高质量。建议大家争取在大学四年中积累编写十万行代码的经验。我们必须明白的是:好程序员是写出来的,不是学出来的。
3. 求实干
不要轻视任何实际工作,比如一些看似简单的编码或测试。要不懈追求对细节一丝不苟的实干作风与敬业精神。我发现不少程序员对于知识的掌握很肤浅,不求甚解,没有好奇心,不会刨根问底。比如,学会了C++,是否了解一个对象在编译后,在汇编代码中是如何被初始化的?这个对象的各个成员在内存中是如何存放的?当一个成员函数被调用时,编译器在汇编代码中加入了哪些额外的动作?虚函数的调用是如何实现的?这些东西恐怕在编程语言或编译原理中都没有详细提到,只有
通过踏实的实干才能真正掌握。
4. 重视数学学习
数学是思维的体操,数学无处不在。学计算机至少要学习离散数学、概率论、布尔代数、集合论和数理逻辑。这些知识并不难,但是对你未来的工作帮助会很大。尤其当你对一些“数学密集型”的领域如视频、图像处理等有兴趣时,这些知识将成为你手中的利器。
5. 培养团队精神,学会与人合作。
今天的软件工程早已经不是一个人可以单独操作的,而必须靠团队合作才能成功。不懂得合作的人是不能成大器的。大家要多去寻找可以与人一起做项目的机会。
6. 激励创新意识,培养好奇心,不要死记硬背。
没有掌握某种算法技术的根本原理,就不会有应变和创新的能力。想成为一位好程序员(其实从事任何一个行业都是如此),重要的是要养成钻研,好奇,创新,动手,合作的优秀习惯,不满足于填鸭,不满足于考试交差,不满足于表象。这不是学几门课能够一蹴而就的。
7. 有策略的“打工”
在不影响学业的前提下,寻找真正有意义的暑期工作或兼职。去找一个重视技术的公司,在一个好的“老板”指导下完成真正会被用户使用的程序。不要急于去一个要你做“头”而独挡一面的地方,因为向别人学习才是你的目的。找工作也是一样,不要只看待遇和职衔,要挑一个你能够学习的环境,一个愿意培养员工的企业,一个重视你的专业的公司。最后,还要挑一个好老板。
希望大家都能把握机会,养成好的学习习惯,把算法学精学透;希望大家都能有一个美好的未来!
算法为魂
凌小宁
“国内一般的开发企业和开发者偏浮躁,缺乏扎实的基本功,这直接导致他们自主创新的能力低下”
“算法是魂,程序是衣。”
现代意义上的计算机算法的概念是在1936年Alan Turing提出现代计算机的基本模型图灵机之后才清晰起来(http://www.turing.org.uk/turing):算法是解决问题或执行任务的过程;它能够一步一步地在图灵机或等价的机器(如现代的计算机)上执行。一个典型的计算机算法可以输入零个,一个,或多个数据,经过有限个确定的、精确的步骤,得到一个或多个结果。对这一过程的设计和分析称为算法的设计与分析。
算法研究的典型问题包括计算机最常用的分类、排序、搜索、遍历、集合运算等等。
算法的常用设计方法包括循环、递归、分治、动态规划、线性规划、搜索与枚举、启发式搜索等等。
算法的主要分析方法是建立与算法相应的数学公式,来计算该算法所用的运行时间和存储空间(称为算法的性能分析)。通过这样严格的数学训练可以获得一种直觉的对算法性能的估计能力。这种能力是微软的软件大腕儿都具备的。
有个学生告诉我,他的理想不是当程序员而是当软件架构师。我说:当架构师是个很好的理想,但不当程序员而当架构师不是理想是幻想。我知道的架构师,包括微软首席架构师比尔·盖茨,视窗和办公软件的总架构师,都曾是最优秀的程序员。软件架构设计不仅仅是画些框图写些流程而已,它需要坚实的基础(包括算法基础)和丰富的经验。
算法基础学习
如果你找到好的方法,学好算法基础并不是件很困难的事。这里我给大家提四个建议。
第一,先学好相关的数学。高等代数是算法分析中最常用到的,必须掌握。离散数学中的布尔代数、集合论、排列组合等是算法的基础的基础,应该掌握好。数理逻辑或形式逻辑教你推理和证明方法,对建立算法性能公式和算法性能分析很有帮助。微积分中的的极限理论可以帮助你更好地理解算法性能公式。
第二,讨论计算机算法不能脱离数据结构。因此,数据结构是学习算法的基础。有些大学把算法和数据结构放在一起教,是一种可行的办法。
第三,学会方法比记住结论更重要!设计算法的几种通用方法,例如:循环、递归、分治、搜索法、动态规划和线性规划等等,都是程序设计中最常用的方法,都是可以举一反三的“灵丹妙药”,应成为算法学习的重点。
第四,像学习软件专业的其他课程,学习算法的最好的方法就是编程练习。找一个你最感兴趣的问题,设计出几个不同的算法解,对每个算法,推导出性能公式,为每个算法编出程序,运行这些程序并统计出实际性能,比较你的理论结果和实际结果,最后,做出分析。这个过程,既可以帮助你建立坚实的算法编程基础,又可以培养你对算法及其性能的直觉。这两者对程序员都是极为重要的。