Vue3核心源码解析
/packages/complier-core
- 定位:编译时核心,处理 Vue 模板的编译逻辑。
- 核心功能:
- 模板解析:将
.vue
文件的模板语法(HTML-like)解析为 抽象语法树 (AST)。 - 转换优化:静态节点提升(Hoist Static)、Patch Flags 标记(动态节点标记)。
- 代码生成:将 AST 转换为可执行的 渲染函数(
render
函数)。
- 模板解析:将
- 特点:
- 与平台无关,不直接处理浏览器或 DOM,只负责语法层面的转换。
- 支持自定义编译器指令(如
v-xxx
的自定义扩展)。
vue3模板编译原理
模板编译分为三个阶段:
1.解析阶段
该阶段的核心任务是将原始的 HTML 模板字符串转换为初始的抽象语法树(AST)。解析器通过状态机(State Machine)逐字符扫描模板,识别出标签、属性、事件、插值表达式(如 {{ }}
)和组件标签等语法单元。例如,对于 <div :class="cls">{{ text }}</div>
,解析器会拆解出标签名 div
、动态属性 :class
及其绑定表达式 cls
,以及插值内容 text
,最终构建出一棵树形结构的原始 AST。此阶段的 AST 仅保留模板的语法结构,尚未包含任何优化信息,但它为后续的转换和代码生成提供了基础数据结构。
2.转换阶段(transform)
转换阶段是 Vue3 编译流程的核心优化环节,通过对 AST 的多轮遍历,实现语义分析和结构改造。这一阶段包含多项关键技术:
1. Node Transforms 多步处理
作用:通过一系列转换函数(如 transformIf
、transformFor
)逐层处理 AST 节点,将模板声明式语法转换为可执行的 JavaScript 逻辑。
技术细节:
- 递归遍历 AST,依次应用
v-if
→ 条件表达式、v-for
→ 循环结构等转换规则 - 动态绑定分析(如识别
:class
和{{ text }}
的动态性差异) - 为后续优化阶段(如静态提升)提供结构化标记
2. 静态提升(Static Hoisting):识别纯静态内容(如无动态绑定的 <div>Static</div>
),将其提取为常量并复用,避免重复创建虚拟节点。
3. Patch Flags 标记:为动态节点添加二进制标志(如 CLASS | STYLE | PROPS
),指导运行时仅对比变化的属性,跳过全量 Diff。例如,动态绑定的 :class
和 {{ text }}
会被标记为不同的 Patch Flag。
4. 块追踪(Block Tracking):将包含动态子节点的父节点标记为“块”(Block),运行时通过 openBlock()(标记一个动态块的开始,开始收集后续动态节点)
和 closeBlock()
(通过createBlock()
自动关闭块,无需显式调用)控制更新范围,缩小虚拟 DOM 的比对粒度。
5. 缓存优化:对事件处理函数和动态属性值进行逻辑赋值缓存(如 _cache[0] || (_cache[0] = ...)
),避免重复创建函数或计算表达式。
这些优化使得 AST 从“原始语法描述”升级为“富含运行时提示的中间形态”,为生成高效代码奠定了基础。
3.生成阶段
生成阶段将优化后的 AST 转换为可执行的渲染函数代码。代码生成器遍历 AST 节点,根据节点类型和优化标记拼接字符串,最终输出类似 function render() { ... }
的 JavaScript 函数。例如,一个包含静态提升和动态绑定的模板会被编译为:
const _hoisted_1 = createVNode("div", null, "Static");
function render() { return (openBlock(), createBlock("div", null, [ _hoisted_1, createVNode("p", null, ctx.text, 1 /* TEXT */) ]));
}
此阶段还会注入运行时代码(如 createVNode
、openBlock
),并确保生成的代码符合 JavaScript 语法规范。最终输出的渲染函数与 Vue 的运行时协作,在组件渲染时高效生成和更新虚拟 DOM。
/packages/reactivity
- 定位:响应式系统的独立实现,Vue3 的「数据驱动」核心。
- 核心功能:
- 依赖追踪:通过
Proxy
+Reflect
实现数据的响应式代理。 - 核心 API:
reactive
:创建深度响应式对象。ref
:包装基本类型值为响应式引用。effect
:副作用函数(替代 Vue2 的 Watcher)。computed
:计算属性。
- 依赖收集与触发:通过
track
和trigger
管理依赖关系。
- 依赖追踪:通过
proxy通过new Proxy(target,handler) 生成,new Proxy是JS原生API,用于创建一个代理对象,这个代理对象会包装原始对象(target),并允许通过拦截器(handler)定义目标对象的操作行为
Proxy
一、new Proxy
的核心作用
1. 创建代理包装器
- 输入:一个原始对象
target
和一个拦截器对象handler
- 输出:生成一个代理对象(Proxy Instance),该代理对象会转发所有操作到原始对象,但允许通过
handler
拦截特定操作
const raw = { a: 1 };
const handler = {get(target, key) {console.log(`读取属性 ${key}`);return target[key];}
};
const proxy = new Proxy(raw, handler);console.log(proxy.a); // 输出 "读取属性 a",然后输出 1
2. 定义拦截行为
handler
对象中可定义陷阱函数(Traps),用于拦截 13 种对象操作(如get
、set
、deleteProperty
等)- 当对 Proxy 实例进行操作时,会优先触发对应的陷阱函数,未定义的陷阱会直接转发到原始对象
二、生成的 Proxy 实例特点
1. 透明访问性
- 镜像原始对象:Proxy 实例的属性访问、方法调用等行为会默认转发到
target
const raw = { x: 10 }; const proxy = new Proxy(raw, {}); console.log(proxy.x); // 10(未定义陷阱,直接访问原始对象)
2. 操作可拦截性
- 精细拦截:通过陷阱函数可拦截以下操作:
陷阱函数 拦截的操作 get
读取属性(如 obj.prop
)set
设置属性(如 obj.prop = 1
)has
in
操作符(如'prop' in obj
)deleteProperty
delete
操作符(如delete obj.prop
)apply
函数调用(如 fn()
)construct
new
操作符(如new Fn()
)ownKeys
Object.keys()
、for-in
循环等
3. 引用独立性
- 独立对象:Proxy 实例是一个独立的对象,与
target
是不同引用const raw = {}; const proxy = new Proxy(raw, {}); console.log(proxy === raw); // false
4. 动态关联性
- 实时关联:Proxy 实例的操作会实时影响原始对象
const raw = { a: 1 }; const proxy = new Proxy(raw, {}); proxy.a = 2; console.log(raw.a); // 2(修改代理实例会影响原始对象)
5. 不可变性
- 代理不可逆:无法通过 Proxy 实例直接获取原始的
handler
或target
(需通过特殊属性或方法)const proxy = new Proxy({}, {}); console.log(proxy); // 控制台输出 Proxy 对象,但无法直接看到 handler 和 target
三、在 Vue 3 中的特殊设计
在 packages/reactivity
模块中,Vue 3 的 reactive()
函数生成的 Proxy 实例有以下特点:
1. 响应式触发器
get
陷阱:触发依赖收集(track
)set
陷阱:触发更新通知(trigger
)
2. 嵌套对象懒代理
- 仅在访问嵌套属性时,才递归生成子 Proxy 对象
const obj = reactive({ nested: { a: 1 } // 此时 nested 未被代理 }); console.log(obj.nested); // 访问时生成嵌套 Proxy
3. 原始对象标记
- 通过
ReactiveFlags.RAW
标记可获取原始对象
四、与普通对象的对比
特性 | 普通对象 | Proxy 实例 |
---|---|---|
动态属性拦截 | 不支持 | 支持(如新增属性、删除属性) |
引用关系 | 独立对象 | 独立对象,但操作关联原始对象 |
操作拦截能力 | 无 | 可拦截 13 种操作 |
性能开销 | 无 | 微小(但频繁操作可能累积开销) |
五、示例:实现一个简易响应式
const handler = {get(target, key) {console.log(`读取 ${key}`);return target[key];},set(target, key, value) {console.log(`设置 ${key} 为 ${value}`);target[key] = value;return true;}
};const raw = { count: 0 };
const proxy = new Proxy(raw, handler);proxy.count++; // 输出 "读取 count",然后 "设置 count 为 1"
Reflect
一、Reflect
的本质
Reflect
是 ES6 引入的全局对象,提供了一套与对象操作方法一一对应的函数式 API。例如:
Reflect.get(target, key)
↔ 对应target[key]
Reflect.set(target, key, value)
↔ 对应target[key] = value
Reflect.has(target, key)
↔ 对应key in target
其核心设计目标是规范化对象操作,使得原本隐式的操作(如属性读写、in
操作符)可以通过函数显式调用。
二、在 Proxy 陷阱中的必要性
当使用 Proxy
时,必须通过 Reflect
方法转发默认操作,否则会导致原始对象行为的丢失。以下是关键原因:
1. 保持 receiver
上下文正确性
在访问器属性(getter/setter)中,this
的指向需要正确绑定到代理对象(而非原始对象)。
通过 Reflect.get(target, key, receiver)
的第三个参数 receiver
,可以确保 this
指向代理对象。
示例:
const raw = {_value: 0,get value() {return this._value; // this 必须指向代理对象}
};const proxy = new Proxy(raw, {get(target, key, receiver) {// 使用 Reflect 传递 receiverreturn Reflect.get(target, key, receiver);}
});console.log(proxy.value); // 正确触发代理的 get 陷阱
2. 返回值标准化
Reflect
方法返回布尔值或操作结果,与 Proxy 陷阱的返回值要求一致。例如:
Reflect.set
返回boolean
表示是否设置成功Reflect.deleteProperty
返回boolean
表示是否删除成功
示例:
const proxy = new Proxy({}, {set(target, key, value, receiver) {// 必须返回布尔值return Reflect.set(target, key, value, receiver);}
});
3. 避免破坏对象内部方法
直接操作 target[key]
可能绕过对象内部的 [[Get]]
、[[Set]]
等内部方法,而 Reflect
确保操作符合规范。
在 JavaScript 中,直接通过
target[key]
操作对象属性可能会绕过对象内部的[[Get]]
和[[Set]]
等内部方法,原因如下:
一、
[[Get]]
和[[Set]]
的本质对象的属性访问(如
obj.prop
)和赋值(如obj.prop = value
)本质上会触发对象内部的[[Get]]
和[[Set]]
方法。这些内部方法负责:
- 访问器属性(getter/setter)的执行
- 原型链的查找
- 属性描述符(如
writable
、configurable
)的校验
二、直接操作
target[key]
的问题当在 Proxy 的陷阱函数中直接操作
target[key]
时,可能绕过以下关键逻辑:1. 绕过访问器属性(getter/setter)
如果目标对象(
target
)的属性是访问器属性(定义了get
或set
),直接通过target[key]
访问或赋值会跳过访问器逻辑,直接操作底层值。示例:
const obj = {get value() {console.log("getter 被调用");return this._value;},set value(v) {console.log("setter 被调用");this._value = v;} };const proxy = new Proxy(obj, {get(target, key) {// 直接返回 target[key],绕过 getterreturn target[key]; // ❌ 错误方式},set(target, key, value) {// 直接赋值 target[key],绕过 settertarget[key] = value; // ❌ 错误方式return true;} });proxy.value = 1; // 不会触发 setter 的 console.log console.log(proxy.value); // 不会触发 getter 的 console.log
- 结果:直接操作
target[key]
会导致访问器逻辑被绕过,_value
被直接读写。2. 破坏
this
绑定访问器属性中的
this
默认指向原始对象(target
),而非代理对象(proxy
)。这会导致依赖代理对象的逻辑(如嵌套响应式)失效。示例:
const raw = {get value() {return this._value; // this 指向 raw,而非 proxy} };const proxy = new Proxy(raw, {get(target, key) {return target[key]; // ❌ this 错误绑定到 raw} });proxy._value = 42; console.log(proxy.value); // 42,但若 proxy 有拦截逻辑,this 指向错误会导致问题
3. 绕过嵌套 Proxy
如果目标对象本身是另一个 Proxy,直接操作
target[key]
会绕过其陷阱函数,直接访问原始值。示例:
const inner = new Proxy({ a: 1 }, {get(target, key) {console.log("inner 的 get 陷阱");return Reflect.get(target, key);} });const outer = new Proxy(inner, {get(target, key) {// 直接访问 target[key],绕过 inner 的 Proxy 陷阱return target[key]; // ❌ 不会触发 inner 的 get 陷阱} });console.log(outer.a); // 直接输出 1,无日志
4. 忽略原型链和属性描述符
直接操作
target[key]
可能绕过原型链查找和属性描述符(如writable
)的校验。示例:
const parent = { a: 1 }; const child = Object.create(parent); const proxy = new Proxy(child, {get(target, key) {return target[key]; // ❌ 直接返回 undefined(不会查找原型链)} });console.log(proxy.a); // undefined(正确应为 1)
三、为什么
Reflect
能避免这些问题?
Reflect
方法(如Reflect.get
)会严格遵循对象的[[Get]]
和[[Set]]
内部方法,确保以下行为:1. 触发访问器属性
const proxy = new Proxy(obj, {get(target, key, receiver) {return Reflect.get(target, key, receiver); // ✅ 触发 getter},set(target, key, value, receiver) {return Reflect.set(target, key, value, receiver); // ✅ 触发 setter} });
2. 绑定正确的
this
(通过receiver
参数)Reflect.get(target, key, receiver);
receiver
参数确保访问器属性中的this
指向代理对象(而非原始对象)。3. 处理原型链和属性描述符
Reflect.get(target, key, receiver); // ✅ 沿原型链查找属性 Reflect.set(target, key, value, receiver); // ✅ 校验 `writable` 等属性
4. 支持嵌套 Proxy
// 通过 Reflect 触发内层 Proxy 的陷阱 Reflect.get(innerProxy, key, receiver); // ✅ 触发 innerProxy 的 get 陷阱
四、关键对比
操作方式 直接操作 target[key]
使用 Reflect
访问器属性 绕过 getter/setter 正确触发 getter/setter this
绑定指向原始对象( target
)指向代理对象(通过 receiver
)原型链 可能中断查找 完整执行原型链查找 嵌套 Proxy 绕过内层 Proxy 的陷阱 触发内层 Proxy 的陷阱 属性描述符校验 忽略 writable
、configurable
等严格校验
三、在 Vue 响应式系统中的具体应用
Vue 3 的 reactive()
函数通过 Proxy
+ Reflect
实现响应式代理。以下是核心场景:
1. 依赖收集(Track)
在 get
陷阱中,通过 Reflect.get
获取值,并收集依赖:
function createGetter() {return function get(target: object, key: string | symbol, receiver: object) {// 使用 Reflect.get 获取原始值const res = Reflect.get(target, key, receiver);// 依赖追踪track(target, TrackOpTypes.GET, key);// 递归代理嵌套对象if (isObject(res)) {return reactive(res);}return res;};
}
2. 触发更新(Trigger)
在 set
陷阱中,通过 Reflect.set
设置值,并触发更新:
function createSetter() {return function set(target: object,key: string | symbol,value: unknown,receiver: object): boolean {// 获取旧值const oldValue = (target as any)[key];// 使用 Reflect.set 设置值const result = Reflect.set(target, key, value, receiver);// 触发更新(仅当值变化时)if (hasChanged(value, oldValue)) {trigger(target, TriggerOpTypes.SET, key);}return result;};
}
3. 处理 has
和 ownKeys
陷阱
拦截 in
操作符和 Object.keys()
:
四、Reflect
与直接操作对象的区别
操作方式 | 直接操作对象(如 target[key] ) | 使用 Reflect |
---|---|---|
this 绑定 | this 指向原始对象 | 通过 receiver 参数控制 this 指向 |
返回值 | 无标准返回值(可能抛出错误) | 标准化布尔值或操作结果 |
原型链处理 | 可能无法正确处理继承属性 | 严格遵循对象原型链规则 |
函数式调用 | 无法以函数形式调用 | 函数式 API,便于组合和抽象 |
五、关键设计思想总结
-
行为一致性
Reflect
方法严格遵循 ECMAScript 规范,确保代理对象的行为与原对象一致。 -
代理链完整性
在多层代理(如 Vue 的readonly(reactive(obj))
)中,Reflect
能正确传递receiver
,维护代理链的上下文。 -
错误处理简化
通过Reflect
的布尔返回值,避免手动处理异常(如设置不可写属性时的TypeError
)。
示例:没有 Reflect
的陷阱
若在 Proxy 陷阱中不使用 Reflect
,会导致意外行为:
const raw = { a: 1 };
const proxy = new Proxy(raw, {get(target, key) {// 错误!未使用 Reflect.get,this 指向错误return target[key];},set(target, key, value) {// 错误!未返回布尔值target[key] = value;return true;}
});const child = { __proto__: proxy };
console.log(child.a); // 期望触发 get 陷阱,但实际不会!
/packages/runtime-core
- 定位:运行时核心,实现 Vue 组件的生命周期、虚拟 DOM、渲染调度等。
- 核心功能:
- 虚拟 DOM 算法:Diff 算法(
patchKeyedChildren
)、节点 Patch 逻辑。 - 组件系统:组件实例化、Props/Emits 处理、Slots 管理。
- 生命周期钩子:
onMounted
、onUpdated
等 Composition API 的实现。 - 自定义渲染器:提供
createRenderer
API,支持跨平台渲染(如小程序、Canvas)。
- 虚拟 DOM 算法:Diff 算法(
- 特点:
- 平台无关,不直接操作 DOM,依赖外部传入的 宿主环境 API。
- 包含 Vue 的核心逻辑,但需与
runtime-dom
结合才能用于浏览器。
/packages/runtime-dom
- 定位:浏览器端运行时,提供 DOM 相关的原生操作。
- 核心功能:
- DOM 操作 API:封装
document.createElement
、parent.appendChild
等原生方法。 - 事件处理:标准化事件监听(如
onClick
的自动转换)。 - 属性处理:处理 HTML Attributes、DOM Properties、类名、样式等。
- DOM 操作 API:封装
- 特点:
- 基于
runtime-core
实现,是 Vue 在浏览器环境下的 默认渲染器。 - 导出
createApp
等浏览器端专用 API。
- 基于
/packages/runtime-test
- 定位:测试用运行时,用于单元测试场景。
- 核心功能:
- 轻量级 DOM 模拟:提供内存中的虚拟 DOM 操作,避免依赖真实浏览器环境。
- 序列化输出:将渲染结果序列化为字符串,方便断言(Assertion)。
- 生命周期追踪:记录组件生命周期钩子的调用顺序。
- 使用场景:
- 测试组件渲染逻辑,不依赖
jsdom
或浏览器。 - 验证虚拟 DOM 的 Diff 算法是否正确。
- 测试组件渲染逻辑,不依赖
相关文章:
Vue3核心源码解析
/packages/complier-core 定位:编译时核心,处理 Vue 模板的编译逻辑。核心功能: 模板解析:将 .vue 文件的模板语法(HTML-like)解析为 抽象语法树 (AST)。转换优化…...
JavaScript解密实战指南:从基础到进阶技巧
JavaScript加密技术广泛应用于数据保护、反爬虫和代码混淆,但掌握解密方法能帮助开发者突破技术壁垒。本文结合爬虫实战与安全分析场景,系统梳理JS解密的核心方法与工具。 一、基础解密方法 1. Base64解码 适用于简单编码场景,如Cookie加密…...
指针(2)
1.数组名的理解 使用指针访问数组的内容时,有这样的代码: int arr[10]{1,2,3,4,5,6,7,8,9,10}int * p&arr[0]; &arr[0] 的方式拿到了数组的第一个元素的地址,但是其实数组名本来就是地址,而且还是首元素的地址…...
Android开发中广播(Broadcast)技术详解
在 Android 开发中,广播(Broadcast) 是一种广泛使用的组件通信机制,它允许应用程序在不直接交互的情况下传递消息。本文将详细讲解 Android 广播的基本概念、类型、发送与接收流程、使用场景及注意事项,并结合具体的代…...
Python网络爬虫设计(三)
目录 一、需要登录的爬虫 二、pyppeteer与requests库结合 1、cookie和session 三、其他 1、绝对网址和相对网址 2、sleep函数 一、需要登录的爬虫 在众多种类的页面中,不同的页面有不同的功能,有的是进行展示的,而有的则是登录类的。在…...
【深度学习—李宏毅教程笔记】各式各样的 Attention
目录 一、普通 Self-Attention 的痛点 二、对 Self-Attention 的优化方式 1、Local Attention / Truncated Attention 2、Stride Attention 3、Global Attention 4、知名的 Self-Attention 的变形的应用 (1)Longformer (2)…...
leetcode 1143. Longest Common Subsequence
目录 题目描述 第一步,明确并理解dp数组及下标的含义 第二步,分析明确并理解递推公式 第三步,理解dp数组如何初始化 第四步,理解遍历顺序 代码 题目描述 这道题和第718题的区别就是,本题求的是最长公共子序列的长…...
Unity C\# 实战:从零开始为游戏添加背景音乐与音效 (AudioSource/AudioClip/AudioMixer 详解)
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...
【代码解读】开源模型 minimind之pretrain
minimind原模型地址: https://github.com/jingyaogong/minimind 本文解读下开源模型minimind的预训练代码 train_pretrain.py,解释以代码注释的形式添加 1. 参数配置代码 parser argparse.ArgumentParser(description"MiniMind Pretraining") parser.ad…...
wordpress独立站的产品详情页添加WhatsApp链接按钮
在WordPress外贸独立站的产品展示页添加WhatsApp链接按钮,可以帮助客户更方便地与你联系。以下是实现这一功能的步骤: 方法一:使用HTML代码添加按钮 编辑产品展示页 进入WordPress后台,找到需要添加WhatsApp按钮的产品展示页。…...
从入门到精通汇编语言 第五章(流程转移与子程序)
参考教程:通俗易懂的汇编语言(王爽老师的书)_哔哩哔哩_bilibili 一、“转移”概述 1、转移的概念 (1)般情况下指令是顺序地逐条执行的,而在实际中,常需要改变程序的执行流程,这就…...
Redis下载
目录 安装包 1、使用.msi方式安装 2.使用zip方式安装【推荐方式】 添加环境变量 配置后台运行 启动: 1.startup.cmd的文件 2.cmd窗口运行 3.linux源码安装 (1)准备安装环境 (2)上传安装文件 (3&…...
硬件工程师笔记——电子器件汇总大全
目录 1、电阻 工作原理 欧姆定律 电阻的物理本质 一、限制电流 二、分压作用 三、消耗电能(将电能转化为热能) 2、压敏电阻 伏安特性 1. 过压保护 2. 电压调节 3. 浪涌吸收 4. 消噪与消火花 5. 高频应用 3、电容 工作原理 (…...
第一章,HCIA复习
抽象语言---->电信号抽象语言---编码 编码------二进制 二进制----电信号 OSI参考模型 TCP/IP模型(4参考5对等) 应用层:程序的编译过程;人机交互的接口。 表示层:数据格式化--->二进制 会话层:维护网…...
在 Debian 12 中恢复被删除的 smb.conf 配置文件
https://forum.ubuntu.com.cn/viewtopic.php?t494763 本文结合ai输出,内容中可能有些错误,但确实解决了我的问题,我采取保留完整输出的方式摘录。 在 Debian 12 中恢复被删除的 smb.conf 配置文件,需结合 dpkg 和 ucf(…...
Java开发软件
Main.java // 主类,用于测试学生管理系统 public class Main { public static void main(String[] args) { StudentManagementSystem sms new StudentManagementSystem(); // 添加学生 sms.addStudent(new Student(1, "Alice", 20)…...
SSRF学习
靶场 fofa搜:“重庆橙子科技”,里面找SSRF。 SSRF基础知识 绕过127限制 要查看127.0.0.1/flag.php,但是127被过滤。 绕过方法:使用不同的进制表示127.0.0.1即可。 二进制:01111111.00000000.00000000.00000001 八…...
使用virtualbox的HostOnly建立共享网络-实现虚拟机上网
目录 环境描述解决方案具体步骤1.新建一个virtual host-only ethernet adapter2.设置windows的wifi信号网络共享3.确认winows宿主网络信息3.1.wifi适配器的信息3.2.虚拟网卡的信息3.3.确认virtualbox中虚拟网卡的ip地址 4.虚拟机网卡设置5.虚拟机网络设置5.1.本地连接设置5.2.u…...
RNN的理解
对于RNN的理解 import torch import torch.nn as nn import torch.nn.functional as F# 手动实现一个简单的RNN class RNN(nn.Module):def __init__(self, input_size, hidden_size, output_size):super(RNN, self).__init__()# 定义权重矩阵和偏置项self.hidden_size hidden…...
Transformers是一种基于自注意力机制的神经网络模型
概述与发展历程 背景介绍 Transformers是一种基于自注意力机制的神经网络模型,最早由Google团队在2017年的论文《Attention Is All You Need》中提出。该模型旨在解决传统循环神经网络(RNNs)在处理长距离依赖关系时的低效性问题,…...
leetcode0078. 子集-medium
1 题目:子集 官方标定难度:中 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入࿱…...
C++编程 希尔排序
步骤: 1.先选定一个小于N的整数gap作为第一增量,然后将所有距离为gap的元素分在同一组,并对每一组的元素进行直接插入排序。然后再取一个比第一增量小的整数作为第二增量,重复上述操作… 2.当增量的大小减到1时,就相当…...
网络操作系统与应用服务器
1.通过PTR实现IP地址到主机域名的映射 2.在windows中,可以使用事件查看器来游览日志文件 3.IMAP即交互式邮件存取协议,邮件客户端可以使用其同步服务器和客户端之间的邮件列表 4.DHCP Discover ->DHCP Offer->DHCP Request->DHCP Ack 5.在DNS的资源记录中,类型A表…...
不确定与非单调推理的模糊推理
模糊推理是利用模糊性知识进行的一种不确定性推理。 模糊推理与前面讨论的不确定性推理的概率方法、可信度方法、D-S理论有着实质性的区别。前面那几种不确定性推理的理论基础是概率论,它所研究的事件本身有明确而确定的含义,只是由于发生的条件不充分,使得在条件与事件之间…...
Vite打包原理: Tree-shaking在Vue3项目中的实际效果
Vite打包原理: Tree-shaking在Vue3项目中的实际效果 随着前端开发技术的不断进步,Vue框架在国内外都备受青睐。而在Vue3项目中,Vite作为一款新型的构建工具,其支持的Tree-shaking技术成为了开发者关注的焦点之一。那么,Vite中Tree…...
LangChain4j语言模型选型指南:主流模型能力全景对比
LangChain4j语言模型选型指南:主流模型能力全景对比 前言 在大语言模型应用开发中,选择合适的底层模型提供商是架构设计的关键决策。LangChain4j作为Java生态的重要AI框架,其支持的20模型提供商各有独特的优势场景。本文通过功能矩阵深度解…...
聚宽策略----国九条后中小板微盘小改,年化135.40%
最近在研究的聚宽策略,一般技术分析的我直接转qmt了,财务因子有一点麻烦,我直接利用我开发强大的服务器系统,直接读取信号,最近在优化一下系统,最近在开发对接bigquant的交易系统,完成了api数据…...
FreeRTOS中断管理
中断优先级 任何中断的优先级都大于任务! 在我们的操作系统,中断同样是具有优先级的,并且我们也可以设置它的优先级,但是他的优先级并不是从 0 ~ 5 ,默认情况下它是从 5 ~ 15 , 0 ~ 4 这5个中断优先级不是FreeRTOS控…...
键入网址到网页显示,期间发生了什么?
文章目录 2.键入网址到网页显示,期间发生了什么?2.1真实地址查询DNS:2.2**协议栈:**上半部分是负责收发数据的TCP和UDP协议,下面一半是用IP协议控制网络包收发操作,在互联网上传数据时,数据会倍…...
代理模式(Proxy Pattern)
文章目录 1. 概述1.1 基本概念1.2 为什么需要代理模式1.3 代理模式的四个角色2. 代理模式的类型2.1 静态代理2.2 JDK动态代理2.3 CGLIB动态代理3. 代理模式的UML类图和基本实现3.1 UML类图3.2 基本实现3.2.1 静态代理基本实现3.2.2 JDK动态代理基本实现3.2.3 CGLIB动态代理基本…...
9.QT-显示类控件|Label|显示不同格式的文本|显示图片|文本对齐|自动换行|缩进|边距|设置伙伴(C++)
Label QLabel 可以⽤来显⽰⽂本和图⽚ 属性说明textQLabel中的⽂本textFormat⽂本的格式.• Qt::PlainText 纯⽂本• Qt::RichText 富⽂本(⽀持html标签)• Qt::MarkdownText markdown格式• Qt::AutoText 根据⽂本内容⾃动决定⽂本格式pixmapQLabel 内部包含的图⽚.scaledCo…...
Python多任务编程:进程全面详解与实战指南
1. 进程基础概念 1.1 什么是进程? 进程(Process)是指正在执行的程序,是程序执行过程中的一次指令、数据集等的集合。简单来说,进程就是程序的一次执行过程,它是一个动态的概念。 想象你打开电脑上的音乐播放器听歌,…...
【英语语法】词法---副词
目录 副词1. 副词的核心功能2. 副词的分类(1) 按意义分类(2) 按形式分类 3. 副词的构成(1) 形容词变副词的规则(2) 不规则变化 4. 副词的位置(1) 修饰动词时的位置(2) 多个副词的排列顺序 5. 副词的比较级与最高级(1) 规则变化(同形容词)(2) 不规则变化(…...
51c大模型~合集119
我自己的原文哦~ https://blog.51cto.com/whaosoft/13852062 #264页智能体综述 MetaGPT等20家顶尖机构、47位学者参与 近期,大模型智能体(Agent)的相关话题爆火 —— 不论是 Anthropic 抢先 MCP 范式的快速普及,还是 OpenAI…...
Day3:个人中心页面布局前端项目uniapp壁纸实战
接下来我们来弄一下个人中心页面布局user.vue <template><view class"userLayout"><view class"userInfo"><view class"avatar"><image src"../../static/Kx.jpg" mode"aspectFill"></im…...
多元协同网络拓扑模型
一、组织逻辑架构解构 1.1 多元协同网络拓扑模型 (1)产业链价值链重构图谱 阶段核心节点技术耦合系数商业转化周期基础层云服务供应商(阿里云/ECS集群)0.8512-24个月中台层开发者生态(百炼平台/API网关)…...
基于 Elasticsearch 8.12.0 集群创建索引
索引创建 创建一个产品的索引 解释: productId: 产品的唯一标识符,使用 keyword 类型,适合精确匹配和聚合操作。name: 产品名称,使用 text 类型进行全文搜索,同时包含一个 keyword 子字段用于精确匹配。description:…...
LeetCode283.移动零
给定一个数组 arr,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 示例 2 输入: nums [0] 输出: [0…...
select、poll、epoll实现多路复用IO并对比差异
目录 一、select实现多路复用 1.select函数介绍 2.select优缺点 3.select使用示例 二、poll实现多路复用 1.poll函数介绍 2.poll优缺点 3.poll使用示例 三、epoll实现多路复用 1.epoll函数介绍 2.epoll工作原理 3.epoll工作模式 (1)水平触发LT模式 (2)边缘触发ET模…...
FastAPI-MCP
介绍 开源地址: https://github.com/tadata-org/fastapi_mcp FastAPI-MCP 是一个开源项目,旨在简化 FastAPI 应用与现代 AI 代理(如基于大语言模型的系统)之间的集成。它通过自动将 FastAPI 的所有 API 端点暴露为符合 Model Co…...
Matlab 复合模糊PID
1、内容简介 Matlab 209-复合模糊PID 可以交流、咨询、答疑 2、内容说明 略摘 要:在并联型模糊 PID 复合控制器设计中,必须根据偏差大小及时地调整模糊控制部分和 PID 控制 部分的比例,而这种较为复杂的控制策略利用普通的 Simulink 模块是很难实现的.采用S-函数来解决 这个问…...
javaSE.队列
链表:屁股入队,头部出队 链尾入队👇 是while(tail.next!null) 👇 链首出队(head.next)👇 仅获取队首👇...
c++基础·左值右值
一、左值与右值的本质特征 1. 基础定义 左值 (lvalue) ✅ 可出现在赋值运算符左侧 ✅ 可被取地址(有明确存储位置) ✅ 通常为具名变量(如int a 10;中的a) 右值 (rvalue) ❌ 不可出现在赋值左侧 ❌ 不可取地址(无持久…...
From RAG to Memory: Non-Parametric Continual Learning for Large Language Models
从RAG到记忆:大语言模型的无参数持续学习 原文链接:https://arxiv.org/pdf/2502.14802 Code: https://github.com/OSU-NLP-Group/HippoRAG 🧠 HippoRAG 2 流程概述 1. 离线索引(Offline Indexing) 在此阶段,HippoRAG 2 构建一个开放式知识图谱(Open KG)以存储知识…...
STM32配置系统时钟
1、STM32配置系统时钟的步骤 1、系统时钟配置步骤 先配置系统时钟,后面的总线才能使用时钟频率 2、外设时钟使能和失能 STM32为了低功耗,一开始是关闭了所有的外设的时钟,所以外设想要工作,首先就要打开时钟,所以后面…...
Docker 安装配置教程(配置国内源)
## 一、Windows 安装 Docker Desktop 1. 系统要求: - Windows 10 64位:专业版、企业版或教育版 - 必须开启 Hyper-V 和容器功能 - 至少 4GB 内存 2. 安装步骤: - 访问 Docker 官网下载 Docker Desktop - 双击安装程序 - 按照向导完成安装 - 重启电脑 ## 二、macOS 安装 Dock…...
016-C语言内存函数
C语言内存函数 文章目录 C语言内存函数1. memcpy2. memmove3. memset4. memcmp 注意: 使用这些函数需要包含 string.h头文件。 1. memcpy void * memcpy ( void * destination, const void * source, size_t num );从source指向的位置开始,向后复制num…...
[FPGA]设计一个DDS信号发生器
一、DDS DDS(Data Distribution Service) 是一种面向实时分布式系统的通信中间件标准,专为高性能、高可靠性、低延迟的数据传输场景设计。它由对象管理组织(OMG) 制定并维护,广泛应用于物联网(…...
MySQL 线上大表 DDL 如何避免锁表(pt-online-schema-change)
文章目录 1、锁表问题2、pt-online-schema-change 原理3、pt-online-schema-change 实战3.1、准备数据3.2、安装工具3.3、模拟锁表3.4、解决锁表 1、锁表问题 在系统研发过程中,随着业务需求千变万化,避免不了调整线上MySQL DDL数据表的操作,…...
脚本中**通配符用法解析
在文件路径匹配中,** 是一种特殊的通配符(Glob Pattern),主要用于表示递归匹配任意层级的子目录。这种语法常见于以下场景: 1. 典型应用场景 .gitignore 文件: **/__pycache__ 表示匹配项目根目录下所有层…...