与我合作的自由职业开发者指南
过去七年里,我一直在招聘软件开发者和其他自由职业者。虽然大多数代码都是我自己写的,但招聘其他开发者是一种极其有效的力量倍增器,能为我腾出时间处理业务的其他方面。
如果管理得当,自由职业者能很好地开展工作,但合作关系也有数百种出问题的方式。开始合作的最佳方式,是对自由职业者与客户之间的关系建立共同理解。
下面这份文档说明了作为自由职业开发者与我合作会是什么样子。我发布每一份开发职位时都会附上它,并且在我们开始合作后,我会付费让承包商仔细阅读。它能吸引工作方式相合的候选人,并缩短招聘后的上手时间。
我以知识共享 BY-4.0 许可发布这些指南,因此欢迎你重新使用或改编它们。
概览
本文档说明了我与自由职业开发者合作时采用的流程和惯例。
如果你是在与我合作前阅读本文档,可以随意略读,看看这种工作方式是否适合你。如果你是在与我签订有效合同时阅读,请仔细通读,并将阅读所花时间计入账单。
黄金法则
我希望以自己希望被对待的方式对待你。
沟通
我最看重有效沟通。
沟通时宁可多说一些。当分享解决方案时,了解你为什么选择它,以及还探索过哪些其他途径,会很有帮助。
迅速处理邮件
我主要通过邮件沟通。
我的邮件风格正如 Cal Newport(卡尔·纽波特)所描述的“以流程为中心”。简而言之,邮件通常代表一项任务或一个问题,我们的目标是用尽可能少的来回沟通解决它。这要求我们双方都认真组织邮件,而不是随手发出一封能让邮件线程从收件箱中消失的最快回复。
糟糕的邮件往来
下面是一个糟糕邮件往来的虚构示例。自由职业者没有在一开始投入时间思考自己需要哪些信息,而是一个接一个地零散提出问题。
自由职业者:你偏好哪种图片格式?PNG 还是 JPEG?
我:PNG
自由职业者:尺寸应该是多少?
我:800x600px
自由职业者:在较小的设备上需要缩放吗?
我:需要,在小于 768px 的视口上应为 400x300px。
良好的邮件往来
相比之下,下面的邮件往来以有计划且高效的方式回答了同样的问题。
自由职业者:想请你对图片提些意见。能否告诉我你对以下各项的偏好?
- 格式(PNG 还是 JPEG)?
- 尺寸(以像素为单位)?
- 在较小的设备上是否需要缩放?
我:谢谢你提出考虑周全的问题!
- 格式应为 PNG。
- 在小于 768px 的视口上,尺寸应为 400x300px;其他情况下应为 800x600px。
邮件回复时间
我希望在一个工作日内收到邮件回复。换句话说,如果我在周二下午 3 点给你发邮件,我希望在周三下午 3 点前收到回复。如果你还没有完整答案,请先回复确认已收到消息,并提供完整回复的预计时间。
偶尔超过一天回复也没关系,但这应该是例外,而不是常态。你也可以对我抱有同样的期待。
会议
对于用文字沟通效率低下或无法沟通的话题,会议很有用。会议的成本很高——它会打断专注并限制日程安排,因此我会尽量减少会议。
我用邮件沟通事实,用会议互动讨论话题。例如,如果我们要评审一份设计文档,就不需要在线一起阅读。我们可以提前阅读文档,把会议时间留给现场讨论。
我还会每月安排一两次会议,让我们进行非正式的面对面交流。只通过邮件沟通可能会让事情显得缺乏人情味且气氛紧张。
| 讨论话题 | 备注 |
|---|---|
| “我们能安排一次会议讨论这个项目的截止日期吗?” | 不好:这是一个不需要开会的简单问题。 |
| “你下一个 pull request(拉取请求)会很难评审。我们能开个会让我向你解释吗?” | 不好:如果代码复杂到难以理解,开会并不能解决问题。 |
| “我有一个新架构的想法。我们能通个电话讨论一下吗?” | 不好:我更希望先看书面说明,读完后再讨论。 |
| “你的设计文档要求我们使用 Postgres,但我想了解其中的约束条件,并讨论其他选项。” | 好:这是一个复杂的决策,可能需要许多次小范围的来回沟通,因此实时讨论会比邮件更高效。 |
| “你在代码评审中给过我关于‘内聚性’的反馈,但我觉得我们对它的理解仍不完全一致。我们能开会讨论一下吗?” | 好:如果我们已经尝试通过文字沟通某件事,但效果不好,开会把问题彻底讨论清楚是很好的方式。 |
面试
我从不通过正式面试来决定是否录用。
我会要求查看你以往工作的示例,或者可能通过邮件提几个问题,但我主要关心的是我们合作得有多好。如果你是合适的候选人,我会按你的正常薪酬率安排一项范围明确的工作。人们通常把这种方式称为“先合同后录用”。
如果我请你开始一项付费试做任务,即使我们之后决定不合作,我也会为你的时间付费。唯一的例外是你没有善意地完成任务(例如,你为一项编程任务计费十小时,却交付了零行代码)。
尽职调查
自由职业者在尽量减少我监督其工作的时间时,能提供最大的价值。这要求你在提出问题前做好尽职调查。
你可以放心寻求帮助,但我希望你在可能的情况下自行寻找答案。如果你无法解决问题,请告诉我你尝试过哪些方法。
糟糕的问题
- 如何在我的电脑上安装 Flask?
- 如何链接到 Google Doc 的特定部分?
- 我们的服务器配置中,数字 443 有什么意义?
好的问题
- 我不太理解规范的第 3 节。“client”指最终用户,还是 API 的客户端?
- 我尝试安装你的软件时收到错误消息
FooBarBaz。我重新读过安装指南,也搜索过未解决的问题,但还是无法弄清楚哪里出了问题。你知道问题所在吗?
可用时间
我不希望任何人每周工作超过五天。除非你另行告知,否则我会假设你周末不工作。
我周末和美国重大节假日不工作。你周末可以给我发邮件,但我会在下一个工作日才回复。我尽量避免在美国东部时间中午之前处理邮件。
你可以自行选择工作时间,但我希望你的工作时间与我的工作时间有部分重叠;我的工作时间是美国东部时间上午 10 点至下午 6:30。
我不要求你每周遵循固定日程,但我越能预测你的工作时间,就越容易准备与你的可用时间相匹配的任务和反馈。
反馈
我经常会在项目进行期间或结束后征求反馈。自由职业者通常有改善流程或工作互动的宝贵想法,但有时只有在被直接询问后才会觉得可以分享。
我通常会问:
- 有没有什么改变能让工作更顺畅或更愉快?
- 有没有哪类工作是你希望多做一些或少做一些的?
截止日期
我很少需要紧急交付工作,因此通常会让你自行设定截止日期。你有责任在不需要我提醒的情况下按时完成。
不要让截止日期悄悄过去却不更新进展。如果你告诉我预计在美国东部时间周二下午 3 点交付,那么到了周二晚上我还没看到你的任何消息就会感到焦虑。我会猜想你是完全忘记了任务、需要从头开始,还是已经接近完成、几小时后就能交付。
如果你要错过截止日期,请告诉我。你越早提醒我进度会延迟越好。最迟也应该在截止日期当天告诉我延误。
一般来说,只要我能据此安排计划,延误并不是什么大问题。如果某个截止日期对我很重要,我会告诉你。
指定截止日期时,请使用精确、明确的时间表达:
- 还不错:我会在周五下班前发给你
- 更好:我会在 12 月 8 日美国东部时间下午 5 点前发给你。
- 不好:我会在接下来几天内准备好。
- 太含糊。
- 糟糕透顶:准备好后我会告诉你。
- 极其含糊
时间盒
在我们合作初期,我会要求你限制每周或每个里程碑的可计费工时。这样做是为了在了解你的开发速度以及我们是否适合合作的同时控制账单。
如果你接近工时上限却无法完成,请留出时间整理已经完成的工作。通过邮件发给我,并说明哪些已经完成、哪些尚未完成,以及你预计剩余工作需要多少小时。
超过约定工时上限的时间,我不会付费。
随着我们合作增多,我会提高或取消工时上限,让你拥有更多自主权。
文档
我非常重视文档。
如果项目有已记录的流程或 GitHub 模板,请遵循它们。如果文档要求你做的事情看起来不正确,请告诉我。不要自行假设说明已经过时或不适用于你。
当你开始参与我的某个项目时,你就成为其上手文档的新负责人。如果你因为文档写得不好或完全没有文档而遇到困难,请提交修改来补齐缺漏。
请认真记录你编写的代码。尽量让代码能够自我说明,但对于代码无法表达的信息,要加入源代码注释。新代码的注释详尽程度应大致与附近代码相同。
# Number of days per week (seven) <-- BAD comment
DAYS_PER_WEEK = 7
# This is a workaround for a bug in FooComponent, which crashes the process
# if we call it immediately after writing to disk. <-- GOOD comment
time.sleep(5)
代码质量
相比交付速度,我更看重质量和可维护性。
代码能够运行后,请寻找简化或重构逻辑、让代码更直观的机会。如果让代码简洁 30% 需要花两倍时间,对我来说这仍然是净收益。
代码评审
我会彻底评审所有代码变更,并提供详细反馈。
我的评论不是为了批评你或让你难受。我严格评审是为了理解代码,并将其调整到我可以长期维护的状态。
以下文章介绍了我的代码评审流程:
代码风格
我的项目遵循 Google 的代码风格指南:
在可能的情况下,我使用自动化工具强制执行代码风格约定。
Git
我使用 Git 进行源代码控制。只要你理解基本功能,就不需要成为 Git 专家:
- 克隆仓库
- 创建分支
- 进行提交
- 推送和拉取变更
- 变基提交(偶尔需要)
GitHub 权限
我按照最小权限原则分配访问权限。如果你参与的是我的公开仓库,可以直接 fork 它并开始提交 pull request,无需额外权限。
我使用两个需要令人恼火的广泛权限的 GitHub 集成:CircleCI 和 Reviewable。这两个应用都要求对你 GitHub 账户中的所有仓库拥有写入权限。如果你不放心授予这些权限,就需要为与你合作专门创建一个 GitHub 用户账户,以便授予这些工具完全访问权限。
提交规范
有些开发者认为每次提交都美好而神圣。我不是这样的人。
对我来说,main 分支拥有合理的提交历史很重要。在其他所有分支中,你可以随意提交。你可以针对每条代码评审意见进行一次提交,也可以在一次提交中处理所有意见。你偏好哪种工作流都没问题。我使用 GitHub 的压缩并合并功能,因此每个 pull request 最终都会合并为一次提交。
如果你提交的 pull request 包含许多次提交,我会阅读 pull request 的标题、说明和评论。我不会翻阅单独的提交,因为我假设它们代表你的中间工作。文章“How to Write a Git Commit Message(《如何编写 Git 提交信息》)”介绍了我偏好的贡献记录风格,只不过这里应用于 pull request,而不是单独的提交。
测试
创建 pull request 时,你有责任确保持续集成(continuous integration)中的所有测试都通过。在把代码发给我评审前,修复所有构建错误。
如果你添加了功能或以其他方式改变了行为,请更新自动化测试,以覆盖新的行为。
如果你修改的功能难以通过自动化测试,请手动测试该功能,以验证新代码。如果你找不到办法做到这一点,在提交评审时告诉我它尚未经过测试(这种情况应该极其罕见)。
可计费工时
我认为你为了与我合作而做的几乎所有事情都属于可计费工作。
可计费工作的示例
- 与我沟通(包括邮件、视频通话和面对面会议)
- 阅读我要求你阅读的文档(包括本文档)
- 研究与你工作相关的技术或方法
- 通过散步思考复杂问题
不可计费工作的示例
- 因为某本书与你的工作有关而从头到尾读完它
- 读一个章节没问题。
- 因为硬盘损坏而修理你的工作电脑
- 购买新的办公椅
费用
我希望你提供作为自由职业开发者开展工作所需的基本工具(例如电脑、网络和电力)。
任何能让你工作更高效或更愉快的软件、服务或设备费用,我都愿意支付。只需先和我确认。
如果我要求你购买与工作相关的物品,我会在你的下一张发票中报销。
监控
我相信你会如实申报工时。我永远不会要求你向我“证明”工时,也不会要求你在系统中安装任何监控软件。
如果我们使用 Upwork 这类内置监控功能的平台,我总会将监控功能设为可选。我不会查看监控数据,除非工时存在严重不符。即使出现这种情况,我也会先与你沟通,再检查数据。
进度更新
很难明确规定应多久分享一次更新,因为这需要一定程度的判断。
对于范围明确的任务,例如需求清晰的功能开发,每完成八到十个可计费小时更新一次。对于范围多变的任务,例如调查 bug 或需要进行实验的功能开发,目标是每完成两到四个可计费小时更新一次。两次状态更新之间的绝对最长间隔,应为三个日历日的可计费工作时间或 10 个可计费小时,以先到者为准。
分享状态更新的最佳方式,是提交能反映进展的 pull request。理想情况下,你可以将部分工作拆出,形成一个完整的 pull request;如果做不到,也可以分享一个 pull request,并将其标记为“draft”,表示仍在进行中。要在调查 bug 期间分享进展,请更新 GitHub issue,概括你调查了什么以及学到了什么。
如果你不希望在 GitHub 上广泛分享有关工作的元讨论,可以私下给我发邮件,但请尽量将讨论保留在 GitHub 上。
付款
请每两周就你的工时向我发送发票。发票开出后五个工作日内付款,通常会更早。
我不支付奖金或小费。我希望你的报酬透明明确,这样你不必猜测那些由我自行决定、没有明确规定的收入。
我会根据你的偏好,通过 PayPal、Payoneer、ACH 转账(仅限美国)或邮寄支票(仅限美国)付款。
合同结束后的工作
项目结束后,我绝不会因为询问你的工作或要求免费修改而联系你。确认你在合同约定的时间内交付我要求的一切,是我的责任。
如果我在向你付款后发现你的工作存在问题,我有责任自己修复,或为你提供额外的可计费工时。
税务
如果我每个日历年向你支付超过 600 美元,我需要你提供一些税务表格。
知识产权
如果我们合作的项目需要由我保留知识产权,我会向你发送一份合同供电子签名。合同声明我购买你为我编写代码的版权。
合同只涉及我付费让你制作的工作,不涉及你在为我工作的付费时间之外创作的任何内容。
封面插画:Loraine Yow(洛琳·尤)绘制。
你是客户还是自由职业者?我很想看看类似的文档,或听听其他人如何处理这个问题,欢迎在评论中分享。
随机一篇博客