Random Tech Thoughts

The title above is not random

The Second Most Important CS Class

Steve Yegge 在 Blog 里发新文章 “Rich Programmer Food“了,这次的话题是 Compiler。

先摘一段话来看看 Steve Yegge 认为 Compiler 有多重要:

Gentle, yet insistent executive summary: If you don’t know how compilers work, then you don’t know how computers work. If you’re not 100% sure whether you know how compilers work, then you don’t know how they work.

所以 Steve 说 Compiler Construction 是 CS 本科阶段第二重要的课程。(第一重要的课程呢?呵呵,到文章最后去找吧。)

Steve 在大学本科上了两次编译课程,第一次拿了 0 分,第二次才感觉学的不错。我在大三第一个学期学了编译原理,虽然分数不错,但是感觉只是知道了个大概,所以也就是说还是不明白编译器是怎么工作的。相信国内会有很不少人说编译原理没有用吧,但我自己看来还是有不少用处的。Steve 在文章里面提到了 7 个场景,其实学过编译的人都会明白怎样去解决,而没有学过的恐怕就没辙了。

因为我大三一年有三个学期,每个学期都比较短,所以编译原理只学了一小部分内容,主要就是词法分析、语意分析的部分,运行时环境稍微看过一些,代码生成和优化完全没有看过。但即使这样,我觉得语言语意分析的内容对我现在还是很有帮助。举几个例子来看看。一个是正则表达式,写程序经常要和文本打交道,另外 UNIX 系统里面文本文件也是无比的重要,正则表达式在处理文本上真的是帮了不少忙。第二点是写程序要解析文本的话会用词法分析里学到的东西,会用状态机或者 lex,写起来不会没有头绪。很可惜,语意分析那一部分在学习编译时没有太多编程的经验,所以现在一直都没有用上,当然也跟我写的程序没有这样的需求有关。

而另外很重要的一点时学习编译以后对程序设计语言也有了更多的理解。一些例子是明白了局部变量和全局变量的区别,名字覆盖是怎么回事,知道 BNF、EBNF 以后看到语言标准时不会一片茫然,而且有些简单的语言直接看 BNF 就可以知道它的语法规则。而当时仅有的一点运行时的概念也帮助我理解了 C 里面函数调用时参数究竟时怎么传递的,SICP 里面讲求值环境的内容也帮助我在学习 Ruby、Lisp 这样的动态语言时更容易理解其动态特性。

总得来说,就我目前所学的编译知识对我帮助最大的两个方面就是文本处理和对程序设计语言的了解。我现在想了解更多的是语言运行时环境方面的内容,尤其是动态语言的运行时环境。

关于大学 CS 专业的课程,Steve 说了下面一段话:

Most programmers gravitate towards a set of courses that can best be described as the olive-garden of computer science: the places where dumb programmers go to learn smart programmer stuff. I hesitate to name these courses explicitly. I wouldn’t be agile enough to dodge the game of graphic bloodshed aimed at me by animated, project-managing, object-oriented engineers using Java and Web 2.0 technologies to roast me via user interfaces designed rationally through teamwork and modern software methodologies. I’d become a case study in the ethics of software and its impact on our culture.

国外的不少大学开始把编译作为选修课程,许多学生为了得到一个好的 GPA 就放弃了这门课。Java、面向对象这样的课程当然也很重要,但是有些课程的话我个人觉得在大学以外的地方也可以学到。大学当然也需要教授技能,但是大学更重要的应该时传授思想。Java 有着非常丰富的类库,可以极大的方便我们写程序,但是用 Java 始终不会让我有多少成就感。有一个原因可能是周围太多用 Java 的人了,我不喜欢随大流,物以稀为贵,人也一样,虽然会比较孤立一些。当然这不是主要原因,更重要的原因是用 Java 以及其他项目提供的类库的时候,我自己始终只是一个用户,我所完成的工作不过是拿别人的东西来用而已。

学习使用一个库或者一个具体的技术现在看来其实都是很快的(并不是深入理解,只是了解到可以在实际工作中使用而已),边学边用的速度可能是最快的。但要学习思想和理论的时候需要一套比较完整的体系才能很好的了解,这个可能就是理论和技术的区别吧。技术因为可以在实践中去体会因此比较容易有感性认识,而理论则不是那么容易通过实践来体会的,所以那些能把理论转换为技术的人是很了不起的。想起之前看到的一篇文章,武学大师一般都是既懂理论,又有实战的人。只有实战的人可以很强,但是成不了大师,而只懂理论的人可能就只能摆花架子了。所以要做大师的话你可以从实战里面总结出一套理论出来,或者你学到一套武功秘技,然后在实践中加以发展最后自成一家。

所以我一直都希望在理论方面多学一点东西。目前打算看算法,然后想看计算理论、编译。以后的话还想了解些人工智能、分布式系统方面的东西。有些课程虽然已经学过了,但是总感觉深度不够。计算机要学的东西太多了,要深入的话只能选其中的一部分,不过太少的话就没有意思了。算上大四 1 年,研究生 2 年的话还有 3 年时间,得抓紧时间好好学了,当然前提是能顺利保研了,否则还得浪费半年时间去考。不过这些课程很可能都要自学了,有些课程学校都不会开设。

差点忘了说 CS 最重要的课程是什么了,我自己还没有办法确定那个是最重要的,Steve 说是打字入门。自己看着办吧。

Comments