当前位置: 首页 > 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…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...