早在五月份,我们发布了我们的第一份招聘启事,以帮助我们找到一名全栈开发人员加入我们的团队。
在收到近 900 份申请并面试了数十位才华横溢的人之后,我们很高兴最终分享 Robin Malfait 接受了我们职位的邀请,并且从今天起正式成为 Tailwind Labs 团队的一员!

Robin 是一位来自比利时的才华横溢的开发人员,并且长期以来一直是 Tailwind 社区的活跃成员。如果您是 Tailwind UI 的客户,并且曾经在我们的 Discord 服务器上的 #react
频道中提出过问题,那么他有 90% 的可能性是回答您问题的乐于助人的人。他甚至构建了一个 书签小程序,以帮助人们将 Tailwind UI 组件转换为 JSX!
Robin 是一位经验丰富的 React 开发人员,他加入我们的目的是帮助领导我们正在开发的开源无渲染 UI 库,这将是 Tailwind UI 中官方 React 和 Vue(无论如何,先从这两个开始)支持的基础。
我们非常高兴他今天终于开始与我们合作了,并且迫不及待地想看到他的贡献使人们能够更快、更有信心地构建出色的 UI。欢迎加入团队,伙计!
接下来是关于我们如何招聘这个职位的故事,以及我们如何将候选人从最初的近 900 份申请中筛选出来,最终向 Robin 发出邀请。
招聘启事
在此职位之前,我们只聘请了我们已经认识并信任的 Brad,因此我们不需要招聘启事或任何形式的严格申请流程。
我知道,如果我们想获得真正优秀的候选人,我们必须写一份引人注目的招聘启事。在花费了大约 3-4 天的时间后,最终我们得到了这样的结果
以下是我在撰写时关注的重点事项
- 具体说明申请人开始工作后将从事的项目
- 明确我们是一个小团队,所以每个人都必须做一些事情,包括客户支持
- 给出我们刚刚完成的项目的具体例子,如果申请人已经在公司工作,他们就会参与这些项目
- 详细说明我们预计在下一个重大项目中会遇到的具体难题,以帮助申请人了解对我们有价值的专业知识类型
- 分享具体的薪资和福利信息。我永远不会在不清楚薪资的情况下申请工作,那么我为什么要期望有才华的人在不了解薪资的情况下申请我们的职位呢?
我们收到了关于此招聘启事的大量积极反馈,我为它的结果感到非常自豪。我认为它是以申请人为中心的,并且我认为这对于我们收到的申请质量产生了很大的影响。
申请流程
我们与其他公司略有不同的一点是,我们没有要求提供简历,也没有给申请人提供一大堆要回答的问题。我们所要求的只是“申请”,形式由申请人自己决定。它可以是一封求职信、一个小网站、一段视频、一份幻灯片,任何形式都可以。
我决定以这种方式要求申请有几个原因
- 我只是认为简历没有那么重要
- 我想筛选出具有一定营销意识的人,我们是一家小公司,所以我们需要 T 型 人才,而不是我们需要专家
- 我想筛选出能够交付成果的人,而且完全自由形式的申请方式可以告诉你很多关于某人将某件事从无到有,并独自将其打磨成完善产品的能力
- 我想找到那些在没有被提示的情况下谈论我们正在寻找的东西的人 — 找到一个与我们尝试做的事情自然高度一致的人对我们来说是一个很大的优势
- 我预计会有很多申请,而且我认为以这种方式要求申请可以很容易地过滤掉那些使用“广撒网”方式求职,而并非特别有兴趣与我们合作的人
即使我认为申请流程相当吓人,我们仍然收到了 100 多份申请,其中显然花了很多时间为我们的职位精心制作了一些非常具体的内容,当然也包括 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 中难以捕捉的任何行为。
我们试图给出非常清晰的说明,并确保指出我们希望人们将时间集中在哪里,以及我们不希望他们过度思考或花费太多时间在哪些领域。
我们给每位候选人大约两周的时间来完成该项目,只是为了确保他们有机会将其安排到他们的日程中,而不会造成干扰。
我们收到的所有提交都非常好,但是我们再次强迫自己限制了下一阶段的候选人,这次减少到 6 人。
我们非常喜欢 Robin 的提交的一点是,他花费大量时间通过代码中的注释来指导我们完成他的解决方案。对于常规的生产代码,我会说这绝对是多余的,但是作为工作申请的一部分,我认为这对于了解他实际上是如何思考他正在编写的代码的幕后情况非常有帮助。他还花费大量时间描述了某些问题的替代解决方案,以及他为什么没有采用这些方法,这也非常有益。
结对编程环节
申请流程的最后一步是与我进行两个小时的结对编程环节。
当像这样作为面试流程的一部分进行结对编程时,存在一个固有的权力动态会影响整个过程的风险。我真的想尽可能地避免这种情况,所以我做了两件事
- 我确保我们结对编程的任何内容都是全新的,我没有事先的经验
- 我让候选人建议一些我们结对编程的内容,并从他们的列表中选择了一些内容
我绝对不想在一些我都知道答案的事情上进行结对编程,而我只是在观察候选人是否能找出我已经知道的东西。这绝对不能代表实际工作,而且我认为它根本不会有用。
相反,通过选择我们俩都没有太多经验的问题,我们可以把权力动态放在一边(至少尽可能地放在一边),而只是专注于一起学习新知识,并了解我们如何帮助彼此摆脱困境。
我结对编程的一些内容包括
- 从头开始构建日期选择器
- 学习 XState
- 使用 Vue 3 组合 API 构建模态对话框
我非常喜欢这个过程,并且为我们如何把它组织起来感到非常自豪。这绝对是面试过程中最有信息量的部分,它真的让我非常确信我们正在把工作机会提供给正确的人。
在罗宾的面试环节中,我们决定从头开始构建一个 SVG 图表库(我们两个人都没做过),使用 Svelte (一个我们两个人都没用过的框架)。这是罗宾的主意,他有勇气在面试环境中同时解决两个全新的问题,这真的给我留下了深刻的印象。我们在这个环节中合作得很愉快,而且在整个过程中,我们都没有感觉到谁比另一个人领先,或者需要赶上对方的进度。我们之间的配合非常默契,感觉充满活力和效率,让我想起了我职业生涯中经历过的一些最好的结对编程环节,考虑到我们之前从未合作过,并且他正在被评估是否适合这份工作,这真是太不可思议了。
发出录用通知
整个过程大约花费了一个半月,最后我们在几个顶尖候选人之间难以抉择。实际上,我们聘用他们中的任何一位都不会后悔,但我和罗宾面试和结对编程的经历更胜一筹,我很高兴能够向他提供这份工作。我们知道他将非常适合这个团队,我迫不及待地想在接下来的几个月里和他一起解决一些难题。
想讨论这篇文章吗?在 GitHub 上讨论 →