【改善软件组迭代】针对当前迭代问题的解决方案(完整分析)

大纲

  • 聊的问题: 软件规划 & 工作进度问题
    • 软件无法预期发版
    • 软件发版后问题频出
  • 聊天前提: 要聊的原因
    • 我从什么时候开始面对这些问题
    • 为什么是找 boss 聊
  • 从举例开始:
    • 目标制定的过程上下脱节
    • 达成目标的过程有问题
    • 开发迭代是个恶心循环
  • 分析:
    • 上层如何定义计划, 下层的实际情况
    • 实施工程时没规划, 一步到位而非逐步迭代
  • 根源性冲突: 外界需求不断要求变化, 内部低效迭代,无法适应变化
  • 引出 “让事情解决在发生之前”
  • 解决方案

问题:

主要是聊聊咱软件规划&进度的事情,
这引起了两个问题:

  • 软件无法预期发布
  • 软件发布后问题频出

为什么我关注这个问题:

  • 一个影响很大的是, 公司无法在 需要的时间, 发布特定功能 的产品
    意味着我们工作没产生效益 (公司的盈利 | 因盈利带来的个人收益 | 想要成就一个很酷产品的这种情怀)
    意味我们过去两年工作是是失败的
    严重一点, 公司也可能无法维持

  • 直接相关的是: 因为规划与执行问题, 开发的工作让人非常狼狈(工作不舒心)
    跨组低效, 工作常打断, 做的东西反复, 我们自己折腾自己
    外部目标不断变化, 内部无法及时抽身, 弄得非常仓促

后果是, 目标长期达不成, 做东西没信心, 无动力无成就. 功能被砍, 反复折腾大家负面情绪很重.

归纳来说: 内部迭代低效, 而外部环境在不断有要求, 既无法达成目标且又不能适应变化


声明前提

这里先说一些今天找你聊这些事情前提:

  • 我关注这些事情比较久: 大概在 18 年初开始就接触这些事情, 伟星哥之前主要是技术上支持, 我得把控进度
    • 之前其实经常和杨老师讨论, 我们面临很多具体的问题: “APP 组内部管理”, “跨组功能协作”, “怎么保证不同模块测试”, “人的问题还是制度问题”
    • 这些具体的问题可能不同层面有些改善, 但整体上,却没有质的改变. 所以我尝试结合以前的思考, 从更高角度看问题

  • 问题需要自上而下解决: 为什么要聊这些事呢
    • 不是说有什么不爽, 找 boss 吐槽或者指责谁一番, 这对我没意义
    • 聊的原因:
      • 一方面是我的角度没有足够的信息, 结论不一定对
      • 另一个, 只从我或我的 leader 有些问题不一定能解决(直白点就是, 这是个自上而下的事情)

引出: 待会我会很直接的提到一些我们的问题, 目的不在于指责,吐槽. 我会给出结论的


举例

ok, 回到我们的主题, 问题涉及到这三个方面:

  • 目标制定过程上下脱节
  • 完成目标的方式有问题
  • 开发的迭代是恶性循环

我逐个举例:

目标制定

回顾之前我们的计划:
(一个不断延后的日期)
从结果来看, 目标在当时的 实际情况 下就是完不成, 目标定义的有问题.
(实际情况指的不是做出来的 客观需要时间 , 而是当时的人员,当时的制度, 当时的实现方式所耗费的时间)

负面效应是, 越来越不把目标当一回事(后面造成的效率越来越低下,节点越完不成等…), 积极性受挫.
这是目标制定上的问题

往下走, 实现方面:
xx年 xx月份能发布的承诺是开发自己评估说能给出的
很多次我们延期的工作都是这个流程:
上面定目标, 开发说行 / 勉强行 / 冲一把能行, 结果不行

啥意思, 开发自己没弄清楚过 实际情况
大家想的都是, 冲一把定个日期也许能发布, 冲一把,拼命做也许能做出来. 我称之为 迎合 目标的评估

对于上层要考虑的一件事是, 这个时间节点定下来, 是真的想要在这个时间点拿到产品, 还是一种激励手段?
如果想要产品,那拿到下层预估时, 就要清晰的知道, 这个预估是有依据, 还是在迎合(抱着冲一把的心态)
(实际情况是, 定目标的人更期望实现方说这个目标能完成)

什么叫 “实际情况”
例, 现在有个 leader, 要求我五月上线直播.
我告诉你没问题
你得想, 这家伙这么答应,
想清楚里面都包含啥了吗, 没有需要调研才能确定的东西? 没有跨组协调的风险?
他是不是抱着拼命一把的心态,一定程度迎合目标, 才告诉我这事是 ok 的

根据我的经验, 即使是 APP (大部分情况只有业务复杂性, 事情繁琐,细节多,但难度不高, 很少技术问题的情况)
都不能保证开始能想明白涉及的所有内容, 保证联调的时间,实现的效果. 只能随着实现将预估逐步收敛

但我从一线开发的角度, 都几乎没看到过有参考价值的:
《进度情况》 :我们整体需要做的有多少功能点, 做完多少,验收哪些, 剩余多少. 和其他组的依赖关系, 以及剩余的不确定因素.
《验收情况》 :所有的功能共有多少个点, 这次覆盖了哪些部分, 哪些因为 bug 无法继续, 哪些验收完毕

[真的一层一层(树状)往下想过需要的功能吗? 各功能,不同组之间的依赖理清楚吗? 需要调研才能确定的事项理出来了吗?]
(都无, 要安排的都说出来否, 不确定的理清楚否)


目标实现的方式

还记得去年 xx月, 我们计划发一个版本, 然后用下来发现很多基础功能都存在问题的情况吗?
套用某某人这个完全没参与开发的人的话来说 “ 我已经尽我可能去无视因为未完成带来的问题, 但这个产品对我来说还是不可用的”

当时我们的实现目标的方式是怎样的?
产品一次性提供了可能缺少一些细节, 但已经定完整定义整个产品需求

  • 就比如说, 一个模块, 有 10 块功能, 每个功能可能有 20 个细节. 当时 10 块功能 200 个细节已经都定义出来了
  • 以预览流举例, 我们有 4 个模式, 跟拍,手动,轨迹,构图. 很早就完整定义完了(效果上一直很虚)

开发方面
每个人分配一个模块或里面的一部分, 把除了特别细的, 都联调做完, 然后每人阶段性的部分简单冒烟.合并
之后才继续做下一个模块


(此处自行想象一张很大的树状图, 里面描述 APP 的功能的所有分支所有的细节, 不方便放出来)


直到最终测试前, 我们拥有了

  • 一个个 功能全面且复杂
  • 做的过程中经过(也许(往好的说))一部分一部分冒烟测试完

功能很多,但都不一定靠谱的模块.


然后在某个时候, 啪, 把各个组所有模块整合起来.

导致了一个什么结果? 我们得到一个由
很多不同组(CE,CS,FC,Gimbal,Captain,Tracker,OA,BSP,MediaServer,WEB,APP)
很多复杂模块
组成的
只经过了小单元基本测试的
交互不通, 流程有问题, bug 频出, 改需求 bug 改了两个月的”产品”

为啥?
这些功能被串起来(APP 引导用户连接, 控制飞机, 和飞机交互实现功能)前, 不是个产品.
只能验证功能自身可行性, 无法作为产品整体验证(典型的: 我们做了长时间优化的飞机 cpu, 从头做到尾的智能模式)
(所以每组的某个模块只是功能上通了)
每个模块的零星 bug,和不同模块不同端合并后就是灾难 (再强调, APP 上就有多个模块, 这些模块本身就分飞机部分, APP 部分)
这个灾难加上逼近的目标, 灾难加一等

咋解决, 后面再讲…


糟糕的迭代

就最近, 某 月 7 号要发版, 某 月 4 号晚上
群里提到有用户反馈, 某某系统遇到一个问题, 无法xxx
其原因呢, 是因为之前着急发版,某某系统有 bug ‘xxxxxx’,
嵌入式同事和产品商量, 需求就定成了当时的情况.

然后, 某 月 7 发版, 某 月 4 晚提出问题, 产品和测试就做了决定. 7 号要带上这个修改

这是一个典型的, 因为之前仓促, 采用妥协/临时方案, 造成了问题, 然后又再次决定仓促改一版的过程
类似的事情在我们开发过程中 每次, 每次发版 都会遇到
去年 xx 月正式对外发 xx 前一周, 我们的xx还因为其不确定性, 导致要修改交互

第二个例子:
最近产品要新增一个社交方面的需求,
我们 xxx 的计划 GM 的时间点在 xx 月 xx 号.
此前, 因为测试人手不足, 我们以很缓慢的速度在等着出 bug, 现在还没测完.
这个功能上线后, 可以预见的, 需要再一轮开发和测试, 而上一轮测试还未结束.


那么这里有两点,

  • 要么我们 GM 时间是假的, xx 月 xx 以后还能再做一轮迭代(开发-测试-改 bug).(我知道可以推, 但定个目标用来往后推本身就是个问题)
  • 要么我们愿意很仓促的实现功能, 在新代码提交后, 以承担一定问题的代价.简易测一版.
    这是一个典型的, 前期无规划, 需求突如其来, 导致要么预期目标后延, 要么靠拼命冲一把达成目的情形
    类似这样的情况, 比如各种 demo, 比如由外界导致新增的需求.

第三个例子:
我们曾要求 xx 年中出一个具备 “基本功能” 的 xxx 版本
这个版本从 xx 月一直到 xx 月, 一直都处于 xx 无法收敛.
反复测试每次都有新问题的状态
我们当时目标是 xx 月,但 x~xx 月期间处于:
需求还在更改, 功能没全做完, 测试不系统, 反复测试, 但每次涵盖的面都不一样的状态




做个强调: 我不是表达 “不要加/改 需求”, “应该延期” 这种观点
点不在这, 我们有办法 ”全都要” 的.

关键在于, 我们往往大规划上没做好, 导致被逼在战术上做挣扎
一个可以被规划执行好的事情. 变成意料之外突如其来,要么取舍, 要么接受一个糟糕的东西


总结

总结下来就是:
我们开发的流程长期处于,

  1. 制定了无保障的目标日期,
  2. 内部不合理的迭代, 导致目标既无法实现, 开发也十分仓促.
  3. 同时因为前面目标还未达成, 无法适应外部变化(新问题,新需求,新目标), 导致需要开发新的需求更加仓促.

结果是, 我在这儿的几年, 大的节点几乎都没有顺利达成; 每次版本结束, 必然有很长的弥补/修改期


分析

第一点, 目标制定

我尝试从动机上理解这件事
上:

  • 对公司产品, 或者 CEO 来说. 重要的事情是什么?
    在什么样的时点, 能发布出具备什么样功能的产品
    (不管是市场, 投资等等因素来说都是)
    达不成目的的东西, 花再多时间,做得再好都是没意义的
  • 目标/实现进度这种事, 员工的主动性是决定性因素.
    同一个活可以估十天,五天,都是可能的, 一个估五天的活, 定个三天的目标. 说不定能达成目标

下:

  • 开发是没有规划的动力的, 也不直接负担规划职责
    • 开发角度, 规划完做是做, 没规划, 莽着做也是做.
    • 把东西做好, 做细致, 就是个优秀的开发

比如做个用户引导, 一个像素不差的做出来. 对开发来说就是完美完成工作.
但实际情况可能是这个阶段, 用户引导都不需要做更别说画细致的 UI.
(当然现实情况很复杂,大家其实都是聪明人, 会在一定程度有纠正机制)

达成目标的过程: 迭代

这个不做过多分析, 这个直接给个对比
第一种, 既现在的方式:

  • 我们从一开始给产品定义了 3 个模块, 每个模块带 100 个功能点
  • 我们目前的实现方式是, 一人每次做一个模块中的部分功能, 和其他组联调,测试
  • 然后 3 个模块都差不多做完 80% 共, 80 个功能点后
  • 试图把这 240 个东西合起来,让他正常工作
  • 这时候, 不论产品, 测试, 开发. 一次面对的都是 240 个功能点这个庞大的数字

(此处自行想象一张树状图, 里面描述 APP 的功能的所有分支, 如果已经想象过了,可以再想一遍)

第二种, 解决方案:

  • 我们开始只提出 3 个模块, 每个模块 10 个功能点
  • 正常开发, 联调, 测试
  • 这 30 个点做完后, 作为一个简陋的产品, 开始以产品的角度验收(系统性测试, 需求优化)
  • 整理上一个版本的需求问题, 结合剩余的内容. 再提出目标, 比如 A 模块 + 10 ,B 模块 +5
  • 再迭代一版, 验收新增的 15 个功能
    (注意, 这个经过一次迭代后, 第二次提出的需求, 必定比第一种方案中, 那 100 个功能点的需求更合理, 因为是有基础的)

(此处自行想象一张树状图, 里面的细枝末节全部被修剪掉, 主干部分被分成了几个阶段,每个阶段在原有基础上逐渐丰富)



什么叫迭代,
迭代就是去年 Milestone 那一套, 或者是我们有 1.0 版后持续更新的那一套
既: 更早, 更多阶段, 更细致的产品化目标

前者: 我们过早的开发了可能用得上可能用不上的, 一块一块复杂的功能模块

(比如花了很长时间实现的图片视频编辑功能, 在第一版被砍掉的相机设置, HC2 中没有的 usb 模式, 甚至一些不需要太早加入用户体验上的 ui)
虽然每个功能可能提交时都是测过的, 但随着内容逐步加入, 早期的东西不可靠
并且这些功能块,相互独立(不同组的, 不同模块的). 无法以产品化的角度验收(只能功能上跑通)
他在整合时又庞大而复杂,最糟糕的情况, 我们会因为这 240 个东西, 不断延期到做出来为止

后者: 可能最早几个版本十分简陋, 完全无法作为用户产品发布(但可以内部使用, 是基础平台). 并且理论上可能花费更多时间(实际不是)
他价值在于, 很早的就可以以产品化标准, 将飞机各组的软件以整体角度做验证.

每次面对的问题少, 开发是一个增量的过程 (一个在已发布版本上新增功能, 跟发布一个全新产品, 心态和开发节奏上是很不同的)
并且不会在与当前版本不相关的细节上花太多时间.
某个阶段以后, 任意一个版本都可以拿出去发布. 任意版本可以随时打断, 插入行任务

另一种迭代的概念:

我把他称之为: 软件发布的 客观流程
一个软件, 我们希望他是靠谱的, 必定经过:
需求 — 开发 — 验收(产品方面 , 测试方面) - 修改 - 回归
(前面还有需求-评审阶段(不是要讨论的问题))
不论怎么压缩时间, 必须要这个步骤做完了. 发布的内容才能靠谱


这意味着: (对本版本而言)

  1. 需求到某个阶段后,只能小优化不能大改
  2. 开发到某个阶段必须提供包含完整功能的代码
  3. 测试到某个阶段,必须保证全面测完, 剩余已知问题修改后, 可以发版

每个角色, 每个阶段都 向前依赖截止日期, 截止日期, 截止日期
我们会有突发事情,(上面用户突然提出的 bug, 产品突然需要标识限定版)
诚然我们可以充分发挥主动性, 冲一把, 压缩时间把事情做出来.
但这个客观流程无法保证, 必定意味着我们牺牲了什么. 一方面仓促, 一方面质量无法保障

ps. 开发不为”做东西”焦虑, 焦虑的是,本身的活很庞大, 期限内无法做完. 然后还有新的”意外”不断加入

对整个产品来说(对外: 对市场, 对投资人), 优先级上:

  • 产品具备某个功能(用于作为卖点, 吸引投资). 优先于 ↓
  • 功能的稳定性, 优先于 ↓
  • 功能的用户体验
    这是为什么会插入或修改需求, 并且从”大局”上,我们允许这么做的原因

我把会影响我们流程的事情归为两类:

  • 外界因素
  • 行为相关

外界因素:

比如 某年 年中, 如果能发出 某产品, 那市场对我们就有利
比如 某年 年中, 直播是个风口, 上了就能提高销量.
这没啥好说的, 客观因素(其实弹性很大, 由人为主观决定的客观外界因素, 上层关注, 我不解)…

行为相关:

我们大部分这样的事情, 不是因为某个事情, 某个需求必须在这个时间点才能做.
而是因为:
要发版了, 开始 review 需求, 发现的需求不合适.
要发版了, 开始重新定义产品, 发现以前的定义不足
要发版了, 开始做各种可以早期开始做的测试
用户反馈了, 觉得是个问题

咋办? 咋办?
ok 我这里要引出我今天最重要的点了..


“临时看到更好的需求, 提出目标, 号召大家冲一下,拼命把东西在短时间做出来”
相比
“我们真的没有办法把事情解决在变成问题以前吗”

根源性冲突

不合理的迭代方式造成的内部开发低效
与由外部而来, 所制定的一个个实现日期, 以及需要我们适应的变化
相互之间无法兼容造成的问题

解决方案

  • 增设一个角色, 分离”开发””产品””进度管理”职责, 协调整体资源及规划, 并对上确保制定合理目标
    (对于飞机这样的大产品, 需要多个)
  • 用有依据的软件目标制定, 解决一直延期上下脱离的目标
  • 用干 -> 枝 -> 叶, 阶段小目标, 快速迭代的方式. 解决我们的迭代流程
  • 引入的管理角色 + 结合目标和迭代的优化, 引导软件组中各角色的职责, 直接导向产品结果

具体参考上面 针对当前迭代问题的解决方案(核心结论部分)