当前位置: 首页 > news >正文

《A++ 敏捷开发》- 16 评审与结对编程

客户:我们的客户以银行为主,他们很注重质量,所以一直很注重评审。他们对需求评审、代码走查等也很赞同,也能找到缺陷,对提升质量有作用。但他们最困惑的是通过设计评审很难发现缺陷。
我:你听说过敏捷的结对编程吗?
客户:听过,也给客户做过培训,但是一般管理层都接受不了用两个人干一个人的活,所以几乎都没有团队在实际工作中使用。
我:单做培训确实难以推动并持续,必须按3步走,按部就班才有效果,让我分享一下。

背景

4月

现场结对编程培训之前8个月,首次见这家客户的总监。他们想用一年时间改进软件开发质量。事后知道原来他们有个超过12月的大型项目,因为验收时质量不达标,不能通过风险的验收测试,被拒收。因为公司是老字号,不想影响声誉,请求客户给机会让他们重头再做,客户同意但估计产生的损失超过100万,所以高层下定决心必须改进软件质量,避免类似情况再发生。

7月

与客户签了CMMI服务合同后首先做差距分析, 首先收集各领导的关注点。
某部门经理最担心的是系统维护:如果有人员离职,新人要花很长时间才能上手。
技术总监更担心是有些交付后的缺陷会很花工作量:如某系统交付后开始使用的时候很正常,但过了9个月,用户量和数据量都增加了,偶尔会出现有些报表出错,我们架构师、工程师等,花了3个半月才发现其中某接口的参数有问题。
另外发现开发人员水平参差,也没有做好单元测试和代码评审,代码可读性低,其他程序员难以理解,在分析后的汇报里,建议利用TDD和面向对象的设计原则改善编码规范,并加强培训,推行结对编程培训,提高代码的可读性,方便日后维护。
最后发现很多项目资源不足,没有充分的时间确保代码的质量。

给管理层汇报
因缺陷绝大部分都是后期测试才发现、缺陷修改的总工作量很大(估计占项目总工作量30%),建议加强开发单元测试。
因代码都是个别程序员负责,建议团队用结对编程,除了能提高质量也防止一人离开其他人无法跟进的风险。
也预警管理层开始时要预留15-25%时间给开发团队,当后面返工量减少,以后的总工作量会降低(生产率提升)。

2天培训课

第一天讲面向对象设计原理,设计模式,测试驱动开发;
第二天讲结对编程:

Interview Parnas Screenshot 2025-01-21 162541.jpg

问:在软件工程常被忽略的最大风险是什么?

答:不称职的开发人员。据估计,美国需要的程序员数量超过20万。这完全是误导。这不是数量问题。我们有质量问题:一位糟糕的程序员一年内便很容易就会产生两个新岗位(的工作量)。如果我们有更多优秀的程序员,并且能够轻松识别他们,我们需要的就会减少,而不是增多。

“也有人说:“卓越的程序员比优秀的程序员,不仅是好一些,而是倍数级的差异。”
请问你们觉得团队里程序员的水平也存在很大的差异?”
培训开始,对应以上幻灯片,我问大家。

你们是否觉得:

  • 交付后的软件难以维护
  • 其他人难以读懂其他人的代码,员工离职后其他成员难以跟进和维护
  • 代码总体设计不好,如缺乏良好架构,不灵活
  • 系统交付后,有些缺陷需要很长时间才能修复好

如大家希望提高代码质量,必须从人入手。

如果你们团队也有同样问题,有什么好的解决办法呢?培训?
编码的最佳学习方式并非读书,而是动手做,所以单靠搞内部培训效果有限。有什么好方法帮助开发人员提升?

代码评审

就算评审规范做得很好能帮助初级程序员提升吗? 很难,因为代码都已经写完了。
比如我跟另一位老师看团队的代码,他们都写了起码几千行。我们的结论就是:虽然代码的设计很有问题,但已经到了这个地步,除非重写,否则单靠修正部分代码并没有帮助。这也是代码评审常常难以做好的主要原因。而且大家都要面子,如果在评审里,直接说他设计有问题,也可能会影响到大家的关系,所以在设计评审时难以找出缺陷,这很正常。
团队主管看程序员代码 只能把关防止严重错误,对程序员提升没有作用,所以评审不能有效保证代码质量,也不能帮助团队能力提升。
当写完了几千行代码后,就很难在评审时要求开发改动。程序员会觉得又不是不对,测试也跑得通,为什么要改。所以代码的质量问题应在写的时候就避免,这是结对编程的原理。你可以把结对编程看成是提高团队之间互相交流的培训方法。因为结对编程是在编码时针对具体问题集思广益进行解决,很容易落地,效果会比培训或评审好。
两个人互相讨论写代码才就是有效的培训,不能单挑单靠设计和编码规范和指南。

培训设计

有些人误以为:

  • 结对编程必须要找一位合适的搭档,人与人之间是否合得来最重要
  • 结对时只是在旁边看
  • 以为仅仅是教同伴应怎么做
  • 以为只是看,作为人手编译器,只看代码是否写对,能否通过编译

我们针对这些重点设计一天培训。

培训重点

要培训有效,必须利用练习,让学员动手动脑筋。

结对编程和实践说明

练习#1和讨论:代码阅读
结对编程说明

练习#2和讨论:设计和结对编程
练习#3和讨论:Code Review和Pair Programming
练习#4 怎样开始结对编程:10分钟结对编程
讨论:10分钟正确结对编程
练习#5:队伍结对编程
Pair-Solo Programming

练习一:用10条代码实例,每一条分A与B两种方式写,问学员那种更容易读懂,说明代码应怎样写才能让一般人容易读懂
练习二:先自己按面向对象做总体设计 然后两人结对分享设计做出最终设计学员讨论结对是否有效
然后解释若要持久,必须轮流替换伙伴,也介绍各类结对方式的利弊,例如:

Public-private pair programming ; pair - solo programming

练习四:先2人试试结对
练习五:六人为一队,轮流合作写程序,让学生体验交换。(详见附件)

经验分享

结对编程需要2人对话沟通,例如某人写代码时,另外一个人提问题,有些不习惯编写代码边说话沟通,培训时,预先写好台词。如果想多了解结对编程如何沟通,可参考书的实例。
有些程序员比较内向,不想说话,我们会用角色扮演: 先写好台词,让他们展示在结对编程时如何沟通。 帮助他们先打出一步,鼓励尝试。
注:如果想了解结对编程如何沟通,可以参照Robert MARTIN先生的保龄球游戏实例(参考书里第6章),了解两个人如何从需求、总体类设计、按TDD写单元测试用例、然后写代码,让它通过,一步一步最终完成整个程序。

总结

培训开始时用例子说明结对编程除了能帮助团队知识分享和提高团队精神以外,更能:

  • 提高代码质量和可读性(编码规范)
  • 提高代码复用
  • 加强测试驱动开发

利用互动练习让学员亲身体验结对编程的原则:

  1. 一边写代码一边说
  2. 提问,如:这方法是否归为这个类
  3. 每人带纸和笔(最好铅笔)
  4. 不断想复用

--- *** === *** ---

客户:我猜你说的3步是:
第一步,高层认同软件质量问题的严重性,为此交过学费,知道损失多大
第二步,管理层不仅了解软件的质量问题和改善措施,更需要内部立项做培训和投入资源(人力),做过程改进
第三步才是具体的培训课。因为缺乏第一步和第二步,所以之前做完了结对编程培训后,没有效果
我:厉害,完全对。结对编程只是改进的一种方法,如果高层不关注、不立项、不投入资源,不会有改进效果。
结对编程这方法在70年代已经开始,与TDD、代码重构已经都经过验证能有效改善质量减少返工。所以结对编程本身没问题,要解决的问题是总体质量改进。
若要成功推行结对编程,必须先说服管理层,投入时间和资源,但投资会有好回报。
结对只是一种有效的改进方法,团队必须有每个迭代回顾,持续提升的好习惯,不可能单靠管理层下命令来推行,更好是团队自己有改进的动力,选择使用结对编程来提升质量,减少返工。


本章最佳实践对应

  • CMMI
    • 单元测试:PR 2.X 3.X 所有实践
  • XP
    • 结对编程,代码共同拥有 都是XP里的实践

附件

Ex 5

时间组一组二组三
1A 和 B 结对并打开信封XC和D结对并打开信封YE和F结对并打开信封Z
看清楚需求,然后把X掉了看清楚需求,然后把Y掉了看清楚需求,然后把Z掉了
A和B 开始结对编程,A写B看C和D开始结对编程,C写D看E和F开始结对编程,E写F看
2过了4分钟转换
3F和A结对编程X ,F写A看B和C结对编程Y ,B写C看D 和E结对编程Z ,D写E看
4过了4分钟转换
5E和F结对编程X,E写F看A和B结对编程Y,A写B看C和D结对编程Z,C写D看
6过了4分钟转换
7……
……

相关文章:

《A++ 敏捷开发》- 16 评审与结对编程

客户:我们的客户以银行为主,他们很注重质量,所以一直很注重评审。他们对需求评审、代码走查等也很赞同,也能找到缺陷,对提升质量有作用。但他们最困惑的是通过设计评审很难发现缺陷。 我:你听说过敏捷的结对…...

jar、war、pom

1. <packaging>jar</packaging> 定义与用途 用途&#xff1a;默认打包类型&#xff0c;生成 JAR 文件&#xff08;Java Archive&#xff09;&#xff0c;适用于普通 Java 应用或库。 场景&#xff1a; 开发工具类库&#xff08;如 commons-lang.jar&#xff09;。…...

WSL2安装过程记录

WSL2安装过程记录 1 先决条件2 安装WSL3 安装Linux4 图形化界面 因为命令安装的时候会直接将linux发行版安装到C盘&#xff0c;对于系统盘容量小和介意不能自定义安装位置的用户来说&#xff0c;非常不友好&#xff0c;所以我这里采用手动安装的方式&#xff0c; 命令安装可以参…...

HTML列表,表格和表单

列表 在 HTML 中&#xff0c;列表&#xff08;List&#xff09;是常见的一种布局方式。列表分为两种类型&#xff1a;有序列表&#xff08;Ordered List&#xff09;和无序列表&#xff08;Unordered List&#xff09;。 无序列表 无序列表&#xff08;Unordered List&#…...

Mysql进阶篇

存储引擎 Mysql体系结构 1). 连接层 最上层是一些客户端和链接服务&#xff0c;包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念&#xff0c;为通过认证安全…...

Spring-JAVA

针对你的问题&#xff08;211本科、Java开发方向&#xff09;&#xff0c;以下是中级Java开发工程师的晋升时间、薪资水平及技术要求的详细说明&#xff0c;结合国内一线/二线城市现状&#xff08;数据基于2023年行业调研&#xff09;&#xff1a; 一、晋升中级开发工程师的时间…...

sql的索引与性能优化相关

之前面试的时候&#xff0c;由于在简历上提到优化sql代码&#xff0c;老是会被问到sql索引和性能优化问题&#xff0c;用这个帖子学习记录一下。 1.为什么要用索引 ------------------------------------------------------------------------------------------------------…...

【Git版本控制器】第四弹——分支管理,合并冲突,--no-ff,git stash

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux网络编程 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 ​ 相关笔记&#xff1a; https://blog.csdn.net/djd…...

Elasticsearch除了用作查找以外,还能可以做什么?

前言 Elasticsearch用于实时数据分析、日志存储、业务智能等。还有日志与监控、多租户和安全性。以及应用场景包括日志分析、公共数据采集、全文搜索、事件数据、数据可视化。处理错误拼写和支持变体&#xff0c;不过这些可能还是属于搜索优化。企业搜索、日志管理、应用监控、…...

Gradio全解11——使用transformers.agents构建Gradio UI(6)

大模型WebUI:Gradio全解11——使用transformers.agents构建Gradio UI(6) 前言本篇摘要11. 使用transformers.agents构建Gradio UI11.6 通过agents构建Gradio UI11.6.1 ChatMessage数据类1. 数据结构2. 例程11.6.2 构建Gradio UI示例1. 代码及运行2. 代码解读参考文献前言 本…...

自定义实现简版状态机

状态机&#xff08;State Machine&#xff09;是一种用于描述系统行为的数学模型&#xff0c;广泛应用于计算机科学、工程和自动化等领域。它通过定义系统的状态、事件和转移来模拟系统的动态行为。 基本概念 状态&#xff08;State&#xff09;&#xff1a;系统在某一时刻的特…...

算法常见八股问题整理

1.极大似然估计和交叉熵有什么关系 在分类问题中&#xff0c;当我们使用softmax函数作为输出层时&#xff0c;最大化对数似然函数实际上等价于最小化交叉熵损失函数。具体来说&#xff0c;在多分类情况下&#xff0c;最大化该样本的对数似然等价于最小化该样本的交叉熵损失。 交…...

关于GeoPandas库

geopandas buildings gpd.read_file(shapefile_path) GeoDataFrame 对象有一个属性叫做 sindex 空间索引通常是基于 R-树 或其变体构建的&#xff0c;这些数据结构专为空间查询优化&#xff0c;可以显著提高查询效率&#xff0c;尤其是在处理大型数据集时。 buildings_sin…...

【漫话机器学习系列】103.学习曲线(Learning Curve)

学习曲线&#xff08;Learning Curve&#xff09;详解 1. 什么是学习曲线&#xff1f; 学习曲线&#xff08;Learning Curve&#xff09;是机器学习和深度学习领域中用于评估模型性能随训练过程变化的图示。它通常用于分析模型的学习能力、是否存在过拟合或欠拟合等问题。 从…...

电商运营中私域流量的转化与变现:以开源AI智能名片2+1链动模式S2B2C商城小程序为例

摘要 电商运营的核心目标在于高效地将产品推向市场&#xff0c;实现私域流量的转化和变现。本文以“罗辑思维”的电商实践为背景&#xff0c;探讨了私域流量变现的重要性&#xff0c;并深入分析了开源AI智能名片21链动模式S2B2C商城小程序在电商运营中的应用与价值。通过该模式…...

Python常见面试题的详解19

1. 如何使用Django 中间件 Django 中间件宛如一个灵活且强大的插件系统&#xff0c;它为开发者提供了在请求处理流程的不同关键节点插入自定义代码的能力。这些节点包括请求抵达视图之前、视图完成处理之后以及响应即将返回给客户端之前。借助中间件&#xff0c;我们可以实现诸…...

Python 数据类型转换

目录 整数&#xff08;int&#xff09;与浮点数&#xff08;float&#xff09;之间的转换 &#xff08;1&#xff09;int()&#xff1a;将浮点数或字符串转换为整数 &#xff08;2&#xff09;float()&#xff1a;将整数或字符串转换为浮点数 字符串&#xff08;str&#xf…...

进程概念、PCB及进程查看

文章目录 一.进程的概念进程控制块&#xff08;PCB&#xff09; 二.进程查看通过指令查看进程通过proc目录查看进程的cwd和exe获取进程pid和ppid通过fork()创建子进程 一.进程的概念 进程是一个运行起来的程序&#xff0c;而程序是存放在磁盘的&#xff0c;cpu要想执行程序的指…...

PyEcharts 数据可视化:从入门到实战

一、PyEcharts 简介 PyEcharts 是基于百度开源可视化库 ECharts 的 Python 数据可视化工具&#xff0c;支持生成交互式的 HTML 格式图表。相较于 Matplotlib 等静态图表库&#xff0c;PyEcharts 具有以下优势&#xff1a; 丰富的图表类型&#xff08;30&#xff09;动态交互功…...

RT-Thread+STM32L475VET6——ADC采集电压

文章目录 前言一、板载资源二、具体步骤1.打开CubeMX进行配置1.1 使用外部高速时钟&#xff0c;并修改时钟树1.2 打开ADC1的通道3&#xff0c;并配置为连续采集模式(ADC根据自己需求调整&#xff09;1.3 打开串口1.4 生成工程 2. 配置ADC2.1 打开ADC驱动2.2 声明ADC2.3 剪切stm…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...