时常能在知乎一些文章的评论区中看到有人问文章作者你是怎么读源码的,但是文章的作者可能早已将这种方法内化于心,难以说出个所以然来。
常言道授人以鱼不如授人以渔,分享阅读源码的方法也许比分享某个具体模块的源码分析心得更加重要。因此,应一些读者朋友的要求,写下这篇文章。
心态
我觉得在开始学习之前首先要明确一下心态的问题= =……吧。
1.首先是UE的代码量长达几百万行,而我们在看源码时往往看个上千行代码就已经头晕眼花了。虚幻引擎的代码量,决不是个人开发者可以读完的。哪怕穷尽此生,我们能学习到的,也只是虚幻引擎的十不足一。大钊在直播时坦言每一次引擎更新,我又激动,又害怕。激动的是引擎又有新的功能,害怕的是自己更加学不完。
因此我觉得研究虚幻引擎源码的读者应该像大钊说的那样与自己和解,与自己妥协,坦然承认没错,我的确学不完,然后但是学不完又怎么样?吾生有涯而知也无涯,但是学一点有学一点的收获,进一寸有进一寸的喜悦
2.然后是比起好奇心更应该保持耐心。好奇心固然重要,毕竟没有好奇心你也压根提不起兴趣去研究源码。但是耐心也很重要。耐下心,踏踏实实地读文章,画图,起初看起来一团乱麻的东西,渐渐地自然就会豁然开朗。
当然,直到最后也搞不懂的情况也很多。这时我觉得应当克制,将这个问题记录下来,留待以后去解决。很多时候不懂某些东西往往是自己在某个方面的知识有欠缺而不自知,等以后功力上来了,或者机会到了,自然就会豁然开朗,而且退一万步说,连你这种深入研究引擎源码的人都搞不懂的东西,别人自然更不懂了,在工作中的影响也不会大,所以没必要逼自己一定要弄懂。
3.其次是希望读者朋友可以保持谦逊,自信和开放的心态……我自己也在不断尝试去做到这些:
谦逊指的是意识到自己的渺小,无论是UE庞大的源码库,还是众多比自己强无数倍的大佬巨巨,深刻感受到人外有人。也要意识到自己今天的成就并不是因为自己有多么厉害,更多只是因为时运使然,机缘巧合罢了。
自信指的是清楚地意识到自己渺小,但是不会自卑,也不会强求自己去和那些大佬比肩(有的大佬从小学就开始学编程,开始积累沉淀,有的人惊才绝艳……人和人之间是难以比较的)。只需要和过去的自己比,感受到自己是在踏踏实实地进步,这样就足够了。
开放指的是不固步自封,不认为自己的观点就是对的。怀着谦逊和开放的心态,思考别人的观点,敢于改变自己旧有的认知。毕竟如果讨论的人自身并没有打算放弃自己的观点,那讨论就没有任何价值。
4.最后是希望读者对于那些一直坚持做分享的前辈,开拓者,可以心存感激。毕竟写文章是要花非常巨大的时间和精力的,他们并没有义务做把自己的知识分享出来,因此对于愿意分享的人,我觉得像大钊前辈说的那样心存感激,应该是比较好的。
学习步骤
下面我将先从自己每一次读源码时的学习步骤开始讲起。
1.首先确定自己这次要学什么,UE那么大,不确定一个比较明确的主题,即使是看源码也不知道从何看起。比方说想要学习UE的内存管理,这个主题就比较泛,可以再细分成UE的垃圾回收,智能指针,FMemory这几个小块来分别学习。
2.确定好要学什么之后,先尝试在网上找有没有前人写过的技术分享文章、博客。前面的人在从零开始研读源码之后以文章的形式为我们留下的宝贵财产,要好好利用起来,以节省我们的时间。找到几篇质量比较高的之后,就可以先通读一遍,然后自己一边看源码一边结合着读了。
这样的技术文章一般主要分布于知乎,博客园,CSDN(现在已经狗都不用了),简书等网站上。其实源码看得多了,那些经常做技术分享的大佬,名字都已经很眼熟了。比如南京周润发,风恋残雪,可可西,带带大师兄等等。
当然也有少数时候你连一篇技术文章都找不到,这个时候就要考虑换一换搜索关键词,把要搜索的东西更加细化或者更加泛化,中译英或者英译中,把想看的源码中某个比较主要的类放上去做关键词。然后如果还是真的啥都找不到,就可以去官方文档中搜索,去UE的提问论坛上,去谷歌上搜索。如果连这也一无所获的话,那恭喜你,你成为了这一部分源码的开拓者之一,如果你研究完了之后写下文章,那将会为后来的研究者开辟出更加宽广的道路(快进到后来者写的文章都引用了你的那篇)。
对于很多人来说,其实前两步就已经够了。但是读源码这种事本来就不是人人都会干的,读都读了,何不百尺竿头更进一步?接下来的几步要介绍的就是如何更加精益求精,使得你能在读源码时学到更多东西,保持更久的记忆。
3.画图。这一点在大钊的中文直播中也有特别提到,有一说一,画一张思维导图真的可以大大大大大大大大大大大大大大大大加快你理解的速度。思维导图画什么并没有特殊的要求,你可以用思维导图记录下层层嵌套的函数调用,也可以用来表示类和类的关系,也可以表示一个类底下的成员变量和方法之间的联系……都可以,只要是能帮助你更好的理解源码的都行。
为什么是思维导图,而不是UML图呢?大钊在直播说了自己的亲身经历:画UML图,你一半以上的时间都拿来调格式,调排版了。而且以人的脑容量,根本不可能处理的好那么多类之间的关系。所以我现在都是画思维导图,相比UML图更方便,也更灵活。
那用什么画思维导图?很多人第一反应想到的是Xmind,MindMaster之类的。它们除了要付费以外的确没什么缺点,只是这个价格并不是还未工作的学生可以承受的……
免费的思维导图自然也是有的,在这里推荐两款:
1.百度脑图(已停止更新,但仍然可以使用)
缺点是没有关联线,对于样式的自定义设置还不够友好。在知犀出来之前是个好东西,知犀出来之后就给比下去了。
2.知犀思维导图
这个是我一直在使用的思维导图。我每篇研究源码的文章也都会附带上对应的思维导图,都是用知犀做的。支持关联线,支持比较高度的自定义,支持导出成png,pdf,word等格式,支持在线分享,颜值也很高……而且最重要的是对个人使用者是完全免费的。(不过有开放捐赠通道) 同时支持Windows,安卓,Mac等多平台,也可以直接在网页上编辑。缺点是不支持导出成Xmind格式,但是允许导入XMind格式。(所以以前是XMind的读者朋友可以把自己以前的思维导图移过来)
现在也还在不断的更新,相比早已停更多年的百度脑图,强!
除了画思维导图也可以画流程图(虽然我感觉思维导图其实就可以充当流程图的功能了),推荐ProcessOn。能把流程图画明白了说明你是真明白了,当然画流程图的过程本身也能帮助你的理解。
4.写文章。(只适合责任心比较强的)很多人也有写笔记的习惯,不过我的个人看法是,写文章>画思维导图>写笔记。虽然做笔记可以帮你加深印象,减慢遗忘(后面忘了也能看笔记回想起来之类的),思维导图可以帮你整理思绪加快理解,但是都没有写文章来的有用。
能把别人教明白了,你才是真的明白了。在写文章的过程中,因为要对读者负责,所以你得不断拷问自己,不能允许自己把某些东西含混过去了,似懂非懂。知之为知之,不知为不知。知道的东西就会想尽办法给读者讲清楚,讲明白,不知道的东西就会尽力去查更多资料,看更多源码来试图弄懂,真的不懂时也会坦然承认。当然,这一切的前提都建立在你有较强的责任心,想要对看你文章的读者负责的前提上。在文章中说了未经考究,可能是错误的话,是有可能误导无数后来的读者的。
除了这个教学相长的因素以外,我想谈谈自己是抱着什么想法去写文章的:
一个是想要将对以前帮助过我的前辈们 的这份感谢的心情传递下去,既然我难以回报这份谢意,就只能做力所能及的事,像他们一样去帮助这条路上的后来者。写文章就是方式之一。
另一个是想要让社区中有更加良好的分享的风气。如果每个读了源码的人都想要藏着掖着,生怕别人也会了,自己的竞争力就降低了——那么国内游戏领域将会是一片死水,因为每个人的精力都是有限的,缺乏交流,一味的闭门造车,是难以进步的。最终每个人会的东西都很有限,只有个别天才才能吃到大蛋糕。
而如果大家都把自己所学的东西分享出来,不是去分蛋糕,而是把蛋糕做大,那么国内游戏行业的人才就会不断涌现,整体的技术力也会不断的上升,国内游戏做的好了,卖的动了,落到我们这些程序员手里的钱才能变多。
希望读者朋友也能有这样的想法。
5.调试源码,跟着流程跑一遍。这样有助于明确整个执行的流程。这一块我的经验太浅,于是就直接引用大钊前辈的中文直播内容了。
不过以我个人的经验来说,如果对于阅读源码的深度没那么高的要求的话,其实也没有必要跟着调试的步骤走一走流程。我个人觉得对于好奇心比较重,想要更加精益求精,尽善尽美的读者来说,可以这么干。
工具篇
1.网易有道云词典
这个软件的翻译能力较为优秀,而且支持截屏翻译的功能。笔者因为不擅长英语,所以经常用它翻译源码的注释。
2.Everthing
该软件相比Windows自带的搜索功能更为强大,可以有效地搜索想要的文件。比如现在你身处xxx.h文件中,想要定位到xxx.cpp去,那么利用Everything可以快速地找到它。
3.VS+番茄助手
番茄助手相比VS原生的功能,拥有更加优越的代码联想,补全,以及定位功能。即使不是为了读源码,想要写虚幻C++一般也会装一个番茄助手。
4.知犀思维导图 / ProcessOn
前面介绍过了,一个字,好!
5.Markdown
写文章用word或者知乎提供的编辑器固然可以,不过我觉得Markdown更加好用。知乎也支持直接导入Markdown格式的文档。Markdown学起来也很快,ctrl+shift+Q创建引用块,ctrl+shift+K创建代码块,ctrl+B加粗,Ctrl+数字键1~5设置标题等级,主要就这几个功能。用两下就会了。
6.学习双拼
文章写得多之后,真的感觉打字打多了手累。学双拼可以大幅度降低你敲键的次数。只不过从开始学,到恢复至你全拼时的打字速度,需要一个月的适应期。(而且有时候打英文也会想用双拼打,比如tour会手快打成tzr之类的,这个倒是小问题)
其它技巧
1.善用VS的搜索功能
Ctrl+F 或者 shift+F12。比如我想找一下A函数到底被谁调用了,我就可以用Ctrl+F在h文件,或者cpp文件中找一找。如果有时这个文件被其它文件所引用,那就能用shift+F12来在多文件中查找对函数/变量的引用。
2.打打断点
在读源码的时候,如果想要观察函数的流程,想要知道是谁调用了这个函数(第一个步骤中说的有时难免会有遗漏),那就在源码中打上断点然后运行。值得一提的是,需要读者去github上下载UE的源码,然后在自己的电脑上编译一次,否则打在引擎内部的断点是不会被触发的。编译需要的时间可能要几个小时,需要80G以上的硬盘空间。(我之前就因为硬盘空间不够一直迟迟没能弄上= =……)
我调试源码的经验较少,就不妄谈了。
3.遇到问题时先记录下来,在接下来的学习源码的过程中也许就会解决。如果出现了学完了还没解决的情况,就像我在心态篇说的那样,等着以后出现一个契机解决,或者解决不了也没关系。
最后
如果读者看了这篇文章之后,下定决心和我一样成为创作者,愿意为国内社区分享知识与技术,一起把蛋糕做大的话——那就应该能体会到,同为创作者,虽然初心并不是为了点赞,也许只是抱着想要加深自己的理解之类的想法而写的文章,但是点赞确实能够提供很好的正面反馈。
所以,还请屏幕前的各位,以后多多为看到的文章点赞吧,哪怕只是收藏想要以后再看,也不妨顺手再按个点赞(知乎收藏量是点赞量的两倍几乎已经是传统了……但是这也并不是什么好事)
感谢
等众多前辈,没有你们,也就不会有我的这些文章。谢谢你们的分享与对我的帮助,我会努力把这份感谢的心情传承下去的。也谢谢那些一直愿意给我点赞的读者。今后我也会继续创作下去的 。
参考:[中文直播]第12期 | 虚幻C++进阶之路 | Epic 大钊哔哩哔哩bilibili(强烈推荐读者朋友去看一看这期直播,这期直播给我的UE学习生涯带来了重大的影响)
于是我们就,下次再见吧~
评论0