如何阅读别人的代码?

亡梦爱人 提交于 2020-01-26 14:18:18

1. 不要畏惧。我发现大家都经常会感叹XXX强大,YYY流行,无形中你会把它放在一个不可触及到的地位,感觉它很难,而令自己不敢去挑战它。

2. 带着问题去阅读代码,这也是我认为最有效的方式。这会让你在阅读时候有个主线,比较有针对性。

3. 断点调试。在Python代码中使用pdb一般不太好使,因为代码复杂的话,这种断点需要你使用多个n跳到对应的位置,我一般都是先抛出异常,然后使用pdb的up/down/n等命令调试。当然在目标位置添加一些print日志或注释部分代码然后直接使用exit()退出也是可以的。

4. 理解作者的思考方式。不同的项目要有不同的思考方式来阅读,不要拧着自己的习惯去阅读,这样会很累,得尝试接受别人的观点,甚至于改变自己。

7. 记忆并绘制项目架构。项目就是一堆代码的组合,除了学习编程技巧,还要了解项目的架构决策,这对于未来自己写大型项目非常用用。这种理解越补充,你会对它就越来越清晰。

参考其他地方的
阅读代码之前弄清楚下面两点是很有帮助的: 
1,理论层面。是基于什么理论来实现功能的。
2,提供了什么样的API接口,也就是说,暴露给用户的是哪些功能,这个可以反推出基本的模块有哪些 

 

分层次阅读

  在阅读代码的时候不要一头就扎下去,这样往往容易只见树木不见森林,阅读代码比较好的方法有一点二叉树的广度优先的遍历。

在程序主体一般会比较简单,调用的函数会比较少,根据函数的名字以及层次关系一般可以确定每一个函数的大致用途,将你的理解作为注解写在这些函数的边上。当然很难一次就将全部注解都写正确,有时候甚至可能是你猜测的结果,不过没有关系这些注解在阅读过程是不断修正的,直到你全部理解了代码为止。

一般来说采用逐层阅读的方法可以是 你系统的理解保持在一个正确的方向上。避免一下子扎入到细节的问题上。在分层次阅读的时候要注意一个问题,就是将系统的函数和开发人员编写代码区分开。在 c, c++,java ,delphi中都有自己的系统函数,不要去阅读这些系统函数

  写注解

  写注解是在阅读代码中最重要的一个步骤,在我们阅读的源代码一般来说是我们不熟悉的系统,阅读别人的代码一般会有几个问题,

1搞明白别人的编程思想不 是一件很容易的事情,即使你知道这段程序的思路的时候也是一样。

2阅读代码的时候代码量一般会比较大,如果不及时写注解往往会造成读明白了后边忘了前边的 现象。

3阅读代码的时候难免会出现理解错误,如果没有及时的写注解很难及时的发现这些错误。

4不写注解有时候你发生你很难确定一个函数你时候阅读过,它的功能是什么,经常会发生重复阅读、理解的现象。

 说一些写注解的基本方法:

1猜测的去写,刚开始阅读一个代码的时候,你很难一下子就确定所有的函数的功能,不妨采用采用猜测的方法去写注解,根据函数的名字、位置写一个大致的注解,当然一般会有错误,但你的注解实际是不但调整的,直到最后你理解了全部代码。

2按功能去写,别把注解写成语法说明 书,千万别看到fopen就写打开文件,看到fread就写读数据,这样的注解一点用处都没有,而应该写在此处开发参数配置文件(****。dat)读出 系统初始化参数。。。。。,这样才是有用的注解。

3在写注解的使用另外要注意的一个问题是分清楚系统自动生成的代码和用户自 己开发的代码,

4在主要代码段要写较为详细的注解。有一些函数或类在程 序中起关键的作用,那么要写比较详细的注解。这样对你理解代码有很大的帮助。

5对你理解起来比较困难的地方要写详细的注解,在这些地方往往会有一些编程的技巧。不理解这些编程技巧对你以后的理解或移植会有问题。

  重复阅读

  一次就可以将所有的代码都阅读明白的人是没有的。至少我还没有遇到过。反复的去阅读同一段代码有助于得代码的理解。一般来说,在第一次阅读代码的时候 你可以跳过很多一时不明白的代码段,只写一些简单的注解,在以后的重复阅读过程用,你对代码的理解会比上一次理解的更深刻,这样你可以修改那些注解错误的 地方和上一次没有理解的对方。一般来说,对代码阅读3,4次基本可以理解代码的含义和作用。

  运行并修改代码

  如果你的代码是可运行的,那么先让它运行起来,用单步跟踪的方法来阅读代码,会提高你的代码速度。代码通过看中间变量了解代码的含义,而且对 以后的修改会提供很大的帮助

从 程序代码的启始点开始读起,一来要循序读完所有的程序代码旷日费时,二来透过这种方式来了解系统,很难在脑中构建出系统的面貌,进而了解到系统真正的行 为。所以,阅读程序代码的重点,不在于读完每一行程序代码,而是在于有效率地透过探索及阅读,从而了解系统的架构及行为模式。以便在你需要了解任何片段的 细节实作时,能够很快在脑上对映到具体的程序代码位置,直到那一刻,才是细读的时机。 

在阅读程序代码时,却应该先采由上至下(Top-Down)的方式。对程序代码的阅读来说,由上至下意谓着,你得先了解整个系统架构。

Top-down 模式,就是先设定一个 use case,比如说打开一个文件。然后静态跟着代码看,或者用 debugger 跟着看。每次出现函数调用的时候,把函数的执行层次纪录下来。大致如下:
func1( )
   func2(  )
       func(  )
   func3(  )


这种图表很随意,你可以根据自己的需要增加信息。比如我有时会把重要的「实际参数」一直标下来,这样阅读深层次代码不用再回头查形式参数到底指什么。这个图的基本作用是防止在阅读深层次代码时忘记总体执行层次。

Top-down 模式进行到一定层次,往往会发现虽然图画了出来,但还是无法了解程序再干什么。这时需要转入 bottom-up 模式,一直深入到最底层,给能了解作用的底层函数一个一个的写文档。当然这时的文档是完全底层的观点。

然后就是不断在两个模式之间转换,不断的细化两种模式的理解。

 

读代码慢就是对常用函数和常用库不熟,不熟悉python常用的编程技巧,读代码的时候精力太分散,读代码是一句一句的读,还需要经常上网查语法什么的,没有办法把精力放在代码的整体结构上,即使是每行代码都看明白了还是不知道整个程序的逻辑,同时耗费精力比较大,很快就累了,效率很低。
熟悉了常用库和编程技巧之后读代码的时候很多功能自己都实现过类似的,扫一眼就看明白了,很多函数扫一眼就知道什么功能,思路不会被不懂得语法或者编程技巧打断,一直停留在程序的逻辑上,这样看代码就轻松多了,而且很快,基本上小的项目随便翻翻就知道它的思路了,大的项目的话其实不用全都把握,只要把与自己要看的部分相关的熟悉了就好了。

 

1. 一个项目的目录和层级,肯定按照不同的功能区分的。认识每个不同的目录和文件 ,文件夹的名字都是有意义的。
2. 从主函数入口开始,了解各层目录之间的调用关系,把握项目的整体逻辑 
3. 代码都是一个一个的函数和对象组成, 把他们当作一个小单元,精读

 

. 在代码中选一个你已知的结果(功能),然后从结尾开始,逐步反推出代码中每一步的操作

举个栗子,你知道你看的这段代码,最后会生成一个包含许多影片清单的文件。于是,你得首先在代码里找到生成那个文件的具体代码,定位这个生成操作在代码中的哪几行。

接着往回找,看看代码是如何把数据写入文件的。

再接着看上一步,这些数据是哪里来的。

就这样一步一步,直到你把整个来龙去脉都弄懂为止。

这类彼此相连的代码,我们称之为“操作链”。

使用这种方法,你必然会循着“操作链”浏览代码的各种不同部分。这将会让你了解有关代码的这些信息:

  • 代码的本体是如何组织的(在哪里声明/定义变量,不同的函数在什么位置,等等)
  • 作者的代码风格如何
  • 代码作者是如何思考并解决问题的(这部分比较难以描述,但当你看得多了,你就能从直观上察觉出来)

在这么做之后,你将会逐渐熟悉代码的全貌,理解它的构成。也就是说,你刚开始可能面对的是:

[ 满屏幕花花绿绿的代码,完全看不出有什么意义 ]

而之后你面对的将是:

[ 还是满屏幕花花绿绿的代码,但这其中的几段我知道它们是干什么的 ]

 

 

b. 查看变量的状态。程序自身的报错会告诉你发生了什么错误,但你还需要找出为什么会发生错误。通过 print 输出出错语句涉及到的相关变量的值和类型,可以帮助分析出错原因。

c. 找出出错位置。往往错误的原因并不在报错的位置,所以多输出一些标记,多 print 不同位置的变量值,查看变量在运行过程中值的变化情况,可以观察是在哪里发生了问题。

 

 

b. 在出错行之前输出。报错行涉及的一些变量,他们的数值和类型,全都输出出来,看看和预期是否一致。

c. 一行做一件事。如果你出错的一行里连续调用了多个函数或运算,请分开写,分开输出。

d. 对于字符串,直接 print 会被转义和解码,影响对变量实际值的观察。可以用 print(repr(text)) 或 print([text]) 的方式查看。

 

然后通读你打印出来的代码并做好标记,标记的内容包括以下几个方面:

  1. 函数以及函数的功能。
  2. 每个变量的初始赋值。
  3. 每个在程序的各个部分中多次出现的变量。它们以后可能会给你带来麻烦。
  4. 任何不包含 else 的 if 语句。它们是正确的吗?
  5. 任何可能没有结束点的 while 循环。
  6. 最后一条,代码中任何你看不懂的部分都记下来。

接下来你需要通过注解的方式向自己解释代码的含义。解释各个函数的使用方法,各个变量的用途,以及任何其它方面的内容,只要能帮助你理解代码即可。

最后,在代码中比较难的各个部分,逐行或者逐个函数跟踪变量值。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!