美文网首页技术程序人生E_Coder
这样读源码,不牛X也难

这样读源码,不牛X也难

作者: 安晓辉0 | 来源:发表于2016-04-25 07:19 被阅读12697次
    源代码

    程序员在工作过程中,会遇到很多需要阅读源码的场景,比如技术预研、选择技术框架、接手以前的项目、review他人的代码、维护老产品等等。可以说,阅读源代码是程序员的基本功,这项基本功是否扎实,会在很大程度上影响一个程序员在技术上的成长速度。

    2014年写《Qt on Android核心编程》和《Qt Quick核心编程》时,很多内容都是通过分析Qt源码搞明白的。这阵子研究CEF和PPAPI,也主要靠研究源代码来搞明白用法。最近工作上要修改已有项目的一个子系统,也是得硬着头皮先读懂代码。

    总之在开发工作这十来年中,读过太多源码了,从源代码中学习到太多东西了,如果不阅读源代码,真不知道自己能否成长起来。

    写代码是从模仿开始的,提高也是从观摩别人的优秀设计和代码开始的。所以阅读源码至关重要,接下来咱从下列方面聊聊阅读源码的事儿。

    • 目的
    • 工具
    • 知识准备
    • 运行与开发环境
    • 笔记
    • 实用技巧
    • 心理调试(散步在各个环节)

    目的

    当我们阅读面前的源码时,无非有以下几种目的:

    • 纯粹学习
    • 添加新功能
    • 重构旧代码
    • 修复他人的Bug

    不同的目的会有不同的心情,会影响到工作的进展,像修复他人的Bug这种事情,类似于没被掰弯的男猿捏着鼻子给另外一个男人擦屁股,是很恶心的,很容易让人拒绝的。所以因这种目标而阅读源码,往往是欲拒还迎、欲说还休,效率较低。然而修复实际工作中帮别人修复Bug这种情形,十有八九你要遇到,无可逃避。所以,心理调试很重要。

    为了学习去读源码,这是最愉快的最放松的。不过提醒一点,设定可检验的目标才会有收获,否则就会像走到大街上看见一美女擦肩而过那样,惊艳一下下,过后嘛关系嘛收获也没了。

    其他的目的,重构旧代码、添加新功能,比帮别人擦沟子(陕西话,屁股)略强,因为他带有创造性,创造性的活动能给人带来强烈的愉悦,所以虽然这两种目的也有很多让人不爽的部分,不过想到我可以让一棵老树焕发青春,不爽也就慢慢弱下去了。

    工具

    工欲善其事必先利其器,这是亘古不变的道理。要很好的完成阅读源码的任务,我们大概需要下列这些工具:

    • SourceInsight,最好的源码浏览工具,它能维护符号库,动态显示上下文,还能绘制调用关系图,最好的,没有之一
    • 纸质笔记本,随时记录心得和疑惑,随时绘制各种图(类图、时序图、框图),比UML工具快,也比Visio快
    • 中性笔
    • 记事本、Notepad++、有道云笔记、为知笔记等,记录阅读源码过程中的关键点、心得体会、分析过程
    • Visio,用于绘制简单的框图,表述源码的模块划分、层次结构等
    • StartUML,用于最后绘制类图、时序图等,方便交流
    • 扫描全能王(CamScanner),一款可以通过拍照达到扫描效果的App,可以用它扫描你在纸质笔记本上写下的文字,绘制的框图,分享给其他人,如果你懒得用软件绘制图标,那手绘之后扫描成电子档就最适合你了

    知识准备

    前戏很重要,准备好了后面水到渠成快感不断,否则就会频频受挫直感道阻且长。

    • 业务基础,每一份有实际意义的源码都离不开业务,必须先对业务有概念
    • 技术基础,这个源码用什么语言,什么框架,什么第三方模块,都需要先有所了解
    • 文档,尽量找到业务、需求、概要、详细等文档,帮助会很大,然而,我们经常面临的情况是,只有源码,只有源码,只有源码,片言只字的文档也无,所以只好坚信——源码是最好的文档。这个心理门槛儿其实也容易过,你就想像着源码只是神仙姐姐的画像,看再多画像也不抵当面一眼效果强大——要么摧毁三观要么魂牵梦萦
    • 人,搞明白哪个程序员维护过这份代码,方便后面不懂时请教,有时人家点一下顶你自己瞎琢磨一天

    运行与开发环境

    • 配置好开发环境,目的是为了调试,对有些程序员来讲,调试是弄明白软件内部机理的最好方法,按着F5、F10、F11、F9,一切都搞定了
    • 配置好运行环境,为使用软件、体验软件做准备,从用户角度,从外面看看软件到底是怎么回事,便于揣摩内部逻辑

    笔记

    在阅读源码的过程中,做笔记是必须的。我有这样的体会,因为代码不是自己写的,很难很快在脑子里刻下印记,经常是看着这里忘了那里,早上觉得弄懂了数据流向,中午吃个饭就忘了。所以,笔记就显得尤为重要。

    • 找到适合你的记录方式,小本本、软件皆可。用软件(Notepad++、有道笔记、为知笔记等)来记录有个坏处——必须切换屏幕,会在形式上中断代码阅读过程。所以我经常在紧张得不能中断时随手用笔写些断句残章在本子上,告一段落时梳理下用软件再记录。
    • 尽可能详细的记录,但不必看到什么记录什么,要间隔性的记录,比如弄明白了某个子模块的逻辑、某个类的作用、某些函数的调用关系时再记录,否则记录这个动作本身会打断思考
    • 每天工作结束,记录进度(弄明白的部分),记录疑问,记录第二天要弄明白什么东西,这样你的工作状态就入栈了,第二天来了很容易出栈,快速进入工作状态
    • 记录看到的优秀设计,提高审美,见贤思齐,自我成长

    沧海遗珠

    我在漫长的读码生涯里积攒了一些的经验,算是碎碎念,供参考:

    • 理清某一业务如何映射在代码执行流程上的,这点很关键。
    • 理清不同模块间的业务关系,代码调用关系,很关键
    • 调试是弄明白代码调用流程的最快方式,之一
    • 找出关键代码(代表实际对象的类、衔接不同模块的类、代表业务关键节点的类)
    • 分析日志可以帮助分析代码执行流程和业务流程
    • 先用已有的可运行软件,体验业务,琢磨你点这里一下点那里一下代码可能是怎么做出反应的
    • 阅读应该围绕目的,把实现目标放在第一位,比如修改Bug,如果有期限,在最后日期前搞定是第一要务,然后有时间就继续读源码或改进Bug修复方案,力求没有副作用和后遗症,再有时间就修修别人留下的破窗户(你也可以顺带鄙视下前任维护者)
    • 千万次的问,还记得前面说要弄明白谁维护过你要读的代码吧,别不好意思,问吧,问吧,问吧
    • 对着设计文档、接口文档或测试用例看代码
    • 心理调试,勿畏难,别放弃。我有时看代码,看两天也不知道看了个甚,一头雾水两眼发花是常有的事儿,有时真是觉得搞不定了,然而,这要么是你基础知识没准备好,要么是你找错了入口,要知道,任何一份代码,都有一条隐形的线串着,耐心点,总会找到。这样不行就那样,多换换角度,多换换方法,读不行,就调试,调试不行,就运行,运行不行,就研究日志,都不行,我靠,while(!i.isDead())i.analyzeCode(),跟Y死磕!总之,你不放弃自己,就没人能放弃你!
    • 给自己设置小奖励,弄明白某个逻辑或某个模块的代码后奖励自己休息一下,5~10分钟,走出办公室转转,或者干脆在网上瞎逛一下,浏览自己喜欢的网站
    • 读不懂才要读,想不明白才要想,这是进步和成长的开始。那些阻挡你的蹂躏你的而杀又不死你的,终将帮助你成长让你变得更强大。

    相关阅读

    相关文章

      网友评论

      • a2e9c6797ac4:喜欢源代码,写得很好!
      • Hey_大晨:多谢
      • 梦还梓:可以
      • ZoarYu:谢谢作者,写得真好.学习一下,记个笔记.
      • ae5a32942062:你好😊这篇文章很棒,我想把它分享到我们学校的一个平台上让同学们学习学习可以吗?
      • 735a341226a2:同!!!!!!!!!!!!!!!!!!
      • 神经旷野舞者:QT quick 和 QT android什么区别,没接触过QT
      • 1914d5d70b6a:◑▂◑
      • 69d4d308f442:分析的很好,值得借鉴
      • 0976aa15c169:作者是陕西哪块的啊
      • 点妮子:写的不错,也是在不断的看优秀源码,模仿学习过程中:smile:
        安晓辉0:@点妮子 是啊,模仿是好的开始。
      • shangjing:写的真不错,赞
        安晓辉0:@shangjing 谢谢
      • f2ad83637a44:我工作中写了一些代码,可能技术难度不高的原因,更多的是看document API,很少遇到需要阅读源码的场景,倒是看了不少sample demo的代码,大部分都是从这些demo中学习的,都是工作中需要用到的部分才去找去看,看完就能马上拿来用的。文中说的时序图、动态分析工具,对于大型复杂而又陌生的系统才有必要。根据我个人经验,断没有理由为了看源码而看,还整那么多工具笔记。甚至对于学生来讲,除非需要你重构,否则都没有必要从时序图的层次去分析源代码。与其学习从头到尾彻彻底底(按照文中介绍的工具和方式)了解一份源代码,倒不如先确认自己想要构建什么系统,然后各处搜集阅读源代码,画自己的时序图,写自己的源代码,发布并公开api,提高他人的效率,才配得上“大牛”的称号
        安晓辉0:@shanquan 有道理哦,不过如果你想学习好的设计,观看api是不够的。如果你接手已有系统,更需要看怎么实现的。
      • eb4b3b89f712:就像学英语单词是“砖瓦”,学编程代码是基础,从基础开始垒砖瓦,一步一步构筑自己的编程大厦
        安晓辉0:@乌托邦的守卫 对呢。
      • 溪西:支持!学习中~
      • 134bbc1ccd62:这篇文章刚好用到 最近准备大量阅读源码 顺便整理下心得 先用为知记录下 再发布到个人博客 感谢作者的心得分享
        安晓辉0:@asii 太好了,我希望自己的文章有用。
      • 784831c3363d:我是做ios的,最近也在学习第三方框架,感觉有困难。还有以下几个问题:
        1、学习框架的源码具体是学什么?
        2、不同类型(视图、非视图)的框架,各应从哪些方面入手?
        3、做好准备工作后,开始正式看代码了,凭您的经验有没有什么规则?(比如先看哪里、再看哪里)。
      • 金戈大王:哇,原来Qt那两本书是楼主写的,太厉害啦😜
        金戈大王:@foruok 真的很给力,去年我做毕设用Qt,网上资料太少了,全靠你这两本书才完成的,非常感谢~
        安晓辉0:@金戈大王 谬赞,当时血气之勇,现在写不来了。
      • efc168f9d45b:阅读源码
      • 苧erSunShine:很感谢作者,最近正好也在看一份项目源码,因为是已经快做完才让我接手的,看的有点头疼,虽然也做了一些记录,但感觉记得不全,在后面我会借用你的方法去分析,相信会很有收获,谢谢🌹🌹🌹
        安晓辉0:@苧erSunShine 希望有帮助 :smile:
      • 大黄蜂2018:除了在技术圈看到这种文 都觉得无意义 更多是为了吸引眼球
      • YeZhou:加油,最近想看LINUX源码,先从LINUX内核设计与实现看起。
        安晓辉0:@YeZhou 看吧,看下来,收获肯定很大
      • b9a860a4d173:最不喜欢的维护别人的代码! 还得按照别人的逻辑来!
        b9a860a4d173:@foruok 现在我我写的代码逻辑弄得很复杂! 需求一改再改。。。。。。不能怪我为难后来人 :stuck_out_tongue_winking_eye:
        安晓辉0:@oviovi 有时难免要委屈下自己……
      • 罗曼蒂克:支持,写得很不错
      • 821765af5c0a:文章是好文章,挺有借鉴意义的!不过最后有个地方,而杀又不死你的,好像有点问题~~,其他都挺好
        安晓辉0:@曦為 哦,是吧,我回头再改改,谢谢。
      • jkhmnk:配点图会更好些
      • 袁赋豪:支持!!!!!好文
      • shenmeguia:作者看的都是啥代码
      • dc8c8e4ab226:这个还真的有点点拨作用,不错 :smile:
        安晓辉0:@justinlinsong 有用最好了,开森
      • 麦当劳叔叔:支持下咱老陕
        安晓辉0:@耶西安 :smiley:
      • 4c2fe3adc1d7:赞赞赞 各种看不懂的代码
      • c4857242be80:写的很好,点赞,喜欢,开始不再迷茫
        安晓辉0:@QWERASDF 哇,这么有用,开心。!!!
      • 后端沉思录:写的很好!
      • a93ea8ead53c:帮顶,顺便马住
      • Tsing2015:握爪,基本上工作六年都是在阅读代码,基本上也是用你提到的工具,
        安晓辉0:@Tsing2015 哇,所见略同啊。 :+1:
      • mkitclear:不错,刚好最近在看源码,正好就是那种没有一字文档的那种,老师还一直在催进度。用你的逻辑就是,在看一堆莫名其妙的shit,然后别人还一直追着你问这堆shit里的营养成分是什么?!WTF,有什么你自己吃下去不就知道了!!!
        f2ad83637a44:如果你真觉得是shit,不管老师如何催,你也可以不用看,自己去优化它重构它。可我担心的是,如果都搞不懂源码的内涵和结构,仅仅因为自己看不懂就排斥骂shit,那可能真正shit的不是它,而是你的心态。
        mkitclear:@且涉烟尘 你没有,你是纯洁的,污的是我
        安晓辉0:@且涉烟尘 我有说SHIT啊?居然不记得了
      • AKAE:作者好污啊 不过我喜欢 :kissing_heart:
        安晓辉0:@AKAE :sunglasses: 污?No!
      • 小哥奇葩:我最讨厌看代码啦!!
        小哥奇葩: @foruok C语言,C++,数据结构,算法设计,计算机图形学 为了不挂科个个都拼的😂
        安晓辉0:@小哥奇葩 必修课哦
      • littledust:正在看代码,基础也不牢,人生惨淡
        安晓辉0:@littledust 看多了就牢了,牢不可破
      • 窗框:我去研究一下作者那个软件怎么用
      • wxflyme:丫的,作者辛辛苦苦的写了,尽然没人评论,攒下人气,那就我来咯,话说一楼耶 :wink:
        wxflyme:@foruok sourceinsight有Mac版么
        安晓辉0:@wxflyme (⊙o⊙)… :joy:

      本文标题:这样读源码,不牛X也难

      本文链接:https://www.haomeiwen.com/subject/zypfrttx.html