Coding Interview University
我最初创建这份资料,只是为了列一个简短的学习清单,目标是成为一名软件工程师,但随着时间推移,它逐渐演变成了你今天看到的这份庞大清单。完成这份学习计划之后,我成功入职亚马逊,担任软件开发工程师!你可能不需要像我一样花那么多时间学习。总之,你所需要的一切都在这里了。我每天学习约 8-12 小时,持续了好几个月。这是我的故事:为什么我为了 Google 面试而全职备考了 8 个月 请注意: 你不需要像我一样学那么多。我在很多不必要的知识上浪费了大量时间,下文会详细说明。我会帮你避开这些弯路,不浪费你宝贵的时间。这里列出的内容将帮助你为几乎任何软件公司的技术面试做好充分准备,包括各大巨头:Amazon、Facebook、Google 和 Microsoft。祝你好运!
翻译版本:
Bahasa Indonesia
Bulgarian
Español
German
Japanese (日本語)
Marathi
Polish
Português Brasileiro
Russian
Tiếng Việt - Vietnamese
Urdu - اردو
Uzbek
বাংলা - Bangla
ខ្មែរ - Khmer
简体中文
繁體中文
翻译进行中:
Afrikaans
Arabic
French
Greek
Italian
Korean(한국어)
Malayalam
Persian - Farsi
Telugu
Thai
Turkish
Українська
עברית
हिन्दी
这是什么?
这是我为进入大型公司担任软件工程师而制定的多月学习计划。
前提条件:
有一定的编程基础(变量、循环、方法/函数等)
耐心
时间
请注意,这是一份针对软件工程的学习计划,并非前端工程或全栈开发。针对那些职业路径,其他地方有非常出色的路线图和课程资源(详见 https://roadmap.sh/)。
大学计算机科学课程涵盖的内容非常广泛,但对于面试来说,掌握其中约 75% 已经足够,因此我在这里只涵盖这部分内容。如果你想要完整的 CS 自学方案,我的学习计划所参考的资源已被收录进 Kamran Ahmed 的 Computer Science Roadmap:https://roadmap.sh/computer-science
目录
学习计划
这是什么?
为什么使用它?
如何使用它
不要觉得自己不够聪明
关于视频资源的说明
选择一门编程语言
数据结构与算法书籍
面试备考书籍
不要重蹈我的覆辙
不涵盖的内容
每日计划
编程题练习
编程题目
学习主题
算法复杂度 / Big-O / 渐近分析
数据结构 数组
链表
栈
队列
哈希表
更多知识 二分查找
位运算
树 树——入门
二叉搜索树:BST
堆 / 优先队列 / 二叉堆
平衡搜索树(一般概念,无需深入细节)
遍历:前序、中序、后序、BFS、DFS
排序 选择排序
插入排序
堆排序
快速排序
归并排序
图 有向图
无向图
邻接矩阵
邻接表
遍历:BFS、DFS
更多知识 递归
动态规划
设计模式
组合数学(n 选 k)与概率
NP、NP-Complete 与近似算法
计算机如何处理程序
缓存
进程与线程
测试
字符串搜索与操作
Trie
浮点数
Unicode
字节序(Endianness)
网络
最终复习
获得工作机会
更新你的简历
寻找工作
面试流程与通用面试准备
面试时需要思考的问题
向面试官提问
入职之后
---------------- 以下内容均为可选 ----------------
可选附加主题与资源
额外书籍
系统设计、可扩展性、数据处理(适合 4 年以上经验者)
额外学习内容 编译器
Emacs 与 vi(m)
Unix 命令行工具
信息论
奇偶校验与 Hamming Code
熵
密码学
压缩
计算机安全
垃圾回收
并行编程
消息系统、序列化与队列系统
A*
快速傅里叶变换
Bloom Filter
HyperLogLog
局部敏感哈希(Locality-Sensitive Hashing)
van Emde Boas 树
增强数据结构
平衡搜索树 AVL 树
伸展树(Splay trees)
红黑树
2-3 搜索树
2-3-4 树(又称 2-4 树)
N 叉树(K 叉树、M 叉树)
B 树
k-D 树
跳表(Skip lists)
网络流
不相交集合与并查集(Union Find)
快速处理的数学知识
Treap
线性规划
几何学、凸包
离散数学
部分主题的额外详细内容
视频系列
计算机科学课程
论文
为什么使用它?
如果你想在大型公司担任软件工程师,这些都是你必须掌握的知识。
如果你和我一样没有计算机科学学位,这份资料可以帮你补上这段空白,省去四年的时间成本。
当我启动这个项目时,我连栈和堆的区别都不知道,对 Big-O 一无所知,也不了解树,更不知道如何遍历图。如果当时要我写一个排序算法,我可以告诉你,那一定会惨不忍睹。我用过的每一种数据结构都是语言内置的,我根本不知道它们底层是如何运作的。我从不需要手动管理内存,除非某个运行中的进程报出"内存不足"的错误,那时我才不得不想办法绕过去。我这辈子用过几次多维数组、成千上万次关联数组,但我从未从零手写过一个数据结构。
这是一份很长的计划,可能需要你花费数月时间。如果你对其中很多内容已经熟悉,所需时间会大大缩短。
如何使用它
以下所有内容都是提纲,你应该按照从上到下的顺序逐一完成。
我使用了 GitHub 特有的 Markdown 格式,包括用任务列表来追踪进度。
- 更多关于 GitHub Markdown 格式的说明
如果你不想使用 git
在本页面,点击顶部附近的 Code 按钮,然后点击"Download ZIP"。解压文件后,你就可以直接操作文本文件了。
如果你在一个支持 Markdown 渲染的代码编辑器中打开,所有内容都会以格式化的方式清晰呈现。
如果你熟悉 git
创建一个新分支,这样你就可以像下面这样勾选条目,只需在方括号内填入 x:[x]
Fork GitHub 仓库:
https://github.com/jwasham/coding-interview-university点击 Fork 按钮即可。克隆到本地仓库:
git clone https://github.com/ /coding-interview-university.git cd coding-interview-university git remote add upstream https://github.com/jwasham/coding-interview-university.git git remote set-url --push upstream DISABLE # so that you don't push your personal progress back to the original repo完成修改后,用 X 标记所有复选框:
git commit -am " Marked personal progress " git pull upstream main # keep your fork up-to-date with changes from the original repo git push # just pushes to your fork
不要觉得自己不够聪明
成功的软件工程师都很聪明,但很多人都有一种不安全感,觉得自己不够聪明。
以下视频或许能帮你克服这种不安全感:《天才程序员的神话》
《独自上路的危险:与科技圈隐形怪物的较量》
关于视频资源的说明
部分视频只有注册 Coursera 或 EdX 课程才能观看,这类课程被称为 MOOC。有时候课程并不在开课期间,你可能需要等待数月,在此期间无法访问相关内容。
如果能用免费且始终可访问的公开资源(例如 YouTube 视频,最好是大学讲座)来替换这些在线课程资源就好了,这样大家随时都可以学习,而不必等待某个特定在线课程开课。
选择一门编程语言
你需要为编程面试选择一门编程语言,同时也需要找一门可以用来学习计算机科学概念的语言。
最好两者选用同一门语言,这样你只需精通一门就够了。
针对本学习计划
当我执行这份学习计划时,主要使用了两种语言:C 和 Python
C:非常底层。它允许你直接操作指针以及内存的分配与释放,让你对数据结构和算法有刻骨铭心的体会。在 Python 或 Java 这类高级语言中,这些细节都被隐藏起来了。在日常工作中,这当然很好,但当你学习这些底层数据结构是如何构建的时候,能够贴近底层是很有裨益的。C 语言无处不在,在你学习期间,无论是书籍、讲座还是视频,随处都能看到它的身影。
《C 程序设计语言(第 2 版)》 这是一本篇幅不长的书,但它能让你对 C 语言有很好的掌握,稍加练习你就能迅速上手。理解 C 有助于你理解程序和内存的运作原理。
你不需要把书啃得很深(甚至不需要读完)。只要达到能够流畅阅读和编写 C 代码的程度即可。
Python:现代且表达能力极强,我学习它是因为它实在太实用了,而且在面试中能让我写更少的代码。
这是我个人的偏好,你当然可以选择自己喜欢的语言。
你可能用不上,但以下是一些学习新语言的网站:
Exercism
Codewars
HackerEarth
Scaler Topics(Java、C++)
Programiz PRO Community Challenges
针对编程面试
你可以使用自己熟悉的语言来完成面试中的编程环节,但对于大型公司来说,以下是比较稳妥的选择:
C++
Java
Python
以下语言也可以使用,但建议先多方了解一下,可能存在一些注意事项:
JavaScript
Ruby
这是我写的一篇关于如何为面试选择语言的文章:为编程面试选择一门语言。这是我那篇文章所参考的原文:为面试选择编程语言
你需要对所选语言非常熟悉,并且具备扎实的知识储备。
阅读更多关于如何选择的内容:
- 为你的编程面试选择合适的语言
数据结构与算法书籍
这本书将奠定你计算机科学的基础。
只需选择一本,用你最熟悉的语言版本即可。你将进行大量的阅读和编程练习。
Python
《Coding Interview Patterns: Nail Your Next Coding Interview》(首要推荐) 来自业内人士的视角,揭示面试官真正考察的内容及其原因。
101 道真实编程面试题,附详细解答。
直观易懂的解析,引导你像在真实面试中一样逐步解题。
1000+ 张图解,清晰呈现核心概念与解题模式。
C
- 《Algorithms in C, Parts 1-5(合订本)第 3 版》 涵盖基础知识、数据结构、排序、搜索与图算法
Java
任选其一:
Goodrich、Tamassia、Goldwasser 著《Data Structures and Algorithms in Java》
Sedgewick 与 Wayne 著《Algorithms》
免费 Coursera 课程,涵盖该书内容(由作者亲自讲授!):Algorithms I
Algorithms II
C++
自选其一:
Goodrich、Tamassia 与 Mount 所著《Data Structures and Algorithms in C++》第 2 版
Sedgewick 与 Wayne 所著《Algorithms in C++》第 1-4 部分:基础知识、数据结构、排序、搜索
《Algorithms in C++ Part 5: Graph Algorithms》
面试备考书单
以下是一些推荐书目,可作为学习的补充参考。
《Coding Interview Patterns: Nail Your Next Coding Interview》
《Programming Interviews Exposed: Coding Your Way Through the Interview》第 4 版,答案使用 C++ 和 Java 编写
适合作为《Cracking the Coding Interview》的热身读物
难度不高。大多数题目可能比你在面试中实际遇到的更简单(据我所读)
《Cracking the Coding Interview》第 6 版,答案使用 Java 编写
如果你有大量额外时间:
从以下选择其一:
《Elements of Programming Interviews》(C++ 版)
《Elements of Programming Interviews in Python》
《Elements of Programming Interviews》(Java 版)- 配套项目:书中每道题的方法存根与测试用例
不要重蹈我的覆辙
这份清单历经数月积累,确实有些失控了。
以下是我曾犯过的一些错误,希望能让你少走弯路,节省数月时间。
1. 你不可能记住所有内容
我看了数小时的视频,记了大量笔记,但几个月后很多内容都忘了。我花了 3 天时间整理笔记、制作闪卡以便复习,结果发现其中大部分知识根本用不上。
请务必阅读这篇文章,避免重蹈我的覆辙:
Retaining Computer Science Knowledge。
2. 使用闪卡
为了解决这个问题,我自己做了一个小型闪卡网站,可以添加两种类型的闪卡:通用型和代码型。每种卡片格式不同。我将其做成移动端优先的网站,这样无论在哪里,我都可以用手机或平板复习。
免费制作你自己的闪卡:
- 闪卡网站仓库
我不推荐直接使用我的闪卡。 数量太多,而且大部分都是你用不到的冷知识。
但如果你非要用,这里是链接:
我的闪卡数据库(1200 张):
我的闪卡数据库(极限版 - 1800 张):
请注意,我当时做得有些过头了,卡片内容涵盖从汇编语言、Python 冷知识到机器学习和统计学的方方面面,远超实际所需。
关于闪卡的注意事项: 第一次认出答案时,不要把它标记为"已掌握"。你需要多次看到同一张卡并连续答对,才算真正掌握。通过重复,这些知识才会在你的大脑中留下深刻印记。
使用闪卡网站的另一个替代方案是 Anki,已被多次向我推荐。它采用间隔重复系统帮助记忆,界面友好,支持全平台,并具备云同步功能。iOS 上售价 25 美元,其他平台免费。
我的闪卡数据库(Anki 格式):https://ankiweb.net/shared/info/25173560(感谢 @xiewenya)。
有些学生反映存在空白字符导致的格式问题,可通过以下方法修复:打开牌组,编辑卡片,点击"卡片",选择"样式"单选按钮,并在卡片类中添加 white-space: pre; 属性。
3. 在学习的同时练习编程面试题
这一点非常重要。
在学习数据结构和算法的同时,就要开始练习编程面试题。
你需要将所学知识应用于解题,否则很快就会遗忘。这正是我当年犯的错误。
当你学完某个主题并感到较为熟悉时,例如链表:
打开一本编程面试书(或下文列出的编程题网站)
做 2 到 3 道关于链表的题目
继续学习下一个主题
之后再回头做另外 2 到 3 道链表题
对每个新学的主题都这样做
在学习所有内容的过程中持续刷题,而不是等学完之后再刷。
面试考察的不是你掌握了多少知识,而是你如何运用这些知识。
相关资源很多,下文均有列出,继续加油。
4. 专注
有很多干扰会占用你宝贵的时间。专注和集中注意力是很难的。放一些没有歌词的音乐,你会发现自己能更好地集中精神。
本计划不涉及的内容
以下是一些常见技术,但不在本学习计划的范围之内:
Javascript
HTML、CSS 及其他前端技术
SQL
每日计划
本课程涵盖大量主题,每个主题可能需要几天甚至一周或更长时间,具体取决于你的学习安排。
每天从列表中取下一个主题,观看相关视频,然后用你为本课程选定的编程语言实现该数据结构或算法。
你可以在这里查看我的代码:
C
C++
Python
你不需要记住每一种算法,只需理解到足以写出自己的实现即可。
编程题练习
Why is this here? I'm not ready to interview.
为什么需要练习编程题:
识别问题类型,判断哪种数据结构和算法适合解决该问题
梳理问题的需求
像面试时一样,边思考边口头讲解你的解题过程
在白板或纸上写代码,而不是用电脑
分析你的解法的时间复杂度和空间复杂度(见下文 Big-O 部分)
测试你的解法
有一篇很好的文章介绍了如何在面试中系统、清晰地解决问题,编程面试书里也会讲到,但我觉得这篇文章尤为出色:Algorithm design canvas
在白板或纸上写代码,而不是用电脑。用一些样例输入测试一遍,然后再把代码打到电脑上运行验证。
如果家里没有白板,可以去美术用品店买一个大型绘图板。你可以坐在沙发上练习,这就是我的"沙发白板"。照片里的笔只是用来对比大小的。如果你用钢笔写,你会后悔没法擦掉的,很快就会一团乱。我用的是铅笔和橡皮。
编程题练习的目的不是死记硬背题目答案。
编程题目
别忘了这里的重点编程面试书籍。
解题方法:
如何找到解题思路
如何拆解 Topcoder 的题目描述
编程面试题视频:
IDeserve(88 个视频)
Tushar Roy(5 个播放列表)——非常适合跟着学习解题思路
Nick White - LeetCode Solutions(187 个视频)——对解法和代码的讲解清晰易懂
可以在短时间内连续观看多个
FisherCoder - LeetCode Solutions
刷题/练习网站:
LeetCode——我最喜欢的编程题网站。备考期间(通常为 1-2 个月)订阅会员是值得的。
代码讲解可参考上面提到的 Nick White 和 FisherCoder 视频。
HackerRank
TopCoder
Codeforces
Codility
Geeks for Geeks
AlgoExpert——由 Google 工程师创建,也是磨练技能的优质资源。
Project Euler——非常注重数学,不太适合编程面试备考
让我们开始吧
好了,说够了,开始学习!
但别忘了在学习的同时练习上面的编程题!
算法复杂度 / Big-O / 渐进分析
这部分没有需要实现的内容,只需看视频、做笔记就好!太棒了!
这里有很多视频,看到理解为止就行,之后随时可以回来复习。
不用担心看不懂背后所有的数学推导。
你只需要理解如何用 Big-O 来表达一个算法的复杂度。
Harvard CS50 - Asymptotic Notation(视频)
Big O Notations(通用快速教程)(视频)
Big O Notation(以及 Omega 和 Theta)- 最佳数学解释(视频)
Skiena(视频)
UC Berkeley Big O(视频)
Amortized Analysis(摊还分析)(视频)
TopCoder(包含递推关系和主定理):Computational Complexity: Section 1
Computational Complexity: Section 2
速查表
[复习] 18 分钟分析算法(播放列表)(视频)
好了,这部分差不多就到这里。
当你读《Cracking the Coding Interview》时,有一章专门讲这个,最后还有一个小测验,让你判断不同算法的运行时复杂度。这是一个非常棒的复习和自测环节。
数据结构
数组 关于数组:Arrays CS50 Harvard University
Arrays(视频)
UC Berkeley CS61B - Linear and Multi-Dim Arrays(视频)(从第 15 分 32 秒开始观看)
Dynamic Arrays(动态数组)(视频)
Jagged Arrays(交错数组)(视频)
实现一个 vector(可自动扩容的可变数组):用数组和指针练习编程,用指针运算跳转到指定索引,而不是直接用下标访问。
可以在底层分配一个原始整型数组,但不使用其内置特性
初始大小为 16,若初始所需容量更大,则取大于该值的 2 的幂次——16、32、64、128
size()——返回当前元素个数
capacity()——返回当前可容纳的元素个数
is_empty()——是否为空
at(index)——返回指定索引处的元素,若索引越界则报错
push(item)——末尾添加元素
insert(index, item)——在指定索引处插入元素,将该位置及其后的元素向右移动
prepend(item)——在索引 0 处插入,可调用上面的 insert 实现
pop()——从末尾移除元素并返回其值
delete(index)——删除指定索引处的元素,将其后所有元素向左移动
remove(item)——查找该值并删除持有它的索引(即使出现在多个位置也全部删除)
find(item)——查找该值,返回第一个匹配的索引,未找到则返回 -1
resize(new_capacity)——私有函数,当容量满时调用,扩容为原来的两倍
当 pop 元素后,若当前元素个数为容量的 1/4,则缩容为原来的一半
时间复杂度:末尾添加/删除为 O(1)(扩容时为摊还复杂度),按索引访问或更新也是 O(1)
在其他位置插入/删除为 O(n)
空间:在内存中连续存储,有助于提升性能
所需空间 = (数组容量,>= n)× 每个元素大小,即使是 2n 也仍为 O(n)
链表 描述:Linked Lists CS50 Harvard University——建立直觉认知。
Singly Linked Lists(单链表)(视频)
CS 61B - Linked Lists 1(视频)
CS 61B - Linked Lists 2(视频)
[复习] 4 分钟了解链表(视频)
C Code(视频)——无需看完整个视频,只看关于 Node 结构体和内存分配的部分
Linked List vs Arrays: Core Linked Lists Vs Arrays(视频)
In The Real World Linked Lists Vs Arrays(视频)
Why you should avoid linked lists(为什么应该避免使用链表)(视频)
注意事项:你需要掌握指针的指针相关知识(用于当你将一个指针传递给某个函数,而该函数可能会改变该指针所指向的地址时)。本页仅供入门了解指针的指针,不推荐这种链表遍历方式,因为过于"聪明"会导致可读性和可维护性下降。Pointers to Pointers
实现(我分别用带尾指针和不带尾指针两种方式实现了):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) - 移除链表中第一个具有该值的元素
双向链表 Description (video)
无需实现
Stack Stacks (video)
[Review] Stacks in 3 minutes (video)
无需实现。用数组实现非常简单
Queue Queue (video)
循环缓冲区/FIFO
[Review] Queues in 3 minutes (video)
使用链表实现,带尾指针:enqueue(value) - 在尾部位置添加值
dequeue() - 返回值并移除最早添加的元素(头部)
empty()
使用固定大小的数组实现:enqueue(value) - 将元素添加到可用存储的末尾
dequeue() - 返回值并移除最早添加的元素
empty()
full()
复杂度:若使用链表的糟糕实现方式——在头部入队、在尾部出队,则为 O(n),因为每次出队都需要找到倒数第二个元素,导致每次都要完整遍历一次链表
enqueue:O(1)(均摊,链表和数组均适用 [探测法])
dequeue:O(1)(链表和数组均适用)
empty:O(1)(链表和数组均适用)
Hash table 视频:Hashing with Chaining (video)
Table Doubling, Karp-Rabin (video)
Open Addressing, Cryptographic Hashing (video)
PyCon 2010: The Mighty Dictionary (video)
PyCon 2017: The Dictionary Even Mightier (video)
(进阶)Randomization: Universal & Perfect Hashing (video)
(进阶)Perfect hashing (video)
[Review] Hash tables in 4 minutes (video)
在线课程:Core Hash Tables (video)
Data Structures (video)
Phone Book Problem (video)
分布式哈希表:Instant Uploads And Storage Optimization In Dropbox (video)
Distributed Hash Tables (video)
使用数组配合线性探测法实现:hash(k, m) - m 为哈希表的大小
add(key, value) - 若 key 已存在,则更新其值
exists(key)
get(key)
remove(key)
More Knowledge
Binary search Binary Search (video)
Binary Search (video)
详细说明
蓝图
[Review] Binary search in 4 minutes (video)
实现:二分查找(在已排序的整数数组上)
使用递归实现二分查找
Bitwise operations 位运算速查表——你应当熟记其中许多 2 的幂次方(从 2^1 到 2^16 以及 2^32)
深入理解使用以下运算符操作二进制位:&、|、^、~、>>、<< 相关词汇
推荐入门资料:Bit Manipulation (video)
C Programming Tutorial 2-10: Bitwise Operators (video)
Bit Manipulation
Bitwise Operation
Bithacks
The Bit Twiddler
The Bit Twiddler Interactive
Bit Hacks (video)
Practice Operations
2 的补码与 1 的补码 Binary: Plusses & Minuses (Why We Use Two's Complement) (video)
1s Complement
2s Complement
统计置位数(set bits) 4 ways to count bits in a byte (video)
Count Bits
How To Count The Number Of Set Bits In a 32 Bit Integer
值交换:Swap
绝对值:Absolute Integer
Trees
Trees - Intro Intro to Trees (video)
Tree Traversal (video)
BFS(广度优先搜索)和 DFS(深度优先搜索)(video) BFS 笔记:层序遍历(BFS,借助队列实现)
时间复杂度:O(n)
空间复杂度:最优:O(1),最差:O(n/2)=O(n)
DFS 笔记:时间复杂度:O(n)
空间复杂度:最优:O(log n) - 树的平均高度,最差:O(n)
中序遍历(DFS:左、自身、右)
后序遍历(DFS:左、右、自身)
前序遍历(DFS:自身、左、右)
[Review] Breadth-first search in 4 minutes (video)
[Review] Depth-first search in 4 minutes (video)
[Review] Tree Traversal (playlist) in 11 minutes (video)
Binary search trees: BSTs Binary Search Tree Review (video)
Introduction (video)
MIT (video)
C/C++:Binary search tree - Implementation in C/C++ (video)
BST implementation - memory allocation in stack and heap (video)
Find min and max element in a binary search tree (video)
Find the height of a binary tree (video)
Binary tree traversal - breadth-first and depth-first strategies (video)
Binary tree: Level Order Traversal (video)
Binary tree traversal: Preorder, Inorder, Postorder (video)
Check if a binary tree is a binary search tree or not (video)
Delete a node from Binary Search Tree (video)
Inorder Successor in a binary search tree (video)
实现: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 在概念上以树的形式呈现,但在存储上通常是线性结构(数组、链表)
Heap
Introduction (video)
Binary Trees (video)
Tree Height Remark (video)
Basic Operations (video)
Complete Binary Trees (video)
Pseudocode (video)
Heap Sort - jumps to start (video)
Heap Sort (video)
Building a heap (video)
MIT 6.006 Introduction to Algorithms: Binary Heaps
CS 61B Lecture 24: Priority Queues (video)
Linear Time BuildHeap (max-heap)
[Review] Heap (playlist) in 13 minutes (video)
实现最大堆:insert
sift_up - insert 所需
get_max - 返回最大元素,但不移除它
get_size() - 返回已存储的元素数量
is_empty() - 若堆中不含任何元素则返回 true
extract_max - 返回最大元素并将其移除
sift_down - extract_max 所需
remove(x) - 移除索引 x 处的元素
heapify - 从一个元素数组构建堆,heap_sort 所需
heap_sort() - 借助最大堆或最小堆,将未排序数组原地转换为有序数组
Sorting
注意事项:实现各种排序算法,并掌握每种算法的最优/最差情况及平均时间复杂度:不要实现冒泡排序——它非常糟糕——O(n^2),除非 n <= 16
排序算法的稳定性("Quicksort 是稳定的吗?")Sorting Algorithm Stability
Stability In Sorting Algorithms
Stability In Sorting Algorithms
Sorting Algorithms - Stability
哪些算法可用于链表?哪些适用于数组?哪些两者皆可?不建议对链表进行排序,但归并排序是可行的。
Merge Sort For Linked List
堆排序请参见上方的堆数据结构部分。堆排序很出色,但不稳定
Sedgewick - Mergesort(5 个视频)1. Mergesort
-
- Bottom-up Mergesort
-
- Sorting Complexity
-
- Comparators
-
- Stability
Sedgewick - Quicksort(4 个视频)1. Quicksort
-
- Selection
-
- Duplicate Keys
-
- System Sorts
UC Berkeley: CS 61B Lecture 29: Sorting I (video)
CS 61B Lecture 30: Sorting II (video)
CS 61B Lecture 32: Sorting III (video)
CS 61B Lecture 33: Sorting V (video)
CS 61B 2014-04-21: Radix Sort (video)
Bubble Sort (video)
Analyzing Bubble Sort (video)
Insertion Sort, Merge Sort (video)
Insertion Sort (video)
Merge Sort (video)
Quicksort (video)
Selection Sort (video)
归并排序代码:Using output array (C)
Using output array (Python)
In-place (C++)
快速排序代码:Implementation (C)
Implementation (C)
Implementation (Python)
[Review] Sorting (playlist) in 18 minutes Quick sort in 4 minutes (video)
Heap sort in 4 minutes (video)
Merge sort in 3 minutes (video)
Bubble sort in 2 minutes (video)
Selection sort in 3 minutes (video)
Insertion sort in 2 minutes (video)
实现:归并排序:平均和最差情况均为 O(n log n)
快速排序:平均情况为 O(n log n)
选择排序和插入排序的平均和最差情况均为 O(n^2)
堆排序请参见上方的堆数据结构部分
非必须,但推荐了解:Sedgewick - Radix Sorts(6 个视频)1. Strings in Java
-
- Key Indexed Counting
-
- Least Significant Digit First String Radix Sort
-
- Most Significant Digit First String Radix Sort
-
- 3 Way Radix Quicksort
-
- Suffix Arrays
Radix Sort
Radix Sort (video)
Radix Sort, Counting Sort (linear time given constraints) (video)
Randomization: Matrix Multiply, Quicksort, Freivalds' algorithm (video)
Sorting in Linear Time (video)
总结:这里有一份 15 种排序算法 的可视化展示。如需深入了解该主题,请参阅 Additional Detail on Some Subjects 中的"Sorting"章节。
Graphs
图可以用来表示计算机科学中的许多问题,因此本节篇幅较长,与树和排序章节类似。
注意事项:在内存中表示图有 4 种基本方式:对象与指针
邻接矩阵
邻接表
邻接映射
熟悉每种表示方式及其优缺点
BFS 和 DFS——掌握它们的计算复杂度、各自的权衡取舍,以及如何在实际代码中实现
遇到问题时,优先寻找基于图的解法,若不适用再考虑其他方案
MIT(视频):Breadth-First Search
Depth-First Search
Skiena 讲座——极佳的入门资料:CSE373 2020 - Lecture 10 - Graph Data Structures (video)
CSE373 2020 - Lecture 11 - Graph Traversal (video)
CSE373 2020 - Lecture 12 - Depth First Search (video)
CSE373 2020 - Lecture 13 - Minimum Spanning Trees (video)
CSE373 2020 - Lecture 14 - Minimum Spanning Trees (con't) (video)
CSE373 2020 - Lecture 15 - Graph Algorithms (con't 2) (video)
图(回顾与扩展):6.006 Single-Source Shortest Paths Problem (video)
6.006 Dijkstra (video)
6.006 Bellman-Ford (video)
6.006 Speeding Up Dijkstra (video)
Aduni: Graph Algorithms I - Topological Sorting, Minimum Spanning Trees, Prim's Algorithm - Lecture 6 (video)
Aduni: Graph Algorithms II - DFS, BFS, Kruskal's Algorithm, Union Find Data Structure - Lecture 7 (video)
Aduni: Graph Algorithms III: Shortest Path - Lecture 8 (video)
Aduni: Graph Alg. IV: Intro to geometric algorithms - Lecture 9 (video)
CS 61B 2014: Weighted graphs (video)
Greedy Algorithms: Minimum Spanning Tree (video)
Strongly Connected Components Kosaraju's Algorithm Graph Algorithm (video)
[Review] Shortest Path Algorithms (playlist) in 16 minutes (video)
[Review] Minimum Spanning Trees (playlist) in 4 minutes (video)
完整 Coursera 课程:Algorithms on Graphs (video)
我将实现:使用邻接表的 DFS(递归)
使用邻接表的 DFS(用栈迭代)
使用邻接矩阵的 DFS(递归)
使用邻接矩阵的 DFS(用栈迭代)
使用邻接表的 BFS
使用邻接矩阵的 BFS
单源最短路径(Dijkstra)
最小生成树
基于 DFS 的算法(参见上方 Aduni 视频):检测环(拓扑排序所需,因为我们会在开始前先检测环)
拓扑排序
统计图中连通分量的数量
列出强连通分量
判断二分图
更多知识
递归 Stanford 递归与回溯讲座:Lecture 8 | Programming Abstractions(视频)
Lecture 9 | Programming Abstractions(视频)
Lecture 10 | Programming Abstractions(视频)
Lecture 11 | Programming Abstractions(视频)
什么时候适合使用递归?
尾递归为何优于普通递归?What Is Tail Recursion Why Is It So Bad?
Tail Recursion(视频)
5 Simple Steps for Solving Any Recursive Problem(视频)
动态规划 面试中你可能不会遇到动态规划题,但掌握识别一道题是否适合用动态规划求解的能力是很有价值的。
这个主题可能相当难,因为每个可用 DP 求解的问题都必须被定义为递推关系,而推导递推关系本身就颇具挑战。
建议多看动态规划题目的例子,直到你对其中涉及的模式有扎实的理解为止。
视频:Skiena: CSE373 2020 - Lecture 19 - Introduction to Dynamic Programming(视频)
Skiena: CSE373 2020 - Lecture 20 - Edit Distance(视频)
Skiena: CSE373 2020 - Lecture 20 - Edit Distance(continued)(视频)
Skiena: CSE373 2020 - Lecture 21 - Dynamic Programming(视频)
Skiena: CSE373 2020 - Lecture 22 - Dynamic Programming and Review(视频)
Simonson: Dynamic Programming 0(从 59:18 开始)(视频)
Simonson: Dynamic Programming I - Lecture 11(视频)
Simonson: Dynamic programming II - Lecture 12(视频)
单个 DP 题目列表(每道都很短):Dynamic Programming(视频)
Yale 课程讲义:Dynamic Programming
Coursera: The RNA secondary structure problem(视频)
A dynamic programming algorithm(视频)
Illustrating the DP algorithm(视频)
Running time of the DP algorithm(视频)
DP vs. recursive implementation(视频)
Global pairwise sequence alignment(视频)
Local pairwise sequence alignment(视频)
设计模式 Quick UML review(视频)
学习以下模式:strategy(策略模式)
singleton(单例模式)
adapter(适配器模式)
prototype(原型模式)
decorator(装饰器模式)
visitor(访问者模式)
factory, abstract factory(工厂模式、抽象工厂模式)
facade(门面模式)
observer(观察者模式)
proxy(代理模式)
delegate(委托模式)
command(命令模式)
state(状态模式)
memento(备忘录模式)
iterator(迭代器模式)
composite(组合模式)
flyweight(享元模式)
系列视频(27 个视频)
书籍:Head First Design Patterns 我知道经典教材是《Design Patterns: Elements of Reusable Object-Oriented Software》,但《Head First》对面向对象入门者来说非常友好。
实用参考:101 Design Patterns & Tips for Developers
组合数学(n 选 k)与概率论 Math Skills: How to find Factorial, Permutation, and Combination (Choose)(视频)
Make School: Probability(视频)
Make School: More Probability and Markov Chains(视频)
Khan Academy: Course layout: Basic Theoretical Probability
纯视频 - 共 41 个(每个都简单且简短):Probability Explained(视频)
NP、NP-Complete 与近似算法 了解最著名的 NP-complete 问题,例如旅行商问题和背包问题,并能在面试官换一种方式提问时识别出来。
了解 NP-complete 的含义。
Computational Complexity(视频)
Simonson: Greedy Algs. II & Intro to NP-Completeness(视频)
NP Completeness II & Reductions(视频)
NP Completeness III(视频)
NP Completeness IV(视频)
Skiena: CSE373 2020 - Lecture 23 - NP-Completeness(视频)
CSE373 2020 - Lecture 24 - Satisfiability(视频)
CSE373 2020 - Lecture 25 - More NP-Completeness(视频)
CSE373 2020 - Lecture 26 - NP-Completeness Challenge(视频)
Complexity: P, NP, NP-completeness, Reductions(视频)
Complexity: Approximation Algorithms(视频)
Complexity: Fixed-Parameter Algorithms(视频)
Peter Norvig 探讨旅行商问题的近优解:Jupyter Notebook
若你有 CLRS,请阅读第 1048 至 1140 页。
计算机如何处理程序 How CPU executes a program(视频)
How computers calculate - ALU(视频)
Registers and RAM(视频)
The Central Processing Unit (CPU)(视频)
Instructions and Programs(视频)
缓存 LRU cache: The Magic of LRU Cache (100 Days of Google Dev)(视频)
Implementing LRU(视频)
LeetCode - 146 LRU Cache (C++)(视频)
CPU cache: MIT 6.004 L15: The Memory Hierarchy(视频)
MIT 6.004 L16: Cache Issues(视频)
进程与线程 Computer Science 162 - Operating Systems(25 个视频):进程与线程相关内容见第 1-11 个视频
Operating Systems and System Programming(视频)
What Is The Difference Between A Process And A Thread?
涵盖内容:进程、线程、并发问题——进程与线程的区别
进程
线程
锁
互斥锁(Mutex)
信号量(Semaphore)
监视器(Monitor)
它们是如何工作的?
死锁
活锁
CPU 活动、中断、上下文切换
多核处理器的现代并发结构
分页、分段与虚拟内存(视频)
中断(视频)
进程所需资源(内存:代码段、静态存储、栈、堆,以及文件描述符、I/O)
线程所需资源(与同进程内其他线程共享上述资源(除栈之外),但每个线程有自己的 PC、栈计数器、寄存器和栈)
Fork 实际上是写时复制(只读),直到新进程向内存写入时才进行完整复制。
上下文切换:操作系统和底层硬件是如何发起上下文切换的?
C++ 中的线程(系列 - 10 个视频)
CS 377 Spring '14: Operating Systems from University of Massachusetts
Python 中的并发(视频):线程短系列
Python Threads
Understanding the Python GIL (2010) 参考资料
David Beazley - Python Concurrency From the Ground Up LIVE! - PyCon 2015
Keynote David Beazley - Topics of Interest (Python Asyncio)
Mutex in Python
测试 涵盖内容:单元测试的工作原理
什么是 mock 对象
什么是集成测试
什么是依赖注入
Agile Software Testing with James Bach(视频)
Open Lecture by James Bach on Software Testing(视频)
Steve Freeman - Test-Driven Development (that's not what we meant)(视频)slides
依赖注入:video
Tao Of Testing
如何编写测试
字符串搜索与处理 Sedgewick - Suffix Arrays(视频)
Sedgewick - Substring Search(视频)1. Introduction to Substring Search
-
- Brute-Force Substring Search
-
- Knuth-Morris Pratt
-
- Boyer-Moore
-
- Rabin-Karp
Search pattern in a text(视频)
如果你需要深入了解这一主题,请参阅部分主题的补充详情中的"String Matching"章节。
Tries 请注意 Tries 有多种类型。有些带前缀,有些不带,有些用字符串而非比特位来记录路径
我通读了代码,但不会亲自实现
Sedgewick - Tries(3 个视频)1. R Way Tries
-
- Ternary Search Tries
-
- Character Based Operations
Notes on Data Structures and Programming Techniques
短课视频:Introduction To Tries(视频)
Performance Of Tries(视频)
Implementing A Trie(视频)
The Trie: A Neglected Data Structure
TopCoder - Using Tries
Stanford Lecture(实际应用案例)(视频)
MIT, Advanced Data Structures, Strings(后半段内容可能相当晦涩)(视频)
浮点数 简单的 8 位表示:Representation of Floating Point Numbers - 1(视频——计算中有一处错误,请参见视频说明)
Unicode The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets
What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text
字节序(Endianness) Big And Little Endian
Big Endian Vs Little Endian(视频)
Big And Little Endian Inside/Out(视频)这是一场面向内核开发者的技术性很强的演讲,大部分内容听不懂也不用担心。
前半段足够了。
网络 如果你有网络相关工作经验,或者希望成为可靠性工程师或运维工程师,请预期会遇到相关问题
否则,了解这些内容也有好处
Khan Academy
UDP and TCP: Comparison of Transport Protocols(视频)
TCP/IP and the OSI Model Explained!(视频)
Packet Transmission across the Internet. Networking & TCP/IP tutorial.(视频)
HTTP(视频)
SSL and HTTPS(视频)
SSL/TLS(视频)
HTTP 2.0(视频)
系列视频(21 个视频)(视频)
Subnetting Demystified - Part 5 CIDR Notation(视频)
Sockets: Java - Sockets - Introduction(视频)
Socket Programming(视频)
最终复习
This section will have shorter videos that you can watch pretty quickly to review most of the important concepts. It's nice if you want a refresher often.
2-3 分钟短主题视频系列(23 个视频)Videos
2-5 分钟短主题视频系列 - Michael Sambol(48 个视频):Videos
Code Examples
Sedgewick Videos - Algorithms I
Sedgewick Videos - Algorithms II
更新你的简历
参见以下书籍中的简历准备信息:《Cracking The Coding Interview》和《Programming Interviews Exposed》
Gayle McDowell(《Cracking the Coding Interview》作者)的文章"This Is What A GOOD Resume Should Look Like"。作者注:「本文针对美国求职简历。印度及其他国家的 CV 有不同要求,但许多要点是相通的。」
Tech Interview Handbook 的「逐步简历指南」:详细介绍如何从零开始搭建简历、撰写有效的简历内容、优化简历并进行测试
面试流程与通用面试准备
How to Pass the Engineering Interview in 2021
Demystifying Tech Recruiting
如何进入四大科技公司:How to Get a Job at the Big 4 - Amazon, Facebook, Google & Microsoft(视频)
How to Get a Job at the Big 4.1(后续视频)
Cracking The Coding Interview Set 1: Gayle L McDowell - Cracking The Coding Interview(视频)
Cracking the Coding Interview with Author Gayle Laakmann McDowell(视频)
Cracking the Facebook Coding Interview: The Approach
Problem Walkthrough
备考课程:Python for Data Structures, Algorithms, and Interviews(付费课程):以 Python 为核心的面试备考课程,涵盖数据结构、算法、模拟面试等更多内容。
Intro to Data Structures and Algorithms using Python(Udacity 免费课程):免费的以 Python 为核心的数据结构与算法课程。
Data Structures and Algorithms Nanodegree!(Udacity 付费纳米学位):通过 100 余道数据结构与算法练习题积累实战经验,并有专属导师指导,帮助你为面试和实际工作场景做好准备。
Grokking the Behavioral Interview(Educative 免费课程):很多时候,阻碍你得到梦想工作的不是技术能力不足,而是行为面试表现不佳。
AlgoMonster(付费课程,含免费内容):LeetCode 速成课程,涵盖从数千道题目中提炼出的所有解题模式。
模拟面试:
Gainlo.co:来自大公司的模拟面试官——我用过这个平台,它帮助我在电话面试和现场面试时放松心态
Pramp:与同伴互相进行模拟面试——一种点对点的面试练习模式
interviewing.io:与资深工程师进行模拟面试——与来自 FAANG 的资深工程师进行匿名算法/系统设计面试
Meetapro:与顶级 FAANG 面试官进行模拟面试——一个类似 Airbnb 风格的模拟面试/辅导平台
Hello Interview:与专家教练和 AI 进行模拟面试——可直接与 AI 对练,也可与 FAANG 的 staff engineer 和经理面试
Codemia:借助 AI 或社区方案和反馈练习系统设计题——通过 AI 练习工具完成系统设计题,也可将你的方案分享给社区以获取人工反馈
面试前需要提前准备的内容
提前想好约 20 道你可能被问到的面试题,类型参考下方列举。每道题至少准备一个回答。不要只是罗列数据,要用故事的方式讲述你的成就。
你为什么想要这份工作?
你解决过的最棘手的问题是什么?
你曾面临过哪些最大的挑战?
你见过的最好/最差的设计是什么?
对现有产品的改进思路
你作为个人以及作为团队成员时,各自最佳的工作方式是什么?
你的哪些技能或经验能够成为这个职位的优势?为什么?
你在 [工作 x / 项目 y] 中最享受的是什么?
你在 [工作 x / 项目 y] 中面临的最大挑战是什么?
你在 [工作 x / 项目 y] 中遇到过的最难调试的 bug 是什么?
你在 [工作 x / 项目 y] 中学到了什么?
你在 [工作 x / 项目 y] 中有哪些地方可以做得更好?
准备向面试官提问
以下是我会问的一些问题(有些我可能已经知道答案,但想听听他们的看法或团队视角):
你们团队有多大?
你们的开发周期是怎样的?采用瀑布/Sprint/Agile 哪种方式?
赶截止日期的情况常见吗?还是有一定的灵活性?
你们团队如何做决策?
你每周有多少会议?
你觉得你们的工作环境有助于集中注意力吗?
你目前在做什么?
你喜欢它的哪些方面?
日常工作状态如何?
工作与生活的平衡情况怎么样?
拿到 Offer 之后
恭喜你!
持续学习。
学无止境。
***************************************************************************************************** ***************************************************************************************************** Everything below this point is optional. It is NOT needed for an entry-level interview. However, by studying these, you'll get greater exposure to more CS concepts and will be better prepared for any software engineering job. You'll be a much more well-rounded software engineer. ***************************************************************************************************** *****************************************************************************************************
延伸书目
These are here so you can dive into a topic you find interesting.
The Unix Programming Environment 经典老书,至今仍有价值
The Linux Command Line: A Complete Introduction 更现代的替代选择
TCP/IP Illustrated Series
Head First Design Patterns 设计模式的入门读物
Design Patterns: Elements of Reusable Object-Oriented Software 即"四人帮"(Gang Of Four)著作,简称 GOF
设计模式领域的权威经典
Algorithm Design Manual(Skiena 著) 适合用于复习和题型识别
算法目录部分的难度远超面试所需
本书分为两部分:数据结构与算法的教材部分——优点:与其他算法教材一样,是不错的复习资料
记录了作者在工业界和学术界解决问题的有趣经历
代码示例使用 C 语言
缺点:有时和 CLRS 一样晦涩难懂,某些章节 CLRS 或许是更好的替代
第 7、8、9 章读起来可能较为痛苦,部分内容讲解不够清晰,或者需要超出我能力范围的思维深度
我很喜欢 Skiena,喜欢他的教学风格和表达方式,只是我可能达不到 Stony Brook 的水准
算法目录:这才是你购买本书的真正理由
- 本书更适合作为算法参考手册,而非从头到尾通读的书籍
可在 Kindle 上租借
答案:Solutions
勘误表
Algorithm(Jeff Erickson 著)
Write Great Code: Volume 1: Understanding the Machine 本书出版于 2004 年,略显过时,但对于简短理解计算机工作原理来说是一本极好的资料
- 作者发明了 HLA,因此书中涉及 HLA 的提及和示例应持保留态度。HLA 并不广泛使用,但提供了一些还不错的汇编语言示例
- 以下章节值得一读,可为你打下良好基础:第 2 章 - 数值表示
- 第 3 章 - 二进制运算与位操作
- 第 4 章 - 浮点数表示
- 第 5 章 - 字符表示
- 第 6 章 - 内存组织与访问
- 第 7 章 - 复合数据类型与内存对象
- 第 9 章 - CPU 架构
- 第 10 章 - 指令集架构
- 第 11 章 - 内存架构与组织
Introduction to Algorithms 重要提示: 阅读本书的价值有限。它是复习算法与数据结构的好书,但无法教你如何写出优质代码。你必须能够高效地写出合理的解题代码
- 又称 CLR,有时称 CLRS(因为 Stein 是后来加入的)
Computer Architecture, Sixth Edition: A Quantitative Approach 内容更丰富、更新(2017 年),但篇幅更长
系统设计、可扩展性、数据处理
如果你有 4 年以上的工作经验,可以预期会被问到系统设计题。
可扩展性与系统设计是非常宽泛的话题,涵盖众多子议题和资源,因为设计一个可扩展的软硬件系统需要考虑大量因素。预计需要在这方面花费相当多的时间
注意事项:可扩展性——将大数据集提炼为单一值
- 将一个数据集转换为另一个数据集
- 处理海量数据
系统设计功能集
- 接口
- 类层次结构
- 在特定约束条件下设计系统
- 简洁性与健壮性
- 权衡取舍
- 性能分析与优化
从这里开始:The System Design Primer
HiredInTech 的系统设计课程
如何备战技术面试中的设计题?
系统设计面试 8 步攻略
数据库规范化 - 1NF、2NF、3NF 和 4NF(视频)
System Design Interview——此资源内容丰富,请浏览其中的文章和示例,我在下方列出了部分内容
如何在系统设计面试中脱颖而出
每个人都应该了解的关键数字
上下文切换需要多长时间?
跨数据中心的事务处理(视频)
CAP 定理的通俗英文介绍
MIT 6.824:分布式系统,2020 年春季(20 个视频)
共识算法:Paxos——Paxos 协议——Computerphile(视频)
Raft——Raft 分布式共识算法介绍(视频)易于阅读的论文
信息图
一致性哈希
NoSQL 模式
可扩展性:以下资源无需全部学习,挑选几个你感兴趣的即可
- 精彩概述(视频)
- 短系列视频:克隆
- 数据库
- 缓存
- 异步
可扩展的 Web 架构与分布式系统
分布式计算的谬误详解
Jeff Dean——在 Google 构建软件系统与经验教训(视频)
系统规模化架构入门
使用 App Engine 和 Cloud Datastore 将移动游戏扩展至全球受众(视频)
Google 如何为行星级基础设施进行行星级工程(视频)
算法的重要性
数据分片
长远游戏的工程之道——Astrid Atkinson 主题演讲(视频)
YouTube 七年可扩展性经验 30 分钟精华(视频)
PayPal 如何仅用 8 台虚拟机扩展至每日数十亿笔交易
如何在大型数据集中去重
Jon Cowie 讲述 Etsy 的规模与工程文化(视频)
是什么推动 Amazon 走向自身的微服务架构
压缩还是不压缩,这是 Uber 的问题
何时应使用近似查询处理?
Google 从单数据中心到故障转移,再到原生多宿主架构的演进
每天承载数百万次请求的图片优化技术
Patreon 架构简析
Tinder:全球最大推荐引擎之一如何决定你看到谁?
现代缓存的设计
Facebook 规模下的直播视频流
Amazon AWS 扩展至 1100 万+ 用户的初学者指南
Netflix 全栈架构 360 度全景
延迟无处不在,它正在蚕食你的销售额——如何彻底消灭它
Instagram 背后的技术:数百台实例,数十种技术
Salesforce 架构——他们如何处理每天 13 亿笔事务
ESPN 规模架构——每秒运行 100,000 次的系统
关于将各服务粘合在一起的技术,请参阅下方"消息传递、序列化与队列系统"章节
Twitter:O'Reilly MySQL CE 2011:Jeremy Cole,"@Twitter 的大数据与小数据"(视频)
时间线的规模化
更多内容,请参阅视频系列章节中的"挖掘海量数据集"视频系列
系统设计流程实战练习:以下是一些可以在纸上尝试推演的思路,每个案例都附有真实世界的处理方案文档:复习:The System Design Primer
HiredInTech 的系统设计课程
速查表
流程:理解问题与确定范围——在面试官的帮助下定义使用场景
建议补充功能
去除面试官认为超出范围的内容
假设需要高可用性,将其作为一个使用场景
思考约束条件:询问每月请求量
询问每秒请求量(面试官可能主动告知,或要求你自行估算)
估算读写比例
估算时牢记 80/20 法则
每秒写入数据量
5 年内所需的总存储量
每秒读取数据量
抽象设计:分层(服务层、数据层、缓存层)
基础设施:负载均衡、消息传递
驱动该服务的核心算法概述
识别瓶颈并确定解决方案
练习题:设计一个随机唯一 ID 生成系统
- 设计一个键值数据库
- 设计一个图片分享系统
- 设计一个推荐系统
- 设计一个短链接系统:参见上文
- 设计一个缓存系统
延伸学习
I added them to help you become a well-rounded software engineer and to be aware of certain technologies and algorithms, so you'll have a bigger toolbox.
编译器 编译器工作原理约 1 分钟讲解(视频)
Harvard CS50 - 编译器(视频)
C++(视频)
理解编译器优化(C++)(视频)
Emacs 与 vi(m) 熟悉一款基于 UNIX 的代码编辑器
vi(m):使用 Vim 编辑 01——安装、配置与模式(视频)
VIM Adventures
四集系列视频:vi/vim 编辑器——第 1 课
vi/vim 编辑器——第 2 课
vi/vim 编辑器——第 3 课
vi/vim 编辑器——第 4 课
用 Vi 替代 Emacs
emacs:基础 Emacs 教程(视频)
三集系列视频:Emacs 教程(初学者)- 第 1 部分——文件命令、剪切/复制/粘贴、光标命令
Emacs 教程(初学者)- 第 2 部分——缓冲区管理、搜索、M-x grep 与 rgrep 模式
Emacs 教程(初学者)- 第 3 部分——表达式、语句、~/.emacs 文件与插件包
Evil Mode:或,我如何学会放下焦虑、爱上 Emacs(视频)
用 Emacs 编写 C 程序
Emacs 绝对初学者指南(David Wilson 视频)
Emacs 绝对初学者指南(David Wilson 笔记)
Unix/Linux 命令行工具 以下列表内容来自优质工具推荐。
bash
cat
grep
sed
awk
curl 或 wget
sort
tr
uniq
strace
tcpdump
Essential Linux Commands Tutorial
DevOps DevOps 路线图
信息论(视频)Khan Academy
更多关于 Markov 过程的内容:核心 Markov 文本生成
核心 实现 Markov 文本生成
项目 = Markov 文本生成演练
详见下方 MIT 6.050J 信息与熵系列
奇偶校验与 Hamming 码(视频)简介
奇偶校验
Hamming 码:错误检测
纠错
错误校验
熵 另见下方视频
请务必先观看信息论视频
信息论、Claude Shannon、熵、冗余、数据压缩与比特(视频)
密码学 另见下方视频
请务必先观看信息论视频
Khan Academy 系列
密码学:哈希函数
密码学:加密
压缩 请务必先观看信息论视频
Computerphile(视频):压缩
压缩中的熵
倒置树(Huffman 树)
额外比特/三进制位 - Huffman 树
文本中的优雅压缩(LZ 77 方法)
文本压缩与概率
Compressor Head 视频
(可选)Google Developers Live:GZIP 还不够!
计算机安全 MIT(23 个视频)简介、威胁模型
控制流劫持攻击
缓冲区溢出攻击与防御
权限分离
能力机制
原生代码沙箱化
Web 安全模型
Web 应用安全加固
符号执行
网络安全
网络协议
旁路攻击
垃圾回收 Python 中的 GC(视频)
深入 Java:垃圾回收是好事!
深入 Python:CPython 中的垃圾回收(视频)
并行编程 Coursera(Scala)
高性能并行计算的高效 Python(视频)
消息传递、序列化与消息队列系统 Thrift 教程
Protocol Buffers 教程
gRPC Java 开发者的 gRPC 101(视频)
Redis 教程
Amazon SQS(队列)
Amazon SNS(发布-订阅)
RabbitMQ 入门
Celery Celery 初步
ZeroMQ 简介 - 阅读手册
ActiveMQ
Kafka
MessagePack
Avro
A* A* 搜索算法
A* 寻路(E01:算法讲解)(视频)
快速傅里叶变换 傅里叶变换互动指南
傅里叶变换是什么?有什么用?
什么是傅里叶变换?(视频)
分治法:FFT(视频)
理解 FFT
布隆过滤器 给定一个具有 m 位和 k 个哈希函数的 Bloom filter,插入和成员测试的时间复杂度均为 O(k)
布隆过滤器(视频)
布隆过滤器 | 斯坦福大学海量数据挖掘(视频)
教程
如何编写一个布隆过滤器应用
HyperLogLog 如何仅用 1.5KB 内存统计十亿个不同对象
局部敏感哈希 用于判断文档的相似性
与 MD5 或 SHA 相反,后者用于判断两份文档/字符串是否完全相同
Simhashing(希望如此)化繁为简
van Emde Boas 树 分治法:van Emde Boas 树(视频)
MIT 课程讲义
增强数据结构 CS 61B 第 39 讲:数据结构增强
平衡搜索树 至少掌握一种平衡二叉树的类型(并了解其实现方式):
"在平衡搜索树中,AVL 树和 2/3 树已经过时,红黑树似乎更为流行。一种特别有趣的自组织数据结构是伸展树,它通过旋转将任意访问的键移动到根节点。" — Skiena
在这些结构中,我选择实现伸展树。据我所读,面试中不会要求实现平衡搜索树。但我希望亲手编写一个,而且说实话,伸展树实在太妙了。我确实阅读了大量红黑树代码。伸展树:插入、搜索、删除函数。如果你最终实现红黑树,只需实现以下内容:
搜索和插入函数,跳过删除
我想更深入了解 B-Tree,因为它在超大数据集中应用极为广泛
自平衡二叉搜索树
AVL 树 实践中:据我所知,AVL 树在实践中用得不多,但我能想到它适用的场景:AVL 树是另一种支持 O(log n) 搜索、插入和删除的结构。它比红黑树平衡性更强,导致插入和删除较慢,但检索更快。这使它对于可以一次性构建、无需重建即可加载的数据结构颇具吸引力,例如语言字典(或程序字典,如汇编器或解释器的操作码)
MIT AVL 树 / AVL 排序(视频)
AVL 树(视频)
AVL 树实现(视频)
拆分与合并
【复习】AVL 树(播放列表)19 分钟速通(视频)
伸展树 实践中:伸展树通常用于缓存、内存分配器、路由器、垃圾回收器、数据压缩、绳索(用于长文本字符串的字符串替代结构)的实现,以及 Windows NT 中(虚拟内存、网络和文件系统代码)等
CS 61B:伸展树(视频)
MIT 讲座:伸展树:数学推导较多,但最后 10 分钟务必观看。
视频
红黑树 这是 2-3 树的一种变体(见下文)。
实践中:红黑树对插入时间、删除时间和搜索时间均提供最坏情况保证。这不仅使其在实时应用等时间敏感型应用中极具价值,也使其成为其他需要最坏情况保证的数据结构的重要构建模块;例如,计算几何中的许多数据结构可以基于红黑树构建,当前 Linux 内核中使用的完全公平调度器也采用了红黑树。在 Java 8 版本中,集合类 HashMap 经过修改,不再使用 LinkedList 存储哈希码相同的元素,而改用红黑树
Aduni - 算法 - 第 4 讲(链接直跳起始位置)(视频)
Aduni - 算法 - 第 5 讲(视频)
红黑树
二分搜索与红黑树简介
【复习】红黑树(播放列表)30 分钟速通(视频)
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 第 26 讲:平衡搜索树(视频)
自底向上的 2-3-4 树(视频)
自顶向下的 2-3-4 树(视频)
N 叉树(K 叉树、M 叉树) 注意:N 或 K 是分支因子(最大分支数)
二叉树是分支因子为 2 的 2 叉树
2-3 树是 3 叉树
K 叉树
B 树 趣闻:B 的含义至今成谜,可能代表 Boeing、Balanced 或联合发明人 Bayer。
实践中:B 树在数据库中被广泛使用。大多数现代文件系统采用 B 树(或其变体)。除数据库外,B 树还被文件系统用于实现对文件中任意块的快速随机访问。核心问题是将文件块地址转换为磁盘块(或磁道/磁头/扇区)地址
B 树
B 树数据结构
B 树简介(视频)
B 树的定义与插入(视频)
B 树的删除(视频)
MIT 6.851 - 内存层次模型(视频)— 涵盖缓存无关 B 树,非常有趣的数据结构——前 37 分钟较为深奥,可跳过(B 为块大小,即缓存行大小)
【复习】B 树(播放列表)26 分钟速通(视频)
k-D 树 非常适合在矩形或更高维对象中查找多个点
适合 k 近邻算法
kNN K-d 树算法(视频)
跳表 "这是一种颇具邪教色彩的数据结构" — Skiena
随机化:跳表(视频)
更多动画与详细说明
网络流 Ford-Fulkerson 5 分钟搞定——逐步示例(视频)
Ford-Fulkerson 算法(视频)
网络流(视频)
不相交集合与并查集 UCB 61B - 不相交集合;排序与选择(视频)
Sedgewick 算法 - 并查集(6 个视频)
快速计算的数学基础 整数运算、Karatsuba 乘法(视频)
中国剩余定理(用于密码学)(视频)
Treap 二叉搜索树与堆的结合体
Treap
数据结构:Treap 详解(视频)
集合运算中的应用
线性规划(视频)线性规划
求最小代价
求最大值
用 Python 求解线性方程组——单纯形算法
几何、凸包(视频)图算法 IV:几何算法简介——第 9 讲
几何算法:Graham & Jarvis——第 10 讲
分治法:凸包、中位数查找
离散数学 计算机科学 70,001——2015 年春季——离散数学与概率论
Shai Simonson 的离散数学(19 个视频)
IIT Ropar NPTEL 离散数学
部分主题的补充详解
I added these to reinforce some ideas already presented above, but didn't want to include them above because it's just too much. It's easy to overdo it on a subject. You want to get hired in this century, right?
SOLID Bob Martin 面向对象与敏捷设计的 SOLID 原则(视频)
S - 单一职责原则 | 每个对象承担单一职责 更多说明
O - 开放/封闭原则 | 生产级对象对扩展开放,对修改封闭 更多说明
L - 里氏替换原则 | 基类与派生类遵循"IS A"原则 更多说明
I - 接口隔离原则 | 不应强迫客户端实现其不使用的接口 接口隔离原则 5 分钟讲解(视频)
更多说明
D - 依赖倒置原则 | 降低对象组合中的依赖关系。为什么依赖倒置原则如此重要
更多说明
并查集 概述
朴素实现
树结构
按秩合并
路径压缩
分析选项
更多动态规划(视频)6.006:动态规划 I:Fibonacci、最短路径
6.006:动态规划 II:文本对齐、21 点
6.006:DP III:括号化、编辑距离、背包问题
6.006:DP IV:吉他指法、俄罗斯方块、超级马里奥兄弟
6.046:动态规划与高级 DP
6.046:动态规划:全源最短路径
6.046:动态规划(学生复习课)
高级图处理(视频)同步分布式算法:对称性破除、最短路径生成树
异步分布式算法:最短路径生成树
MIT 概率论(数学性强,宜放慢节奏,适合数学内容)(视频):MIT 6.042J - 概率论简介
MIT 6.042J - 条件概率
MIT 6.042J - 独立性
MIT 6.042J - 随机变量
MIT 6.042J - 期望 I
MIT 6.042J - 期望值 II
MIT 6.042J - 大偏差
MIT 6.042J - 随机游走
Simonson:近似算法(视频)
字符串匹配 Rabin-Karp(视频):Rabin Karps 算法
预计算
优化:实现与分析
表格倍增,Karp-Rabin
滚动哈希,摊销分析
Knuth-Morris-Pratt(KMP):Knuth-Morris-Pratt(KMP)字符串匹配算法
Boyer–Moore 字符串搜索算法 Boyer-Moore 字符串搜索算法
高级字符串搜索 Boyer-Moore-Horspool 算法(视频)
Coursera:Algorithms on Strings 开头讲得很好,但过了 KMP 部分之后就变得比实际需要更复杂了
对 tries 的清晰讲解
可跳过
排序 Stanford 排序讲座:Lecture 15 | Programming Abstractions(视频)
Lecture 16 | Programming Abstractions(视频)
Shai Simonson:Algorithms - Sorting - Lecture 2(视频)
Algorithms - Sorting II - Lecture 3(视频)
Steven Skiena 排序讲座:CSE373 2020 - Mergesort/Quicksort(视频)
CSE373 2020 - Linear Sorting(视频)
NAND To Tetris:从第一性原理构建现代计算机
视频系列
放松坐好,尽情享受。
动态规划问题列表(每道题都较短)
x86 架构、汇编与应用(11 个视频)
MIT 18.06 线性代数,2005 年春季(35 个视频)
极佳 - MIT 微积分回顾:单变量微积分
Skiena 基于《算法设计手册》的讲座 - CSE373 2020 - 算法分析(26 个视频)
UC Berkeley 61B(2014 年春季):数据结构(25 个视频)
UC Berkeley 61B(2006 年秋季):数据结构(39 个视频)
UC Berkeley 61C:机器结构(26 个视频)
OOSE:使用 UML 和 Java 进行软件开发(21 个视频)
MIT 6.004:计算结构(49 个视频)
Carnegie Mellon - 计算机体系结构讲座(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.824:分布式系统,2020 年春季(20 个视频)
MIT 6.851:高级数据结构(22 个视频)
MIT 6.854:高级算法,2016 年春季(24 个视频)
Harvard COMPSCI 224:高级算法(25 个视频)
MIT 6.858 计算机系统安全,2014 年秋季
Stanford:编程范式(27 个视频)
Christof Paar 密码学导论 课程网站及幻灯片与习题集
挖掘海量数据集 - Stanford University(94 个视频)
Sarada Herke 图论(67 个视频)
计算机科学课程
在线 CS 课程目录
CS 课程目录(许多附有在线讲座)
算法实现
- Princeton University 多种算法实现
论文
热爱经典论文?
1978:通信顺序进程,已在 Go 中实现
2003:Google 文件系统,已于 2012 年被 Colossus 取代
2004:MapReduce:大型集群上的简化数据处理,已大部分被 Cloud Dataflow 取代?
2006:Bigtable:面向结构化数据的分布式存储系统
2006:面向松耦合分布式系统的 Chubby 锁服务
2007:Dynamo:Amazon 的高可用键值存储,Dynamo 论文开启了 NoSQL 革命
2007:每位程序员都应了解的内存知识(篇幅很长,作者建议跳过部分章节)
2012:AddressSanitizer:一种快速地址健全性检查器:论文
视频
2013:Spanner:Google 的全球分布式数据库:论文
视频
2015:Google 的持续流水线
2015:大规模高可用性:构建 Google 广告数据基础设施
2015:开发者如何搜索代码:一项案例研究
更多论文:1,000 篇论文

219

被折叠的 条评论
为什么被折叠?



