研发团队的绩效问题以及其与Agile管理、DevOps的关系

这一个月大家都在忙着写小结做评估,所以一提到评估和绩效,大家就想到绩效的评估。

实际上绩效考核只是绩效管理的手段之一,而绩效管理的目的是提高组织绩效,它的手段除了绩效指标的制定和考核之外,还有其他手段。

一、提高组织绩效的手段

  • 组织架构的优化,自组织的建立(康威定律所说的怎么样的组织结构决定怎么样的产品结构)

  • 迭代开发和敏捷管理方法的采用

  • 从开发到运维各个环节正向流程和反向流程的打通,也就是devops的实施

  • 建立强大的中台,聚合丰富的业务服务、数据服务、流程服务

  • 好用的工具

  • 及时的培训

  • 专业的支持

  • 高效的沟通

  • 顺畅的流程

同时,对于绩效考核而言,也不是为了考核而考核,而是为了提高绩效而考核。所以考核指标的好坏就看是不是能提高团队绩效。所以有一些原则需要遵守。

二、研发组织绩效度量体系设计五原则
本部分摘抄自https://mp.weixin.qq.com/s/VvZWroN1Z34k1H2IEJsYeA
1.外部性
在《21世纪的管理挑战》这本书中,德鲁克指出,**任何组织的绩效都只在外部反映出来。**以一个咖啡厅为例,客户等待时间、咖啡口感、价格,这些都是客户可感知的外部指标。研发组织也应优先选取其客户可感知的外部指标作为研发组织绩效指标,这里客户包括但不限于业务人员、产品经理、最终用户等。

2.无害性
管理学有一个原则**“你考核什么你就会得到什么”,绩效指标对团队行为具有很大的牵引作用。设定一个指标后,需要首先考虑负向牵引作用,既团队会采取哪些短期行为来试图迅速达成绩效指标?评估一下这些短期行为对组织的伤害有多大?举个例子,如果用 开发代码行数来评估开发工作量,就会对开发工程师产生一个明显的负向牵引作用,让开发工程师失去进行优雅设计或重构代码从而让代码更精简的动力。因此,绩效度量体系应尽量选取一些难于伪造或者伪造行为对组织伤害比较小的绩效指标。
3.整体性
软件研发组织是一个复杂系统,各岗位间界限很难完全明确。管理者要克制将绩效指标分解到不同岗位,甚至分解到个人的冲动。这种
无效的指标分解往往会导致局部优化**,即各岗位仅仅为自己的绩效而优化工作方法,反而降低了组织的绩效。例如, 将进度和质量两个互相牵制的指标,割裂开分配给开发测试,这造成开发只关心进度,忽视移交质量,而光靠测试来保证质量。这种方式是不可能获得高质量软件的,也不可能达到快速交付的目的。
4.制衡性
研发组织没法用单一指标来衡量,而需要用一组指标来互相制约以求得平衡。例如, 单纯追求交付速度是危险的,必须用质量指标来平衡。
5.演进性
绩效指标应该随着组织的发展不断调整,需要定期增减修订指标,保持指标体系精简,降低管理成本。

三、研发组织绩效KPI制定的建议:

  1. kpi指标定义不能顾此失彼(整体性)
    例如,将进度和质量两个互相牵制的指标,割裂开分配给开发测试,这造成开发只关心进度,忽视移交质量,而光靠测试来保证质量。这种方式是不可能获得高质量软件的,也不可能达到快速交付的目的。
    又如,假如控制生产发布次数,可以提高项目组的质量意识。但是用户新增需求和bug修复的上线及时性就下降
    但如果不控制生产发布的次数,那么项目质量就有可能下降,发布很随意。
    所以需要几个指标一起来平衡。 比如现在流行的 软件交付效能 指标的四个指标
    • 部署频率:部署代码的频率
    • 变更前置时间:从代码提交到代码成功运行在生产环境需要的时间
    • 服务恢复时间:发生服务故障时(例如:计划外中断,服务受损),恢复服务通常需要的时间
    • 变更失败率:有多大比例的变更会导致服务降级或需要事后补救?(例如:需要热修复、回滚、前向恢复、补丁等)
      通过这四个指标的平衡,可以培养出“充分测试,严格上线” 的文化,使每个项目组把交付的效率和质量兼顾考虑。
  2. kpi指标不能没有数据支撑。
    实际上从软件能力成熟度模型CMMI的角度来看,要做到大量指标可度量是CMMI3的级别。
    实际上,我们在做KPI的时候,可以把软件开发质量是否可度量作为一个KPI指标,让我们的项目管理先具备收集指标的能力,推动工具链的建设和使用,获得全面可信的质量数据。
    以下是常用的软件开发质量指标:
    • 需求耗费时长:需求耗费时长反映研发组织交付需求的速度。
      ​需求上线时间-需求提出时间
    • 需求吞吐率: 需求吞吐率就是单位时间内每个开发工程师完成的需求规模,例如每人每月完成两个需求,或者每人每月完成五个功能点。
      需求吞吐率是一个适应性指标,它和需求耗费时长形成一对制衡,避免团队单纯改善交付速度,而降低交付数量。
    • 测试缺陷需求比:测试缺陷需求比反映开发团队初始移交质量水平
      测试缺陷数量/移交需求规模
    • 生产缺陷需求比:
      生产缺陷数量/上线需求规模
      也可以通过生产缺陷需求比和测试缺陷需求比的差值来看出项目测试团队的效能
  3. KPI考核的目的不单是关注结果的正确,还要关注过程的正确。也就是“做正确的事,和正确的做事”,两者都要兼顾。
    所以我们可以把流程review作为KPI指标。关注流程的优化调整问题。比如ITIL的事件管理和问题管理当中,我们不能只关心CMDB移动报表中登记的事件和问题是不是都解决了,还需要关心,从CA出来的报警是不是合理筛选了,是否全了,有没有遗漏未登记的,等等,这些都需要事件经理和问题经理经常做回顾调整。

**四、Devops、敏捷和绩效的关系 **
devops和敏捷管理的目标是一致的,都是为了提高团队绩效。
1,提高软件开发的质量和效率
2,打通工具链、打破功能团队之间的壁垒 (比如开发团队与测试团队、测试发布团队和生产发布团队、开发测试团队和运营团队)让相关人员坐在同一条船上。
当然,最早的认为是,DevOps是为了打通开发和运维之间的gap的,而敏捷是为了打通业务(需求)和开发之间的gap的;现在的理解可能更侧重于敏捷是团队的打通,DevOps是工具链的打通吧。
所以,敏捷开发和DevOps就是相辅相成的。这里有一点特别重要,为了提高效率和质量,那么软件开发中的各个工具组件(项目管理,需求管理,测试用例管理,bug管理,代码检查工具,编译打包工具链,自动化测试工具链,发布工具,监控报表和工具等)就必须高效地集成起来,并让敏捷团队自助使用。

实际例子:我们ADD项目(敏捷开发部署平台)的一个例子(Sonar是个开源产品、其源代码我们不更改)

报错信息
在sonar生产环境扫描的时候连续多次遇到客户端扫描成功,但是服务器端报错的问题,报错原因是说磁盘空间不够无法解析报告:

java.lang.IllegalStateException: Fail to extract report AWcRmDMRQO9Nqe7BvzTr from database
         at org.sonar.server.computation.task.projectanalysis.step.ExtractReportStep.execute(ExtractReportStep.java:66)
         at org.sonar.server.computation.task.step.ComputationStepExecutor.executeSteps(ComputationStepExecutor.java:64)
         at org.sonar.server.computation.task.step.ComputationStepExecutor.execute(ComputationStepExecutor.java:52)
         at org.sonar.server.computation.task.projectanalysis.taskprocessor.ReportTaskProcessor.process(ReportTaskProcessor.java:73)
         at org.sonar.ce.taskprocessor.CeWorkerImpl.executeTask(CeWorkerImpl.java:134)
         at org.sonar.ce.taskprocessor.CeWorkerImpl.findAndProcessTask(CeWorkerImpl.java:97)
         at org.sonar.ce.taskprocessor.CeWorkerImpl.withCustomizedThreadName(CeWorkerImpl.java:81)
         at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:73)
         at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:43)
         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
         at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: No space left on device
         at java.io.FileOutputStream.writeBytes(Native Method)
         at java.io.FileOutputStream.write(FileOutputStream.java:326)
         at org.sonar.api.internal.apachecommons.io.IOUtils.copyLarge(IOUtils.java:1793)
         at org.sonar.api.internal.apachecommons.io.IOUtils.copyLarge(IOUtils.java:1769)
         at org.sonar.api.internal.apachecommons.io.IOUtils.copy(IOUtils.java:1744)
         at org.sonar.api.utils.ZipUtils.copy(ZipUtils.java:169)
         at org.sonar.api.utils.ZipUtils.unzipEntry(ZipUtils.java:109)
         at org.sonar.api.utils.ZipUtils.unzip(ZipUtils.java:92)
         at org.sonar.api.utils.ZipUtils.unzip(ZipUtils.java:61)
         at org.sonar.server.computation.task.projectanalysis.step.ExtractReportStep.execute(ExtractReportStep.java:64)
         ... 16 more

解决思路

  1. 在github上寻找源代码片段,定位源代码(开发团队)

    https://github.com/SonarSource/sonarqube/blob/branch-6.7/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ExtractReportStep.java

  2. 解读源代码(开发团队)

 public void execute() {
    try (DbSession dbSession = dbClient.openSession(false)) {
      Optional<CeTaskInputDao.DataStream> opt = dbClient.ceTaskInputDao().selectData(dbSession, task.getUuid());
      if (opt.isPresent()) {
        File unzippedDir = tempFolder.newDir();
        try (CeTaskInputDao.DataStream reportStream = opt.get();
             InputStream zipStream = new BufferedInputStream(reportStream.getInputStream())) {
          ZipUtils.unzip(zipStream, unzippedDir);
        } catch (IOException e) {
          throw new IllegalStateException("Fail to extract report " + task.getUuid() + " from database", e);
        }
        reportDirectoryHolder.setDirectory(unzippedDir);
        if (LOGGER.isDebugEnabled()) {
          // size is not added to context statistics because computation
          // can take time. It's enabled only if log level is DEBUG.
          try {
            String dirSize = FileUtils.byteCountToDisplaySize(FileUtils2.sizeOf(unzippedDir.toPath()));
            LOGGER.debug("Analysis report is {} uncompressed", dirSize);
          } catch (IOException e) {
            LOGGER.warn("Fail to compute size of directory " + unzippedDir, e);
          }
        }
      } else {
        throw MessageException.of("Analysis report " + task.getUuid() + " is missing in database");
      }
    }
  }
  1. 开启文件系统监控 (原来是OS功能团队,跨部门,现在要敏捷团队自己解决)
  2. 开启数据库session监控(原来是DBA功能团队,跨部门,现在要敏捷团队自己解决)
  3. 综合各种监控结果,定位问题根源,并解决问题。

结论,为了快速解决产品问题,提高团队绩效敏捷的特性团队采用DevOps开发运维方式,可以利用OS团队和DBA团队提供的监控工具和及时的培训,自行监控代码运行的结果,其职能充当了原来OS团队和DBA团队的一线和二线支持的职能,而OS团队和DBA团队由二线支持退位到三线支持,主要目的是给敏捷团队提供自助平台,确保自助平台的正常运转,同时提供及时的技术支持和培训服务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

alpha xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值