您认为代码是自我记录的吗?[关闭]


24

这个问题是多年前作为一次面试的研究生提出给我的,它时不时地困扰着我,我从来没有真正找到一个令我满意的好答案。

有问题的面试官正在寻找黑白答案,没有中间立场。我从来没有机会问过这个问题背后的原因,但是我很好奇为什么这个问题会交给开发人员,您将从是或否的答案中学到什么?

从我自己的角度来看,我可以阅读Java,Python,Delphi等,但是如果我的经理问我,问我在项目中走了多远,我说“代码已完成80%”(之前您开始将我击落,我听说过开发人员在几个办公室说过的话,那么自我记录到底有多准确?道歉,如果这个问题看起来很奇怪,但我宁愿提出询问并对此提出一些意见,以更好地理解为什么将其放在面试中。


6
我不会从是或否的答案中学到东西,而是从问这个问题的黑白答案中学到东西。我的回答是不会。去工作
mouviciel 2011年

12
不知道我明白你的问题,“自我记录代码”通常描述写得很好,很容易理解(意向)代码,没有真正涉及到进步AFAIK ...一些开发人员使用此方法,而不是代码注释...

1
@Nim- 评论等外,更常见的是,但对该评论+1。
Steve314 2011年

1
@ Nim,我对“自我记录代码”的含义有不同的定义,但是对我提出的问题的方式在我的脑海中翻译为“您可以查看那里的任何代码并理解您需要知道的一切吗?仅仅通过查看代码?”,也许我正在使它复杂化,但是如果再次使用它,我完全不知道该如何回答。那就是我的意思。
荒凉星球

1
@史蒂夫,我希望是这样。.<sigh />
Nim

Answers:


50

部分地。

使用大英文单词的代码可以部分自我记录,因为所有函数和变量的名称都可以告诉您它在做什么。但这可能不会告诉您原因。

比较:

a->b;
# what is b doing? what is the a object?

carEngine->startIgnition;
# much more clear what objects are involved

但是您仍然不知道为什么要启动汽车。因此,仅部分。您的面试官期待一个黑白答案是很可怕的,除非他的黑白观点包括很强的可能。


7
+1代码可以解释发生了什么,仍然可能无法解释为什么以这种方式(而不是其他方式)发生。
FrustratedWithFormsDesigner

24
+1我认为这是自记录代码应该做什么和注释应该做什么的最佳定义。代码应始终清楚地告诉您“什么”,注释应始终告诉您“为什么”。
Dan McGrath

9
您丢失了关键:清楚地说明正在发生的事情的代码也将清楚地向具有领域知识的读者解释为什么要执行的任务。这就是为什么在我的代码中,我通常不写注释-那些足够在意代码的人会知道它应该做什么,因此已经有了“为什么”了-但是当我在做时看起来不寻常或任意的东西,我将在评论中解释其必要性。
梅森惠勒

5
@梅森,不一定。例如,如果您有一个需要排序算法的地方,并且有一个非常清晰易懂的“选择排序”实现,但是您没有说明为什么需要这样做,而不是仅仅使用默认的排序例程。运行时库?(然后证明,交换两个项目非常昂贵,选择排序仅需要进行n次交换,而其他大多数交换则使用更多...)

4
如果该语句在名为InitiateCommuteToWork()或StartPreRaceSequence()的函数中,您将知道为什么要启动汽车。
Pemdas

33

否。代码本身不是自我记录。

原因是代码声明了HOW,而不在乎WHY,这是人类维护代码所需要知道的。

因此,您需要其他注释来解释所有WHY。您可以通过让变量名包含决策的某些部分来限制它们,但是您不能避免它们。


1
++确实如此。评论应该是“为什么”和“如何”之间的链接。
迈克·邓拉维

4
+1是为了强调评论会回答原因,而不是原因或原因。
oosterwal

有了这个答案,这个问题就很有意义了(不是80%的部分)。
用户未知

商定,文档不仅适用于程序员,还适用于企业用户。只需尝试向他们显示代码,然后看着他们的眼睛呆呆。
GrumpyMonkey 2011年

坦率地说,谢谢,为什么要经过2年的编程,才使我明白了注释代码的目的。
拉斐尔·埃姆肖夫


6

如果他们坚持黑白回答,不允许中间立场,那么答案是否定的。

更完整的答案是,代码应在合理的最大范围内自我记录,但是没有合理的方法在代码中包含某些类型的文档。仅举例来说,该代码可能会很好地记录以下信息:在表单A上收集哪些信息,在表单B上收集什么信息以及在表单C上收集什么信息。它通常不会(也可能不应该)尝试记录显示这种划分的测试。与(例如)仅使用两种形式而不是三种形式相比,以这种方式存储的数据减少了x%的错误。

除了最琐碎的代码之外,任何其他代码都可以从至少一些外部文档中受益。


5

我的答案。在最大程度上,您应该努力使代码尽可能地自我记录。这件事情是由很多原因导致的。最初编写时,平均每10行就有一个错误。往往会发现并纠正代码中的错误。文档中的错误往往会留下。在维护中,代码和文档经常会分开。

就是说,使代码清晰可完成的工作存在局限性。在这种情况下,您必须进行记录。

如果您可以选择记录文档呢?我的观点是,维护在很大程度上取决于您的组织。如果您拥有优秀的软件开发人员和严格的代码审查流程(例如Google),那么您的流程和人员就可以让您不必担心注释无法维护。在那种情况下,更多的评论风格很有用。(实际上,Google确实具有大量评论的风格。)但是,如果您拥有更典型的组织,那么我将非常不信任我看到的任何评论,并且希望您中有人相信试图使代码自我记录。在这种情况下,我认为评论是多余的。

有关进行评论的优缺点的有趣对话,请参阅http://www.perlmonks.org/index.pl?node_id=65153,以了解我曾经参与的旧对话。(请注意,在我们进行对话的同时,有一些私人聊天更为友好。我一直很后悔只有对话的负面部分是公开的。)我的观点不再完全符合我当时的想法,但我仍然认为对话值得我们深思。


1
+1可能会留下“文档错误”,尽管这还远远不够。这更像是“直到几年后,当有人注意到他们与代码不匹配时,才注意到文档中的错误”。
拉里·科尔曼

5

我发现这个问题很多,而且经常引起人们的宗教热潮。这是我的看法...

在理想的世界中,可以做出以下陈述:

代码应以这样一种方式编写,即无需注释即可遵循逻辑。

好的,这很公平,但是问题是我们没有生活在理想的世界中。实现这一理想陈述存在一些问题。

  1. 程序员通常不是他们所针对的行业专家。理解这样的功能很容易,例如startEngine(Car car)(大多数)每个人都可以理解这里的要求。但是,进入现实世界,事情变得有些模糊。例如,对于getSess(String tid, String aid)理解DWDM系统的运输工程师来说,该功能将是完全可以理解的,但对于刚投入该项目的新程序员而言,它可能会带来挑战。适当放置的注释可帮助您轻松过渡到及时理解代码。

  2. 要求维护代码的程序员通常不如代码的原始设计师那么熟练。原始程序员可能足够熟练,可以编写快速,简洁,高效的算法来完成特定任务。但是负责维护该代码的程序员可能难以尝试理解正在发生的事情。适当放置的注释可帮助您轻松过渡到及时理解代码。

  3. 您编写了几次代码,后来又难以理解为什么这么做,甚至试图达到目的?我们每个人都不时这样做。解决问题和产生易于解决的问题通常是两种不同的心态。除非您是能够完美地编写代码的人,否则在进行过程中,您经常会犯很多错误。您可能还可能暂时无法恢复到这段代码。 适当放置的注释可帮助您轻松过渡到及时理解代码。

  4. 特殊情况需要说明。例如,程序员可能想知道为什么在与DWDM设备通信的代码中放入100ms的暂停。让下一个程序员知道需要暂停,因为该设备的吸收速度很慢,并且可能会错过该命令,这将是有价值的信息。 适当放置的注释可帮助简化向及时理解代码的过渡。

写得很好的“自我记录”代码很容易找到。编写得很好的“自我记录”代码,加上位置适当,内容丰富的注释,这真是天赐之物,也是非常难得的发现。


4

只是为了对最初问题的每一面都提出意见:

是的,代码是自记录的。变量,方法和类名都可以使其易于阅读和理解,因此这是一种自我记录的形式。在代码风格中,最后可能会提供XML文档的某些内容被视为标准过程。换句话说,提供可能与代码混合在一起的文档是开发人员工作的一部分。

不,代码不是自记录文件。所做的业务决策,设计选择和其他因素不会出现在代码行中,而应在代码库之外写下。因此,外部文档是必要的,而这些只是示例。

问的要点:您会给出部分答案,以认识到答案的局限性吗?还是会盲目地偏向于您认为更好的做法呢?如果是或否,您的答案中有多少信念?它可能被认为是一个压力很大的问题,旨在使可能会回答以下问题的人反感:“这是什么??这是您可能问过的最愚蠢的问题。我拒绝以侮辱为由回答我的智慧令人难以置信!” 作为一个相当傲慢而自大的答案,我可以想象一些人以这种口吻给出答案。


4

显然他是Knuth风格的识字程序员。对于LP门徒来说,代码必须是自记录的,才能有效。因此,唯一可能的答案是“是”。

这里的问题是,识字的编程语言并不多,在广泛的商业用途中我也不知道。因此,它必须在某处处于利基地位。


我真的不同意识字编程的这种特征。在我看来,它更像是一本关于用当地人类语言编写的代码的书,恰好包含了供计​​算机参考的代码。:)
PeterAllenWebb

3

我认为面试官可能一直在寻找:“您如何编写自我记录代码?” 暗示“您对文档的态度是什么?”

一次,我参加了一个叫Robert C Martin的人的鼓舞人心的演讲,他在他的书中谈到了Clean Code一书的“编写方法”一章。

他显然提出了一些纯粹主义者的立场,但是我采纳了他的建议,即当您将代码分割成小的可重用方法并使用诸如以下的简单技巧时:

  • 将方法中的所有语句保持在相同的抽象级别
  • 将控制流条件或循环块的内容提取到方法调用中
  • 当您发现自己将相同的参数传递给一个类中的多个方法时,便会分离出一个新类
  • 还有一些简单的技巧,例如用方法调用替换神秘的布尔表达式
  • 等等...

您最终得到了易于理解的,有点自我记录的代码(只要您将精力放在简洁但描述性的名称上),该代码就易于理解和维护。

我发现这些东西确实很有帮助,但是要想做好,就需要了解设计模式,您肯定需要用类和高级方法文档来补充该方法。


3

通常,自记录代码是指对变量,函数等使用命名约定的做法,以使代码的目的显而易见。因此,没有代码本身不是自我记录。我不明白您在第三段中所指的是什么。这似乎与自我记录代码无关。


2

杰克·里夫斯(Jack Reeves)提出了令人信服的论点,即代码就是设计。就许多人而言,实际代码是唯一告诉您系统功能的“文档”。随着实时系统趋向于逐渐偏离设计系统,其他一切都会衰减。即使你是生成的代码文件(如许多UML工具可以做时下),它仍然是系统的唯一一个准确的文件在那个时间点

是的,代码是自我记录的。记录的好坏是另一个问题。


2

随着我变得越来越有经验,我了解到,真正的答案是代码和阅读器的环境决定了自我记录的水平。

为了最小化读者环境和作者环境之间的差异,我们添加了注释。需要的评论越多,通常作家的经验就越少。那里有一篇很棒的文章描述了软件开发的这一方面,但是我不记得是谁写的或者在哪里找到的。


++如果按读者的环境,您是说读者对领域和编程技术了解多少,那么我100%与您在一起。
Mike Dunlavey

领域,技术,阅读该语言的能力-所有这些。
保罗·内森

2

我知道大多数人希望这个问题的答案是“否”,但我要说的是。如果在面试中被问到这个,我仍然会说是。

我已经使用开放源代码和封闭源代码进行了许多不同的项目。它们的文档范围很广,从留下的简单注释(作为程序员注释)到完整的API文档。尽管API文档可能很棒,但是我最终总是遇到这样一种情况,即书面文档不足以确定代码的实际行为。我最终查看了源代码,对应用程序进行了逆向工程,或者用源代码访问困扰了开​​发人员以查看源代码并进一步指定。

对我来说,代码是最终的文档。不管用多少字写一个程​​序要做什么,确切的行为都由代码定义。


2

我同意在编写代码时,应尽量使代码尽可能自我描述。但是,正如其他人提到的那样,在复杂的程序中几乎不可能完全描述代码正在执行的所有操作。我并不反对评论,实际上,我发现使用好的评论可以使代码阅读起来更加容易,即使代码无需注释即可解释自己,而阅读英语或某些口语几乎总是更容易。

我发现最有用的文档几乎从来没有注释。我最近从事的大多数项目都包含Wiki,其中包括所有不同部分以及它们之间的连接方式。我试图解释我在编写代码时的想法,以便其他人不会因为我不明白原因而破坏我的代码。它还可以帮助其他人更有信心地重构代码。我经常发现自己对重构代码犹豫不决,因为我不知道它可能会破坏什么,也没有解释。即使您是我保证在一两年内完成项目的唯一人员,您也会忘记您为什么要做某件事,即使它是最漂亮的代码,您仍然会忘记它为什么在那儿。


2

当然,如果您有无限的时间。我花了25年以上的时间为其他开发人员编写代码。我的立场一直是,我尝试解释一些东西,以便其他开发人员可以在5分钟内完成,而他们只需检查一下代码并在半小时内弄清楚。如果我将每个看该方法的人员都救了25分钟,那么我就完成了自己的工作。


+1。可读性方面经常被换成较短的时间来写下代码。实际上,与编写代码相比,在阅读上将花费更多时间。
Schedler

1

我认为应该始终使用类图来记录代码。我认为,如果您不直接看代码,就可以看到完整的体系结构。我同意,如果您自己编写代码或长时间工作,则可以理解,但是每次出现新需求时,都需要查看代码并在哪里添加此新代码。

我们在公司中所做的就是拥有我们项目的类图视图。我们并没有真正花费时间在建模上,而只是在进行逆向工程之后使用类图来可视化代码。如果代码更改,则存在合并机制,并且我的类图始终会更新。

奇妙的是,除了Java doc之外,还能够在图中添加注释,约束。我们反转项目,然后创建一个模型并最终从显示为UML类图的模型中提取视图。我目前不编写代码,但是可以从代码体系结构中获得蓝图,并对其进行工作以创建或扩展当前的体系结构。如果喜欢,则按一下按钮,现有代码将与我的图表合并。我的意思是合并,当然不是完整的代码生成。仅写入现有代码和我的图之间的差异,而不是每次都编写完整的代码。

我已经学习了很多年,拥有硕士学位并且仍然在编写代码,但是我不想只是一名Java作家,并且想多动一点脑筋。UML视图为我提供了思考我的体系结构,与其他团队成员进行交流并创建更好的体系结构所需的资源,而无需使用模型驱动的开发,而仅是现有手动编写的代码与以图形方式创建类图之间的差异。我在代码级别创建我的体系结构,然后将其反转并查看模型。我创建视图并尝试直接在代码中改进我的体系结构,然后再次反转并查看完成的操作等。这是一个永久迭代,没有模型驱动的代码生成,但实时同步或在代码和UML之间合并。我喜欢的是代码驱动UML,当然不是相反。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.