FHE 之 面向小白的引导(Bootstrapping)
1. 引言
FHE初学者和工程师常会讨论的一个问题是;
- “什么是引导(bootstrapping)?”
从理论角度看,这个问题的答案很简单:
- 引导就是套用 Gentry 提出的思想——在加密状态下同态地执行解密操作,并使用其私钥的加密形式来实现。
但这个解释往往让人困惑,尤其是在面对如今各种 FHE(全同态加密)库所提供的不同加密方案时,这种说法并不能真正帮助理解什么是引导。
要理解引导,首先需要理解两个概念,它们适用于所有同态加密的密文:
- 密文的“等级”(level)
- 密文中的“噪声”(noise)
无论使用哪种底层加密方案(BGV、BFV、CKKS 或 TFHE),每个密文都有一个噪声值;而“等级”这个概念只适用于 BGV、BFV 和 CKKS 这类方案。
在这些方案中,每次执行同态乘法时,都会“消耗”一个等级:
- 也就是说,密文的等级值会减少 1 1 1;
- 同时,密文中的噪声也会增加。
经过一定数量的操作后(具体数量取决于所使用的加密方案),密文就无法再继续执行操作了。这通常是因为:
- 等级已经降到 0(执行了过多的乘法);
- 或 噪声增长过大(如执行了大量加法);
- 或者 两者同时发生。
在这个时候,就需要“引导(bootstrapping)”了:
- 引导的作用是将密文的等级恢复到更高的值,
- 并且(根据不同方案)可能还能减少噪声。
引导通常被认为是一个昂贵的操作(虽然目前的技术已经让它变得更快了),因此大家在实际使用中会尽量避免频繁执行引导操作。
为了让情况变得更复杂一些,常常会看到同一个加密方案的同一实现,其运行时间却各不相同。这是因为“运行时间”可以从以下四个角度来看待:
- 最直观的方式是延迟(latency):
也就是“执行一次引导操作需要多长时间?” - 第二个角度(适用于 BGV、BFV、CKKS)是密文打包(ciphertext packing)的概念:
在这些方案中,可以将多个明文打包进一个密文中,从而实现摊销(amortization)。
换句话说:每秒可以对多少个明文槽(slot)执行引导操作?
这衡量的是吞吐量(throughput),其计算方式大致为:
吞吐量 = 支持的槽位数 单次引导的延迟(秒) \text{吞吐量} = \frac{\text{支持的槽位数}}{\text{单次引导的延迟(秒)}} 吞吐量=单次引导的延迟(秒)支持的槽位数
这类摊销来自于纯粹的数学优化。 - 第三个角度是利用指令级并行带来的摊销:
比如使用切片策略、多线程、甚至 GPU 实现。
这类优化不是数学上的,而是工程实现上的优化。
它同样可以用“每秒可引导的明文槽位数”来衡量。 - 第四种衡量方式(在2021年论文Bootstrapping for HElib 中提出):
考虑的是:
引导操作提供的槽位数 × 可支持的乘法深度 执行一次引导所需时间 \frac{\text{引导操作提供的槽位数 × 可支持的乘法深度}}{\text{执行一次引导所需时间}} 执行一次引导所需时间引导操作提供的槽位数 × 可支持的乘法深度
本文不会深入讨论这种摊销方式。
不过,在大多数应用场景中,人们关注的重点并不是高吞吐量,而是低延迟——
也就是说,更希望快速完成一次函数评估,而不是慢慢完成很多次函数评估。
因此,在许多实际应用中,引导性能的关键指标是:
- 延迟。
要更深入理解这个问题,就必须结合具体加密方案来研究引导操作对等级、噪声和性能的影响。
而这恰恰是引发混淆的地方:
- 一种加密方案中的引导行为,通常无法直觉性地迁移到另一种方案中去理解。
现在,来总结目前主流加密库中提供的三大类 FHE(全同态加密)方案在执行引导(bootstrapping)时的行为差异:
- BGV / BFV
- CKKS
- TFHE
其中:
- [1] 指:2021年论文Bootstrapping for HElib
- [3] 指:2021年论文Sine Series Approximation of the Mod Function for Bootstrapping of Approximate HE
- [4]指:Zama团队2022年7月6日博客Announcing Concrete-core v1.0.0-gamma with GPU acceleration
2. BGV / BFV
在BGV / BFV这些方案中,引导操作的作用是:
- 增加密文的等级(level);
- 同时减少噪声(noise)。
引导前后的密文加密的是相同的明文消息(即明文内容不发生变化)。
一个 BGV/BFV 计算通常是由一系列加法和乘法组成的:
- 目标是尽量减少乘法的深度(multiplicative depth);
- 乘法深度越高,所需引导次数也越多。
- BGV/BFV 的引导操作通常非常耗时(延迟高);
- 但由于支持密文打包(ciphertext packing),可以实现较好的摊销效果。
3. CKKS
在 CKKS 中,明文本身就带有一定的噪声,因为它们表示的是实数的近似值。
- 引导操作不会减少噪声,它只是提升密文的等级。
因此,CKKS引导前后的密文并不加密完全相同的明文:
- 它们分别是对同一个实数的不同近似值。
不过,随着每次操作(包括引导),明文近似值的误差也会不断增大。
- 所以,如果要计算一个很深的电路,就必须使用非常大的参数;
- 仍然需要关注长运算序列中误差的积累问题。
总体而言,CKKS 的引导延迟与 BGV/BFV 相近。
4. TFHE
在 TFHE 中,引导操作在某种程度上类似于 BGV/BFV 方案的引导 —— 它能够减少噪声。但由于 TFHE 没有“等级(level)”的概念,无需考虑与等级相关的问题。
然而,TFHE 的引导具有两个重要的区别:
- 延迟非常低
引导操作的延迟极小,每秒可以执行成千上万次引导,如果使用 GPU 加速,性能还会更高。 - 支持“可编程引导(Programmable Bootstrapping)”
在引导过程中,可以同态地评估一个查找表(LUT)函数,且几乎没有额外开销。
如,假设一个密文加密的是一个 4 4 4-bit 的值,即取值范围为 [ 0 , … , 15 ] [0, \ldots, 15] [0,…,15] 的整数,那么在引导的同时,可以“免费”地评估任何一个将 4 4 4-bit 输入 映射为 4-bit 输出 的函数。
这意味着在 TFHE 中,同态计算变成了 一系列的加法、乘法和查找表函数的评估。因此:
- 引导的速度比其他方案快了若干个数量级;
- 计算可以用更丰富的语言表达;
- 实现复杂函数所需的操作次数更少;
- 无需像 CKKS 那样通过增加参数规模来支持深层电路。
5. 总结
引导(Bootstrapping)技术使得同态计算可以持续不断地进行下去。它的实现依赖于修改密文关联的“等级(level)”与“噪声(noise)”。具体如何修改、其延迟(latency)和吞吐量(throughput)等性能指标,都取决于所采用的具体 FHE 加密方案。
为了总结各种方案下引导的表现,以下我提供了一张对比表,内容摘自目前(2022年11月)所知的相关研究论文。
其中:
- [1] 指:2021年论文Bootstrapping for HElib
- [3] 指:2021年论文Sine Series Approximation of the Mod Function for Bootstrapping of Approximate HE
- [4]指:Zama团队2022年7月6日博客Announcing Concrete-core v1.0.0-gamma with GPU acceleration
对于表中 BGV 的时间数据(来源于2021年论文Bootstrapping for HElib),使用了 thin-bootstrapping 的计时方式:也就是说,假设每个明文槽(plaintext slot)仅包含一个基本域/环上的元素,而不是扩展域/环的元素。这种形式在实际应用中最具相关性。
需要注意的是,对于 BGV,还可以考虑第四种性能度量方式:
- 即引导的摊销成本,涵盖所有明文槽以及未来可以“免费”执行的乘法次数(即无需再次引导)。
- 在以上表格中未纳入这一项,但可以粗略理解为:将原始吞吐量乘上 15 到 30 的系数,具体取决于使用的参数集合。
2022年论文BASALISC: Flexible Asynchronous Hardware Accelerator for Fully Homomorphic Encryption 中 提出了一种用于 BGV 的硬件加速器设计,它在明文空间为 Z / ( 12 7 3 ) Z Z/(127^3)Z Z/(1273)Z、并具有 64 个明文槽的情况下,实现了 40 毫秒的引导延迟。预计如果为其他同态加密方案也设计专用硬件,加速效果也将达到3 个数量级的提升。
至于 CKKS 的引导时间,采用2021年论文Sine Series Approximation of the Mod Function for Bootstrapping of Approximate HE 中的实验数据,其引导误差为 2 − 25 2^{-25} 2−25。
参考资料
[1] Zama团队2022年11月16日博客 Bootstrapping for Dummies
相关文章:
FHE 之 面向小白的引导(Bootstrapping)
1. 引言 FHE初学者和工程师常会讨论的一个问题是; “什么是引导(bootstrapping)?” 从理论角度看,这个问题的答案很简单: 引导就是套用 Gentry 提出的思想——在加密状态下同态地执行解密操作ÿ…...
安装:Kali2025+Docker
安装:Kali2025Docker Kali2025安装 直接官网下载WMware版本 https://www.kali.org/get-kali/#kali-virtual-machines 直接打开运行 初始用户密码 kali/kali sudo -i 命令切换到root 更换镜像 切换到其他可用的 Kali Linux 镜像源可能会解决问题,可以使用国内的镜像源&…...
什么是深拷贝什么是浅拷贝,两者区别
什么是深拷贝什么是浅拷贝,两者区别 1.深拷贝 递归复制对象的所有层级,嵌套的引用类型属性,最后生成一个完全独立的新对象,与原对象无任何引用关联。 特点: 新对象和原对象的所有层级属性是独立的(修改…...
A2A大模型协议及Java示例
A2A大模型协议概述 1. 协议作用 A2A协议旨在解决以下问题: 数据交换:不同应用程序之间的数据格式可能不一致,A2A协议通过定义统一的接口和数据格式解决这一问题。模型调用:提供标准化的接口,使得外部应用可以轻松调…...
第七章 数据库编程
1 数据库编程基础 1.1 数据库系统概述 数据库系统是由数据库、数据库管理系统(DBMS)和应用程序组成的完整系统。其主要目的是高效地存储、管理和检索数据。现代数据库系统通常分为以下几类: 关系型数据库(RDBMS):如MySQL、PostgreSQL、Oracle等&#x…...
电影感户外哑光人像自拍摄影Lr调色预设,手机滤镜PS+Lightroom预设下载!
调色详情 电影感户外哑光人像自拍摄影 Lr 调色,是借助 Lightroom 软件,针对户外环境下拍摄的人像自拍进行后期处理。旨在模拟电影画面的氛围与质感,通过调色赋予照片独特的艺术气息。强调打造哑光效果,使画面色彩不过于浓烈刺眼&a…...
C++--类的构造函数与初始化列表差异
一,引言 在类中成员函数的构造函数担任其将对象初始化的作用,而初始化列表也有着相似的作用。大部分人建议都是初始化列表进行初始化,本文主要进行讲解二者的区别。 首先看一下构造函数的初始化方式: #define _CRT_SECURE_NO…...
深入浅出之STL源码分析4_类模版
1.引言 我在上面的文章中讲解了vector的基本操作,然后提出了几个问题。 STL之vector基本操作-CSDN博客 1.刚才我提到了我的编译器版本是g 11.4.0,而我们要讲解的是STL(标准模板库),那么二者之间的关系是什么&#x…...
Lambda表达式解读
本文通过具体案例演示函数式接口Function<T,R>的三种实现方式演变过程。 一、传统匿名内部类实现 Integer resInt1 t1(new Function<String, Integer>() {Overridepublic Integer apply(String s) {int i Integer.parseInt(s);return i;} });实现特点࿱…...
PySide6 GUI 学习笔记——常用类及控件使用方法(常用类边距QMarginsF)
文章目录 类简介方法总览关键说明示例代码 类简介 QMarginsF 用于定义四个浮点型边距(左、上、右、下),描述围绕矩形的边框尺寸。所有边距接近零时 isNull() 返回 True,支持运算符重载和数学运算。 方法总览 方法名/运算符参数返…...
Android方法耗时监控插件开发
需求:自定义一个Gradle插件,这个Gradle插件可以统计方法的耗时,并当方法耗时超过阈值时,可以通过打印Log日志在控制台,然后可以通过Log定位到耗时方法的位置,帮助我们找出耗时方法和当前线程名,…...
TWAS / FUSION
FUSION 是一套用于执行转录组范围和调控组范围关联研究(TWAS 和 RWAS)的工具。它通过构建功能/分子表型的遗传成分的预测模型,并使用 GWAS 汇总统计数据预测和测试该成分与疾病的关联,目标是识别 GWAS 表型与仅在参考数据中测量的…...
C++中的static_cast:类型转换的安全卫士
C中的static_cast:类型转换的安全卫士 在C编程中,类型转换是不可避免的操作,而static_cast作为C四大强制类型转换运算符之一,是最常用且相对安全的一种转换方式。今天我们就来深入探讨一下这个重要的类型转换工具。 一、static_…...
uniapp-商城-51-后台 商家信息(logo处理)
前面对页面基本进行了梳理和说明,特别是对验证规则进行了阐述,并对自定义规则的兼容性进行了特别补充,应该说是干货满满。不知道有没有小伙伴已经消化了。 下面我们继续前进,说说页面上的logo上传组件,主要就是uni-fil…...
04 mysql 修改端口和重置root密码
当我们过了一段时间,忘了自己当初创建的数据库密码和端口,或者端口被占用了,要怎么处理呢 首先,我们先停止mysql。 一、修改端口 打开my.ini文件,搜索port,默认是3306,根据你的需要修改为其他…...
多线程 2 - 死锁问题
死锁 死锁,是多线程代码中的一类经典问题。加锁能够解决线程安全问题,但如果加锁方式不当,就很可能产生死锁。 出现死锁的三种场景 1、一个线程一把锁 就像上篇文章讲过的,如果对同一个线程上了两把锁,而且上的锁是…...
网络原理(Java)
注:此博文为本人学习过程中的笔记 在网络初始中谈到TCP/IP五层模型,接下来我们将介绍这里面涉及到的网络协议。 应用层是程序员接触最多的层次,程序员写的代码只要涉及到网络通信都可以视为是应用层的一部分。应用层里的东西和程序员直接相…...
HDFS 常用基础命令详解——快速上手分布式文件系统
简介: 本文面向刚接触 Hadoop HDFS(Hadoop 分布式文件系统)的读者,结合 CSDN 博客风格,系统梳理最常用的 HDFS 客户端命令,并配以示例和注意事项,帮助你在开发和运维中快速掌握 HDFS 的文件管理…...
Unity Shaders and Effets Cookbook
目录 作者简介 审稿人简介 前言 我是偏偏 Unity Shaders and Effets Cookbook 第一章:Diffuse Shading - 漫反射着色器 第二章:Using Textures for Effects - 着色器纹理特效的应用 第三章:Making Your Game Shine with Specular - 镜…...
Markdown—LaTeX 数学公式
目录 一、字母1. 希腊大写字母2. 希腊小写字母3. 花体字母 二、上标和下标1. 上标2. 下标3. 其他 三、括号四、数学符号1. 基本数学符号1)运算符2)常见函数3)分式、根号、累加/乘4)极限5)积分 2. 三角函数与几何符号1&…...
AI 驱动的开发工具
🔧 主流 AI 前端开发工具 1. GitHub Copilot 由 GitHub 与 OpenAI 联合开发,集成在 Visual Studio Code、JetBrains 等主流 IDE 中,提供智能代码补全、函数生成等功能,极大地提高了开发效率。 (CSDN博客) 2. Cursor 一款 AI 驱…...
【入门】数字走向I
描述 输入整数N,输出相应方阵。 输入描述 一个整数N。( 0 < n < 10 ) 输出描述 一个方阵,每个数字的场宽为3。 #include <bits/stdc.h> using namespace std; int main() {int n;cin>>n;for(int i1;i<n*n;i){cout…...
Kubernetes生产实战(十三):灰度发布与蓝绿发布实战指南
在微服务架构中,如何安全高效地发布新版本是每个团队必须掌握的技能。本文将深入讲解Kubernetes中两种主流发布策略的落地实践,附带生产环境真实案例。 一、金丝雀发布(灰度发布):渐进式验证新版本 核心思想…...
数孪实战笔记(1)数字孪生的含义、应用及技术体系
一、含义 数字孪生(Digital Twin)是一种通过数字化模型在虚拟世界中实时映射和模拟物理实体、系统或过程的技术。它的核心目的是通过对现实对象的建模、感知、分析和预测,实现对物理世界的全面感知、智能控制和优化决策。数字孪生 实体对象 …...
深入浅出之STL源码分析5_类模版实例化与特化
在 C 中,类模板的实例化(Instantiation)和特化(Specialization) 是模板编程的核心概念,而 显式实例化(Explicit Instantiation)和隐式实例化(Implicit Insta…...
JDBC演进之路:从基础操作到高效连接池
文章目录 一、JDBC 1.0:手动管理的起点1.1 核心特点1.2 代码示例:1.3 痛点分析 二、JDBC 2.0:配置化的升级2.1 核心改进2.2 代码示例2.3 优势与不足 三、JDBC 3.0:连接池的革命3.1 核心改进3.2 代码示例3.3 核心优势 四、版本对比…...
远程调试---在电脑上devtools调试运行在手机上的应用
1、启动项目–以vite项目为例:先ipconfig查看ip地址 ,然后在vite中配置host为ip地址 2、手机上查看项目:保证手机和电脑在同一局域网, 在手机浏览器打开我们vite启动的项目地址, 3、使用chii进行远程调试 (1) 安装 npm install chii -g (2)启动 chii start -p 8080 (3)在…...
街景主观感知全流程(自建数据集+两两对比程序+Trueskill计算评分代码+训练模型+大规模预测)27
目录 0、Emeditor软件1、Place Pluse 2.0数据集2、街景主观感知大框架2.1 街景主观感知:自建数据集2.2 街景主观感知:两两对比程序2.3 街景主观感知:Trueskill评分2.4 街景主观感知:训练模型,Resnet或EfficientNet或V…...
进阶二:基于HC-SR04和LCD1602的超声波测距
一、实验目的 掌握HC-SR04超声波测距模块的工作原理和使用方法。学会使用LCD1602液晶显示屏显示测量数据。熟悉89C51单片机与外设的接口电路设计和编程方法。二、实验原理 1. HC-SR04超声波测距模块原理 HC-SR04超声波测距模块可提供2cm - 400cm的非接触式距离感测功能,测距精…...
单因子实验 方差分析
本文是实验设计与分析(第6版,Montgomery著傅珏生译)第3章单因子实验 方差分析python解决方案。本文尽量避免重复书中的理论,着于提供python解决方案,并与原书的运算结果进行对比。您可以从 下载实验设计与分析(第6版&a…...
《Python星球日记》 第53天:卷积神经网络(CNN)入门
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、图像表示与通道概念1. 数字图像的本质2. RGB颜色模型3. 图像预处理 二、卷积…...
基于人工智能的个性化 MySQL 学习路径推荐研究
基于人工智能的个性化 MySQL 学习路径推荐研究 摘要: 随着信息技术的飞速发展,数据库在各行业应用广泛,MySQL 作为主流数据库之一,学习需求庞大。然而,不同学习者在知识水平、学习进度和目标上存在差异,传统统一的学习路径难以满足个性化需求。本研究通过运用人工智能技…...
阿里云OSS-服务端加签直传说明/示例(SpringBoot)
目录 概述 OSS文件上传方式 1. OSS控制台上传 2. 客户端直传 3. 后端上传 4. 加签直传 服务端加签方式 1. 服务端生成PostObject所需的签名和Post Policy 2.服务端生成STS临时访问凭证 3. 服务端生成PutObject所需的签名URL 实现1:生成PostObject所需的签…...
《向上生长》读书笔记day5
哎,好像有点坚持不下去了,有点松懈了 不咋想继续写读书笔记😂,不过我不可能这么轻易放弃的,起码要做完这一本书,话不多说,开始进入的读书📒笔记 今天读了两个章节,穷人翻…...
优选算法——队列+BFS
目录 1. N叉树的层序遍历 2. 二叉树的锯齿层序遍历 3. 二叉树最大宽度 4. 在每个树行中找最大值 1. N叉树的层序遍历 题目链接:429. N 叉树的层序遍历 - 力扣(LeetCode) 题目展示: 题目分析: 层序遍历即可~仅…...
Java MCP 实战 --> AI玩转贪吃蛇
MCP 实战 --> AI玩转贪吃蛇 MCP 更加便捷的扩展了 LLM 的能力,使得 AI 发展更加迅猛。本篇主要为了学习MCP的应用,实现了让AI去玩贪吃蛇,使用 Java 实现了 MCP Server 和 MCP Client 的编码。其他文章如下: thinking 基础版…...
Day20打卡-奇异值SVD分解
今天学习非特征筛选的方法: 知识点回顾: 线性代数概念回顾(可不掌握)奇异值推导(可不掌握)奇异值的应用 特征降维:对高维数据减小计算量、可视化数据重构:比如重构信号、重构图像&am…...
【RT-Thread Studio】nor flash配置Fal分区
前置条件:【RT-Thread Studio】W25Q128配置 添加 FAL软件包 配置SFUD驱动程序,使用FAL的设备为W25Q128 将fal_cfg.h和fal_flash_sfud_port.c提取出来,放到自己创建的fal_porting目录。 修改 fal_flash_sfud_port.c struct fal_flash_dev n…...
在资源受限设备上实现手势识别:基于包络EMG数据和实时测试的Tiny-ML方法
英文标题:Enabling Gesture on a Resource-Constrained Device: A Tiny-ML Approach with Envelope EMG Data and Real-Time Testing 中文标题:在资源受限设备上实现手势识别:基于包络EMG数据和实时测试的Tiny-ML方法 作者信息 Mohsin Ali S…...
动态规划:最长递增子序列
给定一个数组,求最长递增子序列的长度,就是要求我们求出一个序列中最长的上升子序列的长度,最长上升子序列的定义就是从原序列中按照孙旭去除一些数字,这些数字是逐渐增大的。 *定义dp[i]表示以第i个元素结尾的最长上升子序列的长度。 *初始…...
贪心算法专题(Part2)
目录 1. 最优除法 2. 加油站 3. 坏了的计算器 4. 可被三整除的最大和 5. 单调递增的数字 6. 合并区间 7. 无重叠区间 8. 用最少数量的箭引爆气球 1. 最优除法 题目链接:553. 最优除法 - 力扣(LeetCode) 题目展示: 题目分…...
4.9/Q1,GBD数据库最新文章解读
文章题目:The burden of diseases attributable to high body mass index in Asia from 1990 - 2019: results from the global burden of disease study 2019 DOI:10.1080/07853890.2025.2483977 中文标题:1990 年至 2019 年亚洲高体重指数导…...
API 网关核心功能解析:负载均衡、容灾、削峰降级原理与实战摘要
在微服务架构中,API 网关作为流量入口枢纽,通过负载均衡、容灾、削峰降级等核心功能保障系统稳定性与高可用性。本文结合 Spring Cloud Gateway 实战代码、原理剖析及行业最佳实践,深度解析网关核心能力,并对比当前前沿技术方案&a…...
Spring之AOP
什么是AOP AOP:Aspect 0riented Programming(面向切面编程、面向方面编程),可简单理解为就是面向特定方法编程。 场景:案例中部分业务方法运行较慢,定位执行耗时较长的接口,此时需要统计每一个业务方法的 执行耗时。 优势: 1.减少重复代…...
TransmittableThreadLocal:穿透线程边界的上下文传递艺术
文章目录 前言一、如何线程上下文传递1.1 ThreadLocal单线程1.2 InheritableThreadLocal的继承困境1.3 TTL的时空折叠术 二、TTL核心设计解析2.1 时空快照机制2.2 装饰器模式2.3 采用自动清理机制 三、设计思想启示四、实践启示录结语 前言 在并发编程领域,线程上下…...
基于STM32的甲醛检测
一、制作目标 以正点原子的miniSTM32F103RCT6开发板为主控,使用甲醛传感器检测环境空气中的甲醛含量(以mg/m^3为单位)、C02含量(以ppm为单位)和总有机挥发物含量TVOC(以mg/m^3为单位)在OLED显示…...
人形机器人:主控芯片
目前人形机器人领域的主控芯片因厂商和应用场景不同而有所差异,以下是一些主要人形机器人及其可能使用的主控芯片概况,基于公开信息和行业趋势。由于具体型号常为商业机密,部分信息为推测: 主要人形机器人及其主控芯片 特斯拉&am…...
Web自动化测试入门详解
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、目的 web自动化测试作为软件自动化测试领域中绕不过去的一个“香饽饽”,通常都会作为广大测试从业者的首选学习对象,相较于C/S架…...
数据结构:树(树的定义和基本术语)
非空树:有且仅有一个根节点 空树:节点数为0的树 在非空树中根节点没有前驱,叶子结点(终端结点)没有后继,分支结点(非终端结点)前驱和后继都有,前驱有且仅有一个。 下图…...
用jsp简单实现C语言标准化测试系统
C语言标准化测试系统 在Web编程技术的学习过程中,我们小组为了深入理解相关技术原理,提升实践能力,开发了一个基于动态Web工程框架的C语言标准化考试系统。现在,就来和大家分享一下我们的项目经历。 一、实验目的剖析 这个项目…...