This commit is contained in:
louzefeng
2024-07-09 18:38:56 +00:00
parent 8bafaef34d
commit bf99793fd0
6071 changed files with 1017944 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
<audio id="audio" title="09 | 为什么软件工程项目普遍不重视可行性分析?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/b1/cf/b1fd96720d7bc20f8457181d994f72cf.mp3"></audio>
你好,我是宝玉,我今天分享的主题是:可行性研究, 一个从一开始就注定失败的跨平台项目。借此来与你一起讨论,为什么软件工程项目普遍不重视可行性分析。
如果你随手拿起本软件工程教材翻翻,第一章一般都是讲“可行性研究”的,呈现顺序仅次于“绪论”,可见其重要性。
“可行性研究”通常讲的是如何科学地论证项目的可行性,以及这个项目是不是值得做。这个知识点比较简单,落实到期末考试的题目上,一般只是一道像这样的选择题或填空题:
>
“可行性研究主要从哪几个方面进行?”
这个题目要回答的话也不难,记住答案即可。
>
对于软件项目的可行性研究,主要从以下几个方面入手:
<ol>
- 经济可行性;
- 技术可行性;
- 社会可行性。
</ol>
看上去这么简单的知识点,到底重要在哪里呢?我们先来看一个真实的案例。
2015年的时候Facebook推出了一个跨平台的移动端解决方案React Native只要用JavaScript一门语言就可以将写好的代码运行于iOS、Android移动平台。
所以在2016年的时候某著名大型互联网公司的移动部门负责人非常看好这个技术专门成立了项目组用了不少人力花了大半年时间将移动端iOS、Android产品迁移到React Native技术框架上。
就在项目快要上线的时候法务部门却发现React Native的开源许可协议是“BSD+专利”。那这个“BSD+专利”的许可协议是什么呢?
BSD 的许可协议本身是开放的、没有限制的,但 Facebook 在此基础增加了一个“专利”协议。也就是说如果对Facebook及其子公司提出专利诉讼不管诉讼的项目是否与该协议有关用户的所有专利权利也都会自动终止。
也就是说,如果未来该公司因为专利问题与 Facebook 产生纠纷,那么该公司将会无条件输了官司。
而目前该公司和Facebook是有竞争关系的所以法务部门为了避免未来可能的纠纷不得不叫停这个项目。而此时他们在这个项目上投入的大量人力财力相当于全打水漂了。
即使后来2018年的时候Facebook把React Native的开源协议修改为友好的MIT协议也为时晚矣。
你看,如果在立项之前,就让法务部门帮助评估一下社会可行性(具体到这里,也就是法律方面的可行性),该公司就可以避免很大一笔损失。
类似的案例其实不在少数。许多公司老板或者部门负责人不是很懂技术,天马行空想到一个点子,或者看到某个热门技术(比如说团购、共享经济、人工智能、区块链),不做可行性研究就直接立项去做,耗费了不少人力、物力和时间成本不说,最后项目也不得不以失败告终。
## 为什么软件项目很少做可行性研究?
可行性研究不是软件项目的专利,在很多其他工程领域,项目正式启动前,都会有可行性研究这一环节,而且一般都会请一家甚至多家专业的评估机构帮助做可行性分析,并出具可行性研究报告,然后项目方来决定是不是立项。
拿建筑工程来说,你要在某条街上盖房子,却不做可行性研究,那么如果这条街两年后要拆迁,那就意味着你的房子也会面临被拆掉的命运,那损失就大了。
为什么在软件工程领域,可行性研究就不是很灵了?如果你也经历过或者听说过一些失败的软件项目,不知道你有没有想过,为什么这些软件项目很少有做可行性研究的?如果你有机会就这个问题去做一下调查,很可能会得到下面这些答案。
**1. “因为我们是软件项目,所以我们很特殊。”**
“我们很特殊”,这句话听着有没有很熟悉?软件项目确实有和其他工程项目不一样的地方。
比如说软件项目很抽象,以至于在立项之前对于问题的描述(需求)和解决方案(技术方案)通常都是模糊不清的,只有随着项目的推进,才能逐步搞清楚需求。
而可行性研究是基于问题和解决方案来分析的,因此这有点像“先有鸡还是先有蛋”的问题:你得先立项才能慢慢搞明白需求是什么,然后才能有解决方案;而你只有搞明白需求是什么,以及解决方案是什么,才能去做可行性研究。
但“我们很特殊”,不能成为不做可行性分析的借口,可能项目需求最开始是模糊不清的,还不具备可行性研究的条件,那么等到项目有了一定的进展,需求逐步明确后,要继续对可行性做研究。
**如果发现方案不具备可行性,也应及时调整方案或停止项目以止损。**
**2.“老板拍板的项目,明知道不可行也得硬着头皮干呀!”**
这个问题要分类讨论,有两种情况。
第一种情况,多半是由于老板或者项目负责人控制决策权,且对于不同意见容忍度较低。底下人不敢提不同意见,明知道不对也只能执行。
如果你是项目执行人员,不能参与决策,但觉得项目明显不可行,我仍然建议你尽可能站在专业的角度给出科学的分析,通过合理的方式反馈意见。毕竟,项目如果失败了,你也一样可能遭受损失。
如果你就是老板或者项目负责人,则应该建立可行性研究的意识,并理性听取不同意见,科学客观地进行可行性分析,以便有效降低项目失败概率。
第二种情况,老板或者项目负责人能接触到的信息更多、更全面,同时还有战略上的一些考虑,所以下面执行的人觉得不靠谱,并不代表真的不靠谱。
举个例子2009年阿里巴巴决定做阿里云的时候公司反对者占绝大多数只有马云和王坚等少数人觉得这个项目可行而且必须做。最后事实证明他们是对的。
所以有时候,也不要着急下结论,可以换个角度思考下,也许是你因为条件限制还没想清楚。
**3.“软件项目是鼓励创新、鼓励试错的,可行性研究会阻碍创新!”**
这也是一种很典型的错误观点,认为创新就可以不做可行性研究,否则会阻碍创新。实际上可行性研究和创新从来就不是矛盾的,它反而可以帮助你提前过滤掉那些不靠谱的创新想法,提前发现可能的风险。
想一想文章开头关于React Native开源协议冲突的案例虽然是一个创新性的项目却未绕过开源协议引起的法律纠纷。如果当初有法律方面的可行性研究完全可以改用开源协议更友好的同类开源技术避免项目的失败。
## 如何做好可行性研究?
前面,我们讲了可行性研究在软件工程中的重要性,也帮你厘清了几个常见的困惑,接下来我们来看看“如何做”的问题。
其实,**当你决定要做可行性研究,你就已经成功一半了,怎么做反而是相对简单的部分!**
软件工程的教材里面,通常会讲如何写可行性研究报告,很繁琐,要撰写诸如引言、背景、定义等内容。在这里,我们关注的重点是,软件工程中是如何去做可行性研究的。如文章开头所说的,通常从三个方面着手做:
- **经济可行性。**从成本和收益角度分析,看投入产出比。不仅要分析短期利益,还要分析长期利益,看是不是值得做。
- **技术可行性。**软件项目最终是需要人通过技术来实现的,所以要分析技术上是不是可行,如果有技术上解决不了的问题又能否规避。
- **社会可行性。**社会可行性涉及法律、道德、社会影响等社会因素。比如,触犯国家法律的事情肯定不能做;产品如若不符合道德标准,可能带来较大的社会负面影响,那么也要慎重考虑。
仍然以文章开头提到的React Native项目为例我们从这三个方面出发来做一个简单的可行性研究。
先来看看经济可行性。按照投入成本和收益估算,我们在此仅做一些简单假设:
- 这个项目要投入10个人每个人的人力成本预计是10000元/月,预计要花半年时间上线;
- 每个人在项目实施过程中所需要的硬件和软件成本预计在1000元/月;
- 每年该部门预计完成10个项目每个项目收益预计1000000元
- 该项目导致2个项目延期半年
- 该项目预计可以节约项目成本所以每个项目收益可以提高50000元
- 该项目可以让部门每年完成的项目提升到12个。
预计投入1660000元/半年投入使用后每年可以产生约2600000元的收益不到一年可以收回成本。
<img src="https://static001.geekbang.org/resource/image/ff/e9/ffcf64bafc95994c75db0b26e91179e9.png" alt="">
以前我写程序的时候并没有多少成本意识,觉得就改改代码而已,后来发现真要把工资和用的时间算一下,其实成本还是不低的。
就像上面这样一个10个人的项目半年下来就要花一百多万。当然如果项目成功的话不到一年就可以收回成本而且后面还会持续创造价值。所以从经济可行性分析还是可行的。
然后再来看看技术可行性。
- 从技术本身来说,经过一年多的发展,技术已经成熟稳定,并且已经有了几个成功案例。
- 从人员储备来说部门已经有5名成员有React Native项目经验其他人员可以通过3个月左右的培训上手。
- 从风险角度看,部分老的安卓机型无法支持,但是这部分机型占有率非常低,可以不予考虑。另外,部分视频组件需要自己实现,技术上可行,需要把这部分的开发任务放入项目计划中。
<img src="https://static001.geekbang.org/resource/image/8f/5d/8ff84a8cd3c2ac358d7b64d51296425d.png" alt="">
技术可行不可行,关键还是在人。就算技术成熟,如果短时间内找不到人来做,也是有很大风险的。同时也要评估可能存在的技术风险,像本例中的设备兼容问题,如果不兼容设备很多,那技术就不可行了。
像这个项目,已经有一定的人才储备,不会成为技术上的瓶颈,另外不支持的设备只占极少数,可以忽略不计,所以总体上技术还是可行的。
最后再来看看社会可行性。
- 道德可行性是没有问题的,不会有任何不良道德行为。
- 社会影响方面,也没有负面影响。
- 法律可行性上项目本身不违反国家法律法规。版权上React Native采用BSD+专利开源协议,存在法律风险!
<img src="https://static001.geekbang.org/resource/image/c6/75/c6c533c98fad3ba2f9b4dfa4691b5c75.png" alt="">
至此,我们可以得出结论,这个项目从经济可行性和技术可行性上来说,都没问题,但是社会可行性方面存在很大风险。于是,接下来我们和公司法务部门进一步沟通,确认并达成一致,最好的结果是暂时冻结该项目。
就这样,我们通过项目启动前的可行性研究,及时冻结项目,为公司避免了人力、物力和时间上的浪费。而且,这样一来,我们还有了及时寻找其他解决方案的时间和机会。
## 总结
可行性研究是项目启动前很关键的一步,可能最早帮你发现风险,甚至避免损失,千万要重视起来。就如我前面所说的:
>
哪怕你做的可行性研究不能改变决策,最后项目结束的时候,和当初做的可行性研究做一下对比,也都是非常宝贵的项目经验积累。
结合《[工程思维:把每件事都当作一个项目来推进](http://time.geekbang.org/column/article/83277)》一文的内容,我建议你把每件事都当作一个项目来看,因此每次决定做一件事前,不妨先做一个“可行性研究”。
<li>
比如说,你打算要做一个功能模块的性能优化,不妨先列一下成本和收益(经济可行性),看看你投入的时间精力,再看看最终带来的性能提升效果,来判断下是不是值得做。
</li>
<li>
比如说,你要换工作,那就列一下你工资提升带来的收益(经济可行性)。最好换算成时薪,看看长期是不是真的更合算,因为有时候虽然工资多了一点,但加班太多反而得不偿失。
</li>
最重要的,你要关注一下法律上的风险(社会可行性),想一想你有没有签竞业协议,新工作会不会因违反竞业协议给你带来巨额赔偿问题。
最后,我想给你一个小建议:**如果可行性研究并不能给你一个很明确的结果,也可以考虑小范围试点,先实现一个最小化可行产品,等验证了可行性,再逐步加大投入。**
## 课后思考
除了本文列出的几个,你觉得还有哪些原因导致了可行性研究形同虚设?你身边有没有关于可行性研究的案例,以及你是怎么做可行性研究的?欢迎你在留言区留言,和我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,173 @@
<audio id="audio" title="10 | 如果你想技术转管理,先来试试管好一个项目" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/87/ff/87af147a0fa36fb68ebdced9706ca9ff.mp3"></audio>
你好,我是宝玉,我今天与你分享的主题是:如果你想技术转管理,先来试试管好一个项目。
技术转管理,是很多技术人员的梦想,所以经常有人问我,怎么样才能转型管理?
项目管理,是最基础的管理,既要管理一个项目,又要协调整个团队一起,完成共同的目标。
我的管理转型就是从项目管理开始的,在从技术转型项目管理的过程中,让我从以前专注于局部技术实现,逐步转向关注项目整体;从个人的单打独斗,到借助整个团队的力量一起完成一个项目。
一直到后来做开发总监要去管理整个开发部门,发现还是一样绕不开要管理项目,只是从直接管项目变成了间接管项目而已。
所以我一般会建议:如果你想技术转管理,先试试管好一个项目。项目管理通常是技术人员转型管理的第一步,也是非常关键的一步!
## 技术人员转型管理的障碍是什么?
很多人认为技术人员是不适合做管理的,包括网上也有很多对程序员的刻板印象,比如说:极客、木纳、不善交际、头发少、穿格子衫……
而我了解的程序员却不是这样子的,他们都很聪明,学习能力强,而情商这些其实和其他职业群体是没有区别的。
那么为什么程序员会给人这种刻板印象呢?
一方面原因是这个群体勇于自黑,不介意这些印象;另一方面则是他们过于专注技术实现,沉浸于细节中,而忽视了其他事情。
程序员总是想着如何技术实现、用什么语言框架、怎么提高效率……要钻研技术,这些是非常好的优点,但是要转管理,这反而会是一种障碍。
**因为管理,最重要的一点就是大局观,要能从整个项目的角度,从整个团队的角度去思考,去确定方向,去发现问题,对问题及时解决及时调整。**
但是当你把注意力都放在技术细节上,就容易忽视其他事情,例如和其他人之间的沟通、不关心当前项目进展。
就像有人说的:
>
<p>关注细节的,是工程师;<br>
关注过程的,是项目经理;<br>
关注结果的,是老板。</p>
所以,如果你要技术转管理,可以先从管好一个项目开始。这也是为什么我在专栏一开始,就建议你要逐步转变思维,从技术思维到工程思维,不要仅仅局限于自己负责的那一个小模块,而是要多从项目的整体去思考。
## 怎么样去管理一个软件项目?
软件项目管理涉及知识不少,既有传统的项目管理知识,又需要掌握软件工程的知识,所以很多人一谈到项目管理就觉得很难很复杂。
我在专栏中一直强调“道、术、器”,对于很多知识,如果我们能总结出其中的“道”,再去看很多问题,其实就没那么复杂了。
**就软件项目管理来说,“道”就是管好人、管好事。**如果从这两个维度去看如何管理项目,就会发现其实并不难,有很多“术”可以为我们所用。
#### 怎样管好软件项目中的人?
软件项目管理的一个维度是管人。项目管理中的人,主要涉及两类:客户和项目成员。
**1.管理好客户的预期**
客户,就是会使用你软件产品的人,通常也是给你项目出钱的人。
对于客户的管理,就是对于客户期望值的管理,如果你项目的结果高于客户的期望,那么就可以说你的项目就是成功的,如果没有达到客户的期望,可能就是不成功的。
想要满足客户预期,通常来说,就是你能在项目的质量、范围、时间和成本上达到要求。
- 质量达标:交付产品是高质量的,满足客户需求的。
- 完整交付:按照约定的功能范围交付最终产品。
- 按时交付:项目按照客户认可的进度完成。
- 预算之内:在预算内完成项目。
这四个要素,并不是说必须都要满足,其实很多时候是可以协商的,重点是要达到一个平衡,怎么达到平衡?具体你可以参考《[08 | 怎样平衡软件质量与时间成本范围的关系?](http://time.geekbang.org/column/article/85302)》,我已经在这篇文章中进行了详细的解答。
**2.用流程和规范让项目成员一起紧密协作**
项目成员,也就是帮助你一起完成项目的人。
对于项目成员的管理,不需要过多依赖人的管理,否则项目经理就会成为项目管理的瓶颈。所以更多要落实到流程和工具上。
**好的项目管理,不需要直接去管人,而是管理好流程规范;项目成员不需要按照项目经理的指令做事,而是遵循流程规范。**
合适的项目管理工具,也可以简化流程,保障流程的执行,提高效率。
关于具体怎样制定流程规范,我会后续更新的文章《[12 | 流程和规范:红绿灯不是约束,而是用来提高效率](https://time.geekbang.org/column/article/87129)》中有更多介绍。
关于项目管理的工具,也会在《[14 | 项目管理工具:一切管理问题,都应思考能否通过工具解决](https://time.geekbang.org/column/article/87787)》中有详细介绍。另外,你也可以先参考我在《[06 | 大厂都是如何应用敏捷开发的?(上)](http://time.geekbang.org/column/article/84652)》中提到的部分案例。
## 怎样管好软件项目中的事?
软件项目管理的另一个维度就是管事。软件项目中的事,是指要完成项目目标,在整个开发过程中所产生的一系列任务。对项目中事情的管理,本质上就是对软件开发过程的管理。
**1.选择适合项目的开发模式**<br>
软件项目的过程管理,和其他工程项目完全不一样,有其独特性,好在软件工程对这些过程的开发模式都已经有了很好的总结,我们直接借用就可以了。
选择好开发模式,才好确定后续的一系列问题,例如流程规范、使用什么工具,如何制定项目计划等。
所以对软件项目过程的管理,首先就是要根据项目特点选取合适的开发模式,是敏捷开发还是瀑布模型或者瀑布模型的衍生模型?是一步到位还是逐步迭代?
对于开发模式的选择,可以参考《[03 | 瀑布模型:像工厂流水线一样把软件开发分层化](http://time.geekbang.org/column/article/83598)》《[04 | 瀑布模型之外,还有哪些开发模型?](http://time.geekbang.org/column/article/84054)》和《[05 | 敏捷开发到底是想解决什么问题?](http://time.geekbang.org/column/article/84351)》的内容。
当然,开发模式选好了后,还需要配套的流程规范,以及合适的工具,以保障开发模式的执行。
**2.制定好项目计划**
凡事预则立不预则废,在选择好开发模式后,紧接着就是要做好项目计划,有了项目计划,才能有计划有目的地去推动项目进展,出现问题也能及时发现、及时调整。
对于如何制定计划,我将在下一篇更新的文章《[11 | 项目计划:代码未动,计划先行](https://time.geekbang.org/column/article/86817)》中进行详细讲解。
**3.对计划进行跟踪和控制,同时做好风险管理**
计划制定后,并不是说事情就会完全按照我们设想的进行,实际执行难免会和计划有些出入,所以还需要对计划进行跟踪和控制。当项目的推进过程中,如果计划有出入时,需要分析原因,对计划做出调整。
同时也不能盲目乐观对于项目过程中可能存在的风险要进行识别做好B计划这样一旦风险发生变成问题可以及时应对减少风险导致的损失。有关风险管理的内容可以参考《[15 | 风险管理不能盲目乐观凡事都应该有B计划](https://time.geekbang.org/column/article/88259)》。
**管好人、管好事,你就能管好软件项目。**除了上面介绍的一些项目管理知识,涉及软件项目管理的知识内容还有很多。这里并不是说其他知识内容不重要,而是在刚开始的时候,先把这些事情做好,可以保证项目管理不会出现大的偏差,然后逐步拓展到其他知识领域。
在这里,我把前面说的内容做了个简单的思维导图,希望可以对你的项目管理转型起到一定的帮助作用。
<img src="https://static001.geekbang.org/resource/image/36/5e/36e001d1d632d027f3ada5080c70dc5e.jpg" alt="">
## 技术转管理的一些经验教训分享
技术转管理的路上肯定不会是一帆风顺的,要自己踩过很多坑才能成长,我这里也给你分享一点经验教训,希望能帮助你少走一点弯路。
- **控制你想写代码的冲动**
我给每一个刚从技术转型管理的同学的第一个建议都是一样的,那就是:“不要写代码,不要写代码,不要写代码,控制你想自己动手写代码的冲动。”
前面我说过技术人员转型管理的最大障碍是什么,那就是过于关注技术,而忽略了其他事情。从技术转型管理,是个巨大的转变,这种思维的转变是很难一蹴而就的。
对于程序员来说,写代码是自己的“舒适区”,而管理则是“学习区”或“恐慌区”,在转型的过程中,特别容易回到舒适区。
比如你看某个接手你的程序员代码写的实在是不够好,那是你最熟悉的,你只要一小时就写完了,而他要一整天的时间,还没有你写的质量好,你会很有冲动去帮他完成。
比如说在项目进度吃紧的时候,你可能第一想法就是自己去写代码帮助团队赶上进度。
但是,你要知道,当你转型管理后,你的主要职责就是管理,而不是写程序。如果你还是把大部分时间用在写程序上,那么你就很容易忽略项目中的问题。比如没有去关注项目的进展、目前项目的瓶颈、和客户以及其他项目组之间的沟通协调等。
这就是为什么你第一步是要控制自己写代码的冲动。作为一个项目管理者,你的第一要务是管理好项目,而不是去写代码。当你控制住不去写代码以后,你才能把注意力放到团队和项目上去,去领导团队。团队出现问题时,你能及时解决、及时调整。
所以,如果你带的项目进度吃紧时,你要做的不是去写代码,而是去帮助团队从其他角度想办法。具体怎么做,你可以参考我在《[08 | 怎样平衡软件质量与时间成本范围的关系?](http://time.geekbang.org/column/article/85302)》这篇文章里介绍的一些方法,看是不是可以用这些办法缓解进度压力。
- **团队的成功,才是你的成功**
我刚转型做管理的时候,问过老板一个问题:“是不是我把上级的工作做了,我就能升职了?”老板的回答很出乎我意料:“并不是你把上级的工作做了就能升职,而是你的下级都成长了,能替代你的位置了,你就可以升职了。”
这让我明白一个道理:作为一个管理者,团队的成功,才是你的成功。做程序员的时候,把代码写好就很成功了,但是转型做管理后,团队的成功和项目的成功,才是你的成功。
- **形成自己的管理风格**
我在刚开始工作的时候,当时的项目经理很厉害,对我们要求非常严厉,做错了可能就要挨批评,项目管理的很好。那段时间我也进步很大,所以我觉得他是一个很好的项目经理,我就想着自己以后也要像他一样去管理项目。
等到我开始管理项目时,我也想像他一样去严厉的对待下属,但我的性格是比较温和的,我没有办法去做到动不动就去责骂、批评下属,这也让我有了很大的困惑。
后来我尝试着结合自己的性格特点,更多地去激励、帮助下属。在这种管理风格下,整个团队的氛围很融洽,大家做事情也积极主动,一样达到了很好的管理目标。
所以说管理这种事,并不是只有一种风格一种方法,你完全可以根据自己的特点,找到适合自己的管理风格。
- **坚持就是胜利**
技术转型管理的过程,一定不会是一帆风顺的,你会面临很多挑战,会有非常大的压力。这时候最容易产生的冲动行为就是:“算了,还是回去写程序吧!”
我在转型的过程中也遭遇过非常大的压力,遇到过各种困难,掉了好多头发。我有过好多次想放弃的念头,最终还是咬咬牙,坚持了下来。
这样过了几年后,我再回头看当初觉得特别难、压力特别大的事情,现在看起来根本不算什么。如果我当初真的放弃了,恐怕再难迈过那道坎,完成转型。
一旦你已经下定决心要转型,就不要轻言放弃,坚持就是胜利。
## 总结
想要技术转型管理,首先从转变思维方式开始,从技术思维到管理思维,从关注细节到关注整体。然后去改变习惯,控制自己想写代码的冲动,多去从其他角度想办法。
要管理好一个项目,关键是要管理好项目中的人和事。对客户要管理好期望,对项目成员则通过合理的流程规范更好的一起协作;对于项目中事的管理就是对软件开发过程的管理,选择好开发模型很重要,然后就是制定好计划,按照计划推进,过程中不断的调整,并且管理好项目中的风险。
## 课后思考
你是否有想法从技术转型管理,打算怎么做?如果你正在准备转型或者转型中,有没有遇到什么困难,打算怎么去解决?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,169 @@
<audio id="audio" title="11 | 项目计划:代码未动,计划先行" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/9e/7e/9e7527da107dcd7fbfc0de2f682f9a7e.mp3"></audio>
你好,我是宝玉,我今天想与你聊一聊“项目计划”的问题。
若干年前,我接手一个陷入困境的项目,当时的项目经理刚从技术高手转型项目管理,还是没有摆脱技术思维,项目没有什么计划。
他把关键模块分给了自己开发,同时还要兼顾项目管理,导致自己的工作遇到瓶颈,其他人的进度也受影响,大家加班加点也没什么进展,士气低落。
我接手后,第一件事是重新制定项目计划,在排任务时,避免了对某个人的过度依赖,设置了几个关键里程碑。我还特地把第一个里程碑设置的相对容易一点,只需要运行核心功能。
这样大家重整旗鼓,很快就完成了第一个里程碑。达到第一个里程碑的目标后,团队成员很受鼓舞,士气很快就上来了,后面按照新的计划,并没有太多加班加点,就完成了一个个的里程碑,最后顺利完成项目。
你看,**如果没有计划,你的项目可能会陷入一种无序和混乱中。**
计划,就像我们出行用的导航,你可以清楚地看到项目整体的安排,同时它还时刻提醒我们目标是什么,不要偏离方向。
执行计划的项目成员,就像使用导航的司机,可以知道什么时间做什么事情,保证任务得以执行。执行计划的过程,就像我们沿着导航前进,可以了解是不是项目过程中出现了偏差,及时的调整。
## 做技术的就不用关心计划吗?
很多程序员对计划有误解,也不愿意做计划,他们通常都会用一些原因来说做计划是没必要的。
一种典型观点是:“既然计划总是在变,干嘛还要做计划?还不如上手就是干来的爽快!”
这就好比我看过的一个段子:“既然飞机老是晚点,还要时间表干吗?”“没有时间表,你怎么知道飞机晚点了呢?” 计划也是这样,给你提供一个基准线,让你知道后面在执行的时候,是不是出现了偏差,可以根据计划不断地修正。
还有的人说,做计划那是项目经理的事,我是程序员,项目计划与我无关。
我在专栏中常说你要有大局观,不要将自己局限在程序员的身份中。试着做计划就是一个非常好的培养大局观的方式。比如说,你在制定计划的过程中,需要去综合考虑各种因素:有哪些任务要做,可能存在什么风险,任务之间的依赖关系是什么,等等。
参与做计划的过程,可以让你对项目的各种事情了然于胸,这就相当于扩大了你的上下文,让你有更高的视角看待当前工作遇到的问题。
另外,我还见过很多人抱怨项目经理制定的项目计划有问题,却很少看到会有人愿意主动参与制定项目计划。如果你不主动参与计划的制定,最终就只能按照项目经理制定的计划执行了。出现计划不合理的地方,你也只能接受,工作就会一直很被动。
当然,有时候你可能确实是没机会参与到当前的项目计划中。不过,万事皆项目,你一样要学会做计划,因为学会做计划,会对你工作生活的方方面面起到积极的作用。
比如很多人都有一些目标:要转型做管理、要移民、要写一个业余项目,然而很多目标都无疾而终了。**这是因为光有目标还不够的,必须得要付诸行动。而要行动,就需要对目标进行分解,进而变成可以执行的计划。**
## 如何制定计划?
如果有一天,你接手了一个项目,通常第一件事就是得去制定一个项目计划。那么怎么制定计划呢?
制定项目计划,通常有三个基本步骤:
- 第一步:任务分解;
- 第二步:估算时间;
- 第三步:排任务路径。
以前我在飞信时有一个项目叫“留言飞语”就是飞信用户可以在网站或者PC客户端互相留言当时我负责这个项目的服务端正好我还留着当年制定的计划虽然不算一个很好的计划但好在它是一个真实项目的计划正好可以用它来说明一下如何制定计划。
<img src="https://static001.geekbang.org/resource/image/57/de/57b1e4d72cb44939d986a50ceaac38de.png" alt="" title="备注:图片较大,需要点击查看大图">
你看到的这个计划其实不是第一版,可能也不是最后一版,因为制定计划本身是一个反复迭代的过程,尤其是一开始在需求并不够明确的时候,只能比较粗粒度的分解任务和估算,在项目推进的过程中再逐步细化和完善。
#### 第一步:任务分解
我们写程序的时候都有经验,就是要把复杂的问题拆分成简单的问题,大的模块拆成小的模块,在工程里面这个叫“分而治之”。做计划也是一样,第一步就是要对任务进行分解。
在项目管理中对任务分解有个专业的词汇叫WBS它意思是工作分解结构Work Breakdown Structure, WBS)。**就是把要做的事情,按照一个树形结构去组织,逐级分解,分割成小而具体的可交付结果,直到不能再拆分为止。**
下图就是“留言飞语”项目按照WBS拆分的结果。
<img src="https://static001.geekbang.org/resource/image/68/3d/68d47122bef8af0c5f18c1497766c63d.png" alt="">
可以看得出,整个过程是按照瀑布模型来划分的,大的阶段分成技术方案设计、编码和测试,然后每一个大的阶段下面再进一步细分。
例如技术方案设计下面再有需求分析、技术方案设计和评审等;而编码阶段则是按照功能模块再进一步拆分。拆分之后,都是小而具体、可交付结果的任务,且不能再进一步拆分。
这里需要注意的是,在制定计划时,除了要拆分任务,还需要反复思考各种可能存在的问题。
比如这个项目不仅是网站可以访问还需要在PC客户端能发留言所以还需要考虑和PC客户端的通信协议、什么时间可以让PC客户端可以测试协议等。如果上手就写没有良好的计划就可能会忽略这些问题最后导致PC客户端都不知道怎么去调用服务端接口也不知道什么时候可以和客户端联调。
如果项目经理对技术细节不熟悉,可以邀请架构师或者技术负责人协助进行任务的分解。
#### 第二步:估算时间
任务分解完之后,你就需要对每一个任务估算时间。就像下面这样。
<img src="https://static001.geekbang.org/resource/image/a3/10/a3548ca342418c4029f6ee64bde80210.png" alt="">
估算时间这事,有很多方法可以参考,主要还是得依靠以前的经验。要想估算准确,需要从两个方面入手:
- 任务拆分的越细致,想的越清楚,就能估算的越准确。
- 要让负责这个任务的人员参与估算。
举例来说,让你直接给出一个“留言飞语”这样项目的估算时间,是很难的,但对于某个具体功能模块的实现,就可以比较准确了。当把“留言飞语”这样大的项目拆分成足够小的任务时,你就可以很容易的对小的任务进行准确的估算,从而让整体的时间估算变得准确起来。
为什么要让开发人员参与估算呢?
我们来对比一下。假如说一个任务项目经理估计需要3天但是实际执行的时候这个任务可能要5天结果导致开发人员加班。这时候开发人员心中肯定会有不满的情绪认为是项目经理的错误估算导致了他的加班。
如果这个任务所需的时间是由项目经理和开发人员一起估算出来的结果最终发现错误估算了任务的难度这时候开发人员多半会主动加班加点努力在3天之内完成也不会轻易怪罪到项目经理头上。
但这不意味着项目经理对估算不需要控制,通常来说,项目经理需要自己有一个估算,然后再请开发人员一起评估。如果结果和自己的估算差不多,那就可以达成一致,如果估算不一致,那怎么办呢?
其实很简单,**就是要双方一起沟通,消除偏差。**特别要注意的是,开发人员预估工作量通常会很乐观,所以最后时间会偏紧,这种情况一样要去沟通消除偏差。估算的主要目的是尽可能得到准确的时间。
但是在沟通中也要注意技巧不要采用质问的方式“这么简单一个模块居然要5天”这只会让听者产生逆反心理无法有效的沟通。可以恰当的提一些问题来达到有效沟通的目的比如我通常会问两个问题
- “能不能把你这个任务再细化一下?”
- “能不能简单介绍一下这个模块你是打算如何实现的?”
估算出现偏差,可能是由于开发人员没想清楚,或者是项目经理自己低估了其难度。**提问可以帮助双方搞清楚真实的情况是什么样的,而且也不会招致反感。**同时项目经理还可以给予一些建议和支持。
沟通最好的方式就是倾听和恰当的提问。
如果任务的粒度太粗,就需要进行细化,细化后就能更准确的知道结果。
对于估算的结果通常还要考虑增加一些余量因为实际项目执行过程中并没办法保证是100%投入,有可能并行还有其他事情,或者一些突发事情、事先没有考虑到的任务都有可能影响进度。至于加多少余量,还是要根据项目的情况和经验来判断。
#### 第三步:排路径
我们知道项目中有些任务是可以并行做的而有些任务之间则是有依赖关系的。比如说“留言飞语”项目中编码和测试方案是可以同时进行的而Code Review要在编码完成后进行。
所以,**排路径就是要根据任务之间的关系,资源的占用情况,排出合适的顺序。**例如下图。
<img src="https://static001.geekbang.org/resource/image/62/ad/62cb0d16d486b8a0b8084d23262e01ad.png" alt="">
排路径是一个相对比较复杂的任务比如要注意任务的依赖关系要注意路径的长度尽可能让几个任务可以并行的进行避免相互等待。如果借助像Project这种工具会让这个过程相对容易些可以直观的看出来哪些任务是相互依赖的哪些是同时进行的。没有MS Project这类软件也可以用一些替代手段例如Excel上画表格。
制定计划时不要担心不够准确,先有一个基本的计划,可以粒度比较粗,不那么准确,让事情先推进起来。
## 设置里程碑
不知道你有没有参加过那种周期很长的项目,一直看不到结果,时间一长会很疲惫。所以有经验的项目经理会在项目启动后,根据制订好的初步计划,确定几个关键的里程碑。
里程碑的时间点确定后计划可以灵活调整但里程碑一般不会轻易改变因为里程碑代表着一份承诺。这对于项目成员来说有两个重要的影响一方面成员会有很明显的来自DeadLine的进度压力自古DeadLine就是第一生产力另一方面就是在里程碑完成后大家会获得一种正面激励。
里程碑的设置,并没有特别的规则,可以是项目生命周期的特定主要时间,也可以是一些关键的时间点。拿“留言飞语”这个项目来说,有三个时间点非常关键:
- 第一个时间点就是确定和PC客户端的通信协议这样PC客户端可以根据这个协议开始开发功能了
- 第二个时间点就是服务端开发完成PC客户端可以服务端联调了
- 第三个时间点就是测试验收通过,可以上线了。
最终这三个时间点被定义为里程碑。
在项目的推进过程中,根据里程碑完成的情况,你就可以很直观地知道项目的进展如何。如果发现不能如期完成里程碑,就需要进行适当的调整了,例如加班,或者砍掉一些功能需求。
当然,设置好的里程碑也不是不能调整,但是要注意调整次数不宜过多,不然就会变成“狼来了”,以后就没有人相信你的时间点了。
## 计划需要跟踪和调整
项目管理中,并不是计划制定好了就完事了,还需要跟踪和调整。就好比你要开车去什么地方,设置好导航还不够,还需要沿着导航前进,如果遇到障碍或者走错路了,得要及时调整。
项目的跟踪是很必要的,可以了解计划的执行情况,了解成员的工作情况,是否能按时完成,需要什么样的帮助。
跟踪进度的方式主要有两种,一种是项目经理定期收集跟踪,一种是项目成员主动汇报。项目经理挨个收集的话,会有一个沟通确认的过程,对进度会了解的更准确;项目成员主动汇报,可以减少项目经理的收集工作,但有可能不准确。
在这方面,我觉得敏捷开发的两个实践特别值得借鉴和推广。
第一个就是每日站立会议,在每天的站立会议上,每个项目成员都需要说一下自己昨天做了什么,明天计划做什么,有没有什么阻碍。通过这种方式,可以非常好的了解每个人的任务进展情况,同时对于成员遇到的困难,其他人也可以及时给予支持。
第二个就是看板,通过看板,可以非常直观的看到每个人在干什么,进展如何。
通过对项目计划的跟踪,可以很容易的看出来执行的情况,也会发现偏差,计划出现偏差是很常见的,所以需要定期进行调整,也不需要太频繁,例如可以每周一对计划做一次调整。
## 总结
项目计划是保障软件项目成功非常重要的手段,制定计划的过程,可以让你对项目有全面的了解,跟踪计划让你知道项目进展情况,出现问题也可以及时调整。
将任务分解、估算时间、排路径,三步就可以制定出一个项目计划,制定计划不要追求完美,制定好一个初步计划后,就可以先按照计划推进起来,进行过程中还可以继续调整细化。设置里程碑可以有效的保证项目的按时交付。
最后,并不需要当项目经理才能去制定计划,生活中每件事都可以当作一个项目,都可以去制定计划来帮助你实现目标。
## 课后思考
你现在项目的计划制定的如何?如果你是项目经理,你会如何改进?你日常生活中,会有制定计划的习惯吗?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,175 @@
<audio id="audio" title="12 | 流程和规范:红绿灯不是约束,而是用来提高效率" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/ca/16/ca9036cfa1f7e97aee6471d75e4a8416.mp3"></audio>
你好,我是宝玉,我今天想与你讨论流程和规范的价值,以及如何参与制定好的流程规范。
不知道你所在的软件项目中是不是也有各种流程规范,例如:
- 开发人员不能直接在生产环境修改代码操作数据库,必须在本地先测试验证后,由运维操作;
- 代码需要Review通过才能合并主分支
- 代码需要遵守各种规范像命名、格式还有缩进用几个空格还是tab的细节问题
- 遇到Bug先提交到Bug跟踪系统。
在我经历的项目中,或多或少都会有各种各样的流程规范,而且越是大的、正规的项目团队,流程规范越是多。
然而很多人对于流程规范并不是很理解,甚至觉得是一种约束。
## 为什么要有流程规范?
从某种程度上来说,流程规范确实是一种约束:约束了我们如何做一件事,约束了我们用什么标准做事,约束了我们用特定的顺序做事。
既然如此约束我们,为什么还要有流程规范呢?
### 提升团队效率
**从个体来看,因为流程规范的存在,确实可能存在效率降低的情况,但从团队的角度来看,好的流程规范反而是提升效率的。**
这其实很像我们生活中的红绿灯,用一个简单的规则:红灯停绿灯行,来约束车辆行人按照指示灯行进。
从单个车辆来看,看似是因为红绿灯的存在而影响了效率,但是从整体来看,因为红绿灯的存在,有效避免了拥堵,反而是提升了大家出行的效率。
其实红绿灯除了能提高效率,还有其他好处:
<li>
红绿灯这样好的管理交通的经验,形成流程规范后,就可以全世界共享这种先进的经验;
</li>
<li>
红绿灯不再处处依赖于人指挥交通,而变成了让红绿灯的规则来指挥交通。
</li>
软件项目中的流程规范是不是也有这样的效果呢?
以代码审查的规范为例,对于技术高的程序员来说,代码审查可能会耽误一点时间,但对整个团队来讲:
<li>
即使是水平高的程序员,也可能会被发现有错误,代码审查可以降低出错的概率,保障质量;
</li>
<li>
对于水平低的程序员,可以通过代码审查学习和成长,代码被高水平程序员审查后,可以有效提高质量。
</li>
软件项目中这样的例子还有很多类似的还有像遇到Bug要提交到Bug跟踪系统还需要配合重现步骤说明看起来繁琐但是却让Bug可以有效跟踪让开发人员可以重现和定位从而高效的修复Bug。
### 将好的实践标准化流程化,让大家可以共享经验
我们知道,在运动项目上,有些运动员特别有天分,总能拿好的成绩,而这些运动员的动作,会被反复的研究学习,最终形成标准化动作。而其他天分一般的运动员,按照研究出来的标准动作练习,也能取得非常好的成绩。
软件工程也是这样,早些年的软件项目,就是个人英雄主义盛行的时代,项目的成败极其依赖于个别厉害的项目经理或者技术高手,而这种牛人,总是稀缺的存在。
所以后来很多编程高手写代码的方式,甚至写代码的格式,也会被研究,最终形成一套套的代码规范。其他水平一般的程序员,按照代码规范,也能写出不错的代码。
代码规范还有个好处,就是大家写出来的代码看起来差不多,换个人接手别人的代码,也能很快上手。
如果我们站在流程规范的角度看软件工程的开发模式,它也是源自实践过程中,有些厉害的项目经理发现了好的、可以提升软件质量的开发实践,不断总结改进,最后变成了流程,让普通的项目经理按照这一套流程,也能做出不错的软件。
你看瀑布模型也好敏捷开发也好最后落实下来不就是开发过程中一个个的流程规范么所以瀑布模型我们需要各种阶段评审敏捷开发需要每天开站立会议需要每个Sprint有计划会、评审会。
### 借助流程规范,让项目管理从人治到“法治”
在《[10 | 如果你想技术转管理,先来试试管好一个项目](http://time.geekbang.org/column/article/86375)》这篇文章中我就提到过,管理就是管人和管事,而管人,就要借助流程规范来管理。
因为如果在项目管理中,过于依赖人的管理,项目经理就会成为瓶颈,大事小事都需要项目经理来决策。再说项目经理也不能保证每次决策的正确性,如果决策失误,会很可能导致一些冲突。
**而好的项目管理,不需要直接管人管事,而是管理好计划和流程规范;项目成员不需要按照项目经理的指令做事,而是遵循计划和流程规范。**
我以前工作过的一个项目组,一个项目持续了好多年,中间人换了一批又一批,甚至有时候连项目经理都空缺,而项目一直井然有序的进行着,没有出什么问题,靠的就是多年积累下来的适合项目组的流程规范。
就像在《[06 | 大厂都在用哪些敏捷方法?(上)](http://time.geekbang.org/column/article/84652)》这篇文章中描述的那样:项目成员日常从看板就可以知道要做什么任务,代码审查、自动化测试可以有效保证质量,项目文档可以保证新人加入时能快速上手,结对编程可以保证新人遇到问题可以得到直接的帮助。
还有一个常见场景就是需求变更,产品经理想加一个紧急需求,这通常是让项目经理为难的事情:加吧,影响项目进度,开发人员有意见;不加呢,可能客户或者产品经理有意见。一个不小心就两边都得罪了。
如果你有一个大家认可的需求变更流程,就不再需要靠项目经理一个人决定该不该加需求,而是通过流程,来大家一起决策是不是要加这个流程。
所以你看,**流程规范,看起来是约束,实际上你用的好的话,不仅可以提高团队效率,还可以将好的实践标准化流程化,让大家可以共享经验,还可以有效的管理项目。**
## 如何制定好流程规范?
在项目管理中,难免要去制定流程规范。即使你不是管理者,也可以提出合理的流程规范,帮助把项目管理好。
有一个科学的制定流程规范的方法,可以让你更好地制定出好的流程规范。
### 制定流程规范的四个步骤
对于流程规范的制定,可以通过四个步骤来开展。
**第一步:明确要解决的问题**
要制定一个流程规范,第一步就是明确你是要解决什么样的问题。项目中很多问题,都可以思考是不是能通过流程解决。
比如说有程序员在生产环境操作,误删了数据表,造成了严重问题。如果只是对程序员进行处罚,寄希望于小心谨慎避免类似问题,那么下一次还有可能会有类似的事情发生。
如果说在流程上规范起来例如数据库操作之前先备份数据库事先写好SQL语句需要有人审查测试环境先测试通过最后再生产环境执行那么就可以避免以后再出现不小心删除数据表的事情发生。
**第二步:提出解决方案**
对于问题,也不用着急马上就想着用流程规范,可以先思考解决的方法,有了方法后再进一步思考是否能提炼流程规范。
那么方法和流程规范有什么区别呢?
相对来说,方法更有针对性,可能只适用于特定场景或者特定人,而要将方法上升到流程规范,则需要有一定的普适性,能变成具体的步骤或者标准,让每个人都能执行。
比如说服务器部署后出现问题,高手可能就直接上服务器操作,直接修改代码编译解决,这是一个解决方法,但这不能成为一个流程规范,因为换一个水平不行或者对代码不熟悉的人来做,可能会搞出更大的问题。这时候回滚操作就是一个相对普适的方法,可以变成一个部署后出现问题的流程。
在提出解决方案,制定开发流程时,可以参考借鉴软件工程中,大家公认的好的实践。比如说:
<li>
**敏捷开发的流程:**虽然你的项目不一定采用敏捷开发的方式,但是敏捷开发中一些好的流程是可以借鉴的,例如参考我之前文章提到的像看板、站立会议、持续集成,这些好的工作流程,都可以借鉴。
</li>
<li>
**代码规范:**其实很多公司都公开了他们的代码规范可以直接基于这些规范制定团队的规范。例如说前端的有Airbnb的代码规范 [Airbnb JavaScript Style Guide](http://github.com/airbnb/javascript)Java的有 [Google Java Style Guide](http://google.github.io/styleguide/javaguide.html) .Net的有[.NET Guide](http://docs.microsoft.com/en-us/dotnet/standard/index),等等。
</li>
<li>
**源代码管理流程:**现在的源代码主流是git而基于Git的代码管理已经有很多成熟的流程规范可以参考。例如阮一峰老师写过的《 [Git 使用规范流程](http://www.ruanyifeng.com/blog/2015/08/git-use-process.html) 》《[Git 工作流程](http://www.ruanyifeng.com/blog/2015/12/git-workflow.html)》和《[Git分支管理策略](http://www.ruanyifeng.com/blog/2012/07/git.html)》或者Github官方出品的《[Understanding the GitHub flow](http://guides.github.com/introduction/flow/index.html)》Gitlab官方推荐的《[Introduction to GitLab Flow](http://docs.gitlab.com/ee/workflow/gitlab_flow.html)》。
</li>
<li>
**部署流程:**十年前,每日定时构建还是很时髦的部署流程,而现在,主流的部署流程已经变成了持续部署,每次代码合并到主分支都可以触发一次自动部署,这样一有问题,就能马上知道发生在哪个环节。
</li>
像这样的好的流程还有很多,在我们专栏会介绍一些。如果平时多留心,你也可以学到很多。
**第三步:达成共识,推广执行**
在流程规范提出后,还需要得到大家认可,只有大家认可,达成共识,才能共同遵守,保障制度的执行。
对于大家都认可、很重要的流程规范,一定要让大家严格遵守,必要的时候需要配合一些奖惩制度,以保障其执行。
比如说流程规范的执行和绩效考评挂钩,对于没有执行的需要私下沟通提醒,严重的需要批评教育。否则流程规范会形同虚设,没有太大的意义。
**第四步: 持续优化,不断改进**
流程制定后,在实际执行的时候,难免发现一些不合理或者不科学的地方,这时候就需要对其进行调整。
还有一些流程规范,随着时间推移,可能已经不能符合要求了,也需要考虑改进甚至放弃,不然反而会成为一种阻碍。
比如说以前采用瀑布模型开发时,项目经理因为需要了解进度,所以每个项目成员要写日报,如果有站立会议了,日报这种形式就可以完全被站立会议替代,没有再存在的必要。
通过以上四个步骤,你就可以将日常项目中遇到的一些问题,用流程规范的方式逐步管理起来,在实施的过程中再不断优化改进,淘汰不合适的流程规范。
### 将流程规范工具化
如果说,以前我还是人为去推动一些流程规范的执行,近些年,我越来越感觉到,**应该尽可能借助技术手段来推动甚至替代流程规范。**
例如说代码规范以前代码规范的执行主要靠反复的教育宣传和代码审查中一个个去检查。而现在借助VSCode这种强大的IDE以及ESLint这种代码检查工具可以方便的检测出不符合规范的代码甚至于可以帮你直接格式化成满足代码规范的格式。
还有像保证代码质量的问题早些年必须依赖测试人员大量手工的测试而现在借助CIContinuous Integration持续集成、自动化测试和Git可以保证代码必须在通过测试以后才会合并到主分支从而很好的保证了代码的质量。
就像任正非的《全面提升软件工程能力与实践,打造可信的高质量产品》公开信中题记的这一段话说的:
>
“软件工程”和“质量工程”需要依靠架构技术而不是依靠CMM和QA管理流程。一切工程问题首先要思考能否通过技术解决当前技术无法解决的问题暂时由管理手段代劳同时不停止寻找技术手段。
“软件工程”不要过于依赖流程和管理手段,要思考怎么通过技术手段去解决问题。
## 总结
流程和规范,就像红绿灯一样,不是一种约束,而是牺牲一点个体利益,提高团队效率;流程和规范将好的实践标准化流程化,让大家可以共享经验;流程和规范,让项目管理从人治变成“法治”。
要制定好项目规范,先明确要解决的问题,然后提出解决方案,看是否可以通过流程规范来解决,有了方案后需要团队成员一起达成一致,最后再推广执行。在执行过程中需要持续的优化,不断改进。
对于需要手动操作的流程,可以思考是不是能采用技术手段自动化,通过技术手段去解决。
## 课后思考
你所在项目中有没有不合理的流程规范?或者欠缺流程规范导致混乱的情况?如果有,你觉得可以制定什么样的流程规范来改善?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,140 @@
<audio id="audio" title="13 | 白天开会,加班写代码的节奏怎么破?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/6e/8a/6e063d117cb74ddbbe5779ef1972e08a.mp3"></audio>
你好,我是宝玉,我今天想与你讨论让很多程序员头疼的话题:开会。
说到开会,是很多人心中的痛,每天白天忙于参加各种会议,压缩了本来就少的可怜的工作时间。最可气的,有的人开完会工作就算完成了,而像我们写程序的,还得下班后加班加点赶进度!
所以一说到开会,程序员们往往如遇洪水猛兽一般,避之不及。
## 开会是有价值的
但我想说的第一个问题是:**开会是有价值的。**软件项目中有不少会议,其实有其价值所在,给你简单举例分析一下。
像评审会议,通过会议,可以让产品设计或架构设计在确定前,收集大家的意见,及时发现问题。
像每日站立会议,可以及时了解项目的进展,了解当前的困难和瓶颈,及时调整计划,解决问题。另外在会议上,每个人都要当众讲一下做过的事情和计划要做的事情,这也是一种无形的监督和约束。
像项目立项会议,可以创建一种仪式感,让每个人都知道项目的关键信息:
- **项目目标:**这个项目是要干什么的,达到一个什么目标;
- **项目里程碑:**项目的开始结束时间,项目的阶段划分,以及各个阶段的时间点;
- **角色分工:**项目成员的分工和角色是什么,每个人知道自己的任务是什么,知道遇到问题该找谁;
- **流程规范:**项目开发的主要流程是什么,基于瀑布还是敏捷。
像项目总结会议,团队成员可以一起总结一下项目的得失,把经验总结下来,帮助团队在下一次做的更好。
还有很多会议我就不一一列举。从上面可以看出,这些会议都是可以创造价值的。
## 开会是有成本的
开会的成本,就像房间里的大象,显而易见而很多人却有意无意无视它的存在。
我们做个简单的数学计算假设一个程序员月薪一万元如果他每天四分之一的时间在开会那就相当于公司每月花了2500元在会议上。
这还只是一个人的成本,如果开会的人多,那么仔细算算,整体的会议成本其实很夸张的。所以我想说的第二个问题就是:**开会其实是有成本的,而且还不低。**
## 什么样的会议是有效率的?
其实软件项目中有些会议我是愿意参加的,因为是有价值的,高效的。比如说前面提到的每日站立会议,时间不长,但是收获很大。
再比如隔壁郑晔老师的《10x程序员工作法》专栏中提到的“[轻量级沟通](http://time.geekbang.org/column/article/82844)”,其中建议的会议方式:人少,面对面沟通。这种小会通常也让我觉得很高效,经常能产生有价值的方案。
还有一些会议则让我觉得没什么价值,比如领导冗长的讲话,比如一堆人在偏离会议主题的讨论,比如跟我没什么关系却被迫参加的会议。
那么为什么这些会议给我的感觉完全不一样?这其实就是我想讲的第三个问题:会议是不是有效率,取决于它创造的价值是不是高于其成本。
我觉得像每日站立会这样的会议更有效率,其时间短、人数少,所以成本低,创造的价值高于其成本。而人数多,又偏离会议主题的讨论会则没有价值,这是因为人数多时间长,导致会议成本高,而其创造的价值远远不及成本。
那为什么还有那么多低效率的会议?**因为有的会议,就不是为了创造价值。**
比如说有的会议,花的成本不是组织者的,对他来说,得到他的会议价值就可以了。
>
你是砍柴的,他是放羊的,你和他聊了一天,他的羊吃饱了,你的柴呢?
还有很多会议,是因为组织者和参与者,都没有意识到开会其实是有成本的,所以浪费了成本还不自知。不过这种情况还好,还是可以想办法改进的。
接下来,我们来看看如何提高开会效率,破除避免白天开会,晚上还要加班写代码的节奏。
## 如何提高开会效率?
我们专栏有一篇文章《[08 | 怎样平衡软件质量与时间成本范围的关系?](http://time.geekbang.org/column/article/85302)》,很多同学看过里面讲的软件项目金三角理论后,直呼“醍醐灌顶”、“终于找到一套可以说服老板的说辞了”、“能够提高与产品经理打太极的水准”。
其实提高开会效率、提升开会价值的方法,就跟软件项目金三角的理论一样,只要从两个角度去想办法:**减少开会的成本,增加开会创造的价值!**
在具体探讨这两类方法之前,我们先要认识到一个前提:**那就是要让大家意识到开会是有成本的,如果开会创造的价值不能大于其成本,就是浪费。**
就像金三角理论,你得先让老板、项目经理明白三条边不可能都占,才好去沟通讨论。要提高开会效率,也需要大家先有这个意识,才能在具体措施上达成一致。
那么,有哪些方法可以减少开会的成本呢?
**1.砍掉一些没价值的会议**
在日常工作中,还有很多会议其实并没有什么价值的。如果一个会议符合这些标准,你就要慎重考虑参加了:
- 没有目标的会议。大家都在随意发散,完全没有主题;
- 不能形成决策,没有会后行动。如果一场会议看完后都没有什么结果,那跟没开都没啥差别;
- 你属于可有可无的角色。如果一个会议,跟你其实没什么关系,你无法提供有效的反馈,对你也没什么价值,只不过是被人拉过去开会的,那不如把这个时间用来做一点对项目更有价值的事。
所以,你可以在每次要接受一个会议邀请之前,先问自己两个问题再做决定:这个会议我真的有必要参加吗?以及,有其他方式可以替代吗?
其实,很多问题并不是非要通过“会议”的方式解决。
以前我负责的一个服务其他组需要调用所以有一个组的同事想跟我组织一个会议让我介绍一下服务以及如何调用。我思考了一下觉得准备这个会议我也要写一个PPT开会还得要时间这时间我足够写一个详细的说明文档出来了而且以后其他组再要用也只要看文档就可以了。
于是我就跟他们说:“我们不用开会,我一会发一个文档链接给你们,如果有问题我们可以在聊天工具上沟通。”后来他们看完文档后,有几处不清楚的地方,在咨询过我以后,我将文档更新好,就没什么问题了,而且后面再不需要为这件事开会了。
**2.减少参与会议的人**
**会议的成本和两个因素相关:一个是人数,一个是时间。如果减少人数,就能减少成本。**
减少人数好处还在于,人一少,每个人都会更投入,也更有效率,所以往往时间反而会少产出会高。而且,如果会议上要形成一些决议,人越多越难做决策,人越少越容易达成一致。要想有决议的话,先开几个小会,达成一致后再开大会,大会更多只是宣布一个结果。
像谷歌和Facebook他们对于会议的态度就是能不开就不开无关的人不参与。Amazon 的规则也很简单:一场会议的人数,最多订两份披萨,如果超出这个规模,说明这个会议的人数太多了。
**3.缩短开会时间**
减少开会成本的另一个方法就是缩短开会时间。缩短开会时间有很多成熟可靠的方案可以选择。
比如说站立会议,通过站立的方式逼着大家快点结束。
另外,麦肯锡开会上有些做法也值得借鉴:
- 每个成员有一张黄牌,用于喊停其他人会议中发散讨论无意义的话题;
- 有人控制节奏,大家快速发言;
- PPT不超过3张鼓励大家预先准备多讨论。
还有比如我们在前面敏捷开发介绍的例子,会议有人主持,当话题开始发散的时候,果断制止,放到“停车场问题”环节,也就是会议的最后专门讨论。
类似这样的缩短开会时间的办法,确实可以有效减少会议成本,这类提升效率的方法还有很多,你可以从这个角度多思考尝试一下。
**4.提升会议所创造的价值**
如果能有效提升会议产出,也一样可以达到很好的效果。
比如说,每个会议要有明确的目的和主题,所有的讨论都要围绕会议目的展开。当你发现会议上一些问题的讨论偏离了会议的主题,例如一个需求评审会,结果架构师在讨论技术细节,这就完全偏离了主题。
你就应该站出来提醒一句:“现在既然是讨论需求,不如先不讨论技术上的问题,等到需求确定了,我们后面再慢慢讨论技术问题。”或者说:“不如这个问题我们另外组织一个会议讨论。”
还有开会后,要有明确的结论,有后续的待办事项,落实到个人,对待办事项有跟踪。
偷偷说一下,有时候一些没什么价值的会议,又必须要参加,我一般会参会前,用一个本子把一个技术难题、或者一篇博客主题,写下来。
开会的时候,把这个难题理清楚思路,把博客的提纲写出来,这样一个会议开完,我的问题也解决了,或者文章提纲也有了。同样也是收获满满,没有浪费太多时间。
这些都是提升会议价值的方式,相信你对会议成本有了概念以后,也可以找到很多可以帮助你提高开会效率、更好创造会议价值的方法。
## 总结
今天带你一起学习了解了开会的“道”,那就是开会是有价值的,开会是有成本,会议是不是高效,就看它创造的价值是不是高于其成本。
如果你想破除白天开会,加班写代码的节奏,就需要从缩减开会成本和提升开会价值的方向上去想办法,还需要让你的老板、项目经理都有“会议是有很高成本”的意识。
砍掉一些没价值的会议,减少开会的人数,缩短会议的时间,提高会议创造的价值。
## 课后思考
你在项目中,有哪些会议其实是可以不参加的?哪些会议是可以缩减人数的?哪些会议是可以缩短时间的?哪些会议是可以更好的提升价值的?或者你对上面的观点有哪些补充?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,182 @@
<audio id="audio" title="14 | 项目管理工具:一切管理问题,都应思考能否通过工具解决" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/88/98/88abdb94a00a87a86ad29c7152cc3398.mp3"></audio>
你好,我是宝玉,我今天想与你分享的主题是:一切管理问题,都应思考能否通过工具解决。
早些年我在做项目管理工作的时候,除了制订计划外,还要花不少时间去跟踪计划的执行情况。
项目管理上出了问题,管理者总是喜欢从流程规范的角度去想办法,于是为此设定了不少流程规范,例如每天要写日报,根据日报更新项目进度,每周要开周例会,看看项目有没有执行上的问题。
对任务进度的量化也是个很困扰项目经理的事情需要频繁地去问程序员“你这个任务进展如何大概完成比例多少从程序员那得到的答复通常都是个很乐观的数字例如80%。第二天以为他能做完结果一问是90%,就这样要持续好多天才真的算做完。
所以后来我得出来一个结论:**一个任务只有0%和100%两种状态是准确的,中间状态都是不靠谱的。**
除此之外,还有个问题就是,项目的进展并不太直观,除了项目经理每天看计划表,对计划有一个大概了解以外,其他人可能只有在到了计划设置的“里程碑”时,才对进度有比较直观的感觉。
项目成员手头事情做完,如果和计划有出入,也不知道自己接下来该干嘛,都要跑去问项目经理,所以项目经理对于很多事情都要从中协调,日常有很多繁重的任务管理工作。
后来我发现其实很多管理者都有类似的困惑:任务不好量化难以估算,项目成员对当前项目进度缺少直观感受,管理者要花大量时间在任务管理上。
这些年,随着软件项目管理工具的发展进化,发现当年困扰我的这些问题已经不再是一个主要问题,因为通过工具就能很好的解决这些问题。
这也是我这些年项目管理和技术管理的一点感悟:
>
一切管理问题,都应思考能否通过工具或技术解决,如果当前工具或技术无法解决,暂时由流程规范代替,同时不停止寻找工具和技术。
下面的微博即是一例,当遇到问题时,不仅从流程上思考有没有问题,更要考虑是不是可以用工具或技术手段来解决。
<img src="https://static001.geekbang.org/resource/image/c7/f7/c7d2a286af31b9f79f95487b507859f7.png" alt="">
在这里,我还是先带你看一下项目管理工具软件发展史,通过工具的演化,你可以更深入的了解到工具是怎么解决这些管理问题的。
## 项目管理工具软件发展史
#### 在没有项目管理工具的年代,都是怎么管理项目的?
早些年,我除了好奇过大厂是怎么开发大型软件项目以外,还好奇过像登月这种超大型项目是如何做项目管理的。正好前不久看了余晟老师写的一篇文章《[“阿波罗“登月中的工程管理一瞥](http://mp.weixin.qq.com/s/-u0TtSBA5EynVpTkuSVdog)》,让我有机会一窥究竟。
其实这种大项目的项目管理并不神秘,就是像我们专栏《[11 | 项目计划:代码未动,计划先行](http://time.geekbang.org/column/article/86817)》那一篇讲的这种大项目也是采用WBS工作分解结构把所有任务一级级分解再排成计划按照计划有序进行。
但阿波罗项目是个超大型项目所有的任务分成了A、B、C三级到C级已经有超过4万个任务。要给这四万多任务排出项目计划就太不容易了一共要几十名分析人员来协调和跟踪所有的任务。最终列计划的图表贴在墙上超过100平米。
[<img src="https://static001.geekbang.org/resource/image/d8/bc/d838250d8a9150eab8af735f16f9f5bc.png" alt="" title="阿波罗登月项目巨型计划图">](http://www.hq.nasa.gov/pao/History/SP-4204/ch15-1.html)
在没有项目管理工具的年代,要制订一个项目计划非常之不容易,需要专业人士花大量时间,而且每次修改调整,都要再花费大量时间精力。
#### 最初的项目管理软件:项目计划工具
直到后来像微软的MS Project这样的项目计划工具软件普及才让制订计划变成了一个相对容易的事情可以方便的对分解好的任务排出计划。
<img src="https://static001.geekbang.org/resource/image/bd/1b/bdd37c9668a7cfbffc0406c0476c1a1b.png" alt="" title="图片来源MS Project官网">
早些年软件项目的开发以瀑布模型为主瀑布模型的这种按阶段划分的开发模式和WBS 工作分解结构这种将任务层层分解的理念不谋而合MS Project 这种软件可以非常好的将所有任务分解、制订计划按照计划跟踪执行。所以那时候会使用MS Project就是项目经理的标配。
MS Projec虽然解决了计划制订的问题但还是有些不足之处。例如不方便跟踪任务进度进度不直观等。
再加上后来敏捷开发开始兴起很多项目都开始采用Scrum的方式来进行项目管理开发变成了迭代的方式以前单纯的项目计划工具就不能很好的满足项目管理需要了。
#### 基于Ticket的任务跟踪系统
传统的项目计划软件还有很多问题无法解决。比如,很多人都有过以下类似的项目经历:
<li>
产品经理口头让开发对产品做一点小改动,开发也答应了,后来就把这事忘了,或者测试都不知道还有这事,也不记得要测试这个模块;
</li>
<li>
代码审查的时候,发现组内某个同事的代码没有写单元测试,但是因为任务紧,只能先上线,于是叮嘱他后面一定要把单元测试代码补上,结果还是忘了。
</li>
日常项目中像这样的小事情不少如果不记下来很容易忘记如果用传统的项目计划软件排进去又很麻烦直到后面有了基于Ticket的任务跟踪系统才很好的解决了这个问题。
Ticket跟踪最早源于客服的工单Ticket系统每次客户接到一个问题就创建一个工单后续和客户的每一次交流和处理都要更新工单内容和状态直到结束。
最早在软件项目中应用Ticket跟踪系统的领域是测试领域用来追踪Bug后来逐步衍生到整个项目管理领域不仅跟踪Bug还用来跟踪需求、开发任务等。
也有很多系统用Issue来表示Ticket的概念无论Ticket还是Issue表示的都是一个工作任务可以包括软件的Bug、功能需求、某个模块的开发、系统的重构任务等。
那一个Ticket应该包含哪些主要信息呢
一个Ticket应该包含
- 标题摘要性的描述Ticket内容
- 类型属于什么类型的TicketBug、需求、任务
- 内容Ticket的详细内容例如如果是Bug的话除了要写清楚Bug内容还需要重现步骤。如果是需求的话要有需求的描述可能还需要额外的文档链接辅助说明
- 创建人谁创建的这条Ticket
- 优先级这个Ticket的优先级高还是低
- 状态Ticket的状态例如未开始、处理中、已解决、重新打开、关闭等
- 指派给谁这个Ticket被指派给谁了谁来负责
- 历史记录整个Ticket改变的历史信息用以跟踪
当然除了这些外还有一些其他信息例如创建时间、附件、标签、版本等。另外现在的Ticket跟踪软件都有强大的定制功能可以增加额外的辅助信息例如你是基于敏捷开发还可以加上Sprint、故事分数等信息。
Ticket的这些内容基本上可以包含一个工作任务所需要的所有内容。有了Ticket之后无论大到一个功能需求还是小到一个Bug从它创建一直到完成整个过程都可以方便的被跟踪起来了。再也不担心像任务被忘记等前面提到的这些情况了。
基于Ticket去跟踪任务不再需要通过日报、一对一会议的方式来收集任务执行情况负责Ticket的项目成员在完成任务后会直接修改Ticket的状态这样其他人就可以看到Ticket是否已经完成。
Ticket通过各种不同状态例如未开始、开发中、完成等可以很直观的了解任务的进展这就避免了任务难以量化的问题。
Ticket跟踪系统和敏捷开发也是很好的搭档。在敏捷开发中产品Backlog产品待办任务列表是一个用来放所有产品的待办任务的清单在每个Sprint开始前的迭代计划会议上从产品待办任务清单里面选取一部分任务到Sprint的待办任务清单Sprint Backlog中。
当使用Ticket跟踪系统后就可以把所有产品的待办任务用Ticket都记录起来当我们在迭代计划会议上选取好任务后就标记为要在当前Sprint完成这样后面就可以方便的筛选出属于当前Sprint的所有Ticket这样大家就可以从Ticket跟踪系统知道我们这个Sprint有哪些Ticket需要完成、进展如何。
如果将当前Sprint中从开始到结束每天记录一下Sprint Backlog中未完成Ticket的数量绘制成一张图表横轴表示时间纵轴表示剩余Ticket数量就可以通过图表直观地看到还剩下多少工作。
这种用于表示剩余工作量的工作图表也叫燃尽图burn down chart可以直观的预测工作将在何时全部完成。
[<img src="https://static001.geekbang.org/resource/image/c2/ca/c2311b8e2943ffe41c3775a80eb491ca.png" alt="" title="图片来源:维基百科">](http://zh.wikipedia.org/wiki/%E7%87%83%E5%B0%BD%E5%9B%BE)
基于Ticket的任务跟踪系统很好的弥补了项目计划工具的不足让项目中大大小小的各种开发任务都可以方便的记录跟踪起来。燃尽图也可以直观的了解剩余工作情况。
如果说美中不足的话就是整体的Ticket状态还不是很直观例如不能清楚的看到哪些任务在进行中哪些任务待领取。
#### 基于看板的可视化任务管理
看板本来是在1940年由“丰田汽车”发明的生产管理系统其中一些理念被借鉴到软件开发中尤其是其可视化的任务管理方式很好地解决了早期 Ticket跟踪系统不直观的问题。
所以现在的Ticket任务跟踪系统几乎都会有看板视图通过看板可以很直观的看到当前任务进展情况。
<img src="https://static001.geekbang.org/resource/image/ae/16/ae93062b417fbe91e475841c9b781916.jpg" alt="">
参考上图可以看出在看板视图上的所有Ticket可以很直观的看出哪些还没开始哪些进行中哪些已经完成。
这种可视化的任务视图,不仅是对项目经理,可以很直观看到进展,对于普通项目成员也是很方便。
- 从“待选取”栏选择一个Ticket拖动到“开发中”栏表示这个Ticket已经选取开始开发了。
- 手头上的Ticket开发完成后就可以将Ticket拖动到下一栏——“测试”栏。
- 测试人员看到新加入“测试”栏就可以从测试栏选取Ticket进行测试。
- 如果测试没通过Ticket就会被拖动到“待选取”栏。
- 如果测试通过Ticket就会被拖动到下一栏——“待部署”栏。
- 部署完成后所有“待部署”栏的Ticket就会被拖动到“完成”栏。
整个过程完全不需要项目经理从中协调太多,尤其是结合每日站立会议,可以让项目成员自发有序地按照看板开展日常工作。
借助Ticket跟踪和看板可视化项目经理可以从繁重的任务管理中解放出来可以抽出来时间做一些其他更重要的事情。
以上就是项目管理工具的一个演化简史,可以看到,每一次工具的发展进化,相应的很多项目管理工作就可以得到简化,很多早期的项目管理问题,也就不再是问题了。
## 有哪些项目管理软件可以选择的?
在了解完项目管理工具的发展历史后,再给你介绍一些目前国内国外主流的项目管理软件,帮助你根据自己项目需要进行选择。
如果单纯是项目计划工具,功能最好、最全的应该是微软的[MS Project](http://products.office.com/zh-CN/project/)但遗憾的是只能运行在Window上不支持Mac平台。如果要在Mac上使用项目计划工具可选的有[OmniPlan](http://www.omnigroup.com/omniplan)和[Merlin Project](http://www.projectwizards.net/en)。
而且这些项目计划工具现在也都支持了看板视图。不过如果只是单机支持的话意义并没有那么大需要在线版的Ticket跟踪结合看板视图才能让整个团队可以一起浏览操作发挥其最大效用。
基于Ticket的任务跟踪系统最有名的应该是[Atlassian](http://www.atlassian.com)公司出品的[Jira](http://www.atlassian.com/software/jira)软件功能全面体验很好。Jira主要是在海外比较流行因为访问速度和使用习惯等原因国内用户要相对少一些。
同类产品也很多,微软的[Azure DevOps](http://visualstudio.microsoft.com/zh-hans/tfs/?rr=https%3A%2F%2Fshimo.im%2Fdocs%2F5A0wCnmLwn0nCjE9) 以前叫TFS, Team Foundation Server和微软系的产品如Visual Studio、Azure可以很好的整合。
代码托管平台[GitHub](http://github.com/account/unverified-email)本身也集成了一套Issue跟踪管理系统虽然没有Jira那么强大但是对于普通项目来说足够用了。尤其是对于开源项目完全可以基于GitHub的Issue进行日常的项目管理。
国内同类的软件有:
- [禅道](http://www.zentao.net):为数不多提供开源版本可以自己搭建的;
- [Worktile](http://worktile.com):集成了即时消息软件;
- [TAPD](http://www.tapd.cn):腾讯出品,可以和腾讯的服务很好整合,例如企业微信和腾讯云;
- [云效](http://cn.aliyun.com/product/yunxiao):阿里巴巴出品,可以和阿里的服务很好整合,例如阿里云和钉钉;
- [DevCloud](http://developer.huawei.com/ict/cn/devcloud):华为出品,和华为云有很好的整合。
还有一些其他产品,这里就不一一列举。
**那么该如何选择适合的工具呢?**
从功能上来说,基本上,上面提到的每一款产品都能满足日常项目管理的基本需求,建议从项目特色、团队成员、价格和服务等因素综合考虑。
例如说你的项目完全是微软技术栈就可以考虑使用TFS如果你深度使用阿里云和钉钉那么就可以考虑阿里的云效如果你想自己搭建那么就可以考虑Jira或者禅道。
这些产品都有免费版本,可以先试用,你可以仔细对比后,根据自身的情况再最终决定。
## 总结
今天我带你一起了解了软件项目管理工具的发展历史从完全手工方式管理项目到借助计划工具分解安排计划到基于Ticket跟踪管理任务再到基于看板的任务可视化。每一次工具的升级都是对项目管理工作的一次简化。
合理的使用项目管理工具,可以帮你极大提高管理效率,起到事半功倍的效果。我也列举了一些目前国内外主流的项目管理工具,希望可以帮助你做出选择。
最后,对于日常项目管理的问题,你也可以多思考是不是可以由工具或者技术手段来解决的。
## 课后思考
你在日常项目中,有哪些应用工具或者技术解决项目问题的例子?或者你觉得可以用工具或技术解决的问题?你现在项目中用的是什么项目管理工具,有什么优缺点?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,198 @@
<audio id="audio" title="15 | 风险管理不能盲目乐观凡事都应该有B计划" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/50/1c/506e2a6bf19da29d1bde67a0e5c9601c.mp3"></audio>
你好我是宝玉我今天想与你分享的主题是风险管理凡事都应该有B计划。
说到风险,很多人都模模糊糊有一些了解,然而在软件项目中,有风险意识的却不多。比如说:
- 估算一个模块工作量,程序员总是会给出一个乐观的进度,而最终实现这个模块的时候,却发现总是有些其他的事情发生影响了进度;
- 一个关键的程序员,突然离职了,导致项目进度停滞。其实早前就有一些迹象,而项目经理没引起重视;
- 技术负责人很激进的采用了一个最近很流行的新技术,结果做的过程中,发现这个技术还不太成熟,很多坑没法填,导致项目最终失败;
- 服务器突然挂了,才发现硬盘坏了而数据没有备份,造成巨大的损失。
这些问题其实都和风险相关,如果没有及时发现这些潜在的风险,没有应对方案,轻则导致项目进度延迟,重则导致项目失败,造成重大损失。
在软件工程里面,针对这些可能造成风险的问题,对风险进行提前识别和管理,就可以有效地应对。
## 什么是风险管理?
风险是指不确定的事件,一旦发生,将会造成消极的影响。风险包含两个方面的内容:
1. 发生后,会造成什么样的损失?
1. 发生的概率有多大?
所以也有人认为:**风险 = 损失 x 发生概率。**
比如说有一次我负责一个小项目激进的采用了刚开始流行的React框架如果使用熟悉的Angularjs框架正常来说一个月就能完成当时很乐观的觉得React和Angularjs也差不多时间应该不会多出来太多就按照一个月时间来做项目计划。
最后到实际开发的时候发现React和Angularjs有很多不一样的地方必须要现学现用原本计划一个月完成的最后加班加点拖到一个半月时间才完成。
在这个项目中,使用新技术就是一个风险:
- 造成的损失就是导致了进度延误;
- 发生延误的概率如果项目开始前估算大概在60%左右项目进行中这个概率就上升到80%了。
像软件项目中这样的风险,如果发生后就会变成问题,问题如果没有及时解决,就会影响到项目计划。如果我们能有效的对风险加以识别,加以管理,就能减少对项目的负面影响。
>
风险管理就是指在项目进行过程中,识别可能的风险,对风险进行评估,并加以监控,从而减少风险对项目的负面影响。
## 风险管理重要吗?
对于风险管理,现在软件项目中提起的不多,应用的更少。
主要原因还在于大家都比较乐观,多少有一定侥幸心理,都觉得自己不会运气那么差,风险事件正好就发生了。还有就是因为如果要做风险管理,需要额外多做一些工作。
这就跟你买保险的道理一样,风险事件没发生,相当于你买保险的钱白花了,但是一旦发生了,你才知道买保险的钱花的值得。
**对软件项目风险的管理,才是体现项目管理水平的地方。**我们对比下面几种应对风险的层次来看:
- 被动应对:风险已经发生,造成了问题才被动应对;
- 有备无患:事先制定好风险发生后的补救方案,但没有任何防范措施;
- 防患未然:对可能的风险做出防范,并把风险防范作为项目任务的一部分。
哪一种层次更体现项目管理水平,相信你心中已经有了答案。
拿前不久发生的拼多多被“薅羊毛”事件来举例。
>
2019年1月20日凌晨拼多多平台出现系统漏洞用户可以领取100元无门槛券。因此开始出现大批用户借此“薅羊毛”利用无门槛券下单虚拟商品例如充话费或Q币等等并一度有消息传出拼多多将因此损失200亿元。
这个事件追究原因的话,当然可以说是开发代码没写好,可以说是测试没测好,也可以说运维没有监控好。
但另一个角度讲,如果这个项目的负责人有一点风险意识,做了风险管理,即使出现这样的问题,损失也一定不会这么大。
## 如何做好风险管理?
#### 1. 培养风险意识
风险管理其实最大的问题不是如何做,而是项目成员缺少风险意识,有了风险意识,才能去识别出来项目中可能的风险,进而去管理风险。
对于培养风险意识,我的经验就是:**项目中的任务不能盲目乐观都思考一下它最坏的结果是什么如果最坏的结果不能接受就说明要有个B计划考虑风险管理了。**
比如说拼多多的无门槛券,最坏的情况是被无限刷,造成巨额经济损失,那这种结果是不能接受的,就需要考虑风险管理。
#### 2. 管理风险
软件项目风险管理,通常分四步来做。
**第一步:风险识别,识别可能的风险**
风险识别,就是看项目中有哪些可能的风险,因为只有找出来有可能存在的风险,才会有后续的步骤。
识别风险这种事经验很重要因为大部分风险其实都是相似的。以前看CSDN总裁蒋涛发过一条微博内容引发了很多人的共鸣每一条无不应对着软件项目中的常见风险。
>
**10个项目死亡的信号**
<ol>
- 第一版做太多功能;
- 太依赖新技术平台;
- 与公司另一个有份量的产品竞争;
- 团队人手不足;
- 复杂的问题,需要复杂的解法;
- 成员开始隐藏进度落后的事实和原因;
- 不断更改、增加的需求
- 2.0 症候群-非要更大、更强、更美
- 产品没有市场立足点;
- 你根本无法解决的大问题。
</ol>
一个识别风险的方法叫**检查表法**,就是可以把类似于上面这些常见风险收集整理起来,分类列成清单,按照清单去检查对照。
软件项目的风险主要分成以下几类:
- 项目风险:项目预算、进度、用户和需求等方面的问题;
- 人员风险:人员离职、人手不足等问题;
- 技术风险:采用的技术所可能带来的风险;
- 商业风险:与市场、产品策略等有关的商业风险。
你也可以按照上面的分类整理出自己的风险检查表。
另外你还可以借助集体的智慧,定期针对风险问题开一些头脑风暴会议,一起发现可能的风险。另外,要有合适的渠道,让项目成员可以反馈可能发生的风险问题。
**第二步:风险量化,对风险进行评估量化**
在风险识别出来以后,需要从两个方面去评估:
- 发生的概率多大?
- 发生后,后果多严重?
对于概率大,后果严重的风险,需要高优先级重点考虑;对于概率不高但后果严重的问题也要考虑,不过优先级略低;对于概率高但后果不严重的风险事件,可以优先级很低或者不考虑;对于概率低后果不严重的,则可以不予考虑。
拿拼多多的“无门槛券”来说,这就属于一个高风险、高概率的事,需要重点考虑。
**第三步:应对计划,对风险制定应对策略**
在评估后,需要后续进一步考虑的,就要制定好应对的计划。针对风险,主要分成以下几个策略。
<img src="https://static001.geekbang.org/resource/image/1f/d5/1f0834c11f675e1846779134746903d5.jpg" alt="">
- **回避风险——更改导致风险的方案**
回避风险很好理解,就是要对可能发生的风险,放弃或者修改导致风险的方案。这样就从根源上消除了风险,简单而彻底。
就像我前面举的因为使用React技术导致风险的例子可以直接放弃使用React用回熟悉的Angularjs技术这样就可以避免技术风险的发生。
但这种方案不一定适合所有情况,例如拼多多“无门槛券”的风险,就无法采用这种方案。
- **转移风险——将损失转嫁出去**
以前玩大富翁游戏,最开心就是有一张“嫁祸卡”,万一遇到倒霉事就可以转嫁到其他玩家身上。转移风险也是这个思路,就是为了避免承担风险损失,将损失转嫁出去的方法。
日常生活中买保险就是一个例子,发生意外,保险公司会帮助赔付。
在软件项目中,举例来说,如果你的团队对于服务器管理不是很在行,有可能会遇到服务器宕机或数据库丢失数据等风险,就可以考虑购买云服务,这样云服务商会帮你解决服务器宕机或数据库丢失的问题,而且万一宕机或丢数据了他们也会承担一定的责任。
- **缓解风险——降低风险发生概率或减少可能造成的损失**
缓解风险就是在风险发生前采取一定措施,降低风险发生的概率,或者减少风险可能造成的损失。
比如你要担心数据库数据丢失的风险,就需要定期备份数据库;比如你担心核心成员要离职,那就涨点工资,避免人才流失。
拼多多的无门槛券也是个典型的例子如果对券的消费增加一定的限制比如说每个用户有领取的上限一个月不能超过100张每张券不超过10元不能用于购买Q币手机话费等虚拟物品这样即使出现问题也不会造成很大损失。
我们在《[04 | 瀑布模型之外,还有哪些开发模型?](http://time.geekbang.org/column/article/84054)》中学到了“螺旋模型”,也是这种策略:每个迭代都要做一下风险评估,再决定项目是不是继续。
- **接受风险——明知山有虎偏向虎山行**
还有一些风险本身很难避免,或者去应对这个风险的成本超过风险发生后造成的损失,那么就没必要应对,直接选择承担风险后果就好了。
比如说前面说的采用新技术React导致进度延迟的案例这个风险虽然有很大概率发生但是进度延迟的影响可以接受并且让团队今后在技术栈上多了新的选择长远来看对项目更有利那么这个风险就是可以接受的还是可以继续做下去。
回避风险、转移风险、缓解风险、接受风险,以上就是针对风险提前准备的一些应对策略,实际项目中,可以根据实际情况来灵活运用以上策略,有效应对风险,减少可能损失。
**第四步:风险监控,对风险进行监控预警**
风险在没发生的时候并不会变成问题也不会造成损失,如果风险可以监控,可以预知风险即将发生,或者可以在风险发生后,第一时间知道,那么就可以马上对风险进行干预,避免变成更大的问题。
要做好监控,第一要能对监控的内容量化,第二要设置阈值,第三就是要有后续的报警和处理机制。
很多公司都已经建立了自己的监控系统,将关键数值量化,并设置阈值,超过阈值后自动触发报警机制。
一个简单的例子就是服务器宕机了,监控系统发现机器没响应了,自动通过邮件、短信、电话等方式通知正在值班的人员。
还有稍复杂一点的方式,像网络服务,可以监控每一次请求结果的状态码,统计请求的成功率。如果单位时间内,服务出错的比例低于阈值,那说明服务是正常的;如果错误比例超过阈值,那说明是出现了问题,需要报警通知相关人员,马上处理。
再回到拼多多“无门槛优惠券”的例子,其实有很多数据可以监控到,比如说单位时间内优惠券使用数量,商品销售数量等,如果结合一些可视化视图,应该可以直观地看到当时有大量虚拟商品销售,大量的优惠款被使用。
如果针对优惠款设置了阈值例如每分钟使用超过1000张就触发报警那么也可以及时发现无限刷的问题避免造成更大损失。
以上四个风险管理的步骤是一个连续循环的过程,在整个项目期间,都要持续地对风险进行识别,对风险量化,对于风险采取应对计划,对风险进行监控。
<img src="https://static001.geekbang.org/resource/image/11/30/11b6e81fd2baffcb0c025bb56c71e130.jpg" alt="" title="项目风险管理过程">
## 总结
今天带你一起学习了软件项目管理中的风险管理知识。软件项目中的风险就是指那些不确定的但是可能会造成消极影响的事件,通过对风险的管理,可以有效降低风险发生的概率,减少风险发生后的损失。
软件项目风险管理包括风险识别、风险量化、应对计划和风险监控四个过程,这四个过程是一个循环的过程,需要在项目中持续进行。
希望你在学习后能提高风险意识不能盲目乐观凡事都应该有B计划。并且能将学到的风险管理知识应用到项目中做到对可能的风险了然于胸未雨绸缪运筹帷幄。
## 课后思考
按照风险管理的知识可以对你目前项目中按照发生概率或造成后果列出1-3条风险并思考如何能管理这些风险。欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,190 @@
<audio id="audio" title="16 | 怎样才能写好项目文档?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/4b/c6/4b5aeb327582f1222820a1e79b30fcc6.mp3"></audio>
你好,我是宝玉,我今天分享的主题是:为什么你不爱写项目文档?以及怎样才能写好项目文档?
我以前看过一个投票,盘点程序员不喜欢的事,有两条和文档相关:
>
<p>不喜欢写文档;<br>
不喜欢项目文档太少。</p>
看起来很矛盾,却很现实。基本上大家都认同:“项目文档很重要”,然而我们在项目中总是**短期高估文档的重要性,而长期低估文档的重要性。**
结果就是口号喊的很响:要重视文档、要写好文档、要多写文档,然而随着项目的推进,总有比文档优先级更重要的任务,文档的优先级总是被有意无意推迟,导致项目的文档缺失、老旧、无人维护。
那么为什么程序员都不爱写文档呢?我总结了一下大致有下面这些原因。
- **不知道怎么写**
不知道怎么写文档的应该占很大一部分比例。
- **太忙没时间写或者懒得写**
程序员确实很忙,但总有不那么忙的时候,却也很少见有人利用这时间去写文档。包括我自己也这样,有时候没那么忙的时候,宁可去想想怎么重构下代码,却很少会愿意去写文档,主要还是太懒。
- **因为是敏捷开发,所以不用写文档?**
对于这个问题,我其实反驳过多次,[敏捷宣言](http://time.geekbang.org/column/article/84351)最后一句话明确指出:“尽管右项有其价值,我们更重视左项的价值。”也就是说敏捷从来没有否认文档的价值,只是更重视“工作的软件”罢了。
## 为什么要写文档?
写文档,其实对个人、对项目、对团队,都是非常重要的事情。
- **帮助写文档的人理清楚思路**
我想你应该有这样的感受:写作的过程,就是一个思考的过程。
写文档,可以让你在写代码之前,梳理清楚思路,想清楚整体结构,比如说有哪些工作是重点难点;哪些要依赖其他人,需要及早协商的;哪些是要考虑安全性的。
如果上手就写代码,就很容易陷入到某个技术细节中,而忽略了整体结构。写的时候才发现一个技术难点无法解决,或者已经在某个不重要的细节上浪费了很多时间;或是发现有些依赖其他人提供的服务还没准备好;又或者是上线后才发现有安全漏洞。
**先写文档,就会抛开代码细节,去站在全局思考。**写的时候,各个模块之间的依赖关系、各种可能的安全隐患、各种可能需要其他人配合的地方,就都冒出来了,必须要去查资料,去找人讨论,反复缜密的思考后最终写出来。
有人觉得自己写作不行,所以不会写文档。写作不行,只是让你在用词遣句上会有所欠缺,而这不是写文档的真正障碍。
**真正的障碍是没想清楚,在心中只有一些未成型的混乱的想法和概念,必须要努力把这些模糊的想法确定化和具体化,才能写出来。**
**换个角度来说,如果你连文档都写不出来,那又怎么能指望代码写得好呢?**
- **便于未来的维护和交接**
“好记性不如烂笔头”,存在脑子里的内容是不可靠的,一个正常的项目组,如果需要长期维护,就需要一定的文档,把设计、操作流程、环境配置等内容记录下来,而不仅仅依赖于口口相传。
我有一个习惯每到一个新项目组就会把日常工作中遇到的问题、各种环境配置、一些操作的步骤等所有以后可能还会用上的都记录下来其中一些还会整理到团队的WIKI上。
一段时间后,这些随手记下来内容都会发挥大作用,对于我来说,很多问题就不需要问第二遍了。对于团队来说,随着人员更替,我记录的这些内容都是最好的一手资料,有新人过来,按照我当初记录的内容,就可以快速上手。
- **便于团队更好的协作沟通**
在一个项目组中,大家都有不同的分工,有人负责产品设计,有人负责架构设计,有人负责测试。而文档,就成为了团队成员很好的沟通工具。
比如说产品设计有雏型的时候,会有一个产品设计的评审会议,基于文档,项目成员可以一起参与其中,提出自己的意见和看法。这样就不至于等到产品设计出来之后,大家才对于设计有改进想法或意见,造成无法更改的结果。
当然,写文档还有很多好处,在这里我就不一一列举了。
## 如何写好文档?
其实文档的重要性真不用多说,很多人也不是不爱写项目文档,而是不知道该如何写好文档。所以在这里我来介绍一下该如何写软件项目文档。
很多人对于写文档是有心理压力,觉得自己写作水平不高,不知道该如何下手。首先你要对文档有一个正确的认识:文档写作,关键是通过文档把你的想法表达出来,至于用词、格式相对都是其次的。
打个比方,我们如果是大厨给餐馆做菜,得追求个宽油大火、色香味俱全,自己在家做饭,就没那么多讲究了,填饱肚子是第一要素,在这个基础上味道好一点就很好了。
我们写文档就像是在家做饭,是不需要追求太多华丽的词藻,也不需要追求字数,只要用简单的文字、图表把想法表达出来,最终在讲解的时候,配合一些口头说明就可以啦,其实比我们上学时写作文容易多了。
下面给你介绍一些具体可行的文档写作方式。
**1. 从模仿开始**
前面有提到,我其实一开始是不知道如何写文档的,直到毕业两年后,我在飞信项目组,领导让我写一个新项目的技术方案文档,我两眼一抹黑说不会写呀,然后领导给了我另一个项目的技术方案文档,说你就“照葫芦画瓢”照着写吧!
“依葫芦画瓢”就简单多了,同时又学习了一下如何画线框图、时序图等图形,很快就完成了一份技术方案文档,再反复修改几次,质量就还可以了。
后来我带团队时,让团队成员写文档,就把当时我写的文档给他们参考,很快他们也能写了。包括后来我写开源项目([angular-ui-tree](http://github.com/angular-ui-tree/angular-ui-tree), [react-video](http://video-react.js.org)),要写英文文档,也是去找了几个同类的开源项目的文档,参照他们的内容和格式,就把文档拼出来了。
**模仿就是最好的写文档方式**,尤其是现在网上可以参考的例子也很多,当你写文档不知道该如何下手的时候,不妨去找一个类似的文档,模仿着写试试。
** 2. 从小文档开始**
一开始写文档,内容不需要很多,可以从小的文档开始。就像前面我提到的,记一些笔记,不要在意格式,一两句话,一些截图,就是不错的笔记。
有一次和同事一起去开会,会上他给另一个组的人介绍了如何调用一个服务,介绍的很详细。我就建议他把刚才介绍的内容写成个小文档,这样下次再有类似会议就可以基于文档来说。
于是他就整理了一个简单的文档,再为别人讲解的时候就基于文档介绍,容易很多。同时,他每次还会再完善一点内容进去。之后再有同类问题时,他直接把文档发给人家就好了,都不需要再专门开会。
项目中很多文档都可以从这样小的内容开始:别人给你讲一个问题的时候记录下来;你给别人讲一个问题的时候记录下来;解决一个技术难题时记录下来方案……
这些记录下来的笔记,稍加整理,就可以是很不错的项目文档。
**3. 从粗到细,迭代更新**
小时候写作文,老师给的最多的建议就是要列提纲,这个建议我小时候当耳边风没怎么听,后来要写项目文档的时候用起来反倒觉得非常实用。
我写一个大一点的文档都是从脑图开始的先基于脑图把基本结构梳理清楚。然后第二步就是写PPTPPT有个好处就是不用太多文字列个一二三画几张图就是个简单的文档PPT还有个好处就是可以用来给别人讲解收集反馈。
写完PPT也收集好了反馈再写正式的文档。先按照脑图列的提纲把主要章节放上去然后把PPT上的内容和画的图放到文档中一篇文档的骨架就搭好了剩下的就是对细节的补充了。
为什么我不一开始就写很细的文档呢?
一个原因是太难写,要花很多时间精力,甚至可能写不下去;另一个原因就是在收集反馈的过程中,会有很多修改。**写得越细则无用功越多,最后,你甚至会因为不想改文档而抵触不同的意见。**
而从粗到细逐步迭代的方式就好多了,一开始的目的是为了梳理清楚思路,只要脑图这种级别的内容就好了,然后进行调整。因为文档很粗,调整也方便,等到基本确定后再写细节,就不会有大的反复。
**4. 一些基本的画图的技巧**
有人说:“字不如表,表不如图,一图胜千言”。这个观点我非常认同,好的图能帮助你简单而直观地把问题说明清楚。
画图其实不复杂不需要多专业的绘画技巧也有很多工具软件可以帮助我们简化操作像Visio、PowerPoint、Keynote、OmniGraffle等都是很好的画图软件。平时看到好的图也要注意收集整理以后自己写的时候也可以直接参考可以帮你少走弯路。
写文档的时候,主要有几种图比较常用:线框图、流程图、时序图、各种格式的截图。
- 线框图
线框图是最常用也最实用的一种图形,用简单的方框代替功能、模块、服务等,再用箭头表示关系或者数据流向,非常简单直接。
要画好线框图并不难,主要是要理清楚有哪些模块,以及模块之间的关系是什么。用方框配上文字表示模块,方框之间的连线和箭头表示关系。
看几个例子:
Twitter当年的缓存方案。
[<img src="https://static001.geekbang.org/resource/image/17/fb/1789cf7139c74de3a5667d50dd8406fb.png" alt="" title="图片来源InfoQ">](http://www.infoq.com/news/2009/06/Twitter-Architecture)
Netflix 的账单系统架构图。
[<img src="https://static001.geekbang.org/resource/image/d1/4e/d11279dd5d943264f190c22578b21e4e.png" alt="" title="图片来源Netflix技术博客">](http://medium.com/netflix-techblog/netflix-billing-migration-to-aws-451fba085a4)
- 流程图
流程图是软件项目文档中一种常用图形,可以方便的表示各种不同条件下的逻辑路径。**要画好流程图不难,重点是要理清楚逻辑关系,各个关键节点在不同条件下的走向。**
例:重置密码流程图。
<img src="https://static001.geekbang.org/resource/image/c3/fa/c310f2fdef032b99c659deac5857d2fa.jpeg" alt="">
- 时序图
时序图也是软件项目所特有的一种图形,可以表示不同对象之间发送消息的时间顺序,尤其在涉及网络通信的文档中特别常用。
画好时序图,关键是要列清楚所有涉及的对象或者服务,以及消息发送的先后顺序。
例:注销登录过程的时序图。
<img src="https://static001.geekbang.org/resource/image/02/5f/0234da35f3bc080864a99d5ea755e25f.png" alt="">
- 各种格式截图
截图也是个非常简单直接的方式把软件的UI、交互设计的效果、数据趋势图、数据统计图等直接截图必要的话配上一些箭头、文字也可以很好的说明清楚问题。尤其是产品设计文档经常用到。
上面就是如何写文档的一些具体建议,按照上面说的方法做,写好项目文档不会是多难的事情,你还可以在日后的工作中,不断学习不断改进。
## 一些关于文档的其他建议
有时候我也看到一些比较极端的情况,就是过于追求文档,项目中要花大量的时间写文档,而很多文档是形式化的,并没有太大意义,可能写完了不会用来讨论,也不会有人看。
所以我是比较认同敏捷宣言观点的:文档很重要,但是工作的软件高于详尽的文档。这里面的平衡很重要。
不需要为代码写很多文档,好的代码格式,良好的注释、完善的单元测试可以很大程度上代替针对代码而写的文档。
Markdown是一种非常好的文档格式可以让你更专注于内容上而不是文档格式上面。
在线文档工具优于离线文档工具在线文档有很好的版本管理也更方便多人协作。像GitHub WIKI、石墨文档、Google Docs、Evernote等都是非常好的在线文档工具。
对于文档的撰写,要作为一个正规的项目任务进行,安排人、安排时间,放到项目计划中去。就像前面说的“懒得写”文档的情况,一旦把文档当成一个与开发同等重要的任务去执行,就没有借口去犯懒了。
**重要的是,文档的写作一样需要多练习,写的越多,就越熟练。**
## 总结
今天,带你一起分析了为什么不爱写项目文档的原因,也解释了为什么写文档很重要。
没时间写或者懒,不能成为不写文档的理由。对于重要的项目文档,就应该加入到日常的开发任务中,把写文档,摆在和设计、开发同等重要的位置。从某种角度来说,写不好文档,代码也很难写好。
针对程序员不爱写项目文档的情况,我也提出了切实可行的写文档的方法。比如说不会写,就可以从模仿别人写的文档开始,然后从粗到细,不断迭代,配合一些图表,就可以写出不错的项目文档。
## 课后思考
你所在的项目组,项目文档情况如何?你写文档吗?有没有什么写文档的经验和大家一起分享的?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。