主要介绍算法面试的一些问题、以及如何准备算法面试
算法面试不仅仅是正确的回答问题
对于面试中遇到的大多数问题,都能有一个合理的思考路径
什么是算法面试?
- 让大家在面对面试中的算法问题时,有一个合理的思考路径:
- 不代表能够“正确”回答每一个算法问题,但是合理的思考方向其实更重要,也是正确完成算法面试问题的前提
- 算法面试优秀不意味着技术面试优秀
- 技术面试优秀不意味着能够拿到Offer
什么是给出合理的思考路径?
- 算法面试的目的不是给出一个“正确”答案,
- 而是展示给面试官你思考问题的方式。
“正确”本身是一个相对概念
- 算法面试不是高考。
- 把这个过程看作是和面试官一起探讨一个问题的解决方案。
- 对于问题的细节和应用环境,可以和面试官沟通。
- 这种沟通本身很重要,它暗示着你思考问题的方式。
例子
我们需要对一组数据进行排序
- 设计排序接口,标准库的设计,业务中排序算法。
- 排序是基础操作,很重要。
解决
快速排序算法:O(nlogn)
- 忽略了算法使用的基础环境。要动态选择。
(向面试官提问):这组数据有什么样的特征?
- 有没有可能包含有大量重复的元素?
- 如果有这种可能的话,三路快排是更好地选择。
- 普通数据:普通快速排序就行了;java语言标准库排序使用的三路快排。
- 是否大部分数据距离它正确的位置很近?是否近乎有序?
- 如果是这样的话,插入排序是更好地选择。
- 按照业务发生顺序,先发生先完成,几乎有序,插入排序是更好的选择。
- 是否数据的取值范围非常有限?比如对学生成绩排序。
- 如果是这样的话,计数排序是更好地选择。高考成绩取值范围有限:计数排序更好。
(向面试官提问):对排序有什么额外的要求?
- 是否需要稳定排序?
- 如果是的话,归并排序是更好地选择。
(向面试官提问):数据的存储状况是怎样的?
- 是否是使用链表存储的?
- 如果是的话,归并排序是更好地选择。
- 快排依赖于数组的随机存取。
(向面试官提问):数据的存储状况是怎样的?
- 数据的大小是否可以装载在内存里?
- 数据量很大,或者内存很小,不足以装载在内存里,需要使用外排序算法。
对一组数据进行排序小结
- 有没有可能包含有大量重复的元素?
- 是否大部分数据距离它正确的位置很近?是否近乎有序?
- 是否数据的取值范围非常有限?比如对学生成绩排序。
- 是否需要稳定排序?
- 是否是使用链表存储的?
- 数据的大小是否可以装载在内存里?
什么是“正确”的回答一个算法问题
- 正确除了你能把代码编出来运行出正确的结果。正确还包含对问题的独到见解;优化;代码规范;容错性;
- 不仅仅是给出解决算法问题的代码,还要把上面因素包括。
- 如果是非常难的问题,对你的竞争对手来说,也是难的。
- 关键在于你所表达出的解决问题的思路。
- 甚至通过表达解题思路的方向,得出结论:这个问题的解决方案,应该在哪一个领域,我可以通过查阅或者进一步学习解决问题。
算法面试只是面试的一部分
- 算法面试只是技术面试的一部分。
- 根据你的简历和应聘职位的不同,势必要考察其他技术方面。
- 项目经历和项目中遇到的实际问题
- 解决能力,是否参与
- 深入思考
- 技术态度
面试前梳理自己简历上所写到的项目:整理一下可能会问到的。
- 你遇到的印象最深的bug是什么?
- 面向对象
- 设计模式
- 网络相关;安全相关;内存相关;并发相关;…
- 系统设计;scalability(大规模)
技术面试优秀不意味着能够拿到Offer
技术面试只是面试的一部分。面试不仅仅是考察你的技术水平,还是了解你的过去以及形成的思考行为方式。
- 关于过去:参与项目至关重要
项目经历:
- 工作人士
- 研究生
- 本科生
- 毕业设计
- 其他课程设计(大作业)
如何找到项目?
- 实习
- 创建自己的项目
- 自己做小应用:计划表;备忘录;播放器…
- 自己解决小问题:爬虫;数据分析;词频统计...
- “不是项目”的项目:一本优秀的技术书籍的代码整理等…(github)
- 分享:自己的技术博客;github等等
行为类问题
通过过去了解你的思考行为方式:
- 遇到的最大的挑战?
- 犯过的错误?
- 遭遇的失败?
- 最享受的工作内容?
- 遇到冲突的处理方式?
- 做的最与众不同的事儿?
具体阐述:我在某某项目中遇到一个怎样的算法问题:这个问题是怎样的。它是我遇到的最大的挑战,我是如何克服解决的。
准备好合适的问题问面试官
- 整个小组的大概运行模式是怎样的?
- 整个项目的后续规划是如何的?
- 这个产品中的某个问题是如何解决的?
- 为什么会选择某些技术?标准?
- 我对某个技术很感兴趣,在你的小组中我会有怎样的机会深入这种技术?
算法面试仍然是非常重要的一部分
如何准备算法面试
准备面试和准备算法面试 是两个概念
- 算法面试,只是面试中的一个环节。
- 远远不需要啃完一本《算法导论》
- 强调理论证明
- 第一遍读不需要弄懂证明
- 前几遍阅读应该记住结论就行了,不需要弄懂证明。把更多的精力放在算法思想上。
- 针对算法面试,算法导论里面的理论推导和证明不是很重要的方面。
学习切记完美主义
- 高级数据结构和算法面试提及的概率很低
- 基础的概念要知道,但是不需要实现等更深入的层面。
- 远远不需要到达信息学竞赛的水平
算法面试的准备范围
- 不要轻视基础算法和数据结构,而只关注“有意思”的题目
- 各种排序算法
- 基础数据结构和算法的实现:如堆、二叉树、图…
- 基础数据结构的使用:如链表、栈、队列、哈希表、图、Trie、并查集…
- 基础算法:深度优先、广度优先、二分查找、递归…
- 基本算法思想:递归、分治、回溯搜索、贪心、动态规划…
例子
Intel的面试题:
初始序列为1 8 6 2 5 4 7 3的一组数采用堆排序,当建堆(小根堆)完毕时,堆所对应的二叉树中序遍历序列为:( )
A. 8 3 2 5 1 6 4 7
B. 3 2 8 5 1 4 6 7
C. 3 8 2 5 1 6 7 4
D. 8 2 3 5 1 4 7 6
乐视的面试题:
对一个含有20个元素的有序数组做二分查找,数组起始下标为1,则查找A[2]的比较序列的下标为()
A. 9、5、4、2
B. 10、5、3、2
C. 9、6、2
D. 20、10、5、3、2
考查二分查找法。
阿里巴巴面试题
一组记录排序码为(5、11、7、2、3、17),则利用堆排序方法建立的初始堆为()
A. (11、5、7、2、3、17)
B. (11、5、7、2、17、3)
C. (17、11、7、2、3、5)
D. (17、11、7、5、3、2)
E. (17、7、11、3、5、2)
F. (17、7、11、3、2、5)
百度面试题
在图采用邻接表存储时,求最小生成树的Prim算法的时间复杂度为( )
- O(n)
- O(n e)
- O(n^2)
- O(n^3)
重点关注
- 基础数据结构的使用:如链表、栈、队列、哈希表、图、Trie、并查集…
- 基础算法:深度优先、广度优先、二分查找、递归…
- 基本算法思想:递归、分治、回溯搜索、贪心、动态规划…
选择合适的OJ(Online judge):在线判题系统
- 不要选择过于偏向程序设计竞赛的OJ *面向竞赛难度过高
- 选择合适的oj
- leetcode
- Online Portal for IT Interview
- 真实的面试问题
- www.leetcode.com
- HankeRank
注意
- 在学习和实践做题之间,要掌握平衡
- 基础算法实现与算法思想
如何回答算法面试问题
解决算法面试问题的整体思路
- 注意题目中的条件
- 给定一个有序数组...(二分法)
- 有一些题目中的条件本质是暗示
- 设计一个O(nlogn)的算法(分治:在一颗搜索树中完成任务,对于数据排序)
- 无需考虑额外的空间(用空间换时间上的优化)
- 数据规模大概是10000(O(n^2)就可以)
当没有思路的时候
- 自己给自己几个简单的测试用例,试验一下
- 不要忽视暴力解法。暴力解法通常是思考的起点。
例子
LeetCode 3 Longest Substring Without Repeating Characters
在一个字符串中寻找没有重复字母的最长子串 如”abcabcbb”,则结果为”abc” 如”bbbbb”,则结果为”b”
- 对于字符串s的子串s[i...j]
- 使用O(n^2)的算法遍历i,j,可以得到所有的子串s[i...j]
- 使用O(length(s[i...j]))的算法判断s[i...j]中是否含有重复字母
- 三重循环:复杂度O(n^3),对于n=100的数据,可行
优化算法
- 遍历常见的算法思路
- 遍历常见的数据结构
- 空间和时间的交换 (哈希表)
- 预处理信息(排序)
- 在瓶颈处寻找答案:O(nlogn) O(n^2) ; O(n^3)
- O(n^2)能否优化。
- 什么样的问题使用什么样的思路和数据结构。
实际编写问题
- 极端条件的判断
- 数组为空?
- 字符串为空?
- 数量为0?
- 指针为NULL?
- 代码规范:
- 变量名
- 模块化
- 复用性
如果你对 Dubbo / Netty 等等源码与原理感兴趣,欢迎加入我的知识星球一起交流。长按下方二维码噢:
目前在知识星球更新了《Dubbo 源码解析》目录如下: 01. 调试环境搭建 02. 项目结构一览 03. 配置 Configuration 04. 核心流程一览
05. 拓展机制 SPI
06. 线程池
07. 服务暴露 Export
08. 服务引用 Refer
09. 注册中心 Registry
10. 动态编译 Compile
11. 动态代理 Proxy
12. 服务调用 Invoke
13. 调用特性
14. 过滤器 Filter
15. NIO 服务器
16. P2P 服务器
17. HTTP 服务器
18. 序列化 Serialization
19. 集群容错 Cluster
20. 优雅停机
21. 日志适配
22. 状态检查
23. 监控中心 Monitor
24. 管理中心 Admin
25. 运维命令 QOS
26. 链路追踪 Tracing
... 一共 69 篇
目前在知识星球更新了《Netty 源码解析》目录如下: 01. 调试环境搭建 02. NIO 基础 03. Netty 简介 04. 启动 Bootstrap
05. 事件轮询 EventLoop
06. 通道管道 ChannelPipeline
07. 通道 Channel
08. 字节缓冲区 ByteBuf
09. 通道处理器 ChannelHandler
10. 编解码 Codec
11. 工具类 Util
... 一共 61 篇
目前在知识星球更新了《数据库实体设计》目录如下:
01. 商品模块 02. 交易模块 03. 营销模块 04. 公用模块
... 一共 17 篇
源码不易↓↓↓↓↓
点赞支持老艿艿↓↓