怎么阅读学习源代码 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
lynn0977
V2EX    Python

怎么阅读学习源代码

  •  1
     
  •   lynn0977 2020-02-09 23:18:33 +08:00 8388 次点击
    这是一个创建于 2085 天前的主题,其中的信息可能已经有所发展或是发生改变。
    想通过阅读一些开源项目,提高自己的知识水平,怎样学比较高效,希望大家分享一下自己的方法和经验。
    28 条回复    2020-05-16 10:00:52 +08:00
    suotm
        1
    suotm  
       2020-02-10 00:09:39 +08:00   1
    刚好在看一篇博客,推荐你去看一下,关键词是:
    Become a Better Developer by Reading Source Code Steve Gordon
    secondwtq
        2
    secondwtq  
       2020-02-10 00:23:02 +08:00   3
    你问对时候了,新鲜出炉的: http://www.yinwang.org/blog-cn/2020/02/05/how-to-read-code
    webshe11
        3
    webshe11  
       2020-02-10 00:23:43 +08:00
    恰好我最近也看到一篇博客: https://www.yinwang.org/blog-cn/2020/02/05/how-to-read-code (水深火热)
    webshe11
        4
    webshe11  
       2020-02-10 00:24:14 +08:00
    @secondwtq 哇 我们几乎同时发的
    wanguorui123
        5
    wanguorui123  
       2020-02-10 00:25:13 +08:00 via iPhone
    单步调试
    AX5N
        6
    AX5N  
       2020-02-10 02:32:19 +08:00   1
    王垠这个不适合普通人(菜鸟)看,普通人看别人源代码主要是为了提高见识,对自己的知识盲区查缺补漏。
    AX5N
        7
    AX5N  
       2020-02-10 02:32:54 +08:00
    比如网银说
    ```
    很多人误以为看大型项目可以提升自己,而没有看到大型项目不过是几十行核心代码的扩展,很多部分是低水平重复。几十行平庸甚至晦涩的代码,重复一万次,就成了几十万行。看那些低水平重复的部分,是得不到什么提升的。
    ```
    AX5N
        8
    AX5N  
       2020-02-10 02:33:48 +08:00
    比如王垠说

    很多人误以为看大型项目可以提升自己,而没有看到大型项目不过是几十行核心代码的扩展,很多部分是低水平重复。几十行平庸甚至晦涩的代码,重复一万次,就成了几十万行。看那些低水平重复的部分,是得不到什么提升的。

    普通人都不知道什么叫做低水平重复,什么叫做垃圾代码,不去看看怎么知道呢。
    IRuNamu
        9
    IRuNamu  
       2020-02-10 02:39:36 +08:00 via Android
    c++步下指跳根本看不的清下 有什么好方法看源
    OldPanda
        10
    OldPanda  
       2020-02-10 07:27:36 +08:00   1
    刻意的看开源代码只会让自己痛苦,花费大量时间精力而不知所得,我一般会带着几分好奇和几分兴趣,比如说自己写的某个小项目用到了,或者突然对某一块知识感到很有兴趣,找到优秀开源代码的片段,详细推敲别人是如何实现的,为什么这样实现,感觉这样比“别人都说这个项目好,那我也来看看”从而阅读源码的效果好得多
    jie170601
        11
    jie170601  
       2020-02-10 07:29:44 +08:00 via Android
    同求好方法,断点调试可以搞清楚某些细节的具体实现,但难把握整体,又没有文档,怎么看比较好
    shiltian
        12
    shiltian  
       2020-02-10 08:03:44 +08:00 via iPhone
    王垠有一点说的我很赞同,就是得先知道这个代码是做什么的,再去看具体的代码。但是很多时候这个前提并不是那么显然,也不是那么容易得到,这个时候我觉得就只能反复的看,像编译器的 bootstrap 一样,这一次理解这么一点,然后和之前理解的结合起来再看下一遍。
    由于我的研究方向就是编译器,所以最近半年一直在读 LLVM 和 OpenMP 的代码。一开始的时候先 gdb 加断点看调用栈,然后再从这一点开始慢慢展开,一遍遍看,慢慢就来感觉了。有了这个感觉再从一个更高角度再去看,之前不理解的部分慢慢就又能懂一些了。这个过程就是一直不停迭代一直到全部理解。颇有一种深度学习那不停迭代最后收敛的感觉。
    levelworm
        13
    levelworm  
       2020-02-10 09:31:15 +08:00
    我觉得对于我这样的初学者来说,比较痛苦的就是怎么挑项目。其实代码质量好坏也无所谓了,反正太坏的也看不下去。但是主要的困难在于选取和自己水平恰当的源代码。也许初学者本来也不用看代码,还是需要有一定水平才需要看。
    zfish
        14
    zfish  
       2020-02-10 09:34:29 +08:00
    推荐使用 sourcetrail 阅读,体验还不错,对 C/C++/Java/Python 语言支持,其他语言还不行
    hyy1995
        15
    hyy1995  
       2020-02-10 09:39:51 +08:00
    我是找别人的技术博客看,先搞懂技术点的实现。

    如果一上来就直接去看源码,肯定蒙蔽。源码经过了好多年的迭代,里面有很多代码是补丁,或者是为了兼容性,真正的核心代码片段不是很容易单独提出来看。
    azcvcza
        16
    azcvcza  
       2020-02-10 10:01:06 +08:00
    针对问题去看吧。想想这些框架拿出来都是为了解决什么问题,如果不用框架你又会怎么解决,尝试造最小化轮子去试验功能,带着问题和解决方案去看估计会有点成效
    Leigg
        17
    Leigg  
       2020-02-10 10:06:50 +08:00 via Android
    先学会这个东西怎么用,并且足够好用,再从你使用的地方进入源码开始看。
    securityCoding
        18
    securityCoding  
       2020-02-10 10:50:17 +08:00   1
    一定带着问题看代码,脑子里面没有疑问看代码是没有作用的,反复复盘思考自己真的理解了吗?核心思路能自己独立实现一遍吗?
    netty
        19
    netty  
       2020-02-10 10:57:38 +08:00   1
    1.了解一下整体架构,相应的组成部分,以及各模板的大概作用。
    2.明确你阅读源码是为了目的?
    不要回答说就是为了学习,学习啥?太泛通常落实不了。容易失败,没有成就感,还受打击。

    由点到面去学习,每次只选一个点。这样,目标明确了,难度降低了,最后看懂了还能获得成就感,进入下一关。
    比如 1 )如何进行初始化 2 )如何监听端口 3 )如何实现单例 4 )如何动态扩容 5 )如何实现哈希
    3.写个 demo,调用一下 API,感受一下
    4.单步调试
    5.总结执行流程和关键代码
    qiumaoyuan
        20
    qiumaoyuan  
       2020-02-10 11:01:37 +08:00
    netty
        21
    netty  
       2020-02-10 11:06:25 +08:00
    @secondwtq
    王老师提到的,洞察到最关键的东西,最近刚好写了一篇文章,我觉得有点类似,分享一下:
    《掌握这些,你也能徒手实现 ArrayList、Vector 和 Stack 》
    https://mp.weixin.qq.com/s/zhDLb3vpbb70abXyFfucww

    不想看文章的,就看里面这段总结吧:
    写到这里,我们来总结一下掌握本篇内容的核心步骤:
    1.学会数组的基本操作,重点是插入、删除和扩容;
    2.基于数组的基本操作,完善并实现 ArrayList ;
    3.在 ArrayList 的基础之上,对所有方法加上同步原语 synchronized,实现 Vector ;
    4.继承 Vector,利用的几个基本方法,实现 Stack 的入栈出栈操作。
    通过以上几个步骤,能够更加高效的学习,更好的理解 ArrayList、Vector 和 Stack 这几个类的实现原理。
    netty
        22
    netty  
       2020-02-10 11:07:23 +08:00
    @qiumaoyuan
    最后还要尝试去对关键逻辑自己实现一下
    ofooo
        23
    ofooo  
       2020-02-10 13:55:28 +08:00
    要是王垠把他的几百行的深度学习框架开源出来就好了。。。。
    wanglufei
        24
    wanglufei  
       2020-02-10 14:10:23 +08:00 via Android
    @ofooo 怎么能让你偷学,然后出去装 X(手动狗头)
    Youen
        25
    Youen  
       2020-02-10 16:52:11 +08:00
    可以从测试入手, 跟着测试代码进去

    随便看看也是有收获的, 比如提高自己的代码"品味", 看到一些代码新姿势等..
    chenqh
        26
    chenqh  
       2020-02-10 17:00:36 +08:00 via Android
    看源代码我看的好慢,我看 tornado 断断续续看了一年,感觉还是生的不行
    encro
        27
    encro  
       2020-02-11 21:11:46 +08:00
    非常好的题目,根据你的题目我刚写了一篇短 Blog。

    如何通过阅读源代码学习?
    https://c4ys.com/archives/2034

    分为三个部分:
    1,有选择的阅读
    2,阅读步骤
    3,学习的要点

    总体思路是带着问题学习。
    YiyangILiu
        28
    YiyangILiu  
       2020-05-16 10:00:52 +08:00
    这个问题我也有感觉。我的想法是:

    1. 一定要带着好奇心和问题阅读框架,看得少没关系,看懂是目的
    2. 第一遍看最好手写一遍
    3. 看懂一步再看下一步
    4. 很多时候因为自己没参与封装的过程,经常出现看到一个点牵扯出三个新的不懂的点。或者更通俗地说,应该深度优先阅读还是广度优先阅读呢?我的方法是,只多看一层。
    比如 pandas DataFrame 类中一个 rename 方法( https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rename.html),函数本身有 8 个 arguments,在 example 中用到了两个 arguments,别的都是默认。那我不熟悉这个方法的话,看 doc 不仅看用到的 2 个 arguments,另外的没用到的 6 个也要学学怎么用。但是更深入一层呢?比如 level 这个参数,如果不懂 pandas 中的 MultiIndex 概念是不能理解它的。那要不要为了理解这个参数去再深入一层,学习 MultiIndex 的概念和用法呢?这时就可以考虑一下,我既然没用过 MulitiIndex,我不理解没关系。这个简单的例子就是深度一层的含义。

    最近一直在阅读一个中小型框架的源码( github 总代码 6K 行左右),是深度学习方面的。这个框架的作用是用两行实现一个 2K 行左右的自然语言处理模型。
    其中第一行是实现一个分词器,也就是 tokenizer,这个 tokenizer 在框架内的实现大约 300 行,其内又有方法若干。第二行是实现一个语言模型,模型在框架内的实现大约 900 行。其内又有方法若干。
    最终,我使用好奇心和一点一点手写的办法,把这些给复现出来了。写完后发现自己很多一开始不理解的问题迎刃而解了。我对模型处理的流程比较理解了,让我复述一遍没问题。但是内部的数学运算还不能说特别理解,很多当时复现的时候就一知半解。

    比如 keras.backend.reshape()( https://www.tensorflow.org/api_docs/python/tf/keras/backend/reshape), tensorflow.einsum()( https://www.tensorflow.org/api_docs/python/tf/einsum),这些函数说实话不难,看例子都能看懂,但是当实操的时候,特别是操作一些四维的 Tensor 的时候,我就犯迷糊了,每个维度都有自己的物理含义,比如 sequence_length 是句子长度, hidden_size 是特征维等等。只能说不断地看不断学。

    我觉得之前一个答案说得好,看源代码就像迭代学习一样,每看一点就理解深一点,想看一遍就会基本不可能。其实世界上大多数事情都是这样,学习是个渐进的过程,特别是前沿的东西,都是在渐进中提高的。
    就比如 github 某个成熟项目源代码量 10k,但是翻 commits 记录,addition 至少是 lines of code 的 3-4 倍。10k 量级源代码,addition 40k 左右是正常的。不可能有哪个框架从 0 写到完成没有修改的。有经验的框架作者如此,学习者就更不能好高骛远了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2077 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 00:59 PVG 08:59 LAX 17:59 JFK 20:59
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86