数据中心站前端的研发让人觉得“唯一不变的就是变化”。以集团的数据资产服务平台为例。经过两年的发展,业务已经从单一的数据管理和使用平台发展成为具有一定规模和影响力的全球数据元交换。前端技术方面,从代码提交报告中可以明显看出,今年平均代码提交量是去年的2-3倍,可见其业务在快速扩张。
代码提交激增的背后是团队、技术和R&D过程的发展。R&D团队从最初的2-3人发展到今天的10人左右;项目前端项目也经历了从常规的React+TypeScript+数据流架构,到支持多个独立业务模块的Monorepo微前端形式,再到Pro-Code和build相结合的开发模式。流程也经历了月迭代,周敏捷开发。一个人负责过很多人的协同开发,甚至和偏远跨业务领域的外包生广泛合作,经历了很多困难。
1为什么要用数据运营?
遇到的困难中,今天先不说这些具体问题。业务增长带来了技术和团队的各种变化,这是相当普遍的。我们换个思路,跳出研究问题本身,先找出问题的根源:
当然,我们希望每一个问题都能准确找到根源,所以我们经常会向发展生寻求反馈,但反馈效果往往有限。比如我不问,对方就不会回问;我觉得没必要优化分,对方也觉得有;我打算用某种方式解决一个效率问题,但往往没有完全解决或者根本没有解决。
这个问题的根本原因在于,我们都是从自己的角度看问题,没有一个更高的高层的视角来帮助我们看到全局,甚至洞察一些规律性的、可预测的变化。越来越多的需求指向了“数据运营”这个概念。
2个明确的目标
如前所述,我们希望通过R&D效率数字化运营的思路,通过真实的R&D效率数据看到团队的整体行情和详细指标,从更高的位置审视团队的业务R&D,隐藏的问题可以在数据中暴露出来,问题的原因可以在数据中揭示出来,让人们更好地思考如何解决,更准确地定位到根源,最终提升R&D效率。
作为数据中心前端团队中的业务开发人员和R&D流程控制员之一,这一次,我想和大家分享一下我们是如何在团队中运用数据运营的思想来管理R&D流程和R&D质量,达到提升R&D效率的目的。
二 研发效能数据化运营全链路1设计索引
为了提高R&D效率,我们需要定义关键数据指标。通常,R&D效率指标涵盖了整个R&D进程的不同环节,并且相互补充。如代码质量得分(代码Lint问题的数量)、需求R&D周期、敏捷迭代交付周期、R&D活动的效率、耗时的发布等。
限于篇幅,本文以“R&D活动效率”为研究对象,结合团队实际情况,探讨我们能做些什么。
R&D活动是团队通常做的最常见的事情。映射到具体的R&D过程是代码提交和代码评审的提交。评审人员负责代码评审的质量控制,最终通过评审,将代码合并到主分支,一个“R&D活动”就成功了。通过团队的大量实践表明,提交的频率和代码审查的处理时间是影响R&D活动效率的最重要的因素。
首先,对于开发者来说,代码审核需要规范。我们规定代码评审提交周期为一两天,每一个Aone缺陷或需求作为最小粒度,每隔一段时间提一个。否则会造成新开发代码的积压,导致评审人员压力过大。如果问题比较多,或者逻辑方向性问题比较多,那么项目进度和风险的控制就会比较困难。相反,如果频率过高,评估员的正常工作会中途中断,也会给他带来麻烦。
其次,对于代码审查人员来说,也需要某些协议。比如提交代码评审的时候,有些评审同学可能会忘记或者临时搁置,导致提交的代码长时间无人问津。同时开发同学提交新的业务代码,又回到了上述代码积压问题,造成了审核堵塞的恶性循环。
说到这里,相信大家都已经知道团队的痛点了:在5+业务领域,并行8+需求、外包合作的10人(正式同学)前端R&D团队中,我们已经明确了代码评审暴露的问题,但不知道具体是什么情况,需要多长时间量化,也不知道哪个开发同学或评审同学节奏异常,只有现象没有突破点。因此,我们采取一个完整的数据操作过程来尝试解决上述问题。
2埋点报告
要观察的指标已经确定,下一步是分解整个指标,以确定哪些数据需要在R&D进程中报告。对于“代码审查处理时间和频率”,我们可以细分以下信息:
如何收集这些数据?
R&D团队绩效工具介绍
由于团队的R&D效率基础设施(见上图),我们通过R&D效率工具DT-Hornet实现了团队R&D过程控制的“统一”。
CR命令层隐藏逻辑
先说一些技术细节。当开发人员提交CR时,它会经历以下自动化步骤:
监控平台使用逻辑和技术层介绍
在上述CR提交和嵌入逻辑的基础上,借助集团监控平台ARMS的能力(封装了通用能力Trace-SDK),我们可以很容易地上报数据。
要使用监控平台,您需要在其中注册一个应用程序,并获得一个唯一的PID标识符。在埋点报告逻辑中,PID是在Trace-SDK实例化时传入的,可以通过在埋点调用其log API来完成报告。下面的代码显示了性能工具内核如何调用Trace-SDK来声明其通用隐藏点报告逻辑。
/* *声明性能工具内核类(与向监控平台上报埋点相关的部分)*/ classhornetcore { /* *声明监控列表实例*/ 私有静态trace instance:tracesdktype = null; /** HornetCore监控初始化*/ Public static init trace =():void = > { HornetCore . trace instance = new TraceLiteSdk({ PID:& # 39;& ltR&D效率工具PID >:& # 39;}); }; /**向监控平台上报参数*/ Public static send tracelog = async( /* * * Report Type Type:String,[//] : TraceLogParamType, ):Promise & lt;void & gt= & gt{ try { /操作工号 consuid = dynamic _ names . admin _ work _ id; //Operator const C1 = dynamic _ names . admin _ name; //应用程序名称 const C2 = dynamic _ names . project _ name; //分支名称 const C3 = dynamic _ names . branch _ name; let C4:any; 设C5:any; 设C6:any; let C7:any; 设c8:any; //工具是不是最新版本 Const C9 = Hornetcore。islastversion . tostring(); //工具内核版本号 Const C10 = hornetcore . version; 开关(类型){ case TRACE_LOG_TYPE。CR: { const { targetBranch,crAdmins,crAdminCnt,currentReqName,crSequence } = params | | { } [c4,c5,c6,c7,c8] = [targetBranch,crAdmins,crAdminCnt,currentReqName,Cr sequence]; break; } 案例跟踪日志类型。CR _ HANDLING:{ const { target branch,currentReqName,crCount,crStartTime,crEndTime } = params | | { } [c4,c5,c6,c7,c8] = [targetBranch,currentReqName,crCount,crStartTime,crend time]; break; } 默认: [c4,c5,c6,c7,c8]=[空,空,空,空,空]; } const log params = { type,uid,c1,c2,c3,c4,c5,c6,c7,c8,c9,C10 }; 返回hornetcore . trace instance . log(logParams); } catch(e){ basic message . error(`报告数据错误:${SPLIT_VALUE。BREAK } $ { e } `); return promise . reject(); } }; } 如代码所示,工具组织了不同的C域(用户自定义的提交域)来匹配不同的提交类型。在CR上报的场景中,需要两种类型,CR用于上报按“次”计算的CR的详细信息,CR_HANDLING用于按“轮”上报计算的CR信息,一轮。
在监控平台端,对应配置C字段的报表类型和别名,方便后续的数据拉取和处理。如下图所示。
隐藏数据并发送请求。一般是请求服务器上某个1*1像素的图片,在发送请求的时候把需要上报的信息都拿走了。这里,除了CR信息,还包括一些一般的系统级信息。
监控平台接收数据,并通过日志服务将数据存储到HBase集群中,可以在arm平台上通过即席查询获得数据。
3数据处理
得益于ARMS监控平台,以上步骤完成了数据的采集和存储,接下来将进行数据的同步回流和初步处理。每天上报给监控平台的实时数据会存储在相应的离线小时表中。我们申请对应表的权限,通过查询表的视图,可以得到效率工具PID下采集的所有详细数据。
脱机数据同步
由于监控平台存储成本有限,数据只能保存近30天,原始表格包含了监控平台中PID上报的所有数据。数据量很大,导致查看查询很慢,如果查询条件不严格,很容易因为资源不足而造成查询错误。所以我们考虑在Dataworks上设置一个周期性的任务,将我们需要的数据周期性的同步到我们自己的表中,这样就可以解决问题了。
在周期性任务中,我们根据ds字段指定的分区范围,每天通过INSERT OVERWRITE语句将数据写入表source_table,不会产生重复数据。任务发布后,每天都会生成一个周期性的实例,稳定地为我们提供所需的监控数据。
用于数据分析的SQL设计
我们使用联邦调查局的平台进行数据分析。在FBI数据集的编辑中,我们可以基于刚刚创建的ODPS表轻松地声明SQL,并进一步分析我们想要的字段。
我们对所有C域进行语义化,并使用简单的内置函数来处理空值或格式化数据以备将来使用。代码评审数据详细分析表、代码评审处理数据详细分析表和代码评审汇总分析表分别说明如下:
/* 代码评审数据详细分析表 */ Select a . stat _ date, a.ds, a.log _ day, substr (a 9) as log_time, substr(a.log_second,9) as log_second, a.c1 as admin_name, b.c2 as project_name,-的中文名称信息1) ascr _ first _ admin,-获取第一审核人为主审核人的信息 a. C6 ascr _ admin _ CNT, a. C7 ascur _ req _ name, concat (C4,& # 39;',c7)作为cur_branch_and_req_name, a.c8作为cr_sequence, a.c9作为latest_version_flag, a.c10作为cur _ version FROM source _ table a LEFT OUTER JOIN( SELECT code, c1, C2 FROM source _ table _ dim-dim-dimension表存储维度code _ review & # 39 和b.code = & # 39project _ name & # 39 和a.c4!= '发展& # 39;-过滤掉提交给主发布分支的CR,因为它不是关键信息 且a . ds > 2021 06 30;-限制ds的数据范围,提高查询性能 * 代码审查处理数据详细分析表 */ select a . stat _ date, a.ds,[9]as log _ hour, substr(a.log_time,9) as log_time, substr(a.log_second,9) as log_second, a.c1',a.c5)作为cur_branch_and_req_name, concat(b.c2,& # 39;',a.c5)作为cur_project_and_req_name, c.c1作为cur_req_admin_name, a.c6作为cr_count, a.c7作为cr_start_time, a.c8作为cr_end_time, date diff( to _ date(a . c8,& # 39;yyyy-mm-DD hh:mi:ss & # 39;), to_date(a.c7,& # 39;yyyy-mm-DD hh:mi:ss & # 39;), & # 39;mi & # 39 )作为CR _ duration,-使用datediff函数计算CR处理时间 a.c9作为latest_version_flag, a.c10作为cur _ version FROM source _ table a 左外连接( SELECT code, c1, C2 FROM source _ table _ dim WHERE codeproject _ name & # 39-关联项目名称信息 ) b on a.c2 = b.c1 左外连接( select distinct code, C1, C2, C3,。要求& # 39;-关联需求信息 ) c on a.c5 = c.c4 其中 a . code = & # 39;code _ review _ handling & # 39 和a.c4!= '发展& # 39;[/h 和a.c8不为空-没有CR结束时间被定义为废弃的CR,并且 和a.c8!= 'null & # 39 和a.ds & gt20210720; /* 代码评审总结分析表 */ Select STAT _ date, Project _ name, Project _ name _ and _ req count(admin _ name)as CR _ CNT-count CR提交数 from ( Select a . STAT _ date, a.ds,,',1) as cr_first_admin, a.c6 as cr_admin_cnt, a.c7 as cur_req_name, concat(b.c2,& # 39;',a.c7)作为project_name_and_req_name, a.c8作为cr_sequence, a.c9作为latest_version_flag, a.c10作为cur _ version FROM source _ table a 左外连接( SELECT code, c1, C2 FROM source _ table _ dim[/hcode _ review & # 39 和a.c4!= '发展& # 39; 和a.ds & gt20210715 和b.code = & # 39project _ name & # 39 ) 分组依据-选择日期、项目名称、需求名称、开发人员等维度 stat _ date、 project _ name、 cur _ req _ name、 admin _ name、4设计报告
为了输出分析数据,接下来可以设计和构建报告。FBI平台提供了丰富的图表可供选择,使用时需要明确其含义。
围绕代码审查,我们设计了以下通用和子指标报告。
代码活动概述报告
代码活动详细信息报告
此外,报表页面还设置了详细查询数据的详细列表,支持搜索各种维度的数据,如项目名称、开发商等。
5问题洞察和解决方案
通过以上的报告构建和优化,可以初步解决“数数”的首要问题——不再担心代码评审的不可量化的成本,能够明确代码评审需要多长时间,从报告中发现和洞察潜在的问题。
案例1:概述分析
从7月初到9月初,已经发现团队的代码活动有了明显的提升。如果项目是固定的,但CR频率增加了,这意味着需求可能有上升趋势。然后对比CR参与项目数量的趋势,基本与CR提交的趋势线吻合,说明更多的项目具备使用效率工具的能力,而需求研发对于项目粒度的研发可以认为是正常的,但总体趋势是项目数量在增加,也要注意团队同学的业务压力。
获取上述信息后,结合团队中实际的研发项目,可以逐一观察项目粒度的详细报表数据,进一步了解业务研发情况。
案例二:洞察力异常
R&D效率经理和项目负责人会关注一些异常数据,如CR处理时间、CR频率等超出健康水平的信息。项目负责人可以立即提醒相应的开发同学或相应的需求负责人关注项目的进展,使项目的需求研发回到健康的状态。
案例3:项目一级的效率评估
项目负责人也可以关注他们自己的项目代码活动的健康状态。上图中,项目A的CR平均处理时间在4小时左右,基本上当天就能解决问题,CR的平均频率为1.8次,说明这个项目的代码评审基本上可以顺利通过或者一次性解决问题。项目健康程度高。
而项目B的数据比较一般,CR平均处理时间在一天以上,平均每轮CR次数达到5.5次,不是一个健康的状态。这时候项目负责人就需要注意了,深入到项目中去,找出是什么因素导致了异常,对项目未来的进展做出一些判断和决策:
1数据运营的本质是沉淀或者验证体验
当我们接触到一个新的领域,或者对于一些商业逻辑和用户体验,不知道现在的产品设计是否真的能服务客户,可以尝试用数据运营来帮助观察效果,积累经验,知道什么样的设计是好的,什么样的设计是没有价值的。
或者说,借助埋点上报的真实统计数据,可以更客观地验证产品设计的价值。比如一个数据表配置页面,用户首先需要一个一个的配置,效率很低;经过后续用户调研,设计增加了一个自动同步元数据的按钮,可以一键添加。用户可能只需要修改一些字段的信息就可以提交。我们可以通过观察从打开编辑页面到单击保存按钮的时间间隔的变化趋势来验证这种优化的价值。
2避免过度依赖数据的误区
数字化运营的优势可见一斑,但也要避免一刀切的过度使用和对数据的依赖。当我们熟悉所在的业务领域,经过多次数据验证和经验积累,在遇到类似场景时,能够快速高效地做出决策。
3数据运营能给R&D效率治理带来什么
R&D效率治理是一个长期持续的过程。随着团队支持的业务不断变化,我们反复迭代效率工具,通过技术手段间接支持业务。
目前,团队所有业务的前端R&D均采用现行的R&D效率工具系统和数据运营方案。搭建的数据报表主要解决的是“计数”的问题,从中可以主动发现异常,找到问题的根源,但数据运营提供的能力并不仅限于此。
自动信息同步机制
以前发布需求时,负责发布的人员会运行性能工具的功能命令,打印出要发布的需求信息。该流程需要手工操作,加上标准化流程中的“新发布计划文档”和“新自检报告文档”的操作,流程成本较高。
通过使用数据操作,可以将创建的需求信息报告给监控平台,从而可以将数据用于每周定期的群组广播。在上线时间准确的情况下,所有开发生都能看到需求上线,信息可以同步。然后通过周期性任务机制,自动创建对应发布日期的文档,大大降低发布过程中的成本。
工程系列连接
R&D绩效报告能做的不仅仅是CR效率。结合整个工程流程,可以添加需求、建设、发布、使用效率工具等相关指标。,并构建一个报表站点。这样就可以将整个工程系统以数字化的方式运营,不断优化体验,比如提高建设速度、发布效率等等,跳出R&D过程控制本身,以更全球化的视角来看待。
实时报警和跟踪
我们可以通过实时报警进一步增强主观能动性。比如开发人员合并代码错误时,立即实时上报错误,让项目负责人第一时间知道是代码冲突、权限还是其他原因,督促需求负责人和开发人员高效解决,避免阻塞项目进度。
当效率工具和工程框架出现逻辑错误时,可以通过实时报警及时通知工具开发者,无需用户反馈即可检查并解决工具bug。
性能工具无人值守
进一步借助数据操作,找出最常见的问题,沉淀自查文档,在性能工具运行出错的catch逻辑中为用户提示文档链接,帮助其自主解决问题。一段时间后,效率工具可以无人值守运行,R&D效率可以进一步提高。
综上所述,我们以代码评审效率洞察为例,学习了如何通过数据操作的方式控制R&D效率,平时可以制定准确的记录,及时解决问题;在解决问题的同时,我们对R&D效率团队的未来发展趋势有了新的思考和规划。
同样,R&D效率治理是一个长期和持续的过程。我们希望能够用数据运营这样的有效方法,广泛实践R&D流程,深入定义、理解、克服其中遇到的问题,让R&D团队像常春藤一样健康持续发展。
作者|杭哥
原文链接:http://click . aliyun . com/m/1000298832/
本文为阿里云原创内容,未经允许不得转载。