【密码学】全同态加密张量运算库解读 —— TenSEAL

news2024/10/28 5:35:27

项目地址:https://github.com/OpenMined/TenSEAL

论文地址:https://arxiv.org/pdf/2104.03152v2

TenSEAL 是一个在微软 SEAL 基础上构建的用于对张量进行同态加密操作的开源Python库,用于在保持数据加密的状态下进行机器学习和数据分析。

TenSEAL 库使用了Microsoft SEAL库作为其加密引擎。它提供了一组高级API,可以方便地进行加密、解密及密态操作,如同态加法、同态乘法和同态运算。

TenSEAL 支持多种机器学习算法,包括逻辑回归、线性回归和神经网络等。通过使用TenSEAL,用户可以在保护数据隐私的同时进行分析和计算,而无需担心数据泄漏的风险。

一、项目工程

功能

  • 基于 BFV(Brakerski/Fan-Vercauteren)方案的整数向量进行加密 / 解密;

  • 基于 CKKS(Cheon-Kim-Kim-Song)方案的实数向量进行加密 / 解密;

  • 密文 - 密文向量以及密文 - 明文向量进行逐元素的加法、减法和乘法操作。

  • 点积和矩阵乘法。

  • tenseal.sealapi 封装了完整的 SEAL API。

示例

# pip install tenseal==0.3.15
import tenseal as ts

# Setup TenSEAL context
context = ts.context(
            ts.SCHEME_TYPE.CKKS,
            poly_modulus_degree=8192,
            coeff_mod_bit_sizes=[60, 40, 40, 60]
          )
context.generate_galois_keys()
context.global_scale = 2**40

v1 = [0, 1, 2, 3, 4]
v2 = [4, 3, 2, 1, 0]

# encrypted vectors【编码和加密】
enc_v1 = ts.ckks_vector(context, v1)  
enc_v2 = ts.ckks_vector(context, v2)

# 密文 + 密文
result = enc_v1 + enc_v2
result.decrypt() # ~ [4, 4, 4, 4, 4]

# 点积:<密文,密文>
result = enc_v1.dot(enc_v2)
print(result.decrypt()) # ~ [10]

matrix = [
  [73, 0.5, 8],
  [81, -5, 66],
  [-100, -78, -2],
  [0, 9, 17],
  [69, 11 , 10],
]
# 密文向量 * 明文矩阵
result = enc_v1.matmul(matrix)
print(result.decrypt()) # ~ [157, -90, 153]

参数

  • SCHEME_TYPE:ts.SCHEME_TYPE.CKKS。

  • poly_modulus_degree:8192。

  • coeff_mod_bit_sizes:系数模数大小,这里的[60, 40, 40, 60]表示系数模数将包含4个素数,分别为60位、40位、40位和60位。

  • global_scale:缩放因子(scaling_factor),即 2^{40}

(1)缩放因子(scaling_factor

CKKS方案的第一步是将实数向量编码为明文多项式,采用固定缩放因子进行定点运算。 缩放因子指的是编码精度,用数字二进制表示。如下图所示:

scaling_factor 是CKKS中用于将浮点数编码为整数以进行加密的缩放比例因子,用于控制加密方案的计算精度。即是在加密和解密过程中使用的缩放倍数,通常是某个 2 的幂次(如2^{40}2^{50})。它决定了加密时将浮点数扩展为整数时的精度。

的作用是在计算过程中对数据进行缩放,以管理噪声的增长。通过适当的缩放,可以在一定程度上减少噪声对计算结果的影响,从而保持计算的准确性。

精度控制缩放因子越大,计算结果的精度越高。它直接影响浮点数在加密过程中保持的精度,较小的缩放因子可能导致精度损失。

噪声积累较大的缩放因子能减少噪声的相对影响,因为密文的精度更高。然而,如果缩放因子过大,会增加密文大小和计算复杂度。

数值范围缩放因子决定了能表示的数值范围。如果缩放因子太小,可能无法表示足够精确的浮点数;而过大的缩放因子可能导致密文噪声增长过快。

计算精度方面,缩放因子的选择直接影响着计算结果的精度。如果缩放因子选择不当,可能会导致计算结果的精度下降,尤其是在进行多次同态计算后。

计算次数方面,缩放因子与 CKKS 算法能够支持的计算次数相关。不合适的缩放因子可能会导致噪声过快增长,从而限制了能够进行的同态计算次数。例如,如果缩放因子过大,可能会在较少的计算步骤后就使噪声超过可接受的范围,无法继续进行准确的计算。因此,需要根据具体的计算需求和数据特点,合理选择缩放因子,以平衡计算精度和计算次数。

(2)多项式模数次数(poly_modulus_degree

poly_modulus_degree 表示CKKS加密方案中多项式环的维度,即多项式的最大次数。多项式环通常表示为R_q = \mathbb{Z}_q[X] / (X^N + 1),其中 N 就是 poly_modulus_degree

这个参数定义了多项式的最大次数,从而决定了加密数据的 “容量”。较高的poly_modulus_degree可以表示更大范围的数值,但同时也会增加计算复杂度。

它决定了多项式环的维度,即加密方案的基本操作空间,通常取为2的幂(例如 1024、2048、4096、8192 、16384、32768)。

性能和存储开销增大多项式模数次数会增加加密密文的大小和计算的开销,因为多项式操作的复杂度与多项式模数次数成正比。

安全性多项式模数次数越大,安全性越高。通常,较大的值提供更好的抗量子攻击能力,但也需要权衡计算效率。

并行化计算较大的多项式模数次数允许更多的并行计算。

如果选择过大的poly_modulus_degree,可能会导致计算速度过慢,不适合实际应用场景。例如,在某些资源受限的环境中,如移动设备或边缘计算节点,过高的多项式次数可能会使加密计算变得不切实际。

(3)多项式系数模数(coeff_mod_bit_sizes

coeff_mod_bit_sizes 表示CKKS的模数链中每个系数模数的位数(通常以比特为单位)。模数链由多个模数组成,随着每次乘法和重新缩放操作,模数链中的模数逐渐减少。 它是一个列表,表示在模数链中的每个模数的比特大小。例如,[60, 40, 40, 60] 表示模数链有 4 个模数,其中每个模数的比特长度分别为 60、40、40 和 60。

由这个参数决定是一组素数coeff_modulus,决定了"新鲜密文""的噪音预算。coeff_modulus 至少有两个素数组成,最好是少的,最合理的使用2~8个素数,单个素数可以达到60bit,噪音预算和这些素数的总比特呈线性关系。

支持的乘法深度多项式系数模数决定了支持的乘法深度(即能执行的最大乘法次数)。模数链越长,支持的乘法次数越多,但计算开销也越大。

噪声控制每次乘法后,密文的噪声会增加。重新缩放操作减少模数链的长度以控制噪声,因此较大的模数链可以处理更多次乘法。

计算精度模数链的大小决定了运算精度。如果模数链太短,重新缩放后剩余的模数不足以支持高精度运算。

coeff_mod_bit_sizes会影响方案的安全性:如果其他参数保持不变,总比特越大,安全性越低。但是为了获得更大的计算力,也就是说要提升噪音预算,就要增加coeff_mod_bit_sizes的总比特数,所以为了安全性,需要增大poly_modulus_degree,这可能会对批处理的性能产生影响,所以计算性能也会改变。从计算性能角度看,较大的系数模数比特大小会增加计算的复杂性。因为在同态运算中,涉及到对系数的操作,更大的比特大小意味着更多的计算步骤。在安全性方面,系数模数的选择也会影响加密方案的安全性。不合适的系数模数可能会导致加密系统容易受到攻击。因此,在选择coeff_mod_bit_sizes时,需要在计算性能和安全性之间进行权衡。

其中,n表示分圆多项式的度数(poly_modulus_degree),logq表示系数模的比特长度(coeff_mod_bit_sizes的总比特数)。security level表示安全级别。

总结

  • poly_modulus_degree:决定多项式环的维度,影响加密系统的安全性、并行计算能力和性能。

  • coeff_mod_bit_sizes:定义模数链的比特长度,决定加密方案的精度和支持的乘法深度。

  • scaling_factor:控制加密和运算的精度,较大的缩放因子提供更高的精度,但也增加了计算复杂度和密文大小。

这些参数的选择通常需要在安全性、性能、精度和计算深度之间做出权衡。

密钥

  • 公钥:用于加密。

  • 私钥:用于解密,不共享,TenSEALContext对象中保存。

  • 重线性化密钥(Relinearization Keys)【可公开】:用于重线性化(密钥交换),在乘法后用于降低密文维数

  • 伽罗瓦密钥(Galois Keys)【可公开】:用于批处理密文的旋转。批处理向量的旋转的应用是密文求和

默认情况下,会自动执行重线性化后和重缩放。

二、论文解读

摘要

机器学习算法已经取得了显著的效果,并被广泛应用于各个领域。这些算法通常依赖于敏感和私有数据,如医疗和财务记录。因此,进一步关注隐私威胁和应用于机器学习模型的相应防御技术至关重要。在本文中,我们介绍了TenSEAL,这是一个使用同态加密保护隐私数据的机器学习开源库,可以轻松地集成到流行的机器学习框架中。我们使用MNIST数据集对我们的实现进行了benchmark测试,结果显示加密的卷积神经网络可以在不到一秒钟的时间内进行计算,通信量不到0.5MB。

1、介绍

近年来,机器学习狂奔发展。在典型场景中,用户需要将数据发送给服务提供商,服务提供商将对数据执行一些计算并返回结果。这种方法有两个关键问题。首先,出于隐私考虑,用户可能不想将其数据发送给服务提供商。其次,如果用户不向服务提供商发送数据,那服务提供商就无法向用户提供模型。使用同态加密,可以解决该问题,用户的数据将始终加密,服务提供商将看不到输入和输出,并且仍然可以对这些加密数据进行计算。然而,在机器学习中采用同态加密的速度很慢。原因之一,虽然目前可用的密码库为密码学家提供了一个优秀的API,但对于数据科学家来说,使用它们可能具有挑战性。另一个原因,是计算成本,包括通信和计算成本。

贡献
  • 我们提出了一个灵活的开源库,使用同态加密进行密文的张量计算。该库可以直接将张量从当前流行的机器学习框架(如 PyTorch 或 Tensorflow)转换为加密版本。

  • 我们在不到一秒的时间内在加密数据上评估卷积神经网络,推理过程中的通信时间不到0.5MB。

论文的其余部分,我们在第2节中描述了库的架构。在第 3 节中详细介绍在加密空间中计算卷积神经网络所需的算法。在第 5 节中,我们对我们的库进行了实验性测试,并在第 6 节中总结了我们工作的一些局限性。

2、架构

TenSEAL 是一个将经典机器学习框架与同态加密功能联系起来的库。它管理着在加密数据进行张量运算的所有复杂性。TenSEAL 依赖于 Microsoft SEAL 中 CKKS方案的实施。客户端可以使用一种受支持的前端语言(C++ 或 Python)处理明文张量或密文张量。在客户端 - 服务器方案中,消息交换是使用协议缓冲区完成的。核心 API 围绕三个主要组件构建:环境(context)、明文张量和密文张量。

环境 context

TenSEAL的context是库的核心组件。它生成并存储加密计算所需的必要密钥。context生成用于加密的公钥、用于解密的私钥、用于旋转的伽罗瓦密钥以及用于密文重新线性化的重新线性化密钥。

这个context对象还将处理 thread-pool,它控制在执行可并行化操作时应并行运行多少个 job。同时context还可以配置为在计算期间执行自动进行密文重新线性化(relinearization)和重新缩放(rescaling)。

明文张量

明文张量(PlainTensor)是一个将未加密张量与加密实现相连接的类。下图描述了张量的转换过程。

张量(Tensor):

是深度学习中广泛使用的数据结构,本质上就是一个高维的矩阵,甚至将其理解为NumPy中array,Pandas中的DataFrame。

单个元素叫标量(scalar),一个序列叫向量(vector),多个序列组成的平面叫矩阵(matrix),多个平面组成的立方体叫张量(tensor)。在深度学习的范畴内,标量、向量和矩阵都统称为张量。

密文张量

EncryptedTensor 接口提供了一个 API,需要由库公开的每个张量实现。接口有一个 TenSEALContext 对象,这是进行任何同态加密操作所必需的。派生类公开了不同的张量风格,例如:

  • CKKSVector 派生 EncryptedVector 接口,并且可以通过将实数向量加密为单个密文。

  • CKKSTensor 将实数的 N 维张量加密为密文的 N 维张量。但是,它可以批处理轴以及每个密文中可用的槽,因此只需要 (N-1) 维的密文张量。

3、方法

在同态加密方案上构建张量时,需要解决两个重要问题: 1,如何在加密之前对张量进行编码? 2、使用特定编码时可以执行哪些操作?

CKKS 方案的批处理功能允许将一个 N \times N 矩阵加密为 N 个密文,每行或每列为一个密文。另一种可能性是将整个张量加密为单个密文。根据我们将明文张量放入密文的方式,我们可以执行不同的操作,具有不同的复杂度。目标是使用最少数量的密文,并在最小运行时间内具有最大深度,从而优化内存和计算。为了寻求这个理想目标,我们发现我们可以使用单个密文对输入图像进行加密,并在卷积神经网络上对其进行计算。这需要在客户端进行预处理步骤,将图像编码为矩阵,由卷积窗口作为行组成,然后通过垂直扫描将其展平为向量。在 TenSEAL 中,所有这些功能都是围绕 CKKSVector 实现的。一个CKKSVector 包含 N/2个实数值,其中 N 是多项式模数的次数。我们可以与其他加密或明文向量执行逐元素操作(加法、减法和乘法)。我们有一种方法用于计算加密向量的幂(逐元素),该方法使用最优电路,从而使用最小乘法深度。此外,因为我们需要不同激活函数的多项式近似,所以我们构建了一种方法,用于以密文向量作为变量求值多项式,确保使用最小电路。除了逐元素操作外,我们还需要矩阵操作来执行机器学习任务。我们实现了 Halevi 和 Shoup(2014)提出的密文向量与明文矩阵乘法的变体,该变体可以使用多个线程以更快地运行。

A.2

可以查看附录中的表3,以获取库的密文张量支持的操作列表。

点积(dot)

TenSEAL为点积提供了与 Halevi & Shoup(2014)类似的计算方法,但支持的向量大小不是2的幂,或者未填满密文的所有插槽。先前方法中的这一限制是由于右旋转期望最后一个元素为第一个元素,而对于我们处理的情况并非如此。如果向量大小不是 2 的幂,我们的方法在点积数量上受到特定限制。然而,通常不会达到此限制,因为该方案允许的乘法数量可能更低。我们通过将输入向量尽可能多次复制到密文插槽中,并在计算期间仅进行左密文旋转来实现。我们的方法与 Halevi & Shoup(2014)具有相同的算法复杂度。我们使用 CKKS实现了它,用于加密向量与明文矩阵之间的点积运算。因此,它可以扩展为支持加密矩阵与明文矩阵之间的点积(矩阵乘法)。

A.3

附录中的图 3 展示了如何在密文向量与明文矩阵之间执行点积运算:

卷积(conv2d)

TenSEAL还支持计算卷积,即提供当前流行的机器学习框架(例如PyTorch)计算卷积的类似实现。我们使用了Image Block to Columns (im2col)技术,该技术将卷积层转换为单个矩阵乘法运算。这种技术需要密文矩阵乘明文向量,我们通过对矩阵转置与复制的明文向量进行逐元素乘法来实现。最后,将结果旋转并累加到单个密文向量中。

此操作仅使用一个乘法运算和log2(N)个旋转和加法,其中N表示矩阵中的行数。下面解释如何将“图像块-》列”算法应用于加密输入。需要注意的是,转换发生在明文数据中,转换后的输入图像进行编码和加密为单个密文。这直接意味着堆叠两个卷积是不可能的,因为重新组织密文的插槽并非易事。j

A.4

可以使用单个矩阵乘法来执行二维卷积,而不是在每个窗口上重复乘法。这种方法称为图像块到列的卷积( image block to column),或图像到列的卷积(image to column)。下图显示了如何使用此方法执行卷积。它首先将输入矩阵重新组织成表示卷积窗口的行,然后用扁平化的卷积核执行点积,如图4所描述。

将此技术应用于加密矩阵(加密为一个密文)并不是一件小事,因为重新组织slot并不那么简单。我们需要在加密之前将矩阵重新组织为预处理步骤,以便为卷积做好准备。

密文矩阵(输入图像)和 明文向量(kernel)的计算可以通过逐元素乘法和一系列旋转和累加来执行。图5、图6显示了执行此操作的步骤。第一步显示了密文矩阵(彩色)是如何编码并与明文向量(kernel)相乘的。第二步是对向左旋转不同的不同版本的输出求和。

 第4小节:相关工作、第5小节:实验性测试、第6小节:总结 ---- 略

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2225217.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ssm旅游网页开发与设计+jsp

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 摘 要 I 目 录 III 第1章 绪论 1 1.1 研究背景 1 1.2目的和意义 1 1.3 论文研究内容 1 第2章 程序…

银河麒麟V10系统下libopenblas.so.0和libllmlmf库的安装

1、当前linux服务器系统是银河麒麟V10&#xff0c;具体的内核和cpu型号如下&#xff1a; 2、使用:uname -a来进行查询 Linux localhost.localdomain 4.19.90-89.16.v2401.ky10.x86_64 #1 SMP Sat Sep 14 13:09:47 CST 2024 x86_64 x86_64 x86_64 GNU/Linux 3、在部署QT开发的应…

vue通过JSON文件生成KML文件源码

可以使用封装的json解析器进行JSON数据获取&#xff0c;读取点的经度、维度、高程等数据&#xff0c;再使用对应的KML文件生成函数使用该源码下载KML文件&#xff08;固定KML生成&#xff1a;js模板式生成大疆上云kml文件&#xff08;含详细注释&#xff0c;已封装成函数&#…

从病理AI的基础模型发展历程,看未来的医学AI发展趋势|个人观点·24-10-23

小罗碎碎念 在临床相关的人工智能&#xff08;AI&#xff09;模型发展方面&#xff0c;传统上需要大量标注数据集&#xff0c;这使得AI的进步主要围绕大型中心和私营企业展开。所以&#xff0c;在这期推文中&#xff0c;我会介绍一些已经商用的模型&#xff0c;并且为计划进军…

Minio文件服务器:SpringBoot实现文件上传

在Minio文件服务器部署成功后(参考上篇文章Minio文件服务器&#xff1a;安装)接下来我们通过SpringBoot框架写一个接口&#xff0c;来实现文件的上传功能&#xff1a;文件通过SpringBoot接口&#xff0c;上传到Minio文件服务器。并且&#xff0c;如果上传的文件是图片类型&…

裴蜀定理与欧几里得算法——蓝桥杯真题中的应用

目录 裴蜀定理&#xff08;Bzouts Theorem&#xff09;1、定义2、推论3、欧几里得算法4、多个整数的裴蜀定理扩展 真题挑战解题思路代码实现与详细注释代码解析 裴蜀定理&#xff08;Bzout’s Theorem&#xff09; 1、定义 对于任意两个整数 a 和 b &#xff0c;如果它们的最…

Gateway 统一网关

一、初识 Gateway 1. 为什么需要网关 我们所有的服务可以让任何请求访问&#xff0c;但有些业务不是对外公开的&#xff0c;这就需要用网关来统一替我们筛选请求&#xff0c;它就像是房间的一道门&#xff0c;想进入房间就必须经过门。而请求想要访问微服务&#xff0c;就必须…

聚链成网,趣链科技参与 “跨链创新联合体”建设

近日&#xff0c;2024全球数商大会在上海举办。大会由上海数据集团和上海市数商协会联合主办&#xff0c;上海市数据局和浦东新区人民政府支持&#xff0c;以“数联全球&#xff0c;商通未来——‘链’接数字经济新未来”为主题&#xff0c;聚焦区块链技术和应用场景展开。 会上…

Windows生成公钥和私钥

1、打开命令提示符或 PowerShell&#xff1a; 按下 Win R&#xff0c;输入 cmd 或 powershell&#xff0c;然后按 Enter 打开命令提示符或 PowerShell 窗口。 2、生成密钥对&#xff1a; 输入以下命令生成 RSA 密钥对 ssh-keygen -t rsa -b 2048-t rsa 表示生成 RSA 类型的密…

开源模型应用落地-Qwen2-VL-7B-Instruct-vLLM-OpenAI API Client调用

一、前言 学习Qwen2-VL &#xff0c;为我们打开了一扇通往先进人工智能技术的大门。让我们能够深入了解当今最前沿的视觉语言模型的工作原理和强大能力。这不仅拓宽了我们的知识视野&#xff0c;更让我们站在科技发展的潮头&#xff0c;紧跟时代的步伐。 Qwen2-VL 具有卓越的图…

android studio编译错误提示无法下载仓库

一、调整方法之一 buildscript {repositories {google()jcenter()//maven { url https://maven.aliyun.com/repository/google }//maven { url https://maven.aliyun.com/repository/central }}dependencies {// classpath "com.android.tools.build:gradle:4.1.1"c…

Python金色流星雨

系列目录 序号直达链接爱心系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4Python李峋同款可写字版跳动的爱心5Python流星雨代码6Python漂浮爱心代码7Python爱心光波代码8Python普通的玫瑰花代码9Python炫酷的玫瑰花代码10Python多…

算法的学习笔记—翻转单词顺序列(牛客JZ73)

&#x1f600;前言 在《剑指 Offer》系列题中&#xff0c;有一道关于翻转单词顺序的经典题目。给定一个由多个单词组成的字符串&#xff0c;需要将每个单词的顺序颠倒。这道题考察了对字符串的操作技巧&#xff0c;尤其是如何在限定空间内完成字符串的翻转。本文将详细解析这道…

吉客云与金蝶云星空系统高效数据对接实践

调拨出库红字对接分步式调入(退货)案例分享&#xff1a;吉客云数据集成到金蝶云星空 在企业的日常运营中&#xff0c;数据的高效流转和准确对接是实现业务流程自动化和优化的重要环节。本文将聚焦于一个具体的系统对接集成案例——如何将吉客云的数据无缝集成到金蝶云星空&…

阿里云物联网的通信方式

阿里云物联网通信的两种方式&#xff0c;一个是物模型&#xff08;分为服务&#xff0c;事件&#xff0c;属性&#xff09;&#xff0c;一个是自定义topic&#xff08;要另外设置数据流转&#xff09; 1.使用产品内的功能定义&#xff0c;&#xff08;其实也就是Topic中定义好的…

Prompt Engineering (Prompt工程)

2 prompt工程2大原则 2.1 给出清晰&#xff0c;详细的指令 策略1&#xff1a;使用分割符清晰的指示输出的不同部分&#xff0c;比如"",<>,<\tag>等分隔符 策略2&#xff1a;指定一个结构化的输出&#xff0c;比如json,html等格式 策略3&#xff1a;要…

重学SpringBoot3-Spring WebFlux之SSE服务器发送事件

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ Spring WebFlux之SSE服务器发送事件 1. 什么是 SSE&#xff1f;2. Spring Boot 3 响应式编程与 SSE为什么选择响应式编程实现 SSE&#xff1f; 3. 实现 SSE 的基本步骤3.…

【JavaEE】【多线程】volatile,wait/notify

目录 一、volatile关键字1.1 内存可见性1.2 volatile解决内存可见性问题 二、wait和notify2.1 wait2.2 notify2.3 使用例子2.3.1 例子12.3.2 例子二 一、volatile关键字 volatile可以保证内存可见性&#xff0c;只能修饰变量。 1.1 内存可见性 在前面介绍线程不安全原因时介…

AI编译器与TVM

由于AI芯片的特殊性和高度定制化&#xff0c;为了兼容硬件的多样性&#xff0c;AI模型必须能被高效地映射到各种AI芯片上。AI编译器将深度学习框架描述的AI模型作为输入&#xff0c;将为各种AI芯片生成的优化代码作为输出。AI编译器的目标是通过编译优化的方法将深度学习框架产…

Git的原理和使用(六)

本文主要讲解企业级开发模型 1. 引入 交付软件的流程&#xff1a;开发->测试->发布上线 上面三个过程可以详细划分为一下过程&#xff1a;规划、编码、构建、测试、发 布、部署和维护 最初&#xff0c;程序⽐较简单&#xff0c;⼯作量不⼤&#xff0c;程序员⼀个⼈可以完…