当前位置: 首页 > news >正文

正则表达式引擎深入探讨

正则表达式引擎(Regular Expression Engine)是正则表达式得以“活起来”的核心。它是一个精密的软件组件,负责接收正则表达式和输入文本,解析模式并执行匹配或替换操作,最终输出结果——可能是简单的“是否匹配”,也可能是提取出的具体内容。从编程语言的内置模块到命令行工具的文本处理功能,正则表达式引擎无处不在。然而,尽管它们的目标一致,不同的引擎在实现方式、性能表现和功能支持上却有着天壤之别。这种多样性不仅影响了正则表达式的使用体验,也决定了它们在不同场景下的适用性。

在本文中,我们将深入探索正则表达式引擎的世界,从基本概念到核心类型,再到具体实现,逐层揭开其神秘面纱。


引言:正则表达式引擎的前世今生

正则表达式的概念最早由数学家斯蒂芬·科尔·克林(Stephen Cole Kleene)在 1950 年代提出,用于描述形式语言的数学模型。随着 UNIX 系统的兴起,正则表达式从理论走向实践,成为文本处理的利器。早期的工具如 greped 将正则表达式引入了程序员的视野,而 Perl 语言在 1980 年代的创新则将其推向了新的高度。Perl 的正则表达式不仅功能强大,还启发了一系列现代引擎的诞生,如 PCRE。

正则表达式引擎的演进伴随着计算机科学的发展。从最初的简单状态机到如今的复杂回溯算法,每一次技术进步都为开发者提供了更强大的工具。然而,这种多样性也带来了挑战:不同的引擎遵循不同的规则,支持不同的特性,甚至在性能上表现迥异。要真正掌握正则表达式,理解引擎的运作原理是不可或缺的一步。

在深入探讨引擎类型之前,我们先来熟悉一些常见术语和背景知识,为后续内容打下基础。


常见术语:正则表达式世界的名词解释

正则表达式引擎的讨论离不开一些关键术语,它们不仅是工具的名称,也是理解引擎差异的钥匙。让我们逐一认识它们,并梳理它们的历史与作用:

  1. grep
    grep 是 UNIX 系统中诞生的经典工具,其名称来源于“Global Regular Expression Print”(全局正则表达式打印),最早出现在 1970 年代的 UNIX V4。它由 Ken Thompson 开发,最初是为了在文件中搜索匹配正则表达式的行。如今,grep 已超越工具本身,成为文本搜索的代名词。默认情况下,grep 使用基础正则表达式(BRE),但通过选项(如 -E-P)可以启用更强大的功能。

  2. egrep
    egrepgrep 的扩展版本,等价于 grep -E,支持扩展正则表达式(ERE)。它由 Alfred Aho 在 1970 年代开发,旨在简化 BRE 的语法,例如去掉对 *+| 等符号的转义要求。egrep 的出现标志着正则表达式向更用户友好方向的演进。

  3. POSIX
    POSIX(Portable Operating System Interface,可移植操作系统接口)是 1980 年代由 IEEE 制定的标准,旨在统一 UNIX 系统的接口。POSIX 规范了两种正则表达式标准:BRE(基础正则)和 ERE(扩展正则),被许多传统工具(如 grepsed)采纳。尽管 POSIX 保证了跨平台兼容性,但它的功能相对保守,难以满足现代需求。

  4. Perl
    Perl(Practical Extraction and Report Language,实用提取与报告语言)由 Larry Wall 于 1987 年发布,以其强大的文本处理能力闻名。Perl 的正则表达式引入了简写字符类(如 \d\w)、回溯引用和环视等特性,成为现代正则表达式的蓝图。它的影响力如此深远,以至于许多后续引擎都以“Perl 兼容”为目标。

  5. 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 会并行探索 abac 两条路径。这种并行性通常通过递归或栈来模拟实现。
    a* 为例,NFA 的状态图可能包含一个循环,允许匹配零个或多个 a。当输入是“aaa”时,NFA 会尝试匹配 0 个、1 个、2 个或 3 个 a,直到找到最佳结果。

  • 优点

    • 灵活性强:NFA 能轻松处理复杂的正则表达式,包括捕获组、管道(|)、量词(*+?)等。
    • 实现简单:它的逻辑直观,易于编程和调试,适合教学和小型应用。
    • 功能全面:支持大多数正则特性,与现代开发需求高度兼容。
  • 缺点

    • 性能瓶颈:当正则表达式包含大量分支或嵌套重复时,NFA 需要尝试的路径可能呈指数级增长。例如,匹配 (a+)+b 对“aaaaa”时,NFA 会尝试所有可能的 a+ 分组组合,导致计算量激增。
    • 资源占用:在极端情况下,递归深度过高可能耗尽栈空间,引发溢出。
  • 应用案例
    假设我们用 NFA 引擎匹配电子邮件地址,表达式可能是:

    [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
    

    NFA 会逐步扫描输入(如 user@example.com),尝试每部分的匹配,最终返回成功。这种灵活性使 NFA 成为 grepsed、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 常用于词法分析器(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 等),计算量呈指数级增长。
    • 不可预测性:性能依赖于正则表达式和输入的组合,难以提前优化。
  • 应用案例
    在 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

不同的工具和语言采用了不同的正则表达式引擎,以下是一些典型代表及其特点:

  1. PCRE(Perl Compatible Regular Expressions)

    • 背景:1997 年由 Philip Hazel 开发,旨在复刻 Perl 的正则功能。
    • 特点:基于回溯算法,支持 \d、环视、非捕获组等特性。
    • 应用:PHP(preg_ 函数)、Apache 配置、NGINX 模块。
    • 案例:匹配 URL:
      ^https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
      
    • 优势与局限:功能丰富,但需警惕灾难性回溯。
  2. RE2

    • 背景:Google 于 2010 年发布,由 Russ Cox 开发,目标是高效且无回溯。
    • 特点:使用 DFA 和 NFA 的混合实现,保证线性时间复杂度。
    • 应用:Google Code Search、大规模日志分析。
    • 案例:快速过滤日志中的 IP 地址:
      \d+\.\d+\.\d+\.\d+
      
    • 优势与局限:性能稳定,但不支持回溯相关特性。
  3. 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
      
    • 优势与局限:生态集成度高,但不支持环视。
  4. 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
      
    • 优势与局限:易用,但复杂模式可能慢。
  5. .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 生态。
  6. POSIX 正则表达式

    • 背景:1980 年代的 UNIX 标准。
    • 特点:BRE 和 ERE,注重兼容性。
    • 应用grepsed 等传统工具。
    • 案例:查找以“error”开头的行:
      grep "^error" log.txt
      
    • 优势与局限:稳定但功能有限。

实践启示:如何选择与优化引擎

理解引擎类型后,我们可以在实际开发中做出更明智的选择:

  1. 明确需求

    • 需要复杂功能(如环视)?选择 PCRE 或回溯引擎。
    • 追求性能(如大数据处理)?考虑 RE2 或 DFA。
  2. 避免性能陷阱

    • 回溯引擎需警惕灾难性回溯。例如,(a+)+b 可以优化为 a+b,减少分支。
  3. 测试与验证

    • 在不同引擎间移植正则表达式时,测试是关键。例如,\d 在 POSIX 中无效,需改为 [0-9]
  4. 工具搭配

    • 小型任务用 grep 或 Python,大型任务用 RE2 或专用引擎。

结语:正则引擎的无限可能

正则表达式引擎是技术与艺术的结合。从 NFA 的灵活性到 DFA 的高效,从回溯的强大到 REVM 的创新,每种引擎都在特定领域熠熠生辉。它们不仅是工具,更是计算机科学演进的缩影。无论是编写简单的搜索模式,还是优化复杂的解析逻辑,理解引擎的原理都能让我们事半功倍。

正则表达式的旅程永无止境。随着技术的进步,说不定未来的引擎会给人们带来更多惊喜。探索它们的奥秘,不仅是技术的提升,更是思维的拓展。

相关文章:

正则表达式引擎深入探讨

正则表达式引擎&#xff08;Regular Expression Engine&#xff09;是正则表达式得以“活起来”的核心。它是一个精密的软件组件&#xff0c;负责接收正则表达式和输入文本&#xff0c;解析模式并执行匹配或替换操作&#xff0c;最终输出结果——可能是简单的“是否匹配”&…...

[蓝桥杯 2023 省 B] 飞机降落(不会dfs的看过来)

[蓝桥杯 2023 省 B] 飞机降落 题目描述 N N N 架飞机准备降落到某个只有一条跑道的机场。其中第 i i i 架飞机在 T i T_{i} Ti​ 时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 D i D_{i} Di​ 个单位时间&#xff0c;即它最早可以于 T i T_{i} Ti​ 时刻…...

DockerTLS加密/不加密传输

前言&#xff1a; 在Docker容器的网络通信中&#xff0c;安全性是至关重要的。DockerTLS作为一种加密传输协议&#xff0c;通过为Docker守护进程与客户端之间的通信提供加密层&#xff0c;有效防止数据在传输过程中被窃取或篡改。然而&#xff0c;在某些特定场景下&#xff0c;…...

基于微信小程序的充电桩管理系统

一、开发背景 在开发充电汽车管理系统之前&#xff0c;深入的需求分析至关重要。我们要充分了解不同用户群体的需求&#xff0c;比如私家车主希望充电过程便捷、高效、安全&#xff0c;能够实时查看充电状态和费用明细&#xff1b;出租车、网约车司机则更注重充电速度和充电桩…...

Excel导出工具类--复杂的excel功能导出(使用自定义注解导出)

Excel导出工具类 前言: 简单的excel导出,可以用easy-excel, fast-excel, auto-poi,在导出实体类上加上对应的注解,用封装好的工具类直接导出,但对于复杂的场景, 封装的工具类解决不了,要用原生的excel导出(easy-excel, fast-excel, auto-poi都支持原生的) 业务场景: 根据…...

创新实训项目初始化——gitee的使用

创新实训项目管理采用gitee&#xff0c;写下这篇博客熟悉gitee进行项目创建和版本同步 一、gitee概述 Gitee 是一个基于 Git 的代码托管平台&#xff0c;与 GitHub 类似&#xff0c;Gitee 提供了丰富的功能&#xff0c;比如代码仓库的创建、分支管理、代码审查等。 二、gite…...

【原创】使用ElasticSearch存储向量实现大模型RAG

一、概述 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;已成为大型语言模型&#xff08;LLM&#xff09;应用的重要架构&#xff0c;通过结合外部知识库来增强模型的回答能力&#xff0c;特别是在处理专业领域知识、最新信息或企业私有数…...

Gymnasium Cart Pole 环境与 REINFORCE 算法 —— 强化学习入门 2

Title: Gymnasium Cart Pole 环境与 REINFORCE 算法 —— 强化学习入门 2 文章目录 I. Gymnasium Cart Pole 环境II. REINFORCE 算法1. 原理说明2. REINFORCE 算法实现 I. Gymnasium Cart Pole 环境 Gymnasium Cart Pole 环境是一个倒立摆的动力学仿真环境. 状态空间: 0: Ca…...

响应式数据 和 Pinia 状态

响应式数据 和 Pinia 状态 是 Vue.js 应用中用于管理数据的两种重要机制&#xff0c;它们之间有密切的关系。以下是它们的定义、特点以及关系&#xff1a; 1. 响应式数据 定义 响应式数据 是 Vue.js 的核心特性之一&#xff0c;指的是当数据发生变化时&#xff0c;视图会自动…...

在大数据开发中hive是指什么?

hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在大数据技术的浩瀚星空中&#xff0c;Apache Hive犹如一座桥梁&#xff0c;连接着传统数据仓库理念…...

LeRobot源码剖析——对机器人各个动作策略的统一封装:包含ALOHA ACT、Diffusion Policy、VLA模型π0

前言 过去2年多的深入超过此前7年&#xff0c;全靠夜以继日的勤奋&#xff0c;一天当两天用&#xff0c;抠论文 抠代码 和大模型及具身同事讨论&#xff0c;是目前日常 而具身库里&#xff0c;idp3、π0、lerobot值得反复研究&#xff0c;故&#xff0c;近期我一直在抠π0及l…...

Python生成requirements.txt的两种方法

Python生成requirements.txt的两种方法 方法一&#xff1a;导出当前环境的依赖包 使用pipreqs --encodingutf8为使用utf8编码&#xff0c;避免编码报错 --force 强制执行覆盖生成目录下的requirements.txt # 安装 python3 -m pip install pipreqs # 在当前目录生成 pipreqs . …...

如何判断 MSF 的 Payload 是 Staged 还是 Stageless(含 Meterpreter 与普通 Shell 对比)

在渗透测试领域&#xff0c;Metasploit Framework&#xff08;MSF&#xff09;的 msfvenom 工具是生成 Payload&#xff08;载荷&#xff09;的核心利器。然而&#xff0c;当我们选择 Payload 时&#xff0c;经常会遇到一个问题&#xff1a;这个 Payload 是 Staged&#xff08;…...

HTML5与CSS3新特性详解

一、HTML5新特性 1.概述 HTML5 的新增特性主要是针对于以前的不足&#xff0c;增加了一些新的标签、新的表单和新的表单属性等。 这些新特性都有兼容性问题&#xff0c;基本是 IE9 以上版本的浏览器才支持&#xff0c;如果不考虑兼容性问题&#xff0c;可以大量使用这些新特…...

Redis常用进阶 存储原理和主从思路

Redis常用进阶 存储原理和主从思路 简介 此篇用于需要时随时查阅的知识. 由于不断的学习总是会忘记一些 所以用于记录 笔记对应视频为黑马redis https://www.bilibili.com/video/BV1Pu411Y7bq 单点redis的问题 : 数据丢失问题 持久化并发能力弱 主从集群存储能力问题 ES故…...

本地部署DeepSeek-R1(Dify升级最新版本、新增插件功能、过滤推理思考过程)

下载最新版本Dify Dify1.0版本之前不支持插件功能&#xff0c;先升级DIfy 下载最新版本&#xff0c;目前1.0.1 Git地址&#xff1a;https://github.com/langgenius/dify/releases/tag/1.0.1 我这里下载到老版本同一个目录并解压 拷贝老数据 需先停用老版本Dify PS D:\D…...

分治-快速排序系列一>快速排序

目录 题目方法&#xff1a;优化方法&#xff1a;代码&#xff1a; 题目方法&#xff1a; 忘记快速排序看这里&#xff1a;链接: link 优化方法&#xff1a; 代码&#xff1a; public int[] sortArray(int[] nums) {qsort(nums,0,nums.length-1);return nums;}private void qso…...

【spring对bean Singleton和Prototype的管理流程】

在 Spring 框架中&#xff0c;Bean 的作用域决定了 Bean 的生命周期和创建方式。Spring 支持多种作用域&#xff0c;其中最常用的是 单例&#xff08;Singleton&#xff09; 和 原型&#xff08;Prototype&#xff09;。以下是 Spring 对单例和原型 Bean 的管理流程详解&#x…...

【Java】grpc-java在IDEA中build不成功的相关问题,Android,codegen C++语言排除

一、解决Android依赖问题 在当前grpc-java项目根目录下创建gradle.properties文件,输入以下内容: skipAndroid=true或者 android.useAndroidX=true二、com.google.cloud.tools.appengine插件找不到的问题 Plugin [id: ‘com.google.cloud.tools.appengine’, version: ‘…...

十七、实战开发 uni-app x 项目(仿京东)- 后端指南

前面我们已经用uniappx进行了前端实战学习 一、实战 开发uni-app x项目(仿京东)-规划-CSDN博客 二、实战 开发uni-app x项目(仿京东)-项目搭建-CSDN博客 三、实战开发 uni-app x 项目(仿京东)- 技术选型-CSDN博客 四、实战开发 uni-app x 项目(仿京东)- 页面设计-C…...

SpringSecurity——基于角色权限控制和资源权限控制

目录 基于角色权限控制 1.1 自定义 UserDetailsService 1.2 加载用户角色 1.3. 给角色配置能访问的资源&#xff08;使用切面拦截&#xff0c;使用注解&#xff09; 总结 资源权限控制 2.2. 需要有一个用户&#xff1b;&#xff08;从数据库查询用户&#xff09; 2.2 基…...

经历过的IDEA+Maven+JDK一些困惑

注意事项&#xff1a;由于使用过程中是IDEA绑定好另外2个工具&#xff0c;所以报错统一都显示在控制台&#xff0c;但要思考和分辨到底是IDEA本身问题导致的报错&#xff0c;还是maven导致的 标准配置 maven Java Compiler Structure 编辑期 定义&#xff1a;指的是从open pr…...

基于Arduino控制的温室蔬菜园环境监控系统(论文+源码)

2.1系统总体方案设计 本课题为基于Arduino控制的温室蔬菜园环境监控系统&#xff0c;在硬件上结合Arduino 控制器&#xff0c;土壤湿度传感器&#xff0c;ESP8266模块&#xff0c;环境温湿度传感器&#xff0c;光敏电阻&#xff0c;液晶等来构成整个系统&#xff0c;其可以实现…...

关于HAL库的知识1----MSP函数

在 HAL 库中&#xff0c;大部分外设在初始化时都会调用一个对应的 MSP 初始化函数&#xff0c;这个函数的主要作用就是配置与外设相关的底层硬件资源&#xff0c;比如时钟、GPIO、中断、DMA 等。常见的外设及其对应的 MSP 函数包括&#xff1a; UART/USART&#xff1a;对应 HA…...

QT 磁盘文件 教程04-创建目录、删除目录、遍历目录

【1】新建目录 bool CreateDir(QString name){QString fileName name ;QDir dir(fileName);if (dir.isEmpty()) {dir.mkdir(fileName);return true;}else{qDebug()<<"文件夹已存在";return false;} } 【2】删除目录 bool DeleteDir(QString fileName){if (…...

高级java每日一道面试题-2025年3月06日-微服务篇[Eureka篇]-Eureka Server和Eureka Client关系?

如果有遗漏,评论区告诉我进行补充 面试官: Eureka Server和Eureka Client关系? 我回答: 在微服务架构中&#xff0c;Eureka作为Netflix开源的服务发现组件&#xff0c;由Eureka Server&#xff08;服务端&#xff09;和Eureka Client&#xff08;客户端&#xff09;两大部分…...

MAC-在使用@Async注解的方法时,分布式锁管理和释放

在使用 @Async 注解的异步方法中管理分布式锁时,需要特别注意 ​锁的获取、释放与异步执行的生命周期匹配。以下是结合 Spring Boot 和 Redis 分布式锁的实践方案: 1. 为什么需要分布式锁? 异步方法可能被多个线程/服务实例并发执行,若访问共享资源(如数据库、缓存),需…...

Kafka 八股文

一、基础概念 1. Kafka 是什么&#xff1f;它的核心组件有哪些&#xff1f; Kafka 的定义 Kafka 是一个 分布式流处理平台&#xff0c;最初由 LinkedIn 开发&#xff0c;后成为 Apache 顶级项目。它主要用于 高吞吐量的实时数据流处理&#xff0c;支持发布-订阅模式的消息传递…...

现代前端开发框架对比:React、Vue 和 Svelte 的选择指南

引言 在当今快速发展的 Web 开发领域&#xff0c;前端框架的选择往往直接影响项目的开发效率、维护成本和用户体验。React、Vue 和 Svelte 作为当前最受关注的三大框架&#xff0c;各自拥有独特的设计哲学与技术实现。本文将通过 5000 字的深度解析&#xff0c;从架构设计、开…...

ffmpeg(库编译) 01 搭建环境和安装依赖

创建目录在home目录下创建 ffmpeg_sources:用于下载源文件 ffmpeg_build: 存储编译后的库文件 bin:存储二进制文件(ffmpeg,ffplay,ffprobe,X264,X265等) mkdir ffmpeg_sources ffmpeg_build bin安装依赖 先执行sudo apt-get update进行更新,再往下走sudo apt-get -…...

Java后端开发技术详解

Java作为一门成熟的编程语言&#xff0c;已广泛应用于后端开发领域。其强大的生态系统和广泛的支持库使得Java成为许多企业和开发者的首选后端开发语言。随着云计算、微服务架构和大数据技术的兴起&#xff0c;Java后端开发的技术栈也不断演进。本文将详细介绍Java后端开发的核…...

Python高级:GIL、C扩展与分布式系统深度解析

文章目录 &#x1f4cc; **前言**&#x1f527; **第一章&#xff1a;Python语言的本质与生态**1.1 **Python的实现与版本演进**1.2 **开发环境与工具链** &#x1f527; **第二章&#xff1a;元编程与动态特性**2.1 **描述符协议&#xff08;Descriptor Protocol&#xff09;*…...

数学之握手问题

问题描述 小蓝组织了一场算法交流会议&#xff0c;总共有 50人参加了本次会议。在会议上&#xff0c;大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手 (且仅有一次)。但有 7 个人&#xff0c;这 7 人彼此之间没有进行握手 (但这 7 人与除这 …...

【Nodejs】2024 汇总现状

之前已经调研了容器、nexus-public&#xff0c;实现了本地构建应用镜像和基础设施的镜像。为实现分布式一体化协作开发的目标&#xff0c;还需要配套的线上协作开发环境。故而重回前端调研现状&#xff0c;比较 5 年前的 nodejs 快好的啊。 以下是针对 Node.js 工具链的深度解析…...

人工智能之数学基础:矩阵的降维

本文重点 在现实世界中,我们经常会遇到高维数据。例如,图像数据通常具有很高的维度,每个像素点都可以看作是一个维度。高维数据不仅会带来计算和存储上的困难,还可能会导致 “维数灾难”,即随着维度的增加,数据的稀疏性和噪声也会增加,从而影响数据分析的效果。因此,我…...

数仓开发那些事(10)

某神州优秀员工&#xff1a;&#xff08;没错&#xff0c;这个diao毛被评为了优秀员工&#xff09;一闪&#xff0c;听说你跑路了&#xff0c;不做零售行业了 一闪&#xff1a;没错&#xff0c;老东家的新it总监上任后大家都开始躺平&#xff0c;失去了当年的动力&#xff0c;所…...

【手工】早教游戏:下楼的猴子

一、效果 二、准备材料 吸管: 10.4 c m 10.4cm 10.4cm&#xff1b;棉签&#xff1a; 6 6 6 根双头棉签&#xff1b;硬币&#xff1a;1角&#xff1b;纸皮人: 2.0 c m 4.0 c m 2.0cm4.0cm 2.0cm4.0cm&#xff1b;纸板&#xff1a; 12.0 c m 30.0 c m 12.0cm30.0cm 12.0cm30…...

力扣刷题46. 全排列

46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 使用dfs搜索&#xff0c;查找所有的情况&#xff0c;首先定义所有的链表集合list&#xff0c;在定义每一种情况的链表res&#xff0c;在主函数中遍历所有的初始元素&#xff0c;首先初始化res&#xff0c;并且添加到res中&…...

【工作记录】pytest使用总结

1、 fixture夹具 可参考&#xff1a; python3.x中 pytest之fixture - 漂泊的小虎 - 博客园 fixture是指夹具&#xff08;把用例夹在中间&#xff09;&#xff0c;它包括前置工作和后置工作&#xff0c;前置是用例代码的准备阶段&#xff0c;后置是用例执行之后的清理阶段,用…...

linux 命令 mkdir

以下是 Linux mkdir 命令的简明总结&#xff0c;适合快速查阅和实际场景应用&#xff1a; 基础语法 mkdir [选项] 目录名... 常用选项速查 选项作用-p自动创建父目录&#xff08;解决多级目录问题&#xff09; mkdir -p a/b/c-m直接设置权限&#xff08;替代chmod&#xff0…...

浏览器对一个资源设置了缓存,如何清除缓存,且后续请求不命中缓存

方式1、浏览器端强制刷新 方式2、修改资源url eg&#xff1a;如下图&#xff0c;添加了查询参数 <link rel"stylesheet" href"style.css?v1.2.1"> <script src"app.js?t20231010"></script> 原理&#xff1a;1、在资源的…...

k8s的存储

一 configmap 1.1 configmap的功能 configMap用于保存配置数据&#xff0c;以键值对形式存储。 configMap 资源提供了向 Pod 注入配置数据的方法。 镜像和配置文件解耦&#xff0c;以便实现镜像的可移植性和可复用性。 etcd限制了文件大小不能超过1M 1.2 configmap的使用…...

[JavaScript]如何利用作用域块避免闭包内存泄漏?

出自《你不知道的JavaScript》上卷 以下是本书给出的反例: function process (data) {...} var bigdata{...} process(bigdata); var btn document.getElementById(x); btn.addEventListener(click, function click{...});click会被回调在其他位置, 在addEventListener函数内…...

Pytorch使用手册—扩展 TorchScript 使用自定义 C++ 操作符(专题五十三)

提示 本教程自 PyTorch 2.4 起已弃用。有关 PyTorch 自定义操作符的最新指南,请参阅 PyTorch 自定义操作符。 PyTorch 1.0 版本引入了一种名为 TorchScript 的新编程模型。TorchScript 是 Python 编程语言的一个子集,可以被 TorchScript 编译器解析、编译和优化。此外,编译后…...

CellOracle|基因扰动研究基因功能|基因调控网络+虚拟干预

在gzh“生信小鹏”同步文章 论文来源: 发表期刊:Nature发表时间:2023年2月23日论文题目:Dissecting cell identity via network inference and in silico gene perturbation研究团队:Kenji Kamimoto 等,华盛顿大学医学院1. 研究背景与问题提出 细胞身份(Cell Identit…...

深入探索JVM字节码增强技术与调优实践

引言 Java虚拟机(JVM)是Java程序运行的基石,而字节码增强技术则是JVM生态中一项强大的工具。通过字节码增强,开发者可以在不修改源代码的情况下,动态地修改或增强类的行为。本文将深入探讨字节码增强技术的原理、常用工具,并结合JVM调优和排错实践,帮助开发者更好地理解…...

vue 中常用操作数组的方法

操作数组方法 记录一下自己常用到的操作数组的方法 1.forEach() 遍历数组 在回调函数中对原数组的每个成员进行修改&#xff08;不用 return&#xff09; 方法接收一个回调函数 回调函数接收两个参数 第一个是遍历的当前元素 第二个是元素的索引 const arr [{name: 张三},…...

envoy 源码分析

整体架构 Envoy 的架构如图所示: Envoy 中也可能有多个 Listener&#xff0c;每个 Listener 中可能会有多个 filter 组成了 chain。 Envoy 接收到请求后&#xff0c;会先走 FilterChain&#xff0c;通过各种 L3/L4/L7 Filter 对请求进行微处理&#xff0c;然后再路由到指定的集…...

c++基础知识--返回值优化

在 C 中&#xff0c;Named Return Value Optimization&#xff08;NRVO&#xff0c;具名返回值优化&#xff09; 是一种编译器优化技术&#xff0c;用于消除函数返回一个局部对象时的拷贝或移动操作。它是 返回值优化&#xff08;RVO&#xff09; 的一种更复杂的变体&#xff0…...

【第14节】windows sdk编程:进程与线程介绍

目录 一、进程与线程概述 1.1 进程查看 1.2 何为进程 1.3 进程的创建 1.4 进程创建实例 1.5 线程查看 1.6 何为线程 1.7 线程的创建 1.8 线程函数 1.9 线程实例 二、内核对象 2.1 何为内核对象 2.2 内核对象的公共特点 2.3 内核对象句柄 2.4 内核对象的跨进程访…...