从九百到一:我们如何聘用 Robin Malfait

Adam Wathan

五月份,我们发布了我们的第一个职位公告来帮助我们找寻一位全栈开发人员加入我们的团队。

在收到近 900 份申请并面试了数十位优秀人才后,我们很高兴最终宣布 Robin Malfait 接受了我们的职位邀请,并从今天起正式成为 Tailwind Labs 团队的一员!

Robin Malfait

Robin 是来自比利时的一位优秀开发人员,长期以来一直是 Tailwind 社区的活跃成员。如果您是 Tailwind UI 的客户,并且曾在我们的 Discord 服务器上的 #react 频道提出过问题,那么有 90% 的可能是他帮助回答了您的问题。他甚至还创建了一个 bookmarklet 来帮助人们将 Tailwind UI 组件转换为 JSX!

Robin 是一位经验丰富的 React 开发人员,他加入我们是为了帮助带领开发我们正在开发的开源无渲染 UI 库,这些库将是 Tailwind UI 官方 React 和 Vue 支持(暂时先从这两个开始)的基础。

我们非常兴奋他今天终于开始加入我们,迫不及待地想看到他的贡献如何帮助人们更快、更有信心地构建出色的 UI。欢迎加入团队,伙计!

以下是我们如何为这个职位进行招聘,以及我们如何从近 900 份初始申请中筛选出候选人,最终向 Robin 提出录用的故事。


职位公告

在此之前,我们只雇用过 Brad,他是我们已经认识并信任的人,所以我们不需要职位公告或任何严格的申请流程。

我知道如果我们想要得到真正优秀的候选人,就必须写一个有说服力的职位公告。经过大约 3-4 天的撰写,我们最终得到了这样的结果:

阅读职位公告 →

以下是我在撰写时关注的重要事项:

  • 具体说明申请人入职后将要从事的项目
  • 明确表示我们是一个小团队,所以每个人都必须做一点所有的事情,包括客户支持
  • 举出具体的例子,说明如果申请人已经在公司工作,他们将参与哪些刚完成的项目
  • 详细说明我们在下一个主要即将推出的项目中预期会遇到的具体难题,以帮助申请人了解什么样的专业知识对我们有价值
  • 分享具体的薪资和福利信息。如果我自己不清楚薪资情况就不会申请工作,那么为什么我要期望优秀的人在不清楚薪资的情况下申请我们的职位呢?

我们收到了_大量_关于这份公告的积极反馈,我对最终的结果感到非常自豪。我认为它是以申请者为中心的,我认为这对于我们收到的申请质量产生了很大的影响。

申请流程

我们做的一件与其他公司有点不同的事情是,我们没有要求简历或给申请人一大堆问题来回答。我们只要求一份"申请",形式由申请人自行决定。它可以是求职信、小型网站、视频、幻灯片,随便什么形式。

我决定这样要求申请的原因有以下几个:

  • 我就是不认为简历那么重要
  • 我想要筛选出具有一些固有营销意识的人,我们是一个很小的公司,所以我们需要T 型人才而不是专家
  • 我想要筛选出能够交付成果的人,让申请完全自由发挥可以告诉你很多关于一个人如何独立地把一件事情从无到有做到完美的能力
  • 我想找到一个不需要被提示就能谈论我们在寻找的东西的人 — 找到一个自然地与我们试图做的事情很好地契合的人对我们来说将是一个很大的优势
  • 我预计会收到很多申请,我认为这种申请方式会让使用大范围申请方法而不是特别对我们公司感兴趣的人更容易被筛选出去

即使我认为这是一个相当令人生畏的申请流程,我们仍然收到了超过 100 份明显花了很多时间为我们的职位公告专门制作的申请,当然也包括 Robin 的:

阅读 Robin 的申请 →

有些人在申请中做了一些_真正_与众不同和有创意的事情(有人甚至制作了一个互动游戏!),但 Robin 的申请因以下几个原因让我们印象深刻:

  • 视觉设计很棒。我们是一家非常注重设计的公司,所以有良好的设计品味对我们来说非常重要。
  • 他关于学习编程和进入 Laravel 社区的故事告诉我们,我们有着丰富的共同历史,即使我们从未见过面。
  • 他大胆分享了一些关于组件设计的强烈观点,这些观点与我们即将开展的一些工作_极其_相关,我同意他说的话,甚至学到了一些东西。
  • 他分享了一个超级有趣的开源库,尽管这个库不太知名,但仍然有非常深思熟虑和完整的文档,以非常好的结构呈现。很明显他即使在编写 markdown 文件时也在考虑视觉设计。
  • 他分享了很多他想要和我们一起开展的项目的具体想法,其中很多都是我已经在期待做的事情。
  • 他把"GitHub"中的"H"大写了(天哪我讨厌人们不这样做)。

Robin 的申请是大约 40-50 份从内容角度来看真正突出的申请之一。

筛选申请

处理近 900 份工作申请是一项艰巨的任务。其中超过一半的申请我们可以立即放弃,因为他们只是提供了他们的 LinkedIn 个人资料链接或一份通用简历,但筛选其余的申请真的很难。

我以前从未以这种方式招聘过任何人,起初我真的觉得我们需要与每个提交了优质申请的人见面和面试。但随着申请源源不断地涌入,我意识到这根本不现实,我们必须设定某种上限。

我决定尽可能地对好的申请进行排序,然后只取前 20 名开始。这意味着我们不会与许多优秀的人交谈,也可能错过了最佳申请人,但现实是我们只能投入这么多时间,我不得不相信在约 20 份最佳申请中,一定会有_多个_我们不会后悔聘用的人,即使最佳人选可能在其他 30 人中。

面试流程

我们首先与大约 20 名申请人安排了视频面试,这花了大约 3 周时间。

这些都是 30-45 分钟的通话,我们就几个主题进行了相当随意的交谈:

  • 这个人最近在做什么工作,他们认为自己的优势在哪里
  • 他们为什么申请这份工作,这个职位的什么方面对他们有吸引力
  • 我们作为一家公司在未来一年左右要做什么,并详细讨论了几个项目
  • 回答这个人对这份工作或我们公司的任何问题

这是一个很好的方式,可以了解申请的人并直观地感受谁最突出。我们真的很享受与每个人见面的过程,但做出了艰难的决定,将名单再次缩减到大约 10 人进入下一阶段。

带回家的项目

申请过程的下一步是一个带回家的项目,申请人必须使用 Vue 或 React 构建 Steve 创建的设计。我们估计这是一个 4-8 小时的项目。

我们提供了一个包含所有说明的 zip 文件、Figma 文件中的设计以及演示工作实现的视频,概述了任何难以在 Figma 中捕捉的行为。

在 GitHub 上查看带回家的项目 →

我们试图给出非常清晰的说明,并确保指出我们希望人们把时间花在哪里,以及哪些区域我们不希望他们过度思考或花费太多时间。

我们给每个候选人大约两周时间完成项目,只是为了确保他们能够将其融入到自己的日程安排中,而不会造成干扰。

我们收到的所有提交都很棒,但我们再次强迫自己将下一阶段的候选人限制在 6 人。

我们特别喜欢 Robin 的提交的一点是,他花了很多时间通过代码中的注释来引导我们了解他的解决方案。对于常规生产代码来说,我会说这绝对是过度了,但作为工作申请的一部分,我认为这非常有帮助,可以深入了解他实际上是如何_思考_他正在编写的代码的。他还花了很多时间描述某些问题的替代解决方案以及他为什么没有采用这些方法,这也很有帮助。

结对编程环节

申请过程的最后一步是与我进行两小时的结对编程环节。

在这样的面试过程中进行结对编程时,存在着固有的权力动态可能影响整个过程的很大风险。我_真的_想尽可能避免这种情况,所以我做了两件事:

  • 我确保我们要一起编程的内容是完全新的,我对此没有任何先验经验
  • 我让候选人建议几件我们可以一起编程的事情,然后从他们的列表中选择了一个

我绝对不想在我已经知道所有答案的事情上结对,然后只是看着候选人是否能找出我已经知道的东西。这绝对不能代表真实的工作,我认为这根本不会有用。

相反,通过选择我们都没有太多经验的问题,我们可以把权力动态放在一边(至少尽可能地),专注于一起学习新东西,看看我们如何帮助对方解决问题。

我结对编程的一些内容包括:

  • 从头开始构建日期选择器
  • 学习 XState
  • 使用 Vue 3 composition API 构建模态对话框

我真的很喜欢这个过程,并为我们如何设置它感到非常自豪。这绝对是面试过程中最有信息量的部分,真的让我对我们提供工作给合适的人充满信心。

对于 Robin 的环节,我们决定从头开始构建一个 SVG 图表库(我们俩都从未做过的事情),使用 Svelte(我们俩都从未使用过的框架)。这是 Robin 的主意,他有勇气在_面试环境_中同时解决两个全新的问题,真的让我印象深刻。我们一起结对编程的过程非常愉快,在整个环节中,从未感觉到我们中的任何一个人领先于另一个人或试图让对方赶上某些事情。我们有很好的化学反应,感觉非常有活力和富有成效,让我想起了我职业生涯中一些最好的结对编程环节,这非常令人难以置信,因为我们从未一起工作过,而且他正在接受工作评估。

提出录用

整个过程花了大约 1.5 个月,最后我们在选择前几名候选人时非常困难。实际上,我们可以雇用其中任何一个人而不会后悔,但我在面试和结对编程中与 Robin 的经历稍微更突出一些,我非常高兴能够向他提供这个职位。我们知道他将成为团队的绝佳成员,我迫不及待地想在未来几个月与他一起解决一些难题。

想讨论这篇文章吗?在 GitHub 上讨论 →

Get all of our updates directly to your inbox.
Sign up for our newsletter.