【慕课实战】玩转算法 第一章学习笔记,泛谈算法面试

-------------------------------------------------------------------------------------------------------------------------

算法只是技术的一部分,算法优秀不代表技术优秀
技术面试优秀,未必你能够拿到offer,

正确本身只是一个相对概念,
尤其是我们走入职场,更应该能够正确的认识这一点
我们解决问题,不是一场考试,
不是我们给出回答,有人告诉我们对或者不对。
算法面试,看做是和面试官一起探讨一个问题的解决方案
对于问题的细节和应用环境,可以和面试官沟通
沟通的过程中,不断提出自己对问题解决模型的假设
一步步深入问题中,沟通十分的重要,暗示着你思考问题的方式
有一些同学对算法面试认识得不够清楚,以为是一场考试。

我们需要对一组数据进行排序?
我个人认为这个是一个实实在在的真实问题。
所有的语言,都有对数据进行排序的接口,这些都是人为设计出来的。
我们究竟要如何设计这个接口呢。
我们解决实际的业务问题,经常要对数据进行排序的。
此时我们应该如何进行排序呢?
排序算法,其实是很多算法的先决条件,
这个是一个公认的基础操作,被研究得非常的透彻了。
好了,请问你要怎么做呢?
快速排序算法O(nlogn)
算法&数据结构实战课对其作出了详细的介绍了,可以去看看。
面对这个问题,显然是一个正确的回答,但是,这个回答未必让人满意。
你忽略了算法使用的具体环境,很多时候,其实是有诸多正确的选择的。
我们需要的不仅仅是正确,而是更优,
也有遇到这么一些情况,我们遇到的都不是最优的,我们需要取舍
选择让我们损失最小的方案,我们需要跟面试官进行沟通了,
这一步非常的重要,问一下面试官,这组数据是不是有什么特征。
1如果有着非常多的重复元素,三路快排是更好的选择。
很多语言的标组库中,快排就是是用三路快排的,比如Java排序背后就是用三路快排
2是否大部分数据距离它正确的距离很近?是否近乎有序?对于银行数据,可能是近乎有序的。
只有极少数的业务,先发生,事务时间长,会发生得晚一点,这时候插入排序是更好的选择。
3是否这组排序取值返回有限?比如对学生的成绩进行排序。高考0-750再见,计数排序更好的选择。
4对排序有什么额外的要求吗?是否需要稳定的排序方式,如果是需要稳定,快排不好,归并好。
5数据的存储状况是怎样的?快排非常依赖于数据的随机存取,如果是链表,快排不好,归并好。
6 数据的大小是否可以装在内存中,如果数据量大,内存很小,不足以装在载内存里,需要用外排序。
面试官希望你可以对这些问题都有深入的思考,各个方面都有思考,
我们不能局限于一个答案,我们需要给出更完善的答案,
毕竟有时候我们的答案,也会换一种场合下,就不适用了。

正确还包含对问题的独到理解,新的想法,优化【算法层面与语言级别】,
代码规范,容错性。等等等等.......
这个课程不仅仅给出解决算法问题的代码,而是要把这些因素囊括进来。

如果是非常难的问题,对你的竞争对手来说,也是难的。
所以不必沮丧,我们取得成功的关键,未必是解决完美的问题,
而仅仅是比你的竞争对手表现好一点而已。
关键在于你所表达出的解决问题的思路、
你的思考路径是如何的,虽然当下你可能无法给出一个正确的解,
但是你给出一个思考方向,力图逼近这个解,也是可以的。

算法面试优秀不意味着技术面试优秀
算法面试只是技术面试的一部分
根据你的简历和应聘职位的不同,面试官就要考察你的技术部分
项目经理和项目遇到的实际问题,你的解决能力是如何的。
可以看出你的过往的经历中,仅仅满足于完成功能,还是你有继续的思考,
你应该对你的项目经历,有提炼出要点,是很重要的。

你遇到的印象最深刻的bug是怎样的?
看似非常的简单,通过每个人的不同的回答,可以看出每个人的水平高下。
对于这一个问题,你应该根据你自己的经历,进行一个整理回顾。
在很多领域的问题,在技术环节可能都会遇到
面向对向,设计模式,网络相关,安全相关,内存相关,并发相关
系统设计,scalability,图形相关,
其实系统设计部分,也有常规的想法,借鉴。
有兴趣的同学,可以网上查查看,进行进一步学习。

我们也必须承认,很多时候,技术面试优秀不一定能够拿到Offer,
虽然对于技术面试而言,技术优秀,是有很大的优势。
技术面试只不过是面试的一部分,面试不仅仅是考察你的技术水平,
还是了解你的过去以及形成的思考行为方式。

技术面试问一些问题,只不过是从形式上考察你的能力而已。
只是一个简单的评估你的方式。
但是最好的评估你自己的一个方式是你过去做过的项目。

我想在这里简单的说一些项目的事情。
对于工作人士来说,项目不是问题,
对于研究生来说,项目经历也不是问题,在自己的实验室也会参加到项目中去
对于本科生来说,项目经理不一定是一定要参与到项目中去,其实毕业设计就是项目了,其实课程设计,也可以作为项目经历。本科生,可以应该给自己课设+毕设封装得好一点。可以增色不少。
对于非科班,如何找到项目呢?
1 实习方式,
有的同学都觉得找到实习非常的困难,那么可以参与实战课程学习,有很多教育机构,提供实战课程的学习,很多课程只要同学们跟下来,就可以是一个项目,慕课网,其实就有很多项目。
Coursera也提供很多这样的课程,现在在线教育非常的多,同学们可以找这些资源
2 同学们完全可以学习基础的知识,进而创建自己的项目,计划表,备忘录,播放器。
ios,android,开发一些小的项目。
自己解决一些小问题,爬虫系统,简单的爬网站数据
对一些网站进行数据分析,分析数据,写在自己的博客上
做一些词频统计
很多不是项目的项目也是很好的,一本优秀的技术书籍的代码整理等.......这其实是一个非常好的项目,完全可以写在自己的简历中。
分享自己的技术博客,github等等,都是可以的。
有的公司会认为,你不仅仅参加了学校,导师,实验室,实习给你的项目
你还有自己的项目,会给你很大的加分。
3 你遇到的最大的挑战是什么?
你犯过的错误?
你遭遇的失败?
最享受的失败?
遇到冲突的解决方式?
做到的最与众不同的事情是什么?
不要说你遇到的最大的挑战,就是笼统的说我遇到算法问题很难,不要这么笼统,
你可以举出一个具体的例子,某某项目中遇到某某算法问题,会更加的可信,你的经验更加的丰富。

同时你面试的时候,你准备好合适的问题问面试官。
还有很多东西,大家都可以和面试官来探讨。
在这里我抛砖引玉,
整个小组的大概运行模式是怎样的?
整个项目的后续规划是如何的?中长期的规划是如何的?
这个产品的某个问题是如何解决的?某个细节是如何解决的,我觉得可能碰到什么问题?
为什么选择某些技术?标准?
我对某个技术很感兴趣,在你的小组中我会有怎样的机会深入这种技术?
这些都是在我看来非常好的,可以问面试官的问题。

算法面试其实仍旧是重要的一个环节,从下面开始我们一起玩转算法面试。

---------------------------------------------------------------------------------------------------------------------------

准备面试, 和准备算法面试是两个概念
算法面试,知识面试中的一个环节。

算法面试并没有那么难,远远不需要啃完一本《算法导论》
《算法导论》虽然是一本经典,但是针对面试而言,其实有部分缺点
太过于侧重理论的推导和证明,其实面试官自己也并不能完全掌握理论的推导和证明。
随机化这一步,我们数学推导是很难的,计算数学的期望值,这一个推导快排的证明,
我们是完全不需要掌握这部分内容的,当然了大家如果有兴趣去读这本书的话,
第一遍读书,应该有选择的去阅读,第一遍,记住结论就可以了,
不然我们第一次很可能会产生巨大的挫败感,这就得不偿失了。
这本书其实也是有很多东西值得我们去学习的,其实这些理论知识是挺有用的,
同学们可以在对算法有了实践,有了感悟后,再回过来阅读理论证明,收获会更大。
我们不能追求一步到位,很多书,很多知识,我们都是要去理解很多遍,慢慢的熟练
直到内化到自己的心里面,学习切记不要有完美主义。
高级数据结构和算法面试提及的概率很低
包括 红黑树,B-Tree 计算几何, 数论,FFT,斐波那契堆
这些问题,在第一轮面试问题,是不需要过度准备的,基础的概念可以准备下
不然是不需要特意准备的,很少考到这些问题。
远远不需要达到信息学竞赛的水平。
远远不需要达到这种信息学竞赛的水平的。
如果你没有参加过acm竞赛,也是不用气馁,毕竟算法面试跟信息学竞赛还是有区别的。
不要轻视基础算法和数据结构,而只关注"有意思"的题目。
实际算法面试还是围绕基础的问题

1 各种排序算法
2 基础数据结构和算法的实现: 如堆,二叉树,图
3 基础数据结构的使用,链表,栈,队列,哈希表,图,Trie,并查集
4 基础算法,深度优先,广度优先,二分查找,递归,
5 基本算法思想: 递归,分治,回溯搜索,贪心,动态规划,
这些其实都是基础的,并没有太高级的内容。特别是1,2两点,都是特别基础的。

----------------------------------------------------------------------------------------------------------------------------

1 初始序列为1 8 6 2 5 4 7 3的一组数采用堆排序,当建堆小根堆完毕时候,堆对应的二叉树
中序遍历是怎样的呢。
2 对一个20个数目的二分查找,数组起始下标为1 A【2】的比较序号为多少?

---------------------------------------------------------------------------------------------------------------------------

这几个问题,大家可以感受到,都是非常基础的问题。
也是名企的面试问题,不要轻视基础的算法和数据结构。

---------------------------------------------------------------------------------------------------------------------------

选择合适的OJ,需要大量的练习和时间
Online Judge,在线判题系统
不要把学习算法面试的过程,只是停留在书本上,而是应该落实到练笔代码上。
codeforces,topcoder,codeechef,这些都是面向竞赛的,不太适合面试算法
Online Portal for IT Interview,如果你是会员的话,可以支付费用,看到这个问题是哪个公司面试问题,出现频率如何。
我们这个视频《玩转算法竞赛》也摘录很多问题,
http://www.leetcode.com 建议大家去注册一个属于自己的账号
HackerRank另一个网站,也是科技界寻找人才的一个网站
http://www.hackerrank.com 可以去注册账号,这里分类很详细,标题,子问题
HackerRank有些问题,会偏向于竞赛类问题,很多问题不是真实的面试问题这个应该作为辅助。
HackerRank做题,就像是在每一个细分的技能树上点技能点。

----------------------------------------------------------------------------------------------------------------------------

在学习和实践做题之间,一定要掌握一个平衡,
这个平衡点在哪里很难讲,每个人不一样,
我们一味的做题,效果不明显的,
我们一味的刷题,对背后的算法思想是掌握得不好的,
学习要补充一些思路,实践也是很重要。
有时候我们好像在oj上通过了很多问题,其实收获不大,
不要陷入体力劳动中,
没有任何一家公司会看你刷了多少题,看判断你的技术水平,
要重视质量而不是数量。

---------------------------------------------------------------------------------------------------------------------------

在最后,给大家讲讲算法面试问题的整体思路
先从一个整体的宏观角度给大家讲讲。
注意题目中的条件。
比如说,给定一个有序数组,注意这个有序关键字,二分查找
有一些题目中的条件,基本是暗示了,O(nlogn)logn 八成离不开分治法,搜索树上实现
无需考虑额外的空间,此时就是要开辟的空间,换取时间的优化
数据规模大概是10000,此时我们设计一个n^2 就可以了,

---------------------------------------------------------------------------------------------------------------------------

当没有思路 的时候,不要慌张,
1 自己给自己几个简单的测试用例,试验一下,摆弄几个测试用例,自然就有了一定的思路
2 不要忽视暴力解法,这个通常都是思考的起点,理论上所有的问题,都是存在暴力解法的,
如果你们没有思路的时候,不妨说出一些暴力解法,而千万不要说没有解法。

LeetCode3
在一个字符串中寻找没有重复字母的最长子串
abcabcbb 则结果为abc
bbbbbb 则结果为b 这个题目你们解决呢,可以思考一下
没有思路不妨使用暴力法,对于字符串s的所有子串s[i....j]
使用O(n^2 )算法遍历i,j 得到所有子串
O(length(S[i....j]))判断是否有重复的字母
这个算法复杂度O(n^3)
这个复杂度,不够优秀,万一你们处理的字符串,最长只有100的话,这也是一个可行的算法
退而求其次而已。说不定也可以。

最难的是优化算法,只提出一个暴力解法是非常容易的。
如果同学们基础素质比较好,
其实我们可以使用某种优化的方式。
1 遍历常见的算法思路
我们要给算法做出分类,索引指针,递归,贪心,动态规划,
2 遍历常见的数据结构进行辅助
栈,队列,堆,树,图
3 空间和时间的交换,常规的思路也可以思考,新空间记录数据,大大优化算法的时间复杂度
哈希表示最典型的。
4 预处理信息(排序)排序后很多问题进一步求解就非常简单了
5 在瓶颈处找答案 O(nlogn )+ O(N^2) ; O(N^3)

----------------------------------------------------------------------------------------------------------------------------

实际编写问题
对于编写,白板上编写,有的时候会在编辑器上编写
编写的时候,要注意极端条件的判断。
数组为空,字符串为空,数组为0,指针为NULL

变量名,最好是要有语义

模块化,复用性。都要注意,给面试官可能就有好的印象了。

很多时候,面试的问题,就是让你实现一个基本的最大堆,最小堆,快排,
希望大家花一些时间准备一下,做到可以白板编程的程度。

---------------------------------------------------------------------------------------------------------------------------

以后会介绍真正的算法了,
目前会使用C++开发。希望大家可以用你们熟悉的语言实现一下算法。

---------------------------------------------------------------------------------------------------------------------------

 

猜你喜欢

转载自www.cnblogs.com/Koaler/p/11986652.html