阅读复杂的 C++ 项目代码需要一定的策略和经验。下面是一些实用的建议,希望对你有帮助:
1. 目的性:在阅读代码时,如果有明确的目的,效果会更好。例如,你要添加某个功能或修复一个 bug,那么有目标地阅读相关的接口和实现会更自然。
2. 时间投入:阅读大型项目的代码需要时间。软件开发是一门手艺,耐心投入足够的时间,逐步理解整体代码逻辑。
3. 方法论:
- 自底向上:从具体的文件到子模块,再到整个项目。先了解具体实现,然后总结出一般规律,与整体抽象对照。
- 自顶向下:从项目的顶层设计到责任分发,再到具体的实现代码。理解整体框架,然后逐步落实到具体实现。
4. 不纠结细节:不要过于深入某个细节,先理解整体。将某个函数或数据结构当作黑盒,知道其输入和输出即可。
5. 使用调试工具:熟练使用 GDB 或其他调试工具。调试信息版本的代码可以帮助你验证想法和理解代码。
6. 文档和注释:阅读代码时,参考文档和方法前的注释。文档和注释通常提供了关键信息。
总之,阅读大型项目的代码需要耐心、目的性和方法论。不断练习和实践,你会越来越熟悉这个过程。
从最常出问题的一个作业调度服务的main()开始,其最常见的一个生命周期流程,从启动,到初始化,到创建各个对象,直到进入服务循环。
然后,很快开始带着我做第一个任务,听我阐述自己的想法和计划,然后分析哪里不对,哪里很好。很快我就在一个又一个任务中,对代码的一个个局部深入理解,最后这些局部慢慢连成片,就掌握了整块代码。攻克了一个组件,再通过接任务进入下一个组件。在这期间,整天就是生看代码、gdb、debug log。
我个人认为,这就是搞定大型项目的不二法则:
- 首先你要有任务,开发任务,或者最好是调查bug的任务。以任务为导向,你才不会整天哈欠连连。
- 要找出一条执行路径,跟着这个路径去看代码。少了“执行”这个概念,代码就是天书。
- 对于c++项目,gdb一定要能熟练操作。只要代码能生成带调试信息的版本,那么当你实在看晕了,或者不确定自己的理解时,gdb是你最好的参考答案。实在没有调试版,有个debug log也可以凑合一下。但最好能自己编译生成,这样你就可以加自己的额外log,帮你验证一些想法了。
- 回到第1点,再次强调,不要泛泛地看代码!不要在代码里漫无目的的溜达,那样很快你就迷失了。
(1) 如何分析大型C++项目? - 知乎. https://www.zhihu.com/question/531050207.
(2) 怎么阅读代码,老司机总结的6个实用经验 - 知乎. https://zhuanlan.zhihu.com/p/159288469.
(3) 拥有 C/C++ 基础的学生,如何看懂1万行代码的项目_怎么看一个c++项目-CSDN博客. https://blog.csdn.net/linjingtu/article/details/51661152.
(4) 如何阅读大型项目的代码? - 知乎. https://www.zhihu.com/question/351618643.
(5) c++ - 如何阅读一份源代码? - Databend - SegmentFault 思否. https://bing.com/search?q=%e5%a6%82%e4%bd%95%e9%98%85%e8%af%bb%e4%b8%80%e4%b8%aa%e5%a4%8d%e6%9d%82%e7%9a%84C%2b%2b%e9%a1%b9%e7%9b%ae%e4%bb%a3%e7%a0%81%ef%bc%9f%e6%9c%89%e4%bb%80%e4%b9%88%e5%a5%bd%e7%9a%84%e5%bb%ba%e8%ae%ae%ef%bc%9f.
(6) 如何快速看懂一个项目_读懂大项目-CSDN博客. https://blog.csdn.net/qq_36479234/article/details/97626620.
① 不要追细枝末节,在刚开始时候追两三级嵌套即可
记住要做总结,要知道你不跟下去的的输入,输出是什么。这个就跟我们学习堆栈一样,压入栈太多,引起了栈溢出。代码不可能一次就吃透全部,我们的策略是不断地渗透,今天一个方法,明天一个文件,然后是一个目录,最后是一个项目。
在一个文件结束后,有可能不是目录,而是一个功能。比如我们看了一个查询系统当前的进程列表方法,进而了解了这个文件,那么我们就可以直接检索系统调用这个方法的地方,看看它的用法,以及它是在哪些文件中使用的,这样子就可以找到下一个切入点,再次深入源码当中学习。
② 画流程图,时序图
可以是在线画图软件,本地的话我用的 StarUML工具,可以满足平时的使用。画这个是方便我们总结,也会加深记忆,同时还能让自己有成就感,学习下去的动力。
我们需要激励源,画图如果让同事看到,会让你有成就感,有了炫耀的资本,这样会更激发自己的战斗欲,这就像是好学生因为老师的表扬,会更加拼命学习,为的就是保持这个好学生的身份。
我们对于分析的代码,随着画图会理解的更精准。从记忆深度来说,文字不如图,图不如视频。我们看项目文档,很多时候都是画的图,清晰,并且让你很好理解。你下次遇见问题,就会想起这个图,然后拿出来进行参考。
③ 笔和纸
我自己喜欢写写画画,于是买了一盒中性笔,同时买了一袋打印纸,也不贵,可以用很久很久。用这个的目的是,很多时候我们工具用的不熟,画起来不符合我们的思维,所以需要个东西去乱画,记录下来当前的疑问。
用笔记录疑问,简单的画下流程,为的是让一闪而过的想法留存下来。画流程图和时序图,实际是已经有了一些掌握,不是一抹黑的阶段。当你对整个流程还不是熟悉的时候,最好的方式就是先随意画,记录下来,然后慢慢消化,最后画出来,变成文档。
④ 带着问题进入,有目的性
没有问题的跟进代码,会让自己不知道在干什么,于是我在学习代码的时候,都是先设定问题,有自己的目标。比如分析完这个文件的所有接口,从接口能分析出这个源文件的对外方法都有哪些,这个文件是做什么用的?比如FileUtil.java ,我们一看就知道是文件相关方法,里面有打开,关闭,追加,删除等方法,这个接口列表就是我的目的。
再比如安卓启动过程的入口是哪个文件,这个文件都有什么方法,都有哪些接口可以调用,记录下来,做总结。
如果有官网 API,那么就上去看,然后发现哪个解释自己能看懂,就先看这个,然后顺着这个进行未知的方法探究,这样子可以做到信心满满,不会被满屏不懂的技术打倒。
⑤ 在解决具体问题后,多看看其他方法
这个在学习过程中非常重要,我平时看见很多人阅读代码只看下自己解决的地方,其他地方不怎么仔细看,于是下次遇到一个需求就不知道有没有支持了。
只有你打开好奇心,在时间充足的时候,对你掌握的代码,进行扩充代码领域,从你熟悉的一个流程里,进行不断扩充边界,这样子你最终就攻下了整个模块。
也就是先找一条线跟进这个模块,然后在这个线上找每个细节,继续扩充知识,最后就出现了知识体系,一个参天大树。很多理论都是可以迁移的,比如目标管理里面强调的,目标,拆解,验证,复盘。
先制定可以测量的目标,然后分解成一个个小节,然后一个个小节验证,最终复盘发现新的问题,再制定新的目标。做项目,做需求,阅读代码,都是可以使用的。源码阅读需要一个线,也就是一个目标,设定了目标,就可以去执行。比如跟踪马达从上层到最终驱动,硬件的流程,绘制出来一个时序图。
然后发现这里还有霍尔器件,还有光感传感器,触摸屏,然后在做完了马达的整个逻辑,是不是就可以探索进入其他模块,继续分析。
只有这么去做,你的知识体系才能日渐丰满。
⑥ 总结,写笔记
多去写,多去思考。只有你去写,有机会的时候,最好要去讲。写和讲这两个方向都会将自己模糊的知识点逼出来,更好地认清自己的不足,从而这些就是你下次阅读代码的目标。
同时写笔记,发到网络上,还是建立自己影响力的一个环节。如果你写的好,那么在当下互联网时代,你的机会就会比其他人大很多。
我们要做到喜欢阅读代码,并且有自己的方法,不是胡乱看看,而是有目的,是解决问题,还是深入研究?是总结文档,还是流程分析?
希望这一节的阅读代码的方法能够帮助到你,如果有任何疑问,欢迎留言讨论。