17

如何向管理层证明对大型代码库中的所有 .java 文件进行批量重新格式化(以使代码符合公司的编码标准)是安全的并且不会影响功能。

答案必须安抚非技术人员和技术人员。

编辑:2010-03-12澄清你们当中的技术;重新格式化 = 仅空白更改 - 没有“组织导入”或“重新排序成员变量、方法等”

编辑:2010-03-12感谢您的众多回复。令我感到惊讶的是,这么多读者对 mrjoltcola 的回答投了赞成票,因为它只是关于偏执的陈述,绝不会回答我的问题。此外,甚至有同一贡献者的评论重申了这个问题。WizzardOfOdds 支持这一观点(但您可能没有阅读所有评论以查看它)。-jtsampson

编辑:2010-03-12我会尽快发布我自己的答案,尽管 John Skeet 的答案在 MD5 建议中是正确的(注意 -g:none 关闭调试)。虽然它只涵盖了技术方面。-jtsampson

2010-03-15我在下面添加了自己的答案。针对“安全”的含义,我的意思是 Java 代码的功能不会受到影响。对 Java 编译器的简单研究表明情况确实如此(有一些警告)。这些警告是“仅限空白”,并被几张海报指出。但是,这不是您想向 BizOps 解释的事情。我的目标是引出“如何证明这样做是合理的”类型的答案,我得到了几个很好的回应。

有几个人提到了源代码控制以及随之而来的“乐趣”。我特别没有提到这一点,因为这种情况已经很好理解(在我的上下文中)。谨防“加油站”效应。请看下面我的回答。

4

24 回答 24

37

如果它只是重​​新格式化,那么不应该改变编译器输出。在重新格式化之前和之后对构建进行哈希(MD5应该足够好) - 如果每个文件都相同,这显然意味着它不能改变行为。无需运行测试等 - 如果输出逐字节相同,则很难看出测试将如何开始失败。(当然,运行测试只是为了展示它可能会有所帮助,但它们不会证明相同的二进制文件不会证明的任何事情。)

编辑:正如评论中指出的,二进制文件包含行号。确保编译时-g:none省略调试信息。行号更改应该没问题 - 但是如果您要更改名称,那将是一个更严重的更改,而且确实可能​​是一个重大更改。

我假设您可以在没有任何人关心的情况下重新格式化和重建 - 只有将重新格式化的代码检查回源代码控制才能引起任何关注。我认为Java 类文件中没有任何内容可以提供构建日期等。但是,如果您的“格式”更改了字段等的顺序,则可能会产生重大影响。

于 2010-03-10T20:11:23.797 回答
35

在商业环境中,您面临两个挑战。

  1. 技术的
  2. 政治的

从技术角度看,重整器是一项成熟的技术。结合散列/校验和,只要语言对空格不敏感,您在技术上是安全的。您还希望确保在没有主要分叉等待合并的停机期间执行此操作。真正的更改将无法与重新格式化分开,因此请分开进行。对于在分叉上工作的任何人来说,合并可能非常困难。最后,我只会在实现完整的测试用例覆盖之后才这样做。因为原因2...

在政治上,如果你不知道如何说服管理层,你怎么知道它是安全的?更具体地说,它对您是否安全。对于控制车间流程的资深、值得信赖的开发人员来说,这是一项更容易的工作,但对于在大型、政治、繁文缛节的组织中工作的开发人员来说,您需要确保涵盖所有基地。

我在 2010 年提出的论点可能有点太聪明了,但解析器、重新格式化程序、漂亮的打印机只是软件;他们可能有由您的代码库触发的错误,特别是如果这是 C++。如果没有随处可见的单元测试,以及庞大的代码库,您可能无法 100% 地验证最终结果是否相同。

作为一名开发人员,我很偏执,这个想法让我感到不安,但只要你在使用:

  1. 源代码控制
  2. 适当的测试覆盖率

那么你就可以了。

但是,请考虑一下:管理层现在意识到您正在处理一个具有“大规模变更”的百万行项目。重新格式化后会报告以前未发现的错误。您现在是导致此错误的主要嫌疑人。是否“安全”有多重含义。这对您和您的工作可能不安全。

这听起来很陈词滥调,但几年前我记得发生过这样的事情。我们在夜间维护窗口后的第二天收到了一份错误报告,我只重新配置并重新启动了IIS服务器。几天来,故事是我一定搞砸了,或者部署了新代码。没有人直接说出来,但我从一个这么说的副总裁那里得到了眼神。我们最终找到了一个已经存在于代码中的 bug,之前已经推送过,但直到 QA 人员最近更改了一个测试用例才出现,但老实说,有些人甚至不记得那部分;他们只记得第二天来到一个新的错误。

编辑:响应jtsampson 的编辑。你的问题不在于如何去做。它是“如何让管理层相信它是安全的”。相反,也许您应该问:“它安全吗?如果是,如何安全地做到这一点。” 我的陈述指出了您的问题的讽刺意味,因为您认为它是安全的,但不知道如何。我很欣赏重新格式化的技术方面,但我指出任何不重要的事情都存在风险,除非你把合适的人放在上面,否则它可能会被搞砸。这项任务是否会影响程序员的其他任务,让他们偏离轨道几天?它会与其他一些编码人员未提交的修订相冲突吗?是否正在修订源?是否有任何对空格敏感的嵌入式脚本,? 任何事情都可能产生意想不到的副作用;对于我们的环境,很难获得一个没有人在分支上工作的时间窗口,并且大规模重新格式化将使它们的合并变得非常丑陋。因此,我不喜欢手动或自动进行大规模重新格式化。

于 2010-03-10T20:07:47.357 回答
13

使用务实的方法:

  1. 构建应用程序。
  2. 保存应用程序。
  3. 重新格式化代码。
  4. 构建应用程序。
  5. 区分二进制文件。
于 2010-03-10T20:12:23.087 回答
8

我会用四个字。

源代码控制。单元测试。

于 2010-03-10T20:08:53.873 回答
5

好吧,这根本不安全,你不可能说服他们。作为一个管理过大量开发的人,我永远不会在任何收入依赖的商业代码库中考虑它。我并不是说按照您喜欢的方式格式化代码没有优势,但是您的格式化不会涉及一些代码更改的可能性为零。这意味着收益微乎其微的巨大风险。如果您必须这样做,请在修复代码的错误时逐步进行,不要大获成功。作为程序员,这对你来说可能是一个不错的决定,但对于他们作为管理层来说,这将是一个糟糕的决定。

于 2010-03-10T20:12:53.573 回答
4

我们在这里谈论的是什么管理?他们是否精通技术,能够理解什么是代码格式以及 Java 如何处理空白?因为如果他们不是,我认为他们没有资格做出这样的技术决定(即,这些问题应该委托给负责代码的人)。

但是,如果他们是,或者您正试图说服您的“架构师”或类似的人,那么这就是信任第三方工具。建议一个有良好声誉的格式化程序,除此之外你无能为力,因为你没有编写格式化程序。

作为一个支线,让我分享一个轶事。我们的架构师一次决定重新格式化所有文件。在数千个 Java 文件中,还没有发现一个错误(这是半年前的事了)。这让我相信 Eclipse 的 Java 源代码格式化程序。这种格式的好处是:

  • 一些格式错误的类现在更易于阅读。
  • 到处都是相同的格式。

但它也有一些负面的方面:

  • 代码格式化程序并不完美。有时手动格式化的代码读起来更好。格式化程序尤其难以处理非常糟糕的代码(行太长、嵌套 if 太多等)。
  • 您是否有其他代码分支,例如偶尔需要修补的旧版本?因为您可以忘记在具有不同代码样式的分支之间进行合并(至少在使用 SVN 时)。
  • 您正在触摸所有文件(有时几乎是每一行)并一次破坏所有文件的历史记录。它损害了可追溯性。
  • 每个开发人员都有自己的代码格式实际上有一个小好处,因为您开始学习该格式,并且可以立即识别一段代码的作者

我个人认为负面大于正面。这听起来是个好主意,但实际上你的收获并没有你想象的那么多。当您遇到一些格式严重的代码时,只需重新格式化该类或该方法,并将其视为朝着大目标迈出的一小步。

于 2010-03-10T22:15:25.837 回答
2

重新格式化后你的单元测试通过了吗?如果是这样,那么你已经把这个想法卖给了管理层!

如果您在处理未经测试的代码,那么您将面临更难的情况。

于 2010-03-10T20:12:57.113 回答
2

您想要“符合公司编码标准的代码” [原文如此] 并想说服管理层?

琐碎:安装CheckStyle,使其成为您流程的一部分,为其提供编码指南,并向他们展示整个代码库在CheckStyle上惨遭失败

于 2010-03-10T21:23:50.997 回答
2

这是技术与业务不匹配的一个很好的例子。

技术人员想要这样做是因为它会使代码难以阅读,但除非它非常糟糕,否则真正的原因是它冒犯了普通程序员通常微妙的敏感性和美学。

业务人员想要管理风险。如果有一些好处并且这里没有商业利益,则可以承担风险,除非您认为使用重新格式化的源代码进行未来开发会更便宜、更快和/或风险更小,老实说,这很难卖。

几乎按照定义,任何变化都存在风险。这里的风险很小,但也并非不存在(从管理层的角度来看),几乎没有上升空间。

还有另一个问题需要考虑:这种更改可能会对源代码控制造成严重破坏。跟踪谁更改了什么变得更加困难,因为对任何行的最新更改将是重新格式化,因此您需要比较修订,这比简单的“责备”或“注释”命令更乏味​​。

此外,如果您有多个活动分支,则重新格式化您的代码将对您的合并造成严重破坏。

于 2010-03-12T03:10:19.867 回答
1

如果您使用Eclipse作为您的开发平台,您可以将所有代码加载到本地工作区中。通过向他们显示“问题”选项卡来向管理层证明没有问题。

然后,右键单击并一一格式化每个项目 - 再次证明没有引入任何问题。

您可以在本地工作站上执行此操作,而不会对您的存储库造成任何损害。

老实说,如果您的管理人员如此非技术性以至于害怕格式化源代码,那么证明格式化后问题选项卡上没有出现任何问题就足以表明代码仍然很好。

更不用说您可能会在源代码管理中标记旧版本吗?

于 2010-03-10T20:09:16.017 回答
1

从某种意义上说,纯粹的格式更改对编译的内容没有影响,因此对运行时代码的行为没有影响,这是安全的。

值得记住的是,在以后处理源代码控制时,批量重新格式化代码可能会带来“乐趣”——如果多个同事检查了代码,并且一个团队成员来重新格式化它,那么所有这些副本都已经过时了。更糟糕的是,当他们更新他们的工作副本时,会出现各种冲突,因为这些格式更改会影响大部分代码,而解决这可能是一场噩梦。

于 2010-03-10T20:11:34.280 回答
1

重新格式化代码与在 Word 中重新格式化文档相同;它改变了布局,从而改变了可读性,但不是内容。

如果所有文件的格式都相同,则代码变得更易读,这使得维护更容易,因此更便宜。此外,代码审查可以更快、更有效。

此外,给定良好的格式样式,可以更容易地发现错误,因为它们无法隐藏;想想没有花括号的 if 语句和那些假想的花括号内的 2 个语句。

一定要聪明,在重新格式化之前签入代码并标记它,这样你就有一个状态可以返回(并告诉人们这将是多么容易),重新格式化并再次签入和标记,无需任何其他更改。

于 2010-03-10T20:13:34.240 回答
1

为管理层回答这些问题,您将在很大程度上说服他们这是一个安全的改变?

  1. 为什么好的格式很重要?
  2. 会有哪些改变?(如果你不能回答这个问题,你对重新格式化的了解不够,不知道它是安全的)
  3. 我们的单元测试套件会证明这些更改没有不良影响吗?(提示答案必须是肯定的)
  4. 是否会在源存储库中标记现有代码,以便我们有一个快速回滚选项?(提示答案最好是肯定的)

那大约涵盖了它。

于 2010-03-10T20:14:12.793 回答
1

实际上,我可能会站在他们一边。当您打开它们进行修复或增强时,重新格式化单元,它们将在重新投入生产之前进行彻底测试。它们应该第一次正确格式化,但如果它们在生产中,仅仅为了风格而重新格式化它们似乎是不必要和鲁莽的。

一致性是好的,但“愚蠢的一致性是小脑袋的妖精”。

于 2010-03-10T20:14:52.653 回答
1

我戴上我的经理帽...

把它当成一个宏大的项目来做,不管争论如何,我都不会让你做。但是,我愿意接受对更改的更长估计,因为您正在修改现有文件以包含这些格式更改。不过,我会要求您自己进行格式更改。

于 2010-03-10T20:35:58.257 回答
1

感谢您的所有回复。

我说服管理层的最后一个论点;包括你所有的回复。感谢您的帮助。

技术的:

  • 重新格式化包括空白更改(没有导入重新排序,没有成员/方法)
  • 重新格式化将使用 [指定工具和流程]
  • 重新格式化将在 [指定编码周期内的时间以尽量减少合并影响]

重新格式化前后:

  • 所有单元测试都将通过
  • 所有集成测试都将通过
  • 所有功能测试都将通过
  • 所有 SOAP-UI 测试都将通过
  • 字节码相同(javac (-g:none) 之后的 .class 文件的 MD5)

商业:

目的:遵守公司标准,该标准规定我们的源文件准确地代表我们代码的逻辑结构。

  • 重新格式化更改与代码更改(如上的 Word 文档示例)
  • 重新格式化会用到【一般流程】
  • 重新格式化将在 [指定业务周期内的时间以尽量减少影响]

飞行员考试:

  • 确认“格式化批处理”导致更少的合并冲突,然后是“格式化为您的代码”。.
  • 确认可执行代码(4k+ .class 文件)保持不变。(MD5测试)
  • 确认的功能不会受到影响(自动测试/冒烟测试)
  • 确认的格式化程序设置仅包含空白更改。

注意:在我的例子中,一部分开发人员使用自动化工具“按代码格式化”(如上面的一些答案所规定)运行了 6 个月的试点测试。虽然有些人认为重新格式化会导致更多的合并冲突,但实际上并非如此。

这种看法是基于重新格式化的时间巧合。例如,考虑一个对汽车一无所知的人。有一天,他们的刹车失灵了。他们将原因归咎于什么?当然是气体。这是他们放入车内的最后一件事(“加油站”效应?)。然而,显然,刹车和燃油系统是不同的系统,格式和代码更改也是如此。我们发现在我们的构建过程中不正确的签入是错误的。

最后,我希望有人能提供一个很好的链接,指向一项显示与通用代码相关的生产力提高的研究,因为很难向企业展示投资回报率。尽管就我而言,由于这是公司标准,因此我有“合规性”。我只需要表明“按代码格式化”与“批量格式化”相比更耗时

于 2010-03-15T16:29:09.640 回答
0

一种思想流派可能是不问就去做,然后能够去“看!”

当然,如果你把这一切都搞砸了,你就会被解雇。你做出你的选择...

或者,源代码控制(或简单备份)然后您可以随时将其回滚。

于 2010-03-10T20:10:42.233 回答
0

我知道以前的答案都很好,但这是另一个可能的答案:在重新格式化之前和之后对编译版本执行CRC 。由于编译会忽略空格、制表符、换行符等,因此编译后的版本应该与原始版本相同,这将向那些半技术经理证明一切都很好。

于 2010-03-10T20:11:51.263 回答
0

从技术上讲,在编译的第一阶段,词法分析器会从源代码中删除所有注释和空格。这是在编译器识别任何代码语义之前很久。因此,任何空格或注释都不能改变程序逻辑中的任何内容。相反,如果添加几个空格或换行符会改变它的语义,该语言将有什么用途以及谁愿意使用它?

在业务方面,您可能会为此使用一些专门的工具。我相信他们在他们的网站上宣传他们工作得很好。

最后一点:如果你必须说服你的管理层相信这一点,也许你应该寻找一种与更聪明的人合作的方法?

于 2010-03-10T20:16:47.803 回答
0

如果您的代码具有接近 100% 的代码覆盖率,那么我认为风险可以降低一点。

然而,即使管理层同意代码库是安全的,我认为他们也会着眼于必须证明支付员工花费数小时重新格式化代码只是为了遵守(我认为)长期引入开发的标准生命周期。

于 2010-03-10T20:41:43.500 回答
0

我们在我目前的工作中使用 Jalopy。这是一个非常可靠的产品,它产生非常整洁的输出。这里最资深的开发人员在将代码库从 CVS 迁移到 SVN 时重新格式化了所有代码库,他必须执行一些测试以确保它可以从头到尾一直工作,现在我们有钩子来确保检查-代码中的格式正确。

话虽如此,我认为您无法说服任何人任何工具都是傻瓜(或错误)证明,因为没有这样的工具。如果您认为收益值得花时间和(非常小的)风险,请尝试让您的管理层相信您在这样做时看到的最大优势。对我来说,最大的优势将来自于:

  • 所有开发人员都有相同的格式设置;
  • 源代码的格式在签入时通过 SCM 中的挂钩进行检查。

因为如果您执行上述操作,如果您的代码已经格式化,那么当您比较 SCM 中的修订版时,您将看到程序逻辑的实际变化,而不仅仅是格式变化。

于 2010-03-10T21:40:44.097 回答
0

如果你对单元测试有很好的覆盖率,那么之前和之后的测试结果就足够了。

于 2010-03-10T23:06:22.790 回答
0

只有一个具体的提示:如果您的公司政策包括按字母顺序排列成员,请注意静态字段的顺序确实很重要。因此,如果您包含执行此操作的保存或清理规则,您可能会破坏您的代码。

于 2010-03-10T23:25:47.013 回答
0

我会问管理层他们目前相信代码有效的基础是什么 - 然后证明相同的工具(测试、文档、小声音......)对于重新格式化的代码同样有效。我希望他们的答案是“测试”......

于 2010-03-15T16:50:21.367 回答