A Conversation

Kakurin: Pure C as opposed to C++. No idea why. Please don't talk about portability, it's BS.

Linus: YOU are full of bullshit. C++ is a horrible language. It's made more horrible by the fact that a lot of substandard programmers use it.


自我分析

昨日拜读陈皓先生的博客,仿佛被卡密尔精准礼仪般的真实伤害击中,让我在屏幕前陷入了长久的沉思。这不仅是对自己知识体系的反思,更像是一场自我认知的洗礼。感触颇多,一方面反思了自己的学习路径,另一方面也在思考未来的成长方向。

其中有一句话对我冲击最大,一针见血地让我意识到自己的愚蠢:

对于大多数自称熟悉C++的程序员来说,基本上他们都是用C++的语法在写C。

这句话精准地描述了我的现状——我写的代码,基本上只是用C++的 class 完成纯C也能实现的功能。我的所谓“封装”只是形式上的,远未真正理解并运用C++的精髓。C++之所以存在并流行,正是因为它能解决C不擅长的问题,而我却依然用C语言的思维去设计和实现,仅仅披上了一层面向对象的外衣。既然如此,为什么不直接用Python?它的开发效率更高、成本更低,而我的应用场景也并无严格的性能要求。过去我总以“通过这种过程可以熟练掌握语言”为借口,但事实上,不跳出舒适区就不会有提升。天天写这种“垃圾程序”有什么意义?美其名曰实践,实际上只是浪费时间,在重复自己会的东西,不敢迈出步伐去学习新知。这张图,这句话,无情地撕下了我用来搪塞自己的遮羞布。没有过硬的本领,又怎能在未来的竞争中立足?

事实上,社区中一直有“C++非常难学”的观点。过去我对这一点的理解非常表面,仅停留在“C++可以用来写游戏引擎、操作系统、高频交易系统”等模糊概念上,这种停留在表象的认知无疑是危险的。学会了类就以为自己学会了C++,多么愚蠢。没有时间根本不是借口,我每天浪费了太多时间在刷手机、做无意义的事情上。我应该静下心来读书,把手机和电脑都丢到十米之外,远离一切电子产品,沉淀下来去学习。或许,就从明天开始吧!

唉,要学的东西还有很多很多,长路漫漫。

想起陈浩先生博客中摘录的Chaucer所言:“The lyf so short, the craft so long to lerne.”(生命如此短暂,技艺如此漫长。)


观点摘录

none

程序员在一开始学习C++的时候,用C++的语法写C觉得很牛,也会觉得自己很快掌握了C++语言,对一切都充满了信心。他们告诉你他们懂C++,其它他们错误,但我们不能说他们在撒谎,因为人总是不知道自己不知道什么。此后,当他们在C++的学习历程中,发现了很多很多稀奇古怪的东西,还有很多相当底层和复杂的东西,他们的将会变得很受挫,很沮丧,还始变得怀疑起,自信心开始下降,甚至有时候他们靠人品来编程。只到有一天,开始开窃,觉得C++的世界不能乱来,需要一定的规则,一定的方法,于是通过大量的错误不停地总结和反省,最终自信心又会被建立起来,经历多年的历练后,才能恢复自信。

以下陈皓先生关于C++的学习建议:

C++是最难的语言。这个世界上最难的编程语言可能非C++莫属了。你千万不要以为几天就可以学好C++,C++的学习曲线是相当BT的,你可以看看这篇文章。C++是一门很自由的语言,自由到了有点BT和恐怖的地步。我甚至认为C++并不是一门成熟的编程语言,因为太容易犯错了。所以,你一定要在一开始就要有很小心谨慎的态度,并把C++当成一种难以训服的猛兽来看待。

多问“为什么要这样”的问题。学习C++一定要多问几个“为什么是这样”,“凭什么要这样”的问题。比如:很多人知道C++有拷贝构造函数和初始化列表,但你真的知道为什么要有拷贝构造函数?为什么要有初始化列表吗?为什么要有template,为什么要有RTTI,为什么不是别的呢?难道就是为了让一门语言变得Cool一些吗?完全不是这样的,C++中的任何一个feature都有些实实在在的原因,你一定要去了解为什么要把C++设计成这样的原因,你才能学好C++。有空看看《C++演化和设计》一书。

看书,大量的C++书。你可以按如下先后顺序阅读(下面这些书,我花了大约4-5年的时间,今天我还在随时温习)
《C++ Primer》,这本初级读本可能让会你啃得很痛苦,所有的语言的特性和为什么都在里面了,好好读读。当然由C++之父写的《C++程序设计语言》也不错。两本看一本就好了(我看的是前者)。
了解C++的语法仅仅是万里长征的第一步,你还需要看看《Effective C++》和《More Effective C++》这两本书并不厚,但我从02年就一直看到现在,每次读我都有新的体会,这两本书太经典了。如果你对C语言不熟,这两本书会让你回去补C语言的课。
Think in C++同样是另一本经典之极的书,学c++必读,但是中文版的翻译的很不好,所以还是去读英文版的吧。
《C++沉思录》同样非常值得一读,这里教的不是编程,而是思考的方法,这是相当珍贵的。
《Exceptional C++》和《More Exceptional C++》让你看看各种问题的解决方法和一些常见的经典错误。
《Advanced C++》和《Modern C++》可以让你知道C++各种神奇的用法。
《泛型编程与STL》是把C++实践到了极致的东西。很强大。STL——神一样的模板库(容器,算法和函数对象),不得不服。
《深入探索C++对象模型》让你了解编译器下的C++是什么样的,让你了解C++的性能并不差。这个对于C++的程序员太关键了。我以前写过的《C++虚函数表解析》还有《C++对象内存布局》属于这个范畴。

和Java语言做对比。我个人以为Java对C++这个并不成熟的语言做了很多调整,规范和限制。所以,对比一下Java和C++,想一想,为什么一些东西在C++中可以做,但在Java中却不行。比如:Java的异常是必需要catch的,不然就会编译不通过。为什么Java不提供操作符重载?为什么Java会引入接口来做多重继承?为什么Java没有像C++那样的I/O字符流?为什么Java不支持指针?为什么Java可以做到垃圾回收?等等。Java体现着很多面向对象设计的东西,学习Java有助于你学会怎么更好地使用C++来编程。

面向对象设计。虽然面向对象可能是个骗局。但是我觉得面向对象设计中的一些实践非常的不错,比如,单一原则,依赖倒置原则,等等,都非常地经典。《设计模式》必需一读,《面向对象的分析和设计》可以一读。但不可以设计模式为中心来编程,而应该是用设计模式来解藕。

类库学习。看看MFC是怎么封装Windows API的,看看ACE是怎么面向对象的,看看boost是怎么玩面向对象的,看看CPPUnit又是怎么设计的。当然,Java的JDK中有太多的设计模式,可以参考。

以下是陈皓先生的一些观点:

他们习惯于获取大量的知识,而从不对这些知识进行思考和总结。
没有思考过,就不算真正的懂,没有思考过,你将无法应对万变的问题,没有思考过,你将成为书呆子。
多多实践而不是研究。
我们的教育的确很“废柴”,但这不是我们成为“废柴”的原因。
我们身边有很多很多优秀的人,网上有很多优秀的文章,书店里也有很多不错的书,而且我们的软件开发日趋成熟,如果我们还学不好的话,那么我们就是在犯罪!

陈皓先生已于2023年5月离世,向他致敬。


TODO

Shit, here we go again. - Carl Jason
既然我只是在用C++的语法写C,那么我就再次从C语言出发吧。学习任何东西给我的感觉都是常看常新,学海无涯。There is always more to learn.
书单(暂时先把这些看完吧):
[ ] 《The C Programming Language》
[ ] 《Algorithms in C》
[ ] 《算法导论》
[ ] 《C++ Primer》
[ ] 《Effective C++》
[ ] 《More Effective C++》