专栏名称: 伯乐在线
关注职业资讯;学习各类职业感悟、心得和经验分享,扩大职业视野;体会求职、工作和创业的历程 - 就在JobBole.com 伯乐在线
目录
相关文章推荐
程序员小灰  ·  AGI来了,我们还需要拼命工作吗? ·  昨天  
程序猿  ·  AI 正在培养“文盲”程序员? ·  昨天  
程序员的那些事  ·  湖南大学的 DeepSeek ... ·  3 天前  
OSC开源社区  ·  字节跳动开源跨平台UI框架Lynx:一套代码 ... ·  3 天前  
51好读  ›  专栏  ›  伯乐在线

初级开发者面试中的不合理问题

伯乐在线  · 公众号  · 程序员  · 2019-06-02 20:24

正文

(给 伯乐在线 加星标,看经典文章

编译:伯乐在线/Ivyw


我有很多初出茅庐做开发的朋友,其中一位给我讲了他在应聘 Ruby 初级开发工程师时的事。下面就说说我和我的一个朋友是如何解决这个面试题的,两个高级工程师来解决这个初级工程师的面试题,显得有点大材小用,但结果令人出乎意外。在这个领域我还是有点见解的,我会详细描述一下我的解题思路。


面试题


那个面试的朋友需要在 30 分钟内用 Java 实现一个链表,他的第一反应是小菜一碟,我也一样。即使是对没有 CS 学位的人来说,链表也是一种很通俗易懂的数据结构。


链表是含有一串节点的链表,每个节点带有一个指向下一个节点的指针,这样你就大概能清楚它的工作过程了:插入节点时前后节点的信息和引用前后关系的指针都会发生改变;删除节点时移除这个节点和它的指针即可;查找节点时按顺序查看指针信息直到找到你需要的那个节点。如果你大学是 CS 专业的,那么这可能是你最初接触到的非嵌入式数据结构。链表的用处很大,C 语言的标准库为接下来的编程工作提供了必要的支持。


对初级开发人员来说这是一个很好的面试题。这个试题涉及了算法技巧,但没有 CS 专业学的那么深奥。其次,这也是非常切合实际的编程测试,因为工作后你肯定要写代码、调试、输出并运行代码。你不会被点名去白板上写点什么来展现自己的能力,这不是白板编程。



我很好奇,为什么那个朋友对这样的面试感到困扰,随后他说出了这道题目的附加条件:面试官希望这个链表能符合 List 的特性。我立马被这道题的复杂性吓到了,完全不像一开始的毫不在意。


救命


可能有人对 Java 标准库接口了解不多,所以让我来普及一下 List 。List 是 Java 的泛型接口,可以用来实现包含很多相同数值的有序集合。这是一个功能强大的接口,提供我们可能会用到所有的定位列表数据类型。它有 25 个公共方法,其中两个方法返回另外的接口含有12 个公共方法,也就是说,你在实现过程中需要构建和测试 37 个公共方法。其中 t 意味着这是一个泛型接口,数据类型没有限制。这简直太荒谬了,而我的朋友仅有 30 分钟的时间来解答。


那么,这个问题是否适合那些经验不足两年的新人呢?当然不适合,而且相当不合理,我就“严肃认真地分析下”(我可以好好施展一番了,我对自己还是很有信心的)。我可以很轻易地完成这项任务,毕竟我是一个“资深”的开发人员,我这半辈子都在和 Java 编程打交道,虽然对工具有些生疏,但领悟很强。只是我不值得为这个任务花费太长时间。


然而这还不够,我们还要精益求精。Pair programming (结对编程)是我最喜欢的一种工作方式,可以协助我们更快地完成工作。你需要向同伴解释自己的思路,当你累了还可以得到同伴的帮助。所以,我找到 Stephen Best 来一起解决这个问题。前20分钟我们没有安装工具,而是做出问题草图、搭建测试环境等等。我们假装是在面试环境中解决这个问题。


很快我们就开始了。Stephen 曾和我一起工作了6个月,其中有三分之一的时间都是这种模式。我们使用 TDD 工作流程协同工作。


首先我们用 Eclipse 自动生成完整的界面框架,然后准备开始实施了。不幸的是,我们没有意识到这个任务的艰巨程度。


这个过程的艰难险阻,简直难以形容。List 接口有个好处,你可以在一些方法之上实现另外一些方法,但 List 接口的复杂度太高。大约 6 小时后,我们放弃了,我们失败了。我们非但没能在 30 分钟内完成实施,我们根本没法解决这个问题。


我们使用了 listIterator() 方法,它必须返回一个 ListIterator 对象并声明注销时间,但是当你几乎快要完成一个复杂接口时,不知道又从哪冒出另外一个。


我们所有的基本操作都已完成,并具有良好的测试覆盖率。我可以指出实现 List 所必须的但 Java 类型系统无法支持的部分,这些部分留给实施者去实现就好。我们没有做范围检查的接入,当你查询任意位置的元素时会报空指针异常,而不是提示范围错误。我们跳过这部分是因为这不是必要的而且我们时间有限。


我想象不出那些初级开发人员在遇到这样的问题时脑袋里会想什么。这是一个 Ruby 的开发岗位,我搞不懂为什么让一个新人去实现如此复杂的接口。当然,很多面向对象的想法可以从 Java 移植到 Ruby,也许这才是面试的侧重点。我和 Stephen 能够承担这项任务的唯一原因是我很熟悉如何构建 Java 通用系统。当你写出如下代码时:


private A reduceNodes(A accumulator, NodeCallback callback) {


其中涉及一个类类型参数、一个方法类型参数和一个匿名回调接口,好像并没有用到 Java 语言。这个命令可以让后面的实现更简单直接,在面试中这样做的话,我很确定面试官一定会很困惑。如果 Stephen 和我这样解答的话,可能无法通过这次面试,这是个危险信号。


继续上面的话题,这究竟说明了什么。这是一个压力面试,面试官给出一个问题,而很显然求职者无法在规定的时间内解决。再次重申一下,我很肯定没人能在 30 分钟内实现 List 链表。这很不公平,那些擅长某种思维的人才会被过滤掉,因为平常很少有程序员会遇到这样的测试。更糟的是,这会打击很多人的信心。下一节中,我们将探讨一下这样给初级开发人员带来的影响。


常春藤 CS Shibboleth


如果一个面试题无法筛选出合适的应聘者,那它还有什么意义,难道是要看应聘者面对无法解答的问题时的反应么?与其这样,还不如选一些合适的面试题,可以让面试官判断出应聘者是否成功解决了问题。


人类很奇怪,喜欢建立部落群居生活。部落是史前最接近现代社会(在地理意义上)的人类群体。这意味着他们是很接近我们的人,我们都喜欢进行筛选。给面试官主观决定的权利意味着他们会选择最接近他们的人。这就是为什么很多公司用白板编程的方式筛选应聘者,那些从名校毕业有 CS 学位的求职者在白板面试环节表现出色,这应该是好学历的特权吧。


有个问题不得不提。在过去几年中,非 CS 专业(考虑到我们这个行业兴起的年头,称之为非传统似乎有点可笑)的技术人员大幅增加。这些初级程序员大部分来自训练营。训练营不会教你如何构建红黑树或如何用 C 语言实现哈希表,他们没必要教这些,因为很少有学员毕业后会用到这些。这并不稀奇,因为当我开发 Rails 应用时,我的 CS 学位根本没有任何帮助。







请到「今天看啥」查看全文