DevOps落地笔记-20|软件质量:决定系统成功的关键
上一课时介绍通过提高工程效率来提高价值交付效率,从而提高企业对市场的响应速度。在提高响应速度的同时,也不能降低软件的质量,这就是所谓的“保质保量”。具备高质量软件,高效率的企业走得更快更远。相反,低劣的软件质量,高效率则会让企业死得更快。高质量的软件是企业一直在追求的目标,那么又有哪些指标可以帮助我们识别软件存在的问题呢?这就是今天就介绍一些有关这方面的内容。
什么是软件质量?
如今,任何一个企业都是数字化企业,任何一家数字化企业都是以软件为业务核心。因此,软件的质量是企业生死存亡的关键因素,务必要引起重视。既然软件质量如此重要,领导者需要了解当前软件质量是多少,存在什么问题,软件质量的发展趋势是什么,这些就是软件质量的度量。
软件质量也包含两部分:内部质量和外部质量。
& 内部质量:是指被开发人员感知的质量,比如,代码的缺陷、坏味道、不合理的架构设计等。内部质量是造成外部质量的源头,在开发过程中要尽早发现、尽早修复内部质量问题,提高发布到生产环境中产品的外部质量。
& 外部质量:是指能够被用户感知到的质量。比如,用户在使用产品的过程中出现异常,服务不可用,响应迟钝等现象,影响用户体验。外部质量是决定产品是否成功的关键,提高外部质量是团队成员的最终目标。
& 下面分别从内部质量和外部质量两个方面介绍软件的质量。
内部质量
企业在实施 DevOps 的实践中,也一直在尝试将代码质量的检查集成到流程中,比如持续交付流水线中集成静态代码检查,单元测试覆盖率检查等环节。针对代码质量检查的工具也有很多,常用的有 SonarQube、PMD、FindBugs 等。下面这张图是 SonarQube 代码质量检查的概览页面。
代码质量检查
代码质量度量是针对代码本身的度量,根据开发人员的主动和被动,以及对软件造成的影响大小,可以分为Bug 和漏洞以及技术债务。
& Bug 和漏洞。
Bug 和漏洞是开发人员在开发业务功能时,在无意识行为下产生的代码问题,即并不是开发人员故意为之。这类问题一般不易被发现,一旦被发现需要及时修复,因为会对软件造成严重影响。Bug 是指代码中的错误,可能会阻止程序按预期运行,影响的是程序的可靠性。漏洞是指代码中的问题,心怀不轨的人会利用这些问题破坏程序的安全性。
比如:Java 语言中,字符串和装箱类型的比较使用 equals() 进行比较。下面这段代码就会检查出 Bug。
String firstName = getFirstName(); String lastName = getLastName();if (firstName == lastName) { ... };
这是因为使用==或!=比较运算符,比较的是内存地址而不是具体的值。在某些情况下,即便 firstName 和 lastName 具体的值相等,但也返回 false。
缺陷和漏洞的度量,一般采用数量和级别,级别分为BLOCKER(阻断)、CRITICAL(严重)、MAJOR(主要)、MINOR(次要)、INFO(提示)。
& 技术债务。
技术债务是指开发人员在开发和设计的时候,为了能满足短期的效益而采取的权宜之计。比如:缺乏自动化测试的代码,包含坏味道的代码。坏味道是指不会阻止程序的正常运行,但可能会对代码的可维护性产生影响。如上图中技术债务需要1天偿还,包含坏味道 86 个,这些就是对技术债务的度量。
如下面就是一个坏味道的例子,当数组或集合返回 null 时,调用方需要做 null 判断,否则就会抛出空指针异常。
public static List<Result> getResults() {return null; // Noncompliant}public static Result[] getResults() {return null; // Noncompliant}public static void main(String[] args) {Result[] results = getResults();if (results != null) { // Nullity test required to prevent NPEfor (Result result: results) {/* ... */}}}
除此之外,还包含圈复杂度、函数代码行、文件代码行、重复代码率、重复文件数等度量。
测试质量检查
测试阶段又称为质量保证(QA)阶段,是软件开发过程中确保软件功能性和非功能性需求满足用户要求的阶段。为了提高测试效率,很多企业逐渐减少人工测试的比率,提高自动化测试的比率。测试阶段的质量度量可以使用测试覆盖率和测试缺陷数量来表示。
测试覆盖率。
测试覆盖率是衡量代码质量的一个方法,是指自动化测试中代码的覆盖程度,包含单元测试、集成测试、回归测试的测试覆盖率。上图中 54.6% 是测试覆盖率的度量。测试覆盖率越高,发现问题的概率越大,在测试阶段发现的问题越多,软件发布到生产环境后问题就会越少。
但是关于测试覆盖率“多少算是合适?”这一问题,很多人是存在分歧的。业界普遍认为测试覆盖率达到 80% 就足够了。这里强调的是,测试一定是有效测试,无效的测试即便 100% 覆盖也没有任何意义。
& 测试缺陷数量。
测试缺陷数量是指在测试阶段发现的代码问题的数量。如下图所示。每一个缺陷又可以按缺陷类型、严重程度、发现阶段进行标记。
1.缺陷类型:用户体验问题、性能问题、接口问题、界面问题、环境问题等。
2.严重程度:致命缺陷、严重缺陷、一般缺陷、轻微缺陷和建议等。
3.发现阶段:功能测试、单元测试、集成测试、用户验收测试等。
测试阶段的目的就是发现问题,所以我们不能惧怕发现问题。在实际开发过程中,测试人员给开发人员提 Bug,开发人员会很抵触,好像是污蔑自己的编码智商,使得开发和测试也会处于对立局面。另外,测试人员要分清哪些是 Bug,哪些是需求改进,不要将需要优化的需求也作为 Bug 提给开发人员。
虽然会度量测试阶段的缺陷数量,但不要作为衡量团队成员能力的依据,也不会作为绩效考核的标准。还是前面提到的,要以结果性、全局性的指标为最终指标。
外部质量
上面介绍了内部质量,以及通过代码检查和自动化测试来保证内部质量,在开发流程中也集成了工具和制度。虽然我们做了大量的质量保证活动,就一定能交付高质量的产品吗?答案是“不一定”。内部质量并不能说明用户对产品是满意的还是抱怨的,也不能说明用户使用过后,是想继续使用还是想舍弃。由于缺少这些相关的度量信息,以至于无法判断产品的质量状态。因此,要从用户满意度、产品非功能性等方面评估产品的外部质量。
用户满意度
用户满意度是从最终用户的角度对产品的评判。企业在调查用户满意度方面已经很成熟了,有多种方式可以收集用户对产品或服务的评价信息。拨打过 10086 的同学都知道,客服在结束时都会说“请您稍后对我的服务做出评价,满意请按 1,不满意请按 2”,这就是收集用户满意信息的一种方式,其他的还有:
& 调查问卷;
& 互联网产品卸载时的弹窗;
& 投诉与建议。
这几种方式,都可以了解用户对产品的哪些功能不满意,为后期进行产品功能优化时提供依据。那么,用什么方式度量用户满意度比较合适呢?业界认为“净推荐值(NPS)”是衡量用户满意度的黄金标准。这是计算某个客户会向其他人推荐某个企业或服务可能性的指数,采用 0-10 分进行打分,分数越高说明你越愿意推荐这个企业或服务。
产品非功能性
除了用户本身对产品或服务的直观感受外,用户在使用产品过程中感知的产品非功能性问题也是衡量产品质量一个因素。比如产品的可靠性、性能等。
& 可靠性:是指用户在使用产品的过程中出现服务不可用的概率。这里既可以指具体的人使用产品功能,也可以指系统间的调用或通信。总之,给用户带来的影响是不能正常的使用产品。
& 性能:是指用户在使用产品时的流畅性,未出现卡顿、延迟等现象。比如,打开一个页面需要 10s 以上,虽然还能够使用产品,但用户体验不好。
产品的非功能性问题会最终影响用户满意度,一般通过用户反馈的缺陷和问题数量及严重程度来度量产品的可靠性,通过应用程序性能监控系统(APM) 度量产品的性能。随着DevOps实践的不断深入,通过蓝绿部署、金丝雀发布等方法,先在一小部分用户使用新版本,以便提前发现软件存在的问题,从而避免让更多用户受到影响。以及使用混沌工程,提前发现问题,减少产品不可用的概率。这些方法都是针对产品的非功能性采取的防控措施。
总结
本课时主要介绍了软件质量,这一决定产品成功与失败的关键要素。软件的质量分为内部质量和外部质量,二者相辅相成,互相影响。内部质量是源头,外部质量是结果。提高内部质量会进一步提升外部质量,外部质量也会反过来促进内部质量的提升。DevOps 的目标是在提高研发效率的同时,也要提高软件产品的质量。
如今市场竞争越发激烈,用户在第一次使用后,认为产品或服务没有达到满意,是不会再有第二次机会的。因此,软件的质量是企业研发的重中之重,也是企业实施 DevOps 的目标之一。
相关文章:

DevOps落地笔记-20|软件质量:决定系统成功的关键
上一课时介绍通过提高工程效率来提高价值交付效率,从而提高企业对市场的响应速度。在提高响应速度的同时,也不能降低软件的质量,这就是所谓的“保质保量”。具备高质量软件,高效率的企业走得更快更远。相反,低劣的软件…...

政安晨:梯度与导数~示例演绎《机器学习·神经网络》的高阶理解
这篇文章确实需要一定的数学基础,第一次接触的小伙伴可以先看一下我示例演绎这个主题的前两篇文章: 示例演绎机器学习中(深度学习)神经网络的数学基础——快速理解核心概念(一): 政安晨&#…...

CTFSHOW命令执行web入门29-54
description: >- 这里就记录一下ctfshow的刷题记录是web入门的命令执行专题里面的题目,他是有分类,并且覆盖也很广泛,所以就通过刷这个来,不过里面有一些脚本的题目发现我自己根本不会笑死。 如果还不怎么知道写题的话,可以去看我的gitbook,当然csdn我也转载了我自己的…...

探索ChatGPT4:新一代人工智能语言模型的突破
ChatGPT4,作为最新一代的语言处理模型,代表了人工智能在自然语言理解和生成方面的最新突破。本文将深入介绍ChatGPT4的新特性,探讨其在各个领域的潜在应用。 ChatGPT4概述 在继承了前一代模型的强大基础之上,ChatGPT4引入了多项…...

PVST详解
PVST(Per-VLAN Spanning Tree)是Cisco公司的一种扩展的Spanning Tree协议,允许在每个VLAN中独立运行一个Spanning Tree实例,从而提高网络的可靠性和性能。 PVST协议在每个交换机中维护多个Spanning Tree实例,每个实例…...

c++ 子进程交互 逻辑
目录 一、主进程逻辑 1、创建子进程时候,写入自己的HWND 2、响应子进程消息...

C#实现矩阵乘法
目录 一、使用的方法 1.矩阵 2.矩阵的乘法原理 二、实例 1.源码 2.生成效果 一、使用的方法 矩阵相当于一个数组,主要用来存储一系列数,例如,mn矩阵是排列在m行和n列中的一系列数,mn矩阵可与一个np矩阵相乘,结果…...

Objective-C 中的SEL
在 Objective-C 中,SEL(Selector)是一种用来表示方法的类型。 它实际上是一个指向方法的指针,用于在运行时动态调用方法。 下面是一个使用 SEL 的代码示例: #import <Foundation/Foundation.h>interface MyCl…...

使用 Docker 镜像预热提升容器启动效率详解
概要 在容器化部署中,Docker 镜像的加载速度直接影响到服务的启动时间和扩展效率。本文将深入探讨 Docker 镜像预热的概念、必要性以及实现方法。通过详细的操作示例和实践建议,读者将了解如何有效地实现镜像预热,以加快容器启动速度,提高服务的响应能力。 Docker 镜像预热…...
锁(二)队列同步器AQS
一、队列同步器AQS 1、定义 用来构建锁或者其他同步组件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。是实现锁的关键。 2、实现 同步器的设计是基于模板方法模式的,也就是说&#…...

【知识整理】招人理念、组织结构、招聘
1、个人思考 几个方面: 新人:选、育、用、留 老人:如何甄别? 团队怎么演进? 有没有什么注意事项 怎么做招聘? 2、 他人考虑 重点: 1、从零开始,讲一个搭建团队的流程 2、标…...

监控概述、安装zabbix、配置zabbixagent、添加被控端主机、常用监控指标、自定义监控项
目录 监控概述 监控命令 zabbix 安装zabbix 6.0 配置zabbix监控web1服务器 在web1上安装agent 在web页面中添加对web1的监控 常用监控指标 自定义监控项 实现监控web1用户数量的监控项 在被控端创建key 创建模板 应用模板到主机 查看结果 监控概述 对服务的管理&am…...

恒创科技:香港 BGP 服务器网络连通性如何测试?
随着互联网的快速发展,网络连通性测试变得越来越重要。网络连通性测试的目的是确定网络设备之间的连接是否正常,以及数据包是否能够在网络中顺利传输。本文将介绍一种简单易行的香港 BGP 服务器网络连通性的测试方法,利用tracer测试工具。这里…...

《动手学深度学习(PyTorch版)》笔记7.6
注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过&…...

Quicker读取浏览器的书签(包括firefox火狐)
从edge换了火狐,但是quicker不能读取本地的bookmarks文件了,就研究了一下。 方法1:读取本地Bookmarks文件(仅谷歌内核浏览器) 谷歌内核的浏览器本地会有Bookmarks文件,放了所有的书签数据,直接…...

【数学建模】【2024年】【第40届】【MCM/ICM】【B题 搜寻潜水器】【解题思路】
一、题目 (一)赛题原文 2024 MCM Problem A: Resource Availability and Sex Ratios Maritime Cruises Mini-Submarines (MCMS), a company based in Greece, builds submersibles capable of carrying humans to the deepest parts of the ocean. A …...

深入探索Redis:如何有效遍历海量数据集
深入探索Redis:如何有效遍历海量数据集 Redis作为一个高性能的键值存储数据库,广泛应用于各种场景,包括缓存、消息队列、排行榜等。随着数据量的增长,如何高效地遍历Redis中的海量数据成为了一个值得探讨的问题。在本篇博客中&am…...

贪心算法之田忌赛马,多种语言实现
目录 题目描述: 输入: 样例输入: 样例输出: c代码实现: c++代码实现: python代码实现: Java代码实现: 题目描述: 这是中国历史上一个著名的故事。 “那是大约2300年前的事了。田骥将军是齐国的高级官员。他喜欢和国王和其他人一起赛马。 “田和王都有三匹不同等级…...

C++ static 修饰全局变量时的作用探究
C static 修饰全局变量时的作用探究 作为一个c开发者,我们面试时经常被问到 static 变量的作用,其中有一个问题是,static 修饰全局变量时起什么作用。 通常我们会回答,“static 修饰全局变量时代表限制这个变量为此源文件可见&a…...

Git的基础操作指令
目录 1 前言 2 指令 2.1 git init 2.2 touch xxx 2.3 git status 2.4 git add xxx 2.5 git commit -m xxxx 2.5 git log及git log --prettyoneline --all --graph --abbrev-commit 2.6 rm xxx 2.7 git reset --hard xxx(含小技巧) 2.8 git reflog 2.9 mv xxx yyy 1…...

前端开发:(四)JavaScript入门
JavaScript是一种强大的脚本语言,用于在网页中实现交互性和动态性。它的发展历史可以追溯到1995年,由Netscape公司的Brendan Eich设计开发而成。JavaScript的重要性在于它能够让网页实现丰富的功能和用户体验,成为Web开发的核心技术之一。 1…...

js文件忽略ESLint语法检查
1. 整个文件忽略 /* eslint-disable */ // 代码开始位置2. 临时禁止 /* eslint-disable */ console.log(hello); /* eslint-enable */3. 对指定规则忽略 /* eslint-disable no-alert, no-console */ alert(foo); console.log(bar); /* eslint-enable no-alert, no-console …...

【深度学习】:实验6布置,图像自然语言描述生成(让计算机“看图说话”)
清华大学驭风计划 因为篇幅原因实验答案分开上传,深度学习专栏持续更新中,期待的小伙伴敬请关注 实验答案链接http://t.csdnimg.cn/bA48U 有任何疑问或者问题,也欢迎私信博主,大家可以相互讨论交流哟~~ 案例 6 :图像自…...

内网安全-内网穿透
目录 内网渗透 Nc使用详解 Nc监听和探测 Nc传文件 termite内网穿透工具 ssh代理内网穿透 ssh配置socket代理 MSF多级网络穿透 内网渗透 Nc使用详解 Nc监听和探测 Nc传文件 termite内网穿透工具 1、termite 之前叫ew (可以进行正向连接,可以…...

【Make编译控制 01】程序编译与执行
目录 一、编译原理概述 二、编译过程分析 三、编译动静态库 四、执行过程分析 一、编译原理概述 make: 一个GCC工具程序,它会读 makefile 脚本来确定程序中的哪个部分需要编译和连接,然后发布必要的命令。它读出的脚本(叫做 …...

MySQL如何定位慢查询
MySQL中定位慢查询通常涉及到以下几个步骤: 1. 慢查询日志 开启慢查询日志是识别慢查询的第一步。通过设置slow_query_log变量为1,MySQL会记录所有执行时间超过long_query_time秒的查询。 -- 开启慢查询日志 SET GLOBAL slow_query_log ON;-- 设置慢…...

npm 上传一个自己的应用(4) 更新自己上传到NPM中的工具版本 并进行内容修改
前面 npm 上传一个自己的应用(2) 创建一个JavaScript函数 并发布到NPM 我们讲了将自己写的一个函数发送到npm上 那么 如果我们想到更好的方案 希望对这个方法进行修改呢? 比如 我们这里加一个方法 首先 我们还是要登录npm npm login然后 根据要求填写 Username 用…...

Linux开发:PAM1 介绍
PAM(Pluggable Authentication Modules )是Linux提供的一种通用的认证方式,他可以根据需要动态的加载认证模块,从而减少认证开发的工作量以及提供认证的灵活度。 1.PAM的框架 PAM的框架由一下几个部分构成 1)应用程序,即需要使用认证服务的程序,这些应用程序是使用抽象…...

Leetcode 3036. Number of Subarrays That Match a Pattern II
Leetcode 3036. Number of Subarrays That Match a Pattern II 1. 解题思路2. 代码实现 3036. Number of Subarrays That Match a Pattern II 1. 解题思路 这一题其实有点水,因为本质上还是一道套路题目,和前两周的两道题目一样,都是考察的…...

华为环网双机接入IPTV网络部署案例
环网双机接入IPTV网络部署案例 组网图形 图2 环网双机场景IPTV基本组网图 方案简介配置注意事项组网需求数据规划配置思路操作步骤配置文件 方案简介 随着IPTV业务的迅速发展,IPTV平台承载的用户也越来越多,用户对IPTV直播业务的可靠性要求越来越高。…...