`
webcode
  • 浏览: 5940875 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

阅读代码真的很难

 
阅读更多

编者按:原文作者Eric Lippert是一名资深软件设计工程师,从1996年起一直在微软开发部门任职,协助设计并实现VBScript、JScript、JScript .NET、Windows Script Host、Visual Studio Tools for Office 和 C#。

  Escalation的工程师JeremyK在他博客中问到:

  你是怎么教人们快速深入挖掘不熟悉的代码(不是自己所写的)?我学习如何编程的方法很传统 —— 自己动手编码。但我现在很纠结:到底是集中精神阅读源码,还是自己编写。对我而言,似乎唯一有效的方法就是自己写过。

  不是和Jeremy开玩笑,写代码的确没有读代码难。

  首先,我同意你的看法,几乎很少有人能读代码但不会写代码。这不像自然书面语或口语,理解他人的意思并不需要去理解他们为什么要那样说。比如,如果我说:

  “写代码有两种方式:一种严格且详细,另一种模糊且草率。前者生成简洁分层的婚礼蛋糕,后者却是意大利面条。”

  上面这句话产生一个平衡且幽默的效果,但即使听众和读者不理解我使用“零照应”和“并列句”这样的文字技巧,也会理解我要说的意思。但是说到代码,既要从代码本身中理解代码作者的意图,又要理解代码产生的预计效果,这两者都极为重要。

  因此,我又回到那个问题了,有些人需要快速切入代码,但不需要动手写代码,那我们如何编写适合这些人的代码?

  下面是我在编写代码时,尽力去做的事,目的就是使其他人能轻松阅读:
  • 使代码遵从工具。Object Browsers和Intellisense虽然很好,但我告诉你,我是守旧派。如果找不到我想要的,我会不高兴。什么使得代码成为可查询的呢?
    • 像"i"这样的变量名不好。如果没有明确的错误提示,你就无法轻易查找代码。
    • 避免使用是其他名字前缀的名字。比如,在代码中有个“perfExecuteManifest”,如果再有一个“perfExecuteManifestInitialize”,这就会让我抓狂,因为每次在源码中查询前者时,我不得不费力地过滤掉后者所有的实例。
    • “临时传递数据”(tramp data)应使用相同的名字。所谓“临时传递数据”(tramp data),就是指那些传递给方法A的变量,还要传给方法B的变量。这两类变量实际上是相同的,所以如果它们有着相同的名字,则更好。
    • 别用宏来重命名东西。如果有个方法叫get_MousePosition,那别这样GETTER(MousePosition)来声明该方法。因为我会找不到实际的方法名。
    • Shadowing会引起很多问题,请不要用它。
  • 坚持使用一种命名模式。如果你打算用匈牙利命名法,那就坚持并广泛使用,否则将适得其反。使用匈牙利命名法来记录数据,而不是存储类型;记录普遍事实,而不是临时条件。
  • 使用断言来记录先决条件(preconditions)和后置条件(postconditions)。
  • 别缩写英文单词。确切来说,别缩写成稀奇古怪的形式。在脚本引擎中,有个变量名叫“NME”,这让我非常抓狂!它应当叫“VariableName”。
  • C语言标准运行时库的设计不是很优秀。别去效仿它。
  • 别写“聪明”的代码;当代码出现问题,维护代码的程序员没时间去理解你的聪慧。(编注:这条建议即为:编写可维护的代码,详情可参见《明星软件工程师的10种特质》中的第8点。)
  • 理解编程语言特性的设计初衷,使用这些特性去做它们适合完成的工作,而不是它们能做到的工作。例如:别把异常当做一般的流控制机制来使用(即便你能做到),而应该用它们来报告错误。别强制把接口指针转换成类指针,即便你知道这样没问题。
  • 按功能单元划分源码树,而不是按组织结构。比如:我目前所在团队中,有2个根子目录的名字是“Frameworks”和“Integration”,这是两个团队的名字。不巧的是,Frameworks团队名下有一个叫“Adaptor”的子目录,而“Adaptor”却是Integration的子目录,这就非常令人迷惑。同理,(如果)有着相同子目录的不同的子树,有些是客户端的组件,有些是服务端的组件;有些是管理组件,有些是非管理组件;有些是处理型组件,有些是非处理型组件;有些是零售组件,有些内部测试工具。这就会乱七八糟的。

  当然,我实际上根本没有回答Jeremy的问题——如何调试不是我写的代码?

  这取决于我的目的。如果我只是因为一个bug,而深挖一段具体的代码,我会在调试器中逐步跟踪所有代码,写下我“走过”的调用分支,记录下哪些方法是特定数据结构的“生产者”,哪些方法是“消费者”;我也会仔细盯着输出窗口,查看出现的有用信息;还要打开异常捕捉器,因为异常通常是问题所在。设置断点;我会记录所有和我上面建议相反的地方,因为这些东西很可能误导了我。

  如果我想在理解一段代码后修改它,我通常是从代码头部开始,或者先查找公共方法。我要知道类是如何实现的,它是如何扩展的,它的作用,它是如何嵌入整个代码中的?我会尽力理解这些东西后,才去了解这些特定部分(代码)是如何实现的。这耗时虽更长些,但如果你准备改动复杂代码,你应当那样做。
分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目源代码

    简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对IT的憧憬、向往!...

    如何看懂源代码.pdf

    很遗憾的是,上述的情况对程式人来说很难避免。我们总是必须碰触到其他人所写成的程式码,甚至必须了解它,加以修改。对 于这项需求,在现今开放原始码的风气如此盛行的今日,正如之前的“程式设计2.0 ”文中所提到...

    自己动手写操作系统(含源代码).part2

    我们有许多源代码公开的操作系统,可供随时下载和阅读,看上去好像让实现一个供自己把玩的微型操作系统变得容易很多,但事实往往不尽人意,因为这些代码动辄上万甚至几十几百万行,而且细节之间经常互相关联,要...

    自己动手写操作系统(含源代码).part1

    我们有许多源代码公开的操作系统,可供随时下载和阅读,看上去好像让实现一个供自己把玩的微型操作系统变得容易很多,但事实往往不尽人意,因为这些代码动辄上万甚至几十几百万行,而且细节之间经常互相关联,要...

    使用 AsyncIO 进行音乐排序的演示_python_代码_下载

    这真的很难推动 Python,如果是这种情况,您的 CPU 可能无法使用它进行实时音频:减少复音; 像往常一样,MIDI IN 和 AUDIO OUT 配置是通过配置文件完成的; 在 macOS 和 Linux(PulseAudio 和 ALSA)下进行测试,...

    abbreviations-in-code:程序代码中的常见缩写列表

    使用长名称(例如,number_of_connected_clients)总是很清楚,但是它需要额外的时间来阅读并且很难记住。 因此,如果可能的话,请选择一个较短的形式,但请注意保持您的姓名有意义和清晰。 请记住,随着范围的...

    C语言入门经典(第4版)--源代码及课后练习答案

    书中除了讲解C程序设计语言,还广泛介绍了作为一名C程序设计人员应该掌握的必要知识,并提供了大量的实用性很强的编程实例。本书的目标是使你在C语言程序设计方面由一位初学者成为一位称职的程序员。读者基本不需要...

    Openstack想说爱你不容易

    我喜欢读取代码的方式是按照情景阅读,比如在Lucene中跟踪索引的过程,跟踪搜索的过程,比如在Hadoop中,跟踪写入文件的过程,跟踪Map-Reduce的过程,于是在Openstack中决定跟踪虚拟机创建的整个过程好在很多先贤...

    STM32F4 处理器的 VGA 风格视频输出_Rust_代码_相关文件_下载

    主要是因为真的很难。我每个像素有四个 CPU 周期可以使用,任何时间变化都会破坏显示。 演示 演示main文件位于m4demos/src/bin中,尽管一些演示的核心实现已迁移到fx 目录。 conway:全屏康威的生命游戏,每秒 60 ...

    高质量C编程指南(林锐).doc

    (3) 真正的程序员几乎不写代码的注释,如果注释很难写,它理所当然也很难读。 (4) 真正的程序员不画流程图,原始人和文盲才会干这事。 (5) 真正的程序员不看参考手册,新手和胆小鬼才会看。 (6) 真正的程序员不写...

    高质量 C++/C 编程指南

    (3) 真正的程序员几乎不写代码的注释,如果注释很难写,它理所当然也很难读。 (4) 真正的程序员不画流程图,原始人和文盲才会干这事。 (5) 真正的程序员不看参考手册,新手和胆小鬼才会看。 (6) 真正的程序员不写...

    JAVA上百实例源码以及开源项目

    笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对IT的憧憬、向往!此时此...

    高质量的C++编程指南

    (3) 真正的程序员几乎不写代码的注释,如果注释很难写,它理所当然也很难读。 (4) 真正的程序员不画流程图,原始人和文盲才会干这事。 file:///D|/My Documents/学习/高质量C++-C编程指南.txt[2008-11-11 21:48:26...

    高质量C编程指南

    真正的程序员几乎不写代码的注释,如果注释很难写,它理所当然也很难读。 真正的程序员不画流程图,原始人和文盲才会干这事。真正的程序员不看参考手册,新手和胆小鬼才会看。真正的程序员不写文档也不需要文档,...

    高质量C++/C 编程指南

    (3) 真正的程序员几乎不写代码的注释,如果注释很难写,它理所当然也很难读。 (4) 真正的程序员不画流程图,原始人和文盲才会干这事。 (5) 真正的程序员不看参考手册,新手和胆小鬼才会看。 (6) 真正的程序员不写...

    为 ARM微控制器 构建前沿工具链的多合一脚本_shell_代码_相关文件_下载

    由于在“Linux 发行版 A”上构建一个可以在“Linux 发行版 B”上运行的二进制文件(其中“Linux 发行版 B”可能只是“几次升级后 6 个月后的 Linux 发行版 A”)真的很难(不可能?),不会有适用于 Linux 的二进制...

    高质量C++编程指南

    (3) 真正的程序员几乎不写代码的注释,如果注释很难写,它理所当然也很难读。 (4) 真正的程序员不画流程图,原始人和文盲才会干这事。 (5) 真正的程序员不看参考手册,新手和胆小鬼才会看。 (6) 真正的程序员不写...

    Vim+基础+进阶+使用手册+源码资源合集

    以我个人学习 vim 的经验来看,通过看文档或看其他人操作其实是很难真正学会 vim 的,你必须在实际应用中,进入真实场景才能逐渐熟悉并掌握相关命令。因此,为了同时满足学习和操作的需求,项目中的文件都采用了 ...

    阅读笔记:https:mohammadalwawi.github.ioreading-notes

    尽管我对编程一无所知,但是世界上的每件事都是使用技术,所以我很感兴趣学习这门课程,这门课是真的很难代码102阅读笔记文件名链接git VS github的 成长心态HTML 远程在GitHub上掌握Markdown Java脚本运算符和循环...

    Java 利用多线程实现文件的分片下载

    特别说明: Main方法是运行开始的方法,里面...里面很多地方我都有注释说明,阅读起来不会很难。当然,希望道友可以指出代码的不足之处,让我们共同进步。毕竟分享是一个过程,能力的锻炼才是我们真正追求的结果!

Global site tag (gtag.js) - Google Analytics