每个程序员都应该挑战的6个项目
作者:Austin Z. Henley
編譯:碼農翻身?
有不少學生和專業的開發人員都想做一個業余的項目,以此來鍛煉提高自己的技術能力,但是他們并不清楚要做點啥。
我給大家看下這幾個讓我受益匪淺的項目,每個項目都可以多做幾次,每次都會讓你學到新的東西。當你不知道學習什么東西的時候,不妨以這些項目作為驅動。
文本編輯器
我們每天都使用文本編輯器,但是你知道他們到底是怎么工作的嗎?忽略掉那些炫酷的功能,你怎么實現一個能夠支持選擇,插入,刪除文本,并且移動光標的文本框呢??
當然了,你不能使用那些GUI框架中已經做好的文本框組件。?
最大的挑戰就是弄清楚如何在內存中保存文檔,我首先想到的就是數組,可是數組在插入文本的時候有著很差勁的性能。幸運的是,還有幾個漂亮的數據結構來解決這個問題。?
另外一個難點就是理解光標在文本編輯器中的行為,比如,當我在一個文本的中央,開始按“向上”箭頭的時候,光標應該向哪里移動??
在同一列移動?不,如果上面的那一行比較短,光標會移動到那一行的末尾,然后再往上移動,如果那一行文本較長,光標還會回到那一行的中間位置。
這就意味著需要記住光標所在的列,這樣才有可能回來。我之前根本沒有注意到這些小細節,直到我開始實現的時候。?
實現了基本的編輯功能以后,下面兩個更有趣的挑戰是:undo/redo和單詞換行。?
以有效的方式來實現undo/redo讓我大吃一驚,我先是嘗試了用一個數組保持之前的狀態,然后轉向了Memento 模式,最后才使用了命令模式。?而單詞換行會強迫你把文本的內存存儲和視覺表現分開。?
從文本編輯器能學到的東西?
-
存儲文本的數據結構:array, rope, gap buffer, piece table.
-
光標的行為和實現?
-
undo/redo的設計模式?
-
利用抽象把文本的存儲和表現分開??
進一步閱讀:?
文本編輯器的數據結構:
https://www.averylaird.com/programming/the%20text%20editor/2017/09/30/the-piece-table/?
設計和實現一個Win32的文本編輯器:?
http://www.catch22.net/tuts/neatpad#?
《數據結構和算法:Java描述》 ?
(碼農翻身老劉亂入:我更推薦《算法》)?
2D 游戲 -- 太空入侵者 ?
即使是最簡單的游戲也需要獨特的數據結構和設計模式,我們是來學習的,所以最好使用一個簡單的2D圖形庫(如SDL,SFML,PyGame),而不是一個隱藏了很多細節的大型游戲引擎。?
首先,你得學會如何在屏幕上繪制東西,實際上你是在清理屏幕,然后快速連續地繪制屏幕的每個部分,一秒多次,以產生物體移動的效果。?
其次,你會學會游戲循環,一個游戲實際上是在繪制,獲取用戶輸入,處理游戲邏輯中間的有效的循環操作。?
第三,你會學會如何處理用戶的輸入,我之前從未注意過按下,按住,釋放一個按鍵或者鼠標的細微差別,更不用說處理雙擊操作了。另外你多久檢查一次用戶輸入?如果一直檢查,那游戲的其他部分就被凍結,無法工作了。?
第四,你會學會如何創建和管理游戲中的對象,以及他們的狀態。例如如果動態地創建一定數量的敵兵?工廠模式能幫助不少。?
第五,你會學會如何應用游戲邏輯,什么時候更新子彈的位置?什么時候更多的敵兵應該在屏幕上出現,你如何得知敵人被消滅?什么時候游戲結束?我之前從未用過按模計算,現在我的游戲代碼中到處都是了。?
基本的游戲運行起來以后,可以增加一點屏幕菜單,游戲結束的畫面,探索如何實現有點兒智能的敵兵,如果還覺得不夠的話,還可以增加材質,聲音,在線的多個玩家!?
能學到的東西:?
-
屏幕繪制?
-
獲取用戶輸入?
-
游戲循環?
-
創建和管理動態數量的物體?
-
狀態機?
-
播放聲音,使用材質, 網絡功能?
進一步閱讀:
《游戲編程模式》
https://gameprogrammingpatterns.com/contents.html?
《Data Structures for Game Programmers》?
《Programming Game AI by Example》?
我從8個視頻游戲中學到的8個教訓?
http://web.eecs.utk.edu/~azh/blog/8lessons8games.html?
編譯器- Tiny BASIC?
我做過的最引人注目的項目是編譯器,時至今日,如果我周日的下午有空編程的話,我仍然回去寫編譯器。?
通過創造一個東西,使得別人能創造更多東西,這種感覺實在太棒了。?
通過實現一個編譯器,我必須得學習很多復雜的編譯器技術,這些技術通常來說根本想不到。我建議從零開始寫編譯器,并且從一個很小的BASIC-like的語言開始(例如Tiny BASIC,https://en.wikipedia.org/wiki/Tiny_BASIC ),然后把它編譯成你所熟悉的語言。?
例如,你可以用Python寫一個編譯器,把Tiny Basic編譯為C#代碼, 不需要輸出成匯編,這能讓你專注到編譯器本身。
編譯器的第一個障礙就是如何做詞法分析,然后你需要構建一顆抽象語法樹,遞歸下降是個非常漂亮的技術。?
接下來做語義分析,確保代碼是有意義的,規則會被遵守。最后輸出目標代碼。?
不要被那些術語嚇住,編譯器有海量的資料,先讓你的基本的編譯器工作起來,然后增加一些標準庫(如簡單的2D圖形功能),優化參數傳遞,改進錯誤提示。
最后,你應該用自己的語言寫一些例子程序,向全世界展示你的工作成果。?
可以學到的東西?
-
詞法分析?
-
語法分析?
-
遞歸下降分析?
-
抽象語法樹?
-
語義分析?
-
代碼優化?
-
代碼生成?
進一步閱讀
《Crafting Interpreters》
https://www.craftinginterpreters.com/contents.html
《Write an Interpreter in Go》
《Let's Build a Compiler 》
https://compilers.iecc.com/crenshaw/?
PeayBASIC source code :?
https://github.com/AZHenley/PeayBASIC?
迷你操作系統?
在課堂上,操作系統的數據結構和算法看起來太抽象而沒啥用處。但實際上,他們是非常有用的。多年來,我把操作系統的基本概念應用到了廣闊的領域,如游戲編程,甚至預測人類行為的模型。?實現一個操作系統能幫助我們深入地理解底層的情況。?
由于依賴硬件,所以剛開始的時候,學習曲線陡峭,有不少障礙,但是如果跟隨一本書或者教程,你可以快速地得到一個可以啟動工作的OS,并且能運行你自己的程序。?
我強烈推薦這本免費的書籍:《Making a RISC-V Operating System using Rust.》?
需要學習的內容?
-
交叉編譯?
-
操作系統自舉?
-
BIOS?
-
中斷?
-
x86 modes?
-
內存管理和分頁?
-
調度(e.g., round robin)?
-
文件系統 (e.g., FAT)?
進一步閱讀:?
OSDev.org's wiki of resources?
https://wiki.osdev.org/Main_Page?
Making a RISC-V Operating System using Rust?
http://osblog.stephenmarz.com/index.html?
《操作系統概念》?
如果你能走到這一步,已經非常厲害了,但是....?
如果你覺得還是不夠難,試試這兩個:?
電子表格 ?
電子表格(例如Excel),把文本編輯器和編譯器這兩大挑戰結合起來了, 需要學會怎么表示單元格的內容,并且實現一個解釋器,以便對單元格的內容進行公式計算。?
進一步閱讀:?
有向無環圖?
https://en.wikipedia.org/wiki/Directed_acyclic_graph?
反應式編程?
https://en.wikipedia.org/wiki/Reactive_programming?
《Spreadsheet Implementation Technology》?
視頻游戲控制臺模擬器?
為視頻游戲寫一個模擬器(或者虛擬機)把編譯器和操作系統的挑戰給結合起來了,當你把別人的游戲在你的模擬器上運行起來以后,那種成就感相當棒。?
這個模擬器其實就是虛擬機,能讓那些游戲以為自己在真實的CPU和其他硬件上運行,難度相當高。我建議從模擬CHIP-8開始,這是一個簡單的虛擬控制臺,然后再轉移到一個真正的視頻游戲控制臺。
NES、SNES、Gameboy和Gameboy的高級版本都是可以模擬的,已經有了大量的文檔和開源模擬器。盡管它們都有自己的怪癖,使事情變得有趣(例如,某些游戲可能依賴于特定硬件的無文檔記錄的bug /特性)。還有PICO-8,它已經成為一個非常有利可圖的“幻想”游戲機。?
進一步閱讀:?
Writing a Chip-8 emulator?
https://aymanbagabas.com/2018/09/17/chip-8-emulator.html?
JavaScript Chip-8 Emulator?
http://blog.alexanderdickson.com/javascript-chip-8-emulator?
《How to Emulate a Game Boy》
https://blog.ryanlevick.com/DMG-01/public/book/
PyBoy source code?
https://github.com/Baekalfen/PyBoy?
后記:我覺得這篇文章列舉的項目都偏重基礎,非常適合在校的大學生,可以鍛煉最基本的編程能力,建議多做幾個。如果已經工作了,很難會有大塊的時間去折騰了,可以考慮選一個自己最感興趣的去實現。
?
原文鏈接:
http://web.eecs.utk.edu/~azh/blog/challengingprojects.html
總結
以上是生活随笔為你收集整理的每个程序员都应该挑战的6个项目的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记住这两幅重要的图
- 下一篇: 做一个完整的Java Web项目太难了,