Glowin:
Google Interview University – 堅持完成這套學習手冊,你就可以去Google 面試了
原文地址:Google Interview University
原文作者:John Washa
這是?
這是我為了從web 開發者(自學、非計算機科學學位)蛻變至Google 軟件工程師所製定的計劃,其內容歷時數月。

這一長列表是從
Google的指導筆記
中萃取出來並進行擴展。因此,有些事情你必須去了解一下。我在列表的底部添加了一些額外項,用於解決面試中可能會出現的問題。這些額外項大部分是來自於Steve Yegge的“
得到在Google工作的機會
”。而在Google指導筆記的逐字間,它們有時也會被反映出來。
為何要用到它?
我一直都是遵循該計劃去準備Google 的面試。自1997 年以來,我一直從事於web 程序的構建、服務器的構建及創業型公司的創辦。對於只有著一個經濟學學位,而不是計算機科學學位(CS degree)的我來說,在職業生涯中所取得的都非常成功。然而,我想在Google 工作,並進入大型系統中,真正地去理解計算機系統、算法效率、數據結構性能、低級別編程語言及其工作原理。可一項都不了解的我,怎麼會被Google 所應聘呢?
當我創建該項目時,我從一個堆棧到一個堆都不了解。那時的我,完全不了解Big-O 、樹,或如何去遍歷一個圖。如果非要我去編寫一個排序算法的話,我只能說我所寫的肯定是很糟糕。一直以來,我所用的任何數據結構都是內建於編程語言當中。至於它們在背後是如何運作,對此我一概不清楚。此外,以前的我並不需要對內存進行管理,最多就只是在一個正在執行的進程拋出了“內存不足”的錯誤後,採取一些權變措施。而在我的編程生活中,也甚少使用到多維數組,可關聯數組卻成千上萬。而且,從一開始到現在,我都還未曾自己實現過數據結構。
就是這樣的我,在經過該學習計劃後,已然對被Google 所僱傭充滿信心。這是一個漫長的計劃,以至於花費了我數月的時間。若您早已熟悉大部分的知識,那麼也許能節省大量的時間。
如何使用它
下面所有的東西都只是一個概述。因此,你需要由上而下逐一地去處理它。
在學習過程中,我是使用GitHub 特殊的語法特性markdown flavor 去檢查計劃的進展,包括使用任務列表。
- <[x] 創建一個新的分支,以使得你可以像這樣去檢查計劃的進展。直接往方括號中填寫一個字符x 即可:[x]
更多關於Github-flavored markdown 的詳情
擁有一名Googler 的心態
把一個(或兩個)印有“
future Googler
”的圖案打印出來,並用你誓要成功的眼神盯著它。

我得到了工作嗎?
我還沒去應聘。
因為我離完成學習(完成該瘋狂的計劃列表)還需要數天的時間,並打算在下週開始用一整天的時間,以編程的方式去解決問題。當然,這將會持續數週的時間。然後,我才通過使用在二月份所得到的一個介紹資格,去正式應聘Google(沒錯,是二月份時就得到的)。
感谢 JP 的这次介绍。
跟隨著我
目前我仍在該計劃的執行過程中,如果你想跟隨我腳步去學習的話,可以登進我在
GoogleyAsHeck.com
上所寫的博客。
下面是我的聯繫方式:

不要自以為自己足夠聰明
Google 的工程師都是才智過人的。但是,就算是工作在Google 的他們,仍然會因為自己不夠聰明而感到一種不安。
天才程序員的神話
關於Google
- <[ ]面向學生——
Google的職業生涯:技術開髮指導
- <[ ] Google 檢索的原理:
- <[ ]
Google檢索的發展史(視頻)
- <[ ]
Google檢索的原理——故事篇
- <[ ]
Google檢索的原理
- <[ ]
Google檢索的原理—— Matt Cutts(視頻)
- <[ ]
Google是如何改善其檢索算法(視頻)
- <[ ]
- <[ ] 系列文章:
- <[ ]
Google檢索是如何處理移動設備
- <[ ]
Google為了尋找大眾需求的秘密研究
- <[ ]
Google檢索將成為你的下一個大腦
- <[ ]
Demis Hassabis的心靈直白
- <[ ]
- <[ ]
書籍:Google公司是如何運作的
- <[ ]
由Google通告所製作—— 2016年10月(視頻)
相關視頻資源
部分視頻只能通過在Coursera、Edx或
http://
Lynda.com
class 上註冊登錄才能觀看。這些視頻被稱為網絡公開課程(MOOC)。即便是免費觀看,部分課程可能會由於不在時間段內而無法獲取。因此,你需要多等待幾個月。
很感谢您能帮我把网络公开课程的视频链接转换成公开的视频源,以代替那些在线课程的视频。此外,一些大学的讲座视频也是我所青睐的。
面試過程& 通用的面試準備
- <[ ] 視頻:
- <[ ] 文章:
- <[ ]
三步成為Googler
- <[ ]
得到在Google的工作機會
所有他所提及的事情都列在了下面
- <[ ]
(早已過期)
如何得到Google的一份工作,面試題,應聘過程
- <[ ]
手機設備屏幕的問題
- <[ ]
- <[ ] 附加的(雖然Google 不建議,但我還是添加在此):
- <[ ]
ABC:永遠都要去編程(Always Be Coding)
- <[ ]
四步成為Google裡一名沒有學位的員工
- <[ ]
共享白板(Whiteboarding)
- <[ ]
Google是如何看待應聘、管理和公司文化
- <[ ]
程序開發麵試中有效的白板(Whiteboarding)
- <[ ] 震撼開發類面試第一集:
- <[ ] 如何在世界四強企業中獲得一份工作:
- <[ ]
面試Google失敗
- <[ ]
為你的面試選擇一種語言
在這,我就以下話題寫一篇短文——
重點:為在Google的面試選擇一種語言
在大多數公司的面試當中,你可以在編程這一環節,使用一種自己用起來較為舒適的語言去完成編程。但在Google,你只有三種固定的選擇:
C++
Java
Python
有時你也可以使用下面兩種,但需要事先查閱說明。因為,說明中會有警告:
JavaScript
Ruby
你需要對你所選擇的語言感到非常舒適且足夠了解。
更多關於語言選擇的閱讀:
Choose the right language for your coding interview
Choosing a Programming Language for Interviews & Jobs
https://www.
quora.com/What-is-the-b
est-language-to-program-in-for-an-in-person-Google-interview
在此查看相關語言的資源
由於,我正在學習C、C++ 和Python。因此,在下面你會看到部分關於它們的學習資料。相關書籍請看文章的底部。
在你開始之前
該列表已經持續更新了很長的一段時間,所以,我們的確很容易會對其失去控制。
這裡列出了一些我所犯過的錯誤,希望您不要重滔覆轍。
1. 你不可能把所有的東西都記住
就算我查看了數小時的視頻,並記錄了大量的筆記。幾個月後的我,仍然會忘卻其中大部分的東西。所以,我翻閱了我的筆記,並將可回顧的東西製作成抽認卡(flashcard)(請往下看)
2. 使用抽認卡
為了解決善忘的問題,我製作了一些關於抽認卡的頁面,用於添加兩種抽認卡:正常的及帶有代碼的。每種卡都會有不同的格式設計。
而且,我還以移動設備為先去設計這些網頁,以使得在任何地方的我,都能通過我的手機及平板去回顧知識。
你也可以免費製作屬於你自己的抽認卡網站:
抽認卡頁面的代碼倉庫
我的抽認卡數據庫
:有一點需要記住的是,我做事有點過頭,以至於把卡片都覆蓋到所有的東西上。從彙編語言和Python的細枝末節,乃至到機器學習和統計都被覆蓋到卡片上。而這種做法,對於Google的要求來說,卻是多餘。
在抽認卡上做筆記:
若你第一次發現你知道問題的答案時,先不要急著把其標註成“已懂”。你需要做的,是去查看一下是否有同樣的抽認卡,並在你真正懂得如何解決問題之前,多問自己幾次。重複地問答可幫助您深刻記住該知識點。
3. 回顧,回顧,回顧
我留有一組ASCII 碼表、OSI 堆棧、Big-O 記號及更多的小抄紙,以便在空餘的時候可以學習。
每編程半個小時就要休息一下,並去回顧你的抽認卡。
4. 專注
在學習的過程中,往往會有許多令人分心的事佔據著我們寶貴的時間。因此,專注和集中註意力是非常困難的。
你所看不到的
由於,這個巨大的列表一開始是作為我個人從Google 面試指導筆記所形成的一個事件處理列表。因此,有一些我熟悉且普遍的技術在此都未被談及到:
SQL
Javascript
HTML、CSS 和其他前端技術
日常計劃
部分問題可能會花費一天的時間去學習,而部分則會花費多天。當然,有些學習並不需要我們懂得如何實現。
因此,每一天我都會在下面所列出的列表中選擇一項,並查看相關的視頻。然後,使用以下的一種語言去實現:
C —— 使用结构体和函数,该函数会接受一个结构体指针 * 及其他数据作为参数。
C++ —— 不使用内建的数据类型。
C++ —— 使用内建的数据类型,如使用 STL 的 std::list 来作为链表。
Python —— 使用内建的数据类型(为了持续练习 Python),并编写一些测试去保证自己代码的正确性。有时,只需要使用断言函数 assert() 即可。
此外,你也可以使用 Java 或其他语言。以上只是我的个人偏好而已。
為何要在這些語言上分別實現一次?
因为可以练习,练习,练习,直至我厌倦它,并完美地实现出来。(若有部分边缘条件没想到时,我会用书写的形式记录下来并去记忆)
因为可以在纯原生的条件下工作(不需垃圾回收机制的帮助下,分配/释放内存(除了 Python))
因为可以利用上内建的数据类型,以使得我拥有在现实中使用内建工具的经验(在生产环境中,我不会去实现自己的链表)
就算我沒有時間去每一項都這麼做,但我也會盡我所能的。
在這裡,你可以查看到我的代碼:
你不需要記住每一個算法的內部原理。
在一個白板上寫代碼,而不要直接在計算機上編寫。在測試完部分簡單的輸入後,到計算機上再測試一遍。
必備知識
- <[ ]
計算機是如何處理一段程序:
- <[ ]
CPU是如何執行代碼(視頻)
- <[ ]
機器碼指令(視頻)
- <[ ]
- <[ ]
編譯器
- <[ ]
編譯器是如何在~1分鐘內工作(視頻)
- <[ ]
Hardvard CS50 ——編譯器(視頻)
- <[ ]
C++(視頻)
- <[ ]
掌握編譯器的優化(C++)(視頻)
- <[ ]
- <[ ]
浮點數是如何存儲的:
算法複雜度/ Big-O / 漸進分析法
並不需要實現
- <[ ]
Harvard CS50 ——漸進表示(視頻)
- <[ ]
Big O記號(通用快速教程)(視頻)
- <[ ]
Big O記號(以及Omega和Theta)——最佳數學解釋(視頻)
- <[ ] Skiena 算法:
- <[ ]
對於算法複雜度分析的一次詳細介紹
- <[ ]
增長階數(Orders of Growth)(視頻)
- <[ ]
漸進性(Asymptotics)(視頻)
- <[ ]
UC Berkeley Big O(視頻)
- <[ ]
UC Berkeley Big Omega(視頻)
- <[ ]
平攤分析法(Amortized Analysis)(視頻)
- <[ ]
舉證“Big O”(視頻)
- <[ ] 高級編程(包括遞歸關係和主定理):
- <[ ]
速查表(Cheat sheet)
如果部分課程過於學術性,你可直接跳到文章底部,去查看離散數學的視頻以獲取相關背景知識。
數據結構
數組(Arrays)
實現一個可自動調整大小的動態數組。
- <[ ] 介紹:
- <[ ] 實現一個動態數組(可自動調整大小的可變數組):
- <[ ] 練習使用數組和指針去編碼,並且指針是通過計算去跳轉而不是使用索引
- <[ ] 通過分配內存來新建一個原生數據型數組
可以使用int 類型的數組,但不能使用其語法特性
從大小為16或更大的數(使用2的倍數—— 16、32、64、128)開始編寫
- <[ ] size() —— 數組元素的個數
- <[ ] capacity() —— 可容納元素的個數
- <[ ] is_empty()
- <[ ] at(index) —— 返回對應索引的元素,且若索引越界則憤然報錯
- <[ ] push(item)
- <[ ] insert(index, item) —— 在指定索引中插入元素,並把後面的元素依次後移
- <[ ] prepend(item) —— 可以使用上面的insert 函數,傳參index 為 0
- <[ ] pop() —— 刪除在數組末端的元素,並返回其值
- <[ ] delete(index) —— 刪除指定索引的元素,並把後面的元素依次前移
- <[ ] remove(item) —— 刪除指定值的元素,並返回其索引(即使有多個元素)
- <[ ] find(item) —— 尋找指定值的元素並返回其中第一個出現的元素其索引,若未找到則返回-1
- <[ ] resize(new_capacity) // 私有函數
若數組的大小到達其容積,則變大一倍
獲取元素後,若數組大小為其容積的1/4,則縮小一半
- <[ ] 時間複雜度
在數組末端增加/刪除、定位、更新元素,只允許佔O(1) 的時間複雜度(平攤(amortized)去分配內存以獲取更多空間)
在數組任何地方插入/移除元素,只允許O(n) 的時間複雜度
- <[ ] 空間複雜度
因為在內存中分配的空間鄰近,所以有助於提高性能
空間需求= (大於或等於n 的數組容積)* 元素的大小。即便空間需求為2n,其空間複雜度仍然是O(n)
鍊錶(Linked Lists)
- <[ ] 介紹:
- <[ ]
單向鍊錶(視頻)
- <[ ]
CS 61B ——鍊錶(視頻)
- <[ ]
- <[ ]
C代碼(視頻)
並非看完整個視頻,只需要看關於節點結果和內存分配那一部分即可
- <[ ] 鍊錶vs 數組:
- <[ ]
為什麼你需要避免使用鍊錶(視頻)
- <[ ] 的確:你需要關於“指向指針的指針”的相關知識:(因為當你傳遞一個指針到一個函數時,該函數可能會改變指針所指向的地址)該頁只是為了讓你了解“指向指針的指針”這一概念。但我並不推薦這種鍊式遍歷的風格。因為,這種風格的代碼,其可讀性和可維護性太低。
- <[ ] 實現(我實現了使用尾指針以及沒有使用尾指針這兩種情況):
- <[ ] size() —— 返回鍊錶中數據元素的個數
- <[ ] empty() —— 若鍊錶為空則返回一個布爾值true
- <[ ] value_at(index) —— 返回第n 個元素的值(從0開始計算)
- <[ ] push_front(value) —— 添加元素到鍊錶的首部
- <[ ] pop_front() —— 刪除首部元素並返回其值
- <[ ] push_back(value) —— 添加元素到鍊錶的尾部
- <[ ] pop_back() —— 刪除尾部元素並返回其值
- <[ ] front() —— 返回首部元素的值
- <[ ] back() —— 返回尾部元素的值
- <[ ] insert(index, value) —— 插入值到指定的索引,並把當前索引的元素指向到新的元素
- <[ ] erase(index) —— 刪除指定索引的節點
- <[ ] value_n_from_end(n) —— 返回倒數第n 個節點的值
- <[ ] reverse() —— 逆序鍊錶
- <[ ] remove_value(value) —— 刪除鍊錶中指定值的第一個元素
- <[ ] 雙向鍊錶
介紹(視頻)
並不需要實現
- <[ ] 介紹:
堆棧(Stack)
- <[ ]
堆棧(視頻)
- <[ ]
使用堆棧——後進先出(視頻)
- <[ ] 可以不實現,因為使用數組來實現並不重要
- <[ ]
隊列(Queue)
- <[ ]
使用隊列——先進先出(視頻)
- <[ ]
隊列(視頻)
- <[ ]
原型隊列/先進先出(FIFO)
- <[ ]
優先級隊列(視頻)
- <[ ] 使用含有尾部指針的鍊錶來實現:
enqueue(value) —— 在尾部添加值
dequeue() —— 刪除最早添加的元素並返回其值(首部元素)
empty()
- <[ ] 使用固定大小的數組實現:
enqueue(value) —— 在可容的情況下添加元素到尾部
dequeue() —— 刪除最早添加的元素並返回其值
empty()
full()
- <[ ] 花銷:
在糟糕的實現情況下,使用鍊錶所實現的隊列,其入列和出列的時間複雜度將會是O(n)。因為,你需要找到下一個元素,以致循環整個隊列
enqueue:O(1)(平攤(amortized)、鍊錶和數組[探測(probing)])
dequeue:O(1)(鍊錶和數組)
empty:O(1)(鍊錶和數組)
- <[ ]
哈希表(Hash table)
- <[ ] 視頻:
- <[ ] 在線課程:
- <[ ]
哈希函數的掌握(視頻)
- <[ ]
使用哈希表(視頻)
- <[ ]
哈希表的支持(視頻)
- <[ ]
哈希表的語言支持(視頻)
- <[ ]
基本哈希表(視頻)
- <[ ]
數據結構(視頻)
- <[ ]
電話薄問題(Phone Book Problem)(視頻)
- <[ ] 分佈式哈希表:
- <[ ]
- <[ ] 使用線性探測的數組去實現
hash(k, m) —— m 是哈希表的大小
add(key, value) —— 如果key 已存在則更新值
exists(key)
get(key)
remove(key)
更多的知識
二分查找(Binary search)
按位運算(Bitwise operations)
- <[ ]
Bits速查表
你需要知道大量2的冪數值(從2^1 到2^16 及2^32)
- <[ ] 好好理解位操作符的含義:&、|、^、~、>>、<<
- <[ ]
字碼(words)
)
- <[ ]好的介紹:
位操作(視頻)
- <[ ]
C語言編程教程2-10:按位運算(視頻)
- <[ ]
位操作
- <[ ]
按位運算
- <[ ]
Bithacks
- <[ ]
位元撫弄者(The Bit Twiddler)
- <[ ]
交互式位元撫弄者(The Bit Twiddler Interactive)
- <[ ]
- <[ ] 一補數和補碼
- <[ ] 計算置位(Set Bits)
- <[ ] 四捨五入2的冪數:
- <[ ] 交換值:
- <[ ] 絕對值:
- <[ ]
樹(Trees)
樹—— 筆記& 背景
- <[ ]
系列:基本樹(視頻)
- <[ ]
系列:樹(視頻)
基本的樹形結構
遍歷
操作算法
BFS(廣度優先檢索,breadth-first search)
MIT(視頻)
層序遍歷(使用隊列的BFS 算法)
時間複雜度: O(n)
空間複雜度:
最好情況: O(1)
最壞情況:O(n/2)=O(n)
DFS(深度優先檢索,depth-first search)
MIT(視頻)
筆記:
時間複雜度:O(n)
空間複雜度:
最好情況:O(log n) – 樹的平均高度
最壞情況:O(n)
中序遍歷(DFS:左、節點本身、右)
後序遍歷(DFS:左、右、節點本身)
先序遍歷(DFS:節點本身、左、右)
- <[ ]
二叉查找樹(Binary search trees):BSTs
- <[ ]
二叉查找樹概覽(視頻)
- <[ ]
系列(視頻)
從符號表開始到BST 程序
- <[ ]
介紹(視頻)
- <[ ]
MIT(視頻)
C/C++:
- <[ ]
二叉查找樹——在C/C++中實現(視頻)
- <[ ]
BST的實現——在堆棧和堆中的內存分配(視頻)
- <[ ]
在二叉查找樹中找到最小和最大的元素(視頻)
- <[ ]
尋找二叉樹的高度(視頻)
- <[ ]
二叉樹的遍歷——廣度優先和深度優先策略(視頻)
- <[ ]
二叉樹:層序遍歷(視頻)
- <[ ]
二叉樹的遍歷:先序、中序、後序(視頻)
- <[ ]
判斷一棵二叉樹是否為二叉查找樹(視頻)
- <[ ]
從二叉查找樹中刪除一個節點(視頻)
- <[ ]
二叉查找樹中序遍歷的後繼者(視頻)
- <[ ]
- <[ ] 實現:
- <[ ] insert // 往樹上插值
- <[ ] get_node_count // 查找樹上的節點數
- <[ ] print_values // 從小到大打印樹中節點的值
- <[ ] delete_tree
- <[ ] is_in_tree // 如果值存在於樹中則返回true
- <[ ] get_height // 返回節點所在的高度(如果只有一個節點,那麼高度則為1)
- <[ ] get_min // 返回樹上的最小值
- <[ ] get_max // 返回樹上的最大值
- <[ ] is_binary_search_tree
- <[ ] delete_value
- <[ ] get_successor // 返回給定值的後繼者,若沒有則返回-1
- <[ ]
堆(Heap) / 優先級隊列(Priority Queue) / 二叉堆(Binary Heap)
可視化是一棵樹,但通常是以線性的形式存儲(數組、鍊錶)
- <[ ]
堆
)
- <[ ]
介紹(視頻)
- <[ ]
無知的實現(視頻)
- <[ ]
二叉樹(視頻)
- <[ ]
關於樹高的討論(視頻)
- <[ ]
基本操作(視頻)
- <[ ]
完全二叉樹(視頻)
- <[ ]
偽代碼(視頻)
- <[ ]
堆排序——跳到起點(視頻)
- <[ ]
堆排序(視頻)
- <[ ]
構建一個堆(視頻)
- <[ ]
MIT:堆與堆排序(視頻)
- <[ ]
CS 61B Lecture 24:優先級隊列(視頻)
- <[ ]
構建線性時間複雜度的堆(大頂堆)
- <[ ] 實現一個大頂堆:
- <[ ] insert
- <[ ] sift_up —— 用於插入元素
- <[ ] get_max —— 返回最大值但不移除元素
- <[ ] get_size() —— 返回存儲的元素數量
- <[ ] is_empty() —— 若堆為空則返回true
- <[ ] extract_max —— 返回最大值並移除
- <[ ] sift_down —— 用於獲取最大值元素
- <[ ] remove(i) —— 刪除指定索引的元素
- <[ ] heapify —— 構建堆,用於堆排序
- <[ ] heap_sort() —— 拿到一個未排序的數組,然後使用大頂堆進行就地排序
注意:若用小頂堆可節省操作,但導致空間複雜度加倍。(無法做到就地)
字典樹(Tries)
需要注意的是,字典樹各式各樣。有些有前綴,而有些則沒有。有些使用字符串而不使用比特位來追踪路徑。
閱讀代碼,但不實現。
- <[ ]
數據結構筆記及編程技術
- <[ ] 短課程視頻:
- <[ ]
對字典樹的介紹(視頻)
- <[ ]
字典樹的性能(視頻)
- <[ ]
實現一棵字典樹(視頻)
- <[ ]
- <[ ]
字典樹:一個被忽略的數據結構
- <[ ]
高級編程——使用字典樹
- <[ ]
標準教程(現實中的用例)(視頻)
- <[ ]
MIT,高階數據結構,使用字符串追踪路徑(可事半功倍)
平衡查找樹(Balanced search trees)
掌握至少一種平衡查找樹(並懂得如何實現):
“在各種平衡查找樹當中,AVL 樹和2-3樹已經成為了過去,而紅黑樹(red-black trees)看似變得越來越受人青睞。這種令人特別感興趣的數據結構,亦稱伸展樹(splay tree)。它可以自我管理,且會使用輪換來移除任何訪問過根節點的key。” —— Skiena
因此,在各種各樣的平衡查找樹當中,我選擇了伸展樹來實現。雖然,通過我的閱讀,我發現在Google 的面試中並不會被要求實現一棵平衡查找樹。但是,為了勝人一籌,我們還是應該看看如何去實現。在閱讀了大量關於紅黑樹的代碼後,我才發現伸展樹的實現確實會使得各方面更為高效。
伸展樹:插入、查找、刪除函數的實現,而如果你最終實現了紅黑樹,那麼請嘗試一下:
跳過刪除函數,直接實現搜索和插入功能
我希望能閱讀到更多關於B 樹的資料,因為它也被廣泛地應用到大型的數據庫當中。
- <[ ]
自平衡二叉查找樹
- <[ ]
AVL樹
實際中:我能告訴你的是,該種樹並無太多的用途,但我能看到有用的地方在哪裡:AVL 樹是另一種平衡查找樹結構。其可支持時間複雜度為O(log n) 的查詢、插入及刪除。它比紅黑樹嚴格意義上更為平衡,從而導致插入和刪除更慢,但遍歷卻更快。正因如此,才彰顯其結構的魅力。只需要構建一次,就可以在不重新構造的情況下讀取,適合於實現諸如語言字典(或程序字典,如一個彙編程序或解釋程序的操作碼)。
- <[ ]
MIT AVL樹/ AVL樹的排序(視頻)
- <[ ]
AVL樹(視頻)
- <[ ]
AVL樹的實現(視頻)
- <[ ]
分離與合併
- <[ ]
伸展樹
實際中:伸展樹一般用於緩存、內存分配者、路由器、垃圾回收者、數據壓縮、ropes(字符串的一種替代品,用於存儲長串的文本字符)、Windows NT(虛擬內存、網絡及文件系統)等的實現。
- <[ ]
CS 61B:伸展樹(Splay trees)(視頻)
- <[ ] MIT 教程:伸展樹(Splay trees):
該教程會過於學術,但請觀看到最後的10分鐘以確保掌握。
視頻
- <[ ]
2-3查找樹
實際中:2-3樹的元素插入非常快速,但卻有著查詢慢的代價(因為相比較AVL 樹來說,其高度更高)。
你會很少用到2-3樹。這是因為,其實現過程中涉及到不同類型的節點。因此,人們更多地會選擇紅黑樹。
- <[ ]
2-3樹的直感與定義(視頻)
- <[ ]
2-3樹的二元觀點
- <[ ]
2-3樹(學生敘述)(視頻)
- <[ ]
2-3-4樹(亦稱2-4樹)
實際中:對於每一棵2-4樹,都有著對應的紅黑樹來存儲同樣順序的數據元素。在2-4樹上進行插入及刪除操作等同於在紅黑樹上進行顏色翻轉及輪換。這使得2-4樹成為一種用於掌握紅黑樹背後邏輯的重要工具。這就是為什麼許多算法引導文章都會在介紹紅黑樹之前,先介紹2-4樹,儘管
2-4樹在實際中並不經常使用
。
- <[ ]
CS 61B Lecture 26:平衡查找樹(視頻)
- <[ ]
自底向上的2-4樹(視頻)
- <[ ]
自頂向下的2-4樹(視頻)
- <[ ]
B樹
有趣的是:為啥叫B 仍然是一個神秘。因為B 可代表波音(Boeing)、平衡(Balanced)或Bayer(聯合創造者)
實際中:B 樹會被廣泛適用於數據庫中,而現代大多數的文件系統都會使用到這種樹(或變種)。除了運用在數據庫中,B 樹也會被用於文件系統以快速訪問一個文件的任意塊。但存在著一個基本的問題,那就是如何將文件塊i 轉換成一個硬盤塊(或一個柱面-磁頭-扇區)上的地址。
- <[ ]
B樹
- <[ ]
B樹的介紹(視頻)
- <[ ]
B樹的定義及其插入操作(視頻)
- <[ ]
B樹的刪除操作(視頻)
- <[ ]
MIT 6.851 ——內存層次模塊(Memory Hierarchy Models)(視頻)
覆蓋有高速緩存參數無關型(cache-oblivious)B 樹和非常有趣的數據結構
頭37分鐘講述的很專業,或許可以跳過(B 指塊的大小、即緩存行的大小)
- <[ ]
紅黑樹
實際中:紅黑樹提供了在最壞情況下插入操作、刪除操作和查找操作的時間保證。這些時間值的保障不僅對時間敏感型應用有用,例如實時應用,還對在其他數據結構中塊的構建非常有用,而這些數據結構都提供了最壞情況下的保障;例如,許多用於計算幾何學的數據結構都可以基於紅黑樹,而目前Linux 系統所採用的完全公平調度器(the Completely Fair Scheduler)也使用到了該種樹。在Java 8中,紅黑樹也被用於存儲哈希列表集合中相同的數據,而不是使用鍊錶及哈希碼。
- <[ ]
Aduni ——算法——課程4(該鏈接直接跳到開始部分)(視頻)
- <[ ]
Aduni ——算法——課程5(視頻)
- <[ ]
黑樹(Black Tree)
- <[ ]
二分查找及紅黑樹的介紹
N 叉樹(K 叉樹、M 叉樹)
注意:N 或K 指的是分支係數(即樹的最大分支數):
二叉樹是一種分支係數為2的樹
2-3樹是一種分支係數為3的樹
- <[ ]
K叉樹
排序(Sorting)
- <[ ] 筆記:
關於堆排序,請查看前文堆的數據結構部分。堆排序很強大,不過是非穩定排序。
- <[ ]
冒泡排序(video)
- <[ ]
冒泡排序分析(video)
- <[ ]
插入排序&歸併排序(video)
- <[ ]
插入排序(video)
- <[ ]
歸併排序(video)
- <[ ]
快排(video)
- <[ ]
選擇排序(video)
- <[ ] 斯坦福大學關於排序算法的視頻:
- <[ ] Shai Simonson視頻,
Aduni.org
:
- <[ ]
算法-排序-第二講(video)
- <[ ]
算法-排序2 -第三講(video)
- <[ ]
- <[ ] Steven Skiena 關於排序的視頻:
- <[ ]
課程從26:46開始(video)
- <[ ]
課程從27:40開始(video)
- <[ ]
課程從35:00開始(video)
- <[ ]
課程從23:50開始(video)
- <[ ]
- <[ ] 加州大學伯克利分校(UC Berkeley) 大學課程:
- <[ ] - 歸併排序:
- <[ ] - 快速排序:
- <[ ] 實現:
- <[ ] 歸併:平均和最差情況的時間複雜度為O(n log n)。
- <[ ] 快排:平均時間複雜度為O(n log n)。
選擇排序和插入排序的最壞、平均時間複雜度都是O(n^2)。
關於堆排序,請查看前文堆的數據結構部分。
- <[ ] 有興趣的話,還有一些補充- 但並不是必須的:
- <[ ]
基數排序
- <[ ]
基數排序(video)
- <[ ]
基數排序,計數排序(線性時間內) (video)
- <[ ]
隨機算法:矩陣相乘,快排, Freivalds’算法(video)
- <[ ]
線性時間內的排序(video)
- <[ ]
圖(Graphs)
圖論能解決計算機科學裡的很多問題,所以這一節會比較長,像樹和排序的部分一樣。
Yegge 的筆記:
有3 種基本方式在內存裡表示一個圖:
對象和指針
矩陣
鄰接表
熟悉以上每一種圖的表示法,並了解各自的優缺點
寬度優先搜索和深度優先搜索- 知道它們的計算複雜度和設計上的權衡以及如何用代碼實現它們
遇到一個問題時,首先嘗試基於圖的解決方案,如果沒有再去嘗試其他的。
- <[ ] Skiena 教授的課程- 很不錯的介紹:
- <[ ] 圖(複習和其他):
- <[ ]
6.006單源最短路徑問題(video)
- <[ ]
6.006 Dijkstra算法(video)
- <[ ]
6.006 Bellman-Ford算法(video)
- <[ ]
6.006 Dijkstra效率優化(video)
- <[ ]
Aduni:圖的算法I -拓撲排序,最小生成樹, Prim算法-第六課(video)
- <[ ]
Aduni:圖的算法II -深度優先搜索,廣度優先搜索, Kruskal算法,並查集數據結構-第七課(video)
- <[ ]
Aduni:圖的算法III:最短路徑-第八課(video)
- <[ ]
Aduni:圖的算法. IV:幾何算法介紹-第九課(video)
- <[ ]
CS 61B 2014 (從58:09開始) (video)
- <[ ]
CS 61B 2014:加權圖(video)
- <[ ]
貪心算法:最小生成樹(video)
- <[ ]
圖的算法之強連通分量Kosaraju算法(video)
- <[ ]
完整的Coursera 課程:
- <[ ]
圖的算法(video)
- <[ ]
Yegge: 如果有機會,可以試試研究更酷炫的算法:
- <[ ] Dijkstra 算法- 上文- 6.006
- <[ ] A* 算法
- <[ ]
A*算法
- <[ ]
A*尋路教程(video)
- <[ ]
A*尋路(E01:算法解釋) (video)
- <[ ]
我會實現:
- <[ ] DFS 鄰接表(遞歸)
- <[ ] DFS 鄰接表(棧迭代)
- <[ ] DFS 鄰接矩陣(遞歸)
- <[ ] DFS 鄰接矩陣(棧迭代)
- <[ ] BFS 鄰接表
- <[ ] BFS 鄰接矩陣
- <[ ] 單源最短路徑問題(Dijkstra)
- <[ ] 最小生成樹
基於DFS 的算法(根據上文Aduni 的視頻):
- <[ ] 檢查環(我們會先檢查是否有環存在以便做拓撲排序)
- <[ ] 拓撲排序
- <[ ] 計算圖中的連通分支
- <[ ] 列出強連通分量
- <[ ] 檢查雙向圖
可以從Skiena 的書(參考下面的書推薦小節)和麵試書籍中學習更多關於圖的實踐。
更多知識
遞歸(Recursion)
- <[ ] Stanford 大學關於遞歸& 回溯的課程:
- <[ ]
課程8 |抽象編程(video)
- <[ ]
課程9 |抽象編程(video)
- <[ ]
課程10 |抽象編程(video)
- <[ ]
課程11 |抽象編程(video)
- <[ ]
什麼時候適合使用
尾遞歸會更好麼?
- <[ ]
什麼是尾遞歸以及為什麼它如此糟糕?
- <[ ]
尾遞歸(video)
- <[ ]
- <[ ] Stanford 大學關於遞歸& 回溯的課程:
動態規劃(Dynamic Programming)
This subject can be pretty difficult, as each DP soluble problem must be defined as a recursion relation, and coming up with it can be tricky.
這一部分會有點困難,每個可以用動態規劃解決的問題都必須先定義出遞推關係,要推導出來可能會有點棘手。
我建議先閱讀和學習足夠多的動態規劃的例子,以便對解決DP 問題的一般模式有個紮實的理解。
- <[ ] 視頻:
Skiena 的視頻可能會有點難跟上,有時候他用白板寫的字會比較小,難看清楚。
- <[ ]
Skiena: CSE373 2012 -課程19 -動態規劃介紹(video)
- <[ ]
Skiena: CSE373 2012 -課程20 -編輯距離(video)
- <[ ]
Skiena: CSE373 2012 -課程21 -動態規劃舉例(video)
- <[ ]
Skiena: CSE373 2012 -課程22 -動態規劃應用(video)
- <[ ]
Simonson:動態規劃0 (starts at 59:18) (video)
- <[ ]
Simonson:動態規劃I -課程11 (video)
- <[ ]
Simonson:動態規劃II -課程12 (video)
- <[ ]單獨的DP問題(每一個視頻都很短):
動態規劃(video)
- <[ ] Yale 課程筆記:
- <[ ]
動態規劃
- <[ ]
- <[ ] Coursera 課程:
- <[ ]
RNA二級結構問題(video)
- <[ ]
動態規划算法(video)
- <[ ]
DP算法描述(video)
- <[ ]
DP算法的運行時間(video)
- <[ ]
DP vs遞歸實現(video)
- <[ ]
全局成對序列排列(video)
- <[ ]
本地成對序列排列(video)
- <[ ]
組合(Combinatorics) (n 中選k 個) & 概率(Probability)
- <[ ]
數據技巧:如何找出階乘、排列和組合(選擇) (video)
- <[ ]
來點學校的東西:概率(video)
- <[ ]
來點學校的東西:概率和馬爾可夫鏈(video)
- <[ ] 可汗學院:
課程設置:
- <[ ]
概率理論基礎
- <[ ]
視頻- 41 (每一個都短小精悍):
- <[ ]
概率解釋(video)
- <[ ]
- <[ ]
NP, NP-完全和近似算法
知道最經典的一些NP完全問題,比如旅行商問題和背包問題,
而且能在面試官試圖忽悠你的時候識別出他們。
知道NP 完全是什麼意思.
- <[ ]
計算複雜度(video)
- <[ ] Simonson:
- <[ ]
貪心算法. II &介紹NP-完全性(video)
- <[ ]
NP-完全性II &歸約(video)
- <[ ]
NP-完全性III (Video)
- <[ ]
NP-完全性IV (video)
- <[ ]
- <[ ] Skiena:
- <[ ]
複雜度: P, NP, NP-完全性,規約(video)
- <[ ]
複雜度:近視算法Algorithms (video)
- <[ ]
複雜度:固定參數算法(video)
Peter Norvik 討論旅行商問題的近似最優解:
《算法導論》的第1048 – 1140 頁。
緩存(Cache)
- <[ ] LRU 緩存:
- <[ ] CPU 緩存:
進程(Processe)和線程(Thread)
- <[ ] 計算機科學162 - 操作系統(25 個視頻):
視頻1-11 是關於進程和線程
操作系統和系統編程(video)
進程和線程的區別是什麼?
涵蓋了:
進程、線程、協程
進程和線程的區別
進程
線程
鎖
互斥
信號量
監控
他們是如何工作的
死鎖
活鎖
CPU 活動, 中斷, 上下文切換
現代多核處理器的並發式結構
進程資源需要(內存:代碼、靜態存儲器、棧、堆、文件描述符、I/O)
線程資源需要(在同一個進程內和其他線程共享以上的資源,但是每個線程都有獨立的程序計數器、棧計數器、寄存器和棧)
Fork 操作是真正的寫時復制(只讀),直到新的進程寫到內存中,才會生成一份新的拷貝。
上下文切換
操作系統和底層硬件是如何初始化上下文切換的。
- <[ ]
C++的線程(系列- 10個視頻)
- <[ ] Python 的協程(視頻):
- <[ ]
線程系列
- <[ ]
Python線程
- <[ ]
理解Python的GIL (2010)
- <[ ]
David Beazley – Python協程- PyCon 2015
- <[ ]
Keynote David Beazley -興趣主題(Python異步I/O)
- <[ ]
Python中的互斥
系統設計以及可伸縮性,要把軟硬件的伸縮性設計的足夠好有很多的東西要考慮,所以這是個包含非常多內容和資源的大主題。需要花費相當多的時間在這個主題上。
- <[ ]
- <[ ] 計算機科學162 - 操作系統(25 個視頻):
系統設計、可伸縮性、數據處理
Yegge 的注意事項:
伸縮性
把大數據集提取為單一值
大數據集轉換
處理大量的數據集
系統
特徵集
接口
類層次結構
在特定的約束下設計系統
輕量和健壯性
權衡和折衷
性能分析和優化
- <[ ]
從這裡開始
:
HiredInTech:系統設計
- <[ ]
該如何為技術面試裡設計方面的問題做準備?
- <[ ]
在系統設計面試前必須知道的8件事
- <[ ]
算法設計
- <[ ]
數據庫範式- 1NF, 2NF, 3NF and 4NF (video)
- <[ ]
系統設計面試
-這一部分有很多的資源,瀏覽一下我放在下面的文章和例子。
- <[ ]
如何在系統設計面試中脫穎而出
- <[ ]
每個人都該知道的一些數字
- <[ ]
上下文切換操作會耗費多少時間?
- <[ ]
跨數據中心的事務(video)
- <[ ]
簡明CAP理論介紹
- <[ ] Paxos 一致性算法:
- <[ ]
一致性哈希
- <[ ]
NoSQL模式
- <[ ]
OOSE: UML 2.0系列(video)
- <[ ] OOSE: 使用UML 和Java 開發軟件(21 videos):
如果你對OO 都深刻的理解和實踐,可以跳過這部分。
OOSE: 使用UML 和Java 開發軟件
- <[ ] 面向對象編程的SOLID 原則:
- <[ ]
Bob Martin面向對象的SOLID原則和敏捷設計(video)
- <[ ]
C# SOLID設計模式(video)
- <[ ]
SOLID原則(video)
- <[ ] S -
單一職責原則
|
每個對象的單一職責
- <[ ] O -
開閉原則
|
生產環境裡的對象應該為擴展做準備而不是為更改
- <[ ] L -
里氏代換原則
|
基類和繼承類遵循’IS A’原則
- <[ ] I -
接口隔離原則
|客戶端被迫實現用不到的接口
- <[ ] D -
依賴反轉原則
|減少對象裡的依賴。
- <[ ]
- <[ ] 可伸縮性:
- <[ ]
很棒的概述(video)
- <[ ] 簡短系列:
- <[ ]
可伸縮的Web架構和分佈式系統
- <[ ]
錯誤的分佈式系統解釋
- <[ ]
實用編程技術
- <[ ]
Jeff Dean -在Goolge構建軟件系統(video)
- <[ ]
可伸縮系統架構設計介紹
- <[ ]
使用App Engine和雲存儲擴展面向全球用戶的手機遊戲架構實踐(video)
- <[ ]
How Google Does Planet-Scale Engineering for Planet-Scale Infra (video)
- <[ ]
算法的重要性
- <[ ]
分片
- <[ ]
Facebook系統規模擴展實踐(2009)
- <[ ]
Facebook系統規模擴展實踐(2012), “為10億用戶構建” (video)
- <[ ]
Long Game工程實踐- Astrid Atkinson Keynote(video)
- <[ ]
30分鐘看完YouTuBe 7年系統擴展經驗
- <[ ]
PayPal如何用8台虛擬機扛住10億日交易量系統
- <[ ]
如何對大數據集去重
- <[ ]
Etsy的擴展和工程文化探究Jon Cowie (video)
- <[ ]
是什麼造就了Amazon自己的微服務架構
- <[ ]
壓縮還是不壓縮,是Uber面臨的問題
- <[ ]
異步I/O Tarantool隊列
- <[ ]
什麼時候應該用近視查詢處理?
- <[ ]
Google從單數據中心到故障轉移,到本地多宿主架構的演變
- <[ ]
Spanner
- <[ ]
Egnyte:構建和擴展PB級分佈式系統架構的經驗教訓
- <[ ]
機器學習驅動的編程:新世界的新編程方式
- <[ ]
日服務數百萬請求的圖像優化技術
- <[ ]
Patreon架構
- <[ ]
Tinder:推薦引擎是如何決定下一個你將會看到誰的?
- <[ ]
現代緩存設計
- <[ ]
Facebook實時視頻流擴展
- <[ ]
在Amazon AWS上把服務擴展到1100萬量級的新手教程
- <[ ]
對延時敏感的應用是否應該使用Docker?
- <[ ]
AMP(Accelerated Mobile Pages)的存在是對Google的威脅麼?
- <[ ]
360度解讀Netflix技術棧
- <[ ]
延遲無處不在-如何搞定它?
- <[ ]
無服務器架構
- <[ ]
是什麼驅動著Instagram:上百個實例、幾十種技術
- <[ ]
Cinchcast架構-每天處理1500小時的音頻
- <[ ]
Justin.Tv實時視頻播放架構
- <[ ]
Playfish’s社交遊戲架構-每月五千萬用戶增長
- <[ ]
貓途鷹架構- 40萬訪客, 200萬動態頁面訪問, 30TB數據
- <[ ]
PlentyOfFish架構
- <[ ]
Salesforce架構-如何扛住13億日交易量
- <[ ]
ESPN’s架構擴展
- <[ ] 下面『消息、序列化和消息系統』部分的內容會提到什麼樣的技術能把各種服務整合到一起
- <[ ] Twitter:
更多內容可以查看視頻部分的『大規模數據挖掘』視頻系列。
- <[ ]
- <[ ] 系統設計問題練習:下面有一些指導原則,每一個都有相關文檔以及在現實中該如何處理。
複習:
HiredInTech的系統設計
cheat sheet
流程:
理解問題和範圍:
在面試官的幫助下定義用例
提出附加功能的建議
去掉面試官認定範圍以外的內容
假定高可用是必須的,而且要作為一個用例
考慮約束:
問一下每月請求量
問一下每秒請求量(他們可能會主動提到或者讓你算一下)
評估讀寫所佔的百分比
評估的時候牢記2/8 原則
每秒寫多少數據
總的數據存儲量要考慮超過5 年的情況
每秒讀多少數據
抽象設計:
分層(服務, 數據, 緩存)
基礎設施: 負載均衡, 消息
粗略的概括任何驅動整個服務的關鍵算法
考慮瓶頸並指出解決方案
練習:
論文
有Google 的論文和一些知名的論文.
你很可能實在沒時間一篇篇完整的讀完他們。我建議可以有選擇的讀其中一些論文裡的核心部分。
- <[ ]
1978:通信順序處理
- <[ ]
2003: The Google文件系統
2012 年被Colossus 取代了
- <[ ]
2004: MapReduce: Simplified Data Processing on Large Clusters
大多被雲數據流取代了?
- <[ ]
2007:每個程序員都應該知道的內存知識(非常長,作者建議跳過某些章節來閱讀)
- <[ ]
2012: Google的Colossus
沒有論文
- <[ ] 2012: AddressSanitizer: 快速的內存訪問檢查器:
- <[ ] 2013: Spanner: Google 的分佈式數據庫:
- <[ ]
2014: Machine Learning: The High-Interest Credit Card of Technical Debt
- <[ ]
2015: Continuous Pipelines at Google
- <[ ]
2015:大規模高可用:構建Google Ads的數據基礎設施
- <[ ]
2015: TensorFlow:異構分佈式系統上的大規模機器學習
- <[ ]
2015:開發者應該如何搜索代碼:用例學習
- <[ ]
2016: Borg, Omega, and Kubernetes
測試
涵蓋了:
單元測試是如何工作的
什麼是模擬對象
什麼是集成測試
什麼是依賴注入
- <[ ]
James Bach講敏捷軟件測試(video)
- <[ ]
James Bach軟件測試公開課(video)
- <[ ]
Steve Freeman -測試驅動的開發(video)
- <[ ]
測試驅動的開發已死.測試不朽。
- <[ ]
測試驅動的開發已死? (video)
- <[ ]
視頻系列(152個) -並不都是必須(video)
- <[ ]
Python:測試驅動的Web開發
- <[ ] 依賴注入:
- <[ ]
如何編寫測試
調度
在操作系統中是如何運作的
在操作系統部分的視頻裡有很多資料
實現系統例程
理解你使用的系統API 底層有什麼
你能自己實現它們麼?
字符串搜索和操作
- <[ ]
文本的搜索模式(video)
- <[ ] Rabin-Karp (videos):
- <[ ] Knuth-Morris-Pratt (KMP) 算法:
- <[ ] Boyer–Moore 字符串搜索算法
- <[ ]
Coursera:字符串的算法
- <[ ]
終面
这一部分有一些短视频,你可以快速的观看和复习大多数重要概念。
这对经常性的巩固很有帮助。
綜述:
排序:
書籍
Google Coaching 裡提到的
閱讀並做練習:
- <[ ] 算法設計手冊(Skiena)
書(Kindle 上可以租到):
http://
Half.com
是一個資源豐富且性價比很高的在線書店.
答案:
勘誤表
read and do exercises from the books below. Then move to coding challenges (further down below)
一旦你理解了每日計劃裡的所有內容,就去讀上面所列的書並完成練習,然後開始讀下面所列的書並做練習,之後就可以開始實戰寫代碼了(本文再往後的部分)
首先閱讀:
然後閱讀(這本獲得了很多推薦, 但是不在Google coaching 的文檔裡):
- <[ ]
Cracking the Coding Interview, 6th Edition
如果你看到有人在看“The Google Resume”, 實際上它和“Cracking the Coding Interview” 是同一個作者寫的,而且後者是升級版。
附加書單
這些沒有被Google 推薦閱讀,不過我因為需要這些背景知識所以也把它們列在了這裡。
- <[ ] C Programming Language, Vol 2
- <[ ] C++ Primer Plus, 6th Edition
- <[ ]
《Unxi環境高級編程》 The Unix Programming Environment
- <[ ]
《編程珠璣》 Programming Pearls
- <[ ]
Algorithms and Programming: Problems and Solutions
如果你有時間
- <[ ]
Introduction to Algorithms
- <[ ]
Elements of Programming Interviews
如果你希望在面試裡用C++ 寫代碼,這本書的代碼全都是C++ 寫的
通常情況下能找到解決方案的好書.
編碼練習和挑戰
一旦你學會了理論基礎,就應該把它們拿出來練練。
盡量堅持每天做編碼練習,越多越好。
編程問題預備:
- <[ ]
不錯的介紹(摘自System Design章節):算法設計:
- <[ ]
如何找到解決方案
- <[ ]
如何剖析Topcoder題目描述
- <[ ]
Topcoders裡用到的數學
- <[ ]
動態規劃–從入門到精通
MIT 面試材料
針對編程語言本身的練習
編碼練習平台:
當你臨近面試時
- <[ ] 搞定代碼面試(videos):
你的簡歷
10 條小貼士讓你寫出一份還算不錯的簡歷
這是搞定面試的第一個關鍵步驟
當面試來臨的時候
随着下面列举的问题思考下你可能会遇到的 20 个面试问题
每个问题准备 2-3 种回答
准备点故事,不要只是摆一些你完成的事情的数据,相信我,人人都喜欢听故事
你為什麼想得到這份工作?
你解決過的最有難度的問題是什麼?
面對過的最大挑戰是什麼?
見過的最好或者最壞的設計是怎麼樣的?
對某項Google 產品提出改進建議。
你作為一個個體同時也是團隊的一員,如何達到最好的工作狀態?
你的什麼技能或者經驗是你的角色中不可或缺的?為什麼?
你在某份工作或某個項目中最享受的是什麼?
你在某份工作或某個項目中面臨過的最大挑戰是什麼?
你在某份工作或某個項目中遇到過的最蛋疼的Bug 是什麼樣的?
你在某份工作或某個項目中學到了什麼?
你在某份工作或某個項目中哪些地方還可以做的更好?
問面試官的問題
我会问的一些:(可能我已经知道了答案但我想听听面试官的看法或者了解团队的前景):
團隊多大規模?
開發週期是怎樣的? 會使用瀑布流/極限編程/敏捷開發麼?
經常會為deadline 加班麼? 或者是有彈性的?
團隊裡怎麼做技術選型?
每周平均開多少次會?
你覺得工作環境有助於員工集中精力嗎?
目前正在做什麼工作?
喜歡這些事情嗎?
工作期限是怎麼樣的?
當你獲得了夢想的職位
我還能說些什麼呢,恭喜你!
堅持繼續學習。
得到這份工作只是一個開始。
*****************************************************************************************************
*****************************************************************************************************
Everything below this point is optional. These are my recommendations, not Google's.
By studying these, you'll get greater exposure to more CS concepts, and will be better prepared for
any software engineering job.
*****************************************************************************************************
*****************************************************************************************************
Additional Learning
Unicode
Endianness
- <[ ]
Big And Little Endian
- <[ ]
Big Endian Vs Little Endian (video)
- <[ ]
Big And Little Endian Inside/Out (video)
Very technical talk for kernel devs. Don’t worry if most is over your head.
The first half is enough.
- <[ ]
Emacs and vi(m)
suggested by Yegge, from an old Amazon recruiting post: Familiarize yourself with a unix-based code editor
vi(m):
emacs:
Unix 命令行工具
信息資源(視頻)
- <[ ]
Khan Academy可汗學院
- <[ ] 更多有關馬爾可夫的內容:
關於更多信息,請參照下方MIT 6.050J 信息和系統複雜度的內容.
- <[ ]
奇偶校驗位& 漢明碼(視頻)
系統熵值(系統複雜度)
請參考下方視頻
觀看之前,請先確定觀看了信息論的視頻
- <[ ]
信息理論,克勞德·香農,熵值,系統冗餘,數據比特壓縮(視頻)
密碼學
壓縮
觀看之前,請先確定觀看了信息論的視頻
- <[ ] 壓縮(視頻):
- <[ ]
壓縮
- <[ ]
壓縮熵值
- <[ ]
由上而下的樹(霍夫曼編碼樹)
- <[ ]
額外比特-霍夫曼編碼樹
- <[ ]
優雅的壓縮數據(無損數據壓縮方法)
- <[ ]
Text Compression Meets Probabilities
- <[ ]
- <[ ]
數據壓縮的藝術
- <[ ]
(可選)谷歌開發者: GZIP還差遠了呢!
網絡(視頻)
- <[ ]
可汗學院
- <[ ]
網絡傳輸協議中的數據壓縮
- <[ ]
TCP/IP和OSI模型解析!
- <[ ]
TCP/IP教程:傳輸數據包.
- <[ ]
HTTP
- <[ ]
SSL和HTTPS
- <[ ]
SSL/TLS
- <[ ]
HTTP 2.0
- <[ ]
視頻
- <[ ]
子網絡解密-第五部分經典內部域名指向CIDR標記
- <[ ]
計算機安全
釋放緩存
- <[ ]
Java釋放緩存;片段化數據(視頻)
- <[ ]
編譯器(視頻)
- <[ ]
Python釋放緩存(視頻)
- <[ ]
深度解析:論釋放緩存在JAVA中的重要性
- <[ ]
深度解析:論釋放緩存在Python中的重要性(視頻)
- <[ ]
平行化(多線程)編程
- <[ ]
Coursera (Scala)
- <[ ]
論平行化編程如何提高Python執行效率(視頻)
- <[ ]
設計模式
- <[ ]
UML統一建模語言概覽(視頻)
- <[ ] 主要有如下的設計模式:
- <[ ] s(strategy)
- <[ ] singleton
- <[ ] adapter
- <[ ] prototype
- <[ ] decorator
- <[ ] visitor
- <[ ] factory, abstract factory
- <[ ] facade
- <[ ] observer
- <[ ] proxy
- <[ ] delegate
- <[ ] command
- <[ ] state
- <[ ] memento
- <[ ] iterator
- <[ ] composite
- <[ ] flyweight
- <[ ]
第六章(第1部分) -設計模式(視頻)
- <[ ]
第六章(第2部分) – Abstraction-Occurrence, General Hierarchy, Player-Role, Singleton, Observer, Delegation (視頻)
- <[ ]
第六章(第3部分) – Adapter, Facade, Immutable, Read-Only Interface, Proxy (video)
- <[ ]
視頻
- <[ ]
Head Fisrt設計模型
儘管這本書叫做設計模式:重複使用模塊,但是我還是認為Head First是對於新手來說很不錯的書。
- <[ ]
基於實際操作對於入門開發者的建議
- <[ ]
信息傳輸, 序列化,和隊列化的系統
- <[ ]
Thrift
- <[ ]
協議緩衝
- <[ ]
gRPC
- <[ ]
Redis
- <[ ]
Amazon的SQS系統(隊列)
- <[ ]
Amazon的SNS系統(pub-sub)
- <[ ]
RabbitMQ
- <[ ]
Celery
- <[ ]
ZeroMQ
- <[ ]
ActiveMQ
- <[ ]
Kafka
- <[ ]
MessagePack
- <[ ]
Avro
- <[ ]
快速傅里葉變換
- <[ ]
什麼是傅立葉變換?論傅立葉變換的用途
- <[ ]
什麼是傅立葉變換?(視頻)
- <[ ]
關於FFT的不同觀點(視頻)
- <[ ]
FTT是什麼
- <[ ]
布隆過濾器
給一個布隆過濾器m比特和k個哈希函數,所有的注入和相關測試都會是通過。
布隆過濾器
布隆過濾器| 數據挖掘| Stanford University
教程
如何寫一個布隆過濾器應用
van Emde Boas 樹
- <[ ]
爭論: van Emde Boas樹(視頻)
- <[ ]
MIT課堂筆記
- <[ ]
更深入的數據結構
- <[ ]
CS 61B第39課:更深入的數據結構
- <[ ]
跳表
“有一種非常迷幻的數據類型” – Skiena
- <[ ]
隨機化:跳表(視頻)
- <[ ]
更生動詳細的解釋
網絡流
- <[ ]
5分鐘簡析Ford-Fulkerson (視頻)
- <[ ]
Ford-Fulkerson算法(視頻)
- <[ ]
網絡流(視頻)
- <[ ]
不相交集& 聯合查找
Math for Fast Processing
Treap
Combination of a binary search tree and a heap
- <[ ]
Treap
- <[ ]
Data Structures: Treaps explained (video)
- <[ ]
Applications in set operations
線性規劃(Linear Programming)(視頻)
幾何:凸包(Geometry, Convex hull)(視頻)
離散數學
查看下面的視頻:(這裡沒看到視頻= =)
機器學習(Machine Learning)
- <[ ] 為什麼學習機器學習?
- <[ ]
谷歌云機器學習工具(視頻)
- <[ ]
谷歌開發者機器學習清單(Scikit Learn和Tensorflow) (視頻)
- <[ ]
Tensorflow (視頻)
- <[ ]
Tensorflow教程
- <[ ]
Python實現神經網絡實例教程(使用Theano)
課程:
- <[ ]
很棒的初級課程:機器學習
- [视频教程](https://www.youtube.com/playlist?list=PLZ9qNFMHZ-A4rycgrgOYma6zxF4BZGGPW) - 看第 12-18 集复习线性代数(第 14 集和第 15 集是重复的)
- <[ ]
機器學習中的神經網絡
- <[ ]
Google深度學習微學位
- <[ ]
Google/Kaggle機器學習工程師微學位
- <[ ]
無人駕駛工程師微學位
- <[ ]
Metis在線課程(兩個月99美元)
- <[ ]
資源:
Go 語言
- <[ ] 視頻:
- <[ ]
為什麼學習Go語言?
- <[ ]
Go語言編程
- <[ ]
Go語言之旅
- <[ ]
- <[ ] 書籍:
- <[ ]
Go語言新手訓練營
- <[ ] 視頻:
—
一些主題的額外內容
我为前面提到的某些主题增加了一些额外的内容,之所以没有直接添加到前面,是因为这样很容易导致某个主题内容过多。毕竟你想在本世纪找到一份工作,对吧?
- <[ ]
動態規劃的更多內容
(視頻)
- <[ ]
圖形處理進階
(視頻)
- <[ ]
異步分佈式算法:對稱性破缺,最小生成樹
- <[ ]
異步分佈式算法:最小生成樹
- <[ ]
- <[ ] MIT
概率論
(mathy, and go slowly, which is good for mathy things) (視頻):
- <[ ]
MIT 6.042J -概率論概述
- <[ ]
MIT 6.042J -條件概率Probability
- <[ ]
MIT 6.042J -獨立
- <[ ]
MIT 6.042J -隨機變量
- <[ ]
MIT 6.042J -期望I
- <[ ]
MIT 6.042J -期望II
- <[ ]
MIT 6.042J -大偏差
- <[ ]
MIT 6.042J -隨機遊走
- <[ ]
- <[ ]
Simonson:近似算法(視頻)
視頻系列
坐下來享受一下吧。”netflix and skill” 😛
- <[ ]
個人的動態規劃問題列表(都是短視頻喲)
- <[ ]
x86架構,彙編,應用程序(11個視頻)
- <[ ]
MIT 18.06線性代數,2005年春季(35個視頻)
- <[ ]
絕妙的MIT微積分:單變量微積分
- <[ ]
計算機科學70, 001 – 2015年春季-離散數學和概率理論
- <[ ]
離散數學(19個視頻)
- <[ ] CSE373 - 算法分析(25 個視頻)
- <[ ]
UC Berkeley 61B (2014年春季):數據結構(25個視頻)
- <[ ]
UC Berkeley 61B (2006年秋季):數據結構(39個視頻)
- <[ ]
UC Berkeley 61C:計算機結構(26個視頻)
- <[ ]
OOSE:使用UML和Java進行軟件開發(21個視頻)
- <[ ]
UC Berkeley CS 152:計算機結構和工程(20個視頻)
- <[ ]
MIT 6.004:計算結構(49視頻)
- <[ ]
卡內基梅隆大學-計算機架構講座(39個視頻)
- <[ ]
MIT 6.006:算法介紹(47個視頻)
- <[ ]
MIT 6.033:計算機系統工程(22個視頻)
- <[ ]
MIT 6.034人工智能, 2010年秋季(30個視頻)
- <[ ]
MIT 6.042J:計算機科學數學, 2010年秋季(25個視頻)
- <[ ]
MIT 6.046:算法設計與分析(34個視頻)
- <[ ]
MIT 6.050J:信息和熵, 2008年春季(19個視頻)
- <[ ]
MIT 6.851:高等數據結構(22個視頻)
- <[ ]
MIT 6.854:高等算法, 2016年春季(24個視頻)
- <[ ]
MIT 6.858計算機系統安全, 2014年秋季
- <[ ] 斯坦福: 編程範例(17 個視頻)
- <[ ]
密碼學導論
- <[ ]
大數據-斯坦福大學(94個視頻)
計算機科學課程