Skip to content

Latest commit

 

History

History
1914 lines (1599 loc) · 131 KB

File metadata and controls

1914 lines (1599 loc) · 131 KB

编程面试大学

原先我为了成为一个软件工程师而建立这份简单的学习主题清单, 但这份清单随着时间的推移而膨胀成今天这样。在做完这份清单上的每个目标后,我成为了 Amazon 的软件开发工程师! 你或许不需要像我一样学习这么多。但是,让你成为一位称职工程师所需要的知识都在这里了。

我每天自学8~12小时,这样持续了好几个月。这是我的故事:为什么我为了 Google 面试而自学了8个月

请注意: 你不需要像我一样那么努力学习。我在一些不必要的事情上浪费了很多时间。关于这个问题下面有更多信息。我会帮助你节省宝贵的时间,让你达到目标。 在这份清单内的主题会让你拥有足够的知识去面对几乎每家软件公司的技术面试,包括科技巨头:Amazon、Facebook、Google,以及 Microsoft。

祝你好运!

这是?

白板上编程 ———— 来自 HBO 频道的剧集,“硅谷”

这是我为成为一家大公司的软件工程师制定的多月学习计划。

要求:

  • 一点编程经验(变量、循环、方法/函数等)
  • 耐心
  • 时间

注意,这是一份关于 软件工程 的学习计划,而不是前端工程或全栈开发。 这些职业路径有很多详细的路线图和课程资料可以在其他地方找到(请参阅 https://roadmap.sh/ 获取更多信息)。

在大学计算机科学专业中,有很多知识需要学习,但是只掌握大约75%的内容就足够应对面试了,这也是我在这里涵盖的内容。 如果你想进行完整的自学计算机科学项目,可以参考Kamran Ahmed的计算机科学路线图:https://roadmap.sh/computer-science


目录

学习计划

学习的主题

获得工作机会

---------------- 以下所有内容均为可选项 ----------------

可选的额外主题和资源


为何要用到它?

如果你想在一家大公司担任软件工程师,这些是你必须了解的事情。

如果你错过了计算机科学的学位,就像我一样,这将帮助你迎头赶上,并节省四年的时间。

当我开始这个项目时,我对堆栈和堆没有任何了解, 也不知道大O表示法或者关于树的任何东西,也不知道如何遍历图形。 如果让我编写一个排序算法,相信我它会很糟糕。 我曾经使用过的每种数据结构都是内置在语言中的,并且我完全不知道它们在底层是如何工作的。 除非运行中的进程出现“内存不足”错误,否则我从来没有管理过内存,并且那时候就需要找到一种解决方法。 在我的生活中,我使用过一些多维数组和成千上万个关联数组,但从未从头开始创建数据结构。

这是一个漫长的计划,以至于花费了我数月的时间。若你早已熟悉大部分的知识,那么也许能节省大量的时间。

如何使用它

下面所有的东西都只是一个概述。因此,你需要由上而下逐一地去处理它。

在学习过程中,我使用 GitHub 特殊语法的 Markdown 去检查计划的进展,包括使用包含任务进度的任务列表。

如果你不想使用 Git

在该页面上,单击顶部附近的 Code 按钮,然后单击“Download ZIP”。解压文件,就可以使用文本文件了。

如果你打开一个代码编辑器,你会看到所有格式都很好。

How to download the repo as a zip file

如果你不介意 Git

创建一个新的分支,这样你就可以检查类似这样的项目了,只需在方括号中放入一个x:[x]

  1. 在 GitHub 上 Fork 该仓库: 点击 Fork 按钮,将 https://github.com/jwasham/coding-interview-university 仓库复制到你的 GitHub 账号中。

    Fork the GitHub repo

  2. 克隆项目到本地:

    git clone [email protected]:<your_github_username>/coding-interview-university.git
    cd coding-interview-university
    git remote add upstream https://github.com/jwasham/coding-interview-university
    git remote set-url --push upstream DISABLE  # 这样你就不会将个人进展推回到原始仓库了。
    
  3. 在你完成了一些修改后,在框框中打 x:

    git commit -am "Marked personal progress"
    git pull upstream main  # 将您的分支与原始仓库中的更改保持最新
      
    git push # just pushes to your fork
    

不要觉得自己不够聪明

相关视频资源

部分视频只能通过在 Coursera 或者 Edx 课程上注册登录才能观看。 这些视频被称为网络公开课程(MOOC)。有时候某些课程需要等待好几个月才能获取,这期间你无法观看这些课程的影片。

很感谢你能帮我把网络公开课程的视频链接转换成公开的,可持续访问的视频源, 比如 YouTube 视频,以代替那些在线课程的视频。 此外,一些大学的讲座视频也是我所青睐的。

选择编程语言

你需要为你做的编程面试选择一种编程语言, 但你也需要找到一种可以用来学习计算机科学概念的语言。

最好是同一种语言,这样你只需精通其中一种。

对于这个学习计划

在这个学习计划中,我主要使用了两种编程语言:C和Python。

  • C: 非常底层。它允许你处理指针和内存的分配与释放,因此你能够深入理解数据结构和算法。 在像Python或Java这样的高级语言中,这些细节被隐藏起来。在日常工作中,这是很好的, 但当你学习这些底层数据结构时,感受它们与计算机硬件的联系也是非常有益的。
    • C 语言无处不在。在你学习的过程中,你会在书籍、讲座、视频以及任何地方看到C语言的例子。
    • 《C程序设计语言(第2版)》
      • 这是一本简短的书,但它会让你很好地掌握C语言,只要稍微练习一下, 你很快就能熟练使用。理解C语言有助于你了解程序和内存是如何工作的。
      • 你不需要深入研究这本书(甚至不用读完它)。只要阅读到你感觉舒服,并能写一些C语言的代码就可以了。
      • 书中问题的答案
  • Python: 现代且非常灵活,我学习它是因为它非常实用,同时在面试中也能让我写更少的代码。

这是我的个人喜好,当然你可以根据自己的偏好来选择。

也许你并不需要,但以下是一些学习新编程语言的网站:

对于你的编程面试

你可以在编程这一环节,使用一种自己用起来较为舒适的语言去完成编程,但对于大公司,你只有三种固定的选择:

  • C++
  • Java
  • Python

你也可以使用下面两种编程语言,但可能会有某些限制,你需要事先查明:

  • JavaScript
  • Ruby

这是我写的一篇关于选择面试语言的文章: 为编程面试选择一种语言。 这是我发布帖子所基于的原始文章: Choosing a Programming Language for Interviews

你需要对你所选择的语言感到非常舒适且足够了解。

更多关于语言选择的阅读:

在此查看相关语言的资源

数据结构和算法的书籍

这本书将为你的计算机科学打下基础。

只需选择一种你感到舒适的语言。你将会进行大量阅读和编码工作。

C

Python

Java

你的选择:

C++

你的选择:

面试准备书籍

你不需要买一堆这些。老实说,《破解编程面试》可能已经足够了, 但我买了更多来给自己更多的练习。但我总是做得太多。

这两个都是我买的,他们给了我大量的练习。

如果你有很多额外的时间:

选择一个:

不要犯我的错误

这个列表在很多个月里不断增长,是的,它变得失控了。

以下是我犯过的一些错误,这样你就能有更好的体验。而且你将节省数月时间。

1. 你不可能把所有的东西都记住

我看了数小时的视频并做了大量笔记,几个月后有很多东西我都不记得了。 我花了三天时间浏览我的笔记并制作闪卡,以便进行复习。其实,并不需要那么多知识。

请阅读以下的文章以免重蹈覆辙:

记住计算机科学知识

2. 使用抽认卡

为了解决善忘的问题,我制作了一个抽认卡的网页,用于添加两种抽认卡:一般的及带有代码的。每种卡都会有不同的格式设计。 而且,我还以移动设备为先去设计这些网页,以使得在任何地方,我都能通过我的手机及平板去回顾知识。

你也可以免费制作属于你自己的抽认卡网站:

我不建议使用我的闪卡。它们太多了,而且大部分都是你不需要的琐事。

但是如果你不想听我的话,那就随你吧:

有一点需要记住的是,我做事有点过头,以至于卡片都覆盖到所有的东西上,从汇编语言和 Python 的细枝末节,到机器学习和统计都被覆盖到卡片上。 而这种做法,对于要求来说是多余的。

在抽认卡上做笔记: 若你第一次发现你知道问题的答案时,先不要急着把其标注成“已知”。 反复复习这张抽认卡,直到每次都能答对后才是真正学会了这个问题。 反复地问答可帮助你深刻记住该知识点。

这里有个替代我抽认卡的网站 Anki,很多人向我推荐过它。 这个网站用同一个字卡重复出现的方式让你牢牢地记住知识。 这个网站非常容易使用,支持多平台,并且有云端同步功能。在 iOS 平台上收费25美金,其他平台免费。

这是我用 Anki 这个网站里的格式所储存的抽认卡资料库: https://ankiweb.net/shared/info/25173560 (感谢 @xiewenya)。

一些学生提到了关于空白间距的格式问题,可以通过以下方法进行修复:打开卡片组,编辑卡片,点击"卡片"选项,选择"样式"单选按钮,在卡片类中添加成员 "white-space: pre;"。

3. 在学习过程中做编程面试题

这非常重要。

在学习数据结构和算法的同时,开始做编程面试题。

你需要将所学知识应用于解决问题,否则你会忘记。我曾经犯过这个错误。

一旦你学完一个主题,并且对它有了一定的掌握,比如 链表(linked lists):

  1. 打开其中一本编程面试书籍(或下方列出的编程问题网站之一)。
  2. 请先做2或3个关于链表的问题。
  3. 继续学习下一个主题。
  4. 稍后,回来再做另外2或3个链表问题。
  5. 使用这种方法来学习每个新主题。

在学习这些内容的过程中不断做问题,而不是之后。

你被雇佣的不是因为你的知识,而是因为你知道如何应用这些知识。

下面列出了许多资源供你参考。继续前进吧。

4. 专注

在学习的过程中,往往会有许多令人分心的事占据着我们宝贵的时间。 因此,专注和集中注意力是非常困难的。放点纯音乐能帮上一些忙。

没有包含的内容

有一些熟悉且普遍的技术在此未被谈及到:

  • Javascript
  • HTML,CSS和其他前端技术
  • SQL

日常计划

这门课涵盖了很多主题。每个主题可能需要你几天的时间,甚至可能需要一周或更长时间。这取决于你的日程安排。

每天,按照列表中的下一个主题,观看一些关于该主题的视频, 然后用你选择的语言为这门课程编写该数据结构或算法的实现。

在这里你可以查看到我的代码:

你不需要记住每个算法。你只需要能够理解它,以便能够编写自己的实现即可。

编程问题练习

这是为什么?我还没有准备好面试。

那就回去阅读这部分。

为什么你需要练习编程问题:

  • 识别问题,并确定合适的数据结构和算法
  • 收集问题的要求
  • 像在面试中那样口头表达解决问题的过程
  • 在白板或纸上编写代码,而不是在计算机上
  • 为您的解决方案确定时间和空间复杂度(参见下文中的大O表示法)。
  • 对你的解决方案进行测试

在面试中,有一种方法论的、有交流的问题解决方法。你可以从编程面试书籍中了解这些, 但我发现下面这个网站也非常出色: 算法设计画布

在白板或纸上写代码,而不是在计算机上。使用一些样例输入进行测试。然后在计算机上键入并进行测试。

如果家里没有白板,请从艺术用品店购买一个大型的绘图本。 你可以坐在沙发上练习。这就是我的"沙发白板"。照片中我加了一支笔来衡量尺寸。如果你使用钢笔,你会希望能擦除。 会很快变得凌乱, 我用铅笔和橡皮擦。

my sofa whiteboard

编程问题练习并不是为了记住解决编程问题的答案。

编程问题

别忘了参考你的主要编程面试书籍这里.

解决问题:

编程面试问题视频:

挑战/练习网站:

  • LeetCode
    • 我最喜欢的编程问题网站。对于你准备的1-2个月时间,订阅会费是值得的。
    • 观看上面提到的Nick White和FisherCoder的视频,可以帮助你理解代码解决方案。
  • HackerRank
  • TopCoder
  • Codeforces
  • Codility
  • Geeks for Geeks
  • AlgoExpert
    • 由谷歌工程师创建,也是提高你技能的优秀资源。
  • Project Euler
    • 主要关注数学问题,并不完全适合编程面试。

让我们开始吧

好了,说得够多了,让我们学习吧!

但在学习的同时,不要忘记做上面的编码问题!

算法复杂度 / Big-O / 渐进分析法

好吧,差不多就到这里了。

当你阅读《破解编程面试》时,有一个章节专门讲述此事,并在最后进行了一次测验, 以测试你是否能够确定不同算法的运行时间复杂度。这是一个非常全面的复习和测试。

数据结构

更多的知识

树(Trees)

排序(Sorting)

总结一下,这是15种排序算法的可视化表示。 如果你需要有关此主题的更多详细信息,请参阅“一些主题的额外内容”中的“排序”部分。

图(Graphs)

图表可以用来表示计算机科学中的许多问题,所以这一部分很长,就像树和排序一样。

更多知识

如果你需要有关此主题的更多详细信息,请参阅“一些主题的额外内容”中的“字符串匹配”部分。


最终复习

本节将包含一系列短视频,您可以迅速观看,以便复习大部分重要概念。
如果您经常需要温习知识,这会很有帮助。

更新你的简历

面试流程与一般面试准备

模拟面试:

当面试来临的时候

随着下面列举的问题思考下你可能会遇到的 20 个面试问题,每个问题准备 2-3 种回答。 准备点故事,不要只是摆一些你完成的事情的数据,相信我,人人都喜欢听故事。

  • 你为什么想得到这份工作?
  • 你解决过的最有难度的问题是什么?
  • 面对过的最大挑战是什么?
  • 见过的最好或者最坏的设计是怎么样的?
  • 对某个产品提出改进建议。
  • 你作为一个个体同时也是团队的一员,如何达到最好的工作状态?
  • 你的什么技能或者经验是你的角色中不可或缺的,为什么?
  • 你在某份工作或某个项目中最享受的是什么?
  • 你在某份工作或某个项目中面临过的最大挑战是什么?
  • 你在某份工作或某个项目中遇到过的最硬的 Bug 是什么样的?
  • 你在某份工作或某个项目中学到了什么?
  • 你在某份工作或某个项目中哪些地方还可以做的更好?

问面试官的问题

我会问的一些:(可能我已经知道了答案但我想听听面试官的看法或者了解团队的前景):

  • 团队多大规模?
  • 开发周期是怎样的? 会使用瀑布流/极限编程/敏捷开发么?
  • 经常会为截止日期(deadlines)加班么? 或者是有弹性的?
  • 团队里怎么做技术选型?
  • 每周平均开多少次会?
  • 你觉得工作环境有助于员工集中精力吗?
  • 目前正在做什么工作?
  • 喜欢这些事情吗?
  • 工作期限是怎么样的?
  • 工作生活怎么平衡?

当你获得了梦想的职位

恭喜你!

继续学习。

活到老,学到老。


*****************************************************************************************************
*****************************************************************************************************

下面的内容都是可选的。
通过学习这些内容,你将会得到更多的有关 CS 的概念,并将为所有的软件工程工作做更好的准备。
你将会成为一个更全面的软件工程师。

*****************************************************************************************************
*****************************************************************************************************

额外书籍

你可以从以下的书单挑选你有兴趣的主题来研读。
  • UNIX环境高级编程
    • 老,但却很棒
  • Linux 命令行大全
    • 现代选择
  • TCP-IP详解系列
  • Head First 设计模式
    • 设计模式入门介绍
  • 设计模式:可复用面向对象软件的基础
    • 也被称为“四人帮”(Gang of Four(GOF))
    • 经典设计模式书籍
  • 算法设计手冊(Skiena)
    • 作为复习以及问题辨别
    • 这本书中算法的部分难度已经超过面试会出现的
    • 本书分为两个部分:
      • 数据结构和算法课本
        • 优点:
          • 跟其他算法课本一样是个很棒的复习素材
          • 包含作者以往解决工业及学术上问题的经验的故事
          • 含C语言代码示例
        • 缺点:
          • 某些地方跟《算法导论》(CLRS)一样艰深,但在某些主题,算法导论或许是更好的选择。
          • 第7、8、9章有点难以消化,因为某些地方并没有解释得很清楚,或者根本上我就是个学渣
          • 别会错意了,我很喜欢 Skiena 的教学方法以及他的风格。
      • 算法目录:
        • 这个部分是买这本书的最大原因
        • 我即将着手进行这部分,一旦完成这部分我会再更新上来
    • 可以在 kindle 上租
    • 解答:
    • 勘误表
  • 算法 (Jeff Erickson)
  • 编程卓越之道(第一卷):深入理解计算机
    • 该书于2004年出版,虽然有些过时,但是对于简单了解计算机而言,这是一个了不起的资源
    • 作者发明了高阶组合语言 HLA,所以提到,并且举了一些HLA的例子。里面没有用到很多,但都是很棒的组合语言的例子。
    • 这些章节值得阅读,为你提供良好的基础:
      • 第2章──数字表示
      • 第3章──二进制算术和位运算
      • 第4章──浮点表示
      • 第5章──字符表示
      • 第6章──内存组织和访问
      • 第7章──组合数据类型和内存对象
      • 第9章──CPU体系结构
      • 第10章──指令集架构
      • 第11章──内存体系结构和组织
  • 算法导论
    • 重要提示:读这本书的价值有限。本书很好地回顾了算法和数据结构,但不会教你如何编写良好的代码。你必须能够有效地编写一个不错的解决方案
    • 又称 CLR,有时是 CLRS,因为 Stein 最后才加入
  • 计算机体系结构,第六版:定量方法
    • 对于更丰富、更时新(2017年)但较长的处理方式

系统设计、可扩展性和数据处理

如果您有4年以上的工作经验,可以预期会遇到系统设计问题。

附加学习

我把它们加进来是为了让你成为更全方位的软件工程师,并且留意一些技术以及算法,让你拥有更大的工具箱。

一些主题的额外内容

我添加了这些内容来加强上面已经提出的一些观点,但是不想把它们放在上面,因为那样会太多。
对于一个主题来说,过度处理很容易。
你希望在本世纪被雇佣吗?

视频系列

坐下来,尽情享受。

计算机科学课程

算法实现

论文

LICENSE

CC-BY-SA-4.0