【设计模式】【行为型模式】解释器模式(Interpreter)
👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD
🔥 2025本人正在沉淀中… 博客更新速度++
👍 欢迎点赞、收藏、关注,跟上我的更新节奏
🎵 当你的天空突然下了大雨,那是我在为你炸乌云
文章目录
- 一、入门
- 什么是解释器模式?
- 为什么要解释器模式?
- 如何实现解释器模式?
- 二、解释器模式在框架源中的运用
- Spring 表达式语言(SpEL)
- 三、总结
- 解释器模式的优点
- 解释器模式的缺点
- 解释器模式的适用场景
一、入门
什么是解释器模式?
解释器模式(Interpreter Pattern)是一种行为设计模式,用于定义语言的语法表示,并提供一个解释器来处理该语法。它通常用于需要解释和执行特定语言或表达式的场景。
为什么要解释器模式?
假设一个电商平台需要实现动态的促销规则,例如:
- 规则1:用户是 VIP 且 订单金额 ≥ 100 元 → 享受 20 元优惠。
- 规则2:商品类别是 “电子产品” 或 库存量 > 50 → 允许参加秒杀活动。
这些规则需要灵活配置,并且随着业务发展可能会新增条件(例如添加“用户年龄 ≤ 30 岁”等)。
下面是没有用解释器模式的实现代码。
public class PromotionRuleWithoutInterpreter {public static boolean checkRule1(Map<String, Object> context) {boolean isVip = (boolean) context.get("isVip");double orderAmount = (double) context.get("orderAmount");return isVip && orderAmount >= 100;}public static boolean checkRule2(Map<String, Object> context) {String category = (String) context.get("productCategory");int stock = (int) context.get("stock");return category.equals("electronics") || stock > 50;}// 每新增一个规则,都需要添加一个新方法,且逻辑无法复用!
}
存在问题
- 重复代码:每个规则都需要手动解析字段和逻辑。
- 难以扩展:新增规则需要修改代码,违反开闭原则。
- 维护困难:如果字段名或条件逻辑变化,需要修改所有相关方法。
如何实现解释器模式?
解释器模式的构成:
- 抽象表达式(Abstract Expression):定义解释操作的接口,通常包含一个
interpret()
方法。 - 终结符表达式(Terminal Expression):实现与语法中的终结符相关的解释操作。
- 非终结符表达式(Non-terminal Expression):实现语法中的规则,通常包含对其他表达式的引用。
- 上下文(Context):包含解释器需要的全局信息。
- 客户端(Client):构建语法树并调用解释操作。主要讲需要分析的句子或表达式转换成解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环节角色间访问解释器的解释方法。
【案例】大促规则 - 改
抽象表达式(Abstract Expression):RuleExpression
接口。
interface RuleExpression {boolean interpret(Map<String, Object> context);
}
终结符表达式(Terminal Expression): IsVipExpressio
类,判断用户是否为vip;OrderAmountExpression
判断订单金额是否≥指定值;ProductCategoryExpression
类,判断商品类别是否匹配。
// 终结符表达式:用户是否是VIP
class IsVipExpression implements RuleExpression {@Overridepublic boolean interpret(Map<String, Object> context) {return (boolean) context.get("isVip");}
}// 终结符表达式:订单金额是否≥指定值
class OrderAmountExpression implements RuleExpression {private double minAmount;public OrderAmountExpression(double minAmount) {this.minAmount = minAmount;}@Overridepublic boolean interpret(Map<String, Object> context) {double amount = (double) context.get("orderAmount");return amount >= minAmount;}
}// 终结符表达式:商品类别是否匹配
class ProductCategoryExpression implements RuleExpression {private String category;public ProductCategoryExpression(String category) {this.category = category;}@Overridepublic boolean interpret(Map<String, Object> context) {String actualCategory = (String) context.get("productCategory");return actualCategory.equals(category);}
}
非终结符表达式(组合条件):AndExpression
类,逻辑"与"操作。OrExpression
类,逻辑"或"操作。
// 非终结符表达式:逻辑"与"操作
class AndExpression implements RuleExpression {private RuleExpression expr1;private RuleExpression expr2;public AndExpression(RuleExpression expr1, RuleExpression expr2) {this.expr1 = expr1;this.expr2 = expr2;}@Overridepublic boolean interpret(Map<String, Object> context) {return expr1.interpret(context) && expr2.interpret(context);}
}// 非终结符表达式:逻辑"或"操作
class OrExpression implements RuleExpression {private RuleExpression expr1;private RuleExpression expr2;public OrExpression(RuleExpression expr1, RuleExpression expr2) {this.expr1 = expr1;this.expr2 = expr2;}@Overridepublic boolean interpret(Map<String, Object> context) {return expr1.interpret(context) || expr2.interpret(context);}
}
客户端,假设需要判断用户是否满足,规则1(VIP 且订单金额≥100元),客户端是负责 构建规则表达式 并 调用解释器执行规则 的部分。
public class PromotionRuleDemo {public static void main(String[] args) {// 上下文数据(模拟用户订单信息)Map<String, Object> context = new HashMap<>();context.put("isVip", true);context.put("orderAmount", 150.0);// 构建规则表达式:isVip && orderAmount >= 100RuleExpression rule1 = new AndExpression(new IsVipExpression(),new OrderAmountExpression(100.0));// 解释并执行规则boolean canApplyDiscount = rule1.interpret(context);System.out.println("是否满足促销规则1: " + canApplyDiscount); // 输出: true}
}
改造后的好处:
- 规则可配置化:
可以将促销规则抽象为表达式对象,甚至通过配置文件或数据库动态生成规则树,无需修改代码。
例如:将规则(isVip && orderAmount >= 100) || (productCategory == "electronics")
存储为 JSON,动态解析为表达式对象。 - 灵活组合条件:
通过组合AndExpression
、OrExpression
,可以轻松实现复杂的逻辑。 - 易于扩展:
新增条件(例如“用户年龄 ≤ 30”)只需添加新的终结符表达式,无需改动现有代码。
二、解释器模式在框架源中的运用
Spring 表达式语言(SpEL)
Spring 的 SpEL(Spring Expression Language)允许在运行时解析字符串表达式(如 "user.name"
或 "price * quantity"
),并绑定到对象属性或执行逻辑。其底层实现使用了解释器模式的思想。
下面的代码时SpEL在 @Value
注解中注入动态值
@Component
public class AppConfig {// 注入配置文件中的值@Value("${app.name}")private String appName;// 使用 SpEL 计算值@Value("#{ T(java.lang.Math).random() * 100.0 }")private double randomNumber;// 引用其他 Bean 的属性@Value("#{userService.defaultUser.name}")private String defaultUserName;
}
SpEL 的核心流程分为两个阶段:
- 解析阶段:将字符串表达式(如 “2 + 3 * 4”)解析为 抽象语法树(AST),树中的每个节点对应一个表达式对象。
- 执行阶段:递归遍历 AST,解释每个节点并计算结果。这一过程完美契合解释器模式的 语法树解释执行 思想。
OpPlus/ \"2" OpMultiply/ \"3" "4"
下面是对源码的分析:
抽象表达式:Expression
接口,所有具体表达式(如字面量、运算符、方法调用)都实现此接口。
public interface Expression {// 核心方法:解释表达式并返回结果Object getValue() throws EvaluationException;// 其他重载方法(支持上下文、目标类型等)
}
终结符表达式示例:LiteralExpression
,LiteralExpression
直接解析字面量(如 “100”),无需依赖其他表达式。
public class LiteralExpression implements Expression {private final String literalValue;public LiteralExpression(String literalValue) {this.literalValue = literalValue;}@Overridepublic Object getValue() {// 直接返回字面量值(如 "42" 转换为整数)return this.literalValue;}
}
非终结符表达式示例:OpPlus
(加法操作)。OpPlus
组合了左、右两个操作数(可能是其他表达式对象),递归解释执行。
public class OpPlus extends Operator {@Overridepublic TypedValue getValueInternal(ExpressionState state) throws EvaluationException {// 递归获取左、右操作数的值Object leftOperand = getLeftOperand().getValueInternal(state).getValue();Object rightOperand = getRightOperand().getValueInternal(state).getValue();// 执行加法操作return new TypedValue(leftOperand + rightOperand);}
}
上下文:EvaluationContex
t接口,StandardEvaluationContext
是默认实现,提供变量绑定和类型支持。
public interface EvaluationContext {// 获取变量值(如 "#user")Object lookupVariable(String name);// 获取类型转换器、函数等TypeConverter getTypeConverter();
}
客户端:SpelExpressionParser:SpelExpressionParser
负责将字符串转换为 Expression
对象(语法树的根节点)。
public class SpelExpressionParser {// 解析字符串为 Expression 对象(语法树)public Expression parseExpression(String expressionString) {// 使用 Tokenizer 分词,Parser 构建 ASTreturn this.doParseExpression(expressionString);}
}
测试类
public class SpELAdditionExample {public static void main(String[] args) {// 1. 创建 SpEL 解析器ExpressionParser parser = new SpelExpressionParser();// 2. 解析加法表达式Expression expr = parser.parseExpression("2 + 3 * 4");// 3. 执行表达式并获取结果Integer result = expr.getValue(Integer.class);// 4. 输出结果System.out.println("计算结果: " + result); // 输出: 计算结果: 14}
}
三、总结
解释器模式的优点
- 易于扩展语法规则
通过添加新的表达式类,可以轻松扩展语法规则,符合 开闭原则(对扩展开放,对修改封闭)。 - 实现简单语法解析
对于简单的语法规则,解释器模式提供了一种直观的实现方式,将语法规则分解为多个表达式类。 - 解耦语法解析与执行
将语法解析逻辑封装在表达式类中,与业务逻辑解耦,使代码更清晰、更易维护。 - 适合领域特定语言(DSL)
解释器模式非常适合实现 领域特定语言(如规则引擎、查询语言等),能够将复杂的业务规则抽象为表达式树。 - 灵活性
可以通过组合不同的表达式类,动态构建复杂的语法树,支持运行时修改规则。
解释器模式的缺点
- 复杂性高
对于复杂的语法规则,解释器模式会导致类的数量急剧增加(每个规则都需要一个表达式类),增加系统复杂性。 - 性能问题
解释器模式通常采用递归解释执行,性能较低,不适合对性能要求较高的场景。 - 难以维护
随着语法规则的增加,表达式类的数量会变得庞大,导致代码难以维护。 - 不适合复杂语法
解释器模式更适合处理简单的语法规则,对于复杂的语法(如编程语言),使用解释器模式会变得非常笨拙。 - 学习成本高
需要开发者熟悉语法树的设计和递归解释执行的原理,增加了学习和实现的难度。
解释器模式的适用场景
- 领域特定语言(DSL)
当需要实现一种简单的领域特定语言时,解释器模式是一种自然的选择。例如:- 规则引擎(如促销规则、风控规则)。
- 查询语言(如 SQL 条件解析)。
- 模板引擎(如动态生成邮件内容)。
- 需要动态解析和执行规则的场景
当规则需要动态配置(如从数据库或配置文件中加载)并在运行时解析执行时,解释器模式非常适用。 - 语法规则相对固定且简单
如果语法规则不会频繁变化,且规则数量较少,解释器模式可以很好地满足需求。 - 不适合使用编译器或解析器生成工具的场景
对于简单的语法规则,使用编译器或解析器生成工具(如 ANTLR)可能过于复杂,解释器模式提供了一种轻量级的解决方案。
相关文章:
【设计模式】【行为型模式】解释器模式(Interpreter)
👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD 🔥 2025本人正在沉淀中… 博客更新速度 👍 欢迎点赞、收藏、关注,跟上我的更新节奏 🎵 当你的天空突…...
DeepSeek-R1 蒸馏 Qwen 和 Llama 架构 企业级RAG知识库
“DeepSeek-R1的输出,蒸馏了6个小模型”意思是利用DeepSeek-R1这个大模型的输出结果,通过知识蒸馏技术训练出6个参数规模较小的模型,以下是具体解释: - **知识蒸馏技术原理**:知识蒸馏是一种模型压缩技术,核…...
无人机航迹规划:互联银行系统优化(Connected Banking System Optimizer,CBSO)求解无人机路径规划MATLAB
一、互联银行系统优化算法 互联银行系统优化(Connected Banking System Optimizer,CBSO)算法是2024年由Mehrdad Nemati等人提出的一种智能优化算法,其灵感来源于银行系统之间的连接和交易过程。在银行系统中,核心银行…...
学习web数据埋点
什么是埋点,以及为什么需要埋点 通过代码主动收集用户行为数据(如点击、浏览、停留时长等),用于数据分析驱动产品优化。 一、前端埋点 在客户端(浏览器、移动端应用)直接采集用户行为数据,通…...
Windows 11 安装 Docker
1.以管理员身份打开 Windows PowerShell 2.执行下面三行命令来启动WSL和虚拟机平台 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestartdism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norest…...
深度学习框架探秘|Keras:深度学习的魔法钥匙
一、引言:深度学习浪潮中的 Keras 前面的文章我们探秘了深度学习框架中的两大明星框架 —— TensorFlow 和 PyTorch 以及 两大框架的对比 在深度学习的众多框架中,还有一款框架备受开发者们的喜爱 —— Keras 。它就像是一位贴心的助手,为我…...
HTML【详解】input 标签
input 标签主要用于接收用户的输入,随 type 属性值的不同,变换其具体功能。 通用属性 属性属性值功能name字符串定义输入字段的名称,在表单提交时,服务器通过该名称来获取对应的值disabled布尔值禁用输入框,使其无法被…...
在vscode中拉取gitee里的项目并运行
拉取项目: 方法一:vscode点击查看--->终端(或者直接通过快捷键ctrol+ `打开) 在终端内通过cd命令定位到你想存放项目的文件夹 例如:cd h: 通过命令:git clone 地址 例如:git clone newbee-mall-vue-app: 前端代码 等待拉取完成即可在对应文件夹下看到项目啦 方…...
Spring Cloud微服务
一、定义 微服务,又叫微服务架构,也就是分布式架构,是软件架构的一种方式。它将一个大的单体架构应用拆分成一系列按业务领域划分模块的、小的自治服务。 如开发部有很多任务,如果把任务给了一个组的话,效率肯定会降低…...
打破AI黑盒,拥抱开源力量:基于openGauss+DeepSeek的本地知识库,打造你的专属AI助手!
引言:什么是RAG和LLM? LLM (Large Language Model,大语言模型): 就像 ChatGPT 这样的 AI 模型,拥有强大的语言理解和生成能力,但它们的知识局限于训练数据,且可能产生“幻觉”(即生成不准确的信…...
如何在 IntelliJ IDEA 中使用 Bito AI 插件
如何在 IntelliJ IDEA 中使用 Bito AI 插件 Bito: On-Demand AI Code Reviews Bito AI 插件是一个智能开发工具,能够帮助开发者提升编码效率,自动化生成代码、注释、单元测试等。本文将详细介绍 Bito AI 插件在 IntelliJ IDEA 中的使用方法,…...
用xml配置spring, bean标签有哪些属性?
用xml配置spring, bean标签有哪些属性? 在Spring框架中,使用XML配置文件时,<bean>标签用于定义一个Bean。以下是一些常用的<bean>标签属性: 1. class 描述:指定Bean的类名。示例:<bean id"myBe…...
微信小程序中缓存数据全方位解惑
微信小程序中缓存数据全方位解惑 微信小程序中的数据缓存是提升用户体验和优化性能的重要手段,跟电脑浏览器中的Local Storage的性质一样。以下是关于微信小程序数据缓存的相关知识点和示例的详细介绍: 1. 数据缓存的类型 微信小程序提供了两种数据缓…...
物联网平台-分布式的设备接入与管理系统
乐吾乐物联网平台是由乐吾乐自主研发的一款分布式的设备接入与管理系统,专为满足不断增长的设备接入和数据处理需求而设计。平台集数据采集、分析、监控、告警和通知等功能于一体,并融合了乐吾乐大屏可视化和乐吾乐3D数字孪生技术,帮助用户快…...
ABP - 事件总线之分布式事件总线
ABP - 事件总线之分布式事件总线 1. 分布式事件总线的集成1.2 基于 RabbitMQ 的分布式事件总线 2. 分布式事件总线的使用2.1 发布2.2 订阅2.3 事务和异常处理 3. 自己扩展的分布式事件总线实现 事件总线可以实现代码逻辑的解耦,使代码模块之间功能职责更清晰。而分布…...
ComfyUI流程图生图原理详解
一、引言 ComfyUI 是一款功能强大的工具,在图像生成等领域有着广泛应用。本文补充一点ComfyUI 的安装与配置过程遇到的问题,并深入剖析图生图过程及相关参数,帮助读者快速入门并深入理解其原理。 二、ComfyUI 的安装与配置中遇到的问题 &a…...
洛谷 P3660 USACO17FEB Why Did the Cow Cross the Road III 题解
题意 有一个圆,圆周上按顺时针方向给出 2 n 2n 2n个点。第 i i i个点的颜色是 c o l o r i color_i colori,其中数据保证 1 ≤ c o l o r i ≤ n 1\le color_i\le n 1≤colori≤n,而且每种不同的颜色有且只有两个点。不存在位置重叠的点…...
kubekey一键部署k8s高可用与kubesphere
kubekey一键安装k8s与kubesphere还是蛮方便的,kubesphere官网上面也提到了高可用安装的一些事宜,但是没有涉及到kubesphere资深的redis的系统的部署问题,本文简单给出对应配置,其实这个配置在kubephere的cluster-configuration.ya…...
SwiftUI 5.0 中宝藏视图修改器 containerRelativeFrame 趣谈(下)
概览 小伙伴们都知道,为了将 SwiftUI 中多如牛毛的视图井然有序、有条不紊的组织起来,我们必须借助容器(Container)伏虎降龙般地威力。而如何最大限度的让容器中的子视图能根据容器尺寸安排自己的空间,则需要一些技术手段来洞幽察微。 在过去,我们往往使用 GeometryRead…...
ElasticSearch基础和使用
ElasticSearch基础 1 初识ES相关组件 (1)Elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容。Elasticsearch结合kibana、Logstash、Beats组件 也就是elastic stack(ELK) 广泛应…...
我用 Cursor 开发了一款个人小记系统
https://note.iiter.cn 项目背景 在日常工作和学习中,我们经常需要快速记录一些想法、收藏一些有用的链接或者保存一些重要的文本、图片内容。虽然市面上已经有很多笔记软件,但我想要一个更轻量、更简单的工具,专注于快速记录和智能检索。于是我开发了这款个人小记系统。 系统…...
如何使用Three.js制作3D月球与星空效果
目录 1. 基本设置2. 创建星空效果3. 创建月球模型4. 添加中文3D文字5. 光照与相机配置6. 动画与控制7. 响应式布局8. 结语 在本文中,我们将一起学习如何利用Three.js实现一个3D月球与星空的效果,并添加一些有趣的元素,比如中文3D文字和互动功…...
DeepSeek接入网络安全领域,AI高效驱动,重新定义网络防御边界!
DeepSeek新一代模型的发布,标志着AI大模型的应用将逐步走向普及,并加速AI技术在各行业的赋能与全面落地。在科技日新月异的今天,AI技术凭借其强大的数据处理与分析能力,已成为推动社会进步的核心动力。 在网络安全领域࿰…...
【动态规划】斐波那契数列模型
目录 动态规划 动态规划的基本步骤 1137. 第 N 个泰波那契数 - 力扣(LeetCode) 算法分析 算法代码 算法代码 面试题 08.01. 三步问题 - 力扣(LeetCode) 算法分析 算法代码 优化 746. 使用最小花费爬楼梯 - 力扣&#x…...
Spring中的IOC详解
文章目录 IOC IOC容器的工作原理Bean的生命周期Bean的自动装配 AutowiredResourceInject 使用Spring底层组件 IOC Spring的核心之一是IOC,IOC全称为Inversion of Control,中文译为控制反转,是面向对象编程中的一种设计原则,可…...
深挖vue3基本原理之七 —— 功能模块的深度技术解析
Vue 3 四个核心功能模块的深度技术解析 一、Effect 调度系统:同步/异步任务队列 实现原理 // runtime-core/src/scheduler.ts const queue: (EffectJob | null)[] [] let isFlushing false const resolvedPromise Promise.resolve()function queueJob(job: Ef…...
数据结构 day 07
数据结构 day07 7. 树7.3. 层次遍历代码实现 8. 查询算法8.1. 顺序查找 seqSearch代码实现 8.2. 二分法查找 binarySearch代码实现 8.2. 分块查找 blockSearch代码实现 8.3. 哈希表 hash 9. 排序算法9.1. 冒泡排序 bubSort代码实现 9.2. 选择排序 selSort代码实现 9.3. 插入排序…...
《代码随想录》刷题笔记——回溯篇【java实现】
文章目录 组合组合总和 III电话号码的字母组合组合总和组合总和II思路代码实现 分割回文串※思路字符串分割回文串判断效率优化※ 复原 IP 地址优化版本 子集子集 II使用usedArr辅助去重不使用usedArr辅助去重 递增子序列※全排列全排列 II重新安排行程题意代码 N 皇后解数独直…...
React:初识React
React是什么? React是由Meta公司研发,也就是Facebook的公司(马克扎克伯格这个见人)研发的构建Web和原生交互界面的库 不仅可以写网页,还可以写苹果和安卓上面的app React的优势: React也是前端里最流行的…...
全面理解-c++中的内存布局
在 C 中,程序的内存布局指的是程序运行时,代码和数据在内存中的组织和分布方式。一般来说,C 程序的内存可以划分为以下几个主要区域: 1. 代码段(Text Segment,也称为 .text 段) 存储内容&…...
百度沈抖:传统云计算不再是主角,智能计算呼唤新一代“操作系统”
Create 2024 百度AI开发者大会 4月16日,Create 2024 百度AI开发者大会在深圳召开。期间,百度集团执行副总裁、百度智能云事业群总裁沈抖正式发布新一代智能计算操作系统——万源,通过对AI原生时代的智能计算平台进行抽象与封装设计ÿ…...
【银河麒麟高级服务器操作系统】服务器卡死后恢复系统日志丢失-分析及处理全过程
了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer.kylinos.cn 文档中心:https://document.kylinos.cn 服务器环境以及配置 【机型】 处理器ÿ…...
VSCode Error Lens插件介绍(代码静态检查与提示工具)(vscode插件)
文章目录 VSCode Error Lens 插件介绍**功能概述****开发背景****使用方法****适用场景** VSCode Error Lens 插件介绍 功能概述 Error Lens 是一款增强 VS Code 错误提示的扩展工具,通过 内联显示错误和警告信息,直接定位代码问题,提升开发…...
ffmpeg configure 研究1-命令行参数的分析
author: hjjdebug date: 2025年 02月 14日 星期五 17:16:12 CST description: ffmpeg configure 研究1 ./configure 命令行参数的分析 文章目录 1 configure 对命令行参数的分析,在4019行1.1 函数名称: is_in1.2. 函数名称: enable1.3. 函数名称: set_all 2 执行退出判断的关键…...
如何调整 Nginx工作进程数以提升性能
🏡作者主页:点击! Nginx-从零开始的服务器之旅专栏:点击! 🐧Linux高级管理防护和群集专栏:点击! ⏰️创作时间:2025年2月15日14点20分 Nginx 的工作进程数࿰…...
分布式 NewSQL 数据库(TiDB)
TiDB 是一个分布式 NewSQL 数据库。它支持水平弹性扩展、ACID 事务、标准 SQL、MySQL 语法和 MySQL 协议,具有数据强一致的高可用特性,是一个不仅适合 OLTP 场景还适合 OLAP 场景的混合数据库。 TiDB是 PingCAP公司自主设计、研发的开源分布式关系型数据…...
try learning-git-branching
文章目录 mergerebase分离 HEAD相对引用利用父节点branch -f 撤销变更cherry-pick交互式 rebase只取一个提交记录提交的技巧rebase 在上一次提交上amendcherry-pick 在上一次提交上 amend tag多分支 rebase两个parent节点纠缠不清的分支偏离的提交历史锁定的Main推送主分支合并…...
【kafka系列】Kafka事务的实现原理
目录 1. 事务核心组件 1.1 幂等性生产者(Idempotent Producer) 1.2 事务协调器(TransactionCoordinator) 1.3 事务日志(Transaction Log) 2. 事务执行流程 2.1 事务初始化 2.2 发送消息 2.3 事务提…...
数据结构6
一、哈希散列--通讯录查找 #include "hash.h" #include <stdio.h> #include <stdlib.h> #include <string.h>//int *a[10];int hash_function(char key) {if (key > a && key < z){return key - a;}else if (key > A && …...
Flutter 的 Widget Key 提议大调整?深入聊一聊 Key 的作用
Flutter 的 Widget Key 提议大调整?深入聊一聊 Key 的作用 在 Flutter 里,Key 对象存在的目的主要是区分和维持 Widget 的状态,它是控件在渲染树里的「复用」标识之一,这一点在之前的《深入 Flutter 和 Compose 在 UI 渲染刷新时…...
src和href区别
src和href区别 (1)请求资源类型不同(2)作用结果不同(3)解析方式不同 (1)请求资源类型不同 href 用来建立文档和元素之间的链接(是引用),常用的有a、linksrc 在请求src资源时候会将指向的资源下载并且应用到文档中(引入),常用的有script、iframe、image。 (2)作用结果不同 hr…...
STM32之SG90舵机控制
目录 前言: 一、硬件准备与接线 1.1 硬件清单 1.2 接线 二、 SG90舵机简介 1.1 外观 1.2 基本参数 1.3 引脚说明 1.4 控制原理 1.5 特点 1.6 常见问题 三、 单片机简介 四、 程序设计 4.1 定时器配置 4.2 角度控制函数 4.3 主函数调用 五、 总结 …...
尚硅谷课程【笔记】——大数据之Hadoop【一】
课程视频链接:尚硅谷Hadoop3.x教程 一、大数据概论 1)大数据概念 大数据(Big Data):指无法再一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发…...
QEMU 搭建 Ubuntu x86 虚拟机
1. 安装 QEMU 在 Ubuntu 系统中,可以通过以下命令安装 QEMU: sudo apt-get update sudo apt-get install qemu-system-x86_64 qemu-kvm libvirt-daemon libvirt-clients bridge-utils virt-manager2. 创建虚拟硬盘镜像 qemu-img create -f raw ubuntu…...
mac 意外退出移动硬盘后再次插入移动硬盘不显示怎么办
第一步:sudo ps aux | grep fsck 打开mac控制台输入如下指令,我们看到会出现两个进程,看进程是root的这个 sudo ps aux|grep fsck 第二步:杀死进程 在第一步基础上我们知道不显示u盘的进程是:62319,我们…...
Acwing-基础算法课笔记之基础算法(双指针)
Acwing-基础算法课笔记之基础算法(双指针) 一、双指针算法概念二、关于双指针的一个问题三、模板 一、双指针算法概念 双指针(又称尺取法)是一个常用的优化技巧,用来解决序列的区间问题。 两个指针i,j&am…...
PCIE基础学习
PCIE PIO模式: 一个CPU传输一个32bit给PCIE(IP)。CPU直接与PCIE做数据传输。 DMA模式: CPU通过PCIE bridge 与多个PCIE设备连接,CPU发送命令给桥,桥控制PCIE与memory直接数据连接。 tlp报文 读报文 …...
架构——Nginx功能、职责、原理、配置示例、应用场景
以下是关于 Nginx 的功能、职责、原理、配置示例、应用场景及其高性能原因的详细说明: 一、Nginx 的核心功能 1. 静态资源服务 功能:直接返回静态文件(如 HTML、CSS、JS、图片、视频等)。配置示例:server {listen 80…...
【教程】比亚迪车机接入AI大模型语音助手
转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 更新说明: v1.1.0.2 1、新增长按音量键触发,不再需要迪加 (需设置modelisten)。 2、新增kimi、豆包、ChatGPT等多个GPT接口。 3…...
ios中常见的设计原则和设计模式
七大设计原则 1:开闭原则 对扩展开放,对修改关闭,在设计模块的时候,使模块在不被修改的前提下可以扩展功能 2:依赖倒置原则 实现尽量依赖抽象,不依赖具体实现 (1)高层模块不应该依赖底层模…...