不學習編譯原理對於CS專業的學生有多大的損失?

提出這個問題的初衷是因為我們下學期學習的四門選修課由於某些原因只修三門,於是又由於某些原因我們班就決定不去修編譯原理這門課。

不是說程序員的三大浪漫嗎?那麼問題來了:不學習編譯原理對於CS專業的學生有多大的損失?

補充:四門專業選修課分別是編譯原理,信息安全概論,高級Java編程技術,軟體體系結構。


編譯原理本身挺重要的,但大部分學校都教得不好,parser講得太多太多,optimization和codegen講得太少,語言設計基本不講……

不學編譯原理,可能永遠給各種寫編譯器的人當奴隸,以為寫程序只能按照他們設計的語言哲學來做。學好了編譯原理,不一定非要自己寫語言,但是至少能把很多其他程序員覺得很酷的東西看得透徹一點,不會被程序語言的設計表象騙到太多。這個還是挺重要的,是一輩子碼工和未來CTO的區別,損失自己算吧……

--

不贊同匿名的那個「這點東西不學也罷」。程序語言和編譯器是連接人和機器的橋樑,本質是個以人為本的學科分支,是在尋找程序員寫得爽和機器跑得快之間的平衡點,因此不僅僅是一套數學模型一組自動機。雖然很可惜大部分編譯原理課的教學都只講技術而不講人文這一層……

--

最後,舉個真實的例子好了:有時經常會遇到類似這樣的問題:

java 線程問題? - Java

如果你學了編譯原理,就應該能回答為什麼那個循環會出不來。

如果你學了操作系統,就應該能知道為什麼那個問題里的寫法不太好。


「編譯原理」這門課被奉為經典,多半是因為它既給了剛會寫代碼的學生一個通往形式化理論的入口,同時涉及了很多系統底層邏輯,比較接地氣。喜歡數學的人和喜歡系統的人都得到了滿足。

如果你有機會從理論層面到應用層面把 代數-&>組合數學、離散數學、圖論-&>形式語言與自動機學完,想明白他們從哪些角度一步步從上到下影響計算機科學的。另外在做一些操作系統級別的編程實踐,「編譯原理」這點東西不學也罷。


編譯原理很好玩。。。

不圖好玩學什麼CS。。。


作為一周前剛考完編譯原理的人來答答這個問題。

首先擺明我的觀點:編譯原理,信息安全概論,高級Java編程技術,軟體體系結構。(軟體體系結構下學期才上,不置評論)前三門作為現在的大學課程教學來說,**只是跟著課堂走 都沒有太大的得益**,但是編譯原理和信安概論於個人而言能拓寬的視野相對來說會比所謂的「高級Java編程技術」好一點。

=== 編譯原理的內容 ===

編譯原理首先可以分為編譯器前端和後端兩個大部分來討論。

前端就是詞法分析、語法分析對輸入文件進行分析的部分,後端就是代碼優化、代碼生成的部分,其中為了可拓展性以及便於優化有了中間代碼生成的部分。

前端部分我覺得最大的得益在於構建「自動機」這一個概念模型,詞法分析和語法分析都是在這一概念上構建起來的,直白一點,自動機就是一個狀態接受輸入後跳轉到另外的狀態,一直跳轉直到跳轉到一個可接受的狀態或者報錯。現實情境當中也有很多事情可以用「自動機」這一個概念來進行抽象。比如:state(懵懂) --action(學習)--&> state(獲得知識) --action(知識轉化為生產力)--&>state(工作)...

而且這部分的知識不單止對於解析代碼的源文件有用,對於其他方面的文本解析也有用,例如 @董成良 這個回答裡面的原來解析法律文本:如何學習編譯原理? - 董成良的回答

比如,作為一名律師和玩票的碼農,我就用yacc來對法律文本、案例文本這種semi-structured的文本進行自動格式分析和整理,覺得yacc好有用,比hand craft一個解析器強多了。

而後端涉及到的堆、棧、函數調用與傳值、垃圾回收部分更是讓你加深對程序具體怎樣在機器上跑起來的認識,讓你更好地理解程序為什麼會出bug,怎樣去避免出bug。

而代碼優化部分更是一個大課題,成熟的編譯器現在在前端部分都差不多,只是替換一下結構而已,真正一直在做的就是代碼優化部分。

引用一下另外一個問題的兩個答案:編譯技術中個環節比重如何? - 軟體

@邵成

學界基本上不怎麼做前端的工作了,因為這一塊從理論到應用都已經高度成熟。理論從Chomsky的工作開始,到各種LL/LR/TDPL之類文法的定義、對應parser演算法、文法優缺點都研究得很透。實際運用的話,一大半市面上編譯器的parser都是手寫(不外乎遞歸下降和狀態機),剩下的就是自動構造parser了,從爺爺輩的yacc到ANTLR再到函數式語言里時髦的各種parser組合子,都有人造過輪子,都有人在用。

@程曦銘

分為早期編譯器和現代編譯器,比重不一樣,分布示意圖參考Alex Aiken的課堂塗鴉

L short for Lexical analysis

P short for Parsing

S short for Semantic analysis

O short for Optimization

CG short for Code Generation

上面的比例示意圖是早期的編譯器比重,下面的是現在的

=== 國內大學中的「編譯原理」 ====

而現在的大學教學中的「編譯原理」,80%以上的內容都是講前端部分的詞法、語法分析部分,老師上課基本是當做一門數學課(演算法課)來上,引入各種符號、定義,講解LL(1)、LR(0)、SLR(1)、LR(1)等各種經典分析演算法的內容,考試也是只考這些。(歸根到底,我覺得這跟國內大部分高校老師都是在從事理論研究的道路有關)

=== 對個人觀點的補充 ===

我在上面說:

編譯原理和信安概論於個人而言能拓寬的視野相對來說會比所謂的「高級Java編程技術」好一點

說這一句的原因是可能許多人之前跟計算機底層的知識接觸不太多,比如被C/C++中的指針搞得昏頭轉向,比如搞不清Java中值傳遞、對象傳遞而導致的各種bug等等,而編譯原理能為你提供一個契機去了解計算機底層的知識(我這裡指的主要是上文「後端」的知識),這些知識能讓你更了解怎樣利用編程語言這一個程序猿的工具去和機器溝通,讓機器去做符合你目的的事。

而信安概論可能是一個能讓你提起對信息安全方面興趣的契機,讓你了解原來除了正向地去編寫程序為人們服務之外,還有一群人是利用各種手段去入侵程序來獲取數據的。就我個人而言,我覺得隨著計算機技術、互聯網的不斷普及,信息安全方面是有一個持續的發展前景的。

而所謂的「高級Java編程技術」,我覺得即使你能抽出總課時的1/5來好好閱讀官方文檔、做一個具體的應用出來,或者實習即使半個月,學到的東西都比你花一學期去學這門課要多。

最後:

知識就是知識,至於能把知識發揮在什麼領域,發揮出多大的作用,這就在於個人的修為了。

以上。


(其實三大浪漫不是我提的,是那個變態的S1論壇上的人提的,可見上知乎的人都不上S1,這是好事)

損失可大了。我在M$無論幹什麼事情,譬如做SQL,做debugger,做網站,做data mining,做Office,都深刻的體會到了:雖然不會編譯原理也能做,但是學會了編譯原理讓我可以做得比別人好,這樣無論跳到哪個組遲早都可以成為go to person,前途一片光明。


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.

--from steve-yegge

Stevey"s Blog Rants: Rich Programmer Food 出處


價值:編譯原理&>軟體體系結構&>&>信息安全概論&>&>&>&>&>&>&>高級Java編程技術

不學編譯原理絕對是捨本逐末


個人感覺樓上裝逼的人多一些。

--解釋一下:

我感覺,對於大部分IT工作人員來說,成長的瓶頸遠沒有達到需要精通編譯原理。

所以,別成天覺得不懂編譯原理就是在別人的設計哲學下面工作,目前本人沒感受到對編譯器原理的深入了解的需要。

如果不懂編譯原理就不能稱為好的程序員,我覺得這個題目不夠,還需要一些題目,比如:

不學習數學對於CS專業的學生有多大的損失?

不學習英語對於CS專業的學生有多大的損失?

不學習ACM對於CS專業的學生有多大的損失?

不學習經濟學對於CS專業的學生有多大的損失?

不學習管理對於CS專業的學生有多大的損失?

不學習人情世事對於CS專業的學生有多大的損失?

我的態度是:作為CS專業的學生,作為課程,你沒有不學習的理由。

但是如果花大量時間學習編譯原理,除非你打算搞編譯器等底層的項目。

至於好的程序員是什麼,我和北大青鳥畢業的區別(個人確實很鄙視培訓速成cser,見諒)在於,我個人認為是:

統籌規劃分配自己精力和時間的能力,解決問題的能力,學習能力以及推動項目進展的能力。

最後答樓主的問題:

強烈建議,樓主一定要選擇編譯原理課

高級Java編程技術,軟體體系結構。這兩門可不選,尤其是最後一門。

另外,那些成天說後悔沒學好編譯原理然後工作不順利的童鞋,我想溫柔的問問你們:你們其他的課學得好么...

本人水平較low,勿噴


放棄高級Java編程技術

其實怎麼選都會有損失,這是個權衡。編譯的確沒有演算法和os立竿見影,如果你沒選它,建議找時間看看《自製編程語言》。


CS的全稱是Computer Science.

CS出身相對於其它科系/自學出身的碼農/程序員的本質區別就是CS出身的至少了解操作系統/編譯原理/計算理論.這三個都不學,又何必浪費時間讀CS呢,讀個北大青鳥不就好了,省錢省時間.不過編譯原理都放到選修了,估計來說,這學校也就那樣了,讀不讀都沒差.


說點玄乎的,編程的一個比較高的境界就是為特定問題設計一門語言,請參考Common Lisp的LOOP。這個應該與編譯原理關係很大。


不理解熵對學物理的有多大的損失?

如果你想做個中學物理老師,一點損失都沒有。(至少我那會兒的教材里沒有這個東西)

如果你想做個科學家,你不知道熵還好意思出來混?

同理,不理解編譯原理對學計算機的有多大損失?

如果你想做個普通的碼農,屁損失都沒有。

如果你想做個高大上能在知乎上貼貼圖片嚇倒一片的碼農中的戰鬥機,那損失可大了。

最後,強烈建議:信息安全概論,高級Java編程技術,軟體體系結構。

這三門不選,選編譯原理。

理由是:絕大部分大學的老師水平也就是個混飯吃的還講不清楚這些東西。編譯原理,如果你看書看得懂,那麼就可能有學的價值,如果看書看不懂,學了也白學,和老師關係不大。

ps: 如果你在的學校不是「大部分大學」,那麼:

建議學習信息安全概論和編譯原理。老師領進門,修行靠個人。這兩門口有領路人會好一些。

至於java和軟體體系,學他們是浪費師資力量。

ps:習慣性黑裝b犯,請選擇性無視


課堂上的編譯原理課程和編譯器的區別,我個人覺得,相當於計算機原理課程和最新蘋果 MAC PRO的差別。用是有用,不過別想有太大的用處。話說回來,一個學一學期的課程,對從事幾十年的人生能有多大影響?


如果以後走工程方向的,學好編譯原理可以基本囊括所有需要的技術,鍛煉腦力,同時可以有廣泛應用,更本質上說,讓你理解你天天用的語言,這是優秀程序員需要具備的專研精神


我是個沒什麼工作經驗的人,我只能舉一些間接的例子來說明《編譯原理》這門課的重要性了。

這門課在我校的計算機科學與技術系的本科生教學中,二十多年以來一直都是由馮博琴老師(國家級教學名師,參見,馮博琴_百度百科)來上的。試問一門不重要的課程會令一位國家級名師耗費他數十年的光陰進行這門課的教學嗎?

按我導師的說法,計算機科學三大原理,編譯網路組成,缺一不可。


就我的經歷來說。

在第一堂編譯原理課上,老師坐在講桌後面告訴我們編譯原理這門課很重要啊,你們要好好學啊,對面的Intel每年從我們這裡招幾個去搞編譯器優化什麼的啊。我覺得這講不通,編譯器作為一個較為獨立的領域,真正會在今後工作中有較深涉及到的人一定少之又少。可是為什麼幾乎國內外所有院校都把它視為計算機系最重要的必修專業課之一呢?

後來我換了一個班,上了一學期的課,最後完成了project。在結束掉這門課之後,我意識到:這門課最終要的部分並不是編譯器中的各種演算法,因為大家在交完考試卷子之後就把它們幾乎全忘完了。

重要的是,在這門課中,我見識了本來一個遙不可及的難題,借著這個領域中先賢的經驗與教訓,是怎樣的由問題到理論,由理論到設計,由設計到實現,由實現到優化,最後連我也可以成功挑戰他的過程。

編譯器是一個較為複雜,但經過過去幾十年無數天才的努力,已經比較成熟地解決了的問題。這門課就是以一個宏大的事例告訴我們,遇到問題不要慌,按照我們這一套方法去定義分析研究嘗試,並最終解決它。

所以之於我看來,編譯原理更是一門關乎計算機科學方法論的課。


我的經驗是大部分情況下沒啥損失。其實很多學校老師也是一知半解的


工作中會缺少許多自信,然後在那個語言好這種月經貼面前會比較無能為力。


十年前網上看到前輩建議學好編譯原理,記住了這句話卻種種原因沒有執行;現在回頭看,有三個以上的關鍵問題,要是當時編譯原理學了會有更好更快的解決方案。個人總結是:干這行就不要懶到編譯原理都不肯學


先說個人情況:工作N年,某互聯網公司碼農,公司很多碼農年收入60w++(當然,本人是裡面比較弱的)。

如果你畢業後想還找寫代碼的工作:選編譯原理。

誠然,編譯原理、操作系統原理、資料庫原理、網路原理等「原理」課程對CS的學生來說,短時間內似乎沒啥用。不學這些,貌似也沒啥不良影響。工作時間長一點,你就有感覺了。


推薦閱讀:

C++ 中的左值、右值、左值引用、右值引用、引用分別是什麼,有哪些關係?
對於LLVM之類的編譯器是如何實現在構造SSA形式的IR的時候,計算出def-use鏈?
有沒有內容類似於《Python源碼剖析》,但內容更新過,針對新版本的Python書籍?

TAG:互聯網 | 計算機科學 | 編譯原理 |