分类存档: 软件项目和团队管理

软件项目管理之零:预算

No estimation,no management !

我曾经的领导Loic如是说。

记得在一次项目流程改善评审会议上,我们项目组的同事试图给法国领导解释“虽然我们没有做预算,但是我们在管理项目”,这位法国领导平常是客气的人,却有些恼火地说 “No estimation, no management ! I don’t know how you manage it !”

对这句话我深表认同,连预算都么有,你说你在做管理,这就像地基都没有打,就在建高楼。

项目管理的本质其实就是PDCA,先做计划,然后按计划执行,同时定期检查,发现偏差,制定行动计划。所以,项目管理的第一步是做计划。而没有预算,我们连计划都做不了,何谈管理。

所以,项目管理的第零步是:做预算。

Why ?在讨论为什么之前,我们先讨论下what — 什么是预算 ?

什么是预算:预算要解决的问题

  • 评估客户需求,找到合适的技术解决方案(硬件方案:MCU等芯片选型;软件方案:相关软件模块的选择)
  • 评估技术方案实施的难度、风险和成本,以及开发周期
  • 给项目组提供决策依据(这个项目值不值得做)

为什么要做预算

我们不妨换个角度,尝试回答下“如果没有预算,下面的问题怎么办:”

  • 客户的需求我们能实现吗?
  • 有哪些软件模块可以从之前项目复用?需要用到哪些新的功能模块和技术?
  • 芯片的RAM/ROM/CPU load 够不够用,会不会在项目后期要更换芯片?
  • 这个项目可能有哪些风险?
  • 有哪些法规需要遵循?
  • 需要采购哪些工具和软件模块?什么时候采购?向谁采购?要多少钱?
  • 要给这个项目安排多少人力?项目各个阶段人力怎么分配?
  • 开发这个项目要准备多少现金投入?

所以,只有当我们做了预算,我们才有信心去做这个项目。

做预算的误区

对于预算,你可能会有下面这些想法:

  1. 我没办法做预算 ,因为客户需求不明确。
  2. 反正我们的预算从来没准过,干嘛要认真做预算。
  3. 我得把余量加多点,不然项目又会超支
  4. 我不把预算做低点,怎么能拿到项目?客户就给这么多钱!

我想说,这些都是误解。我们不妨来一项一项来看看。

1. 我没办法做预算 ,因为客户需求不明确。

不要忘了,预算要做的一件事情就是寻找合适的解决方案,而找到这个最佳解决方案的过程实际是和客户一起探索的过程,我们需要了解客户真正想要的是什么,客户能接受的底线是什么,价格是最重要的还是功能是最重要的。

而从客户的角度看,你的报价也是他们做决策的依据。功能可实现,但造价太贵,可能客户需要放弃功能而采用更有性价比的方案;也可能客户会考虑在旗舰车型上配置这个功能。但在客户做决策前,他需要你的数据。

我们不可能预知未来,我们只能基于当前你了解的情况和你过往的经验,再加上合理假设,对未来做出预估。

所以,你的预算是基于假设的。

虽然你明知预算是基于假设的,会用来做决策,但是不用担心,只要清晰说明你基于什么样的假设就好了。毕竟没有什么事是百分之百的把握才做的,更何况有百分之百的把握也不一定做成。譬如挑战者号航天飞机。

2.反正我们的预算从来没准过,干嘛要认真做预算

这看起来是个不做预算的好理由。这句好就好像是说:人生的不确定性太多了,我也不知道接下来会发生什么,所以,我干嘛要做人生规划呢?

No estimation, No management !

即使你做了预算,事情也不会100%按着你的规划进行,但是,会出现一条基线,事情会在基线附近波动。但是如果没有预算,你连现在走到哪里了都不知道,要去到哪里也不知道。

最重要的是,我们要知道 where we are, and where we go !

3.我得把余量加多点,不然项目又会超支

这是个好理由,但不是解决问题的办法。

为什么说是个好理由呢?我们做上一个项目估算6000个小时,结果花了10000小时,而且按照经验,我们总是会花超,所以,我们要多加点buffer(余量)。 所以,以前的项目超支是因为我们估算少了?实际情况是这样吗?或者实际情况是我们的人力成熟度不够?(在估算模型中我们会再讨论标准工时和人力成熟度因子。)这里,重要的是:我们要识别之前项目超支的原因,并找到改善的方向,而不能含糊地把它归结为故少了。一旦这样做,就还暗含了一层意思:我们只能做到这样,这样的生产效率就是我们的正常水平。

不增加buffer,那我怎么办

找到之前项目超支的原因,找到你担心的真实问题,将它们作为新项目的风险点,列入风险管控中,给出解决建议,以及可能产生的影响。

4.我不把预算做低点,怎么能拿到项目?客户就给这么多钱!

嗯,这确实是个无法拒绝的理由。我严重赞同。

赵本山的小品《不差钱》里有这样一段台词:人最痛苦的是什么,人死了,钱没花完。人最最最痛苦的是人活着,钱没有了。

所以啊,我们做报价也是一样,最痛苦的是报价太贵,拿不到项目;最最痛苦的是报价太低,拿到了项目,发现做不了(越做越亏)。

报价高低和拿不拿项目其实是两回事,一个是技术问题,一个是商务问题。即便利润低,公司也可以因为战略考量拿项目,甚至亏本拿项目。而预算是(且只是)决策的依据之一(只是之一,不是全部),所以在预算阶段不能把决策阶段要做的事情给做了。不然,大老板们做什么?

预算就是要给决策提供真实可靠的依据,所以,预算必须尽可能准确,不是故意多加buffer,也不是故意压缩。

当然这里会有个问题,那就是,预算确实太贵了,没有竞争力。这也确实是我们经常遇到的现实情况。但降低成本,提高竞争力不是做预算时才考虑的问题,也不是做预算时能解决的问题;实际上降本增效是研发管理最核心的工作之一,而且是一个持续活动。

怎么做预算

1.做预算的前置条件

我们先回顾下,预算要解决的问题:

  • 评估客户需求,找到合适的技术解决方案(硬件方案:MCU等芯片选型;软件方案:相关软件模块的选择)
  • 评估技术方案实施的难度、风险和成本,以及开发周期
  • 给项目组提供决策依据(这个项目值不值得做)

那么,做这些事情,我们需要哪些输入呢?

  1. 客户输入:我们得知道到底要个啥?这玩意都有哪些功能?有没有特殊要求,譬如Function Safety,Cyber Security。

这里我们应该拿到 Statement of Work,Compliance Matrix,比较好的情况是我们可以拿到非常文档的开发需求,而且几乎是最终产品开发需求;而比较糟糕的情况是,我们拿到的是客户自己都搞不清楚的东东。

  1. 系统的输入:有些团队系统和软件是没有区分的,我们这里的情况是区分的。这里系统需要输入给软件的是系统级的架构设计,需求分解。客户的需求可能是针对整个产品的,而我们的ECU只是整个产品中的一部分,这时候我们的系统就需要区分哪些是我们ECU的需求,哪些是其他ECU的需求;在确认了我们ECU的功能之后,系统还需要考虑系统级的设计,将功能分解到硬件,软件,机械件。譬如在硬件团队和软件团队的支持下,确定芯片选型;譬如确定按键滤波是由硬件完成还是由软件完成,……。

这里我们应该拿到System Block,System Feature List, 系统级的FVS(Fix,Variable,Specific)分析。

  1. 客户的项目开发计划:什么时候启动项目,什么时候定点(确定供应商),什么时候第一版交样,什么时候SOP。项目开发计划对最终是否能拿项目也非常重要,主要与这几方面因素有关:
    • 新技术的研发成熟度:客户要求1年量产,但是产品的研发成熟度还需要两年才能达到量产水平
    • 人力情况:新项目需要10个工程师,但是当前团队所有人员都是满负荷工作,而且当前项目里SOP还远;同时当前时间点招聘很难。那么,拿新项目就很困难。这种情况可以考虑是否可以从公司层面协调资源。

通常第一版交样非常有挑战性,主要是因为一方面由于各种原因,客户的计划在报价阶段就会延迟,但是整车开发节点不会变(因为上市日期不能变);另一方面,公司内部通常只有在拿到项目后才会启动项目(开始花钱);所以,最后的结果就是研发要在短时间内释放一个有基本功能的样件给客户。

有了这些输入,你可以开始做软件的预算了。

2.做预算时,我们要考虑哪些因素?

先说说预算最终的输出是什么。

是什么呢?

钱!要花多少钱,以及这些钱是基于哪些假设算出来的。

这些钱包含两部分:开发工时 + 现金投入。开发工时有时候可能是几千,甚至是几万,而现金投入有时候可能是几十万,甚至是几百万。在讨论这些这么大的数据是怎么算出来之前,我们先看看在做算的时候我们都考虑哪些因素:

  • 选定技术方案:芯片选型(主控芯片,接口芯片,驱动芯片),通信接口(硬件接口,如UART,SPI,IIC,Ethernet,USB,CAN,LIN;软件协议接口:CAN/CAN FD, 通信协议,以太网应用层协议RTP/SOMEIP等)
  • 考虑Critical Resource:RAM,ROM,CPU,EEPROM/DataFlash
  • 考虑软件架构:整体架构(Autosar, 非Autosar),模块划分,分析哪些模块可以复用,哪些模块可以使用标准组件,哪些模块需要自行开发。对技术方案和软件架构的考虑最后都会体现在软件模块上。
  • 考虑软件开发流程:使用什么样的开发流程,这样的流程需要哪些投入,包括时间投入和工具投入
  • 考虑软件的整体复杂度:复杂度高,工时肯定会更多。
  • 考虑团队的人力成熟度:如果人力成熟度偏低,那么工时肯定会花得更多,所以预算中应该如实体现。
  • 考虑需要哪些工具:哪些需要购买,哪些可以协调
  • 考虑需要采购哪些软件组件:OS,FBL,Autosar组件,通信组件,有免费开源组件?

上面说了这么多,都是正确的废话。下面我们就来说说最有意思的部分——怎么算。

3.怎么做——强大的评估模型

怎么将上面提到的这些预算中要考虑的因素组合在一起呢? 各种因素之间怎样进行关联呢?我具体要怎么做呢?

告诉你个好消息,在我们产品线,我们有一套强大的评估模型。有多强大呢?上面所有的因素都以被评估模型考虑在内,而且评估模型基于过去二十年的项目数据统计给出评估建议。很NB,有木有?

这个模型长什么样子呢?是不是一套AI算法?还有个炫酷的界面,输入参数就得到了评估数据?

No,可能让你有些失望,这个模型就是个包含了一些公式Excel文档。

但好消息是,它简单易用。(这句话的意思是会则不难^_^。)说它好用是因为,只要你照着流程一步一步做,所有上面的哪些因素都自然而然地考虑在内了 。

4.怎么做——静态架构设计

这个部分,我们要做的就是根据客户需求,系统需求,来选择解决方案,并将解决方案转化为软件架构和软件模块。

具体怎么做呢?

额,比较复杂。

简单来说,对于比较成熟的产品,我们依葫芦画瓢就行;对于新产品,这需要你在架构方面的经验,而且是丰富的经验,深厚且宽阔的知识背景。

具体来说,根据System Feature, 我们要确定需要哪些SW Feature,然后,要实现这些SW Feature需要哪些SW Architecture Element。

在这个阶段要完成客户需求分析,确认需求是否可以接受,是否可以是实现;然后完成基本的静态架构设计。

关于今天架构设计,更具体的就留给我们更有经验的架构师吧。

5.怎么做——FVS分析

有了软件架构,接下来就要做FVS分析,什么是FVS?Fixed,Variable,Specific,其实就是看看这个架构(解决方案)中哪些是我们熟悉的,哪些是完全可以照搬以前的代码,哪些是要基于以前的代码修改,哪些是要重新设计实现。(注意:不只是代码,还包括相关的设计和测试。)FVS分析的对象是Architecture Element 的构成单元:SW component。

FVS分析会给出一个关键参数“Weight”,这个Weight有什么用呢?它会最为一个倍数因子,用来计算最后的工时。具体Weight怎么影响工时,就隐藏在我们的评估模型 Excel 模板中。简单来说,可以将Weight理解为软件开发的难度。

6.怎么做——Critical Resource 计算

接下来就可以做Critical Resource评估了。这里的Critical Resource是指RAM,ROM,CPU load。这个评估主要要依赖评估模型(Excel模板)。

要想评估一个软件整体会占用多少ROM,RAM,CPU load,我们需要将软件模块拆分,评估每个模块的资源占用,而每个模块的资源占用怎么得到呢?这就要依赖评估模型(Excel模板)。

在模板中已经有一些基础数据,这些基础数据都是根据经验得到的(对过去项目的模块实际测量得到)。而这些经验数据也做得非常细致,譬如标准按键驱动模块,经验数据会分成如下部分:

  • base(模块基础代码)
  • 按键个数
  • 要检测卡滞的个数
  • 要检测长安的个数
  • 组合键的个数

在做预算时,只需要根据新项目的信息配置就可以得到比较准确按键驱动模块的资源占用情况。另一方面,根据经验,一行代码通常占用大概3个bytes(视编译器和芯片而定),从而可以估算出代码行数(后面用来估算工作量)。

到此,事情看起来很完美。但是,这些都是基于经验的,那如果这是一个新模块怎么办?

如果这个全新的模块是采购的,那请供应商提供相关信息。如果这个模块是需要自己开发,那就要根据经验评估,看看之前有没有做个demo,有没有类似的功能的软件,它的大小是什么样的。这时候最关键的是要边做边看,要投石问路,弄套环境,写些mockup代码试试看,你就知道了。

7.怎么做——研发成本评估

研发成本分为两部分:人力成本,即工时;现金投入。具体来说:

  • 首先,从代码/软件模块的角度评估每个模块需要多少工时。这部分又分为两块:一块是软件模块标准工作流对应的工时,一块是软件模块对于这个项目额外需要的工时,譬如标准直流电机驱动需要开发PulseCounting 反馈功能。这里的软件模块就来自于静态架构设计。
    • 对于标准工作流部分,根据模块的类型(OS,HWI,标准组件,全手写,复用,建模自动代码生产,外购的软件包,第三方和客户提供的模块)等相关参数(代码行数,对于模型考虑接口个数,对于复用模块考虑复用程度)和Critical Resource评估部分的资源评估用公式自动计算得到开发该模块需要的具体实践,譬如需求分析需要多少小时,模块设计,编码和单元测试,集成测试,验证测试,维护 各需要多少工时。
    • 对于模块的额外工时部分,需要评估需求分析,设计,编码和单元测试,集成测试,验证测试各个流程的工时。
  • 然后,从任务的角度考虑将这些模块如何划分成任务包(Increments),在这个划分的过程中还会考虑有没有什么任务是没有包含在代码/软件模块中的。
    • 在上以步中,同时会将软件模块划分到不同的Increment。关于Increment,可以简单的理解为一个任务包,在项目开发过程中可以把这个任务包中的所有事情分给一个人工程师完成。
    • 在这一步,我们可以通过Excel自动得到每个increment各个软件工序的工时统计。同时我们需要考虑每个increment安排在开发周期的哪个阶段。(关于软件开发周期又是另外的话题了。)还要考虑每个increment要安排个哪个site开发。
    • 另外,还要考虑每个increment的技术复杂度和人力成熟度,譬如这个模块技术上非常成熟,团队也非常熟悉这个模块,那么对应的工时应该适当下调,反之则应该对应上浮。具体上下调多少呢?看情况,凭经验。
    • 然后还要考虑increment可能相关的其他事情,譬如某个increment前期由欧洲团队开发,后期要转移给亚洲团队维护,那么交接活动的相关工时应该在这里考虑。又或者这个项目要同时准备一个单独的demo给客户做演示,相关工时也可以考虑在这里。
  • 第三,考虑一些独立于代码和模块开发的全局性任务,譬如软件准备,需求概要分析,架构设计,动态架构验证测试,整体验证评审等。
    • 这里的全局性任务通常已经由评估模型定义,且工时也是评估模型自动计算得到的。在这里我们需要根据实际情况调整技术复杂度因子和人力成熟度因子,得到更贴近实际项目情况的评估。
    • 这里还需要注意,评估模型在计算全局性任务的工时考虑了项目整体的复杂度 Weight 指标,也就是说项目越复杂,全局性任务的工时就会越多。所以,这里要把FVS分析时得到的Weight 指标输入给模型。
  • 第四,根据项目的开发节点和开发阶段,将上面从任务角度考虑的工时分配到各个项目开发阶段,同时计算该阶段需要的项目管理和配置管理工时。对于多site开发的项目,在这个部分同时也会汇总出来各个site的工时汇总。
  • 第五,根据各个site的工时价格,计算得到人力成本。
  • 第六,考虑其他现金投入,主要包括要购买的工具,譬如仿真工具,调试器,编译器;要购买的软件包,譬如通信协议栈,OS,FBL,算法包等;要外包给内部或外部供应商的其他开发业务,譬如Polyspace静态代码分析等。这里有一点需要注意,不花钱但要用到的工具,软件包最好也列在这里,说明这个条目有考虑到,从而避免遗漏。

8.怎么做——检查清单

理论上来说,经过上面的评估,你已经得到了你基于“客户的需求+内部的技术方案+你的评估假设”而评估出来的软件研发成本。还需要做什么呢?还需要对着检查清单查漏补缺,检查是否有报价阶段应该考虑却忘了考虑在列的项目。而这个检查清单则来自于团队的知识积累。

9.怎么做——Offer

上面得到的数据及其计算过程和依据都是工程的语言,现在你需要将这些总结下,转化为可以于项目组和客户沟通的语言,简明扼要的说明:

  • 为你的报价划定边界:你所理解的项目范围是什么(客户要什么,不要什么)
  • 为你的报价申明前提:客户的输入是什么(包括功能需求,时间节点),你的假设是什么(包括技术方案,不清晰的需求条目等)
  • 提供你的评估结果,包括:工时和现金投入,项目风险等级,嵌入式硬件资源占用情况评估

上面没有将风险评估,以后在项目风险管理中再讲。这里要说明的是:项目风险管理是在项目以开始就要考虑的,在项目开发的整个生命周期中都要即时管控。

10.怎么做——同行评审

虽然你工作得很认真,而且经验丰富,并且按照检查清单检查了,但是我们仍然需要进行同行评审。同行评审的目的是进一步减少因为人性的弱点造成错误的概率,进一步降低因为个体的知识、信息局限造成遗漏的概率。评审的目的不是评判你的工作能力行不行,而是尽最大努力完善工程输出。

对于软件报价的同行评审一般需要以下角色参与:

  • 软件部门主管/本site软件主管:他对整个软件团队负责,工时会不会花超算他头上,当然他要同意这个报价才行。
  • 软件专家:最好是熟悉这个产品,且未来会负责跟踪这个项目的软件专家,一方面是提供专家意见,作为软件主管的重要决策依据,另一方面是从项目开始就参与项目。
  • 标准模块团队负责人:你选择哪些由他团队开发提供的模块,所以,需要他确认改模块是否满足你的需求。
  • 其他site软件团队主管:一方面这个项目可能是多site,相关人员必须参加;另一方面,他们也会提供专家意见
  • 你:通常你的角色是软件项目经理,你是第一责任人,当然你要参加。

小结:

  • 尽可能细化任务,评估偏差会更小
  • 评估来自于经验,如果对新东西没有经验,那就要靠探索了,边走边看,投石问路
  • 虽然我们尽最大努力用数据说话,试图尽可能的客观表达,但是实际上仍然从满了主观性