原先我為了成為一個軟體工程師而建立這份簡單的讀書主題清單(To-do list), 但這份To-do list隨著時間而膨脹成這個樣子。 做完這份To-do list上的每個目標後,我成為了Amazon的工程師! 你或許不需要像我讀一樣多。但是,每個讓你成為一位稱職工程師所需要的知識都在這裡了。
我每天讀8~12小時的書,這樣持續了好幾個月。這是我的故事:為什麼我為了Google面試而讀了8個月
在這份To-do list內的主題會讓你擁有足夠的知識去面對幾乎每家軟體公司的專業面試, 這些公司包含了科技巨獸,例如Amazon、Facebook、Google,或者是Microsoft。
祝你好運!
這是我為了從一個網頁開發者(自學,並且沒有任何與資工、電腦科學有關的學位),成為一個大公司軟體工程師,持續好幾個月的讀書計畫。
這是為了那些新手軟體工程師,或者是那些想要轉換跑道,從軟體/網頁開發者轉為軟體工程師(需要資工、電腦科學的知識)的人。
請注意就算你有多年的軟體/網頁開發經驗,那些著名的大型軟體公司,像是Google、Amazon、Facebook,或是Microsoft事實上把軟體/網頁開發(Software/Web Development)與軟體工程(Software Engineering)視為不同,而後者需要的是電腦科學/資訊工程的知識。
如果你想成為一個可靠的工程師或者是Operation Engineer,閱讀並且學習更多這份清單中的The Optional List(裡面包含網路與資訊安全的知識)。
---------------- 以下皆為選讀 ----------------
當我開始這項計畫的時候,我不知道Stack與Heap的差別,不知道時間複雜度(Big-O),不知道樹狀結構(Tree),也不知道如何遍歷一個圖(Graph)。過去如果我需要寫一個排序演算法(Sorting Algorithm),那個code一定是個災難。我過去都用程式語言中內建的資料結構(Data Structure),對於資料結構裡面的實作方法跟原理我完全沒有任何的概念。除非我的程式碰到了"out of memory"的錯誤我才會去找解決方法,否則我從不特別去花費心思管理程式中的記憶體配置。雖然我有用過多維陣列(Multidimensional Arrays)跟關聯陣列(Associative Arrays),但我從來沒有自己時做過資料結構。
這是個遠大的計畫,或許要花上你數個月的時間。如果你對其中大部分的東西已經很熟悉的話,那麼執行這項計畫所花費的時間將減少許多。
下面每項是大綱,你需要從上到下的去理解這些大綱。
我用了Github-flavored markdown語法,其中包含了可以確定完成進度的任務清單。
建立一個新的Branch以使用Github-flavored markdown的勾選功能。只要在[]中打x,像是: [x]
Fork一個branch,並且跟隨以下的指令
git clone git@github.com:<your_github_username>/coding-interview-university.git
git checkout -b progress
git remote add jwasham https://github.com/jwasham/coding-interview-university
git fetch --all
在你完成了一些目標後,在框框中打x
git add .
git commit -m "Marked x"
git rebase jwasham/main
git push --set-upstream origin progress
git push --force
有些影片要註冊Coursera或者Edx的課程後才能觀看,也就是所謂的MOOCs。有時候某些課程需要等待好幾個月才能註冊,這期間你無法觀看這些課程的影片。
我非常喜歡那些大學的線上課程。感謝你們幫忙加入一些免費、可隨時觀看的公開資源,像是那些線上課程的YouTube影片。
在面試的coding階段,你可以選擇任何一個你擅長的程式語言。但多數大公司僅有以下選擇:
你也可以選擇以下的程式語言,但可能會有某些限制:
我之前寫過一篇關於在面試時選擇程式語言的文章:Pick One Language for the Coding Interview
你需要非常熟練這個程式語言,並且對他非常了解。
閱讀更多有關程式語言的選擇:
因為我正在學習C、C++以及Python,所以下面會出現一些有關於這些程式語言的資源。
為了節省你的時間,以下是已經縮減過的書單。
選擇以下其中一個:
面試時你需要選擇一種程式語言(詳如上述)
以下是一些我對程式語言的建議。這邊沒有所有種類程式語言的資源,所以歡迎補充。
如果你讀過以下其中一本,你應該已經具備了所有解決coding問題所需要的資料結構與演算法的知識。除非你想要複習,否則你可以跳過這個計畫中所有的教學影片。
我沒讀過這兩本書,但他們頗受好評。作者是Sedgewick,他超讚的!
如果你有更好的C++書籍,請告訴我。我正在蒐集全面性的資源。
或者:
這份清單隨著時間越來越大。當然,這也同時代表我越來越難以掌握他的整體內容。
以下是一些清單內的錯誤,希望能讓你避免這些錯誤,並且有更好的學習體驗。
我看了數小時的影片,同時也寫下了大量的筆記。但過了幾個月後,大部分的東西都消失的無影無蹤。我花了三天重新看過我的筆記,並做了小字卡幫助我複習他們。
請閱讀以下的文章以免重蹈覆轍:
Retaining Computer Science Knowledge.
有人推薦給我的課程(但我還沒看過:( ): Learning how to Learn
為了解決剛剛提到的遺忘問題,我自己寫了一個小字卡網站。網站上可以新增兩種小字卡,一般的以及程式碼。 每一種類的小字卡都有不同的格式。
這個小字卡網站在製作時便是以行動裝置優先的方式設計的,好處是無論我在何處,我都可以在我的手機與平板上複習。
製作屬於自己的免費小字卡:
我的小字卡資料庫中包含了組合語言、Python的小知識、機器學習以及統計。這些內容已經超出了原本他的預設。
關於小字卡:當你第一次知道答案後,別馬上把那張小字卡標記為已知。反覆複習這張小字卡,直到每次都能答對後才是真正學會了這個問題。反覆的動作會讓這個知識深深地烙印在你的腦海內。
這裡有個替代我小字卡的網站Anki,很多人向我推薦過他。這個網站用同一個字卡重複出現的方式讓你牢牢地記住他。 這個網站非常容易使用,支援多平台,並且有雲端同步功能。在iOS平台上收費25美金,其他平台免費。
這是我用Anki這個網站裡的格式所儲存的小字卡資料庫: https://ankiweb.net/shared/info/25173560 (感謝 @xiewenya)
把你學過的東西應用在解題上面,否則你很快就會忘了他們。這是一個過來人的經驗談。一旦你自認學會了一個主題,像是Linked List之類的,打開任何一本Coding面試問題書籍,做一些裡面有關Linked List的問題。接著繼續讀後面的主題。然後,再回頭反覆做有關Linked List、遞迴或者其他任何東西(原文為Recursion,非Recursive)的題目。但切記一定在讀這些資料結構、演算法的同時,也要實際去寫一些有關這些東西的題目。公司錄取你是為了能有即戰力能夠上戰場,而非一個紙上談兵的人。這邊我覺得還不錯的書籍和網站。更多: Coding Question Practice
我自己寫了一些有關於ASCII Code、網路OSI模型、Big-O(時間複雜度)等等的小抄。我有空的時候就會把他們拿出來看一看複習一下。
打Code累了的話就休息半個小時,並且複習你的小字卡。
能夠干擾你,浪費你寶貴時間的東西很多。因此,專注集中精神實在很難。放點純音樂能幫上一些忙。
以下為普遍但沒有包含在這份清單內的技術:
每個主題所花費的時間都不盡相同,有些只要一天,有些需要花上數天。有些主題只有單純的知識而無包含實作。
每天我選擇下面其中一個主題,看跟該主題相關的影片,再用下面的程式語言實作:
你不需要學會所有的程式語言,你只需要專精在某個程式語言 one language for the interview.
為什麼要這樣寫Code?
我沒有時間做每個主題中的每個東西,但我會盡力而為。
下面是我自己寫的程式碼:
你不需要記住每個演算法裡面的內容。
試試看把程式碼寫在白板或者紙上而不是電腦上。接著用一些測資來測試他。最後才用電腦來驗證。
## 先備知識
[ ] 線上開放式課程:
[ ] 實作雜湊表(用陣列以及線性探測(linear probing))
[ ] 重點:
有關於堆積排序,可以看看上面有關於堆積的介紹。堆積排序很棒,但不太穩定。
[ ] UC Berkeley:
[ ] Bubble Sort (影片)
[ ] Merge Sort (影片)
[ ] Quicksort (影片)
[ ] 合併排序程式碼:
[ ] 快速排序程式碼:
[ ] 實作:
[ ] 非必要,但我建議看一看:
這裡有15種排序演算法的影片,如果你想對排序演算法有更多的了解,看看Additional Detail on Some Subjects裡的「排序」這個部分
圖在電腦科學中可以用來表示、處理很多問題,所以這個部分就像樹以及排序一樣篇幅很長。
重點:
[ ] MIT(影片):
[ ] Skiena Lectures - 很棒的入門介紹:
[ ] 圖(複習以及進階知識):
完整Coursera課程:
我將實作:
[ ] Computer Science 162 - 作業系統 (25部影片):
- 程序與執行緒在第1~11部影片中
- [作業系統以及系統程式設計(影片)](https://archive.org/details/ucberkeley-webcast-PL-XXv-cvA_iBDyz-ba4yDskqMDY6A1w_c)
如果你想知道更多有關這個主題的知識,可以去看某些主題的額外知識中的"String Matching"
如果你已經擁有了4年以上的程式經驗,那你可以來看看有關系統設計的問題
可擴充性與系統設計的範圍非常廣大,裡面還包含了許多主題,因為在設計一個具有擴充性的軟體/硬體時有許多事情需要考量。你可以花點時間看看這些。
考量:
[ ] 從這裡開始: The System Design Primer
[ ] How Do I Prepare To Answer Design Questions In A Technical Inverview?
[ ] 8 Things You Need to Know Before a System Design Interview
[ ] Algorithm design
[ ] System Design Interview - 這個裡面包含許多資源。把裡面的文章與例子都看過一遍,裡面有些我把他特別放在下面。
[ ] 共識演算法(Consensus Algorithms):
[ ] NoSQL Patterns
[ ] 可擴充性:
[ ] 練習系統設計的過程:以下是在紙上練習的一些方法,每個都有他們如何運用在現實中的說明文件:
這部分我放了一些簡短的影片,觀看這些影片可以快速的複習一些重要的觀念。
如果你想時常複習,那真是太棒了!
現在你已經知道上面所有有關電腦科學的主題了,該是時候做些解題的練習了。
解題練習不能死記題目的解法
為什麼你需要練習解題:
這裡有個很棒的入門教學,內容是如何在面試中有條不紊,並且有互動溝通地解決問題。這種能力可以從面試書籍中獲得,但我覺得這個也超讚的:Algorithm design canvas
家裡沒有白板嗎?這很合理。但我是個奇怪的人,家裡有個大白板。沒有白板的話,可以去美術社買個大的繪圖板。你可以坐在沙發上練習。這是我的「沙發白板」。我在照片中放了一枝筆當作比例尺。如果你用筆的話,你將會希望你可以擦拭他,因為他很快就會變髒了。通常我都用鉛筆與橡皮擦。
補充:
閱讀並解題(按照以下順序):
看看上方的書單
學了一些東西之後,可以開始試試每天解一些題目,越多越好!
Coding面試題目影片:
解題網站:
解題repository:
更多面試:
一些我預想的問題(我或許已經知道答案,但想知道他們的意見或是團隊的觀點):
恭喜!!!
繼續學習
活到老,學到老。
*****************************************************************************************************
*****************************************************************************************************
下面的東西都是額外的。
讀這些東西,可以更了解電腦科學的概念,
並且能讓自己對任何軟體工程的工作做更好的準備。
如此一來,你將會成為一個更全面的軟體工程師。
*****************************************************************************************************
*****************************************************************************************************
你可以從以下的書單挑選你有興趣的主題來研讀
Computer Architecture, Sixth Edition: A Quantitative Approach
我把他們加了進來為了讓你成為更全方位的軟體工程師,並且留意一些科技以及演算法,讓你的資料庫中有更多素材。
AVL樹
伸縮樹Splay tree
紅黑樹
2-3搜尋樹
2-3-4樹 (aka 2-4樹)
N-ary (K-ary, M-ary) trees
B樹
我為了強化某些已經在上面呈現的內容,所以才增加這些東西。但因為上面已經有太多內容了,所以不想把這些放在上面。
You want to get hired in this century, right?
SOLID
Union-Find
More Dynamic Programming (影片)
Advanced Graph Processing (影片)
MIT Probability (過於數學,進度緩慢,但這對於數學的東西卻是必要之惡) (影片):
String Matching
排序
坐下來享受一下"Netflix和技巧" :P
Excellent - MIT Calculus Revisited: Single Variable Calculus
Computer Science 70, 001 - Spring 2015 - Discrete Mathematics and Probability Theory
CSE373 - Analysis of Algorithms (25部影片)
UC Berkeley CS 152: Computer Architecture and Engineering (20部影片)
MIT 6.042J: Mathematics for Computer Science, Fall 2010 (25部影片)