代码之家  ›  专栏  ›  技术社区  ›  RJFalconer

熟悉大型代码库的最佳方法是什么?[关闭]

  •  73
  • RJFalconer  · 技术社区  · 16 年前

    加入一个已有大型代码库的现有团队可能会让人望而生畏。最好的方法是什么?

    • 广泛;尝试从代码中大致了解所有内容是如何连接在一起的
    • 窄;一次只关注代码的小部分,了解它们如何充分工作
    • 选择要开发和学习的功能
    • 尝试从类图和UML(如果可用)中获得洞察力(并且是最新的)
    • 还有别的吗?

    我正在研究什么是一个近似20K的线C++应用程序和库(编辑:小东西的宏伟计划!)在工业界,我想你会得到一个有经验的程序员的介绍。但是,如果情况并非如此,您可以做些什么来尽快开始增值?

    ——
    答案摘要:

    • 在调试模式下单步执行代码以查看其工作原理
    • 与比你更熟悉代码库的人配对,轮流是编码人员和观察/讨论人员。在团队成员中轮换合作伙伴,这样知识就会传播开来。
    • 编写单元测试。从你认为代码如何工作的断言开始。如果结果如您预期的那样,您可能已经理解了代码。如果没有,你有一个难题要解决,或者有一个查询要做。(多谢唐纳,这是一个很好的答案)
    • 以与上面类似的方式,通过现有的功能代码单元测试
    • 阅读UML、Doxygen生成的类图和其他文档,以获得对代码的广泛理解。
    • 进行小的编辑或修复错误,然后逐渐积累
    • 记笔记,不要跳入并开始开发;花时间理解比生成混乱或不适当的代码更有价值。

    这篇文章是 the-best-way-to-familiarize-yourself-with-an-inherited-codebase

    19 回复  |  直到 9 年前
        1
  •  24
  •   Brian R. Bondy    16 年前

    如果可能,从一些小任务开始,围绕您的问题调试代码。 在调试模式下单步执行代码是了解某些东西如何工作的最简单方法。

        2
  •  17
  •   user8599    16 年前

    另一种选择是为您感兴趣的特性编写测试。设置测试工具是一种很好的方法,可以确定系统具有哪些依赖性以及其状态所在的位置。每个测试都从一个关于您认为系统应该如何工作的断言开始。如果结果是这样的话,你已经取得了一些成果,并且有了一些可工作的示例代码来重现它。如果不是这样的话,你就有一个难题要解决,还有一系列的问题要解决。

        3
  •  10
  •   Russell Bryant    16 年前

    我通常向尚未提及的人建议的一件事是,在成为开发人员之前,成为现有代码库的合格用户是很重要的。当新开发人员进入我们的大型软件项目时,我建议他们花时间成为专家用户,然后再潜心研究代码。

    也许这是显而易见的,但我已经看到很多人试图过快地跳到代码中,因为他们渴望开始取得进展。

        4
  •  9
  •   Draemon    16 年前

    这完全取决于你是什么样的学习者和什么样的程序员,但是:

    • 宽泛的第一-你需要一个范围和规模的概念。这可能包括略读文档/UML,如果它们很好的话。如果这是一个长期的项目,你需要对每件事都有一个全面的了解,我可能会正确地阅读文档。再一次, 如果 它们很好。
    • 狭隘地选择一些可以管理的东西并试图理解它。对代码有一个“品味”。
    • 选择一个特性——如果你有信心的话,可能是和刚才看到的不同的特性,然后开始做一些小的改变。
    • 迭代——评估事情进展的如何,看看是否可以从更深入地重复早期步骤中获益。
        5
  •  7
  •   Grundlefleck anujkk    16 年前

    配合严格的旋转。

    如果可能的话,在浏览文档/代码库时,尝试使用具有严格旋转的配对。也就是说,你们两个坐在一起一段固定的时间(比如两个小时的会议),然后你们交换一对,一个人将继续完成这项任务,而另一个人将和另一个伙伴一起完成另一项任务。

    两人一组,你们都会学到一点知识,然后当轮换发生时,这些知识会被反馈给团队的其他成员。还有一个好处是,当一对新的代码组合在一起时,完成任务(在本例中是研究代码)的人可以用更容易理解的方式总结和解释概念。随着时间的推移,每个人都应该有一个相似的理解水平,并希望避免“哦,只有约翰知道这一点代码”综合症。

    从我对您的场景的了解来看,您有一个很好的数字(3对),但是,如果您是分布式的,或者不在同一个时间范围内工作,这是不可能的。

        6
  •  5
  •   Paul Nathan    16 年前

    我建议在上面运行doxygen以获得最新的类图,然后再进行一段时间的广泛讨论。这给了你一个快速的大图,你可以使用当你接近和肮脏的代码。

        7
  •  4
  •   user29227    16 年前

    我同意这完全取决于你是哪种类型的学习者。说了这句话,我在两家公司工作过,他们的代码库非常庞大。通常,我这样工作:

    如果可能的话,在查看任何功能代码之前,我先完成已经编写的单元测试。这些通常能帮上不少忙。如果它们不可用,那么我将执行以下操作。

    首先,我在很大程度上忽略了实现,只查看头文件或类接口。我试着了解每门课的目的。第二,我从看起来最重要的领域开始,深入到实现的一个层次。这是很难衡量的,所以有时候我只是从顶部开始,在文件列表中一路向下。我称之为广度优先学习。在这个初始步骤之后,我通常会深入了解代码的其余部分。最初的宽度优先查找有助于巩固/修复我从接口级别获得的任何想法,然后深度优先查找向我展示了用于实现系统的模式,以及不同的设计思想。我指的是深度优先,你基本上是使用调试器逐步完成程序,逐步进入每个函数,看看它是如何工作的,等等。这显然不可能在真正的大型系统中实现,但20K LOC并没有那么多。:)

        8
  •  3
  •   Avdi    16 年前

    与另一个更熟悉系统的程序员合作开发新特性或修复错误。这是我见过的最好的方法。

        9
  •  2
  •   KevDog    16 年前

    我认为你需要把这个和一个特定的任务联系起来。当你手头有时间的时候,选择你想要的任何一种方法。

    当你有事情要做的时候,给自己一个狭隘的焦点,然后完成它。

        10
  •  2
  •   Leigh Caldwell    16 年前

    让团队让你花两个星期(如果你有两个星期的话)。他们会很乐意找人来负责这件事,到这段时间结束时,你会花很多时间在图书馆解决问题,你可能会很清楚。

        11
  •  2
  •   Cervo    16 年前

    如果它有单元测试(我敢打赌它没有)。从小处开始,确保单元测试不会失败。如果你一眼盯着整个代码库,你的眼睛就会变得呆滞,你会感到不知所措。

    如果没有单元测试,您需要关注您想要的特性。运行应用程序并查看功能应影响的结果。然后开始查看代码,试图找出应用程序是如何创建您想要更改的内容的。最后更改它并检查结果是否符合您的需要。

    你提到它是一个应用程序和一个图书馆。首先更改应用程序,并坚持将库作为用户使用。那么,在你学习了图书馆之后,你就更容易改变了。

    从一个自上而下的方法来看,这个应用程序可能有一个主循环或者一个控制所有操作的主GUI。有必要了解应用程序的主要控制流程。阅读代码是值得的,它可以让你对应用程序的主要流程有一个大致的了解。如果它是一个图形用户界面应用程序,那么就创建一张纸来显示有哪些屏幕以及如何从一个屏幕切换到另一个屏幕。如果是命令行应用程序,则说明如何完成处理。

    即使在公司里,采用这种方法也不少见。通常没有人完全理解应用程序是如何工作的。人们没有时间带你到处转转。他们更喜欢具体的问题,所以你必须自己去钻研和实验。然后,一旦你得到了你的特定问题,你就可以试着为应用程序的那一部分隔离知识的来源并提出问题。

        12
  •  2
  •   Robin Bennett    16 年前

    首先要了解“问题域”(它是工资单系统吗?库存?实时控制或其他)。如果你不理解用户使用的术语,你将永远无法理解代码。

    然后看看对象模型;可能已经有了一个图表,或者您可能需要对其中一个进行反向工程(手动或者使用道格建议的工具)。在这个阶段,您还可以调查数据库(如果有的话),如果应该遵循对象模型,但它可能不会,这很重要。

    看看变更历史或bug数据库,如果有一个领域出现了很多问题,请先看看这个部分。这并不意味着它写得不好,但它是每个人都使用的。

    最后,做一些笔记(我更喜欢wiki)。

    • 现有的人可以用它来理智地检查你的假设并帮助你。
    • 你以后需要再参考一下。
    • 团队中的下一个新人会非常感谢你。
        13
  •  2
  •   Mohsin Shafique    15 年前

    我也有类似的情况。我想说你是这样的:

    • 如果它是一个数据库驱动的应用程序,那么从数据库开始,尝试了解每个表及其字段,然后了解它与其他表的关系。
    • 一旦底层存储正常,就向上移动到ORM层。这些表在代码中必须有某种表示形式。
    • 一旦完成了这项工作,就可以继续了解这些对象的来源和来源。接口?什么接口?有验证吗?在它们进入数据存储之前,对它们进行了什么预处理?

    这将使您更好地熟悉系统。记住,只有当您非常了解单元测试时,才能尝试编写或理解单元测试。 什么 正在测试和 为什么? 它需要在 只有 那样。

    如果大型应用程序不是面向数据库的,我建议使用其他方法:

    • 系统的主要目标是什么?
    • 那么解决这个问题的系统的主要组件是什么?
    • 每个组件之间有什么交互作用?制作一个描述组件依赖关系的图。问问已经在做这件事的人。这些组件必须相互交换一些东西,所以也要设法弄清楚这些东西(比如IO可能会将文件对象返回到GUI等)。
    • 一旦适应了这一点,就可以深入到其他最不依赖的组件中。现在研究该组件如何进一步划分为类,以及它们如何相互作用。这样,您就可以掌握一个组件的全部功能。
    • 移动到下一个最不相关的组件
    • 最后,移动到核心组件,它通常依赖于您已经处理过的许多其他组件。
    • 在查看核心组件时,您可能会引用前面检查过的组件,因此不要担心继续努力工作!

    对于第一个战略: 以这个stackoverflow站点为例。检查数据存储、存储的内容、存储的方式、这些项在代码中的表示方式、这些项在UI上的显示位置。它们从何而来,一旦它们返回数据存储区,会对它们进行什么处理。

    对于第二个 以文字处理器为例。有哪些组件?IO、UI、PAGE等。它们是如何相互作用的?随着学习的深入继续前进。

    放松点。写代码是一个人的思维定势,冻结了逻辑和思维方式,阅读它需要时间。

        14
  •  2
  •   unintentionally left blank    10 年前

    首先,如果您有对代码有经验的团队成员,您应该安排他们与您一起概述代码。每个团队成员都应该向您提供他们专业领域的信息。多人解释事物通常是有价值的,因为有些人比其他人更善于解释,有些人比其他人更能理解。

    然后,你需要在没有任何压力的情况下开始阅读代码一段时间(如果你的老板会提供的话,几天或一周时间)。它通常有助于您自己编译/构建项目,并且能够在调试模式下运行项目,这样您就可以单步执行代码。然后,开始弄湿你的脚,修复小虫子,做一些小的改进。希望你很快就能准备好一个中等规模的项目,然后是一个大项目。在你走的时候继续依靠你的队友-通常你可以找到一个特别的愿意指导你的人。

    如果你挣扎的话,不要对自己太苛刻-这很正常。理解一个大的代码库可能需要很长的时间,甚至是几年的时间。事实上,通常情况下,即使经过多年,代码的某些部分仍然有点可怕和不透明。当你在项目间休息的时候,你可以深入到那些领域,你会发现,经过几次尝试,你甚至可以找出那些部分。

    祝你好运!

        15
  •  2
  •   Andreas Haferburg    9 年前

    你可以考虑看看 源代码逆向工程 工具。我知道有两种工具:

    这两个工具都提供类似的特性集,其中包括静态分析,该分析生成软件中模块之间关系图。

    这主要由调用图和类型/类缺陷组成。查看这些信息可以让您很好地了解代码的各个部分是如何相互关联的。利用这些信息,您可以深入了解您最感兴趣的部分的实际来源,以及您首先需要了解/修改的部分。

        16
  •  1
  •   David Turvey    16 年前

    我发现仅仅是跳到代码中可能有点压倒性。尽可能多地阅读有关设计的文档。这将有希望解释每个组件的用途和结构。如果一个现有的开发人员可以带你通过它,那是最好的,但这并不总是可能的。

    一旦您对代码的高级结构感到满意,就尝试修复一两个bug。这将帮助您掌握实际的代码。

        17
  •  1
  •   dicroce    16 年前

    我喜欢所有的答案,比如说你应该使用像doxygen这样的工具来获得类图,并且首先尝试理解全局。我完全同意这一点。

    也就是说,这在很大程度上取决于代码的分解程度。如果真是一团糟,那就很难学了。如果它干净,组织得当,就不会那么糟糕了。

        18
  •  1
  •   Community CDub    7 年前

    this answer 关于如何使用测试覆盖工具来定位感兴趣的特性的代码,而不知道该特性在哪里,或者它是如何跨多个模块分布的。

        19
  •  0
  •   zvikico    15 年前

    (前面无耻的营销)

    你应该退房 nWire . 它是用于导航和可视化大型代码库的Eclipse插件。我们的许多客户使用它通过打印出主要流的可视化效果来侵入新的开发人员。