僅僅從好玩程度考慮,做編譯器或操作系統哪個更有趣味?
同範疇類似的東西中,虛擬機開發比操作系統和編譯器都有意思:
操作系統能玩的好玩的不多,做完進程管理和內存管理,其他就是臟活累活了,要得到一個成型可用的東西,沒有一個團隊弄不了,個人玩不轉。以前調侃過這個話題:
關於LMOS自主操作系統的發展,大家有什麼建議? - 韋易笑的回答而編譯器方面,優化和代碼生成有llvm,用不著自己開發,其他部分基本上是一個固定套路,照著文檔照著書,按固定套路來即可。
以 Lua為例,最精巧的部分就是 Lua虛擬機的實現,整個 Lua-5.3 代碼中,編譯部分只佔2000行,剩下兩萬行全在實現虛擬機。大家津津樂道的各種 lua 奇技淫巧全都在它的虛擬機實現部分中。
Ruby更是如此,整個ruby代碼除去庫實現外,基本在實現ruby的虛擬機,編譯器部分作者都懶得怎麼寫,直接一個的 .y文件搞定,精力都在ruby虛擬機實現上。
虛擬機難是難在開頭的設計,怎樣最精巧,怎樣沒有邏輯漏洞,別寫著寫著發現前後邏輯矛盾了,設計好以後就要開始架構了,先從最簡單的 switch case opcode實現起來,很快你就能得到反饋看到自己的工作成果,接下來給虛擬機實現符號表,object,實現 gc,實現各種容器,優化性能,在內存中翻譯成本地指令碼,然後實現多線程,再給你的虛擬機實現一門彙編語言,每走一步都很有意思。且虛擬機相關的技術目前還在日新月異的發展著,光一個gc,每年都能看到很多新方法出現,大有需要繼續改進迭代的地方。
實現虛擬機需要覆蓋很多知識面,虛擬機設計的好,還可以嫁接很多其他語言,讓這些新語言來這個虛擬機上運行。
大家誇 v8 都是說它虛擬機運行速度快,內存少,沒人說 v8 的編譯部分如何如何,以至於很多新語言都以v8虛擬機為運行環境。
同樣,每年都有很多人嘗試重新實現 lua vm,引入更靈巧的機制或者使用更新的 JIT方法。來pk官方runtime, 以及 luajit,好多人或多或少在某些方面都能並發出很多奇思妙想。
相反,從來沒人碰 lua 的編譯部分,為啥啊?就那樣了,還碰它幹嘛,沒意思了啊。
------------我做過操作系統,也做過編譯器。操作系統當然是純粹好玩,是拿開源系統來鼓搗鼓搗的,編譯器是IBM編譯器,這個當然是工業水準的編譯器了。所以,如果拿這個來說的話,可能沒有辦法來完全對等的比較。不過我最近在做對接LLVM的編譯器(當然這必須是離職IBM了才能做的,在IBM沒有經過允許,是不能碰開源的代碼的,GCC和LLVM都不行,我相信任何一個公司都是如此,代碼污染必須是考慮的),也算好玩的一種,這個可以和以前鼓搗的操作系統來對接比較,可以順帶說一下了。
操作系統和編譯器都很難,需要的知識不盡相同,如果真要說哪個門檻更高一些,其實還真不好說,兩個涉及的東西都多如牛毛。按照大部分的學校開設時間,編譯器總是安排在了操作系統後面,其實這也是可以理解的,因為編譯器要打交道的東西很多,硬體體系架構、OS都是他針對的範圍。所以,編譯器的測試也是極其繁瑣、以及精細,這裡就不說了,因為我相信題主不是去做商業編譯器,商業操作系統的測試我相信肯定也是非常麻煩的。
而從我的經歷來說,哪一個更好玩呢?我覺得是編譯器,尤其是編譯器前端和代碼優化。做編譯器前端,你當然會與語言標準打交道,C++標準雖然很多人都噴太麻煩了,但是我倒覺得很好玩。因為我去設計解析C++語言代碼的時候,我會去把相關地方的C++標準都讀一下,然後會鍛煉你的細緻。而解析成功後,你會有非常大的成就感,你會體會到一個C++程序是如何變成一個一個Token,再被一步一步的完成解析,生成AST,完成Type Analysis,Diagnostic等若干過程,這種喜悅感是難以描述的。而當你有經驗後,你可以自己去設計一門小語言,然後去完成解析,藉助LLVM,或者其他的VM,然後去運行生成目標代碼,就完成了語言的設計,這是多麼大的自豪感與成就感。其實就今天的編譯技術與工具而言,設計一門小語言已經不算一回事兒了,有太多的工具可以利用了。但是你手工去完成Scanner,Parser,AST,Symbol Table,Code Generation這種一波流,那是有非常大的鍛煉價值的,當然也有各種奇葩問題,不過奇葩正好,奇葩才好玩。當然前端覺得已經搞得差不多了,那就是各種代碼優化,這個優化真的就是窮其一生都可以搞得東西,各種演算法多如牛毛,搞現成的優化演算法就夠你喝一壺了,你也可以盡其一生追求更極致,創造個編譯器選項-OBest你就牛逼了。當然你要坐高級優化演算法,你自己搞其實不行的,我一直覺得高級優化演算法掌握在了IBM等巨頭手上。LLVM雖然說其優化很牛,但是引用IBM前同事Kit的話來說,LLVM的優化和IBM的優化相比其實是個渣,如果有發現LLVM的優化做了,IBM沒做的直接告訴他,他來做(這就是大牛的風采與自信)。
下面說說操作系統,操作系統好不好玩?當然好玩,也被譽為是很有難度的東西。OS核心部分我個人愚見是中斷處理、CPU調度、(虛擬)內存管理、文件系統,你做一個小型OS的話,你能把這四部分做出來,就算一個麻雀OS了。而在中斷處理這部分,你會很直接的與硬體打交道,你也會去追蹤Bootstrap的過程,這對於你來說,有一個醍醐灌頂的過程,終於理解了OS啟動的時候發生了什麼。然後做CPU調度的時候,你當然可以採用Round-Robin這樣的輪詢法,完成一個低級的調度演算法,如果你做的難一點兒,可以加上進程的優先順序,來採用有優先順序的調度演算法。不過我覺得都還不算事兒,這很成熟了。然後內存管理這一塊兒,我覺得很好玩兒,這也是最有意義的部分,你終於可以感覺到有主人的感覺,把計算機的內存捏在手上,這裡面也有各種演算法,LRU,FIFO等Page Fault的演算法。文件系統是我們經常打交道的東西,你也能終於體會到文件在我們OS中是如何表示了,然後也能理解設備為什麼可以用文件表示。
總的來說,做OS你像一個去追尋本質,醍醐灌頂的過程,而好玩性來說,編譯器更好玩一些。嗯......我又吹了這麼久的牛了。你可以兩個一起做,做一個裸的、能直接在硬體上跑起來的編譯器/解釋器,比如whily/yalo · GitHub,是一個直接能在x86-64硬體上跑起來、帶REPL的lisp實現。
繼續做下去的話,你需要能在REPL里輸入指令操控硬體,實現支持類似LINQ操作的文件系統,lazy stream表示網路數據,像Racket一樣直接REPL輸出圖片,等等,當然GUI也可以包含在內,腦洞很多,因為要寫驅動所以工作量巨大。
這種高層次編程語言和操作系統合二為一的事情也不是沒人干過,比如Oberon。王垠也曾經在博客里表達過類似想法,建立統一編程語言的操作系統。主意不錯,不過在stock hardware上直接造os輪子,還不能是只能跑個8bit點陣圖版mario的正經系統,那工作量真太大了。認真做都很有意思。
做編譯器最好連語言一塊折騰了,如果定義一門語言太麻煩,那也找一門熟悉的語言自己寫一下 BNF ,如果直接用現成的,那最有意思的部分就沒趕上。曾經 sand-stone 出過一個叫 VisualParer++ 的商業產品,可以調試文法,可惜這個市場實在太小了,如今 sand-stone 的域名已經出售,曾經的競爭者們也都消失了,剛搜了一下,似乎 VisuaLangLab 還不錯,不過沒用過只能您自己去試了。
單純折騰編譯器的話,代碼生成步驟最好對接一個現成的 VM,如 JVM, 或者乾脆對接 LLVM 後端,不建議自己寫 runtime,那個跟編譯器完全是兩個工程。直接生成機器指令的話,還需要理解 Linker Loader ,不過這個倒是非常實用的知識,書只見過那本老掉牙的 Linkers and Loaders (The Morgan Kaufmann Series in Software Engineering and Programming): John R. Levine: 9781558604964: Amazon.com: Books ,零散的文章倒是很多。
代碼生成時的優化是很有趣的,非常有挑戰性,是真正需要創造力和想像力的前沿領域,有太多樂子可找 。可以考慮拿現成的編譯器的 LLVM 實現專練這個。
簡單的操作系統實現也就是個體力活,找本自己動手寫操作系統、30天自製操作系統之類的書操練一下就是了,如果對硬體架構不熟倒是會接觸很多新鮮東西。做一個有工業水準的操作系統就有趣多了,多處理器支持、虛擬化、調度演算法、進程沙盒……,太多太有搞頭的方向,不過在現有開源系統上折騰可能會更省事一點。Solaris 這麼高大上的系統居然也開源了,直接啃這個吧,illumos Home ,實時系統推薦 RT-Thread | 啟動下一代RTOS演化 。當然是編譯器啊……想要有趣味你至少得先弄出東西來不是么?實現一個編譯器,找一個前端一個後端,自己寫一個 SDT 對接,OK,搞定。你要是在 nodejs 上面,用 peg.js 配合我做的 Patrisika(無恥廣告),你要人肉寫的代碼絕對不會超過一千行。弄操作系統你就得看各種硬體的資料(都是幾千頁的 datasheet 哦),其中的坑……唉,不提了。
編譯器
操作系統是好玩,不過是玩你的時候編譯器是一個跨度很大的領域,因為源語言和目標語言各有不同。
如果你寫一個高性能 C 編譯器,那就必須面對各種 CPU 優化問題。但是如果你寫一個 Lua 這樣的編譯器,就屬於一個 big-clean problem,基本是工作在抽象的符號空間里。
和編譯器相比,OS 的領域跨度沒有那麼大,基本上都是底層管理硬體,上層提供一個 C-like 的介面。中間的細節機制各有不同。
如果你喜歡 big-clean problem,那麼只有編譯器領域能涵蓋。話說回來,誰不喜歡 big-clean problem 呢。
我以前的夢想是用自己寫的編譯器編譯自己設計的語言,跑在自己寫的操作系統上,至今未完成,活到老,寫到死吧
我發現真正有難度的不是寫編譯器,而是定義一門牛逼的語言,還讓別人乖乖的用你的語言來寫。
自己算是都做過。就實現角度來講:compiler的各個部分層次分明,耦合度比較低,寫起來非常有感覺,也很容易建立成就感。而OS,且不說一開始就要花一些時間了解體系結構相關的知識,更麻煩的是各個部分聯繫很緊密,很容易寫成一團(尤其是實現了page swapping之後)。門檻就要高不少。實現兩個的過程自然都是很好玩的,但是實現compiler的樂趣一開始就能體會到,而OS則要深入到一定程度之後才能體會到,可能很多人在此之前就放棄了。所以,推薦去寫compiler。
當然是做編譯器。寫os你千辛萬苦寫出來還只有字元界面完了上面還沒程序多無聊啊。如果你想做圖形,你沒有顯卡的資料,只能做出低解析度的VGA,難看爆了。
好玩的話操作系統,搭積木的感覺。另外,現在開發操作系統環境大大改善了,以前大學(20年前)寫過一個32位的內核,開發環境,調試環境,學習環境跟現在一個天一個地。那時候寫了3年(課餘)的東西,現在重新做三個月(業餘)就差不多了。現在有虛擬機,能模擬各種硬體,以前物理機,寫文件系統一個bug可能把整個硬碟分區搞沒了。以前調試靠print,現在gdb可以直接調試內核。以前只有一本80386保護模式編程指南跟一個minix,現在github上很多源碼,有簡單的,中度複雜的,叫完善的,還有龐大的linux內核,還有幾千頁的intel白皮書。當初我就很想開發smp,苦於沒有硬體環境,現在隨便什麼環境,給你模擬出來。甚至可以開發arm。編譯器也現在強大很多,不用每次等半天。elf可以直接被載入,mbr這塊都可以跳過了。最近我又開始玩64了,拿了一個xv6-x86-64作為基礎。
編譯器偏演算法,個人看多了頭痛。
都很有趣。
操作系統強烈推薦mit 6.828。
編譯器的話coursera上的斯坦福公開課不錯,會講到優化。每一項也就是三個月的事情,都刷完之後你自己就知道哪個你更喜歡了。可以先做操作系統,完善後把編譯器包含進去(前提是你能做到這一步)
個人認為是編譯器更好玩.理由有兩個.
做一個玩的起來的OS太難,不要以為只要做好bootloader有個shell就行了,應該還有GUI,網路,驅動跑起來,而且還要做的足夠好才會有人在上面做APP應用,這時候才能算一個比較完備的OS.這個難度太大了.而自己做個腳本語言,比如Lua這樣只有萬把來行的語言,已經不是Toy級別的玩具了,是真正工業級應用的語言.
第二個理由了解了編譯器的理論之後,你可以寫出能理解程序的程序出來,這能在很多方面方便起日常的開發,比如正則表達式就是編譯理論的應用之一.都寫過,RTOS是自己寫著玩的,編譯器是上面的任務。
寫RTOS剛開始會比較有趣,可以學習對應晶元的彙編指令,用彙編碼出精巧的上下文切換過程;任務調度之類的演算法,瀏覽下UCOS源碼,根據自己的想法修改下就差不多了。
~~~~~然後就會沉浸在bug里痛不欲生,特別是涉及到上下文切換部分,接上模擬器跑的結果(如hardFault)與直接跑的結果(如調度錯誤)很可能不一致,printf也可能影響結果,只能用肉眼加led定位bug。。最後終於將各種預定功能塞進了一個比較複雜的app demo,暫時看起來是穩定的,但是自己也不敢用這個RTOS了。。回想下,寫rtos的有趣時間:痛苦時間~1:2寫編譯器(yacc/lex)感覺就無趣多了,上面給了任務,現學下yacc/lex,根據任務目標歸納下文法要求,按照條條框框填充好,其他一些演算法與寫rtos有點類似,根據要求寫唄,debug,審閱,調整,審閱,調整...完成。除了學習yacc/lex時候有點好玩,其他部分都很無聊,當然如果不藉助yacc/lex整個自己寫,那估計有趣時間:痛苦時間類似RTOS。。寫了操作系統,在哪跑?不如寫嵌入式操作系統,RTT般開源,帶上完善FS,TCPIP,USB,CLI,會有很多人感謝你的
操作系統和解釋器都寫過一些。。。
感覺似乎解釋器更好玩一點。。。因為你要設計一個語言,這個很好玩。。。儘管很多時候就是一個玩具語言吧。。。(如果深陷優化的話就會死。。。嗯。。。)操作系統嘛。。。之前看過於淵的書,照著寫過一點。。。
覺得操作系統水很深,因為實際上操作系統的很多東西程序員是沒接觸過的。。。可以趁機接觸一下,但是從趣味性的角度講還是差一些。。。(最後說句題外話,唯一一次做後端工作是在大一的大作業時候做「魔方求解器」,寫了一個窺孔優化23333)個人感覺編譯器更好玩
編譯器和操作系統有區別嗎?都一樣把我們的操作變成機器指令!vm不也算是個高級的操作系統么!操作系統有時不也能運行於vm之上么,比如VMWare上面的windows 7. 遊戲機模擬器不也是一個vm,不也算是一個硬體解釋器么!我覺得編譯器跟操作系統本質是沒區別的。
推薦閱讀:
※操作系統課講64位系統而不是32位,哪些概念會完全不同?哪些不會有什麼變化?
※微軟未來3~5年之內會完全融合手機操作系統與桌面操作系統么?
※蘋果在手機操作系統領域吊打微軟,為何在電腦操作系統領域卻被微軟吊打?
※現代操作系統的內核線程調度是什麼方式,和CPU使用率什麼關係?
※微軟這些年有哪些大的敗筆?