如何学习大型项目的源码?

2024-08-24 07:08
文章标签 源码 学习 大型项目

本文主要是介绍如何学习大型项目的源码?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近有朋友突然问我一个问题 “你怎么把UE4引擎代码看的那么深入的?”

看到问题后我还愣了一下,因为这是第一次有人给我打了个”深入UE4”的标签。其实我接触虚幻引擎满打满算也就两年,确实谈不上深入。只是靠着平时的学习习惯积累,写了一些相关的技术文章。

但这个事却让我突然意识到最容易被我忽略的学习习惯很可能是有一定价值和意义的。我只想着分享我对引擎学习的心得总结,却从没有想过分享我的学习方法,或许后者更为重要。

每一个人做事都有自己的风格与习惯。当你发现身边一个人很优秀的时候,你去看一下他的24小时是怎么度过的,然后再对比一下你的24小时,答案就很明了了。同理,如果你觉得学习源码很困难,不妨请教一下那些比较牛的”过来人”,看一下别人学习源码模块的流程。当然具体来说,影响一个事物的维度,细节,前提条件都很多,别人的方法照搬过来可能是行不通的,比如说别人能一天雷打不动地学10个小时,这个放到有些人身上几乎不可能。这些道理大家都明白,我也不过多阐述。

回归主题,既然标题是“如何学习大型项目的源码”,所以下面我把自己学习虚幻引擎源码(C++)的思路和过程给分享给大家。

虚幻引擎源码大概有几百万行(没有确切统计过,可以参考下面的纯代码文件夹截图),最早可以追溯到1998年Epic自主研发的3D游戏——虚幻。对于一个提供了如此完善功能的游戏引擎,可以想象到他的代码是相当复杂的。所以,在学习的一开始你要明确,你的目的不应该是从头到尾地读遍他所有的源码,而是确定好学习目标后,抽丝剥茧地且有条理的整理出某一个具体模块的内容。

这里写图片描述

这里先给出简化版的总结,然后我会针对每条做进一步的阐述。

准备工作:建议准备大块且连续的时间(细碎的时间容易中断类关系的梳理),一个比较方便查找的IDE或工具(VS,Notepad++等),类图工具(staruml,Edraw等)

学习步骤(简化版):

  • 1.决定要学习的模块,查找官方文档、相关的总结文章,整理出大概的学习内容与目标
  • 2.运行程序,观察表现
  • 3.运行源码,断点调试,从头跟一边源码的执行流程,注意函数堆栈
  • 4.画类图、流程图,先把遇到的重要类记录下来,表明各个类的关系
  • 5.记录问题,把不理解的类或者内容以问题的方式记录下来
  • 6.写文章、笔记,尝试逐个解决之前遗留的问题

2-6可能需要持续的重复进行


学习步骤(详细版):

  1. 查找官方文档、相关的总结文章
    比如说我想研究网络模块,首先去官方文档、论坛、wiki里面过一遍网络相关的所有内容,这时候遇到不懂的问题尽可能解决,解决不了的就把问题记下来,先去官方文档看我觉得是非常有必要的,因为这里的文章是最权威的,错误率非常低。然后,去Google、百度搜索相关的文章与帖子,同时可以加入一些技术qq群(有一些水群果断退了就行,保留一些优质的交流群),过一遍这些文章和资料。目前能看到比较好的技术网站大体上就是各个技术对应的官方网站(论坛)、StackOverflow、知乎、博客园、简书、CSDN、一些个人网站等,当然有些网站复制粘贴现象严重,需要自己筛选。建议能找到原文链接的尽量去原文里面看,因为你有可能从原创作者那里看到更多优秀的文章。

  2. 在运行程序的时候,我们需要调整各种参数来执行不同的情况,进而观察其表现效果来验证我们的猜想与结论。
    比如说,对于一个处于休眠状态的Actor属性是否能正常同步,如果客户端属性与服务器一样是否还会执行回调函数等。执行程序可以快速的得到结论,然后根据结论我们可以更快速准确的进行分析。为了提高效率,最好在一开始就设置不同的配置、GM等来在项目运行时动态改变运行内容,因为大型项目一般都是编译型语言,我们可能可能需要频繁的修改代码编译再重新运行。

  3. 调试可以说是最为关键的一步了,80%的细节需要你在调试中去理解函数什么时候执行到这里(函数断点)?每一步每一个属性值是多少?属性值什么时候发生变化(条件断点)?一个完整的执行流程是什么样的(函数堆栈)?这些问题需要你一点一点的进行跟踪调试,最后再去解决。

  4. 画图的习惯可能很多人没有,但是我个人觉得这是一个必不可少的环节,因为他可以大幅度提高你对框架理解的速度对于任何一个复杂的项目,每一个模块都会牵扯到大量的类(排除纯C项目),类的关系错综复杂,而且为了降低耦合还可能用到各种设计模式,这些都大大提高了代码的阅读难度,很有可能你看了3、4个类之后就完全搞混了他们都是干什么的。举例来说,我在看UE4属性同步模块的时候,完全被各个类之间的关系搞蒙了,所以我看到一个类就把他的类图画下来,看到相关的类就记录他们的关系,最后得到了下面这样一个简化的类图。经过梳理后,几句话我就可以概括他们之间的关系。当然,除了类图以外,还有流程图、时序图,甚至是你自己为了方便发明的“模块关系图”,这时候图的种类与规范其实没有那么重要,只要能帮助你理解就行。这里写图片描述

  5. 记录的问题有两种:别人给你的问题以及你自己给自己的问题别人给你的问题
    别人给你的问题:你在阅读的时候不可能一帆风顺,可能在第一步的时候,就已经遇到了无数的问题。这时候不要着急,按照重要程度顺序依次解决,简单的问题直接网上搜一搜,解决不了可以找身边的大神,网上的牛人解决。如果还是不行,就把问题记下来,然后继续学习,当你深入到一定程度的时候,你的问题可能就不攻自破了。
    自己给自己的问题:当你解决了别人给你的问题后,你应该已经理解了一大半了。不过,任何人写的文章都不可能覆盖到全部,你需要自己挖掘更多更深的问题,然后自己再去解答,这样你才能做到比别人了解的更多,更能体现出你自己的价值。

  6. 写文章和写笔记是有区别的,但是都很有意义
    写文章这件事相比上面的步骤我觉得不算是必须的,这个适合那些追求完美还能挤出时间的人。你写的东西是要给别人看的,所以你的目的是给别人讲清楚。我在写文章的时候会去考虑这个东西我说的真的对么,有没有把握,考虑的是否全面。在这种自我拷问下,我会尽可能的完善我的知识体系,修改文章中那些看起来不够准确的内容。如果最后能做到给读者讲清楚的话,那你是真的会了。
    写笔记相比写文章要轻松很多,我只是把我总结的内容,学习的收获记录下来,不需要考虑太多的东西。虽然没有写文章那么追求完美,但是这个过程中我们可能也会多了很多思考,在之后的学习过程中快速的回忆起自己学习的经验。

备注:第一次执行这个过程是相当漫长和艰难的,如果和我一样一开始知识储备不够,那么几乎每走一步都需要大量的学习和查资料。不过只要坚持下去,你最后会发现自己的收获非常大,阅读其他模块的源码也变得容易很多。
上面只是我学习源码的一个方法,可能并不适合所有人,也还有很多地方可以进一步完善。

最后,我再强调一点,如果只是为了使用好一个工具,你不需要彻彻底底的理解所有内容,因为你的时间是有限的。如果你真的是抱着学习的态度去研究源码细节,那请做好花费大量时间的准备并坚持下去。

有哪些更好的方法或者建议,欢迎留言评论。

更多内容欢迎关注同名微信公众号: 游戏开发那些事

这篇关于如何学习大型项目的源码?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1101788

相关文章

java 恺撒加密/解密实现原理(附带源码)

《java恺撒加密/解密实现原理(附带源码)》本文介绍Java实现恺撒加密与解密,通过固定位移量对字母进行循环替换,保留大小写及非字母字符,由于其实现简单、易于理解,恺撒加密常被用作学习加密算法的入... 目录Java 恺撒加密/解密实现1. 项目背景与介绍2. 相关知识2.1 恺撒加密算法原理2.2 Ja

Nginx屏蔽服务器名称与版本信息方式(源码级修改)

《Nginx屏蔽服务器名称与版本信息方式(源码级修改)》本文详解如何通过源码修改Nginx1.25.4,移除Server响应头中的服务类型和版本信息,以增强安全性,需重新配置、编译、安装,升级时需重复... 目录一、背景与目的二、适用版本三、操作步骤修改源码文件四、后续操作提示五、注意事项六、总结一、背景与

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整