找回密码
 立即注册
楼主: RecursiveFrog

为什么最难不过二叉树的算法出现在面试题中都会被应聘者抱怨?

[复制链接]
发表于 2021-7-4 06:46 | 显示全部楼层
算法:用的/考的?

大多数人抱怨面试算法的原因都很简单:用不上。众所周知算法是比较底层的知识。如果你不是一个算法工程师,架构师或研究学者,仅仅是一名前后端工程师,一个程序开发者,那么你的日常工作就是利用已有的工具和架构。底层调用能明白更好,不懂也足以胜任工作。而公司出于筛选的目的,考察应聘者的基础算法。众多掌握了技术而不想深究底层的应聘者自然抱怨:“你招的就是个装卸工,怎么还考起造航母来了?”。
不怪它们抱怨,比起应用,算法题更像是为了考试而考试。它考察了应聘者转化问题,解决问题的能力,考验他们的基础和认真程度,唯独和实际的工作关系不大。而这些面试题目是可以通过反复刷题,练习来掌握的。很多应聘者不愿意付出时间和精力,觉得做这些有范围、规制性的题目不够能展现自己的特点,就一边不尽力准备面试,一边抱怨算法题的不必要性。
那么面试究竟考察哪些呢?主要是以下这些:
算法部分
二分搜索 Binary Search
分治 Divide Conquer
宽度优先搜索 Breadth First Search
深度优先搜索 Depth First Search
回溯法 Backtracking
双指针 Two Pointers
动态规划 Dynamic Programming
扫描线 Scan-line algorithm
快排 Quick Sort
数据结构部分
栈 Stack
队列 Queue
链表 Linked List
数组 Array
哈希表 Hash Table
二叉树 Binary Tree  
堆 Heap
并查集 Union Find
字典树 Trie 公司:考察/培养?

确实“面试造航母,工作装卸工”的情况已经成为了行业招聘规则之一。国内BAT,国外Google,Facebook等等大公司面试哪个不考算法题?只不过大众认为大公司们待遇好,招聘的时候要求高也属正常。小公司效仿它们则会被吐槽:就你还学人家,谈谈项目、说说能力经验不更好吗?
首先,站在公司角度思考:公司应该考察什么呢?无非是项目经验(说说你参与过的项目和你的贡献),技术细节(某个具体的调用),行为面试(说说你选择我们公司的原因)。可以看出,算法只是面试众多挑战中的一环而已,如果你其他方面的水平足够过关,算法绝不会成为你拿到offer的绊脚石;反之,如果你的经验不够丰富,技术马马虎虎,如果不再展示一些好基础,岂不是雪上加霜、毫无希望了?
另一方面公司的目的在于方便筛选出值得培养的人才。无论大小公司,都希望应聘者可以招之即用、且有一定上升空间。算法题考的简单、基础,被大多数人诟病无用,却能在实际工作中能帮助你更好地理解问题,规避错误。对个人的帮助是潜移默化的。你的抱怨既是出自本能,也是没能体会到算法好处的结果。或许这样的筛选法显得笼统又粗糙,但对公司来讲无疑是最高效节省的方法。
你想造航母吗?或是做一辈子的装卸工

抱怨本身带着失败者和悲剧的气息。你当然可以自嘲过过嘴瘾,但不该一笑而过。要思考:是做一辈子的轮子使用者,还是为了有朝一日成为造轮子的行家而奋斗?每个人的目标不同,不能强求。每个人的境遇不同,无法一言蔽之。唯一可以确定的是,如果你想在技术上走的更远就躲不开算法这一关。
彼之砒霜,吾之蜜糖。如果你真的热爱技术,钟爱coding,那算法就该是你的蜜糖。如果你仅仅把代码当做一份工作,一种技术,一个人生中的阶段,也未尝不可。你该理性地分析现阶段需要什么,时刻为自己充能。如果现阶段仍然无法避免面试,无法避免算法题,就把它作为应试的一部分去学习掌握。起码你不会因此吃亏。
最后,抱怨并不能解决问题,还不如多刷几道题、多做几个项目,让面试充满底气!


推荐阅读
干货!史上最强位运算面试题大总结!
线段树知识点总结
【干货】动态规划十问十答
还在断点调试?教你四种调试技巧让你快速定位错误!


欢迎关注我的微信公众号:九章算法(ninechapter),帮助你了解IT技术前沿,通过面试、拿到offer、找到好工作!
发表于 2021-7-4 06:47 | 显示全部楼层
我说说我的理解,很多时候其实是记不清算法的细枝末节,工作中用到了自然可以查资料查文档,甚至本来就不用知道那些细枝末节,能知道大体怎么用性能如何瓶颈在何处如果要改进可以从什么方面入手就行了。
但面试的时候不一样,面试官一个劲追问细节,甚至要提笔现场实现一个详细版本要考虑各种边界情况什么的(我了个去没有文档没有IDE我连String类有没有内置subString这种函数都不记得)难免让人心里没底。
举个例子我以前实习的时候遇到过一个问题,可以归结为资源分配,用一个图模型去建模,最后化成一个线性规划模型。我觉得如果要面试,问到这里就差不多了。最多问问迭代求解和直接求解的区别和各自的优点,算法复杂度什么的,理论性强一点还可以问问原对偶问题……至于把梯度下降或者矩阵求逆都要现场写一遍,那就没必要了。
当然了,面算法岗位和面开发岗位侧重点也不同,还是要结合具体岗位说的。如果是前面有人提到的PHP工程师或者网页前端,我觉得在实际工作中用到什么高深算法的机会应该很少了,面试时候多问问实际的细枝末节才是更能看出水平的。
发表于 2021-7-4 06:54 | 显示全部楼层
这个问题很有意思,其实应该要分开来看。
个人感觉国内目前的面试套路分为三种,第一种是外企风格,那不用说,基本上以算法题和系统设计题为主,非常硬核,但是很有效,谁聪明谁笨,谁基础扎实谁底层稀疏,谁不懂装懂一问就出来了。
第二种是以候选人简历和经历为主,也就是俗称的简历流。看你简历里写什么问什么,这种在校招当中是最多的,社招当中其实也不少见,尤其是比较对口的面试,比如算法领域对口或者是业务领域对口之类的,那基本上或多或少都会问,除了可以考察能力之外,还能借鉴一下思路。
第三种是当下流,什么意思呢,就是面试官当下手头在做什么,就问什么。这种我最鄙视,我感觉也是最没有技术含量的,对候选人比较不公平。如果不是特别对口很有可能发挥不出应有的实力,或者会得到不太公正的待遇。但是好处是招来的上手就能干活,算是非常利己,但是不是特别友好的面试风格。
这三种风格里,无论是面试别人还是应聘,我都最喜欢第一种,第二种其次,第三种最后。因为第一种最能体现基础和候选人自己的实力和一定的诚意,也是相对非常公平的。因为面试风格往往是可以事先了解的,也就意味着候选人是可以事先准备的。既然知道了对方公司是外企的面试风格,那么一些基本的算法题是肯定要问的。
不平衡的二叉树真的是非常非常基础了,基本上可以说是复习过数据结构就应该会的东西。你可以说红黑树,AVL,splay这些平衡二叉树比较冷门,不是竞赛选手可能不一定知道,或者说不是特别清楚,我觉得是可以理解的。如果是不带平衡的二叉树,我个人觉得一个合格的专业的程序员,这是必须知道的。如果答不出来除了自身基础差之外,还说明了完全没有准备,这真不能怪面试官刁难了。
而且面一些基础算法真的很公平,这些算法都是公开的,谁都可以学,并不是什么机密。就和高考为什么考基础学科,不考奥数、音乐一样。这些内容人人都有机会,门槛很低。如果基本算法应付不来,后面两种只会更糟糕。问你简历,如果你不是特别对口(业务完全吻合),也没有大厂经验,你觉得问简历就能说得出亮点吗?如果你之前没有做过面试官当下从事的工作,对他的技术栈也并不完全熟悉,你觉得你一定能通过么?
相反面试当中的算法题如果能应付漂亮,说明候选人基础扎实,人也不笨。即使技术栈不吻合,培养起来并不太难。如果招聘到的是一个技术不扎实但是经验丰富的,对团队的贡献很有可能是负值。不然那些代码风格奇差、性能优化完全没有的代码你以为是谁写出来的,不就是这帮人贡献的么。
在面试这个问题当中,弱者才会抱怨,强者只管收割offer。
发表于 2021-7-4 07:03 | 显示全部楼层
就说二叉树。我大二学数据结构,大作业的一部分是自己实现一个平衡二叉树,没有任何问题。要是那个时候别人来问我各种细节,毫无压力。

然后我现在研二,自那次大作业以后再也没有实现过平衡二叉树。需要使用各种索引的时候都是无论是自己实现还是直接调用库,都不是平衡二叉树。然后现在要是来问我关于平衡二叉树的各种细节,当然我还记得左旋右旋左右旋右左旋,但你要我把所有的指针赋值都准确回答出来,我一定办不到。包括其他很多经典算法,思想我都有印象,细节我只能抱歉。

这类知识性的东西不经过长时间多次反复是不会形成长期记忆的。所以才会有临时查的情况产生。而且就算形成了长期记忆,这跟骑自行车这种技能还不一样。只要时间够长,总会忘掉的。

我觉得面试者反对的不是问算法,而是单纯地考察这些跟他工作无关的知识。换句话说你就算不问算法,而是问一个写前端的Sql查询怎么优化或者问一个挖数据的怎么做编译器,人家一样会受不了。因为他需要花时间去特地准备。而这准备又跟他的工作无关(面试之前的工作)。

如果面试官问的算法与面试者的工作相关,他却答不上来,确实可以判断他之前的工作有问题,进而他的能力也许有问题。如果无关,这就成了单纯的应试。我们都知道应试教育在人们心目中是什么样的存在。讨厌什么的就可以理解了吧。

现阶段,面试者也许认为算法是基础,人人都该懂,所以才问算法。万一过两年,面试者认为体系结构是基础,人人都该懂,这个题目就会改成问体系结构的了。那么计算机科学或者工作所需的编程实践里到底什么是基础?什么人人都该懂?我也不知道,反正我不觉得算法是。

当然,面试也和应试教育一样。问的问题也许并不好,但是足够公平就行。现阶段也没有别的更好的问题可以问。毕竟不能指望面试官先了解应试者的背景再有针对性地提问。再加上现在大家争着找工作的市场情况。所以作为应试者,还是安心准备为上。再说,不管有用没用,知识多了总没有坏处。

注:本答案只表达了对面试问算法的部分反对,并未提出任何面试提问的建议方案。
发表于 2021-7-4 07:05 | 显示全部楼层
假设一家公司某个软件岗位需要招人,你如果作为面试官,肯定是希望找一个有相关背景的人。
比如招聘一个搜索引擎类的人才,面试的时候,肯定要问相关搜索算法如何实现,各个算法之间有何优劣,甚至让你出示一下你在相关领域的论文等等。你说会让你当时写一段二叉树排序么?
又比如招聘一个无线通信的基带信号处理软件工程师,面试问题肯定是64QAM信号如何解调,IRC算法什么情况会比MRC算法灵敏度高2dB,信道编解码中卷积如何处理,各种调制方式使用哪些算法等等。你说会当场让你写一个矩阵求逆的代码么?

面试时考算法,只有三种情况:第一种是工作密切相关,这种情况下,问的算法可就不是快速排序、二分查找这种本科生的东西了。
第二种情况,就是你的技术背景不匹配岗位要求。什么样的候选人不匹配岗位要求还会得到面试机会?本科应届生(硕士以上基本会在本行业中有所建树)。

对应届生面试,真的想不出什么好的面试题来考察能力。应届生完全是一张白纸,你问他相关行业知识,这不是难为他么?而算法是基础,是基本功,是应届生能力和岗位需求唯一能匹配的地方。

还有一种情况,就是这个岗位太新了,市场上没有几个业内人士。那想招个合适的人,只有面试算法了。比如google就经常面试算法(而且还特难)。

回到题主的问题,工作中的算法是相当艰深的,每个算法背后都是一堆paper。面试问本科应届生肯定是问一些很简单的算法了。为何还让候选人很生气,我觉得主要还是因为很多面试官面试社招生也面试算法了。

对于我自己,我作为面试官,如果是找个新手来培养,面试个排序啊的算法还是很有用的;如果找个有相关背景的,问的问题都是围绕岗位要求而展开的。每个行业的圈子都不大,就那么些人,大家都发过paper,身上多少都有几个专利,兜两圈都能攀上关系,你说面试的时候出个快速排序,无论出题的还是做题的,老脸都没处放。
发表于 2021-7-4 07:06 | 显示全部楼层
“工作中用不到这么多算法”就是个错觉。
有个算法能漂亮地解决一个问题,我不知道,然后自己倒腾了一个弱弱的方法。嘿,你猜怎么着?能跑!于是我告诉自己,这工作果然用不上什么高深的算法。

直到有一天,冒出个竞争对手的产品比我快1000倍。
发表于 2021-7-4 07:12 | 显示全部楼层
这就好比很多人抱怨高考数学难一样,认为学了一堆以后完全用不上的东西去应试。
而大厂恰如各大名校,正是想淘汰掉这批人。
发表于 2021-7-4 07:18 | 显示全部楼层
关于这点,本墙头草有话说,鄙人不才就是凭着刷题一路过关斩将冲进了大厂的。当初内心对于刷题应试也是抗拒的,但是后期真香了!!因为进了大厂,并且刷题后发现自己的能力提高了!
其实这就好比我们高考考数学,其实我们日常生活中用到的也不多,无非就是加减乘除。但是遇到某些复杂点问题的时候上学的知识点又用上了,这时候就体现了所学知识的重要性。同理面试题中出现二叉树的算法也是可以理解的,这可以帮助面试官辨别你的技术功底是否扎实。虽然平时工作不一定用得上,但是某些时刻需要时,你就可以快速调动你的知识库。
在这点上,熟练掌握这方面知识同时又有丰富经验的面试者就脱颖而出了。当然面试也不是只是做算法题,你通过了写题考验,接下来就可以开始侃侃而谈,聊聊你参与的项目等等。
要知道很多企业就是通过写算法题这样的方式淘汰了一批人,特别是大厂(外企如:微软、亚麻这类我们就不多说了;国内:字节、阿里、快手、拼多多、京东等等),企业也希望招到算法很厉害、工作经验丰富的优秀人才,由此可见算法在面试过程中是非常重要的,无论是大厂还是传统企业面试基本上都是要问到算法。
如果想要奔向大厂,拿到一个好offer,算法必须要吃透,建议各位平时没事多刷刷题,毕竟大厂的竞争还是非常激烈的~ 前期刷题时真的非常痛苦,但是一定要说服自己坚持下来,技术的累积是个长期过程。我在刷题时期常在各大BBS里看见在讨论题的大佬们,真的很励志,大佬都在努力的刷题,你还好意思不努力吗?


那么怎样高效的刷题呢?接下来是我之前在Lintcode刷题的经验小结,希望对即将开始刷题的各位有帮助!
面试的算法题只是你平时刷题遇到的一小块内容,但是你又无法确定面试时会遇到什么算法题,那只能大规模的刷题,各个类别的题都涉猎。这个也是我之前听过的算法课上老师总结出的面试常见算法知识点:(有备无患吧,有需要面试的朋友可以看看)
其中拓扑排序算法、二分法、二叉查找树、哈希表、动态规划、堆、分治法...这些算法和数据结构面试中常会遇到,其它的出现概率比较低 但也可能会出现。


首先要根据自己的情况定制自己的刷题学习计划,针对性的刷题。刷题绝对不能心急,思路和方法才是最重要的。国内大厂的面试比较少考难题,所以我给自己定的计划也是围绕简单和中等题来的。
我之前是先把简单和中等的题各刷了3遍,然后把中等题作为练习的重点,简单题作为辅助练习,锻炼自己举一反三的能力,遇到相同类型的题也能快速反应。后期也会给自己加难题,但是真的需要花很多时间,所以练习的量不大,而且面试一般也不会出这么难的题,于是偷懒了,哈哈哈 幸运之神眷顾的人。
刷到一定阶段,我就开始针对想要去的大厂进行刷题计划了,LintCode上还蛮多国内大厂面试真题的,如果你有意向的大厂可以去上面看看。
但是不能光刷题,还要学会讲题,面试时你表述不清楚如何得到题解,面试官会以为你是背的答案,这就很尴尬了。所以在做计划时,也要把这趴安排上~


最后,也是最重要的。刷题刷得熟练,不代表你就一定能拿到Offer了!!!面试看的是应聘者的综合实力,解题只是其中一部分,所以除了刷题外,你还需要准备许多,譬如:简历的准备、面试模拟、各大公司的偏好了解...
要准备的还是挺多的,我当初还是小白的时候真的是对这些一窍不通,凭着一身孤勇应聘了几个大厂,结果通通吃了闭门羹。虽说不是做题一流,但是也还不错来着,真的受了极大打击。然后自己悄咪咪的报了个算法班,才知道原来面试有这么多的套路和注意事项。果然还是要职场老鸟指路!
以上是个人的一些小总结,各位看完记得马克下 点赞 支持~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2021-7-4 07:22 | 显示全部楼层
其实二叉树的例子不见得是最难的了。现如今,算法面试题目越来越多样,准备起来是越来越难。
如果刷好二叉树,就能找上工作,估计大家也还是蛮开心的。
抱怨估计也是因为竞争大和工作不好找吧。或者是因为没有好好准备,觉得自己平时代码写得也不少,面试应该没问题。
还有一点就是,面试其实不仅仅是做题吧,有时候哪怕你做出来,也不是保证你就面试成功吧。
说白了就是,自己轻敌了,找个理由搪塞一下而已。其实我们也知道,面试和平时写算法本来就是不一样的。
压力考试下,大家更容易发挥失常。
不管咱们怎么抱怨,除非所有大公司一起说,哎呀,咱们几家这面试流程得改啊。然后坐下来商量,怎么样才是对面试者最友好的方式,搞出一套新的面试流程来。
要不然,面试流程还是这样,考察的还是数据结构和算法,难度还可能越来越高。更难的可能还是,咱连简历关都过不去,见到做题的机会都没有。不过后面这个难关主要还是New Grad更容易遇到。
对于有经验的人来说,(我瞎猜的,我一个没上岸的人),难的是认真去复习和准备算法和数据结构吧。毕竟每天有工作要做,有家庭要照顾,有On Calls在等着。所以有Recruiter来撩的时候,你觉得你去面面肯定okay的,反正也是一个机会。
但由于比较久没碰算法书了,也没刷LeetCode,面试somehow没过,又是就抱怨一下:
面试造航母,工作拧螺丝钉。
<hr/>那咋办?
既然面试就是这个流程,我觉得大部分人胳膊也拧不过大腿。
那就好好准备吧。毕竟,刷不好题,面试不过,抱怨也解决不了问题。大包还是拿不到。
所以,如果要上岸或是要跳槽,平时学习工作再累再忙,也应该刷刷题。
保证手不生,面试的时候至少不至于太尴尬。
刷题难啊,LeetCode动不动就上千的题。而且每周在增加,不知道何时是个头。
别说自己刷了,给你答案,让你自己看明白,估计也得十天半个月吧,而且还得是你基础本身扎实。
所以题目还得精刷。
怎么精刷?
我恰巧把这些东西整理了一下,希望能方便大家帮忙之中能高效刷题:
穷码农:LeetCode按照怎样的顺序来刷题比较好?我知道这里面大牛多,只是提供一种可能性,大佬们看看一笑了之即可。
主要是想送给那些和我一样还在迷茫,挣扎的小伙伴。
不刷题,基本没出路啊。
以上。
发表于 2021-7-4 07:29 | 显示全部楼层
给大家出一道某硅谷大公司的算法面试题,并给出解答过程,让大家体验一下如何去面试


算法题案例:


Given an input string and a dictionary of words,
segment the input string into a space-separated
sequence of dictionary words if possible. For
example, if the input string is "applepie" and
dictionary contains a standard set of English words,
then we would return the string "apple pie" as output.
简单说就是给定字典,对无空格的短语切词。这里可以考虑一些情形,你先问面试官:

如果输入的刚好是字典中的一个单词怎么办?(特殊例子)
我是不是只要考虑切成2个单词的情况?(不仅仅2个,但可以从2个开始)
如果输入的根本无法切分呢?(就返回空)
有没有一些单词拼写或者助词缩写形式(如im = i am,如果在字典中没有就不算)
如果可以切分多种合理的词?(返回一种就行)
要不要用一些字典的高级数据结构(trie, heap, suffix tree)(不需要理解)
字典有哪些操作的方式?(就是词的查询)
字典有多大?(正常英语词典,内存足够)

这些问题时帮助你理解和简化题目,也考察出你对算法和数据结构的熟练度。

简单化的方案:

就把它拆成两个词。分别验证前后是否在字典中。这个直接简单,也让面试者心里有底。下面是python的代码实例:

def segment_string(input, dict):
  len = len(input)
  for i in range(len):
    prefix = input[0:i+1]
    if prefix in dict:
      suffix = input[i+1:]
      if suffix in dict:
        return prefix + " " + suffix
  return ""
下面考虑怎么推广到一般的情况,有种递归的办法,在上面的基础上稍微改动一下


def segment_string(input, dict):
  if input in dict: return input
  len = len(input)
  for i in range(len):
    prefix = input[0:i+1]
    if prefix in dict:
      suffix = input[i+1:]
      seg_suffix = segment_string(suffix, dict)
      if seg_suffix != '':
        return prefix + " " + seg_suffix
  return ''
给出解答还要分析复杂度,就是所谓的 大O分析,这种递归的做法很多人不清楚怎么计算,但你可以想象 如果单纯想 字典里面只有一个字符组合a,aa, aaa... 输入也是aaa... 你就发现就是全组合的可能性,答案O(2^N)。

还可以做的更好么?

如果大家清楚动态规划或者memoization,可以进一步节约计算,这是一种空间换时间的技巧,但大家能思考它的复杂度吗?如果我说是O(N^2), 大家有办法去证明吗?


memory = {}
def segment_string(input, dict):
  if input in dict: return input
  if input in memory: return memory[input]

  len = len(input)
  for i in range(len):
    prefix = input[0:i+1]
    if prefix in dict:
      suffix = input[i+1:]
      seg_suffix = segment_string(suffix, dict)
      if seg_suffix != '':
        memory[input] = prefix + " " + seg_suffix
        return prefix + " " + seg_suffix
  memory[input] = ''
  return ''

这道题目就展示了不同层次的优化,首先是一道有现实意义的问题,就是做单词自动识别,它也不需要特定领域的知识,当然递归你还是要知道的。在面试过程中,我可以给你一些提示,但最终你走到哪一步,就看你的能力。并且如果你实现了优化解法,我可以继续问当字典大到内存放不下如何?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-21 03:35 , Processed in 0.067735 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表