成为优秀的程序员(01):理解“不理解”
如果需要查看系列中的其它文章,请使用 tag 跳转到文章目录界面:#becoming-an-brilliant-programmer。
没错,我又要开新的坑了。
想想从 2013 年前开始工作,到现在已经有 11 个年头,年假也终于到了 10 天,可喜可贺可喜可贺。
这 11 个年头里,自己算是踩了不少坑。回想起当年,经常会遇到各种迷茫的时刻:为什么我做不好?我到底是强还是弱?所谓的“职业发展规划”到底是什么?等等诸如此类的问题随着各种各样在象牙塔中未曾想象过的变化一起,接踵而至。
而当我试图去模仿那些“成功”的人时,我会发现他们的所谓成功经历根本无法套用在自己身上,从而陷入越来越深的自我怀疑:是不是我自己真的太菜了,所以才不能像他们一样?
直至今日,我依旧觉得这些“成功”是无法复制的。值得欣慰的是,在我自己越来越少地被称作“小朋友”的同时,我也看到小朋友们对这一点的理解越来越深。
同样,我也不认为我的这一系列文章真的能帮助所有人成为优秀的程序员,这只不过是一个噱头罢了。或者再进一步,我这种没人看的博客甚至也不需要什么噱头,这只是因为文章必须要有一个标题,所以我就起了一个标题而已。这些内容与其说是一种指引,不如说是单纯的感悟。如果你也同意一个人的自我是由他过去的所有人生经历所构成的,那么你应该很容易理解这一点。
之所以最终还是起了这样一个标题,其中包含了一些我自己的私心。在我最迷茫的时候,多次幻想着能够有一个人告诉我他在面临类似的情况时是怎么做的。而每次突破了人生的一个难关以后,也都多多少少会有“原来事情不像我想象的那么难,如果当初能有人提点我一下就好了”的想法。
好在这种事情发生得越多,我就越能体会到这样的机遇是多么可遇而不可求。我也看到有很多真的高尚的人,会用自己的时间和金钱去了解和帮助一个群体,例如我的学弟 icedream61(他的 Bilibili 空间:冰梦)。他就是用了几年的时间了解和调研一些二三本和专科学生的实际情况,希望能够借此帮助他们理解导致他们没有成为所谓的“好学生”或找到所谓“好工作”的社会性原因,从而走出结构性失业的困境。比起我闲暇时间写写博客,这才是真正的引路人。但即使如此,可以看到他的这些工作也并不会覆盖好比十年前的我这样的群体,而像他这样的人也少之又少。是的,可遇而不可求。
所以我想,就算我并没有这么高尚的理想,也没有这种坚持下去的韧性,但至少分享自己的知识和认知总是一个好事。特别是对于我们跟着互联网一起成长起来的这一代人,更是从小的时候就打下了这样的烙印。
简而言之,因为这一系列的经历,我会将一些想聊的事情拆成若干不是很长的文章发出来。现在这个系列是和程序员这个职业这份工作相关的,不过会探讨到很多对人生的思考;后面应该也会聊到一些单纯和人生相关的内容,这部分或许会起名叫“成为优秀的人”吧。
那就让我们开始今天的闲聊吧。
由不理解导致的崩溃
由不理解构成的世界
我认为直到今天,我依旧是一个不容易理解其他人类的人。我很羡慕那些很容易共情的人,而且一直很好奇他们是怎么做到的——甚至有些执拗的认为他们可能也并不能理解他人,仅仅是表现得这样罢了。
而不幸的是,这个世界就是由千千万万像我一样的人类组成的。男人是这样,女人也是这样;大人是这样,孩子也是这样(或许好一些?);PM 是这样,测试是这样,程序员更加是这样。
而这个世界,或者说得小一点,你能看到的任何涉及到人与人之间合作的事情,都是在这么一种混乱的底层运行逻辑下进行的。这也是《人月传说》中关于人月不成线性关系这一表象的深层原理:沟通成本不可忽略。而如果你进一步去思考这件事,会得到一个更恐怖的结论:当任何软件开发项目达到一定的级别后,它一定会崩溃。(当然不限于软件开发,不过这个文章只讨论到这一特定范围。)
好消息和坏消息
好消息是,程序员(以及所有相关的职业,恕后文不一一列举)学会了通过抽象来隔离理解成本。
例如你使用 GCC 或 Clang 编译你的 C++ 代码时,并不需要真的理解它们的实现原理和底层设计——你只需要了解它们的接口就可以了。开发 GCC 的团队和你所在的用 C++ 写一些(至少看起来是)垃圾代码的团队,绝大部分情况下都没有任何交集。能参与到编译器开发,或者甚至给它们提过有效 issue 的人,可能都屈指可数,至少不会包括绝大部分平凡的程序员。
但基于抽象的方式,我们都可以使用这些世界上最优秀的工具,正常完成自己一亩三分地里的工作。
不幸的是,坏消息甚至更坏一些:可能现在的世界上没有人能知道,基于抽象的软件开发到底走到什么地步才会崩溃。
如果对前端开发了解的话可能会感受到,现在的前端开发领域已经先一步走在过度抽象的路上。各种基于抽象的框架层出不穷,但是同一个功能可能被几十上百个不同的框架实现;即使其中只有三四个是你听过的,可能也足够复杂了。加上各种新框架的迭代和旧框架的分支,框架的持续学习成本越来越不能为人们所接受。
而放眼到整个编程领域,这个趋势也依旧值得探讨。在人们讨论什么是优秀程序员的时候,他们通常期望这个真空中的球形程序员除了能够使用各类工具,也能够深入理解原理,而且是越深入越好——最好能从沙子怎么变成芯片上的逻辑门讲起。但随着计算机这几十年来突飞猛进的发展,以及基于抽象的这套理论,“术业有专攻”反而成为了大家的共识。
一方面清楚地知道进一步抽象会导致程序员们越来越少地理解其它抽象层,一方面又期望程序员们更多地理解其它抽象层——这就是今天软件行业的困境。
或许也不是问题
困境?我觉得我需要立刻撤回我刚刚的话。因为事情可能并没有严重到这个程度,是我夸大其词了。
仔细想想,其实这个复杂化的过程在科学界更早就发生了。现在的科学领域远比单一的软件工程行业复杂成百上千倍,但同样是基于抽象和分工的做法依旧可行。科学家们只去了解和自己的领域紧密相关的知识,同时在一些通识上选择相信共识的观点,并跟随最新的研究成果不断更新与补充。
这么看来,软件行业似乎不会崩溃。好耶——
……也没那么好。这可能意味着你需要被迫理解这千疮百孔的现状,并试图去适应它们。
稳定的自我认知
(宇宙级叠甲声明:基于某些信仰的原因,或许 TeX 除外;但以我的水平不足以理解它的完美,所以它也是不完美的。)
不要相信任何软件是完美的
在早先的这些年,我从工作中学到的最重要一点就是:不要在不了解一个软件之前,就擅自认为它是完美的或高大上的。这其实涉及到了一个人对自己的了解和认知自我的稳定性,不知道经历了多少次同样的场景之后,我才慢慢明白了这条道理。
面对一个赫赫有名的软件、工具或者框架,需要基于它进行二次开发的时候,我总是不知道如何下手。我也许能够快速地梳理出一些基本的原理,但它们通常会简单到令我担心:大概是我的想法错了,由这个世界上最优秀的一批人(当然,就像四大天王有五个,通常“最优秀的一批人”也会有很多批)开发出的软件,怎么可能这么简单?
于是我就会开始陷入一种深深的焦虑情绪中,期望有人能站出来告诉我就是这样或者不是这样。但正如上面所说,通常这个人是不会出现的。而这种焦虑会进一步裹挟一个人,让他后面的动作变得畏首畏尾。
而我最终解决了这个问题,或者说部分解决了这个问题,其实是靠着对自我的了解越来越清晰达到的。当你经历过足够多的同样场景时,你就会慢慢锚定自己的位置。你会发现这些看似优秀的人其实写出的工具并不是哪里都很完美,他们自然有许多开创性甚至难以匹敌的工作,但从绝大部分角度来看,他们写的软件也不过是借用了前人的经验,很多地方和我们的想法是一致的。
或者说,他们在构建自己的抽象层时,其实也要基于大量其他人的抽象层开发。一个优秀的软件,其优秀之处不在于它自己重新发明了所有的抽象层,而是在已有的抽象层上做出了前人没有做到过的事情。
需要再重申的是:这仅仅是我自己遇到的问题。如果你没有遇到过这样的问题,我在为你庆幸的同时也真心地感到羡慕。
但还是那句话,我也不期望我的这篇文章能帮助到世界上的所有人。如果一个人恰好有和我一样的问题,而我的文字又能在他理解这些问题的道路上协助他稍微地前进一小步,那就已经很好了。
即使没有这种情况发生,也没有什么关系。毕竟退一万步讲,这一系列文章只是我的闲聊,为了满足我自己的表达欲罢了。
用尝试替代思考
虽然我现在的自我认知已经能够一定程度解决这个问题,但这并不代表一个类似的人看了上面的文字就能达到同样的自我认知。相反,作为一个精神内耗其实还挺严重的人,我很理解这种内耗是不能由简单的几句话转变的。
通常在互联网上会基于 MBTI 对人的分类把我这类人称作 I 人,我不认可这个分类方式,但是认可这种简单有效的分类方法。)
毕竟,人的这种固有思维只能由自己新的人生经历来修正,而如果没有遇到机缘巧合,新的经历大多数情况下只能靠自己的行为转变带来。请允许我不厌其烦地提示:大前提是你也同意“一个人的自我是由他过去的所有人生经历所构成的”这个观点。
就像《化物语》中所说的:人只能自己救自己,谁也没有办法拯救别人。(人は一人で胜手に助かるだけ。谁かが谁かを助けることなどできない。)
不过列举这句话只是处于我个人的喜好,过于相信自己的认知范围内文化作品的高大上也是我们这一代程序员身上常见的现象,也请读者们见谅。事实上,哲学家们早就洞见了这个道理。无论是黑格尔的辩证法中对于事物发展的理解,还是斯多葛学派对于理性的思考,无一不在体现这个观点。
而改变自我行为最好的方式,其实就在一句大家耳熟能详的古话中。
学而不思则罔,思而不学则殆。
这里的“学”可以是进一步地学习了解,但也需要包括实践。与其为了一些事情的正确与否原地踌躇不前,不如先接受自己的认知。如果这个认知有错误,那么总有一天它会被修正。
其实这也是小时候每个人都听过的道理:失败是成功之母。只不过之前的我,只是简单地把它理解为“即使失败了也要努力才会成功”。现在想想,或许更重要的道理是:每个人都必然会遇到失败,而且会持续地失败。
就像永远都不完美的那些软件一样。
不理解,但是理解
很幸运第一次尝试顺着“不理解”这个话题,边思考边写下这些文字,就能顺畅地结束在另我自己很满意的地方。
虽然上面没有具体讨论到接下来要提到的这个观点,仅仅是触及了一点点,但我还是想夹带一些私货。我认为《EVA》中把人与人之间的隔阂比作 AT Field,真的是一个再精妙不过的比喻。如果你过于相信他人,完全卸下你和他人之间的隔离,那么就会失去自我;而当你完全不相信他人的时候,你的自我也不再有意义。
有趣的是,这两种看似背道而驰的状态通常不是独立出现的,而是一起出现。同时,你还需要在这两种状态间找到一个平衡,才能在保持自我的情况下在世界上存活下去。
因为我不认为我的读者全部了解《EVA》,所以也不打算接着这个话题展开过多讨论。但无论如何,当一个人能够一边作为不理解这个世界的一员,一边理解自己和所有人类对这个世界的不理解时,这个人才能真的开始理解这个世界。
我一开始其实想将文章的标题叫做“屎上雕花”,这是由我司前 CTO 提出的一个描述软件工程状态的词汇。后来想想,这种表述方式虽然足够准确,但还是过于戏虐了。而且这个词被提出的时候,多少带着一些负面的含义。但我这篇文章的观点,更多地是认为这是一种应当被接受的常态——虽然我这些年的工作内容(特别是 CI/CD 和工程化相关)就是为了尽可能消除这种情况,但我还是要接受这个情况的普遍性这一客观事实。
毕竟,理解这种不理解导致的不完美,也是迈向完美过程中的一环。