guodongxiaren/Blog

也谈C++:重剑无锋,大巧不工

Opened this issue · 0 comments

也谈C++:重剑无锋,大巧不工

我向来观点编程语言没有银弹,要懂得因地制宜,随机应变。但作为编程语言的使用者(程序员)是有个人偏好的,偏爱哪个自然也无关乎对错。

据我感觉至少80%的C++程序员不是为了找工作才学的C++,因为学习C++对很多人来说ROI难成正比。论就业,Java的市场需求肯定比C++的多。论学习速度,Go学习没多久,就能手撸一个性能还不错的网络库。而C++呢?学习时间长,旧语法还没精通,新语法又开始层出不穷。并且还有各种安全隐患,程序员一不小心就会踩坑。你以为我要劝退了?不是。毕竟我也是C++程序员啊。虽然我不劝进,但还是想和你聊一聊我与C++的故事以及我的观点。


我个人大学时期的编程语言学习经历是这样的:

C -> C++ -> Java -> C++ -> C -> C++
刚上大学,课本里学的第一门编程语言就是C语言,本来我也没太感冒,后来我对刷题产生了兴趣,就用C语言在hduoj刷了很多题。这期间编程的基本功力大涨。后来感觉刷题的边际效益比较低了,因为我们学校也没有acm集训队什么的,自己好几天研究一道题太不值当的,容易走火入魔。然后就学C++,看了面向对象的部分,学语法倒也不难,只是没找到感觉。每天对着黑黑的控制台程序没意思,当时移动开发特别火,我就自学安卓编程了,这时候主要是用Java,学习安卓的过程之中,我突然对面向对象理解更深刻了,然后回过头去看C++,感觉通畅了很多(好像学习C++都需要其他语言辅助……)。

这时候我突然想做点桌面端GUI的东西,Java的桌面太丑了,MFC的语法太烂,我就学习了一下QT。哇,开始叹服C++也可以这么优雅。但是后来,不管是我学习安卓开发还有QT开发,感觉很多时候都是在搭积木,遇到了不知道怎么实现的问题,百度一下就能找到答案,然后照(拷)猫(贝)画(粘)虎(贴)就能做出来。时间久了我心里总感觉哪里不对,那就是太空中楼阁了。这和内心的声音相去甚远,我想更多的了解一下底层,了解一下原理,而不是搭积木这般。然后我就又开始学C了,开始学Unix C编程,逐步逐步地了解操作系统,了解内存,了解网络,去探寻我心中的真相。

当然也仅仅是了解,只是比之前深刻些了。然后再翻看专业课的课本,不同课程的知识和自己自学的串联起来了,豁然开朗,心中暗爽。学计算机不再像是集邮一样,把知识概念一件一件纳入进自己脑袋,而是发现知识本身可以有很多关联,自己揉搓在一起会产生奇妙的化学反应。

这个过程下来,颇有古人说人生三种境界的感觉:

看山是山,看水是水;
看山不是山,看水不是水;
看山还是山,看水还是水

看到这,你可能会觉得落脚点怎么到C了。不是说C++么?你喜欢C,那你选择C就好啦。

我想说:谈C++,谈C是绕不开的话题。C++对C的兼容是C++的包袱,但也是C++的亮点。我可以在C++中无缝地使用C的**,去直面内存,直面OS,直面网络。不需要借助虚拟机或者解释器什么的。并且在这基础之上,我还能享受到一些高层语言的便利。

再谈回C++本身。在对C慢慢了解深入以后,我对C++的学习也重新开始了。像另一位答主所言,C++真的是给人一种造物主的感觉。我在大学时候说过类似的话,我说:C++给我一种上帝般的快感。比如别名、运算符重载,在Java中就见不到(当然python中也有),这给我以极大的舒适。除此之外你还能“自定义”关键字,比如QT中的Q_OBJECT(当然,这其实是一个宏)。各种编程范式,你想用那种就用哪种(当然,这可能也是被诟病的地方),面向过程、面向对象、函数式。平心而论,C++也并不是无所不包,比如就没有反射(虽然自己也可以手撸一个类似的),没有热加载(也可以用dlopen搞个类似的)。

除此之外呢?模板元编程。这个是一种非C++作者或者官方设计的,而是从C++模板语法中衍生的”,由于C++模板自己图灵完备,所以说其是另一门编程语言也毫不为过。然而这个玩法是“民间”发掘出来的(当然后来的C++11等标准在官方层面也给了元编程更多支持,这是后话了)。你还能不感觉自己是上帝么?

虽然我选择了C++,但是C++博大精深,并且新标准也在不停扩充,我感觉想精通是不可能了,这辈子都不可能了,要一直学习下去,虽然很多语法特性在工作中是用(不)不(让)到(用)的。但是这就是我们学习C++的乐趣吧。学Java的话,学完语言,就要学各种框架了,学习如何花式写XML。学Go的话,学完Go是不是就要学Rust了,学完Rust呢?当然我也不是在鼓吹C++啦,我讲的只是个人的感受。比如夏天的时候,别人都喜欢吃西瓜,但我不爱吃西瓜,也不能说我有问题是不?每个人都有自己的爱好。有些人就喜欢精通各种语言,在简历上写一长串,这样没有什么问题。请允许我自由地表达自己的观点。

又说了这么多,好像还没点题。

当年杨过断臂之后,偶遇大雕,邂逅剑魔独孤求败埋剑之剑冢。剑冢有四:

第一柄剑长四尺,锋利无比,剑下石片下写着:「凌厉刚猛,无坚不摧,弱冠前以之与河朔群雄争锋。」
第二片石片上没有剑,下面写着:「紫薇软剑,三十岁前所用,误伤义士不祥,悔恨无已,乃弃之深谷。」
剑魔独孤求败的第三把武器:「重剑无锋,大巧不工。四十岁前恃之横行天下。」外表黑黝,剑身深黑之中隐隐透出红光,三尺多长,共重八八六十四斤,两边剑锋都是钝口,剑尖圆圆的似是个半球。
第四个阶段才是渐入化境,第四柄木剑,石片上文字道:「四十岁之后不滞于物,草木竹石均可为剑。自此精进,渐入无剑胜有剑之境。」

从一到四,并非是剑本身优劣从低到高,紫薇软剑未必胜过四尺长剑,同样玄铁重剑也未必会比紫薇软剑更能克敌机先,而第四柄木剑可谓四剑中最弱的。但是四柄剑依次排开,金庸老先生所要展示的并非是剑本身之优劣,而是展示持剑人(也就是独孤求败)自身武功修为之变化。杨过虽然有此奇遇,但并没有得到武功秘籍,只是拿走玄铁重剑。然而后来横行江湖,被称为神雕大侠之时,仪仗的却又并非此剑,而是自创的黯然销魂掌。最终玄铁重剑直接送给郭靖夫妇,被融化成屠龙刀倚天剑了。对他而言,并不可惜,因为彼时,他已然达到独孤求败的第四境界。

编程语言亦是如此,不同的编程语言,只是不同风格,不同特质的剑而已。初学者或者有经验的程序员们,常在剑冢流连忘返,而忽略了自身修为的提高。在我看来C++就是玄铁重剑,所谓重剑无锋,大巧不工。重剑无锋,是说剑刃是钝口,而且剑尖都没有(只是一个半球)。大巧不工,是说这柄剑并没有经过工匠的精心雕琢。这种剑本身杀伤力并不大,而且又因为是重剑,操作难度极大。但是如果你能熟练地挥舞玄铁重剑,那么你自身的内(编)功(程)修为也会逐渐臻至化境,以致于后期能达到『不滞于物,草木竹石均可为剑』的境界,什么编程语言都可以快速掌握,各种逻辑抽象,编程范式都可以轻松应对。
image


有趣的是,回看独孤求败给四柄剑留的字:三十岁前、四十岁前、四十岁后……这生命历程像极了程序员呢。希望我们能干到四十岁后把!

另外我真不是无脑吹C++的,Python也是一门很优秀的语言呢。不、不、不,我不能这么说话。Java和Go也都是很优秀的语言呢。

PHP:你怎么这次不cue我了。

我认为学习什么语言这并不冲突。喜欢哪个就去学习就好了,谁都不会限制你只学一门啊。当然要是说工作语言的话,那就要再综合考虑了。程序员毕竟是要恰饭的,但如果工作中常用的语言恰好是自己喜欢的,那么就好像你喜欢一个妹子,而她也恰好喜欢你。尽管要达到这种完美,可能要花费十六年。