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

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


原文地址:你应当怎样学习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们)。

我的理解:可能是武侠小说看多了。我之前easy有的误解就是内功有了,什么外功都会。这仿佛一看是正确的,但事实上在实际学习中,我们所谓的外功往往也是促进我们内功的修炼的。

这两者应该是相辅相成相互促进的。

过多的强调某一面都会片面。


没有对细节的挖掘。我们非常难理解抽象的理论。不注重对抽象理解的认识和思考,我们又会陷入无休无止的细节中,长进缓慢。

精彩评论:

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

HumanChao wrote:

这么好的帖子怎么没人支持一下呢.我感觉那本《高质量C++编程指南》道是挺实在。仅仅有100页,用点心2个小时就能够读完。

公司每进一名新员工我都会介绍此书。

《高》是一本实用的书,我也读过。

但不应该用来影响刚開始学习的人的编程哲学。很多人读《高》这样的书都easy形成一种感觉,就是细节非常重要。
实际上,正确的态度是。细节是必要的。但细节是次要的。

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的方式,一来用实践驱动学习有干劲。而来不easy堕入为学习而学习从而迷失的地步,三来这非常锻炼人解决实际问题的能力。四来这样的学习是最“经济”,效率最高的。

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。一般都是不要求的。就看你基础打得扎实不扎实,有没有钻研精神。重要的是这个磨练过程。而不是结果,要的是你粗壮的腿,而不是你身上背的那袋盐巴。
我以前问过一个美国大学的教授,是一项国际大学生编程大赛的主席,那些编程大赛的题目到底对实际软件开发有什么用?他说,事实上他们也知道不太实用,可是第一仅仅有这个形式的东西搞比赛easy操作。真正实用的东西没法比赛,第二。重要的是选手參与这个比赛的过程,要想取得最好的成绩。往往要花几年时间,做几千题,几千道跟实际软件开发没太多关系的题。

最后证明,在这个大赛中取得好成绩的,以后在工作中大多数也能取得好成绩。你说这个弯子绕的大不大,这个时间花得冤不冤?
最后。事实上这些话是写给你的。也是写给我自己的。

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++学习来分析程序设计的学习之路,强调不要死抠细节。毕竟编程不是单纯的语言控制。

两位老大都说得在理。

posted @ 2017-07-28 16:20  brucemengbm  阅读(422)  评论(0编辑  收藏  举报