浏览器数据存储方法深度剖析:LocalStorage、IndexedDB、Cookies、OPFS 与 WASM - SQLite
在当今的 Web 开发领域,选择合适的浏览器数据存储方法对于构建高效、功能丰富的应用程序至关重要。随着 Web 应用的不断演进,从早期的静态 HTML 页面到如今复杂的单页应用和本地优先应用,数据存储需求也日益多样化。本文将深入探讨 LocalStorage、IndexedDB、Cookies、OPFS(Origin - Private File System)和 WASM - SQLite 这几种常见的浏览器数据存储技术,比较它们的特性、限制,并通过性能测试揭示其在实际应用中的表现。
一、现代浏览器中的存储 API 概述
(一)Cookies
1994 年由网景公司引入的 Cookies,主要用于存储小型键值数据,在会话管理、个性化和跟踪等方面发挥着重要作用。它不仅存储在客户端,还会随每个 HTTP 请求发送到服务器,因此其存储容量有限,通常每个 Cookie 不超过 4KB(RFC - 6265 规定)。虽然其存储的数据量小,但由于是 Web 的重要基础特性,在性能优化方面一直备受关注,如 Chromium 的共享内存版本控制和异步 CookieStore API。
(二)LocalStorage
作为 2009 年 WebStorage 规范的一部分提出的 LocalStorage,提供了简单的 API 来存储键值对,包括 setItem、getItem、removeItem 和 clear 等方法。它适用于存储少量需要跨会话持久化的数据,存储上限一般在 4MB 到 10MB 之间(不同浏览器有所差异),例如 Chrome/Chromium/Edge 为 5MB,Firefox 为 10MB,Safari 为 4 - 5MB。需要注意的是,其 API 是同步的,在执行操作时会阻塞 JavaScript 进程,可能影响 UI 渲染。此外,还有 SessionStorage,其与 LocalStorage 的关键区别在于数据的生命周期,SessionStorage 在浏览器标签或窗口关闭时会清除数据。
(三)IndexedDB
2015 年首次推出的 IndexedDB 是一种低级 API,用于存储大量结构化 JSON 数据。尽管 API 使用起来有一定难度,但它支持索引和异步操作。不过,其早期版本缺乏对复杂查询的支持,仅允许通过索引迭代,更像是其他库的基础层。2018 年的 2.0 版本引入了 getAll () 方法,大幅提升了批量获取 JSON 文档的性能,而正在开发的 3.0 版本将包含更多改进,如基于 Promise 的调用,使现代 JavaScript 特性(如 async/await)更易于使用。
(四)OPFS
相对较新的 OPFS 允许 Web 应用程序直接在浏览器**中存储大文件,专为数据密集型应用设计,用于在模拟文件系统中读写二进制数据。**它有两种使用模式:在主线程上异步操作,或在 WebWorker 中使用 createSyncAccessHandle () 方法进行更快的异步访问。由于只能处理二进制数据,OPFS 主要作为库开发者的基础文件系统,对于普通应用开发者来说,直接使用可能过于复杂,更适合存储图像等普通文件,而非高效存储和查询 JSON 数据。
(五)WASM - SQLite
WebAssembly(WASM)作为一种二进制格式,于 2017 年开始在主流浏览器中得到支持,允许在 Web 上执行高性能代码。许多人开始将编译后的 SQLite 作为浏览器内的数据库使用。SQLite 的编译字节码约为 938.9kB,在首次页面加载时需要用户下载并解析。WASM 无法直接访问浏览器中的持久存储 API,需要通过虚拟文件系统(VFS)适配器将数据从 WASM 传输到主线程,再存入浏览器 API。
(六)WebSQL(已弃用)
WebSQL 于 2009 年推出,基于 SQLite,允许浏览器使用 SQL 数据库进行客户端存储。然而,由于它未标准化,依赖特定版本的 SQLite,且未得到所有主流浏览器(如 Firefox)的支持,近年来已从浏览器中移除,因此在后续讨论中将忽略它。
二、特性比较
(一)存储复杂 JSON 文档
在 Web 应用中,存储复杂 JSON 文档较为常见。只有 IndexedDB 原生支持 JSON 对象,WASM - SQLite 从 3.38.0 版本(2022 - 02 - 22)开始可以在 text 列中存储 JSON,并支持深度查询和使用单个属性作为索引。其他 API 只能存储字符串或二进制数据,虽然可以使用 JSON.stringify () 将 JSON 对象转换为字符串,但这可能会在查询时增加复杂性,多次使用还可能导致性能问题。
(二)多标签支持
与 Electron 或 React - Native 应用不同,Web 应用用户可能在多个浏览器标签中同时打开和关闭应用。并非所有存储 API 都支持自动在标签间共享写入事件,只有 LocalStorage 通过 storage - event 提供了自动共享写入事件的功能,可用于观察变化。对于 IndexedDB 等不支持的 API,开发者可以使用 BroadcastChannel API 在标签间发送消息来通知变化,或者使用 SharedWorker 在单个工作线程中进行所有写入操作,其他标签订阅该工作线程的消息以获取变化。
(三)索引支持
数据库与普通文件存储的一个重要区别在于索引支持,只有 IndexedDB 和 WASM - SQLite 开箱即支持索引。理论上可以在 LocalStorage 或 OPFS 等存储之上构建索引,但通常不建议自行构建。在 IndexedDB 中,可以通过给定的索引范围获取一批文档,例如查找价格在 10 到 50 之间的所有产品。不过,IndexedDB 对布尔值索引有限制,只能索引字符串和数字,需要在存储数据时进行转换。
(四)WebWorker 支持
在处理大量数据操作时,可能需要将处理从 JavaScript 主线程转移到 WebWorker、SharedWorker 或 ServiceWorker 中,以确保应用保持响应性和快速性。在 RxDB 中,可以使用 WebWorker 或 SharedWorker 插件将存储操作移到工作线程中。最常见的方式是生成一个 WebWorker 并在其中执行大部分工作,通过 postMessage () 与主线程通信。但 LocalStorage 和 Cookies 由于设计和安全限制,无法在 WebWorker 或 SharedWorker 中使用,而 OPFS 的快速版本(使用 createSyncAccessHandle 方法)只能在 WebWorker 中使用。
(五)存储大小限制
Cookies 存储容量约为 4KB,由于每次 HTTP 请求都会发送存储的 Cookies,因此此限制合理。LocalStorage 的存储大小限制因浏览器而异,如 Chrome/Chromium/Edge 为 5MB,Firefox 为 10MB,Safari 为 4 - 5MB。IndexedDB 和 OPFS 的最大存储大小取决于浏览器实现,通常基于用户设备的可用磁盘空间,在 Chromium 浏览器中可使用高达 80% 的总磁盘空间。
三、性能比较
(一)初始化时间
在存储数据之前,许多 API 需要设置过程,如创建数据库、启动 WebAssembly 进程或下载额外资源。LocalStorage 和 Cookies 无需设置即可直接使用,IndexedDB 需要打开数据库和内部存储,WASM - SQLite 需要下载 WASM 文件并进行处理,OPFS 需要下载并启动工作文件以及初始化虚拟文件系统目录。测试结果显示,打开一个新的 IndexedDB 数据库并创建单个存储的耗时较长;将数据从主线程发送到 WebWorker OPFS 的延迟约为 4 毫秒;下载和解析 WASM - SQLite 并创建单个表大约需要半秒,使用 IndexedDB VFS 持久化存储数据会额外增加 31 毫秒,启用缓存并预先准备好表后重新加载页面速度会稍快(内存模式下为 420 毫秒)。
(二)小数据写入延迟
在处理许多相互独立的小数据变化时,写入延迟很重要,例如从 WebSocket 流式传输数据或持久化鼠标移动等随机事件。测试结果表明,LocalStorage 的写入延迟最低,每次写入仅需 0.017 毫秒;IndexedDB 写入速度比 LocalStorage 慢约 10 倍;将数据发送到 WASM - SQLite 进程并通过 IndexedDB 持久化写入速度较慢,每次写入超过 3 毫秒;OPFS 操作将 JSON 数据写入每个文件的一个文档大约需要 1.5 毫秒,将数据发送到 WebWorker 会因数据序列化和反序列化的开销而稍慢,如果将所有数据追加到单个文件而不是为每个文档创建一个文件,性能模式会显著改变,使用 createSyncAccessHandle () 方法的更快文件句柄每次写入仅需约 1 毫秒,但需要记住每个文档的存储位置。
(三)小数据读取延迟
存储一些文档后,测量按 id 读取单个文档所需的时间。结果显示,LocalStorage 读取速度极快,每次读取仅需 0.0052 毫秒,其他技术的读取速度与其写入延迟相似。
(四)大数据批量写入
一次性执行 200 个文档的批量写入操作时,将数据发送到 WebWorker 并通过更快的 OPFS API 运行速度约快两倍;WASM - SQLite 在批量操作上的性能优于其单个写入延迟,因为一次性发送所有数据到 WASM 比逐个文档发送更快。
(五)大数据批量读取
批量读取 100 个文档时,在 OPFS WebWorker 中读取速度比在主线程模式下快约两倍;WASM - SQLite 读取速度令人惊讶地快,进一步检查发现 WASM - SQLite 进程会在内存中缓存文档,这在写入后立即读取相同数据时提高了延迟,若在写入和读取之间重新加载浏览器标签,查找 100 个文档则需要约 35 毫秒。
(六)性能总结
LocalStorage 速度快,但存在阻塞主线程、仅支持键值对存储且无法高效进行基于索引的范围查询等缺点,因此不应在大数据批量操作中使用。OPFS 在 WebWorker 中使用 createSyncAccessHandle () 方法比在主线程中直接使用快得多。WASM - SQLite 虽然可以很快,但初始下载和启动二进制文件需要约半秒,对于频繁打开和关闭的 Web 应用可能是个问题。
四、实际应用场景分析
在实际的 Web 开发中,不同的数据存储方法适用于不同的场景,开发者需要根据具体需求做出选择。
(一)LocalStorage 适用场景
1.简单偏好设置
对于存储用户的简单偏好,如页面主题(亮色或暗色模式)、语言选择等,LocalStorage 是一个理想的选择。这些数据量小且不需要复杂的查询操作,LocalStorage 的简单键值对存储方式能够轻松应对。例如,一个新闻网站可以使用 LocalStorage 来记住用户偏好的阅读字体大小或显示模式,每次用户访问时自动应用其偏好设置,提升用户体验。
2.临时数据缓存
当需要在浏览器会话期间临时缓存一些数据,如 API 请求的结果(在有效期内),以减少重复请求,LocalStorage 可以发挥作用。比如一个天气应用,在用户首次查询某个城市天气后,将结果缓存一段时间(假设 15 分钟),在这段时间内如果用户再次查看该城市天气,直接从 LocalStorage 读取缓存数据,而无需再次向服务器发送请求,既提高了应用响应速度,又减轻了服务器负担。
(二)IndexedDB 适用场景
1.离线应用数据存储
对于构建离线应用,如离线文档编辑器或离线音乐播放器,IndexedDB 能够存储大量结构化数据,如文档内容、音乐播放列表等。即使在离线状态下,用户也可以对这些数据进行操作,并且在重新联网后同步数据到服务器。例如,一个离线笔记应用,用户可以在没有网络连接时撰写和编辑笔记,笔记数据存储在 IndexedDB 中,网络恢复后将更新同步到云端服务器,确保数据不丢失且用户体验不受离线影响。
2.复杂数据管理与查询
当应用需要处理复杂的结构化数据,并进行频繁的查询和更新操作时,IndexedDB 的优势就凸显出来了。比如一个电商应用,需要存储商品信息(包括名称、价格、描述、库存等多个字段),并根据用户搜索、筛选条件(如价格范围、关键词等)快速查询和展示相关商品。IndexedDB 可以创建索引来优化这些查询操作,提高数据检索效率,确保应用的流畅运行。
(三)Cookies 适用场景
1.用户身份验证与会话管理
Cookies 在实现用户身份验证和会话管理方面有着广泛应用。服务器可以在用户登录成功后,通过设置 Cookie 来标识用户的登录状态,包含用户 ID 等关键信息。在后续用户的每个请求中,浏览器自动发送 Cookie,服务器据此验证用户身份,确定用户是否已登录以及其权限等。例如,一个在线银行系统,用户登录后,服务器设置包含用户账号信息的 Cookie,在用户进行转账、查询余额等操作时,服务器通过验证 Cookie 确保操作的安全性和合法性。
2.跟踪用户行为(需谨慎使用)
在一定程度上,Cookies 可以用于跟踪用户在网站上的行为,如记录用户浏览过的页面、点击过的链接等,以便为用户提供个性化推荐或分析用户行为模式。然而,这种跟踪行为需要谨慎处理,遵循相关隐私法规,确保用户知情权和选择权。例如,一个电商网站可能会使用 Cookies 来跟踪用户浏览过的商品类别,然后在首页或推荐页面展示相关商品的推荐信息,但必须明确告知用户并获得用户同意。
(四)OPFS 适用场景
1.大文件存储与处理
当 Web 应用需要处理大文件,如用户上传的图片、视频或大型文档时,OPFS 提供了合适的解决方案。它允许直接在浏览器中模拟文件系统来存储这些二进制文件,并且在 WebWorker 中使用时能够提供较好的性能。例如,一个在线图片编辑应用,用户上传高清图片进行编辑,图片数据可以存储在 OPFS 中,编辑过程中快速读取和写入文件,提高编辑操作的效率。
2.需要文件系统抽象的应用
对于一些需要类似本地文件系统抽象的应用,如在线代码编辑器(需要处理文件的保存、读取、目录结构等),OPFS 可以提供基础的文件系统功能支持。开发者可以基于 OPFS 构建更高级的文件操作逻辑,满足应用的特定需求。
(五)WASM - SQLite 适用场景
1.对 SQL 功能有需求的应用
如果 Web 应用需要强大的 SQL 功能,如复杂的多表关联查询、事务处理等,WASM - SQLite 是一个不错的选择。例如,一个企业级的 Web 应用,需要管理员工信息、项目信息、考勤数据等多个相关联的数据集,通过 SQL 的强大功能可以方便地进行数据的整合、分析和报表生成,WASM - SQLite 能够在浏览器端提供类似传统 SQL 数据库的功能支持。
2.性能要求较高的结构化数据存储(在特定情况下)
尽管 WASM - SQLite 初始化有一定延迟,但在处理大量结构化数据的存储和查询时,如果应用能够接受初始的启动开销,并且在后续操作中能够充分利用其性能优势,它可以提供高效的数据管理。比如一个数据分析 Web 应用,需要对大量历史数据进行存储和深度分析,WASM - SQLite 可以在内存中缓存数据,对于频繁的数据分析查询操作提供较好的性能表现。
五、总结与建议
在选择浏览器数据存储方法时,开发者需要综合考虑多个因素,包括数据类型、操作频率、存储容量需求、多标签支持、性能要求以及应用的特定场景等。
LocalStorage 简单易用,适用于少量简单数据的持久化存储,但在处理大量数据和复杂查询时存在局限性。IndexedDB 功能强大,适合处理大量结构化数据和复杂查询,但 API 复杂,学习成本较高。Cookies 主要用于会话管理和与服务器的交互,但存储容量小且安全性需谨慎处理。OPFS 专为大文件存储和文件系统操作设计,在特定文件处理场景下表现出色,但对于普通 JSON 数据存储和查询不太方便。WASM - SQLite 提供了强大的 SQL 功能,但初始化延迟和对 WebAssembly 的支持要求需要开发者权衡。
在实际应用中,开发者可以根据具体需求灵活组合使用这些存储方法,以达到最佳的性能和功能平衡。例如,在一个大型 Web 应用中,可以使用 LocalStorage 存储用户的基本设置和临时状态,IndexedDB 用于核心数据的存储和查询,Cookies 进行用户身份验证和会话管理,OPFS 处理大文件上传和存储,WASM - SQLite 在需要高级 SQL 功能的特定模块中使用。同时,关注浏览器技术的发展动态,及时利用新的特性和改进,为用户提供更好的体验。
相关文章:

浏览器数据存储方法深度剖析:LocalStorage、IndexedDB、Cookies、OPFS 与 WASM - SQLite
在当今的 Web 开发领域,选择合适的浏览器数据存储方法对于构建高效、功能丰富的应用程序至关重要。随着 Web 应用的不断演进,从早期的静态 HTML 页面到如今复杂的单页应用和本地优先应用,数据存储需求也日益多样化。本文将深入探讨 LocalStor…...

面向金融场景的大模型 RAG 检索增强解决方案
概述 在现代信息检索领域,检索增强生成(Retrieval-Augmented Generation, RAG)模型结合了信息检索与生成式人工智能的优点,从而在特定场景下提供更为精准和相关的答案。在特定场景下,例如金融等领域,用户通…...

经典蓝牙(BT/EDR)蓝牙配对与连接
经典蓝牙的连接过程包括跳频,扫描,配置交换等过程。对ACL链路以及sco的连接过程也做详细的分析。 1. 为什么不配对便无法建立连接? 任何无线通信技术都存在被监听和破解的可能,蓝牙SIG为了保证蓝牙通信的安全性,采用…...

Flask: flask框架是如何实现非阻塞并发的
写在前面:Flask框架是通过多线程/多进程+阻塞的socket实现非阻塞,其本质是基于python的源库socketserver实现的 前言 认识WSGI协议 认识Werkzeug flask是如何实现非阻塞的 本文使用的flask框架为最新的1.1.1版本,所有代码基于python3运行 一:前言 使用过flask或者其他web框…...

JAVA |日常开发中连接Oracle数据库详解
JAVA |日常开发中连接Oracle数据库详解 前言一、Oracle 数据库概述1.1 定义与特点1.2 适用场景 二、Java 连接 Oracle 数据库的准备工作2.1 添加 Oracle JDBC 驱动依赖2.2 了解连接信息 三、建立数据库连接3.1 代码示例(使用服务名)3.2 步骤解…...

头歌 进程管理之二(wait、exec、system的使用)
第1关:进程等待 任务描述 通过上一个实训的学习,我们学会了使用fork创建子进程,在使用fork创建子进程的时候,子进程和父进程的执行顺序是无法预知的。本关我们将介绍如何使得fork创建出来的子进程先执行,随后父进程再…...

详解日志格式配置:XML 与 Spring Boot 配置文件格式
详解日志格式配置:XML 与 Spring Boot 配置文件格式 日志是现代应用程序中不可或缺的一部分,通过定制化日志格式和颜色,开发人员可以更方便地调试和监控应用。本文将深入讲解如何在 XML 配置文件 和 Spring Boot 配置文件 中设置日志格式&am…...

JDK21新特性
目录 虚拟线程(JEP 444): 顺序集合(JEP 431): 字符串模板(JEP 430): 模式匹配的增强(JEP 440、441以及443): 结构化并发和作用域值…...

SqlDataAdapter
SqlDataAdapter 是 .NET Framework 和 .NET Core 中提供的一个数据适配器类,属于 System.Data.SqlClient 命名空间(或在 .NET 6 中属于 Microsoft.Data.SqlClient 命名空间)。它的作用是充当数据源(如 SQL Server 数据库ÿ…...

AI赋能:构建安全可信的智能电子档案库
在档案的政策与法规上,《中华人民共和国档案法》2020年修订新增,对电子档案的合法要件、地位和作用、安全管理要求和信息化系统建设等方面作出了明确规定,保障数字资源的安全保存和有效利用。 日前,国家档案局令第22号公布《电子…...

分类预测 | PSO-PNN粒子群优化概率神经网络多特征分类预测
分类预测 | PSO-PNN粒子群优化概率神经网络多特征分类预测 目录 分类预测 | PSO-PNN粒子群优化概率神经网络多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现PSO-PNN粒子群优化概率神经网络多特征分类预测,运行环境Matlab2018b及以…...

AcWing 3416. 时间显示
文章目录 前言代码思路 前言 这种我最担心的就是一些语法格式忘掉了。还有 int ,long long 的数据范围我记得不是很清楚,印象中 int 是 20 亿左右,long long 不行就得用数组来存这个数字了。int,long long数据类型及数值范围。好像没记错,记…...

【软考速通笔记】系统架构设计师⑲——专业英语
文章目录 一、前言二、常用名词三、架构风格四、非功能需求五、应用架构六、软件架构重用 一、前言 笔记目录大纲请查阅:【软考速通笔记】系统架构设计师——导读 二、常用名词 名词翻译architecture架构system系统design设计requirements需求components组件constr…...

java注解(二):注解的解析以及应用场景、用注解和反射模拟junit框架代码演示
目录 1、什么是注解的解析? 2、解析注解的案例 1、自定义一个注解 2、在类和方法上使用自己定义的注解 3、解析注解 3、模拟Junit框架案例 1、自定义一个MyTest注解 2、定义一个测试类,使用自定义的注解 3、写一个启动类 本文章主要讲解什么是注…...

C# 命名空间(Namespace)
文章目录 前言一、命名空间的定义与使用基础(一)定义语法与规则(二)调用命名空间内元素 二、using 关键字三、嵌套命名空间 前言 命名空间(Namespace)在于提供一种清晰、高效的方式,将一组名称与…...

几个Linux系统安装体验: centos7系统服务版
本文介绍CentOS7服务版本的安装。 前言 当前国产操作系统版本众多,但根据笔者多年的实践经验得到的认知,最好能抓住底层逻辑,上下打通打透,拉齐表现和本质,就能在纷扰版本中看得清清楚楚,明明白白…...

ViT学习笔记(一) 基本的原理和框架结构
原论文地址:https://arxiv.org/pdf/2010.11929 首先大致通读一下原论文,这是很有必要的,但不必完全读懂,因为会有高手给我们解读,比如: 【Transformer系列】深入浅出理解ViT(Vision Transformer)模型-CSD…...

fedora下Jetbrains系列IDE窗口中文乱码解决方法
可以看到窗口右部分的中文内容为小方块。 进入 Settings - Appearance & Behavior - Appearance - Use custom font : Note Sans Mono CJK SC ,设置后如下图:...

nginx根据报文里字段转发至不同地址
nginx接收到post请求.请求报文里是一个json字符串,字符串里有个字段id。 根据id不同,转发到不同地址。 如果idaaa,转发到www.aaa.com.test 如果idbbb,转发到www.bbb.com.test 如何配置,请提供一个nginx.conf 要在 Nginx 中根据 POST 请求的 JSON 负载中的…...

使用 html/css 实现 educoder 顶部导航栏的步骤和方法
要使用HTML和CSS实现一个类似于Educoder网站的顶部导航栏,我们可以设计一个响应式、简洁且功能齐全的导航栏。Educoder的顶部导航栏通常包括网站的logo、主要导航项(如首页、课程、讨论等)、以及用户操作按钮(如登录、注册等&…...

EasyExcel导出列表
通过easyexcel导出列表数据 根据列表内容自适应宽高。 文件名冲突,修改文件名递增设置。 依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>${easyexcel.version}</version&…...

【unity小技巧】分享vscode如何开启unity断点调试模式,并进行unity断点调试(2024年最新的方法,实测有效)
文章目录 前言一、前置条件1、已安装Visual Studio Code,并且unity首选项>外部工具>外部脚本编辑器选择为Visual Studio Code [版本号],2、在Visual Studio Code扩展中搜索Unity,并安装3、同时注意这个插件下面的描述,需要根…...

【JavaScript】Object.keys() 和 Object.values() 的使用示例和相关的简单应用
值是数字的情况: let n 124; Object.keys(n) // [] Object.values(n) // []值是字符串的情况: let s "abc"; Object.keys(s) // [0, 1, 2] Object.values(s) // [a, b, c]值是数组的情况:(常用) let ar…...

SwiftUI 列表(或 Form)子项中的 Picker 引起导航无法跳转的原因及解决
概述 在 SwiftUI 的界面布局中,列表(List)和 Form 是我们秃头码农们司空见惯的选择。不过大家是否知道:如果将 Picker 之类的视图嵌入到列表或 Form 的子项中会导致导航操作无法被触发。 从上图可以看到:当在 List 的…...

基于ZYNQ-7000系列的FPGA学习笔记8——呼吸灯
基于ZYNQ-7000系列的FPGA学习笔记8——呼吸灯 1. 实验要求2. 功能分析3. 模块设计4. 波形图5.代码编写6. 代码仿真7. 添加约束文件并分析综合 上期内容,我们学习了按键控制蜂鸣器,这一期我们开始学习呼吸灯 1. 实验要求 控制领航者核心板上的led&#x…...

探索 Python 应用的分层依赖:解决 UOS 环境中的 libvirt-python 安装问题
探索 Python 应用的分层依赖:解决 UOS 环境中的 libvirt-python 安装问题 背景Python 版本升级 问题描述原因分析与解决方案 Python 应用的分层依赖:安装与部署的视角libvirt-python的分层依赖尝试的解决方案 使用编译好的 .whl 文件"嫁接"整个…...

OpenCV-平滑图像
二维卷积(图像滤波) 与一维信号一样,图像也可以通过各种低通滤波器(LPF)、高通滤波器(HPF)等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。 opencv 提供了函数 **cv.filter2D()**&…...

解决跨域问题方案
跨域问题在前后端分离架构下尤为常见,是每个 Web 开发者都会遇到的核心问题。本文将通过原理解析、场景剖析、解决方案详解以及最佳实践等多个维度,帮助开发者全面理解并有效应对跨域问题。 目录 **一、跨域的本质****1. 同源策略****2. 同源策略的限制范…...

云计算介绍_3(计算虚拟化——cpu虚拟化、内存虚拟化、io虚拟化、常见集群策略、华为FC)
计算虚拟化 1.计算虚拟化介绍1.1 计算虚拟化 分类(cpu虚拟化、内存虚拟化、IO虚拟化)1.2 cpu虚拟化1.3 内存虚拟化1.4 IO虚拟化1.5 常见的集群的策略1.6 华为FC 1.计算虚拟化介绍 1.1 计算虚拟化 分类(cpu虚拟化、内存虚拟化、IO虚拟化&#…...

软件工程复习记录
基本概念 软件工程三要素:方法、工具、过程 软件开发方法:软件开发所遵循的办法和步骤,以保证所得到的运行系统和支持的文档满足质量要求。 软件开发过程管理 软件生命周期:可行性研究、需求分析、概要设计、详细设计、编码、测…...