posted in 程序员之路 

        写博客会花费一些时间,因此有时会想为什么要写博客?
        因为感觉写博客是一个思考、总结的过程,有人说“读书说明你学会了学习,而写作说明你学会了思考”。通过写作,把学习的东西加以总结、凝练,真正变为自己的东西。
        第一次接触到博客是在CSDN的一个校园讲座上,讲座中那个CSDN讲师各种宣扬写博客的好处,什么找工作好找,什么因为一篇博文被IT大佬所赏识,blabla……反正一堆好处,当时就想写博客真是太特么牛掰了,高端大气上档次,于是兴冲冲的跑去申请了一个博客。
        博客申请初期也写什么特别有用的东西,只是转载一些技术文章以及一些杂文,再往后开始写一些简单的学习笔记,转载一些好的文章。再后来看到了一些牛人的博客,写得确实很好,再加上看了一些东西,也开始写一些博客了,写到现在,感觉不错。
        关于为什么要写博客,刘未鹏的博文“为什么你应该(从现在开始就)写博客”和池建强的博文“写作即思考”都有所讨论,对于他们的许多观点也感到十分赞同。当然自己还远远达不到他们的层次,不过有一点是mac君很赞同的,就是要学着开始写博客,或许一开始的时候质量不高,但这是一个开始。写作的过程就是一个思考的过程,写作会推动自己开始思考。
        感觉写作就是一个函数定义的过程。在写作的时候,往往会就某一个问题进行思考,这个问题自己已经思考过很多次,终于有一天自己觉这个问题已经想得小有成果了,可以进行一下总结了,于是就写了一篇文章。
        这就好比是在定义一个函数,或者定义一个类。在函数中,对这个问题的各种情况(函数的各种参数)进行了分析,因为要兼顾到不同的情况(不同参数),因此在定义函数的过程中就会进行一些思考。同时为了保持结果的准确性,就会对事物的推理过程有一个显性的思考的过程:毕竟这不是写私人的日志,而是要写给人看得,事物的推理要过得去才行。最后总结出了一些结论(函数的返回值),这样当再次遇到这个问题时,直接调用这个函数就能直接得到返回值了。另一方面,写出来的文章可以作为一个类来使用,类的一个特性是可派生:在这个类的基础上,可以对其他的一些东西进行思考,进而派生出一个更加复杂问题的思考,而这些思考可以写成另一篇博文(另一个子类),通过这样的方式构造对这个世界的理解。
        相比与只思考不写作的方式,写作一方面能够加深记忆的印象,另一方面对问题有一个更加明确的逻辑。刘未鹏在博文中有过一个比喻:思考的过程就好比是一个打着灯笼探路的过程,因为人大脑的能力有限的(科学测试人只能同时进行7+-2的思考),在探路的过程中往往会迷失了方向。如同在进行深度优先遍历时,走到一个“树”的子结点上回溯不到上层节点了,这时通过写作就能对事物进行一个更加深层次的把握。还有一个优势在于,博文写出来是给人看得,别人看了之后可能会有一个思想的交流的过程,思维的碰撞产生智慧的火花,这算是写作的意外收获了。

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/9884047

posted in 程序员之路 

 

锐哥准备为大家烹饪红烧鲤鱼,小丫主动要求跟锐哥学习烧鱼,这也使小蔡和大熊非常感兴趣变得积极主动。锐哥首先要求他们把配料准备好,小丫又进行配料准备任务分工,没有的配料分头到超市购买。用料如下:

鲤鱼(一斤半到两斤的鱼最好)、蒜头两头整的、姜片5~6片、小香葱3根、小红辣椒10个左右,分两段切(超市有的卖盒装的),辣豆豉(可用老干妈代替)1大匙、豆瓣酱2大匙、盐少许、鸡精1小匙、料酒1匙、清水2碗、1两纯瘦肉馅、植物油少许。

锐哥让他们注意,收拾鱼的时候要将鲤鱼鱼腹两侧各有一条与细线一样的白筋去掉,可以除腥味;在靠鲤鱼鳃部的地方切一个小口,白筋就显露出来了,用镊子夹住,轻轻用力,即可抽掉。大家七手八脚很快备齐了用料。

时间:6月10日 17点 地点:锐哥家 人物:锐哥、小蔡、大熊、小丫

锐哥边烹饪鱼边讲解说:“首先将收拾好的鲤鱼控干水,最好准备一条干净餐布或者厨房专用纸巾再将鱼上的水分吸干,油入锅烧热,把准备好的鱼放里面煎至黄色再翻面煎成黄色,将鱼装盘待用,如果你手艺到家,鱼也可以一直放在锅里进行别的程序操作。再将肉馅放入锅里炒,直到变色,放少许料酒,再接着放豆瓣酱还有老干妈和肉馅炒匀,这时姜片和整粒的蒜也放进去小炒一分钟,把煎好的鱼再放进去,加两碗水放入小红辣椒。

“这会可以放一点点盐,因为豆瓣酱和老干妈里都有盐味,再放鸡精粉盖上锅盖,改中小火烧至汤快收干时把鱼装好盘,里面的汤剂留在锅里,把切好的小香葱放入锅里翻炒两下关火,将汤剂淋到鱼上。这道菜就做成了,看似复杂,其实材料都准备好做起来又快又简单。”

小丫品尝了一口称赞:“锐哥的手艺真不错!味道好极了,色泽红亮,蒜香浓郁,皮焦肉嫩,咸鲜微辣。”很快大家一起吃完了饭。

锐哥:“大家注意到没有,其实烹饪鱼的过程与一个人的职业规划的过程相似,从配料收集→加工→实现目标(红烧鲤鱼)。另外,职业规划非常重要的一点是要学会角色分析能力。大部分人在长期的工作中趋于麻木,对自己的角色并不清晰。但是,就像任何产品在市场中要有其特色的定位和卖点一样,在职者必须让自己有一些过人之处,让自己的价值和成绩得以体现并受到认可。”

小蔡:“在第一次钓到鱼的时候,我感悟到的就是因为对软件行业不了解,所以缺少一根结实的线将自己与梦想有序地串联起来,因此很难深刻体会到目标在自己掌控下挣扎时的力量。那么,通常程序员如何对自己的角色做分析呢?”

锐哥顺手在纸上画了几个图,说:“确切地说,你应该问程序员通常的发展路线是怎样的?你们可以看看这个图(如图3-1所示),当一个初步的职业规划方案已经成型时,如果制订者目前已在一个软件公司工作,那么,对他来说进一步的提升非常重要。首先要做的则是进行角色分析,反思一下这个职业环境对个人的要求和期望是什么,如何使自己在单位中脱颖而出。

1936235.jpg

图3-1

“通常,软件技术人员的职业发展有几个选择:专注于技术,成为技术专家;转型到技术型销售、技术支持等;随着技术成长,从技术性管理到高级管理。这是大家都看得清楚的方向,也都在向这些方向的金字塔尖努力。

“就像烹饪鱼一样,每一个阶段目标都需要你进行角色分析,找出这一角色需要的‘配料’,当你注意收集技术、素养等相关‘配料’后,就会成功烹饪出你所需要的目标鱼。前提是你一定要了解自己的特点和优势,就好比黄瓜种子是不可能培育成西瓜一样。”

锐哥继续说:“这归根结底,都是以技术为基础。在扎实的技术基础上(高级软件工程师),如果有着比较强的抽象设计能力,又打算专注于技术开发,架构师是个好的选择;如果性格更适合做管理,情商能力突出,技术型管理应该是下一步的方向。这种发展规划属于‘瘸腿走路’的类型,各有侧重主攻发展的职业方向,也是目前一般程序员普遍采用的发展路线规划。”

小蔡认真地看着图说:“程序员职业规划还有这么多学问!我看到每个角色配合的学历,那么学历和认证证书真的很重要吗?还有必要花钱参加社会技术培训吗?”

锐哥:“决胜点在于长期的点滴积累,认证证书、成绩、丰富的经历是求职的表面文章,在目前软件行业里不是很看中这个,真正的‘内功’是需要规划的。至于培训,我倒是很建议直接加入软件公司,你就会学到很多实际的东西。不过,学历教育虽然在职业生涯里不是主要的,但是随着职位的提升却有很重要的意义,能辅助拓展你的职业发展空间,而不是以此为阻碍从而失去更多的机会。 ”

“已经工作两年以上的程序员可以有几种基本的职业规划:技术专家、软件架构师、实施顾问或销售。其中程序员最主要的发展方向是资深技术专家,无论是Java、.NET还是数据库领域,都要首先成为专家,然后才可能继续发展为架构师。尽管架构师的职位可以工作一辈子,待遇也非常好,对于科班出身的程序员最为适合,但这种工作职位非常有限,因为在中国目前的IT行业,架构师需要的条件比较复杂,而且需求量也比较少,这也是我国软件行业走向国际并有待成熟的因素之一。”

大熊指着另外一张图说:“这个是综合才能型发展路线图(如图3-2所示),我听说目前国内缺乏的是管理能力和专业知识技能并驾齐驱的IT人才。是不是指着这种复合型人才?”

1936237.jpg

图3-2

锐哥说:“是的,特别是懂得运用目标管理技术的项目管理人才,既掌握核心技术又有全局掌控能力的项目管理人才,非常难找。我建议对于大多数人来说,首先是要专,只有在技术方向上做得比较深入,才能适当做工作调整,把自己转变为某个领域的专家。

“然后,根据自己的情况,决定自己做软件架构师还是高级的顾问销售,另外一部分人可能就会走向管理,这和个人性格与情商有关。软件优秀的管理者都必须懂得技术,掌握核心技能的人才向管理岗位转型有很大的优势,因而提升管理能力成了转型的关键。譬如,当唐骏还是微软一名普通程序员时,就从公司发展的角度考虑,向老板提议开发了中文版Windows,最终使他从几万名工程师中脱颖而出,成为部门经理。正如他所说,虽然是程序员,但自己不能只把自己当程序员,你可以为老板和公司着想。

“调查研究后,带着解决方案去找老板,就会得到老板的重视和信任,所以一定要增强工作主动性和参与性。无论是软件开发还是项目管理,国内员工大多只是做好份内事或完成交派任务,很少能主动发现问题。其实,只有拥有更高眼界,才能谋取大发展。

“总之,程序员要根据本身的基本素质、技术能力选择开发层次,由低到高,逐步发展。也是一名程序员本身具备相应素质的循序渐进的发展轨迹,包括很强的技术背景和综合管理才能等素养,这也就是所谓‘两条腿走路’的职业规划发展路线。”

小蔡:“原来技术转型还有这么多学问,受益匪浅。我打个比方,如果只是一名程序员,但仍需要站在项目经理的层面上看自己的工作,这样才能更好地合作,融入团队中,并且锻炼自己的思想境界,从而提高自己。”

锐哥:“小蔡说得是。另外,在未来发展上首先确定自己的发展方向和研究方向,在学习技术的同时还要为以后做准备,做好以后的技术转型。广度和深度是相对的,先广还是先深实质上从某种意义来说取决你的工作性质,如果你是从事单一工作的,多半你会短暂先深,因为这是你立足的根本;而如果你选择的职业是综合性的,比如管理、讲师等,那么你必然要先有广度才可以,但一段时间后,你都要转入深度,只有你在某一方面或领域有一定的深度后,你才能继续寻求广度,否则,你将什么都会,但什么都不精,这样的人在市场上是最难以立足的。”

大熊:“这张程序员发展路线图挺有意思,国际人才型(如图3-3所示),一定要求外语口语流利吧?”

1936239.jpg

图3-3

锐哥:“是的。如果说前面‘两条腿走路’要求的综合能力成分多,随着国际化相互联系越来越紧密,那么国际化人才可以说是当前更为便捷的程序员职业规划发展之路。目前,国际化软件项目经理是人才市场上炙手可热的人才,有丰富经验、外语口语好的软件项目经理是抢手的香饽饽,供不应求,薪水自然也是水涨船高。最重要的是,一个优秀的项目经理可以在这个岗位上长久工作下去,并且有向高层进一步提升的可能。外语好、技术又好的程序员发展路线很广,是目前国内外软件企业需要的热点人才。”

小蔡:“锐哥跟我们说了这么多,感觉对程序员、对软件行业的整体发展路线清晰了很多,但是我该用什么方法进行选择呢?”

锐哥:“要想正确地选择,你得必须充分地了解、分析自己,你要学会SWOT职业规划自我分析法。”

总结与提升

成功与失败的区别在于,成功者选择了正确而失败者选择了错误。因此,我们常常能够看到一些天赋相差无几的人,由于选择了不同的方向,人生却迥然相异。选择正确的方向尤为重要,希望不同的程序员根据自己不同的优势和特点能画出适合自己的程序员职业规划图。

软件开发也是有层次区别的,比如,按层次从高到低通常可分为:

系统开发:如操作系统、数据库系统、服务器系统开发;

专业开发:如网络安全、游戏、人工智能开发;

应用开发:如MIS、BI、ERP等系统开发;

普通开发:如网站、简单应用系统开发。

不同的层次,难度系数不一样,对技术要求、个人素质要求也不一样。要成为系统开发者、专业开发者、高级应用开发者,需要有很高的专业知识和很强的逻辑、抽象、空间思维能力,这就要求具有很好的基础,同时具有较大的提升潜力。而要成为简单开发者和初级应用开发者则相对容易些,正是这样,才使很多人走上了软件开发的道路。

(责任编辑:董建伟)

转自:http://tech.ccidnet.com/art/3089/20090908/1880563_1.html

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8986086

posted in 程序员之路 

    一直以来中国教育以“填鸭”式的教学风格而闻名,最近在看了几本英文翻译过来的书后特别有感触。

    甭管学生想不想学,学了能不能消化,学了会不会用,只是一味的教授知识。

    上了(6+3+3+2)年的学终于对如何学习有了一点自己的感悟,在此与大家分享。

   

**    中国填鸭式教育造成的问题:**

    有人把学习总结了一个 "3W学习原则":Why、 What 、Why

    Why:为什么要学习这个知识,以及知识为什么是这个样子而不是那个样子的。

    What:这个知识究竟是什么样的。

    How:如何应用学到的知识。

    个人感觉只有从这3个角度认识了知识,学习了知识才能算是真正掌握了知识。国内的教学往往偏重的是 What 概念性原理性的讲解,以及 如何做题。关于 Why 和 How的部分却少有提及, 而Why 和 How,才是真正能够激起一个人学习兴趣的,而课堂上几乎不讲这些,学生也习惯了不问,最终在"填鸭式"的教育中逐渐失去了对学习的兴趣。

    为什么说 Why 和 How才是真正能够激起一个人学习兴趣的部分?我是这么理解的:知道了Why ,知道了为什么要学习这个知识,才能够体会到 学习这个知识的必要性。知道知识为什么是这个样子的,而不是那个样子的,才能够打心底里认同学习的知识,才能够体会到前人智慧的伟大之处,才能够油然的产生一种对知识的渴求。 知道了How,才能够知道学到的知识有什么用,才能够感觉到学习之后自己的一点一点的成长,才能够感受到自己应用知识解决问题之后的成就感。

    比如在大一和大二期间学习了 工科数学分析、计算机导论、数字电子、汇编语言, 学这几门课有共同点:

    1. 不知道为什么要学习这门课。尤其是数字电子,讲课老师显然不是学计算机出身的,只管将讲他的课,至于为什么要学习数字电子,对学习计算机的学生有什么用,为什么前人要总结出这些概念,一概不管。颇有种"我讲我的课,你们只管学,不要管为什么"的感觉。因而学习中一直很迷茫。

    2. 听着听着就听不懂了。课程一开始能听懂,但听着听着就听不懂了,而且作业不愿意做,上课不愿意听,根本没有一点兴趣。

    3. 考前抱佛脚,考完试就忘的差不多了。因为大部分考试知识都是考前一个周突击的,死记的知识学得快,忘得也快。

    总之,这种学习 自己不喜欢的东西的感觉是非常痛苦的。

    直到后来看了 Charles Petzold的《编码的奥秘》一书,才理解了为什么要学习 数字电子 和 汇编语言,并 唤起了对 计算机组成原理和 操作系统 浓厚的兴趣。因为他在这本书中阐述了 为什么要学习这几门课,为什么前人要总结出这些知识点,学习了之后有什么用,在看完书后,我不禁生出一种仰天长啸的感觉。如果当初上课老师按照这本书的思路,怎么会学的那么痛苦?!

    这个学期又学习了 计算机组成原理 ,由于这门书的原因,自己上课一直听的比较愉快,因为自己知道为什么要学习 这门课,学了有什么用,这些知识处于自己知识框架的哪一个部分。反观身边的同学,一如既往,学习的十分的痛苦,因为他们就根本不想学习这些知识呀!每每想到这些,我都十分庆幸遇到了这本书。

 

**    如何在这种"填鸭式"的教育中学习**

    在高中化学中,学习了两个概念"定性"和"定量",学习知识,既要定性的学习,又要定量的学习。好比学习一个化学方程式,只有知道了反应物和生成物是什么,才有可能 定量 的计算生成物。如果直接就定量的学习肯定会不适应。

    在中国这个现实环境中,课堂上只"定量"的教授知识,却不"定性",即不教授 Why 和 how,既然我们改变不了环境,只好适应这个环境,现在的关键问题就是:如何"定性"的学习,即如何知道学习知识的必要性,如何应用知识,进而激发对学习的兴趣?我认为可以从两个方面着手:

    1. 多看科普书籍。 这里的所谓的科普书籍就是指的那些 浅层次的讲授知识,扩大人的知识面,却不深层次的探究每个问题的书,也正是这类书能够引起人们对某些问题深深的好奇,引起人们对学习的兴趣。如之前提到的《编码的奥秘》一书,只是就某些知识做了"定性"的讲解,让人们知道为什么要学习这门知识,这门知识有什么用?至于深层次的探究——“定量”学习,正好放到课堂上进行。

    关于这些科普书籍,通常有这几种特点: 国内的不如国外翻译过来的,国外翻译过来的不如直接看英文原版(虽然我没能做到)。当然不否认国内也有一些好书。如何才能从茫茫书海中掏出这些 珍贵的书籍?

    一个好的途径就是 上豆瓣,在豆瓣上你可以看到每本书的评分,无数人已经对这本书做出了评分和书评,通过这些评分和书评,就能够权衡这本书究竟有没有必要读,适合什么阶段的人读,以后要注意的问题等。 

    2. 多实践。 记得有一个很牛的学长说过, 动手实践是学习最快的方式,因为为了使用知识而学习知识,这种感觉是非常棒的。在实践过程中,你不仅获得了学习的动力,更在实践过程中深入的理解了知识。

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8914696

posted in 程序员之路 

引子

唉,本实在不想发水文的,可还是发了,看来是周末闷骚咯,没兴趣的请赶紧飘过 ~~~

本篇博文其实是用来给在读大学生一点借鉴的,并不会讨论什么技术类的点 ,所以,不喜欢这种类型文章的也可以飘过,

但是如果各位有兴趣的且保有不同意见者,也可以提出,欢迎讨论,毕竟出来混的应该也看过了很多学校里所谓的大学生,

估计心里头对现在从大学里头招进来的各位小学弟小学妹也不咋的满意,而我也算是比较了解一些学生的,

所以,何不趁着周末一起出来指点一下他们呢?

                

           

致学生 - 大学最重要的不是 Java 和 .Net 而是基础,基础才是最重要的 !!!

在这里,我也主要是因为见很多大学生现还在学校里迷茫,毫无方向感,

而刚好自己周末有点闷骚吧,因此也站出来说两句话,希望不会因此受到人身攻击,

当然,我只是扯淡,说出我的建议,至于觉得发言不妥者,自可以飘过,也欢迎提出新的见解,

而这里我对大伙扯的两句,尤其适用于现还在大学里的各位学弟学妹们,

首先,现在大学里过多追求就业率,拿我们学校来说吧,是个二流学校,为了有好的就业率,

学校一直和校外培训机构进行合作,一直主推 Java ,甚至推出学生如果在某个培训学校培训的话,

是可以不用去上课的,这一点,我实在想不通,最后我给自己一个答案,那就是学校已经自认为比不上外面的培训机构了,

这个不得不说是一个悲剧哦 ! ! !

而后就是,我们学校里,好不容易有个博导给我们上课,但是悲剧又来了,博导上的课居然是计算机导论,

最差劲的一门了,唉,现在才发现,大学里真正教书的一般都是助教和讲师,博导可都是有自己的项目要做,

有自己的公司要开,有自己的人际网要拓展,博导这么忙,当然也就只能请个助教了,

这个其实才是现今大学教学的一个大悲剧 ! ! !

还有就是我本科学的是软件工程,大学里,我很悲剧我没有学过组成原理,编译原理等等基础课,

我们听讲座听的最多的居然是培训学校来的老师的演讲(基本上是推销),

呵呵,够悲剧了吧,希望各位的学校不会和我们学校一样 . . .

上面呢,就是我在学校时候的学习背景了。

          

然后呢,我再根据我自己的经历来谈谈我的看法,我呢,也算是个计算机行业的狂热分子吧,

自大一接触  C++ ,我一直都对这行业很感兴趣,曾经也经常在网吧上通宵(当然那会是为了学习  C++ ),

大一到大二上学期,我一直都是在黑框框里面(也就是 DOS 环境下)写着 C++ 程序,

也潜心写过汉诺塔,迷宫,八皇后等等经典算法题,

那会儿写的呢也很带劲,但一直没有接触过具体界面的实现,所以总是感觉有些不爽,因为总觉得那不是软件,

甚至都怀疑起  C++ 到底能够做什么用,现在想来那时候的想法真是幼稚啊,

并且自己也总是幻想着能够什么时候做一个具体的软件出来(那个时候总是觉得只有有了现在所谓的图形界面才算得上软件),

后来一次偶然的机会,我接触了 . Net ,然后,我发现,做图形界面是如此的爽呼呼,

于是乎,一个人拼命地学,拼命地学 .Net,然后开始拼命地写我那个时候我所认为的所谓的软件,

写一些数学工具,一些小游戏,也将一些诸如迷宫,八皇后的算法题从 C++ 改成 C# 写的应用程序,

然后就是做  Web  开发,学了很多很多,也做了很多的诸如什么什么的管理系统等等,

但一直都感觉不再向大一学习  C++ 那么正派了,有点说不出的感觉,

但也一直总结不出什么内容,

不过现在算是总结出来了,因为我过早的涉及了高级语言,而忽略了真正的基础  ! ! !

因为总结出来了结果,所以我也越发的思考大学里面,作为一个大学生到底应该要学的是什么?

总结了个人所认为的在技术上的几点内容,注意是技术上的,至于做人处事上的,我自己都做的不好,没资格在这里扯淡,

英语很重要,我的英语一直不怎么的,因为英语差劲我也吃了很多亏的,甚至我现在看英文资料,我都得开着金山词霸的划词翻译,

看起来的那个速度自然是不用说了,

曾经我也总是想,现在国内资料那么多,要英语干吗?呵呵,听我一句劝,好好学习英语吧,

因为你会发现,你真正要找的资料是某个不常用  API  的英文解释,而不是要找  HelloWorld  怎么实现的中文资料,

然后就是难道你以为任何一门语言都有向  MSDN  中  C#  这么全面的中文文档?那你看看  MSDN  中 VC++ 的文档吧 ! ! !

或许有人会说:为什么  C/C++  中文资料这么多?

天呐,难道你想一辈子跟在别人几十年后面,你知道  C/C++ 是一年出来的吗?难道,你愿意永远比别人了解到新知识晚几十年?

数学很重要,大学里,我数学一直都还不错,无论是高数,还是线数,离散,我都学得不错,也一直有些沾沾自喜,

但是到现在看来,我的数学,呵呵,悲剧,学得太烂了,数学的话,我觉得各位在校的,也听一句劝,学得越深越好,

曾经,我也总是觉得数学没一点用处,但是后来看了  OpenCV ,也和同学讨论了  OpenGL ,谈论了一些计算机图形学的内容,

也看了同事的一些不晓得是什么的东西,居然列那么多数学公式,关键是我一个都不懂,

此时我才发现,计算机的世界其实是一个数学世界,

你想深入了解计算机,那你得数学得学得非常牛逼,里头全是数学,所有的东西都是数学,

甚至让我觉得,计算机搞到很牛逼了的话,那么一定可以成为一个牛逼的数学家了,

或许各位会说,我只局限在我所了解的领域里面了,因为在  .Net 中,数学似乎一点都不重要呢,

但是我会反问,难道你又不是局限在 .Net  中了,

或许,你觉得微积分,常微分方程离我们很远,其实,你错了,它离我们很近,你总有一天会发现的,

呵呵,其实数学的重要不重要,关键在于你想不想真正的呆在这一行里面;

汇编很重要,弄到这里,应该会有很多人反对了,因为,向汇编这种东西,在搞 Java  和 .Net 的这些高级语言程序员眼里,

那早就应该是过时的内容了,呵呵,其实我以前也是这么觉得的,毕竟,有本事你拿汇编做个  Web 应用程序出来看看,

呵呵,以前多幼稚的想法啊,人家<<疯狂程序员>>里头的绝影就是弄的汇编,不晓得现在混得咋样咯,应该不会差那头去吧,

毕竟人家弄的是汇编,确实,那汇编做应用软件或者 Web 应用程序的话,确实太牵强了,但是为何我现在搞 .Net 这么多年了,

反而回过头来学习汇编了呢?因为我发现,我对内存的管理,对寄存器中的内容,对整个 .Net  的底层,对所有的一切都掌控不了,

曾经看一本书,好像是<<Sql  Server  2005  高级程序设计>>吧(一本  Sql  Server  方面的巨著,这里擅自推荐一下),

里面的作者就说了,计算机中最害怕的事情就是不可预料,无法掌控,

而且汇编语言中,对内存的寻址,以及寄存器的使用都有非常好的解释和频繁的使用,

通过学习汇编,你可以更好的理解地址总线,数据总线,控制总线和 CPU 以及内存之间真正的工作流程,

以及它们之间的一些最基层的协作关系,同时也能理会内存最真实的使用,

而不会向无头苍蝇一样,甚至连内存是什么都不知道,只会说,我只要分配内存即可,只要  new  就 OK 了,

当然如果你只想做到你所要的  new  的话,我也没有办法,我只能说你还不够狂热,不够专业,不是合格的程序员;

计算机组成原理和编译原理,计算机组成原理的重要性是不言而喻的,毕竟考研专业课中,这东西好像还占蛮大的比例的,

至于这编译原理吗,肯定又有人反对编译原理了,说,又不让你自己搞编译器,学什么编译原理,

呵呵,说的也不错,但是我想说的是,并不是你想搞什么你才去学什么,眼光放远点,

你会发现,你的世界里并不是只有 .Net  和 Java,

而且在编译原理这东西里面,你确实能够学到很多东西,就比如,如果当初设计  Java  的是你,

你会想到先将程序编译成字节码,然后再使用解释器来解释字节码吗?

我想,你肯定想不出的 ~~~

操作系统

操作系统,这个名词听着都感觉很严重,毕竟,在操作系统被  Windows  垄断的环境下,

也确实很难有人愿意接受操作系统是很重要的东东了,

甚至觉得学习操作系统就是学习如何在  DOS  环境下,敲个命令出来一大堆东西,

或者觉得学习操作系统就像是学习  <<Windows  操作系统一千招>>一样,

能够打开个注册表,能够优化一下电脑,改变一下电脑启动画面,那就是学习操作系统了,

又觉得以后操作系统这东西就给微软去做吧,

如果你真这样想的话,那我只能说,真是个悲剧 ! ! !

我想说,如果你觉得操作系统不重要的话,那你真是错到家了,

大学里头,我一开始也是带着混的心态混过的操作系统课程的,

但是在考试前一个星期,我居然迷恋上了操作系统,那可真是作死的看操作系统啊,

整整在一个星期里,我拿着<<操作系统概念>>看了 2 遍,甚至在看完 2 遍中文版的之后,

我还准备去啃原版的,无奈英文水平太差,最后只能作罢,

经过了那次的操作系统的学习后,我自以为操作系统我掌握的还不错了,

但是后来,我发现,我一直都在追赶操作系统里面的知识,

从我写驱动程序开始,我就一直在追赶操作系统,为此,我重新学习操作系统,看  Windows  内核原理,

看  Windows  分析,看内存管理,看进线程调度,看  CPU  调度,看  I/O 管理,即插即用管理等等,

看了很多,至今我都觉得,我在操作系统这一块还很欠缺,很欠缺,我越往深处学习,我就觉得我越欠缺操作系统的知识,

现在也还正在打算到哪里再去找些什么资料来填补空缺呢,呵呵,说了这么多,

我只是想纠正现在大学里头很多人认为操作系统不重要这一观念,

操作系统真的很重要,很重要 ! ! !

C/C++,这两个东西我想不必多说了,只是在这里奉劝那些和我当年幼稚想法一样的说  C/C++ 做不了什么用的人,

如果这两个东西,你错过了,你补都补不回,

其实啊,我们被大学里头的老师害惨了啊,

曾经我的  C++ 老师就说,美国什么航空火箭发射上天后失败,直接掉了下来,照成  n  人死亡,损失惨重,

而这一切竟然是一个指针惹的祸,所以,我们  C++  老师就跟我们说,指针这个东西很危险,少接触为妙,

哈哈哈,真被害惨了,后来才发现 C/C++ 如果没有了指针,那就真的一点用处都没有咯 ~~~

还有,当年老师教  Goto  语句的时候,老师只讲了一句话:这东西,影响程序逻辑性,造成程序可读性差,所以大家禁用 ~~~

呵呵,现在出来,这个  Goto 语句也还是经常看到的

(这里我并不是推广使用  Goto 语句哦,只是有些东西,并不是说老师不教我们就可以不学的,也不是我们不学,以后就不会碰到要使用的情况的)

劝诫各位,千万不要看不起黑框框,来句形象点的:一切图形界面都是过眼浮云 ~~~

我最庆幸的是,我当初对 C++ 还执着过那么一年半,所以,也还算有一点点,也就是一点点底子而已,

拿最简单的说,人家  Windows  还是 C 写的呢,人家  Oracle  也是  C  写的呢,你还敢说  C/C++ 没用 ?

然后,那你又会说,那些都是做的系统集成,系统软件,

呵呵,那我现在给公司里写的也都是  C  写的呢,而且写的环境还是在黑框框里头写的呢 (Dos  环境下编译调试),

那你现在还会很鄙视黑框框吗 ?

数据结构和算法,对数据结构还好,在大学里,还是有很多人意识到了数据结构的重要性的,

而且,基本上上课的老师也会稍微强调一下数据结构的重要性,呵呵,所以,在大学里头,这门课缺课的人还是比较少的,

确实,如果等到各位将来研究一些稍微底层的代码时,或者如果有机会写系统软件的时候,

你会发现,底层里头的链表那个多啊,循环链表,双向循环链表,平衡数,顺序表,最小生成树等等用的到处都是,

当然啦,现在 C# 里头,大家或许很少有机会接触到了,要队列有队列,要表有表,要字典有字典,要什么有什么,

一般来说一个字典,一个  Array , 一个泛型基本上全部搞定,

但是忘了告诉各位,用得这么方便可是需要付出代价的哦  ! ! !

而对于算法的话,现在感觉越来越不受重视了哦,

甚至很多学校都不开算法课了,只是一个简单的数据结构带过而已,

所以很多人也都不晓得贪心算法,动态规划等了(说实话,我也不太懂了,不过打算有时间去补补),

都是高级语言惹得祸(注意,这里不是抨击高级语言哦),把算法都封装的那么好,

说实在的,如果真不做大的系统的话,算法这东西真的很多都可以不需要掌握了的,

但是,如果,这世界上每一个人都这样想的话,就不会有  Windows  ,Oralce 了,

殊不知,Windows  整个结构的复杂性,其中调度算法的使用,

也殊不知,Oracle  体系结构的复杂度,其中缓存处理算法的复杂度等等,

如果你只想在  .Net  上用用别人的东东,或者说是有空拿个循环玩玩的话,算法这东西确实跟你隔得很远了,

但是,难道你愿意这样???

你去看现在年薪高的程序员,哪一个不是算法高手?

呵呵,这就是差别哦  ~~~

数字电路和模拟电路,说到这里,更多意见应该会冒出来了,咱搞软件的,为什么要搞这些东西呢?

呵呵,如果真的不用搞这些东西,大学里就不会开这些课咯,博客园里头搞 .Net  的居多,搞  Web 开发和 .Net 应用软件开发的居多,

而现在市场上搞  Java  和  .Net 的又是居多,所以设计到数字电路和模拟电路的内容不多,

甚至是一片空白,所以也就觉得这两东西真是扯淡,说真的,我很能体会大伙的心情,因为我以前也是这样觉得的,

但是,大家眼光放开点,真的放开点,这个世界上真的就只有  Java  和 .Net 了吗?

而除了  Java  和  .Net  以外,很多其他地方,对于数字电路和模拟电路都是要求很高的,

尤其现在社会上很缺模拟电路方面的人才哦,而且,理解了这两个东西以后,对于自身理解程序的具体怎么跑的,

为什么能输出个字符,为什么能执行计算操作都是很有帮助的,而不会像一个码农,连自己在做什么都不知道,

这也就是所谓的不可预知 ! ! !

计算机网络,这个东西呢,说真的,也不好说,当今早就过了以前那个计算机只是用来做计算的时代了,

现在是网络的时代,如果你真不懂网络,说实在的,你连程序员都不适合,不要求你有多深的掌握,

但是  TCP,UDP 还是要分得清吧?TCP/IP 协议五层结构总的知道吧?

数据具体的流动过程也要有所了解吧,呵呵,都是很基础的东西啊,

可是,这些基础却是最重要的东西~~~

 

                       

总结

上面总结出来的几门课程,都是我认为大学里头,在计算机中最最基础的课程了,

但是,这些课程却被很多大学给忽略了,从而也被很多大学生给忽略掉了,

而诸如软件工程,数据库,软件项目管理之类的课程我在这里没有提及,因为,那一块过多涉及软件方向了,

会限制到一些思维,所以我没有提及。

现在的大学里(像我所在的学校),侧重点已经变咯,培养学生事小,捞到收入才是最重要的了,

学校为什么拼就业率啊?就业率高了,自然学生来得多,学生来得多,自然,国家给的钱多,

自然,腰包里钱更多,然后又大肆拼就业率,拼就业率,那就得多让学生接触所谓的现在社会上所需要的(Java  和  .Net  程序员),

如何培养出这样的程序员呢?交给培训学校吧 . . .

甚至,似乎今年还推出了一个新的专业,是和牛耳培训学校合作的一个软件外包专业,

呵呵,专业外包人才,靠 . . . 名字真好听 . . . 要我说,学校太不负责了 . . .

说实在的,以前,有一些不同意老赵对培训学校的观点的,

但是,现在看来,也还是有一些同意了(但培训学校确实还是有一些作用的,或许会培养人,但是我觉得也会害死人),

通观全文,可能有读者会觉得我在反对高级语言,其实,我一直都在努力地避开这个话题,

因为,我本身的意愿并不是反对高级语言,只不过,我觉得大学里头的学生,

尤其是大一,大二,大三的学生,他们不应该过早的接触到高级语言,

如果他们基础真的好了,那他们到哪里都可以展翅,当然,等到基础好了,

学起高级语言来也是手到擒来的 . . .

还有就是需要解释一下,现在大学里头流传的:学基础课程是找不到工作的 !只有  Java  和  .Net  才是王道;

我的回答是放屁 !

           

好了,拍砖的拍砖,要骂的请先给出理由,然后再骂,最讨厌什么都不标明就进行人身攻击者 !

          

同意的请顶起,反对的请说出理由,也算是给学弟学妹们一个指导 !

         

          

欢迎转载,但转载请注明:     转载自    Zachary.XiaoZhen - 梦想的天空

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8759243

posted in 程序员之路 

这段时间受到很多人的来信。他们看了我很早以前写的推崇 Linux 的文章,想知道如何“抛弃 Windows,学习 Linux”。天知道他们在哪里找到那么老的文章,真是好事不出门…… 我觉得我有责任消除我以前的文章对人的误导,洗清我这个“Linux 狂热分子”的恶名。我觉得我已经写过一些澄清的文章了,可是怎么还是有人来信问 Linux 的问题。也许因为感觉到“舆论压力”,我把文章都删了。

简言之,我想对那些觉得 Linux 永远也学不会的“菜鸟”们说:

  1. Linux 和 Unix 里面包含了一些非常糟糕的设计。不要被 Unix 的教条主义者吓倒。学不会有些东西很多时候不是你的错,而是 Linux 的错,是“Unix 思想” 的错。不要浪费时间去学习太多工具的用法,钻研稀奇古怪的命令行。那些貌似难的,复杂的东西,特别要小心分析。

  2. Windows 避免了 Unix,Linux 和 Mac OS X 的很多问题。微软是值得尊敬的公司,是真正在乎程序开发工具的公司。我收回曾经对微软的鄙视态度。请菜鸟们吸收 Windows 设计里面好的东西。另外 Visual Studio 是非常好的工具,会带来编程效率的大幅度提升。请不要歧视 IDE。要正视 Emacs,VIM 等文本编辑器的局限性。当然,这些正面评价不等于说你应该为微软工作。就像我喜欢 iPhone,但是却不一定想给 Apple 工作一样。

  3. 学习操作系统最好的办法是学会(真正的)程序设计思想,而不是去“学习”各种古怪的工具。所有操作系统,数据库,Internet,以至于 WEB 的设计思想(和缺陷),几乎都能用程序语言的思想简单的解释。

先说说我现在对 Linux 和相关工具(比如 TeX)的看法吧。我每天上班都用 Linux,可是回家才不想用它呢。上班的时候,我基本上只是尽我所能的改善它,让它不要给我惹麻烦。Unix 有许许多多的设计错误,却被当成了教条,传给了一代又一代的程序员,恶性循环。Unix 的 shell,命令,配置方式,图形界面,都是相当糟糕的。每一个新版本的 Ubuntu 都会在图形界面的设计上出现新的错误,让你感觉历史怎么会倒退。其实这只是表面现象。Linux 所用的图形界面(X Window)在本质上几乎是没救的。我不想在这里细说 Unix 的缺点,在它出现的早期,已经有人写了一本书,名叫 Unix Hater's Handbook,里面专门有一章叫做 The X-Windows Disaster。它分析后指出,X Window 貌似高明的 client-server 设计,其实并不像说的那么好。

这本书汇集了 Unix 出现的年代,很多人对它的咒骂。有趣的是,这本书有一个“反序言”,是 Unix 的创造者之一 Dennis Ritchie 写的。我曾经以为这些骂 Unix 的人都是一些菜鸟。他们肯定是智商太低,或者被 Windows 洗脑了,不能理解 Unix 的高明设计才在那里骂街。现在理解了程序语言的设计原理之后,才发现他们说的那些话里面居然大部分是实话!其实他们里面有些人在当年就是世界顶尖的编程高手,自己写过操作系统和编译器,功底不亚于 Unix 的创造者。在当年他们就已经使用过设计更加合理的系统,比如 Multics,Lisp Machine 等。

可惜的是,在现在的操作系统书籍里面,Multics 往往只是被用来衬托 Unix 的“简单”和伟大。 Unix 的书籍喜欢在第一章讲述这样的历史:“Multics 由于设计过于复杂,试图包罗万象,而且价格昂贵,最后失败了。” 可是 Multics 失败了吗?Multics,Oberon,IBM System/38, Lisp Machine,…… 在几十年前就拥有了 Linux 现在都还没有的好东西。Unix 里面的东西,什么虚拟内存,文件系统,…… 基本上都是从 Multics 学来的。Multics 的机器,一直到 2000 年都还在运行。Unix 不但“窜改”了历史教科书,而且似乎永远不吸取教训,到现在还没有实现那些早期系统早就有的好东西。Unix 的设计几乎完全没有一致性和原则。各种工具程序功能重复,冗余,没法有效地交换数据。可是最后 Unix 靠着自己的“廉价”,“宗教”和“哲学”,战胜了别的系统在设计上的先进,统治了程序员的世界。

如果你想知道这些“失败的”操作系统里面有哪些我们现在都还没有的先进技术,可以参考这篇文章:Oberon - The Overlooked Jewel。它介绍的是 Niklaus Wirth(也就是 Pascal 语言的设计者)的 Oberon 操作系统。

胜者为王,可是 Unix 其实是一个暴君,它不允许你批评它的错误。它利用其它程序员的舆论压力,让每一个系统设计上的错误,都被说成是用户自己的失误。你不敢说一个工具设计有毛病,因为如果别人听到了,就会以为你自己不够聪明,说你“人笨怪刀钝”。这就像是“皇帝的新装”里的人们,明明知道皇帝没穿衣服,还要说“这衣服这漂亮”! 总而言之,“对用户友好”这个概念,在 Unix 的世界里是被歧视,被曲解的。Unix 的狂热分子很多都带有一种变态的“精英主义”。他们以用难用的工具为豪,鄙视那些使用“对用户友好”的工具的人。

我曾经强烈的推崇 FVWM,TeX 等工具,可是现在擦亮眼睛看来,它们给用户的界面,其实也是非常糟糕的设计,跟 Unix 一脉相承。他们把程序设计的许多没必要的细节和自己的设计失误,无情的暴露给用户。让用户感觉有那么多东西要记,仿佛永远也没法掌握它。实话说吧,当年我把 TeXbook 看了两遍,做完了所有的习题(包括最难的“double bend”习题)。几个月之后,几乎全部忘记干净。为什么呢?因为 TeX 的语言是非常糟糕的设计,它没有遵循程序语言设计的基本原则。

这里有一个鲜为人知的小故事。TeX 之所以有一个“扩展语言”,是 Scheme 的发明者 Guy Steele 的建议。那年夏天,Steele 在 Stanford 实习。他听说 Knuth 在设计一个排版系统,就强烈建议他使用一种扩展语言。后来 Knuth 采纳了他的建议。不幸的是 Steele 几个月后就离开了,没能帮助 Knuth 完成语言的设计。Knuth 老爹显然有我所说的那种“精英主义”,他咋总是设计一些难用的东西,写一些难懂的书?  谈 <wbr>Linux,Windows <wbr>和 <wbr>Mac

一个好的工具,应该只有少数几条需要记忆的规则,就像象棋一样。而这些源于 Unix 的工具却像是“魔鬼棋”或者“三国杀”,有太多的,无聊的,人造的规则。有些人鄙视图形界面,鄙视 IDE,鄙视含有垃圾回收的语言(比如 Java),鄙视一切“容易”的东西。他们却不知道,把自己沉浸在别人设计的繁复的规则中,是始终无法成为大师的。就像一个人,他有能力学会各种“魔鬼棋”的规则,却始终无法达到象棋大师的高度。所以,容易的东西不一定是坏的,而困难的东西也不一定是好的。学习计算机(或者任何其它工具),应该“只选对的,不选难的”。记忆一堆的命令,乌七八糟的工具用法,最后脑子里什么也不会留下。学习“原理性”的东西,才是永远不会过时的。 

Windows 技术设计上的很多细节,也许在早期是同样糟糕的。但是它却向着更加结构化,更加简单的方向发展。Windows 的技术从 OLE,COM,发展到 .NET,再加上 Visual Studio 这样高效的编程工具,这些带来了程序员和用户效率的大幅度提高,避免了 Unix 和 C 语言的很多不必存在的问题。Windows 程序从很早的时候就能比较方便的交换数据。比如,OLE 让你可以把 Excel 表格嵌入到 Word 文档里面。不得不指出,这些是非常好的想法,是超越“Unix 哲学”的。相反,由于受到“Unix 哲学”的误导,Unix 的程序间交换数据一直以来都是用字符串,而且格式得不到统一,以至于很多程序连拷贝粘贴都没法正确进行。Windows 的“配置”,全都记录在一个中央数据库(注册表)里面,这样程序的配置得到大大的简化。虽然在 Win95 的年代,注册表貌似老是惹麻烦,但现在基本上没有什么问题了。相反,Unix 的配置,全都记录在各种稀奇古怪的配置文件里面,分布在系统的各个地方。你搞不清楚哪个配置文件记录了你想要的信息。每个配置文件连语法都不一样!这就是为什么用 Unix 的公司总是需要一个“系统管理员”,因为软件工程师们才懒得记这些麻烦的东西。

再来比较一下 Windows 和 Mac 吧。 我认识一个 Adobe 的高级设计师。他告诉我说,当年他们把 Photoshop 移植到 Intel 构架的 Mac,花了两年时间。只不过换了个处理器,移植个应用程序就花了两年时间,为什么呢?因为 Xcode 比起 Visual Studio 真是差太多了。而 Mac OS X 的一些设计原因,让他们的移植很痛苦。不过他很自豪的说,当年很多人等了两年也没有买 Intel 构架的 Mac,就是因为他们在等待 Photoshop。最后他直言不讳的说,微软其实才是真正在乎程序员工具的公司。相比之下,Apple 虽然对用户显得友好,但是对程序员的界面却差很多。Apple 尚且如此,Linux 对程序员就更差了。可是有啥办法呢,有些人就是受虐狂。自己痛过之后,还想让别人也痛苦。就像当年的我。

我当然不是人云亦云。微软在程序语言上的造诣和投入,我看得很清楚。我只是通过别人的经历,来验证我已经早已存在的看法。所以一再宣扬别的系统都是向自己学习的 Apple 受到这样的评价,我也一点不惊讶。Mac OS X 毕竟是从 Unix 改造而来的,还没有到脱胎换骨的地步。我有一个 Macbook Air,一个 iPhone 5,和一个退役的,装着 Windows 7 的 T60。我不得不承认,虽然我很喜欢 Macbook 和 iPhone 的硬件,但我发现 Windows 在软件上的很多设计其实更加合理。

我为什么当年会鄙视微软?这很简单。我就是跟着一群人瞎起哄而已!他们说 Linux 能拯救我们,给我们自由。他们说微软是邪恶的公司…… 到现在我身边还有人无缘无故的鄙视微软,却不知道理由。可是 Unix 是谁制造的呢?是 AT&T。微软和 AT&T 哪个更邪恶呢?我不知道。但是你应该了解一下 Unix 的历史。AT&T 当年发现 Unix 有利可图,找多少人打了多少年官司?说微软搞垄断,其实 AT&T 早就搞过垄断了,还被拆散成了好几个公司。想想世界上还有哪一家公司,独立自主的设计出这从底至上全套家什:程序语言,编译器,IDE,操作系统,数据库,办公软件,游戏机,手机…… 我不得不承认,微软是值得尊敬的公司。

公司还不都一样,都是以利益为本的。我们程序员就不要被他们利用,作为利益斗争的炮眼啦。见到什么好就用什么,就学什么。自己学到的东西,又不属于那些垄断企业。我们都有自由的头脑。

当然我不是在这里打击 Linux 和 Mac 而鼓吹 Windows。这些系统的纷争基本上已经不关我什么事。我只是想告诉新人们,去除头脑里的宗教,偏激,仇恨和鄙视。每次仇恨一个东西,你就失去了向它学习的机会。

后记:“对用户友好”是一个值得研究,却又研究得非常不够的东西。很多 UI 的设计者,把东西设计的很漂亮,但是却不方便,不顺手。如果你想了解我认为怎样的设计才是“对用户友好的”,可以参考这篇博客

 

转自:

王垠博客

http://blog.sina.com.cn/yinwang0

 

 

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8699391

posted in 程序员之路 

2006年5月

算法是计算机科学领域最重要的基石之一,但却受到了国内一些程序员的冷落。许多学生看到一些公司在招聘时要求的编程语言五花八门,就产生了一种误解,认为学计算机就是学各种编程语言,或者认为,学习最新的语言、技术、标准就是最好的铺路方法。其实,大家被这些公司误导了。编程语言虽然该学,但是学习计算机算法和理论更重要,因为计算机语言和开发平台日新月异,但万变不离其宗的是那些算法和理论,例如数据结构、算法、编译原理、计算机体系结构、关系型数据库原理等等。在“开复学生网”上,有位同学生动地把这些基础课程比拟为“内功”,把新的语言、技术、标准比拟为“外功”。整天赶时髦的人最后只懂得招式,没有功力,是不可能成为高手的。

算法与我

当我在1980年转入计算机科学系时,还没有多少人的专业方向是计算机科学。有许多其他系的人嘲笑我们说:“知道为什么只有你们系要加一个‘科学’,而没有‘物理科学系’或‘化学科学系’吗?因为人家是真的科学,不需要画蛇添足,而你们自己心虚,生怕不‘科学’,才这样欲盖弥彰。” 其实,这点他们彻底弄错了。真正学懂计算机的人(不只是“编程匠”)都对数学有相当的造诣,既能用科学家的严谨思维来求证,也能用工程师的务实手段来解决问题——而这种思维和手段的最佳演绎就是“算法”。
记得我读博时写的Othello对弈软件获得了世界冠军。当时,得第二名的人认为我是靠侥幸才打赢他,不服气地问我的程序平均每秒能搜索多少步棋,当他发现我的软件在搜索效率上比他快60多倍时,才彻底服输。为什么在同样的机器上,我可以多做60倍的工作呢?这是因为我用了一个最新的算法,能够把一个指数函数转换成四个近似的表,只要用常数时间就可得到近似的答案。在这个例子中,是否用对算法才是能否赢得世界冠军的关键。
还记得1988年贝尔实验室副总裁亲自来访问我的学校,目的就是为了想了解为什么他们的语音识别系统比我开发的慢几十倍,而且,在扩大至大词汇系统后,速度差异更有几百倍之多。他们虽然买了几台超级计算机,勉强让系统跑了起来,但这么贵的计算资源让他们的产品部门很反感,因为“昂贵”的技术是没有应用前景的。在与他们探讨的过程中,我惊讶地发现一个O(n*m)的动态规划(dynamic programming)居然被他们做成了O(n*n*m)。更惊讶的是,他们还为此发表了不少文章,甚至为自己的算法起了一个很特别的名字,并将算法提名到一个科学会议里,希望能得到大奖。当时,贝尔实验室的研究员当然绝顶聪明,但他们全都是学数学、物理或电机出身,从未学过计算机科学或算法,才犯了这么基本的错误。我想那些人以后再也不会嘲笑学计算机科学的人了吧!

网络时代的算法

有人也许会说:“今天计算机这么快,算法还重要吗?”其实永远不会有太快的计算机,因为我们总会想出新的应用。虽然在摩尔定律的作用下,计算机的计算能力每年都在飞快增长,价格也在不断下降。可我们不要忘记,需要处理的信息量更是呈指数级的增长。现在每人每天都会创造出大量数据(照片,视频,语音,文本等等)。日益先进的记录和存储手段使我们每个人的信息量都在爆炸式的增长。互联网的信息流量和日志容量也在飞快增长。在科学研究方面,随着研究手段的进步,数据量更是达到了前所未有的程度。无论是三维图形、海量数据处理、机器学习、语音识别,都需要极大的计算量。在网络时代,越来越多的挑战需要靠卓越的算法来解决。
再举另一个网络时代的例子。在互联网和手机搜索上,如果要找附近的咖啡店,那么搜索引擎该怎么处理这个请求呢?
最简单的办法就是把整个城市的咖啡馆都找出来,然后计算出它们的所在位置与你之间的距离,再进行排序,然后返回最近的结果。但该如何计算距离呢?图论里有不少算法可以解决这个问题。
这么做也许是最直观的,但绝对不是最迅速的。如果一个城市只有为数不多的咖啡馆,那这么做应该没什么问题,反正计算量不大。但如果一个城市里有很多咖啡馆,又有很多用户都需要类似的搜索,那么服务器所承受的压力就大多了。在这种情况下,我们该怎样优化算法呢?
首先,我们可以把整个城市的咖啡馆做一次“预处理”。比如,把一个城市分成若干个“格子(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里面的机器down掉一半,整个farm依然能够运行。正是因为这个天才的认识,才有了Map and Reduce算法。借助该算法,Google几乎能无限地增加计算量,与日新月异的互联网应用一同成长。

算法并不局限于计算机和网络

举一个计算机领域外的例子:在高能物理研究方面,很多实验每秒钟都产生几个TB的数据量。但因为处理能力和存储能力的不足,科学家不得不把绝大部分未经处理的数据丢弃掉。可大家要知道,新元素的信息很有可能就藏在我们来不及处理的数据里面。同样的,在其他任何领域里,算法都可以改变人类的生活。例如人类基因的研究,就可能因为算法而发明新的医疗方式。在国家安全领域,有效的算法可能避免下一个911的发生。在气象方面,算法可以更好地预测未来天灾的发生,以拯救生命。
所以,如果你把计算机的发展放到应用和数据飞速增长的大环境下,你一定会发现,算法的重要性不是在日益减小,而是在日益加强。

给程序员的七个建议

(1)练内功。不要只花功夫学习各种流行的编程语言和工具,以及某些公司招聘广告上要求的科目。要把数据结构、算法、数据库、操作系统原理、计算机体系结构、计算机网络,离散数学等基础课程学好。大家不妨试试高德纳所著The Art of Computer Programming里的题目,如果你能够解决其中的大部分题目,就说明你在算法方面有一定的功力了。
(2)多实战。通过编程的实战积累经验、巩固知识。很多中国大学毕业生缺乏编程和调试经验;学习C语言,考试过关就算学会了;课题项目中,只要程序能够编译,运行,并且输入输出满足要求就算了事。这些做法是不行的。写程序的时候,大家必须多想想如何把程序写得更加精炼、高效、高质量。建议大家争取在大学四年中积累编写十万行代码的经验。我们必须明白的是:好程序员是写出来的,不是学出来的。
(3)求实干。不要轻视任何实际工作,比如一些看似简单的编码或测试。要不懈追求对细节一丝不苟的实干作风与敬业精神。我发现不少程序员对于知识的掌握很肤浅,不求甚解,没有好奇心,不会刨根问底。比如,学会了C++,是否了解一个对象在编译后,在汇编代码中是如何被初始化的?这个对象的各个成员在内存中是如何存放的?当一个成员函数被调用时,编译器在汇编代码中加入了哪些额外的动作?虚函数的调用是如何实现的? 这些东西恐怕在编程语言或编译原理中都没有详细提到,只有通过踏实的实干才能真正掌握。
(4)重视数学学习。数学是思维的体操,数学无处不在。学计算机至少要学习离散数学、概率论、布尔代数、集合论和数理逻辑。这些知识并不难,但是对你未来的工作帮助会很大。 尤其当你对一些“数学密集型”的领域如视频、图像处理等有兴趣时,这些知识将成为你手中的利器。
(5)培养团队精神,学会与人合作。今天的软件工程早已经不是一个人可以单独操作的,而必须靠团队合作才能成功。不懂得合作的人是不能成大器的。大家要多去寻找可以与人一起做项目的机会。
(6)激励创新意识,培养好奇心,不要死记硬背。没有掌握某种算法技术的根本原理,就不会有应变和创新的能力。想成为一位好程序员(其实从事任何一个行业都是如此),重要的是要养成钻研,好奇,创新,动手,合作的优秀习惯,不满足于填鸭,不满足于考试交差,不满足于表象。这不是学几门课能够一蹴而就的。
(7)有策略地“打工”。在不影响学业的前提下,寻找真正有意义的暑期工作或兼职。去找一个重视技术的公司,在一个好的“老板”指导下完成真正会被用户使用的程序。不要急于去一个要你做“头”而独挡一面的地方,因为向别人学习才是你的目的。找工作也是一样,不要只看待遇和职衔,要挑一个你能够学习的环境,一个愿意培养员工的企业,一个重视你的专业的公司。最后,还要挑一个好老板。

希望大家都能把握机会,养成好的学习习惯,把算法学精学透;希望大家都能有一个美好的未来!

 

转自:

开复学生网

http://www.5xue.com/modules/kaifulee/view.article.php/21/c0

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8662854

/** * RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS. * LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables*/ /* var disqus_config = function () { this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable }; */ (function() { // DON'T EDIT BELOW THIS LINE var d = document, s = d.createElement('script'); s.src = 'https://chenzz.disqus.com/embed.js'; s.setAttribute('data-timestamp', +new Date()); (d.head || d.body).appendChild(s); })();