需求

一个好的项目是从需求开始的。一个成功漂亮的需求分析-会让你拥有更多的潜在用户-但更重要的是紧急需求, 用户迫切需要你解决的实际问题-让他们知道你的产品能做到这些,他们才会不得不使用他。如果你能满足一个人的紧急需求,你最少也能得到一个固定客户;如果你能解决更多需求,那更没的说了。对于大多数人来说,优先解决一个人的需求(平常)再去解决更多需求,会更容易达成目标。
你能自我了解这个需求是很重要的。理想地,它是你在自己的经历上产生的需求。比如说,你可能会不顾一切地寻找另一个人去和你约会。次好的是,如果你能外出和尝试过一种会激发那种需求的生活方式。比如说,如果你很幸福地已婚了,你可能会尝试征询你的配偶的允许,因此你可以外出和不顾一切地寻找另一个人去和你约会。这不是完全一样,但至少有共同点。最起码,你应该坐下来看看那些有这个需求的人们并能够理解他们。去当你的单身朋友的照看者同时看着他们设法找个人。
当然,你的需求很古怪是可能的。有时候人们会很热衷于一个想法以至于他们将假装有对它的需求。你想去确认你在满足的是一个真实的需求。一个好的做法是确保你能找到至少一个陌生人,他和你一样强烈地感受到这个需求。
例子时间:我从事于一个给人们提供一系列有意思和有趣的东西去观看的网站。对于大多数办公室工作者,这是一个相当强烈的需求——办公室很无聊而且你真正能做的只是坐在电脑前看,所以你极度渴望观看有趣的事物来解闷。相比之下,我的朋友从事于一个允许你查阅各种正在发生在你周围的政府事物(新酒许可获得批准,人们被拘留,汽车被拖曳等等)。你可以想出许多关于为什么这是有趣的或者为什么人们可能想知道这类事的理由,不过这个网站没有满足真正强烈的需求。尽管我的朋友做得比我更好,但是我从事的这个网站变得比他的更受到广泛的欢迎。

想法

但是一个需求是不够的,你也需要一个想法去满足需求。客观地看一秒你的想法。它是否看起来像是真正满足需求?大多数糟糕的想法是差的是因为它们不真正满足需求。你想把需求进一步转换为想法,而不是从想法退化到某种理由。我提及的政府资料就遭受到这个问题,政府资料真的是很酷和提供了一些简单的搜索方法给人们,这让它看起来像一个真正好的想法。而且一旦你迷上了那个想法,就很容易提出它可能满足的需求。不过你只是在提出理由。这不是一个直接找出任何一个需求的方法。而且抓住一个需求总是比去满足两个的好。
这不是说一个想法不能解决多种需求。伟大的想法确实可以。他们能真正地解决多种需求。他们是对问题直接和明智的对策,而不仅仅是把不同需求硬塞去实现一个你已经喜欢的想法。
拿iPhone当例子吧。你可能会说“iPhone解决了什么需求?史蒂夫 乔布斯只是提出了一个真的很好和通用的想法,然后它正好有效地满足了各种需求”。不过那不是事实。当iPhone发布时,乔布斯宣传它满足了三个需求:它是一个宽频视频iPod,一个有活力的网络通讯器,和一个好玩的手机。拿这些其中似乎最不像iPhone的一条来说。什么会让你就需要去做一个伟大的宽屏视频iPod?哦,你会需要一个大的,宽的,占据整个设备的屏幕和一块能长久持续的电池。你也会需要某种输入机制,不过当屏幕占据了整个设备时你会怎么做呢?好吧,你不得不把屏幕做成输入设备。但是现在你有一块和你口袋里放着的电话差不多大小的砖块。你真的应该把它们结合起来。因此为什么不用触屏来为好玩的手机提供接口。而且既然你有了一个大的触屏和一个无线连接,不能用它来连接网络似乎显得很傻…然后你就回到了iPhone。即使史蒂夫 乔布斯不够优秀去推销一个不能满足真正需求的好想法。
一旦你有了一个基本的想法,你不需要去探究其中大量的细节。不过既然你是那种喜欢提出想法的有创意的人,不管这样你将会。你将会不断地提出各种酷的特性或者扩展或者用途和摆设。这些不是重要的,这意味着他们会使你分心除非你对它们做些什么。所以把他们放到一个Lenin Document。一个Lenin Document就仅仅是关于你大多数想法的样子的描述,从主要的特性(它能够打电话)开始和进而完成更模糊的部分(它会有一个应用程序,让你从床上就可以控制烤箱)。
你可能将不再看这个文档,不过你和你的同事提出的好想法不会再困扰你,一旦你有一个安全的地方去把它们写下来。

招聘

哦,等一下,什么同事?你也会需要组一个队。当雇用某人时,你想去问三个关键问题:

  • 他们聪明吗?
  • 他们能完成事情吗?
  • 你能和他们工作吗?

在这些问题上很容易克扣,例如雇用某个满足三个条件中两个的人。不过这是一个大的错误。一些聪明但不能把事情完成的人应该做你的朋友,不是你的雇员。即使你不能雇用他们,你仍然可以在他们因现有工作而耽搁的时候和他们讨论你的问题。一些把事情完成但不聪明的人是效率低的:不聪明的人经常用困难的方式来做事而聪明的人不能忍受观看他们这么做而且会从他们真正的工作中抽出时间来帮忙。一些你不能与之共事的人,你真的不能和他们一起工作。很容易地会听到“好吧,这仅仅是工作,我们不用做朋友”,不过当工作是困难的而且如果你不觉得自己可以与同事真诚地交流,那么他们会做错事并且你不去纠正他们,结果他们仅仅是坐在角落里而没做有用的事。
传统的程序员招聘过程包括:a)阅读简历,b)在电话上问一些难题,还有c)当面给他们出程序题。我认为这是一个糟糕的招聘体制。你从简历只能了解非常少而且在面试中当你问应试者难题时,他们真的很紧张。编程不是一类在压力下的工作,所以观察应试者紧张时的表现是相当没用的。而且被问的面试问题似乎是专挑那些令人抓狂的。有多少问这些问题的人真的能在他们第一次听到的时候回答上来呢?
相反地,仅仅试着去回答上面的三个问题。去找出是否他们能把事情做好,问他们做了什么。如果某人真的能做好事情,他们到现在应该做了一些事。如果某人真的擅长做事,他们不会一直避开它。没有先前的经验是很难当一个好的程序员而且现在任何人可以通过发起或参与一个自由软件项目的方式来获得一些经验。所以只要要求一些代码例子和一个演示,看看它是否看起来优秀。你真的很快地了解了许多,因为你不是看着他们回答一个不自然的面试问题,你看的是他们实际的作品代码。是否简洁,整齐,讲究的,有用的?有没有你的产品要的东西?
去考察一个人是否聪明,只需和他闲谈一下。尽你所能去消除压力:在咖啡馆见面,表明这不是一个面试,尽量显得自然和友善。任何情况下你都不应该问他们任何标准的“面试问题”—仅仅是像你在聚会上和某人谈话那样和他们交流。(如果你在聚会上让人们说出他们的优缺点或者去评估在芝加哥的钢琴调音师的数量,你会有更大的麻烦。)在闲谈中很容易看出一个人是否聪明。我们经常对我们遇到的人是否聪明做决定,就像我们经常能判断我们看到的人是否有吸引力。
不过如果你仍然不是很确定,就看三个方面。首先,他们懂吗?问他们思考过什么并对此探查他们。他们显得在细节上理解吗?他们能清楚地解释它吗?(清楚的解释是真正理解的一个特征)他们知道些关于项目的你所不知道的东西吗?其次,他们是否有求知欲?他们通过问些关于你的问题来回应你吗?他们真的感兴趣或者仅仅出于礼貌?他们问了关于你所说的进一步的问题吗?他们的问题让你思考吗?第三,他们是否学习?在对话的有些时候,你可能会给他们解释一些东西。他们真的理解它了吗或者他们仅仅是点头和微笑呢?有些人懂一些小领域的事物但不关心其它的。而且有些人有求知欲但不肯学习,他们问了很多问题但没有用心听。你需要能满足以上所有三点的人。
最后,你可以跟他们出去聚聚来断定你是否可以跟他们共事。许多聪明人可以再一个小时的交谈里表现的很愉快,但是几个小时以后,他们的一些怪癖就会被放大。所以,在你们聊完天以后,你可以邀请他们和团队里的其他人一起吃个饭或者在办公室里打个游戏。再说一次,尽可能的自然随便一点。关键就是看他们是否会让你心烦。
如果他们都看起来不错,而你只打算雇佣其中几个,做最后一轮检测确保你没有被忽悠:让他们做一部分工作。通常这意味着拿一些你需要的小的并且独立的部分让他们写。(如果你坚持要看别人顶着压力工作,那就给他们一个最后期限)。如果需要,你可以给他们提供一点酬劳,但是绝大多数的程序员并不介意被给予像这样的小任务,只要他们做的这些东西是开源的就行。这个测试本身并不起作用,但是如果有些人通过了前三个部分,那么这个测试就足以用来证明他们没有忽悠你,他们真的可以做他们所说的工作。
现在更倾向于说“好的,我们何不试着让你来做一个月看看怎么样呢”,其实这并没有用。首先,这会使你的雇员如履薄冰,总是想着去提高自己,这很残忍并且达不到理想效果(压力和恐惧会让他们更低产)。其次,如果在一个小项目结束后你不能保证说不,那么一个月后你同样做不到,结果你就招了个不够理想的人。还不如直接说不好招更好的人。

假定

现在,你有一个团队,是时候做点实事了。虽然立即俯下身来建设梦想(包括你所自豪的事情)的想法的确诱人。但那是一种巨大的浪费。没人喜欢在多余的事情上浪费时间,你会想要做的更少些。现在有了。
工作中的每一个创意都依赖于对世界的某种假定;如果假定不正确,创意就不会成功。譬如你在航空公司工作,你知道人们讨厌排队登机。你的解决方法是:我们可以在检票时出售一份价值 5 美元的“提前登机”票,以便他们提前登机。这个创意依赖于下面几个假定:

  • 我们的乘客希望提前登机。
  • 我们的乘客愿意为此支付 5 美元。
  • 我们的乘客愿意在检票的时候这样做。
  • 但又没有太多的人愿意买它,他们都在排队等候。
  • 等等

你会想写出这些假设,并挑选出最重要的。比如说,“客户希望尽早登机”是最重要的。现在请牢记,如果这个假设是错误的,我们之前做的所有工作将会是徒劳。因此,在假设被证实之前,不要投入太多精力。
那么,检验的最低限度是什么呢?对此的原生术语,即最小可行量或MVP,然而它已经成为了一个时髦词,被不真正了解它的人所曲解。大多数人会说这一想法的最小可行量是一个切实的主干系统,只需让你在检查时多付5美元,或许会在你的登记证上标记一下,然后通知检票员让有标记的乘客先登机。很简单,不是吗?
也许是,但还有比它更简单的方法。检测这个假定最精确简单的方法就是支付页面增加一个“点击这里提前登机”的按钮。当有人点击时,弹出一条“对不起,该‘提前登机’的程序无法使用”的错误提示。之后你就可以测算有多少人点击了该按钮。如果有很多人点击它,那么就知道人们是希望提前登机的。如果没有人点击它,那么说明人们对这个产品没有需求。
但是多少点击量算多呢?可以拿出实际的数据作为参考。“哇,有一千人点击了该按钮”,你说。“真多啊!这是使用豪华包监测服务人数的十倍!”
“不,不是的”,跟你抬杠的同事反驳道,“太少人用了,使用终端机服务的人比这个还要多一倍。”
为了避免这种争论,你可以事先从那个同事认可的数字里选一个来作衡量。你们两个必须统一商量好,如果结果数字比选定数字大,那么之前的假设成立;否则不成立。
但是,你应该怎么来作统计呢?总不能真的去地数点击按钮的次数吧。这种情况下可以使用虚荣(虚假?)度量。假设实际上100人中只有1个人想提前登机。大家都知道,圣诞节的时候,坐飞机的人是平时的3倍。如果你选择在这时进行测试,那么你的按钮点击次数可以轻易地达到2000人次的目标。这不是由于这个按钮真的很有用,只是由于圣诞节前后太多人坐飞机而已。
其实,你真正应该采用的是,创新度量。这种统计得出的数字,只与你感兴趣的方面有关,其它的东西都不会对结果有影响。就上面所说的例子,我们只统计点击按钮的人数的百分比。假设有3%的人点击了按钮。这个百分比不会因为旅客突然大量增加而改变。
当然,这个百分比反而有可能下降。因为圣诞节的旅客比较匆忙,无暇顾及其他。所以你要相应地调整你的预期目标为:3%常规旅客会点击按钮。这样,即使旅客突然激增,这个统计也比较稳定。
你甚至可以圈定群体来帮助统计。一个群体是指一组事先选定的人。例如,你可以事先选定一组常规旅客,只有他们可以看到按钮。这样的话,突然激增的旅客就不会影响你的统计了,他们都看不到按钮,因为他们并不是你圈定的群体。
另外,你也可以进行类比统计。可能多加一个按钮会使人们更加不想购买升舱服务(可能很贵)。将你事先圈定的群体随机分成人数相等的两份。其中一份可以看到按钮,另一份看不到。对比这两份人的统计,你就可以看到添加按钮是否有影响。如果实验中只有4%旅客购买升舱服务,但是你圈定的群体中有8%购买了,那么你就要考虑将这个差异纳入到将来的计划了。

团队

一旦你确立了一个假设,并用最小可行的方法来验证它,一套明确的度量标准类证明它,是时候去实际践行它的时候了。应该从一名产品负责人开始。他们是你的产品的“乔布斯”-他们会为了保证整个产品的完整性而重新对每一个细节进行授权并签发许可。
你最好写一张卡片(3X5大小或者像Asana这样的列表式任务管理系统),用来描述你的目的与你将用来证明它的度量。

“挑选一帮经常访港的家伙,将他们分为实验组和对照组”。 当我准备登机检票的时候,我能看到这样一个按钮,能提供给我一次让我尽早登机机会的按钮,如果我点击了它,我就会收到一条表明该服务当前无法使用的错误提示信息。 这证明了我们的顾客想尽早登机的假设。我们认为该假设表明实验组有超过2%的人点击了有可能能让自己尽早登机的按钮。我们同时也监测了他们购买的其他升级,他们为了保证推广该功能而不会引起严重的广告效应的登机完成率。

第一段提到了被实验的对象。第二段讲述了一个关于改变用户生活经历的故事。第三段解释了我们为什么进行实验以及我们寻找的尺度是什么。
这些都涉及到一堆(或者是在线To List)按照优先级排序的卡片,并把最重要的需要验证的假设放在最前面。你的设计师们,当他们在做他们当前的任务的时候,将从一堆卡片中摘取最靠前的卡片。他们将与产品负责人一起设计,看起来就像(按钮放在哪?到底要要怎么表达?)。一旦产品负责人认可了相关设计并签了字,设计师们将会亲自把卡片交给程序设计人员,同时和他们一起工作以实现该设计。
从实施或实际使用的经验所带来的实际问题,一旦实施完成,就会导致花费大量的时间进行重新设计,或许这样反复修改能给产品负责人带来更多的反馈建议。

开发

当你着手开发的时候为你的软件编写自动化测试是一项很好的实践,这样在之后未通过(部分测试)时就很容易知道(是哪里出的问题)。你觉得自己搞定的时候就可以运行测试以确保它们全部通过,当然,你得保证测试能同时覆盖到那些有把握的和所有实验性的功能点。
编码是一项费神的活儿,所以找个人来做结对编程通常更加有效:一个码代码,一个边看变指点(一个人写测试然后把键盘甩给另一个人写代码让测试通过有时也蛮有趣的)。
如果你一直找不到人跟你结对,那么至少得保证你能拉一个人过来评估下你做的变更。在往工程里提交代码之前,你应该 总是 看看diff (比如说运行 git diff HEAD)。

架构

如果你正在开发一项网络服务(比如Web应用),就应该按照应用开发十二要素来设计。满足这十二要素的应用程序遵循以下12条原则:

  1. 将整个应用的代码存储在唯一的版本控制库里。如果软件的不同部分由不同的版本库控制,那么你应该把它们当作不同的应用,其间无为服务。如果多个应用共用一个版本库,那么你应该找到它们的相同依赖项,将其放入各自的代码库里。
  2. 你可以使用Git,因为它是目前最流行功能最丰富的版本控制系统。
  3. 明确声明所有依赖项。如Ruby 里可以使用Gemfile,Python 使用requirements.txt,等等。本地的话你可以使用类似Bundler或VirtualEnv这样工具隔离开发环境以确保未使用未声明的依赖。
  4. 所有配置值应当作环境变量存储。这包括任何不宜公开的信息:密码、密钥以及所有因部署而有所不同的内容(包括数据库地址和管理员Email)。
  5. 所有后端系统 (如数据库或内存缓存( in-memory caches)) 皆视为服务。本地与第三方服务之间不做区别,它们都通过网络访问。
  6. 代码部署分三个独立阶段:构建(编译构建软件);发布(加入环境配置并放到服务器上);运行(执行应用)。这几个步骤应该完全独立:服务器不能在运行时改变其配置,因为发布阶段已经完成;发布阶段不能编辑软件,因为此时构建阶段已经结束。
  7. 应用应该作为一系列无共享状态的进程执行,任何进程可以在任何时候被干掉。也就是说所有状态都应该存储在后端服务中。
  8. 应用应该完全独立,只通过IP 端口(通过设置$PORT)与外界通信,而不应寄存于某些大进程中。
  9. 应用应该由各种不同进程类型组成,并可以通过启动新实例扩展。例如,当web 堵塞时,你可以通过开启更多的web类型进程来搞定。
  10. 进程应该是可任意使用的,你可以在任何时候启动或停止它,而不用担心任何破坏。
  11. 开发和产品间的隔阂应该尽可能地的小——相同的支持服务、依赖、团队应该在两处都被使用。
  12. 日志应该是无缓冲写入标准输出(stdout)的事件流。不要由应用负责日志的位置,那是基础设备该干的活儿。
  13. 管理任务应该当做是一次性的进程。

你应该使用“12-要素”主机系统,如Heroku,因为它可以强制遵守这些约束。
您还应该 引入”Chaos Monkey”来 进一步确保 您的系统 的 稳健性,”Chaos Monkey”是一个自动化的过程,去激活一个系统的不同元素,以确保它们是健壮的响应中断。例如:进程的是一次性的,”Chaos Monkey”会自动杀死一个随机的生产过程,这能避免开发人员依赖持续性的进程,如果他们犯了一个错误,并且一直没有发现,早期捕捉这个错误则能避免这个错误以及错误引发的其他衍生物最终导致的灾难性的结果

部署

软件设计师一旦提交他们的代码到版本控制库中,那么他们所有的测试都将顺利通过。
如果他们要求改变后端服务的代码(如数据库模式更改),这可以通过迁移做到。一个迁移能改变它如何制作和回滚。当部署一个新的软件版本时,运行任一未运行的迁移模式。同步的代码版本依赖于其后备服务。在回滚之上,迁移同时又被回滚。这意味着后备服务与代码总是同步的。
几乎所有的新代码都是致力于开发的主线的(又名主干或HEAD)。这就避免了不同的开发分支合并后的痛苦。因为任何大的变化都应作为一个实验来实现,如果一个变化没有完成或者没有准备好,就很容易被大多数实验外的用户关闭。如果代码准备好了,则更多的人可以加入到实验组而这种拴牢最终将被删除。
一旦 提交 到版本库,版本 库就会 自动 建立 , 释放, 并 在一个新的 测试环境 中 运行这些 代码并 自动测试它们 。 然后,就应该 尝试 运行代码,并 迁移 对 生产 支持 服务 的完整副本 (read: 数据库) , 尝试通过运用 和回滚 的迁移这两种方式确保测试通过。
如果它们全部都通过了,它就应该发布出来。为了确保一些莫名其妙地通过了测试的断码不发布出来,你应该有一个免疫系统去监控部署。系统会查看你的主要创新指标(寻找新的收益,新的用户等等),以确保他们没有受到不利影响的部署。如果是这样,它会自动回滚,并提醒团队。
为了确保 还没有被产品所有者 审查的代码不发布 出来 ,你应该给它们着手 控制 实验 。 新功能应该在 最初时没有任何人的实验中 投入生产 。 产品所有者 可以 添加 自己 的实验 , 或 把 实验放在预览服务器让 每个人 来测试 它 。 QAs 也可以测试 。 当所有人都 快乐了 ,就会有越来越多的人 加入到 实验中 。 如果 指标看起来很棒 ,甚至 可以 增加更多 ,直到 最终 100 %的用户都参与到 实验里来 和有控制 可以 从 代码库 中 删除的力量 。

发布

有些人会鼓励你举行一个大的如同好莱坞式的发布会,在软件推出的几个月前就开始大肆宣传发布日期。 这种方式也许在好莱坞很好用——如果你的电影在首映周票房高唱,影院心甘情愿的多放映几周,且你的电影被誉为“本周最佳影片”。但对于软件开发者,这是极其荒谬的。你的软件并非在影院发布,它发布在互联网上。你的软件不比担心被影院展示一周就下架。你可以年年推送,培养用户群。
一场盛大发布会的问题在于,除非你是完美的,发布当天总会出现一些你忽视掉的 BUGs 和概念错误。现在,数以百万计的人正在访问你的产品,体验这些错误。(也许你的错误时没有适时的加载和测试服务器,导致网站宕机。)
相反的,你应该视你的发布会为另一场实验,并在表现良好的时候缓慢增加允许访问的用户数量。学习 Gmail 的例子:邀请极少的人,针对他们的使用和反馈测试你的设定,当他们开始喜欢上的时候,允许他们邀请另一些人加入。慢慢增加人数,直到所有期待邀请的人都已被邀请,整个世界都将是你的试验场。
祝你好运!

致谢

此文 最初是由Aaron Swartz写的,是他和其他人 很多不同的想法的组合 。 需求和想法的讨论可能受到Paul Graham 的影响 。招聘 是改编自Aaron 的我如何雇佣程序员,这涉及到 Joel Spolsky的 作品 ( 他的书 被称为聪明地把事情办好 ) 。 假定是 改编自精益创业 和丰田 生产系统 。 团队和开发 是基于 极限编程 的 想法 。 架构 明显是基于 12-要素的应用 。The Chaos Monkey 是来自于Netflix 。 从Rails 迁移 是一个长期的过程 。 部署 通过 蒂莫西· 菲茨来自IMVU的 连续性 免疫系统 。 发布的部分 是改编自如何启动软件