65.9K
CodeProject 正在变化。 阅读更多。
Home

招聘看重表现而非技能

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (18投票s)

2015年8月11日

CPOL

18分钟阅读

viewsIcon

25595

招聘看重表现而非技能

引言

本文将详细介绍如何根据表现而不是仅仅根据技能来招聘开发人员或架构师。这应该会极大地提高您的开发团队的表现。

背景

标准的开发人员/架构师面试通常只包含一些记忆性问题,然后通常是白板编程。这是一种替代方法,它应该能让面试官深入了解候选人在现有技能集下承受压力的能力。

作者:Chris Johnson @ intrin.sc

招聘看重表现而非技能

本文本质上是我上一篇获奖文章《招聘优秀程序员》的第二部分(请参阅 https://codeproject.org.cn/Articles/814978/Hiring-a-Great-Programmer)。这次,我想深入探讨招聘开发人员(或组织成功的任何关键职位)的非技术方面。

尽管大多数管理者都明白明智招聘的重要性,但许多人却不知道如何做到。最终,他们常常凭直觉选择潜在的员工。虽然这种策略有时会奏效,但更多时候会导致管理者雇佣到无效或缺乏动力的员工,从而拖累组织。基于情感、偏见、个性和刻板印象的决定,事后看来往往是错误的。避免这种陷阱的关键在于训练自己,使所有招聘决策都基于理性而非情感。

我做了多年的顾问,也经历过不少好的和坏的面试。我最近在一家软件公司面试,他们正在为一个重要项目招聘一名高级顾问。那是一场董事会式的面试,有四位高级管理人员和技术人员面试我。所以,这通常会让被面试者感到至少有一点表现的压力。其中一个问题是:“如果我们房间里有 10 个人,最多可能发生多少次握手?”(即,每个人之间的握手次数各不相同)。我立刻想到这应该有个公式,我应该立刻给出一个答案,但思考了几秒钟后,我意识到我一时想不起来有什么公式,于是我开始计算。人数基本上是无关紧要的,所以如果你有 n 个人,不同的握手次数是 (n-1)*n/2 = 3。我计算了 3 个人握手的情况,然后意识到有一个公式,并将其应用于 10 个人。所以,我得到了正确的答案。但是,由于我在压力下,我花的时间比平时长(我相信这对每个人都适用)。然而,面试官似乎不喜欢我的答案,可能是因为我花了一分半钟才回答。他说他面试的另一个人立即给出了答案,只是因为他已经记住了那个问题和答案。我有点震惊,他竟然偏爱那些死记硬背的人,而不是那些从一无所知开始,仍然能找到正确答案的人。我意识到这位经理在寻找死记硬背的人,而不是解决现实世界问题的人。我还意识到,这个问题永远不会是现实世界中需要解决的问题,而且几乎不适用于任何 IT 相关的工作。这位经理显然是在招聘看重技能而非表现的人,尽管我的答案是正确的,但他却期待的是死记硬背。通常,你接受的教育和通过经验获得的技能,在工作中或新项目中只占大约 20% 到 30%。在高绩效的工作中,这比技能和死记硬背更重要,而这些技能和死记硬背在任何特定工作中都可能被使用,也可能不被使用。批判性思维和承受压力的能力,比任何人能获得的几乎任何技能都更重要。

但遗憾的是,大多数管理者从未意识到这一点,并不断地招错人。我见过一些新入职的员工,在最基本的工作上都感到困难,比如搭建开发环境或调试程序故障。我记得有一次,一个 Web Service(一种为网络或万维网提供信息的程序的华丽名称)是由几个月前离开公司的开发人员编写的。另一位负责让现有代码正常运行的“老手”开发人员,已经在公司工作了大约 10 年,却难以在他们的开发机器上安装和运行 Web Service。尝试了两周后,他们放弃了,并请我帮忙。大约三分钟后,我发现“IIS”配置中有一个属于那位旧开发人员的 ID,我问新开发人员是否可以尝试将其更改为他们的 ID,看看是否有效。我对 Web Services 几乎没有经验,但我知道不能使用一个不再存在的 ID!他们说服我错了(甚至没有尝试我的建议),于是我回到了我正在做的另一个项目。又过了一周,他们坚持让我放下手头的工作,在我自己的开发机器上安装这个 Web Service 并尽快运行它,因为让它工作至关重要。于是,我将它安装在我的机器上,并通读了文档(不幸的是,文档是用蹩脚的英语写的,而且非常技术化)。这时,那位开发人员已经让我确信 ID 不是问题,所以我徒劳地尝试更改配置文件,并通过代码进行追踪,但都没有成功。然而,我想我应该试试我的 ID 理论,在将“IIS”配置更改为使用我的 ID 后,它立即奏效了!所以,我的观点是,根据表现招聘至关重要,并且如果您能招聘到合适的人,将为您的公司节省数十万甚至数百万美元的劳动力成本。而那个合适的人,就是能够正确思考、从不假设任何事情的人。在这种情况下,那位“开发人员”浪费了公司三周的时间,无论他的工资是多少(我猜他的工资对于一个开发人员来说是平均水平,因为他已经做了二十多年的开发人员了),招聘我,我的时薪大约是他的四倍,仍然能为公司节省一大笔钱。从美元的角度来看(使用假设数字):

成本明细

高级“开发人员”时薪 50 美元(每天 8 小时)处理问题 3 周。成本:6,000 美元

Chris 时薪 200 美元(当然我没那么高,但很有理由认为我应该!)大约需要 10 分钟安装并运行项目。 成本:33.33 美元

总节省: 5,966.67 美元

当然,这些数字还不包括适当的税款,而且别忘了如今员工的各种福利。但这足以证明我的观点!我为公司节省了数千美元。而且,请记住,这确实发生过,信不信由你,我并没有编造!如果当时我不在那里,会发生什么?由于部门里没有人了解 Web Services,那位开发人员可能会继续研究这个问题,不知道要到什么时候!但是,让我惊讶的是,在这种情况下,经理似乎并不在意,因为那位员工的工资比我便宜得多。他们仍然没有意识到,招聘错误的人会给公司带来巨大的损失。无论“正确”的人的工资是多少,他们仍然会比工资很低但错误的人给公司带来更少的成本!我在我咨询过的每一家公司都反复遇到这种情况,并与我合作过的一些经理讨论过这个问题。然而,以较低的薪资招聘员工的一个卖点是,监督招聘工作的经理会因为“为公司节省了这么多钱”而感到满意。所以,那位负责招聘的经理可能会获得更多的奖金或其他激励,以便尽可能低地招聘人员。我在北美(以及很可能在全球范围内)看到了这种趋势。这也是我成为顾问的原因之一,因为我可以收取更高的费用。当然,缺点是我们必须按时完成项目,同时还要每天帮助其他像这样的“开发人员”最多几个小时。因此,您的工作量更大,工作时间比团队其他成员更长。

在面试一个人时,还有另一件事要避免,那就是仅仅给出标准的记忆和编码测试。他们应该接受实际的测试,而不是仅仅基于技能或记忆。我过去的一个项目中遇到的一个真实的现实世界挑战,涉及对程序的一部分以及底层代码和数据库结构进行相当大的更改。正如您在下面看到的,这是为一个大型电力公司设计的,该公司正在为整个省创建一个新系统。问题的简要概述如下:

现有场景

  1. 省内地理位置的层次结构图。您可以通过树状结构查看,如下所示:

    图 1:层次结构图
  2. ElectricalGroups 表是一个自引用表,其中“ParentElectricalGroupId”指向表本身的 ID。

    图 2:EG(电气组)表
  3. 实体表(可能是Substations(如图 1 所示)、发电单元等,或任何与电气组相关的未来实体)。此表有一个“ElectricalGroupID”字段,该字段当然直接指向该实体所属的电气组记录,该实体位于树的“第三”级别(在某些情况下是第四级)。

    图 3:Substations 表
  4. 输出是实体更新屏幕上的一个二维层次结构图,如下所示:B.C. -->Lower Mainland + Vancouver Island --> Victoria --> Downtown Substation。

  5. 遍历树的代码相当简单。您有一个来自Entity表的子 E.G.(在此例中为变电站),因此您的代码只需要递归地查看 Electrical Group 表中的“ParentElectricalGroupId”字段,直到“ParentElectricalGroupId”为NULL,然后反转 Electrical Group 记录列表,并在屏幕上显示。

新场景

  1. 不再是一个层次结构图,可以有任意数量的电气组层次结构图。
  2. 为了简化流程,我们需要在系统中添加一些屏幕,以便用户可以选择任何现有的地图并进行复制,然后进行可视化编辑,从而可以删除他们想要的任何节点,并在需要时更改文本。这看起来会类似于图 1,当然还要有正确的图标!
  3. 在每个实体屏幕上,现在可能会显示无限数量的地图。这是通过一个 JQuery 插件实现的,开发人员将指定地图类型的 ID。然后,您可以在实体屏幕上放置任意数量的 JQuery 插件,有多少地图就可以放置多少。

那么,这所有的一切究竟是如何实现的呢?对于一个思路清晰、不先思考代码而先理解高层设计的人来说,这并不难。我原以为大多数开发人员都像我一样思考,在看代码之前先提出一个高层设计。但不幸的是,我错了……。

解决方案

  1. 添加一个地图表。该表将有一个 Map ID 和一个“rootElectricalGroupID”,它只指向上面 ElectricalGroup 表中的最顶层ElectricalGroupID。(保持现有的 Electrical Group 表不变)

    图 4:Map 表
  2. 添加一个EntityElectrical组的链接表,其中包含一个 EG(电气组)ID、一个 Entity ID 和一个 Entity 类型(或者您可以为每个实体类型设置一个链接表)。

    图 5:SubstationToEG 表。
  3. 创建一个新屏幕,允许用户在树上将实体可视化地分配给电气组。这已经完成了(尽管被之前的开发人员做得有些糟糕),但现在必须更新实体链接表记录。

  4. 从实体表中删除“ElectricalGroupID”字段,因此您将不得不使用新的实体到电气组链接表。
  5. 最重要的是(在理解了上述所有数据库更改后),要显示二维层次结构图,您可以使用两种不同的方法来遍历“树”。而且,每种方法在系统中存在多少个电气组地图的情况下,效率都会有所不同。
    1. 要在地图数量较少的系统中以最快的速度显示层次结构图,您将从现有的EntitytoElectricalGroup表记录开始,因为该 ID 存储在实体表本身中。您将以与之前相同的方法遍历“树”(即 Electrical Group 表),因为您知道“ParentElectricalGroupID”,您将递归地遍历ElectricalGroup记录,直到“ParentElectricalGroupID”为NULL。然而,有趣的地方在于这里,而这是 99% 的开发人员出错的地方。大多数开发人员会认为到此为止。我之所以这样说,是因为在我工作的团队中,“架构师”声称他已经完成了遍历,并继续编写了一些 C# 代码,这是另一个大错误。然后,我与第三位开发人员进行了交流,他也得出了同样的结论。我一直试图向这两位开发人员解释,在编码之前,必须足够地理解高层设计。但我的话被左耳进右耳出了。所以,继续解决这个问题,现在您已经从下往上遍历了一次“树”。所以您得到了父电气组 ID。但显然,由于现在有多个地图,您无法确定您获得的根 ID 是否对应正确的电气组地图,对吧?然后您查看地图表,如果正确的 Map 记录与您刚刚检索到的根ElectricalGroupID匹配,那么您就完成了,可以显示二维地图。如果不匹配,那么您必须重新开始,因为实体到电气组链接表可能有多条记录与您的实体 ID 匹配。所以,简单地对剩余的 Entity To Electrical Group 链接表记录重复此过程,直到找到电气组表中的正确根 EG ID,然后显示二维地图。
    2. 要在地图数量非常多的系统中以最快的速度显示层次结构图(在这里“非常多”当然取决于您的性能测试结果),您将从现有的 Map 表开始,并使用您感兴趣的地图的根 EG ID。您必须递归地遍历树中的每一个节点,直到找到与EntitytoElectricalGroup表中的记录匹配的ElectricalGroupID。当然,您的代码必须只保留从父节点到子节点的最后一个完整“路径”。

摘要

正如您所看到的,对现有解决方案进行微小的更改会导致极其复杂的代码更改,而大多数团队成员(他们也参与了现有的数据库和代码编写)都无法理解。我认为我比大多数人更快地理解它的原因是,我只是在视觉上观察事物,并试图尽可能清晰、尽可能简单地写出来,这样就能清楚地知道发生了什么。在与团队中其他开发人员进行有些有趣的对话中,他们一直在谈论代码,但直到“伪代码”和完整设计完成后,我们才需要依赖任何代码。但同样,这很可能也是我在项目中期被叫来的原因。因为,最初解决方案的“架构师”也正在进行一个为期 9 个月的子项目,该项目由 3 个屏幕组成,本质上是为电气组和相关实体概念添加时间元素,实际上被称为“项目”。“架构师”可能过于专注于他当前的项目灾难,而无暇顾及添加新功能。然而,由于我不想卷入这三个屏幕的灾难,我坚持让他把上述新功能的代码添加到他的代码部分。实际上并没有多少代码需要编写。我知道它会被错误地完成,尽管我向“架构师”和整个团队解释了这个过程至少七次,并用详尽的文档记录了整个过程。所以,我不得不拿走错误的 कोड,并进行修复以完成解决方案。

当然,比这个简单的解释要复杂得多。还有其他几个屏幕需要编写,允许用户通过拖放电气组并将它们与相关实体关联,当然还有遍历树的所有代码,以及用于在实体屏幕上显示二维代码的插件。JQuery 插件允许用户将其放置在任何屏幕上,然后用所需的 Map Id 调用插件。插件负责其余的事情。但同样,我必须强调,对于任何进行此类更改的开发人员来说,在考虑需要进行哪些编码更改之前,在头脑中完全理解高层设计是绝对至关重要的。即使您不是数据库架构师,或者没有任何 JQuery 经验,一个有能力的开发人员也应该能在几周内完成这项工作。而且,任何有能力的开发人员应该能在 20 分钟内弄清楚高层设计!所以,这对于测试新开发人员来说是一个完美的方案。而不是问他们面向技术的问题,这些问题完全绕过了 proper high-level / technical design 的概念,一个像上述场景这样的问题应该成为任何开发人员面试的必考题。这应该告诉面试官,这个人是否能在不将问题与任何编码风格或技术挂钩的情况下解决问题,而这比学习任何技术都重要得多。

遵循“按表现招聘”的概念将使您能够避免招聘上述场景中的“架构师”,您应该不惜一切代价避免这样做。这位架构师在“项目”这三个屏幕的灾难上花费了近一年的时间。看看“项目”模块的最终结果,添加一个时间元素到现有解决方案不可能需要一年时间。我还不得不忍受业务分析师和“架构师”之间持续的讨论,他们正在讨论添加一些新的、实际上没有意义的功能,因为业务分析师根本没有开发经验。在这种情况下,“架构师”应该足够聪明,知道 BA 的想法是错误的,不应该实施它们,并给出不实施的理由。他们还应该意识到 BA 缺乏技能,并尽可能与最终用户澄清。这可能不会让 BA 满意,但项目只需要三个月而不是一年,因为不必要的编码就可以避免。按高级开发人员/架构师的平均年薪约 10 万美元计算,这将为公司节省 7.5 万美元!

所以,正如您所见,尤其是在软件开发领域,按表现招聘实际上比按技能招聘更为重要。我上面描述的场景确实发生过。我发现的另一个问题是,尽管项目的特定部分花费的时间太长,管理层却从未试图纠正。在我看来,这造成了大多数大型项目失败的原因。本质上,经理招错人了,直到为时已晚才意识到,而那时,又不能简单地替换这个人,因为他们必须报告解雇她的原因。所以,他们不得不继续下去,直到项目完成(如果可能的话)。如果我是一位经理,我会认真考虑进行一些面试,以确定这个人是否能在真实场景下表现出色,而不是像典型的开发人员面试那样,只是让应聘者背诵事实,然后写一些代码来看看他们学习或记忆得有多好。这肯定每年能为公司节省数十万甚至数百万美元,这对于公司或 IT 部门的成败至关重要。

历史

  • 版本 1.0:2015 年 8 月 11 日
© . All rights reserved.