正则表达式引擎深入探讨
正则表达式引擎(Regular Expression Engine)是正则表达式得以“活起来”的核心。它是一个精密的软件组件,负责接收正则表达式和输入文本,解析模式并执行匹配或替换操作,最终输出结果——可能是简单的“是否匹配”,也可能是提取出的具体内容。从编程语言的内置模块到命令行工具的文本处理功能,正则表达式引擎无处不在。然而,尽管它们的目标一致,不同的引擎在实现方式、性能表现和功能支持上却有着天壤之别。这种多样性不仅影响了正则表达式的使用体验,也决定了它们在不同场景下的适用性。
在本文中,我们将深入探索正则表达式引擎的世界,从基本概念到核心类型,再到具体实现,逐层揭开其神秘面纱。
引言:正则表达式引擎的前世今生
正则表达式的概念最早由数学家斯蒂芬·科尔·克林(Stephen Cole Kleene)在 1950 年代提出,用于描述形式语言的数学模型。随着 UNIX 系统的兴起,正则表达式从理论走向实践,成为文本处理的利器。早期的工具如 grep 和 ed 将正则表达式引入了程序员的视野,而 Perl 语言在 1980 年代的创新则将其推向了新的高度。Perl 的正则表达式不仅功能强大,还启发了一系列现代引擎的诞生,如 PCRE。
正则表达式引擎的演进伴随着计算机科学的发展。从最初的简单状态机到如今的复杂回溯算法,每一次技术进步都为开发者提供了更强大的工具。然而,这种多样性也带来了挑战:不同的引擎遵循不同的规则,支持不同的特性,甚至在性能上表现迥异。要真正掌握正则表达式,理解引擎的运作原理是不可或缺的一步。
在深入探讨引擎类型之前,我们先来熟悉一些常见术语和背景知识,为后续内容打下基础。
常见术语:正则表达式世界的名词解释
正则表达式引擎的讨论离不开一些关键术语,它们不仅是工具的名称,也是理解引擎差异的钥匙。让我们逐一认识它们,并梳理它们的历史与作用:
-
grep
grep是 UNIX 系统中诞生的经典工具,其名称来源于“Global Regular Expression Print”(全局正则表达式打印),最早出现在 1970 年代的 UNIX V4。它由 Ken Thompson 开发,最初是为了在文件中搜索匹配正则表达式的行。如今,grep已超越工具本身,成为文本搜索的代名词。默认情况下,grep使用基础正则表达式(BRE),但通过选项(如-E或-P)可以启用更强大的功能。 -
egrep
egrep是grep的扩展版本,等价于grep -E,支持扩展正则表达式(ERE)。它由 Alfred Aho 在 1970 年代开发,旨在简化 BRE 的语法,例如去掉对*、+、|等符号的转义要求。egrep的出现标志着正则表达式向更用户友好方向的演进。 -
POSIX
POSIX(Portable Operating System Interface,可移植操作系统接口)是 1980 年代由 IEEE 制定的标准,旨在统一 UNIX 系统的接口。POSIX 规范了两种正则表达式标准:BRE(基础正则)和 ERE(扩展正则),被许多传统工具(如grep、sed)采纳。尽管 POSIX 保证了跨平台兼容性,但它的功能相对保守,难以满足现代需求。 -
Perl
Perl(Practical Extraction and Report Language,实用提取与报告语言)由 Larry Wall 于 1987 年发布,以其强大的文本处理能力闻名。Perl 的正则表达式引入了简写字符类(如\d、\w)、回溯引用和环视等特性,成为现代正则表达式的蓝图。它的影响力如此深远,以至于许多后续引擎都以“Perl 兼容”为目标。 -
PCRE
PCRE(Perl Compatible Regular Expressions,Perl 兼容正则表达式)由 Philip Hazel 于 1997 年开发,是 Perl 正则表达式的开源实现。它不仅继承了 Perl 的丰富功能,还被广泛集成到 PHP、Apache、NGINX 等工具中。PCRE 凭借其强大的表达能力和灵活性,成为现代开发中的主流引擎。
这些术语为我们理解正则表达式引擎的多样性提供了切入点。接下来,我们将深入探讨引擎的核心类型,剖析它们的技术原理和应用场景。
正则表达式引擎的主要类型
正则表达式引擎的核心任务是将模式与文本匹配,但实现这一目标的方式却千差万别。根据底层技术,引擎可以分为四大类型:NFA、DFA、回溯和正则表达式虚拟机(REVM)。每种类型都有其独特的优势和局限,适合不同的使用场景。让我们逐一剖析它们。
1. NFA(非确定性有限自动机)
NFA(Non-deterministic Finite Automaton,非确定性有限自动机) 是正则表达式引擎的经典实现之一,源于自动机理论。它的设计灵感来源于数学模型,通过状态转移图来表示正则表达式。
-
工作原理
NFA 将正则表达式转化为一个状态机,其中每个状态可能有多个后续状态(非确定性)。在匹配过程中,NFA 从左到右扫描输入文本,同时尝试所有可能的路径。例如,对于正则表达式a(b|c),NFA 会并行探索ab和ac两条路径。这种并行性通常通过递归或栈来模拟实现。
以a*为例,NFA 的状态图可能包含一个循环,允许匹配零个或多个a。当输入是“aaa”时,NFA 会尝试匹配 0 个、1 个、2 个或 3 个a,直到找到最佳结果。 -
优点
- 灵活性强:NFA 能轻松处理复杂的正则表达式,包括捕获组、管道(
|)、量词(*、+、?)等。 - 实现简单:它的逻辑直观,易于编程和调试,适合教学和小型应用。
- 功能全面:支持大多数正则特性,与现代开发需求高度兼容。
- 灵活性强:NFA 能轻松处理复杂的正则表达式,包括捕获组、管道(
-
缺点
- 性能瓶颈:当正则表达式包含大量分支或嵌套重复时,NFA 需要尝试的路径可能呈指数级增长。例如,匹配
(a+)+b对“aaaaa”时,NFA 会尝试所有可能的a+分组组合,导致计算量激增。 - 资源占用:在极端情况下,递归深度过高可能耗尽栈空间,引发溢出。
- 性能瓶颈:当正则表达式包含大量分支或嵌套重复时,NFA 需要尝试的路径可能呈指数级增长。例如,匹配
-
应用案例
假设我们用 NFA 引擎匹配电子邮件地址,表达式可能是:[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}NFA 会逐步扫描输入(如
user@example.com),尝试每部分的匹配,最终返回成功。这种灵活性使 NFA 成为grep、sed、Perl 等工具的首选。 -
适用场景
NFA 适合需要功能优先而非极致性能的场景,如脚本开发或中小型文本处理。
2. DFA(确定性有限自动机)
DFA(Deterministic Finite Automaton,确定性有限自动机) 是 NFA 的“确定性”版本,旨在提升效率。它的状态转移图中,每个状态在给定输入下只有一个确定的后续状态,避免了路径的歧义。
-
工作原理
DFA 在匹配前将正则表达式编译成一个确定的状态机,然后以线性时间扫描文本。例如,对于a(b|c),DFA 会生成一个状态表,确保每个输入字符只触发一次状态转换。匹配时间始终是 O(n)(n 为文本长度),与正则复杂性无关。 -
优点
- 高效稳定:DFA 的性能只取决于输入长度,非常适合大规模文本处理。
- 无回溯:不像 NFA 那样需要反复尝试,DFA 一次性完成匹配,计算路径明确。
- 预测性强:运行时间可提前估算,无性能陷阱。
-
缺点
- 内存开销:DFA 需要预先构建完整的状态转移表,对于复杂正则表达式,状态数可能呈指数级增长。例如,
(a|b)*的状态表可能包含数百个状态,占用大量内存。 - 功能受限:DFA 不支持捕获组、回溯引用或环视等高级特性,因为这些功能依赖于动态路径选择。
- 内存开销:DFA 需要预先构建完整的状态转移表,对于复杂正则表达式,状态数可能呈指数级增长。例如,
-
应用案例
DFA 常用于词法分析器(Lexer),如编译器的前端。例如,匹配简单的关键字(如if|else)时,DFA 可以快速扫描代码:grep -f "if|else" code.txt这里的
-f模式接近 DFA 的行为,效率极高。 -
适用场景
DFA 适用于高性能需求的场景,如搜索引擎的初步过滤或实时日志分析,但不适合需要复杂功能的现代开发。
3. 回溯(Backtracking)
回溯引擎 是现代正则表达式引擎的主流实现,尤其在 PCRE 和许多编程语言中占据主导地位。它通过递归尝试所有可能的匹配路径来解决问题,一旦当前路径失败,就“回溯”到上一个选择点,探索其他可能性。
-
工作原理
以正则表达式a(b|c)d为例,回溯引擎会先尝试abd,如果d不匹配,则回溯到a,再尝试acd。这种试错机制通过栈保存中间状态,确保所有可能性都被覆盖。
对于(a+)+b,回溯引擎会尝试各种a+的组合,直到找到匹配b的位置或确认失败。 -
优点
- 功能强大:支持捕获组、非捕获组、环视、回溯引用等高级特性,是 PCRE 等引擎的核心。
- 直观实现:其逻辑与人类思维类似,易于理解和调试。
- 广泛支持:几乎所有现代语言(如 Python、PHP、JavaScript)都采用回溯引擎。
-
缺点
- 性能隐患:在某些极端情况下,回溯可能导致“灾难性回溯”(Catastrophic Backtracking)。例如,
(a+)+b匹配“aaaaa”时,引擎会尝试所有可能的a+分组(1+4、2+3、3+2 等),计算量呈指数级增长。 - 不可预测性:性能依赖于正则表达式和输入的组合,难以提前优化。
- 性能隐患:在某些极端情况下,回溯可能导致“灾难性回溯”(Catastrophic Backtracking)。例如,
-
应用案例
在 Python 中提取 HTML 标签的属性值:import re text = '<div class="container">Hello</div>' match = re.search(r'<[^>]+class="([^"]+)"', text) print(match.group(1)) # 输出 "container"回溯引擎会逐步尝试匹配标签和引号内的内容,灵活性极高。
-
适用场景
回溯引擎适合功能优先的场景,如 Web 开发中的数据提取或复杂的文本解析。但在处理大数据时,需警惕性能问题。
4. 正则表达式虚拟机(REVM)
正则表达式虚拟机(Regular Expression Virtual Machine, REVM) 是一种较少见但颇具创新的实现方式。它将正则表达式编译成类似字节码的中间代码,然后通过虚拟机解释执行。
-
工作原理
REVM 类似于编程语言的编译器+解释器模型。例如,\d+可能被编译为一系列指令(如“匹配数字”、“重复至少一次”),然后由虚拟机逐条执行。编译过程优化了匹配逻辑,解释执行则保留了灵活性。 -
优点
- 性能优化:编译后的代码可以针对特定硬件或场景优化,匹配速度可能优于纯回溯引擎。
- 可扩展性:虚拟机模型允许动态添加新功能,如自定义字符类。
- 混合优势:结合了预编译的高效性和解释执行的适应性。
-
缺点
- 实现复杂:需要额外的编译和解释步骤,开发成本较高。
- 适用范围窄:目前仅在少数引擎(如某些学术项目或专用工具)中使用,未广泛普及。
-
应用案例
在嵌入式系统中,REVM 可以将正则表达式编译为紧凑的字节码,用于资源受限的环境。例如,匹配设备日志中的时间戳:\d{4}-\d{2}-\d{2}REVM 会生成高效的指令序列,适合低功耗设备。
-
适用场景
REVM 适用于对性能和扩展性有特殊需求的场景,如嵌入式开发或实验性项目。
常见正则表达式引擎:从 PCRE 到 RE2
不同的工具和语言采用了不同的正则表达式引擎,以下是一些典型代表及其特点:
-
PCRE(Perl Compatible Regular Expressions)
- 背景:1997 年由 Philip Hazel 开发,旨在复刻 Perl 的正则功能。
- 特点:基于回溯算法,支持
\d、环视、非捕获组等特性。 - 应用:PHP(
preg_函数)、Apache 配置、NGINX 模块。 - 案例:匹配 URL:
^https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ - 优势与局限:功能丰富,但需警惕灾难性回溯。
-
RE2
- 背景:Google 于 2010 年发布,由 Russ Cox 开发,目标是高效且无回溯。
- 特点:使用 DFA 和 NFA 的混合实现,保证线性时间复杂度。
- 应用:Google Code Search、大规模日志分析。
- 案例:快速过滤日志中的 IP 地址:
\d+\.\d+\.\d+\.\d+ - 优势与局限:性能稳定,但不支持回溯相关特性。
-
JavaScript 引擎(如 V8)
- 背景:随 ECMAScript 标准演进,V8 是 Google Chrome 的实现。
- 特点:回溯算法,支持全局匹配(如
/g)。 - 应用:Web 开发中的表单验证。
- 案例:验证邮箱:
const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; console.log(regex.test("user@example.com")); // true - 优势与局限:生态集成度高,但不支持环视。
-
Python 正则表达式(re 模块)
- 背景:Python 标准库的一部分,受 Perl 启发。
- 特点:回溯引擎,支持 Perl 风格语法。
- 应用:脚本中的文本处理。
- 案例:提取电话号码:
import re text = "Call me at 123-456-7890" match = re.search(r"\d{3}-\d{3}-\d{4}", text) print(match.group()) # 123-456-7890 - 优势与局限:易用,但复杂模式可能慢。
-
.NET 正则表达式引擎
- 背景:微软 .NET 框架的核心组件。
- 特点:回溯引擎,支持命名捕获组等高级功能。
- 应用:C# 开发中的数据解析。
- 案例:解析 CSV:
string text = "name,age\nJohn,25"; var regex = new Regex("^(?<name>[^,]+),(?<age>\d+)$", RegexOptions.Multiline); foreach (Match m in regex.Matches(text)) {Console.WriteLine($"{m.Groups["name"]}, {m.Groups["age"]}"); } - 优势与局限:性能优化好,限于 .NET 生态。
-
POSIX 正则表达式
- 背景:1980 年代的 UNIX 标准。
- 特点:BRE 和 ERE,注重兼容性。
- 应用:
grep、sed等传统工具。 - 案例:查找以“error”开头的行:
grep "^error" log.txt - 优势与局限:稳定但功能有限。
实践启示:如何选择与优化引擎
理解引擎类型后,我们可以在实际开发中做出更明智的选择:
-
明确需求
- 需要复杂功能(如环视)?选择 PCRE 或回溯引擎。
- 追求性能(如大数据处理)?考虑 RE2 或 DFA。
-
避免性能陷阱
- 回溯引擎需警惕灾难性回溯。例如,
(a+)+b可以优化为a+b,减少分支。
- 回溯引擎需警惕灾难性回溯。例如,
-
测试与验证
- 在不同引擎间移植正则表达式时,测试是关键。例如,
\d在 POSIX 中无效,需改为[0-9]。
- 在不同引擎间移植正则表达式时,测试是关键。例如,
-
工具搭配
- 小型任务用
grep或 Python,大型任务用 RE2 或专用引擎。
- 小型任务用
结语:正则引擎的无限可能
正则表达式引擎是技术与艺术的结合。从 NFA 的灵活性到 DFA 的高效,从回溯的强大到 REVM 的创新,每种引擎都在特定领域熠熠生辉。它们不仅是工具,更是计算机科学演进的缩影。无论是编写简单的搜索模式,还是优化复杂的解析逻辑,理解引擎的原理都能让我们事半功倍。
正则表达式的旅程永无止境。随着技术的进步,说不定未来的引擎会给人们带来更多惊喜。探索它们的奥秘,不仅是技术的提升,更是思维的拓展。
相关文章:
正则表达式引擎深入探讨
正则表达式引擎(Regular Expression Engine)是正则表达式得以“活起来”的核心。它是一个精密的软件组件,负责接收正则表达式和输入文本,解析模式并执行匹配或替换操作,最终输出结果——可能是简单的“是否匹配”&…...
监控视频联网平台在智慧水利中的应用
随着智慧城市建设的深入推进,智慧水利作为其中的重要组成部分,正逐步实现数字化、智能化和网络化转型。在这一过程中,监控视频联网平台凭借其高效的数据采集、传输与分析能力,成为智慧水利建设的关键技术支撑。以下是监控视频联网…...
深入解析素数筛法:从埃氏筛到欧拉筛的算法思想与实现
素数筛法是一种用于高效生成素数的算法。常见的素数筛法包括埃拉托斯特尼筛法(埃氏筛)和欧拉筛(线性筛)。下面我们将详细讲解这两种筛法的思想: 一、 埃拉托斯特尼筛法(埃氏筛) 思想࿱…...
关于前端指令
在前端开发中,指令(Directives)通常指在框架中使用的一种特殊的语法或机制,用于扩展 HTML 的功能。常见的指令主要存在于前端框架中,如 Vue.js、Angular 等。下面我们将分别介绍 Vue.js 和 Angular 中的常用指令&#…...
ubuntu20.04系统没有WiFi图标解决方案_安装Intel网卡驱动
文章目录 1. wifi网卡配置1.1 安装intel官方网卡驱动backport1.1.1 第四步可能会出现问题 1.2 ubuntu官方的驱动1.3 重启 1. wifi网卡配置 我的电脑是华硕天选4(i7,4060),网卡型号intel ax201 ax211 ax210通用。 参考文章&#…...
蓝桥杯day2:解码异或 后的数组
一、题意 未知 整数数组 arr 由 n 个非负整数组成。 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encoded[i] arr[i] XOR arr[i 1] 。例如,arr [1,0,2,1] 经编码后得到 encoded [1,2,3] 。 给你编码后的数组 encoded 和原数组 arr …...
Vite+微前端Qiankun-状态管理
一、前言 在微前端架构中,状态管理是一个重要的课题。由于子应用是独立的,它们之间可能需要共享状态或通信。以下是基于qiankun微前端架构的状态管理方案,结合Vue 3和Vite的实现。 二、状态管理方案 在微前端中,状态管理可以分为…...
【初学者】Python语言中有没有指针类型?
李升伟 整理 在Python语言中,没有像C或C那样的显式指针类型。Python的设计哲学强调简洁和易读,因此它隐藏了许多底层的细节,包括指针。 不过,Python中的变量可以被视为对对象的引用。当你创建一个对象并将其赋值给一个变量时&am…...
网络编程---多客户端服务器
写一个服务器和两个客户端 运行服务器和2个客户端,实现聊天功能 客户端1 和 客户端2 进行聊天 客户端1将聊天数据发送给服务器 服务器将聊天数据转发给客户端2 要求: 服务器使用 select 模型实现 客户端1使用 poll 模型实现 客户端2使用 多线程实现…...
SPACE_GAME
以下是一些關於星際遊戲的 GitHub 代碼範本,您可以根據需求進行修改或擴展。這裡提供一個簡單的 Python 代碼範例,展示如何創建一個簡單的星際遊戲框架。 專案結構 space_game/ ├── main.py ├── spaceship.py ├── enemy.py └── README.md1…...
Web Component 教程(五):从 Lit-html 到 LitElement,简化组件开发
前言 在现代前端开发中,Web 组件是一种非常流行的技术,它允许我们创建可重用的、自包含的 UI 元素。而 Lit-html 是一个简洁高效库,用于在 Web 组件中进行渲染。在这篇教程中,我们一步步学习如何 Lit-html 来创建 Web Component。…...
Vue3:构建高效用户界面的利器
一、Vue.js 简介 Vue.js(读音 /vjuː/, 类似于 view)是一套构建用户界面的渐进式框架。它只关注视图层,采用自底向上增量开发的设计。Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件 ,学习起来非常简单…...
LeetCode 2614.对角线上的质数:遍历(质数判断)
【LetMeFly】2614.对角线上的质数:遍历(质数判断) 力扣题目链接:https://leetcode.cn/problems/prime-in-diagonal/ 给你一个下标从 0 开始的二维整数数组 nums 。 返回位于 nums 至少一条 对角线 上的最大 质数 。如果任一对角线上均不存在质数&…...
红日靶场(二)——个人笔记
靶场搭建 新增VMnet2网卡 **web:**需要配置两张网卡,分别是外网出访NAT模式和内网域环境仅主机模式下的VMnet2网卡。 **PC:**跟web一样,也是需要配置两张网卡,分别是外网出访NAT模式和内网域环境仅主机模式下的VMn…...
实时视频分析的破局之道:蓝耘 MaaS 如何与海螺 AI 视频实现高效协同
一、蓝耘 MaaS 平台:AI 模型全生命周期管理的智能引擎 蓝耘 MaaS(Model-as-a-Service)平台是由蓝耘科技推出的 AI 模型全生命周期管理平台,专注于为企业和开发者提供从模型训练、推理到部署的一站式解决方案。依托云原生架构、高…...
清晰易懂的 Swift 安装与配置教程
初学者也能看懂的 Swift 安装与配置教程 本教程将手把手教你如何在 macOS 系统上安装 Swift,配置依赖包缓存位置,并指出新手容易踩坑的细节。即使你是零基础小白,也能快速上手! 一、安装 Swift(macOS 环境)…...
大数据 ETL 异常值缺失值处理完整方案
在大数据时代,数据已成为推动业务创新与决策优化的重要资产。然而,数据的海量、异构及实时性往往伴随着噪声、错误记录以及缺失现象,严重影响下游分析模型的准确性和可靠性。尤其在 ETL(抽取、转换、加载)环节中,如何在海量数据流中迅速甄别并处理异常数据,便成为决定整…...
macOS homebrew - 切换源
https://mirrors.tuna.tsinghua.edu.cn/help/homebrew/ 环境变量中 添加: export HOMEBREW_BREW_GIT_REMOTE"https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git" export HOMEBREW_CORE_GIT_REMOTE"https://mirrors.tuna.tsinghua.edu.cn…...
如何基于Gone编写一个Goner对接Apollo配置中心(下)—— 对组件进行单元测试
项目地址:https://github.com/gone-io/gone 原文地址:https://github.com/gone-io/goner/blob/main/docs/test_goner.md 本文介绍的例子,代码在:https://github.com/gone-io/goner/blob/main/apollo 文章目录 引言编写“可测试”的…...
走进Java:String字符串的基本使用
❀❀❀ 大佬求个关注吧~祝您开心每一天 ❀❀❀ 目录 一、什么是String 二、如何定义一个String 1. 用双引号定义 2. 通过构造函数定义 三、String中的一些常用方法 1 字符串比较 1.1 字符串使用 1.2 字符串使用equals() 1.3 使用 equalsIgnoreCase() 1.4 cpmpareTo…...
python系列之元组(Tuple)
不为失败找理由,只为成功找方法。所有的不甘,因为还心存梦想,所以在你放弃之前,好好拼一把,只怕心老,不怕路长。 python系列之元组(Turple) 一、元组是什么?——给新手的…...
破解验证码新利器:基于百度OCR与captcha-killer-modified插件的免费调用教程
破解验证码新利器:基于百度OCR与captcha-killer-modified插件的免费调用教程 引言 免责声明: 本文提供的信息仅供参考,不承担因操作产生的任何损失。读者需自行判断内容适用性,并遵守法律法规。作者不鼓励非法行为,保…...
批量删除 PPT 中的所有图片、某张指定图片或者所有二维码图片
PPT 文档中的图片如何删除呢?相信很多小伙伴或碰到类似的需求。比如我们需要删除 PPT 文档中的某一张图片或者某张二维码图片,如果每一页都有这张图片,或者有很多 ppt 都有同一张要删除的图片,我们应该怎么快速的完成删除呢&#…...
大模型开发(六):LoRA项目——新媒体评论智能分类与信息抽取系统
LoRA项目——新媒体评论智能分类与信息抽取系统 0 前言1 项目介绍1.1 项目功能1.2 技术原理1.3 软硬件环境1.4 项目结构 2 数据介绍与处理2.1 数据集介绍2.2 数据处理2.3 数据导入器 3 模型训练3.1 配置文件3.2 工具函数3.3 模型训练3.4 模型评估 4 模型推理 0 前言 微调里面&…...
mysql-innodb存储引擎主键索引叶子结点数据结构(非单纯的双向链表)
我们应该清楚行记录是放在页中的。 compact行记录格式: 主要介绍几个比较重要的参数 heap_no: 页号 record_type: 0 表示普通类型(叶子结点),1表示B树的非叶子节点 ,2 表示最小记录ÿ…...
MySQL 进阶学习文档
一、存储引擎 1.1 核心架构 四层架构:连接层 → 服务层 → 引擎层 → 存储层插件式存储引擎:不同引擎独立管理数据存储,可动态选择 1.2 主流引擎对比 特性InnoDB(默认)MyISAMMemory事务支持✅ 支持❌ 不支持❌ 不支…...
物联网为什么用MQTT不用 HTTP 或 UDP?
先来两个代码对比,上传温度数据给服务器。 MQTT代码示例 // MQTT 客户端连接到 MQTT 服务器 mqttClient.connect("mqtt://broker.server.com:8883", clientId) // 订阅特定主题 mqttClient.subscribe("sensor/data", qos1) // …...
Vmware中的centos7连接上网
有很多刚刚开始配置了centos7,然后发现不能上网现在来解决这个问题。 测试能不能上网 先还原这个设置,如果没有动过的话就不用,连接模式是NAT模式 然后进去设置网络环境,记得是用超级用户设置 vi /etc/sysconfig/network-script…...
【AI知识】常见的优化器及其原理:梯度下降、动量梯度下降、AdaGrad、RMSProp、Adam、AdamW
常见的优化器 梯度下降(Gradient Descent, GD)局部最小值、全局最小值和鞍点凸函数和非凸函数动量梯度下降(Momentum)自适应学习率优化器AdaGrad(Adaptive Gradient Algorithm)RMSProp(Root M…...
线性规划的标准形式
标准形式的定义 目标函数:最大化线性目标函数 其中,x 是决策变量向量,c 是目标系数向量。 约束条件:等式形式约束 A x b, 其中,A 是约束系数矩阵,b 是常数项向量。 变量非负约束: 。 因此…...
