多年前,我写过一些我鄙视的面试题。今天我想讨论一个比类型更具体的问题。我从来没有问过自己这个问题,但我在实际面试中看到过这个问题,我正式将其提名为最糟糕的编码面试问题。在之前的公司,经常有同事问这个问题,那是面试的时候第一次听到。公司面试是两人一组,两名工程师,一名应聘者。有一天,我和他结对面试了一些可怜的候选人。我认为候选人实际上表现不错,然后我的同事提出了这个问题。申请人结结巴巴,显然很尴尬。面试后的聚会上,所有面试过他的工程师都对他竖起了大拇指,只有我的伙伴反对聘用他,因为“任何有资格的工程师都应该能够回答”。他斩钉截铁地说,他不能和那个人共存。值得一提的是,这个故事有一个圆满的结局,我们不顾他的抗议聘用了我的合伙人,并在几个月内解雇了我的合伙人,候选人仍然在那家公司工作,干得好。反正我觉得这道题的面试是“有问题的”,所以我想在这里解释一下为什么它几乎是一道恐怖的面试题:写一个可以检测链表是否有环的函数。看起来像是一个基本的算法问题,对吧?站起来把函数写在白板上。这很正常,对吧?不,这是错误的,不要这样做。1.这完全不合适。这是求职面试。你有一个实时环境,你正在与之交谈的人正在接受采访。紧张是正常的。而那种带有“灵魂闪现”的谜题,才是最糟糕的一类问题。你的大脑将专注于思考“该死,我搞砸了这次面试”,而不是专注于手头的问题。人们喜欢“了解候选人的想法”,但谜题对此无济于事。正因为是拼图。只能寄希望于谜题能给你“豁然开朗”。有时我听到有人想知道应聘者如何应对压力,但你应该知道面试本身就是有压力的。向人们提出困难的问题完全是在浪费时间,这样做只会考察候选人是否以前见过这个问题。换句话说,就是考演技(听说问题知道答案假装没听见,然后假装一步步推演得到答案)。这个问题是最浪费时间的。你为什么还要问?好吧,想象一下,如果一个人真的是第一次听到这个问题,而你希望他能给出答案。对于这道题,一般来说,“正确”的答案是龟兔赛跑算法,把两个指针放在链表的头部,一个是一次走两个节点,一个是一步走一步时间;如果指针指向同一个节点,则表示存在循环。当然还有更简单的答案,比如把所有通过的节点都标记为“通过”,或者从每个点开始,看该点是否可以回答,或者在遍历过程中做一次hash,看是否有是任何没有重复。但是当你抛出这些答案的时候,面试官会加上条件,要求内存或者时间用的少或者不能改变原来的数据结构。最好的答案是龟兔赛跑。我们一开始就应该考虑这么多吗?无论如何,看起来你觉得自己很体贴。链表数据结构于1955年由AllenNewell、CliffShaw和HerbertA.Simon发现。“正确”的链表循环检测算法被称为“Floyd环搜索算法”,以纪念发现者RobertW.Floyd,那是在1967年。在1955年到1967年之间,这个问题是开放的,也就是说,无数人正在参加数学或计算机博士考试的人可以将其写入论文。尽管有这么多人在钻研,这个问题12年了还是没有解决。你真的认为仅仅超越所有学者的压力就能在20分钟内解决这个12年无法解决的问题吗?似乎是不可能的。你觉得还行,只是因为看了答案,然后在面试中,你“似曾相识”,“忽悠”了。2.这完全不切实际如果上面给出的理由没有让你对那个糟糕的问题发笑,那么再想想这个问题是否真的对日常工作有用。我的意思是:在实践中你是怎么遇到带环的链表的?我不是说你故意创建一个指向自身的链表,而是说无缘无故有这种东西?链表的数据结构不是抽象的东西,而是栈或者队列。您可能会在某些抽象数据结构中使用像链表这样的真实事物。比如栈,你用它来压栈、出栈、查看,对吧?那怎么会引起响铃呢?没有人想把事情搞砸吧?即使你自己写一个链表,你也不想让它看起来像这样。再看java的LinkedList类,你无法从外部控制它的next和prev,只能获取第一个或最后一个,在某个位置添加节点,按位置或值删除节点。看看java源码就知道真的没有:privatestaticclassEntry
