标签(空格分隔): 三省吾身


原文地址:你应当如何学习C++(以及编程)

  本人反思自己这些年在学校学得稀里糊涂半灌水。看到这篇文章,感觉收获不少。仿佛有指明自己道路的感觉,当然真正困难的还是坚持学习,多动手实践。
  但是这篇文章确实对于纠结知识细节还是看抽象理论给出了指导意义。麻省理工大学的《计算机科学及编程导论》课程上,Eric Grimson开篇就说到这本课不仅教授如何编程让电脑做一些事情,而是面对问题的时候思考,如何用算法或机器语言来描述这个问题,然后让电脑来替我们解决这个问题。以下是原文。

  This course is going to be not just about teaching you how to program a computer, how to tell the computer instructions that it can understand. It’s also going to be really important to create within you a capability to think computationally. So our goal is to let you become skillful at not only getting the computer to do something, but to do that thing that you want it to, to get it to solve a problem. By the end of this course, we hope that your first instinct when faced with any interesting challenge is to first think about how could I capture that challenge, that problem in an algorithmic or mechanical description of steps such that I could get the computer to do the work for me. If you can do that, it’s going to give you a great deal of advantage as you face any kind of problem. And those are the skills that you’re going to see throughout this course.

以下是原文摘抄和自己的理解:

1. C++中众多的细节虽然在库设计者手里面有其用武之地,但普通程序员则根本无需过多关注,尤其是没有实际动机的关注。一般性的编码实践准则,以及基本的编程能力和基本功,乃至基本的程序设计理论以及算法设计。才是真正需要花时间掌握的东西。

链接中的几本书,
1.《代码大全》:云风的 blog《代码大全》读书笔记
2. CSAPP 《深入理解计算机系统》
这是 CMU 的“计算机科学导论”的教材。是计算机系统和操作系统入门。
3. SICP 《计算机程序的构造和解释》
这是 MIT 的6.001课程的教材。是编程语言入门。(这门课在好几年前就改成Python了)
4. CLRS 《算法导论》
这是 MIT 的6.006课程的教材。是算法分析入门。
后面三本书知乎上有讨论。

2. 避免去过问任何语言细节,除非必要。这个必要是指在实际编程当中遇到问题,这样就算需要过问细节,也是最省事的,懒惰者原则嘛。一个掌握了基本的编程理念并有较强学习能力的程序员在用一门陌生的语言编程时就算拿着那本语言的圣经从索引翻起也可以编出合格的程序来。十年学会编程不是指对每门语言都得十年,那一辈子才能学几门语言哪,如果按字母顺序学的话一辈子都别指望学到Ruby了;十年学习编程更不是指先把语言特性从粗到细全都吃透才敢下手编程,在实践中提高才是最重要的。

我的理解:语言细节也是重要的,不熟悉一门语言但也必须对其中原理掌握的很透彻,不然真正用起来的时候,很可能根本不知道要用到什么细节。对于细节的不理解,你也不知道哪个是有用的,哪个无用的,无从下手。翻过了,怎么才能对其中的原理掌握透彻呢?往往也是从一门语言开始学起。对于一般人来说,不深入具体细节,也很难理解抽象。所有往往第一门语言比较难学,之后会轻松很多。

3. 然而真正的编程能力是与语言细节没关系的,熟练运用一门语言能够帮你最佳表达你的意图,但熟练运用一门语言绝不意味着要把它的边边角角全都记住。懂得一些常识,有了编程的基本直觉,遇到一些细节错误的时候再去查书,是最节省时间的办法。

4. C++的书,Bjarne的圣经《The C++ Programming Language》是高屋建瓴的。《大规模C++程序设计》是挺务实的。《Accelerated C++》是最佳入门的。《C++ Templates》是仅作参考的。《C++ Template Metaprogramming》是精力过剩者可以玩一玩的,普通程序员碰都别碰的。《ISO.IEC C++ Standard 14882》不是拿来读的。Bjarne最近在做C++的教育,新书是绝对可以期待的。

5. P.S. 关于如何学习编程,g9的blog上有许多精彩的文章:这里,这里,这里,这里… 实际上,我建议你去把g9老大的blog翻个底朝天 :P

g9老大,他的博客

6. 实际上,正确的态度是,细节是必要的。但细节是次要的。其实学习编程我觉得应该最先学习如何用伪码表达思想呢,君不见《Introduction to Algorithm》里面的代码?《TAOCP》中的代码?哦,对了它们是自己建立的语言,但这种仅教学目的的语言的目的就是为了避免让写程序的人一开始就忘了写程序是为了完成功能,以为写程序就是和语言细节作斗争了。Bjarne说程序的正确性最重要,boost的编码标准里面也将正确性列在性能前面。

7. 重要的不是你掌握的语言,而是你掌握的能力,借用myan老大的话,“重要的是这个磨练过程,而不是结果,要的是你粗壮的腿,而不是你身上背的那袋盐巴。”。此外学习C++的意义其实真的是醉翁之意不在酒,像C/C++这种系统级语言,在学习的过程中必须要涉及到一些底层知识,如内存管理、编译连接系统、汇编语言、硬件体系结构等等等等知识(注意,这不包括过分犄角旮旯的语言枝节)。这些东西也就是所谓的内功了(其实最最重要的内功还是长期学习所磨练出来的自学能力)。对此大嘴Joel在《Joel On Software》里面提到的漏洞抽象定律阐述得就非常漂亮。

我的理解:这种能力应该就是对编程本质的理解。所谓看山是山,看山不是山吧。以前看到一个东西,知道它能用到哪里,一开始有点死记硬背。后来明白这是什么,为什么需要这样,什么情况和它实际是一样的,有了类比联想。但是现在自己不管内功外功都太差,都需要功夫。

8. 让你成为高手的并不是你掌握什么语言,精通C++未必就能让你成为高手,不精通C++也未必就能让你成为低手。我想大家都不会怀疑g9老大如果要抄起C++做一个项目的话会比大多数自认熟练C++的人要做得漂亮。所以关键的不是语言这个表层的东西,而是底下的本质矛盾。当然,不是说那就什么语言都不要学了,按照一种曹操的逻辑,“天下语言,唯imperative与declarative耳”。C++是前者里面最复杂的一种,支持最广泛的编程范式。借用当初数学系入学大会上一个老师的话,“你数学都学了,还有什么不能学的呢?”。学语言是一个途径,如果你把它用来磨练自己,可以。如果你把它用来作为学习系统底层知识的钥匙,可以。如果你把它用来作为学习如何编写优秀的代码,如何组织大型的程序,如何进行抽象设计,可以。如果掉书袋,光啃细节,我认为不可以(除非你必须要用到细节,像boost库的coder们)。

我的理解:可能是武侠小说看多了,我之前容易有的误解就是内功有了,什么外功都会。这仿佛一看是正确的,但其实在实际学习中,我们所谓的外功往往也是促进我们内功的修炼的。这两者应该是相辅相成相互促进的。过多的强调某一面都会片面。
没有对细节的挖掘,我们很难理解抽象的理论。不注重对抽象理解的认识和思考,我们又会陷入无休无止的细节中,长进缓慢。

精彩评论:

2楼 pongba 2007-05-16 15:30发表 [回复]

HumanChao wrote:

这么好的帖子怎么没人支持一下呢.我感觉那本《高质量C++编程指南》道是挺实在,只有100页,用点心2个小时就可以读完。公司每进一名新员工我都会介绍此书。

《高》是一本有用的书,我也读过。但不应该用来影响初学者的编程哲学。许多人读《高》这样的书都容易形成一种感觉,就是细节非常重要。
实际上,正确的态度是,细节是必要的。但细节是次要的。

12楼 g9yuayon 2007-05-16 22:05发表 [回复] [引用] [举报]

这篇写得真不错。收藏了。Damien Katz重写Notes公式引擎的前还不懂C++, 读了一半《C++ Programming Language》就后就上手了。鲍岳桥他们开发联众前也不懂Win32,但还是一边查手册一边把联众开发出来。那是可还不能用Google满世界找资料。

13楼 myan 2007-05-16 22:08发表 [回复] [引用] [举报]

我想每一个曾经深入研究那些细节的人,或迟或早都还是会走出来的。2000年我开始研究STL,后来到Loki,再后来一点点Boost,也曾经以为细节掌握越多、语法规则运用越熟练、奇思妙想越多,就是水平越高。当年曾经跟一个朋友在论坛里斗编程,他写一个Python程序,我写一个C++程序,看谁简洁。写实际产品的时候,不用上STL、Design Patterns就亏心得睡不着觉。我把boost::mempool/smart pointer给剖离出来,移植在Windows CE 3.0平台上。当时的eVC3仅具有初步的模板支持能力,要做大量的代码修改剪裁工作。后来的结果是,内存分配比WinCE CRT的malloc加速85倍,当时高兴的不得了。那种感觉,今天回想起来恍如隔世。
可是到了03年初,就已经发现这个路子有问题。程序毕竟是以用为本,而真正有用的程序,反而在编码上往往是质朴的,强在对领域知识的理解和创新上,对用户需求的把握和体现上。从那时开始,我的思想发生了一个痛苦的嬗变。在认识到自己过去所想有问题的同时,也进入了一种迷茫状态,丧失了对一切语言和技术细节的学习兴趣。什么.NET,Java,POSIX,Compiler, Web,SOA,好玩的东西就那么一小撮,大部分细节是索然无味的,甚至面目可憎。这个状态持续了将近两年,才随着对Python、Ruby的了解而逐渐过去。
现在回过头来反思,当年拼命研究那些细节,固然是进入误区,但是何尝又不是一段历练。现在C++社群的大牛们纷纷提出要改造C++教学路径,这个我当然是支持了。现在的C++学习者可以不用绕弯路,可以直接用那些高层抽象工具解决问题,不用再苦苦理解什么函数重载决议的规则,不用为内存的高效利用而发愁,对于做具体项目来说当然幸福,但是对他们的技术成长就一定是好事吗?恐怕也未必。少了一份磨难,也就少了一份成熟。
所以我觉得,多绕点弯路其实没关系,力气还是长在了自己身上。关键还是要踏踏实实下功夫搞。如果让我回答“应当如何学习C++”这个问题,我只有一句话可说,那就是:“下足功夫”。

14楼 pongba 2007-05-16 22:23发表 [回复] [引用] [举报]

myan老大提到:

所以我觉得,多绕点弯路其实没关系,力气还是长在了自己身上。关键还是要踏踏实实下功夫搞。如果让我回答“应当如何学习C++”这个问题,我只有一句话可说,那就是:“下足功夫”。

myan老大所说的下足工夫当然是无可厚非的。做任何事都是这样,不下足工夫不可能认识到一些东西。
但真正的问题是工夫是花在刀刃上还是刀背上。是下足工夫做语言律师还是下足工夫搞实践。
时间只有一份。对于中国的学生,尤其如此。C++的细节庞杂无比,C++的书籍满天飞,光是下足功夫学习语言核心都不知道要多久。由于时间只有一份,所以就没时间去学习更重要的编程基本功、解决实际问题的能力、算法,等等。后者同样可以达到锻炼乃至是更强的锻炼。所以,光是要下足功夫其实是避开了真正的问题。
我自己也经历了myan老大的这个过程。我的看法跟myan不一样。我认为时间是宝贵的,所以工夫自然要下,但真正的问题是,往什么地方下。
g9老大提到:

Damien Katz重写Notes公式引擎的前还不懂C++, 读了一半《C++ Programming Language》就后就上手了。鲍岳桥他们开发联众前也不懂Win32,但还是一边查手册一边把联众开发出来。那是可还不能用Google满世界找资料。

这种下功夫的方式我非常认同。窃以为这才是真正pragmatic的方式,一来用实践驱动学习有干劲,而来不容易堕入为学习而学习从而迷失的地步,三来这非常锻炼人解决实际问题的能力。四来这样的学习是最“经济”,效率最高的。

24楼 myan 2007-05-17 09:57发表 [回复]

to pongba:
你的基本观点我当然是赞同,相信每个从细节走出来的人都会赞同。问题在于对于初学者(当然主要是学生),怎么走合适。你说:“时间只有一份。对于中国的学生,尤其如此。”
事实上,任何工作了几年的人都能感觉到,学生阶段是最有时间的,工作了以后就没时间了。所以如果要走弯路,要琢磨一点语言细节,要做一点吃饱了撑的事情,练一点内功,最好在学生阶段走。当然,你觉得,如果在学生阶段都不走弯路,那岂不是更好?看上去当然更好,但是走弯路是不是真的可以避免,那条路是不是弯路,你指的路是不是就那么直,不那么好说的。特别是在你人生不同的阶段,你会对自己的过去有不同的看法和评价。我的观点就是,总体上讲,弯路是不可避免的,走弯路也不全是坏事,甚至在年轻的时候多走弯路,可能是太好太好的事情了。你以为的直路,说不定到头来是更大的弯路。人生的事情很难说清楚,最不用后悔的是受磨砺,最不用担心的是没机会。
至于那条“直路”,对于学生来说还挺令人向往的,可等到工作阶段,你立刻就能体会到是个什么感觉了。每天都被任务驱动着,根本不用自己费力去找“pragmatic”方式,每天都是街头喋血,连回去练练扎马步、丹田气的机会不多。到时候别说语言细节,就是一些必要的应用数学、算法理论之类的东西,也只能见缝插针学一点,囫囵吞枣,解决问题就好。实际上未鹏你是中国学生里的一个异数,你在学生阶段踏踏实实搞了一些“语言律师”的东西,因此现在有所反思,觉得自己应该早点街头肉搏,而且现在你去街头肉搏,最多已开始有点不适应,一旦适应之后,你就够厉害,因为你内功厚。但是大多数学生,他们一开始的学习方式就是你所倡导的“pragmatic”街头喋血。但是他们的结果,不是写出Notes规则引擎,不是开发出联众,而是搞了多年ASP,不知道HTTP原理;学了三年.NET,但就是理解不了异步编程模型,一碰到BeginInvoke就发怵;写了两年MFC程序,不理解Windows事件模型,一遇到问题就只能抓瞎。我这些说法都不是凭空说的,背后都有我身边的实际例子。如果你把视野放的足够大,你就会认识到,中国的学生不是太务虚,而是太务实,不是太不实用主义,而是太实用主义了。所以我觉得你的这个呼吁,对于一小部分人来说是合适的,对于绝大多数人来说是不适用的。
当然,工作当中需要了解的细节也是有的,比如做国际化的人,需要对字符编码的问题滚瓜烂熟,搞Windows向Linux移植的人,需要对Windows内部钩子的实现、Linux/X系统内部事件机制了然于心;搞WinCE开发,需要对微软ActiveSync的一些编程接口非常熟练。这些细节,或者说特定领域的知识技术,没有具体的应用背景和支撑环境,是不可能学进去的。因此现在大公司招高校毕业生,普遍比较理性,知道学生没有那个环境和条件搞pragmatic,一般都是不要求的。就看你基础打得扎实不扎实,有没有钻研精神。重要的是这个磨练过程,而不是结果,要的是你粗壮的腿,而不是你身上背的那袋盐巴。
我曾经问过一个美国大学的教授,是一项国际大学生编程大赛的主席,那些编程大赛的题目究竟对实际软件开发有什么用?他说,其实他们也知道不太有用,但是第一只有这个形式的东西搞比赛容易操作,真正有用的东西没法比赛,第二,重要的是选手参与这个比赛的过程,要想取得最好的成绩,往往要花几年时间,做几千题,几千道跟实际软件开发没太多关系的题。最后证明,在这个大赛中取得好成绩的,以后在工作中大多数也能取得好成绩。你说这个弯子绕的大不大,这个时间花得冤不冤?
最后,其实这些话是写给你的,也是写给我自己的。10年前的这个时候,正好是我已经熟练掌握了C,开始雄心勃勃地向C++主峰发起进攻的时候。今天如果能够让我年轻10岁,回到大学里重新选择,我可能不会选择深入研究C++,而是把C学透了,就去研究OS、Compiler、TCP/IP。但是当年我看不到这些,只能看到C++。我后悔吗?不太后悔。人只能在一种局限性与另一种局限性之中选择,走了那条路,今天就会后悔别的事情。如今我对IT这个产业链有所了解之后,更觉得世界之大,岂是一人一时所能逆料。所以全局最优是可望不可及的,个人所能做的,只是追求局部最优而已,然后让命运的大浪把你送上高峰或者拍入深渊。比如,你以为出国读书,一定是好?你以为被一流大公司高薪聘请,一定是妙?你以为你在学生阶段写出一个软件,搞得天下闻名,万人敬仰,就一定有好结局?真的不一定啊。但是不一定,是不是我们就可以吊儿郎当,游手好闲?当然不是。全局最优不可期盼,但局部最优一定要努力争取,要按照自己定的路线去踏踏实实的努力,取得尽可能好的成果。所以,你要想做个好的语言律师,就踏踏实实下功夫去做吧,没什么不对的。还是那句话,下足功夫,练出一副好身板,比什么都重要。如果说后悔,我从不后悔技术路线的选择,只是后悔那时候下得功夫还是不够,还是拿出太多的时间去看电视,吃烧烤了。

34楼 YYLFYY 2007-05-17 21:34发表 [回复]

个人觉得myan老大和pongba老大说的都是正确的,外功与内功,知识和技能,本来就是见仁见智的问题(有些像前段时间金旭亮老师和yuanfeng老大的观点)
我个人很喜欢往细节底层里钻,喜欢《C++ Primer》,喜欢看Lippman把深藏在水下的东西都翻出来展示给大家看,也非常的固执的认为,没有掌握OS和Win32之前,绝对不要碰VC或者BC。
有时间也很迷茫,因为学了那么久,现在也不能写个像样的东西出来。pongba老大说的细节问题反应在论坛上,myan老大说的务实问题反应在学校里,的确是这样。
学校里,没有人会在乎你懂得重载函数的解析过程,或者是说清楚指向函数指针数组的指针这些杂七杂八的东西。“什么?你用Dephi做了一个航空管理系统!”“这个在线答题系统是你用Java设计的?!牛!”通常是这么回事。一方面,企业对于项目经验的要求;另一方面,是学生自己“学以致用”的思想,两者结合,就出现了myan老大说的那种“中国的学生不是太务虚,而是太务实”的观点。是啊,学了没有用的东西,谁会去学。“学OS能写操作系统吗?”“学编译能写Complier吗?”不能,所以还不如学学如何在C++ Builder中拖放控件做个画图程序更有用。
论坛上就不同了,高手低手汇聚一堂,能写航空管理系统算啥,能写虚拟机的人都多得数不过来。当然,能说清楚类模板的名字解析的人就很少了。能开发项目,能写底层,但要是给一张大学C++试卷,能难说能不能及格。细节出于此,在网络上,大家都喜欢把语言的底层机制翻来覆去的玩耍。
我想myan老大考虑的是,工作后不像在大学里,有足够的时间能系统的学习细节和底层,所以偏重于强调大学期间修炼内功。pongba老大从C++学习来分析程序设计的学习之路,强调不要死抠细节,毕竟编程不是单纯的语言控制。两位老大都说得在理。

读刘未鹏老大《你应当如何学习C++(以及编程)》相关推荐

  1. 读刘未鹏老大《你应当怎样学习C++(以及编程)》

    标签(空格分隔): 三省吾身 原文地址:你应当怎样学习C++(以及编程) 本人反思自己这些年在学校学得稀里糊涂半灌水. 看到这篇文章,感觉收获不少.仿佛有指明自己道路的感觉,当然真正困难的还是坚持学习 ...

  2. 读刘未鹏《暗时间》的总结和思考

    请访问我的个人博客:www.lijinma.com 花了两个晚上读完了刘未鹏的暗时间,心中窃喜.今天再次翻看这本书进行浏览总结并思考,通过这本书我到底学到了什么? 1. 为什么人人都应该学点心理学? ...

  3. 读刘未鹏《暗时间》有感

    我写技术文章也好,还是写这种读后感也好,一向倾向于趁热打铁,因为很多东西还鲜活的在脑子里,最近一段时间都在找工作,一直很焦虑,所以断了这么久,现在因为这个情况,也不敢出去,沉淀了几个星期,就找了一本很 ...

  4. 读刘未鹏博客反思和总结(看书,思考,写博文)

    今天晚上把刘未鹏大牛的博客好好的翻了翻,对自己以后看书,学习的方式做个总结,本文并无新颖的观点,内容均来自刘未鹏大牛的博客,各位看官如果对此文观点有兴趣, 文章末尾有传送门.毕竟原汁原味的才好看嘛! ...

  5. 读刘未鹏师兄的大学时光有感

    仔细读了这篇文章,我的第一感觉就是,我的本科和研究生生活就像是一个肥皂泡时间,表面看起来是非常光鲜,该经历的统统经历一遍,但是和师兄的生活比起来,还是显得内劲不足,极不充实.如果早些看见这篇文章可能会 ...

  6. 【如何学习】 -- 读刘未鹏《暗时间》有感

    记录是为了更好的成长,分享从书中学到的精华, 可能每一条都需要我们花上很多时间和精力去学习,不要着急,慢慢靠拢,每天都是更好的你~ 1.从各种抽象层面去掌握知识 2.努力掌握知识最深刻和本质的东西 3 ...

  7. 【转载】刘未鹏的C++学习历程 + 小诗一首

    在上大学以前我从未涉及过编程这一领域,倒是对电脑比较感兴趣,这里所说的"电脑"是指粗浅的应用,我会为了从某一本杂志上看到了一则修改注册表的技巧而兴奋不已,然后回家赶紧尝试,却不名就 ...

  8. 刘未鹏:为什么你应该(从现在开始就)写博客

    今天转载一篇刘未鹏10多年前的一篇博客<为什么你应该(从现在开始就)写博客>,我觉得总结的非常好,上大学的时候我就看过了,因为这篇博客所以我从13年开始坚持写博客.刘未鹏最近博客也不更了, ...

  9. 程序员中"5%神话";刘未鹏:为什么你应该写博客

    程序员中"5%神话":刘未鹏:为什么你应该写博客 http://timyang.net/programming/mythical-5/ Bruce Eckel(Thinking in Java/C++ ...

最新文章

  1. 用python生成词云wordcloud
  2. imp导入时触发器的状态
  3. leetcode 203 移除链表元素 C++
  4. zendstudio快捷键收录
  5. 出错提示:“Could not flush the DNS Resolver Cache: 执行期间,函数出了问题”的解决方法...
  6. php异步通知并查询,服务器异步通知的接收by php
  7. python dateutil_安装python dateutil
  8. 使用ASP.NET快速开发平台,获得表单源码,用珍藏资料换来的代码生成器!
  9. 极路由2hc5761刷华硕固件_[固件] 【原创首发】极二路由HC5761 9012.1.9227s成功刷成openwrt...
  10. 微分方程中解、特解、通解的区别
  11. python依赖库是什么_【转】python导出依赖库
  12. python flag用法_Python之FLAGS用法
  13. 【论文笔记--FORCE】Progressive Skeletonization: Trimming more fat from a networkat initialization
  14. 面向初学者的 Python IDE:Thonny,你值得一试
  15. 流媒体技术笔记(视频编码相关)
  16. 儿童学计算机编程好处,儿童编程课学了有好处吗?4大优势家长要知道
  17. Android使用drawBitmapMesh方法实现旗帜飞扬,舞动的图片效果
  18. 药家鑫案二审驳回上诉 维持一审死刑判决,
  19. amesim安装失败_AMESim 安装后,编译时提示找不到可执行文件
  20. 西门子s1200教程_如何进行西门子的S-1200的S7单边通讯图文详解

热门文章

  1. IP代理池proxy,自建,免费,详细教程
  2. switch语句及三种循环语句
  3. Android 入门第二讲03-约束布局ConstraintLayout(可视化介绍,Chains链,MATCH_CONSTRAIN,百分比布局,圆形定位,Guideline,Barrier)
  4. 最全总结 | Android 系统抓包喂饭教程!
  5. c语言编程led数码管,数码管显示函数
  6. vue+element封装一个填写和校验ip地址的组件
  7. 《微机原理》期末考试计算题例题含答案
  8. (转载)云计算系统测试
  9. 区块链数据共享论文阅读
  10. 解决 fatal: unable to access ‘https://github.com/qweertu/git-demo.git/‘: error setting certificate...