上读代码比写代码难,真的吗?来听听别人都怎么说!
wsivoky
很多人不明白代码意味着什么,代码意味着要随时理清这一坨:
读代码:找到图中两个节点之间的可能路径。
改代码:替换一个节点,完整地保证那个节点和每个节点之间的连通性,正确性。
写代码:新增一个节点,然后(其实不管你怎么)连到原图中。
产品经理:我其实根本就不关心这些线是怎么连起来的。
以上,读代码是NP难度,写代码,不好意思,对很多人是P级别的。
冯东
首先,就不说写的烂的代码了,只说写的好的代码。写的好的代码,依然是很难阅读的。写的好的代码,一般是遵循一些原则。而这些原则,很难从最后的代码中反推出来。这些原则一般都是 declarative knowledge,而我们看到的代码大多是 imperative code。即使是 functional program 或者 declarative language 的 code,一般也是用低级的抽象来描述高级的原则。
举一个类比,目前体育比赛中很多规则的修改,都是借鉴以往比赛中一些旧规则导致比赛比较沉闷,或者被运动员钻空子的经验教训。但是单单去看这些规则,你无法反推出来它们是为了避免什么情况。
所谓的「读懂写的比较好的代码」,一般是从代码以外的途径了解作者的意图。然后再掌握作者贯彻这些意图的一些基本习惯。遵循原则的代码已经如此难以阅读,事实比这个还糟糕。任何原则应用于具体问题,都有例外。所以在任何代码中,都有遵循原则的代码和例外的代码。好的代码只是减少后者的比例,而无法完全杜绝。
vczh
好的代码,读起来容易,但这是有前提的——就是你得跟作者有相同的知识背景。当然这一般是达不到的。就算人家有注释,说不定你得把注释当成关键字,好好地Bing一把,学他个三五个月,你才能理解作者的意图。
王子亭
自我开始编程以来,我一直觉得读别人的代码的难度,要几倍于自己写代码。一直以来我都很困惑,难道是我技艺不精,所以读别人的代码很困难么。其实不是,我能看懂代码中的每一句话,并没有我不认识的语法,但连在一起就不懂为什么作者要这么安排代码了。后来我渐渐有了一些想法,代码是程序员给计算机的命令,是作者思考过后的产物,但思考的过程却没有体现在代码上,这就好比一道数学题,只有一个最终答案,所有的计算过程都被省略掉了,自然难以理解作者的意图。
一段代码一开始写出来,后来发现存在问题,陆陆续续地改过好几版是很常见的事情。最终版本中可能每个小的细节,都是作者花了很多时间试错的结果,但这个试错的过程并没有直接地体现在代码上。另一方面,代码中往往存在一些「隐含前提」,例如假定函数的参数已经在传入之前被以某种方式处理过了,这个假定很可能于另一个文件的某行代码有关,这种联系很难引起阅读者的注意。当然,好的设计可以缓解这个问题,但很难被彻底地解决。代码的历史会被保存在版本控制系统里,但说实话,按我的经验,很少真的有人去翻版本历史,因为正确地使用版本控制工具相比起写代码是一项比较不受重视的技能,在这种情况下翻历史是非常耗时的。
当然,有些人会将一些细节以注释的形式添加到代码中,但注释也只能承载很小的一部分信息,因为维护注释也是一项很高的成本,我个人一向是反对添加注释来解释代码的。所以阅读代码实际上并没有看上去那么轻松,为了彻底理解一段代码,很有可能你需要付出和编写这段代码差不多的努力,来了解这段代码的历史和前提。前面提到的是阅读「好的代码」的情况,比如大多数活跃的开源项目,如果是面对质量较差的代码情况就更为糟糕了。所以我的观点是,读代码绝对不是一种好的学习方式,我认为学习一项技术应当先阅读书籍,然后尝试自己实践,最后再参考代码质量较高开源项目。对于大多数项目而言,可能从未把「供他人学习」当作目标,只有当你自己实践过,积累了一些经验并且也遇到过一些困难的时候,你才能读懂代码并且从中学到解决问题的技巧。而在开始实践之前,最好的知识来源是书籍,因为书籍的内容是经过精心的安排的,最高目标就是供他人阅读。
达
用热力学来回答一下这个问题:因为从思路转换成代码是熵增加的一个过程,要把代码重新整理成思路是熵减少的一个过程。
好比一副有序的扑克牌很容易变乱,已经变乱的扑克牌要变有序需要做更多的功。所以,写代码容易,读代码难。
MisterFin
假如你读到这样一篇文章:“张三把一个不明物体A、一个不明物体B、两个不明物体C交给了杰克,杰克拿起A,把A的一部分出示给皮尔杜,皮尔杜开始在从一个本本里掏出一个东西,连同收到的东西一起交给门捷洛夫,门捷洛夫鼓捣了半天...然后告诉皮尔杜不对,皮尔杜又掏出一个东西...门捷洛夫告诉皮尔杜对,皮尔杜告诉了田中...”提问:张三在干嘛呢?你会不会头疼上面都在胡说什么呢?如果做一个替换:张三 —— 顾客;杰克 —— 收银员;皮尔杜 + 门捷洛夫 + 田中 —— 收银台(扫描 + 查询 + 显示)。读代码的困难之处同上,就是你没法知道作者设置的x, y, count, option, timeline等变量究竟代表了什么东西。
猫杀
读代码有两种情况,一种是读局部,某个算法、流程的实现;一种是读全局,整体架构,模块的组织耦合之类的。读代码的目的有两种,一种是纯学习,看别人怎么做;一种是要用,缺文档的项目要从代码猜出怎么使用,要加功能做修改等。写代码你只需要知道一种实现,读代码你可能需要知道多种实现。
要能很容易的读懂别人的代码,简单的说就是要见多识广,涉及的方面很多,不管是知识上还是技巧上的,所以难度主要是在这一点上体现。代码的质量影响也很大,但是如果你有大量读(写)烂代码的经验,难度会显著的下降。拿到一个项目的代码,你知道这个项目要做什么事情,有多少种可能的实现方法,比如是MVC还是View-Document,很快你就能从各种线索中确定是哪一种,方向一确定,随后的事情就简单了,寻找的都是不同的地方(往往也是好看的地方)。比如拿到个JS写的前端交互项目来做修改,一看到EventBus的出现就知道八九不离十是MVP模式了。
读代码对工具链的熟练程度要求也很高,自己写代码,某些人硬要不用IDE拿记事本写,也就只是慢点而已。读一个大型项目如果不会熟练的利用工具,快速在各种定义、调用和实现之间跳转,那就是找虐。还有一个就是目的性,有着目的性的去读就要容易得多。比如我读Chrome的源代码就是对其多进程架构感兴趣,于是从入口点开始追踪,窗口的初始化、IPC的建立逐步的去顺藤摸瓜的看。几次读Linux的源代码时,都是因为项目需要,去研究Linux的时钟管理、驱动层实现等。尤其是大项目,整体读完的可能性和实用性不大,带目的性的、参考性的去读就要合适一些。除此之外还有很多琐碎的技巧性的东西,都是需要长期积累的。
王瑞期
情况有很多:
1:知识背景不同。比如你对数据库的实现了解很少,你就完全不知道整个代码到底是要实现什么算法,什么数据结构。
2:思考方式不同。有人喜欢 a*(b+c),有人喜欢 a*c+a*c ,右撇子总是很难理解左撇子左手比较有力的那种感觉。
3:无关干扰很多。“门前有两棵树,一棵是枣树,另一棵也是枣树”,表达了作者当时什么样的意境?其实作者就是随便这么一写,但是别人看了,总觉得有深意,被绕进去了。
4:写代码时临时起意的情况很多。建房子,你知道标准流程就那样了,所以一看就知道怎么建的。但是代码呢,比如我要写一个类,这个类专门用于建房子,我最初设想有几个方法:拿钱,设计,找建筑队,建设,装修。然后写着写着,我发现,拿钱这事吧,该有个方法来处理怎么拿。然后设计这事吧,我得写个方法,找出我最满意的设计方案。。。。等等,在写代码的过程中,总体流程算是线性的,但是详细的代码过程中,会有很多突然蹦出来的东西。而我们读代码,模拟不了作者脑子不停蹦创意的过程,所以,就总觉得这代码怎么感觉在迷宫里转悠呀。
李遥
同样是代码,读别人的SQL、HTML、CSS比读别人写的C++、JavaScript要容易,为什么?原因在于非声明式的语言会引入Personal Style这个问题,而别人的Personal Style不像一个编程语言有教程有指南有参考手册,而且作者本人也不一定前后一致,很多情况下你只能“痛苦地”揣测他为什么这么写,因此你的大脑自动就排斥做这种事。
胡江
读比你水平高的代码,自然难。难在跟上人家的想法。读水平相当的代码,难。难在了解代码后面来龙去脉,推测作者的意图。读低水平代码。难在把烂东西看完还要一针见血总结出道道,避免自己犯同样错误。读代码难,其实难在对自己的认识和对对象的把握。最后再扯一下,其实题目也不准确,并不是所有读代码都难。例如开车狭路遇高手,对方会清楚地表达他的驾驶意图,让你轻松决定如何处理。或是人家油门一踩,你还没反应过来车已经过去了。有而最怕的是前方本侧有障碍,你特地给对方留出一大块车道先行。结果对方远光不关,一脚刹车等你来闯关。
声明:本文来源网络,版权归原作者所有。如涉及作品版权问题,请联系删除。
公众号《朱老师IT充电站》。