算法面试一直是程序员大厂面试中的必备环节,本人自从系统性的学习了数据结构与算法之后,对这一块内容已经积攒了大量的实践经验,同时也参加了不少面试,对如何准备算法面试也有了自己的理解。接下来,我将从学习思路、学习工具、训练方法、模拟实战这四个角度,去分享我的经验。

思路篇——博观而约取,厚积而薄发

时间复杂度,空间复杂度

时间复杂度是衡量算法执行效率的重要指标,空间复杂度是衡量算法消耗空间的重要指标。

根据算法种类的不同,时间复杂度可以达到常数级,线性级,指数级不等,能否使用最高效的算法,或者说最优的时间复杂度完成编程开发,是衡量软件工程师素质的重要指标。

数据结构

程序=数据结构+算法。作为软件工程师,需要对常见的数据结构了如指掌,它们包括:

一维数据结构:

  • 基础:数组 array (string), 链表 linked list

  • 高级:栈 stack,队列 queue, 双端队列 deque, 集合 set, 映射 map,

二维数据结构:

  • 基础:树 tree, 图 graph

  • 高级:二叉搜索树 binary search tree (red-black tree, AVL), 堆 heap, 并查集 disjoint set, 字典树 Trie

算法思想

除了各种数据结构,软件工程师还需要掌握各种常用的算法思想,它们包括:

  • 递归 Recursion (Divide & Conquer, Backtrace)

  • 搜索 Search: 深度优先搜索 Depth first search, 广度优先搜索 Breadth first search

  • 动态规划 Dynamic Programming

  • 二分查找 Binary Search

  • 贪心 Greedy

  • 数学 Math , 几何 Geometry

以上基本列举了算法面试的常考知识点,算法初学者可以先针对每个知识点具体学习,基础很重要,这些是灵活掌握算法的基础。

工具篇——工欲善其事,必先利其器

知识vs技能

前面一篇主要列举了算法面试中的常考点,但是只局限于知识的层面。想要真正把知识转化成技能,就需要不断的练习。至于如何高效练习,我推荐leetcode网站,leetcode-cn.com/

leetcode

该网站有大量的算法题,可以在线提交代码检查运行情况,还能参考各路大牛的题解。

通常来讲,在网站上做完300+道题目,就可以基本达到面试大厂的水准。

接下来,我将介绍如何利用该网站进行高效的刷题。

训练篇——积土而为山,积水而为海

刻意练习

刻意练习就是有针对性的反复训练,算法也一样。

leetcode网站提供了各种类型算法的标签分类,可以选择自己薄弱的地方针对性的练习。

另外,针对某一道特定的问题,在做完之后,也要学会去看题解,学习各种各样的解法,在这个过程中体会各种算法优劣的比较,并寻求最优的时间复杂度。

寻找反馈

对于算法初学者而言,刚接触算法是一个非常难熬的过程,你会感到非常的挫败,容易丧失学习的动力。

这时候,一靠自律,你必须努力使自己有攻克算法的强烈渴望,比如为了跳槽,为了更高的薪水等等。二是靠反馈,你可以加入一些刷题社群,跟小伙伴们一起学习,互相督促。另外leetcode网站上可以显示你的全站排名,以及刷题数目,也能给予你一定的正反馈。

温故知新

人的学习会有遗忘曲线,有的题目,即便是你当时看题解后会做了,隔了几天后也许又不会做了。

这很正常,不需要害怕,你要做到的就是过遍数,重新去温习一下这道题。通常来讲,一道算法题,做完五遍以上,才能算真正的掌握。

建立体系

学习的宗旨是为了掌握它,如何掌握浩如烟海的知识,就需要构建出属于自己的知识体系。把一个个点给连缀成一条线,清楚地认识到每一个知识点所在的位置,才能在做算法题时做到游刃有余。

实战篇——凡事预则立,不预则废

经过了前面几个步骤的练习,你已经掌握了各类数据结构和算法,对常考题的各种解法也了然于心,我想此时你一定对面试跃跃欲试了。

可是,面试时做题目跟平时自己联系题目是有区别的,在面试的场景下,很容易由于压力过大或者不习惯白板做题的方式而发挥失常。对于如何针对面试进行训练,我总结了以下几点:

练习白板编程

平时的开发大多是借助IDE(集成开发工具),但是真实的面试中,面试官极有可能就给你一张白纸去写代码。如果是线上面试的话,还可能会借助一些网页工具,实时的共享代码,例如codeshare.io/

所以,在平时训练算法题的过程中,要注重自己白板编程能力的培养,这对编程能力,以及代码风格的要求很高,需要多加练习。

自己想测试用例

在平时的练习里,你可以通过在leetcode上提交代码,很快地知道哪个用例没有通过,而在真实的面试中,面试官很少会给你提供测试用例,需要你自己去考虑各种边界情况。

所以,平时在leetcode上练习时不要急于提交代码,在心里先把各种异常场景想清楚,比如输入值校验,边界情况,大数据量带来的时间复杂度等等,这个过程也是在训练自己的思考能力。

模拟面试

你可以找你的朋友或同事帮助你进行一下模拟面试,在面试之前先给自己找到面试的感觉。

另外,leetcode提供的模拟面试的功能也很有用,我就特别喜欢用它来模拟真实面试场景,限时去完成题目。

总结

学习算法的过程比较枯燥,但它作为程序员的一项内功,是非常值得重视的。

篇幅限制,本文只是简单的概括了我在学习算法过程中的一些经验,很多地方没有展开,等到后面有空,再针对具体的案例进行升华。

如今,程序员行业的竞争已经越来越激烈,算法能力也越来越重要。如果你打算在行业内长期发展,这一块永远是不可或缺的技能,越早掌握,越是快人一步。