我应该什么时候学习编译器?

44

根据这篇文章,我肯定应该学习编译器。

引用温和而坚定的执行摘要:如果你不知道编译器是如何工作的,那么你就不知道计算机是如何工作的。如果你不确定自己是否100%掌握了编译器的工作方式,那么你就不知道它们的工作方式。

我认为这是一篇非常有趣的文章,应用领域非常实用(请自行阅读),但我也看到过成功的高级软件工程师并不是非常擅长编译器,或者说内部机器结构,但是他们对以下列表中的每个条目都知道一些:

  • 一个编程范例(面向对象,函数式等)
  • 一个编程语言API(C#,Java..)并且至少熟悉两种不同的语言(Java / Haskell有人这么说!)
  • 一个编程框架(Java,.NET)
  • 一个IDE使您更加高效(Eclipse,VisualStudio,Emacs等)
  • 最佳实践(例如,请参阅fxcop规则)
  • 编程原则(DRY,高内聚性,低耦合性等)
  • 编程方法论(TDDMDE
  • 设计模式(结构型,行为型等)
  • 架构基础知识(层次结构,过程模型(瀑布,敏捷等)
  • 测试工具(单元测试,模型测试等)
  • GUI技术(WPF,Swing等)
  • 一个文档工具(Javadoc、Sandcastle等)
  • 一个建模语言(和工具,例如UML、VisualParadigm、Rational)
  • (毫无疑问还有其他非常重要的东西被遗忘在这里)

并不是所有这些工具都是成为一名好程序员所必需的(就像当你不需要GUI时),但其中大部分都是必须的。 编译器是什么?它们真的那么重要吗?因为正如我提到的,许多程序员似乎在没有了解它们的情况下也能很好地完成工作。尤其是成为一名优秀的程序员通常是掌握多个知识领域的成就,所以即使编译器非常重要,难道还不会有更重要的东西吗?

或者我应该今天就订购“无限编译器圣经(24小时内学会……)”?

对于那些已经阅读了本文并想要立即开始学习的人:

解析器、解释器和编译器学习资源


2
对于“我应该订购……”这个具体问题的回答是:我认为不需要。听起来你可能有点陷入了学术研究中,并且已经有了很长的阅读清单。停止做一个理论家,开始写一些代码吧! :) - overslacked
我刚读了史蒂夫的博客,内容写得很好,令人振奋。但同时,它也让我觉得我一辈子都无法达到那些已经从事编程工作30年的人所达到的水平。似乎需要学习的东西太多了,让人感到不知所措。 - user898058
9个回答

52

如果你只想成为一名普通的编码者,并编写一些东西...你不需要学习编译器。

如果你想学习计算机科学,欣赏并真正成为一名计算机科学家,你必须学习编译器。

编译器是计算机科学的微观世界!它包含了每一个问题,包括(但不限于)人工智能(贪婪算法和启发式搜索),算法,理论(形式语言,自动机),系统,架构等等。

你将会看到许多计算机科学以一种惊人的方式融合在一起。通过这样的学习,你将不仅更好地理解编程语言的工作原理,而且也将成为一个更好的编码者。你将学会理解低级别的知识,这有助于高级别的应用。

作为程序员,我们很常常喜欢谈论事物是“黑盒子”...但当你对里面的内容有一些了解时,事情会变得更加顺畅。即使你没有构建整个编译器,你也肯定会学到很多。你将会看到解析背后的形式化方法(并认识到它不仅仅是一堆特殊情况的组合),以及许多NP完全问题。你将会看到为什么计算机科学理论对于实际应用非常重要。(毕竟,编译器是极其实际的...而且没有形式化方法,我们今天就不会拥有现在的编译器)。

我真的希望你考虑学习它们...这将有助于你成为更好的计算机科学家 :-).


1
我要补充一点,如果你想知道如何稳健地处理输入,你也需要了解编译器。这是一个常见的需求,即使在普通的编码中也是如此,在我看来。 - Michael Ekstrand
我同意学习编译器的每一个细节是过度的,但我认为任何人都应该至少了解足够的理论知识,以免尝试使用正则表达式来解析HTML。 - Eduardo Wada

11

你应该学习编译器,因为实现编译器能提高你的编程水平。编译器可能并不完美,但在这个过程中你会学到很多知识。这是一个提高(或练习)编程技能的好方法。


4
大家都说学习编译器可以让你成为一个更好的程序员,但具体如何呢?请添加一些关于在何时应用这些知识以及一些经验来帮助解释这一点。 - Flame of udun

6

成为一名优秀的程序员并不需要理解编译器,但是这会有所帮助。当我学习编译器时,发现编译只是一种翻译。

如果你曾经从一种语言翻译到另一种语言,那么你就已经进行了编译。


那么什么时候应该学习编译器呢?

当你想要或需要用它来解决问题时。


我只知道一些基础知识,目前我倾向于同意这种观点,但我不会在这里陈述:http://steve-yegge.blogspot.com/2007/06/rich-programmer-food.html - Peter
4
只有在需要解决问题时学习它?你并不比太晚了吗? - Peter
@Peter 如果你认为将来可能需要它,那么你可以开始学习。与其他制作编译器的人相比,你需要准备投入许多年的经验才能胜任。就像你不想学习外科手术一样,除非你真的想学。 - Unknown
笑,手术也一样:在你真正需要它的时候学习,似乎有点冒险。 - Peter
如果你不是真的喜欢它,只是学了1-2年,你也会失败,而且白白浪费了1-2年的时间。 - Unknown

5

编译器理论是有用的,但不是必需的。

虽然有一些技术非常方便,例如词法分析和语法分析。

另一个是错误处理。编译器需要大量的错误处理。用户输入可能包含任何内容,甚至是意想不到的。您需要处理所有这些情况。


5
如果您在IT领域工作并需要考虑UML和自描述代码等高级问题,那么您可以轻松度过整个职业生涯而不需要了解编译器的详细信息。
但如果您是一名基层程序员,并且没有管理团队的愿望,那么有一天您可能会意识到自己正在与编译器作斗争。这可能是一个随机bug或者是关于while循环和for循环的走廊对话。您会意识到汇编语言(或者在未来几年中可能是IL)离您需要的还有一点差距,这时将展开另一个宇宙。
所以,我的建议是:现在只需了解编译器正在做很多事情,但不要过分担心它。

3
编译器课程通常关注如何分析高级代码并将其翻译成机器代码。这很有趣,但不是至关重要的。更重要的是要理解编译器生成的机器代码是什么,这样您就可以了解计算机是如何工作的,以及每种语言构造的成本是多少。
因此,我更愿意说您应该了解汇编语言(我的意思是针对一种体系结构的有限子集的汇编语言),以了解计算机的工作原理,并且后者绝对是一个称职的程序员所必需的,这样他就能理解什么是段错误,什么时候进行优化以及其他类似的低级事情。

我会学习你的计算机使用的那种编程语言。对我来说,那是Windows x86。 - Unknown
如果你主要开发x86处理器,可以选择MASM。但实际上,汇编语言是非常专业的领域,掌握任何一种都会在未来带来优势。 - sharptooth
不同意翻译不重要的说法——理解编译和链接对于解决错误更有帮助。至于要学习的汇编语言,那么经典的MIX(http://en.wikipedia.org/wiki/MIX)怎么样?我只是半开玩笑…… - Pontus Gagge
只要了解编译和链接的作用以解决错误即可,而在玩转汇编语言时,你一定会学到所有这些知识。 - sharptooth

3
如果你打算编写极其时间关键的实时代码,了解编译器如何优化你的代码会对你有所裨益。然而,更重要的是了解硬件的基本架构。
根据我的经验,如果你了解硬件的工作原理以及编译器如何解释你的代码,你就能编写出完全符合你意图的代码。我曾多次遇到这样的情况,编写的代码被编译器优化掉,导致硬件执行了我不想要的操作。
总之,了解整个软件-硬件堆栈对于编写良好的算法和代码并非必要,但肯定会有所帮助!

2
从实际角度来看,相较于特定平台的汇编器、链接器和装载程序,一般的编译器理论并不那么重要。例如,我只把GCC编译器当作从我的高级C语言到x86平台上的低级汇编语言的翻译器。而且更多情况下,我会手动修改编译器生成的代码。
从科学角度来看,我强烈建议你学习编译器理论,这将有助于你理解计算机建立在伟大思想之上的基础。甚至还有更多收获,你会以不同的眼光看待这个世界。

0

这只是我的观点,但我认为编译器在计算机科学课程中没有得到足够的关注,不管是在我的课程还是其他任何课程中。我认为任何计算机科学专业的学生在休学或完成专业后应该做两件事:如果必要的话重新学习有限自动机和可能的形式化方法语言,并将其应用于实践中。

利用这些知识编写一个简单的编译器。Alex Aiken在他的网上教程中提供了非常有用的关于如何为COOL(Classroom Object Oriented Language)编写编译器的指导,该语言是Scala的子集,截至2013年版本。至少在撰写本文时是这样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接