初学者如何阅读源码?_初学者直接看底层源码-程序员宅基地

技术标签: 程序员  java  编程语言  java程序员  源码  

原文:How to read code – a primer
原文作者:technikhil

我喜欢编程,它也是我的工作,而且我很高兴能够将大部分的时间都花在开发软件上。像许多程序员一样,我既着迷但又困惑的是,我写的代码到底怎么样,以及如何写得更好。

多年来,我已经阅读了许多有关软件开发的文章和书籍。其中不乏有许多墨宝(书上的或者网上的)告诉你如何提高编程,并成为一个像忍者一样的受过专业训练的编程高手!这些建议大多有一些共性,其中之一就是阅读源码。然而相比于其它建议,阅读源码通常也就是简单的一句话来概括:找一些很棒的开源软件,或是任何你喜欢的软件,打开它们(或打印出来)然后阅读它们。虽然总的来说,这确实是个很好的建议,但纸上得来终觉浅,实际去实践的时候才发现问题多多。在这篇文章中,我会尝试给出一些阅读源码的实用建议,但在这之前,首先让我们列举一下都有哪些问题。

对阅读源码的误解

别人一说阅读源码,给你的一般印象似乎他们就像编程大师一样,可以单纯地坐在椅子上,然后像看小说一样读着手上的代码。好吧,我敢肯定,确实有一些精湛的程序员,他们可以很享受地一边喝着咖啡、一边看着一堆类似英语句子的神秘符号,并且还能够在脑海里构建整个类的层次和体系结构。显然这篇文章并不是给他们看的,它的受众是像我一样的,觉得盯着一堆源码看就好比看一些无聊没有意义的练习题的人。

当然,有人会争辩说,可以从一个完整项目里一点一点地看单个类或者单个函数来学习,但在我看来,除非是最简单的问题,大多数软件内部都是相互依赖的。在不了解系统其余部分的情况下,通常不可能理解一个特定函数或者类背后的设计思想和原理。

下一个问题是从哪里获得可以读的源码(当然,在此之前,你得能够鉴别哪些源码值得一读)。优秀的软件很多,既有开源软件可以免费获得,也有闭源软件需要授权。开源仓库有譬如 Sourceforge 和 GitHub 。如果你在软件开发公司工作,那么可以访问源代码库中的专有代码。

第三种常见途径是软件开发书籍附带的程序,或者作为教育资源而提供的程序( Minix 是典型的例子)。确实,众多的选项使我们难以抉择,因此从茫茫代码世界中找出适合我们阅读的是一项艰巨而必不可少的任务。

另一个问题是程序所用的编程语言,读他人的代码已经足够困难了,如果同时还需要去熟悉一门夹杂着奇葩语法的新语言,它所带来的负担,在我看来简直就是个会带来极大挫败感的灾难。所以你需要找到用你熟悉的语言所编写的代码。但如果你要看的代码是来自书本上或作为教育资源所提供的,那懂不懂这门新语言并无关紧要,因为有导师可以解释上下文。倘若你明知山有虎偏向虎山行,在没有书或者导师指引下,去阅读一门并不熟悉的编程语言,那我建议你至少需要学习,并达到可以写出自己的程序的程度(Hello World 就不算了哈)。

前文有关上下文的问题使我想到了下一个问题,如果你不熟悉软件本身,弄清楚代码在做什么就困难得多。例如,如果你不是每天都在使用 Linux 并知晓 Linux 启动顺序,那么就很难在看一边 Linux 代码后弄清楚运行级别是什么。使用某个软件获得的经验、知识能够帮助我们更好地阅读它的源码,这包括常用的术语、软件的功能和特性,甚至包括你遇到的各种错误本身。

理解源码

对我而言,我意识到 “阅读源码” 并不能准确描述我所从事的活动,用 “理解源码” 来表述会更合适。对我来说,坐在笔记本屏幕前(或打印成纸),只是单纯地读满屏的代码是非常困难的。我需要代码之外其它的东西,比如我喜欢翻一翻文档,玩一玩这个软件,单步运行代码甚至写测试代码去跑一跑,然后才能真正欣赏它。因为我会为此投入非常大的时间和精力,所以我必须要精挑细选,寻找我要 “阅读”(理解)的软件。

我的第一层过滤是通过编程语言进行筛选,对我来说,我只阅读由 C#、VB.NET、Python 和 Javascript 编写而成的程序的代码(尽管我也熟悉 C++、Ruby 和 F#,但我并不认为自己有水平来理解其他人的代码)。接下来是寻找我使用过的软件,这会让我有种已经上车的感觉,因为我知道代码的意图,以及它不能做的事情还有它的局限性(如果我足够熟悉的话)。每天都在使用的开源软件正是优秀的候选项(比如,我使用用 C# 编写的开源工具 Cruise Control.NET、NANT 和 NUnit)

碰巧我在一家软件产品公司(一家微软的公司)工作,所以我阅读的源码选择项之一是我们公司在源代码库中的代码。如果碰巧你也在一家软件公司工作,你可以查看其他的项目,甚至你着手项目的较早期版本。
这样,除了可以获得更深层次的代码理解之外,你还可以很好地了解之前和之后都曾尝试过哪些东西。不过有一些警告需要注意:

首先,如果你没有权限访问其他项目,则需要征得许可,因为一些公司对其 “知识产权” 非常看重。

其次,这些软件的质量可能没有你想像的那么高,因为通常情况下,专有代码没有经过像开源代码那样严格的代码走查。需要注意的是,如果缺乏常规的代码审查,那么代码的质量可能不佳。

第三(这一点是从我的朋友提供的反馈中得到启发的),如果你的公司开发的是商业软件(HR、财务、ERP 等),则需要首先理解很多业务关系。而且,由于大多数代码受业务功能因素的影响,因此通常模块化程度不如应用程序或 API 高。

寻找文档齐全的项目(这适用于开源以及专有代码)。我的意思是说,这样的文档应该突出总体设计,并说明代码背后的原理。如果只是简单地自动生成的 Java Doc 类型文档,则不能视之为我所描述的文档 。

其中一种寻找途径是利用为教育而创造的软件(例如 Minix)。由于它们的目的是通过软件进行教学,因此通常会有非常清晰的文档记录下来,并且有大量资料解释代码背后的设计原理。

总结

那么,现在你已经确定了要阅读源码的软件并下载了它的源代码和文档,让我们一步步阅读并理解它:

浏览设计文档,并尝试了解代码的构建方式。好的软件项目遵循某些架构模式,这些决定了代码的组织。一旦掌握了这一点,理解代码就变得容易了很多。如果你还能画出类图,就能更好地了解整体布局。

接下来要做的是编译并运行它。根据项目及其文档循序渐进,这可能很简单也可能很困难。

现在是时候打开你喜欢的 IDE 并开始探索了。一个好的探索起点是,尝试一步步浏览你熟悉的功能的代码。这样一来,你可以遍历各个层和子系统,并了解它们之间的关联。例如,当我探索 NUnit 时,我首先编写了一个测试用例,然后查看涉及到的类。

尝试确定代码中使用的设计模式。如果你还不知道什么是设计模式,那么立刻马上停止看本文,转去阅读设计模式的经典书籍。熟悉设计模式,它们是识别和理解优秀代码中所包含的设计的好方法。熟悉之后就可以更轻松地在阅读代码时将其牢记在心。它还可以帮助你更轻松地识别代码作者在原有设计模式上所做的细微调整和魔改。

尝试为代码编写测试用例以完全理解它,这是理解代码不同部分之间的依赖关系的一种非常有用的方法。写测试用例之前,首先需要满足所有的依赖。接下来,了解代码的可能的入口点和返回值。这可以增进你对代码的理解,助你更上一层楼。

最后,尝试重构代码。在这一步,你已经从单纯地理解代码迈向足够熟悉以能够对其进行修改。随着重构复杂程度的提高,你的理解也将随之增加。此时,如果需要,你可以为项目贡献自己的代码。

“源码阅读”在我看来,不仅仅是阅读,它是一组独特的活动,共同帮助人们理解代码。这似乎比简单的 “阅读代码” 更令人生畏,但它值得付出努力。

现在,你可以更加轻松,快乐地“阅读源码”了吗?

零基础学习Java编程可以加入我的十年Java学习园地

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_49794051/article/details/112306428

智能推荐

基于SSM和MySQL的企业人事管理系统的设计与实现_基于ssm的企业人事管理系统的设计与实现参考文献-程序员宅基地

文章浏览阅读484次,点赞2次,收藏2次。管理员进入主界面,软件开始运行,提供用户登录功能,不同的用户登录操作的功 能不同,非管理员用户登录只能查看一些公告信息等,而管理员登录后,可以进行用户 管理丶部门管理、职位管理、员工管理、公告管理等功能。基于其他企业人事管理软件的不足,要求能够制作一个可以方便、快捷的对员工信 息进行添加、修改、删除的操作,为了能够更好的存储职工的信息,可以将职工的信息添 加到 Word 文档,这样,不但便于保存,还可以通过 Word 文档进行打印。员工信息的管理:维护员工的基本信息,用户可以进行员工档案信息的录入及更改,_基于ssm的企业人事管理系统的设计与实现参考文献

【C语言】手撕二叉树

【C语言】手撕二叉树

Postgresql源码(127)投影ExecProject的表达式执行分析

无论是投影还是别的计算,表达式执行的入口和计算逻辑都是统一的,这里已投影为分析表达式执行的流程。

hive启动beeline报错

出现上面的问题执行以下代码。

【Hadoop】-Hive客户端:HiveServer2 & Beeline 与DataGrip & DBeaver[14]

DataGrip是由JetBrains公司推出的数据库管理软件,DataGrip支持几乎所有主流的关系数据库产品,如DB2、Derby、MySQL、Oracle、SQL Server等,也支持几乎所有主流的大数据生态圈SQL软件,并且提供了简单易用的界面,开发者上手几乎不会遇到任何困难。3、连接成功,在里面我们可以看到我们前面章节所创建的表,这样子就可以在里面操作我们的sql语句的。5、连接成功,在里面我们可以看到我们前面章节所创建的表,这样子就可以在里面操作我们的sql语句的。

java lambda无法使用_java – 为什么不允许lambda函数?-程序员宅基地

文章浏览阅读1.2k次。我一直在Vaadin的GUI中工作,有一些来自我的IT主管的课程.这一切都很棒,但是,今天,我遇到过我不能在addListener方法类型中使用lambda表达式.此方法是自定义的,作为使用它的对象.这是实施:public class ResetButtonForTextField extends AbstractExtension {private final List listeners= n..._java: -source 1.5 中不支持 lambda 表达式

随便推点

FRTC8563时钟芯片的主要特性和应用场景

一款实时时钟(RTC)芯片,它采用SOP-8封装,这种封装形式使得芯片具有较小的体积和良好的引脚连接稳定性,便于集成到各种电子设备中。:该芯片采用低功耗技术,使得在待机状态下功耗极低,有助于延长电池寿命,特别适合用于便携式设备或长时间运行的系统。:FRTC8563基于稳定的晶振工作,能够提供准确的时钟和日历信息,包括年、月、日、星期、小时、分钟和秒等。:芯片支持较宽的电压范围,使其能够适应不同设备的电源需求。提供准确的时间戳和日历信息,支持设备的时间同步和事件记录。:在便携式仪器仪表中,由于其低功耗特性,

wetrtc简介

wetrtc简介

单片机基于ST25DV动态标签的无线通信_st25dv能量采集-程序员宅基地

文章浏览阅读651次。利用I2C有线链路,任何NFC智能手机或NFC/RFID HF专业读卡器以及MCU均可以访问存储在这些标签中的数据,并且支持掉电保存。这些标签的集成度和性价比极高,可提供丰富的功能集,适用于各种应用。此外,开发人员可从评估板、软件工具、移动应用和其他资源构成的完整生态系统中受益,从而加快应用开发速度。在物联网产品的开发过程中,物联网设备非接触式向外界提供可变的交换信息非常有必要,比如路由器向手机提供可配置的WiFi信息,巡检点向手机提供动态的传感器数据等等。_st25dv能量采集

自己搭建 Linux 服务器踩坑记录_建立服务器踩过的坑-程序员宅基地

文章浏览阅读149次。前言妈蛋,自己搭建一个Linux服务器居然能遇到这么多坑。特此整理下,方便下次遇到同样的错误时能够回过头来快速定位问题并解决问题Number 1,服务器重启之后,Xshell 连接不上注:在服务器重启之前,我只安装了 jdk ,配置了 /etc/profile 环境变量,我一直以为是这个原因,后面把jdk 配置注释掉也没用正确的方向应该是先查看 ssh 服务有没有启动键入命令systemctl status sshd.service如果你的显示跟红框一样 【dead..._建立服务器踩过的坑

MT4606-VB_MOSFET产品应用与参数解析-程序员宅基地

文章浏览阅读187次。通过控制20Vgs (±V)的门源电压,可以实现开关管的导通和截止,实现对电流的控制和开关状态的转换。MT4606详细参数说明 - 极性 N+P沟道- 额定电压 ±30V- 额定电流 9A (N沟道), -6A (P沟道)- 导通电阻 15mΩ @ 10V (N沟道), 42mΩ @ 10V (P沟道), 19mΩ @ 4.5V (N沟道), 50mΩ @ 4.5V (P沟道)- 门源电压 20Vgs (±V)- 阈值电压 ±1.65Vth (V)- 封装类型 SOP8。_mt4606

达梦启云平台中,部署使用HIVE笔记_达梦sql中hiveing-程序员宅基地

文章浏览阅读637次。启云平台部署hive_达梦sql中hiveing