进行过程中编译代码是否有好处?


183

我最近接受了一次面试,他们给了我一个小时的时间来编写一些真实的代码。这不是一个很大的数目,可能少于100行。大约45分钟后,我进行了编译,运行并开始运行。我可能花了5到10分钟的时间来解决编译错误和一些小错误,但总体来说还是很顺利的。(顺便说一句,我确实从他们那里得到了报价。)

但是,令我感到困惑的是,在我交出完整的代码后,面试官告诉我,我做错的唯一一件事就是“在进行过程中没有进行编译”。我问他有什么区别,他说:“如果您完成了代码并且没有及时编译,您将怎么做”。

以我的理解,这是一个无效的参数,因为对于给定长度的代码,“获取代码进行编译”通常涉及固定数目的编译错误,并且花费的时间也相当恒定,无论之后是否这样做,这应该是相同的完成编写代码,或者如果您将其与编码时间交织在一起。如果有的话,中断您的编码以搜索丢失的分号可能会损害您的效率。除非在极端情况下,当我尝试对派生类中的虚函数等事物的边缘情况进行模糊处理时,可以合理地预期由有经验的开发人员编写的代码将进行编译,减去偶然的输入错误,甚至如果没有,那就是

在另一起类似的事件中,在一次采访中给我一个不完整的代码库,要求我完成它并进行必要的修改以使其运行。我从阅读现有代码开始,然后过了几分钟(甚至在我看完代码之前),面试官告诉我就足够了。当我问他会做些什么(即“我做错了什么”)时,他告诉我他本来会立即获取代码进行编译。

为什么这甚至有意义?以我的观点和经验来看,一段代码的编译本质上是随机的,涉及诸如分号是否丢失之类的事情,并且与底层程序的正确性无关。(对我来说,专注于编译就像通过拼写检查来运行文章,而无需进行校对来检查语法。)

如果您给我一段不完整的代码,我要做的第一件事就是阅读它。在我不知道代码在做什么并且算法正确之前,我什至不会尝试编译它。

无论如何,这些只是最近发生的几起事件,但总的来说,我听说许多开发人员都在谈论他们在进行代码编译的过程,但是没人能告诉我这样做的好处。我了解在进行代码测试的好处,但是为什么要编译?

所以我的问题是:我错过了什么吗?进行编译实际上有好处吗?还是由软件社区传播的某种神话,您必须经常编译代码?


54
要么,要么就是我的习惯被习惯不同的人称为坏习惯。
CaptainCodeman 2014年

9
@DocBrown如果最终目标是使用正确的产品,则该比较有效。“运行”的程序并不比运行错误的程序好。您不能期望编译器会为您检查代码,而不能期望拼写检查可以解决语法错误。
CaptainCodeman 2014年

7
编译是否打扰您的工作流是非常主观的,并且取决于语言,构建环境,项目的大小/复杂性等。IMO在大型遗留项目中更有可能成为问题。
pjc50 2014年

64
我完全同意OP。我无法理解某人如何判断一个人的工作习惯,例如当他/她用来启动编译器时。唯一重要的是努力的结果。这是正确的吗?它可以维护吗?它是否在预期的时间范围内运行?实施需要多长时间?这些是有趣的问题。所有其他都是任意的BS。如果受访者编写了2个小时的完美代码,并且可以在第一次尝试时进行编译,那么问题出在哪里?只是因为面试官做的不同吗?天哪
JensG 2014年

9
还应该提到的是,对于某些语言和IDE(Java / [Eclipse | NetBeans | etc],C#/ Visual Studio等),IDE 在您键入时已经在后台实时编译所有内容。效果使您可以立即反馈是否犯错。希望IDE开发人员能够对这种随用随编译方法进行研究。
Ogre Psalm33,2014年

Answers:


223

进行编译实际上有好处吗?

有。它为您提供了一个较短的反馈循环-通常,在设计(UI,编写软件,视觉设计等)时,这是一件好事。

反馈周期短,这意味着您可以及早修复错误,而后再进行修复,费用会更高。

要借用您的示例,假设您正在使用类似C的语言进行编码,而忘记了}程序中间的某个地方。

如果您在编写完该语句后立即进行编译,则可以肯定您已经引入了编译错误,可以在几秒钟内修复该错误。

但是,如果不这样做,则必须花费大量时间阅读代码,查找的确切位置,}并确保一旦找到错误,便确定该修复确实是预期的。这将在您留下那段代码之后的一段时间内发生。它不会像您撰写本文时那样清晰。


现在,是的,最终结果是相同的,但是您在编译器可以帮助您的语法问题上浪费了很多时间-如果您在进行过程中进行编译,则可能会大大缩短时间。


72
的确,对于这样的语法错误,现代的IDE基本上一直在编译和重新编译,以使您的反馈循环尽可能地短,这对于捕获较小的错误是不合理的帮助。
Phoshi 2014年

12
@CaptainCodeman-我要说有一些编译错误,这些错误将要求您深入研究很多代码。对于较大的代码库和较大的变更集,情况更是如此。
奥德2014年

29
有时,编译器会给您带来困惑而不是提示,例如gcc模板错误。
pjc50 2014年

14
@ pjc50:绝对(通过在下一次编译之前一次不更改太多内容,因此更容易处理,因此您可以确切地知道最后更改的内容)。
布朗

21
这个想法不仅仅是随机编译。它是在每个重要步骤进行编译,并在您希望其仍能正常工作时进行编译。例如,我将进行编译以进行测试,以确保正确地创建/删除对象,或者确保将事件正确地触发到我创建的新类。如果我创建一个类并以某种方式将其连接到程序中,那么在将更多内容连接到我的应用程序之前,我想确保自己正确完成了操作。小型应用程序的重要性降低,而大型应用程序则至关重要。
Thebluefish

108

编译一种测试形式,尤其是在广泛使用HaskellML等类型的语言中。在其他语言中,这是一个语法扫描,告诉您很少。

话虽如此,“随您随便编译”在我看来是一种非常习惯的习惯。同样,您也可以因为比面试官的个人偏见更频繁地进行编排而被“抽搐”。听起来像挑剔。没有人喜欢承认受访者已经通过了考试;它提示了薪资谈判的规模。

并非所有构建系统都很快。我在一个(C ++)项目中工作,其中Make将花费30秒只是统计所有内容以确定是否需要构建,如果进行了更改,大多数文件将花费几分钟。我们不愿意比每10-15分钟更频繁地执行此操作。毫无疑问,编译时会涉及到拿走您的打孔卡甲板并将其运送到另一座建筑物...

当您觉得自己已经完成了完整的概念单元并准备对其进行验证时,请进行编译。每分钟一次或每周一次,具体取决于工作流程。


25
当您将打孔卡带到sysop进行加载时,请确保您从未放过它们,因为按正确的顺序放回它们是真正的PitA!啊,在必要的调试工具是松紧带的时代。
gbjbaanb 2014年

3
刚开始编程时,我通过不编写就可以编写多少代码的方式来衡量我的进步,主要是根据我的思维编译器的质量。最初是几个字符,然后是几行。现在我不在乎。我只为查看微小的变化就编译了很多东西,而在进行项目的结构布局时却很少编译。
Phil

嗯 只是想说,一个编写良好的C ++文件编译所花的时间不应超过几秒钟。如果更长,那是不好的代码的味道。而且,如果太大而使make出现问题,我会认为该应用程序过于单一。“我的” make永远不会有问题,即使在编译Linux时也是如此。
phresnel 2014年

2
我离开时的LOC为150万。注意Linux不是C ++。模板在gcc中似乎很慢,并且如果您做了一些巧而有用的事情而恰巧编译起来很慢,那么就没有一种简单的方法可以对编译器进行概要分析,以弄清其含义。
pjc50 2014年

21
@gbjbaanb我认为最好说“ 源代码控制是松紧带的日子”。;)
JasonMArcher 2014年

35

所以我的问题是:我错过了什么吗?

是的:您的想法不是编译器。虽然编译器每秒可以进行n次上下文切换,但您的想法却不能。您一天之内可以进行的上下文切换次数取决于许多因素,例如经验/对代码库的熟悉程度,您对代码的投入程度,代码的简洁程度,要解决的问题的复杂程度,如果您经常被打扰或在嘈杂的环境中等,您的疲劳程度如何。

第一次编译代码库(全部同时进行)(例如“带有20个文件的项目”)将迫使您从考虑的内容中切换上下文(例如,“此值在此处设置为5,然后在for循环blablabla,复杂的算法会在返回时产生正确的值”),这与您所考虑的问题(不同的文件/模块/函数/前提条件/语法/变量名称,前提条件等)完全无关)。

一次编译的代码越多,切换思路的环境就越多。当您编写的所有代码都是一个小时内编写的代码时,对于一个小的代码库而言,这不是问题。但是,当在现有代码库中工作时,存在多个(并且很多时候未记录)相互依赖关系,这是一个很大的问题。

进行编译实际上有好处吗?

您可以最大程度地减少必须进行的上下文切换,从而使您可以将更多的精力放在所做更改的影响和副作用上。这也使您不那么累(也更不容易出错),并提高了输出质量(即,一次更改和编译一个文件比编译十个文件更容易保证副作用最小)。

如果您以非常短的迭代进行编译(这假设编译过程已优化为花费很短的时间),则可以在不脱离“区域”的情况下修复编译错误。

还是由软件社区传播的某种神话,您必须经常编译代码?

它也由软件社区传播,但背后有充分的理由。

以我的理解,这是一个无效的参数,因为在给定长度的代码中“获取代码进行编译”通常涉及固定数目的编译错误,并且花费的时间也相当恒定

在我看来,您在维护中型到大型遗留代码库(数百或数千个源文件)方面经验很少(甚至没有)。这就是这种态度(即“随您随便编译”)最有用的地方,也是您养成这种习惯的地方。

我可以想象见过您的人得出了类似的结论(“您在大型代码库中几乎没有经验”)。


1
“编译并更改十” –在很多情况下,这是尝试的最小有意义的单元;例如向函数及其所有调用站点添加新参数。
pjc50 2014年

7
上下文切换。你在开玩笑,对吧?如果我们谈论自动后台编译以指示您在执行过程中代码中的语法错误,那很好。但是最快的上下文切换将无法告诉您算法逻辑是否正确实现或算法是否完全合适。但这是使工作解决方案与组织得井井有条,无错误的编译和快速爆发但完全错误的代码不同的地方。
JensG 2014年

5
@JenS,不,我不是在开玩笑。必须跳过所有代码以解决编译错误,从而确保您不再考虑当前正在解决的问题(使您脱离专区)。相反,如果您可以在编写代码时进行编译,则可以继续检查算法,而不是语法。处理上下文切换的最快方法是确保您不需要它们。我的帖子确实假设了一个理想的世界(使用大型代码库的快速C ++编译和最小的相互依赖性)。
utnapistim 2014年

1
@JensG似乎是一个逻辑上的谬误:这不是在编译的代码和糟糕的代码之间进行选择,而是关于多次编译可能带来的好处。
Jorg 2014年

1
我怀疑这样的说法,即在短时间内打破集中力数十次以修复单个语法错误,比一次打破一次并一次修复十二种语法错误的速度更快(在担心了实际算法之后)。当然,这不是上下文切换在计算中的工作方式(毕竟,我们正在尝试针对吞吐量进行优化)。而且我一直在从事具有超过50万个C ++代码的LoC的项目,该项目已经发展了十多年,所以我希望我们还没有画出经验不足的卡片吗?
Voo

26

我认为这里不仅有一些专业的势利小人。含义似乎是“如果您永远不需要定期编译,那么您就从来没有处理过任何复杂的事情-可以获取更多经验,并在学会完全按照我们的方式工作后再回来。”

但是显然这还有另一面。有些项目需要一定的编译时间。我曾经使用过需要30分钟甚至更长的时间才能编译的框架。如果您需要编辑头文件,Heaven会为您提供帮助。完全重新编译通常在一夜之间完成,并且如果您依靠编译器来捕获错误,那么仍然存在一些罕见的错误,这些错误在部分构建期间不会被检测到。在这种情况下,您只是不会每5分钟重新编译一次- 除非您感到懒惰

编译器无法帮助您解决逻辑或语义错误,并且语法错误确实不是很难避免避免花半天时间进行编译变得很有价值。当然,您偶尔也会打错字,但我将假设您既可以打字,也可以阅读。如果您有选择的自由,请使用一种编码样式,该样式可以充分利用布局来直观地突出显示错误,并且永远不会再放括号,括号或分号。与大多数人相比,这需要一点练习和更多的纪律,但这是可能的。我可以在纯文本编辑器中一次编写几个小时的代码,并且第一次编译要好于十分之九。当然,我可以更频繁地进行编译,但是我不记得上次遇到错误时可以更容易纠正的错误。

如果您不喜欢不断地进行重新编译,那么您的公司就很好。这是唐纳德·克努斯(Donald Knuth):

关于您的真实问题,当我在一个完全未知的环境中感觉自己的方式并且需要有关什么有效和什么无效的反馈时,立即编译和“单元测试”的想法仅对我极少有吸引力。否则,很多时间都浪费在我根本不需要执行甚至思考的活动上。


所有这些都... 如果您在编译是自由行动的环境中工作,为什么不呢?在家里,在个人项目中,我大约每30秒点击ctrl-S一次,并且在一个不断通过编译器前端运行代码以提供实时错误高亮显示的IDE中,“编译”快捷键的访问频率几乎相同。为什么要放弃免费午餐?


我不同意编译是免费的,分神是昂贵的!但是,否则,很好的答案,谢谢:)
CaptainCodeman 2014年

也许我应该将粗体,斜体的“ if”改为“ iff”……我认为,根据项目,编译器和环境的不同,它可能非常接近自由操作。如果您有第二个窗口或屏幕用于编译器输出,则几乎可以停下来进行编译。如果您确实是铁杆(我不是),那么您甚至不需要看代码-只要编译器产生了足够详细的错误就可以在您的外围设备上注册。再次,这是当且仅当编译相当快,否则见上面。
DeveloperInDevelopment

2
I hit ctrl-S about once every 30 seconds。我可能经常省下两倍的费用。这真是个坏习惯。有时我会保存在一行代码的中间,然后在代码末尾再次保存。每当我停下来思考一秒钟而不打字时,我都会保存。
Cruncher 2014年

21

编译时有优点。但是我非常同意,坚持执行任务是可以的编码策略。

增量编译最显着的好处是,许多人在等待最后的编译和测试时便会产生这样的心态:我们比最后任何时候都更关心代码的最终运行。我们说“哦,只需添加此括号,以便编译器停止抱怨”或“哦,只需将其大写”,而无需考虑该语法错误是否隐藏了潜在的语义错误。我确实确实发现语法错误经常将自己嵌套在语义错误中(反之则不成立)。

例如,假设我更改了变量的含义,结果更改了它的名称。名称的更改稍后会在代码中生成语法错误,但是如果我只是通过更正名称来取悦编译器,我将忽略为什么该错误会出现。


5
+1突出显示语义错误和语法错误之间的联系
Doc Brown

15

我了解在进行代码测试的好处,但是为什么要编译?

但是,如果不进行相应的编译,您将如何测试代码?

极端情况是测试驱动开发(TDD)。很明显,TDD不适用于您的策略,因为TDD意味着极短的写测试,编译(应该失败),写代码,再次编译,运行测试,修复错误,再次编译,重构,编译的周期再次,运行测试等等

因此,并不是每个人都进行TDD,至少并非总是如此(我也承认)。使用当前的策略,您将永远没有机会尝试TDD。但是,即使您没有执行TDD,恕我直言,极端定期地测试您的代码也很有帮助-如果您不定期对其进行编译,这是不可能的。而且,当测试失败时,您就可以对其进行调试(这可以帮助您理解为什么几分钟前编写的漂亮算法表现得不如您预期的那么好)。而且,无需编写而编写的代码越多,未经测试就编写的代码就越多,因此遇到无法预测解决问题的时间为“ O(1)” 的情况发生的可能性就越大,因为你写了。


1
我同意你的观点,但是我认为在编译程序(因为要运行它)与编译程序(当没有有​​意义的测试内容(或用于解决编译错误))之间有区别。
CaptainCodeman 2014年

@CaptainCodeman:我认为在编写100行代码时,几乎总是应该有很多小部分可以单独测试。100行代码通常表示4到15个函数(如果使用Bob Martin的风格编写,则大于20)。
布朗

5
@CaptainCodeman:在TDD中,从来没有“毫无意义”的测试。经典示例是您要编写一个新类(我们称其为Foo),然后要做的第一件事就是创建一个单元测试并编写new Foo();,由于您尚未编写类定义,因此显然无法编译。在TDD中,这是运行编译器的正当理由-证明您的单元测试正在运行(失败)。
slebetman 2014年

@slebetman:感谢您的有益评论。我想补充一点,恕我直言,这不仅限于TDD。编写100行代码时,无论是否进行TDD测试,两者之间总会有一些有意义的测试内容。
布朗

14

我实际上同意您的观点,对于有经验的开发人员来说,编译器错误应该不是什么大问题。我认为修复它们的成本不会随着时间的推移而显着增加,不必担心。如果可以将所有编译器错误的修复推迟到推送之前,那么我会这样做,因为这会带来更小,更统一的中断。

不幸的是,发现编译器错误并不是编译器唯一要做的。冒着明显的风险,运行程序需要编译,而运行程序必须查找甚至是经验丰富的开发人员也会创建的所有更复杂,细微且有趣的运行时错误。而这些类型的错误比较困难,因此解决您推迟调试他们的时间越长更昂贵,因为他们可以建立或掩盖对方。

但是,我不一定会在面试练习中将某人打倒,因为要推迟到最后才进行编译。面试往往很简单,有经验的开发人员通常会知道自己的局限性。您对编写的内容越有信心,两次编译之间的时间就越长。那只是人的本性。

但是,为了不让您失望,您必须证明自己的信心。如果您花了45分钟编写某些内容而不进行编译,然后又需要45分钟来调试它,那么我将对您造成很大的压力。


8

据我所知,经常进行编译的一个重要问题是,从我看来,它没有其他答案:如果您很少编译并得到大量的编译器错误,则大多数都是无意义的,因为它们是由第一个错误生成的。可能是因为您输入了错误的类型,错别字或简单的语法错误,从而使某些声明无效。

您总是可以只修复第一个,然后重新编译,修复下一个剩余的,依此类推,但是对于大型代码库,这可能会很慢。但是,如果您尝试浏览一长串独立的编译器错误和发现错误,那么您将花费大量时间阅读不相关的消息,或者将代码从次要错误发现到实际原因。

常规构建的另一件事是,一旦编写了完整的应编译代码块,没有任何事情会阻止您开始编译。然后,只要编译继续进行,只要不保存新的编辑,就可以继续编写更多代码。因此,几乎没有时间在等待构建上。如果等到那时您写完要写的所有内容,那么您就必须等待编译而无需做任何事情。这基本上是现代IDE可以在后台自动执行的手动版本。


有趣的是,即使编译缓慢,这也是定期编译的一个很好的理由。好点子。
sleske 2014年

3

对于一个有足够经验的程序员来说,编译代码从来都不是瓶颈。

一旦您对一种语言有了足够的了解(即,当您不再需要考虑语法而只为功能编写代码时),您往往就不会犯简单的语法错误。您所做的通常是拼写错误或复制粘贴错误,只需几次编译即可将它们快速清除。

我通常整天不编写代码,而后编译,然后在提交代码之前先编译并修复哪些语法错误并警告编译器报告(带有“需要测试!”的注释)。我在短短几分钟内就清理了1,000多行C或C ++代码没有问题。

另一方面,调试和测试需要一段时间。出于各种原因会产生逻辑错误,但我还没有遇到一个可以告诉我完全忘记编写的子例程的编译器,或者会注意到我的二叉树不起作用,因为我node->left应该在应有的时候粘贴它node->right

虽然我认为与面试官打架通常是不明智的,但我想说的是,如果您觉得自己的风格值得捍卫,则应该指出您留给自己足够的时间来调试编写的代码。那是没有一个好的程序员曾经忽略的事情。

ps-如果我一直在看您通过阅读代码来审查代码,那么我本来会雇用您的。专家每次都会这样做。


4
“我还没有遇到能告诉我完全忘记编写的子程序的编译器。” 当我尚未完成深远的更改时,我完全依靠编译器来告诉我。有时,我甚至重命名了一个变量以防止编译成功,直到我检查了每个变量的用法实例并为其赋予了所有新名称。我不明白您怎么能说您还没有遇到缺少某些内容时不会警告您的编译器。除非您编写空的占位符子例程,然后忘记它们,否则天堂将为您提供帮助。
伊恩·戈德比(Yan Goldby)2014年

@par感谢您的回答;很高兴知道我不是唯一这样编码的人!
CaptainCodeman 2014年

3
@CaptainCodeman我很清楚逻辑错误比编译器错误更隐蔽。但这是他关于编译器无法告诉您我想提出异议的丢失代码的断言。除非您故意编写错误(或不完整)的代码进行编译…,但这会否定IMO真正的问题,即编译器无法捕获的错误。哎呀,我什至使用编译器将插入符号移到下一条需要编写代码的行。但是也许我很懒。
伊恩·戈德比2014年

1
@IanGoldby:您完全错过了重点,我什至会说您选择歪曲我的话。编译器无法像我无法告诉您明天早餐吃什么的方式来警告您丢失代码。故意引入语法错误,以便编译器使您想起某种编程技术。它不会被视为错误,也不会赋予编译器心理超能力。
2014年

1
@par我对我显然是由于我的评论造成的冒犯表示歉意-这不是故意的,而且我当然也没有打算歪曲您所说的话。我现在看到,当您编写仍可编译的不完整代码时,您可以通过添加#warning或TODO来确保不遗忘该代码。那是合法的技术。我们都同意的重要一点是,可编译但不起作用的代码比不编译的代码危险得多。
伊恩·戈德比2014年

3

不,在您编写了足够数量的代码之前延缓编译并不是没有道理的(“足够数量”取决于编码器和编写的代码)。

例如,如果您是一个很棒的编码器,花时间将其正确处理,并且没有编写大量代码或令人费解的代码,那么定期进行编译将很浪费,也可能会分散您的注意力。如果不是,那么编译每个函数可能是一件好事。取决于个人。

作为反例,假设您正在编写JavaScript代码-没有编译器。相反(鉴于大多数JavaScript代码的性质),您将运行程序(或刷新页面)以查看编码结果。现在,除非编写足够的代码以使其有意义,否则您将无法执行此操作。结果,JavaScript开发人员倾向于尽可能多地“编译”,而不必经常。

简而言之,这里没有正确的答案-面试官没错,但你也不是。做能使您提高工作效率的事情,而忘记任何人告诉您您应该做的事情。关于编码的重要因素要比F7没有规律击中(或不击中)的倾向绝对没有影响。


您的第二段不清楚;您可能需要对其进行编辑,以明确“超棒的编码器”是否应定期编译。(您是否添加了“ t”并将“ no”更改为“ not”?)
DougM 2014年

@DougM-太好了。
gbjbaanb 2014年

脚本代码经常是“实时”开发的,也就是说,它是在REPL环境中执行的。因此,“编译”确实一直在发生,写入源文件的大多数代码也已经执行过一次。并非所有人都以这种方式编写脚本代码,但是我想说的是,任何人都喜欢并喜欢静态类型语言的相对“安全性”以及错误代码给出的编译器错误,他们应该以这种方式在脚本语言中工作。
海德2014年

2

在良好的开发环境下,除非您实际上打算测试代码,否则几乎没有理由编译。后台语法检查工具捕获了面试官似乎在谈论的大多数内容,尽管我承认,仍有少数情况(涉及跨文件传播的更改)并没有得到完全识别。

话虽这么说,我将尝试编译并运行几乎可以实际产生结果的最小代码单元。半个小时前,我正在创建一种打印一些搜索结果的方法,并做了六打测试打印(以.pdf而不是纸张的形式),对结果进行了更改以使其看起来更好-大约每10个编译一次线。


1

以我的观点和经验来看,一段代码的编译本质上是随机的,涉及诸如分号是否丢失之类的事情,并且与底层程序的正确性无关。(对我来说,专注于编译就像通过拼写检查来运行文章,而无需进行校对来检查语法。)

我的经验是非常不同的:我得到的编译错误中,不到5%是关于语法的。我很了解该语言,当我遇到错误时,主要是类型错误,告诉我语义是不正确的。

这就是为什么我很高兴从编译器的反馈中尽快受益。您是否曾经使用过可实时强调编译错误的IDE?具有较短的反馈回路可能非常有价值。

如果您给我一段不完整的代码,我要做的第一件事就是阅读它。在我不知道代码在做什么并且算法正确之前,我什至不会尝试编译它。

如果希望您使用别人编写的代码,那么您就不会总是有时间阅读所有内容。好消息是:编写良好的代码具有较低的耦合度,应该使您能够仅对所需的部分代码进行独立推理。

在这种情况下,您必须假定尚未阅读的代码是正确的,并在出现问题时懒惰地进行调查。

对于给定的代码长度,“获取代码进行编译”通常涉及固定数目的编译错误,并且花费相当恒定的时间,无论您是在编写完代码之后还是交织在一起,这都应该是相同的它与您的编码时间有关。

上下文切换对您的大脑来说是昂贵的,因此,在编写小错误时就更有效地修复它们。

编辑:当整个团队都在同一个源上工作时,我也可以与源代码控制进行类比。进行编译就像进行频繁的提交一样,它有助于避免在最终不得不合并和整理所有内容时遇到很多麻烦。

您说您禁用了文本下方的红线等功能。在键入电子邮件或撰写技术文档时,您还会这样做吗?然后,您必须再次校对所有页面,而不是在进行过程中纠正错误。

另一个优点是,在处理代码时,如果始终保持编译或接近编译状态,则可以从许多基于语义的IDE功能(安全重命名,重构,查找符号的使用...)中受益。 。

如果您想更好地了解这些功能的作用,可以尝试启用它们并进行练习,以亲身体验它们的好处。您还可以尝试与习惯于他们的任何人进行一些配对编程,并查看他们如何从中受益。


1
我通常会关闭烦人的编译器“功能”,例如自动格式设置,在文本下方绘制红线等。因为我发现没有这些精简的功能,我的工作效率更高。
CaptainCodeman 2014年

1

我对此想了一下,因为我觉得面试官有些非常非常错误的事情,无法确切指出是什么。问题是:对于我过去二十年来编写的任何代码,将可行的算法转换为可编译代码所需的时间最少。该领域效率的任何提高对总开发时间的影响都微乎其微,以至于可以忽略不计,而由于认为该领域效率低下而拒绝候选人的面试官也不知道什么才是优秀的开发人员。

大多数时间应该花在收集信息上,代码应该做什么,收集有关需要使用的外部服务的信息和规范,创建将导致正确且可维护的代码(而不是将代码捆绑在一起)和寻找算法的全局设计。这将导致正常工作的代码,而不是修补在一起的代码,直到碰巧起作用为止(显然没有错误的代码与没有明显错误的代码)。

然后花很少的时间编写可编译的代码。

接下来会花费大量时间来确保代码可以正常工作,并确保我们知道代码可以正常工作。这是通过编写单元测试,逐步执行代码以及首先在很大程度上具有精心设计的代码来完成的。

这位面试官专注于我的答复中用十个单词涵盖的内容。占实际工作时间的百分之十或更少。并且对该开发人员生成可靠且有效的代码的能力几乎没有影响。


这很有意义。我认为,优秀的开发人员应该能够整天在纸上编写代码,然后在一天结束时将其键入。
CaptainCodeman 2014年

1

“边走边编译”的优点是您得到不断的反馈,并且在朝着正确的方向推进之前不会有出错的机会。对于像您这样的称职的程序员来说,这不是一个很大的考虑因素,但对于其他许多人来说,则是一个很大的考虑。换句话说,即使您的情况存在一些潜在的效率损失,“随行进行编译”也是“最小化最大损失”的一种方法。

这些天,公司不仅对成品感兴趣。他们想知道它一直处于“控制之下”。对于他们来说,“到那里去享乐一半”。


这似乎并没有提供超过之前16个答案中所发布内容的实质性内容
gnat 2014年

2
谢谢,但是我们在谈论哪种损失?当然,除非您做了一些大胆的尝试,例如意外地使用错误的语言编写,否则您将永远不必仅由于编译错误而重写任何代码。
CaptainCodeman 2014年

@CaptainCodeman:它使公司感觉更好,并且是一种“保险”形式。这是要花钱的事情,但是会使大多数人(包括经理)“晚上睡得更好”。
Tom Au

@gnat:我要说的是,大多数好处是“公司”级别的好处,程序员应该这样做是因为老板告诉他,而不是因为程序员认为对与错。
Tom Au

已经提出了支持“更短反馈回路”的要点,并在这里的第一个答案中做了很好的解释;老实说,我看不到对“这些天的公司”的盲目猜测会增加什么值得说的内容
gnat 2014年

1

这里的其他答案为经常进行这份工作提供了很好的辩护,但是由于您的问题集中在面试上,我想解决这个问题。

在面试中,我做的完全相反:应聘者不能使用编译器。他们在白板上编写简短的程序,然后我们讨论它们。我发现太多的开发人员将编译器(或解释器)用作拐杖,这比不经常进行编译要浪费更多的时间。如果我为您提供了很多钱,而您甚至没有编译器也无法正确编写FizzBu​​zz,那么您将永远都不会长期削减它,解决的问题比玩具练习困难100倍在面试中。但是,这些简单的练习比面试的其他部分淘汰了更多的候选人。

面试的目的是评估候选人与企业之间的相互适应性。一个好的面试题应说明问题的目的以及如何评估受访者。向受访者提出一个技巧性问题,然后因不知道隐藏的答案而对他们进行惩罚,这无济于事。不幸的是,大多数程序员(甚至是高级程序员)都没有接受过与其他程序员面试的培训,因此他们只是依靠陈词滥调,并在面试时提出与他们面试时所问的相同类型的问题,尽管这些关于评估候选人的有效技巧是否足够有效或不。

我并不是说我的方法是“一种真正的方法”,但它为我提供了很好的帮助。像许多以大写字母开头的软件方法一样,面试的“授权”也相同。他们都是双层床。您需要做对您和您的业务有用的事情。


0

在具有多个子例程的大型项目中,您希望先在大型方案中使用它们之前测试这些部件,因为如果您知道某些部件已经在工作,则调试起来会更容易。

为了测试这些较小的部分,您需要进行编译。

可能是访问员将这种情况与一个不是以这种方式设计的小程序混淆了。


0

关于第二次面试,编译的好处是您可以在几秒钟内观察程序执行(或不执行)的功能。从那里更容易阅读代码并将精力集中在相关部分上。也许这就是面试官的期望。

从头到尾读取这样一个未知的代码库可能会毫无用处(您不是编译器),而编译/运行该应用程序将很快给您带来更大的印象。


这似乎并不能提供先前15个答案中所发布内容的实质性内容
gnat 2014年
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.