Symbol、Set 与 Map:新数据结构探秘
Symbol、Set 与 Map:新数据结构探秘
引言
ECMAScript 6 (ES6) 引入了三种强大的数据结构:Symbol、Set 与 Map,它们解决了 JavaScript 开发中的特定痛点,为我们提供了更多工具来处理复杂的数据操作。
Symbol:唯一标识符的实现
基本概念与特性
Symbol 是 JavaScript 的原始数据类型,表示唯一的、不可变的值。每个 Symbol 值都是唯一的,即使创建时使用了相同的描述。
const sym1 = Symbol('descriptor');
const sym2 = Symbol('descriptor');console.log(sym1 === sym2); // false
console.log(typeof sym1); // "symbol"
Symbol 不会被自动转换为字符串,这是它与其他原始类型的关键区别:
const sym = Symbol('my symbol');
console.log("The symbol is: " + sym); // TypeError: Cannot convert a Symbol value to a string
console.log(`The symbol is: ${sym}`); // TypeError: Cannot convert a Symbol value to a string// 正确的转换方法
console.log("The symbol is: " + sym.toString()); // "The symbol is: Symbol(my symbol)"
console.log(`The symbol is: ${String(sym)}`); // "The symbol is: Symbol(my symbol)"
实际应用场景
1. 对象私有属性
Symbol 最常见的用途是创建对象的"私有"属性,防止属性名冲突:
const privateField = Symbol('privateField');
class MyClass {constructor(privateValue) {this[privateField] = privateValue;}getPrivateValue() {return this[privateField];}
}const instance = new MyClass(42);
console.log(instance.getPrivateValue()); // 42
console.log(instance[privateField]); // 42(如果知道Symbol引用)
console.log(Object.keys(instance)); // [](Symbol属性不出现在这里)
2. 常量定义
使用 Symbol 定义常量可以确保值的唯一性:
const STATUS = {PENDING: Symbol('pending'),FULFILLED: Symbol('fulfilled'),REJECTED: Symbol('rejected')
};// 使用示例
let currentStatus = STATUS.PENDING;// 安全的比较
if (currentStatus === STATUS.PENDING) {// 处理待定状态
}
3. 内置 Symbol 与元编程
ES6 提供了内置 Symbol 值,如 Symbol.iterator,用于自定义对象的迭代行为:
const collection = {items: ['A', 'B', 'C'],[Symbol.iterator]: function* () {for (let item of this.items) {yield item;}}
};for (let item of collection) {console.log(item); // 'A', 'B', 'C'
}
Symbol 与全局注册
除了普通的 Symbol 创建方式,还可以使用 Symbol.for() 在全局 Symbol 注册表中创建和访问 Symbol:
const globalSym = Symbol.for('globalSymbol');
const sameGlobalSym = Symbol.for('globalSymbol');console.log(globalSym === sameGlobalSym); // true// 获取全局Symbol的键
console.log(Symbol.keyFor(globalSym)); // "globalSymbol"
console.log(Symbol.keyFor(Symbol('local'))); // undefined
Set:高效的唯一值集合
基本概念与操作
Set 是一种存储唯一值的集合,可以包含任何类型的值,包括原始值和对象引用。
const uniqueNumbers = new Set([1, 2, 3, 3, 4, 4, 5]);
console.log(uniqueNumbers.size); // 5
console.log([...uniqueNumbers]); // [1, 2, 3, 4, 5]// 添加、检查和删除元素
uniqueNumbers.add(6);
console.log(uniqueNumbers.has(3)); // true
uniqueNumbers.delete(4);
Set 的实际应用
1. 数组去重
Set 提供了数组去重的最简洁解决方案:
const array = [1, 2, 2, 3, 4, 4, 5];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // [1, 2, 3, 4, 5]
2. 实现集合操作
利用 Set 可以轻松实现数学集合操作:
const set1 = new Set([1, 2, 3, 4]);
const set2 = new Set([3, 4, 5, 6]);// 交集
const intersection = new Set([...set1].filter(x => set2.has(x))
);
console.log([...intersection]); // [3, 4]// 并集
const union = new Set([...set1, ...set2]);
console.log([...union]); // [1, 2, 3, 4, 5, 6]// 差集
const difference = new Set([...set1].filter(x => !set2.has(x))
);
console.log([...difference]); // [1, 2]
3. 跟踪唯一对象
Set 可以存储对象引用,适用于需要跟踪唯一对象实例的场景:
const objSet = new Set();const obj1 = { id: 1, name: 'Object 1' };
const obj2 = { id: 2, name: 'Object 2' };objSet.add(obj1);
objSet.add(obj2);
objSet.add(obj1); // 重复添加无效console.log(objSet.size); // 2// 检查对象是否已存在
function isObjectTracked(obj) {return objSet.has(obj);
}console.log(isObjectTracked(obj1)); // true
WeakSet:内存友好的特殊 Set
WeakSet 是 Set 的变体,具有以下特点:
- 只能存储对象引用
- 对对象的引用是弱引用,不会阻止垃圾回收
- 不可迭代且无法获取 size
const weakSet = new WeakSet();
let obj = { data: 'some data' };weakSet.add(obj);
console.log(weakSet.has(obj)); // true// 当对象没有其他引用时,会被垃圾回收
obj = null;
// weakSet 中的对象引用将在下一次垃圾回收时被移除
WeakSet 主要用于存储 DOM 元素或需要被自动垃圾回收的对象集合。
Map:增强的键值对集合
基本概念与操作
Map 是键值对的集合,与普通对象不同,Map 的键可以是任何类型的值,包括函数、对象或任何原始值。
const userMap = new Map();// 添加键值对
userMap.set('name', 'Alice');
userMap.set(42, 'Answer');
userMap.set(true, 'Boolean key');const userObject = { id: 1001 };
userMap.set(userObject, 'Object as key');// 获取值
console.log(userMap.get('name')); // "Alice"
console.log(userMap.get(userObject)); // "Object as key"// 检查和删除
console.log(userMap.has(42)); // true
userMap.delete(true);
console.log(userMap.size); // 3
Map 与普通对象的比较
Map 相比普通对象有以下优势:
- 键的类型:Map 的键可以是任何类型,对象仅限于字符串和 Symbol
- 顺序保证:Map 会保持键的插入顺序
- 性能:在频繁添加和删除键值对的场景中,Map 表现更佳
- 内置迭代:Map 是可迭代的,可直接用于循环
// 迭代 Map
const fruitInventory = new Map([['apples', 5],['bananas', 10],['oranges', 2]
]);// 遍历键值对
for (const [fruit, count] of fruitInventory) {console.log(`${fruit}: ${count}`);
}// 仅遍历键
for (const fruit of fruitInventory.keys()) {console.log(fruit);
}// 仅遍历值
for (const count of fruitInventory.values()) {console.log(count);
}
Map 的实际应用场景
1. 数据缓存系统
Map 适合实现高效的缓存:
class SimpleCache {constructor(maxSize = 100) {this.cache = new Map();this.maxSize = maxSize;}get(key) {if (!this.cache.has(key)) return undefined;// 获取值并更新位置(LRU 实现)const value = this.cache.get(key);this.cache.delete(key);this.cache.set(key, value);return value;}set(key, value) {// 如果键已存在,先删除if (this.cache.has(key)) {this.cache.delete(key);}// 如果达到最大容量,删除最旧的项else if (this.cache.size >= this.maxSize) {const oldestKey = this.cache.keys().next().value;this.cache.delete(oldestKey);}this.cache.set(key, value);return this;}
}const cache = new SimpleCache(2);
cache.set('key1', 'value1');
cache.set('key2', 'value2');
console.log(cache.get('key1')); // "value1"
cache.set('key3', 'value3'); // 会删除 'key2'
console.log(cache.get('key2')); // undefined
2. 关联数据存储
Map 非常适合存储关联数据,尤其是当需要使用对象作为键时:
const userRoles = new Map();const user1 = { id: 1, name: 'Alice' };
const user2 = { id: 2, name: 'Bob' };userRoles.set(user1, ['admin', 'editor']);
userRoles.set(user2, ['user']);function getUserRoles(user) {return userRoles.get(user) || [];
}console.log(getUserRoles(user1)); // ["admin", "editor"]
3. 状态管理与有限状态机
Map 可用于实现状态管理逻辑:
const taskStateMachine = new Map([['idle', { next: ['running'], handler: () => console.log('Task is idle') }],['running', { next: ['paused', 'completed', 'failed'], handler: () => console.log('Task is running') }],['paused', { next: ['running', 'canceled'], handler: () => console.log('Task is paused') }],['completed', { next: [], handler: () => console.log('Task completed') }],['failed', { next: ['idle'], handler: () => console.log('Task failed') }],['canceled', { next: ['idle'], handler: () => console.log('Task canceled') }]
]);class Task {constructor() {this.currentState = 'idle';}transition(newState) {const currentStateData = taskStateMachine.get(this.currentState);if (!currentStateData.next.includes(newState)) {throw new Error(`Invalid state transition from ${this.currentState} to ${newState}`);}this.currentState = newState;const stateData = taskStateMachine.get(newState);stateData.handler();return this;}
}const task = new Task();
task.transition('running').transition('paused').transition('running').transition('completed');
// 输出:
// Task is running
// Task is paused
// Task is running
// Task completed
WeakMap:内存高效的特殊 Map
WeakMap 是 Map 的变体,键必须是对象,且对这些对象的引用是弱引用:
const weakMap = new WeakMap();
let key = { id: 1 };weakMap.set(key, 'Data associated with object');
console.log(weakMap.get(key)); // "Data associated with object"// 当对象没有其他引用时,会被垃圾回收
key = null;
// weakMap 中的键值对将在下一次垃圾回收时被移除
WeakMap 的主要应用场景:
- 私有数据存储:将对象关联到私有数据,而不影响对象的生命周期
const privateData = new WeakMap();class User {constructor(name, age) {this.name = name;privateData.set(this, { age });}getAge() {return privateData.get(this).age;}setAge(age) {privateData.get(this).age = age;}
}const user = new User('Alice', 30);
console.log(user.name); // "Alice"
console.log(user.getAge()); // 30
- DOM 节点关联数据:存储与 DOM 元素相关的数据,不会造成内存泄漏
const nodeData = new WeakMap();function addHandler(node, handler) {nodeData.set(node, { handler });node.addEventListener('click', handler);
}function removeHandler(node) {const data = nodeData.get(node);if (data) {node.removeEventListener('click', data.handler);// WeakMap会自动清理,当node被移除时}
}// 使用示例
const button = document.getElementById('my-button');
addHandler(button, () => console.log('Button clicked'));
性能考量与最佳实践
性能对比
各数据结构的性能特点:
操作 | Object | Map | Set |
---|---|---|---|
查找 | O(1) | O(1) | O(1) |
插入 | O(1) | O(1) | O(1) |
删除 | O(1) | O(1) | O(1) |
迭代 | O(n) | O(n) | O(n) |
Map 在频繁增删键值对的场景中比普通对象更高效,尤其是当键的数量非常大时。
内存占用
- WeakMap 和 WeakSet 对内存友好,适用于需要关联数据但不应阻止垃圾回收的场景
- 大型 Map 和 Set 集合在不再需要时应明确清空(使用 clear() 方法)
使用建议
选择 Symbol 的场景:
- 需要确保属性名唯一性
- 实现对象的"私有"属性
- 需要使用元编程能力
选择 Set 的场景:
- 需要存储唯一值集合
- 频繁检查值是否存在
- 需要高效实现数学集合操作
选择 Map 的场景:
- 键不限于字符串类型
- 需要频繁添加/删除键值对
- 需要维护插入顺序
- 需要直接迭代键值对
选择 WeakMap/WeakSet 的场景:
- 存储对对象的引用但不阻止垃圾回收
- 实现关联数据存储,特别是涉及 DOM 元素时
实际项目中的综合应用
下面展示一个将这三种数据结构结合使用的实际应用示例:构建一个轻量级组件系统。
// 使用 Symbol 定义内部操作标识
const RENDER = Symbol('render');
const STATE = Symbol('state');
const EVENTS = Symbol('events');// 使用 WeakMap 存储组件私有数据
const componentData = new WeakMap();class Component {constructor(element, initialState = {}) {// 初始化组件数据componentData.set(this, {element,[STATE]: new Map(Object.entries(initialState)),[EVENTS]: new Map()});this[RENDER]();}// 私有渲染方法[RENDER]() {const data = componentData.get(this);const state = Object.fromEntries(data[STATE]);data.element.innerHTML = this.template(state);// 重新绑定事件data[EVENTS].forEach((handler, event) => {data.element.addEventListener(event, handler);});}// 模板方法(子类实现)template(state) {throw new Error('Component subclass must implement template method');}// 获取状态getState(key) {const data = componentData.get(this);return data[STATE].get(key);}// 设置状态并重新渲染setState(key, value) {const data = componentData.get(this);data[STATE].set(key, value);this[RENDER]();return this;}// 添加事件处理on(event, handler) {const data = componentData.get(this);// 存储事件处理函数data[EVENTS].set(event, handler);return this;}
}// 使用示例:计数器组件
class Counter extends Component {constructor(element) {super(element, { count: 0 });this.on('click', () => {this.setState('count', this.getState('count') + 1);});}template(state) {return `<div class="counter"><p>Count: ${state.count}</p><button>Increment</button></div>`;}
}// 使用
const counterElement = document.getElementById('counter');
const counter = new Counter(counterElement);
浏览器兼容性
这些数据结构在现代浏览器中有良好的支持:
- Symbol:支持情况良好,IE11 不支持
- Set/Map:所有现代浏览器都支持,IE11 有部分支持
- WeakSet/WeakMap:所有现代浏览器都支持,IE11 不支持
对于需要支持旧浏览器的项目,可以使用核心-js 等 polyfill 库提供兼容支持。
总结与最佳实践
Symbol、Set 与 Map 这三种 ES6 数据结构极大地增强了 JavaScript 处理复杂数据的能力:
- Symbol 提供了创建唯一标识符的机制,解决了属性名冲突问题,并为元编程提供了基础
- Set 提供了高效的唯一值集合,简化了去重和集合操作
- Map 提供了真正的键值对集合,允许任何类型的键,适合更复杂的数据关联场景
在实际项目中,建议遵循以下建议:
- 明确选择数据结构的使用场景,避免过度使用
- 注意内存管理,特别是在处理大量数据时
- 考虑浏览器兼容性,必要时使用 polyfill
- 结合实际业务需求,灵活组合使用这些数据结构
充分利用这些现代数据结构,可以编写出更简洁、高效且易于维护的 JavaScript 代码。
进阶学习资源
- MDN Web Docs: Symbol
- MDN Web Docs: Set
- MDN Web Docs: Map
- ECMAScript 6 规范
- Exploring ES6
如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇
终身学习,共同成长。
咱们下一期见
💻
相关文章:
Symbol、Set 与 Map:新数据结构探秘
Symbol、Set 与 Map:新数据结构探秘 引言 ECMAScript 6 (ES6) 引入了三种强大的数据结构:Symbol、Set 与 Map,它们解决了 JavaScript 开发中的特定痛点,为我们提供了更多工具来处理复杂的数据操作。 Symbol:唯一标识…...

Spring Boot+Activiti7入坑指南初阶版
介绍 Activiti 是一个轻量级工作流程和业务流程管理 (BPM) 平台,面向业务人员、开发人员和系统管理员。其核心是一个超快且坚如磐石的 Java BPMN 2 流程引擎。它是开源的,并根据 Apache 许可证分发。Activiti 可以在任何 Java 应用程序、服务器、集群或云中运行。它与 Spri…...

如何在 Odoo 18 中创建 PDF 报告
如何在 Odoo 18 中创建 PDF 报告 Qweb 是 Odoo 强大的模板引擎,旨在轻松将 XML 数据转换为 HTML 文档。其功能特性包括基于属性的自定义、条件逻辑、动态内容插入及多样化的报告模板选项。这种多功能性使 Qweb 成为制作个性化、视觉吸引力强的报告、电子邮件和文档…...

【ROS2实体机械臂驱动】rokae xCoreSDK Python测试使用
【ROS2实体机械臂驱动】rokae xCoreSDK Python测试使用 文章目录 前言正文配置环境下载源码配置环境变量测试运行修改点说明实际运行情况 参考 前言 本文用来记录 xCoreSDK-Python的调用使用1。 正文 配置环境 配置开发环境,这里使用conda做python环境管理&…...
c/c++的opencv椒盐噪声
在 C/C 中实现椒盐噪声 椒盐噪声(Salt-and-Pepper Noise),也称为脉冲噪声(Impulse Noise),是数字图像中常见的一种噪声类型。它的特点是在图像中随机出现纯白色(盐)或纯黑色&#x…...
C++ TCP程序增加TLS加密认证
TCP为什么要增加TLS TCP程序添加TLS主要是为了解决TCP协议本身的安全缺陷。TCP作为传输层协议,虽然提供了可靠的数据传输,但它是明文传输,存在几个关键的安全问题: 数据泄露风险:TCP传输的数据完全暴露在网络中,任何能够监听网络流量的人都可以直接读取传输内容。这对于…...
构建一个“论文检索 + 推理”知识库服务,支持用户上传 PDF/LATEX 源码后,秒级检索并获得基于内容的问答、摘要、引用等功能
文章目录 1 总体目标 / Overall Goal2 数据管线 / Data Pipeline3 检索策略 / Retrieval Strategy4 服务切分 / Service Decomposition5 Agent & Prompt 设计 / Agent & Prompt6 核心功能 / Core Features7 评测与监控 / Evaluation & Monitoring8 面试亮点 / Inte…...

VLC-QT 网页播放RTSP
先看效果图,代码在文章末尾,包含源码,vlc-qt完整的库 环境说明:VS 2017 QTQt5.13.0 MSVC2017 32位 将vlc_install 目录下的bin,include,lib里所有的东西分别放在qt目录下 bin -> C:\Qt\Qt5.13.0\5.13.0\msvc2017\bin include->C:\Qt\Qt5.13.0\5.13.0\msvc201…...
for(auto a:b)和for(auto a:b)的区别
#include<iostream> using namespace std; int main() {string s( "hello world" );for (auto c:s)c t ;cout<<s<<endl; //结果为hello worldfor (auto &c:s)c t ;cout<<s<<endl; //结果为ttttttttttt }for(auto a:b)中b为一…...
第2章-12 输出三角形面积和周长(走弯路解法)
本题要求编写程序,根据输入的三角形的三条边a、b、c,计算并输出面积和周长。注意:在一个三角形中, 任意两边之和大于第三边。三角形面积计算公式:areas(s−a)(s−b)(s−c),其中s(abc)/2。 import math de…...
Caddy如何在测试环境中使用IP地址配置HTTPS服务
前言 在开发和测试环境中,我们经常需要搭建HTTPS服务进行测试。但通常Let’s Encrypt等证书颁发机构要求使用有效域名,不直接支持IP地址。本文将详细介绍如何使用Caddy在测试环境中通过IP地址配置HTTPS服务,使用自签名证书解决这一问题。 环…...
shell中与>和<相关的数据流重定向操作符整理
shell中与>和<相关的数据流重定向操作符整理 输出重定向操作符>>>2>2>>&> 或 >&&>> 输入重定向操作符<<<<<< 组合重定向2>&1 文件描述符相关重定向[n]< file 和 [n]> file>&- 和 <&…...

【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix
【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix 文章目录 【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix一、资料准备1.去畸变影像2.相机文件3.外方位元素二、创建工程1.新建工程2.导入照片3.编辑相机文件4.编辑外方位元素文件,导入外方位元…...

创建型设计模式之Prototype(原型)
创建型设计模式之Prototype(原型) 摘要: Prototype(原型)设计模式通过复制现有对象来创建新对象,避免重复初始化操作。该模式包含Prototype接口声明克隆方法、ConcretePrototype实现具体克隆逻辑ÿ…...

JNI开发流程
一. 引言 最近在做一个自己的项目,就是基于FastDDS封装一套JAVA库,让android和java应用可以使用dds的功能。 由于FastDDS是使用C编写的开源库,因此java的类库想要调用FastDDS的接口,需要额外编写一个JNI层的动态库对FastDDS的接口…...

STM32G4 电机外设篇(二) VOFA + ADC + OPAMP
目录 一、STM32G4 电机外设篇(二) VOFA ADC OPAMP1 VOFA1.1 VOFA上位机显示波形 2 ADC2.1 用ADC规则组对板载电压和电位器进行采样 3 OPAMP(运放)3.1 结合STM32内部运放和ADC来完成对三相电流的采样3.2 运放电路分析 附学习参考…...
RAG应用:交叉编码器(cross-encoder)和重排序(rerank)
文章目录 Sentence Transformers交叉编码器交叉编码器使用示例检索和重排序Sentence Transformers Sentence Transformers 支持两种类型的模型: Bi-encoders 和 Cross-encoders。Bi-encoders 更快更可扩展,但 Cross-encoders 更准确。虽然两者都处理类似的高水平任务,但何时…...

微服务难题?Nacos服务发现来救场
文章目录 前言1.什么是服务发现2.Nacos 闪亮登场2.1 服务注册2.2 服务发现 3.Nacos 的优势3.1 简单易用3.2 高可用3.3 动态配置 4.实战演练4.1安装 Nacos4.2 服务注册与发现示例代码(以 Spring Boot 为例) 总结 前言 大家好,我是沛哥儿。今天…...

C# 结合PaddleOCRSharp搭建Http网络服务
Windows打开端口: 控制面板 > 系统和安全 > 防火墙> 高级设置 → 入站规则 → 右侧选择 → 新建规则 → 端口 → 协议类型 TCP→ 端口 using System; using System.Drawing; using System.IO; using System.Net; using System.Text; using System.Threadi…...

【连接器专题】SD卡座规格书审查需要审哪些方面?
在审查SD卡座规格书时,我们需要考虑哪些方面? 首先在拿到一份SD卡座的详细规格书时,一般供应商给到的规格书中包括了一些基础信息、产品图纸信息、技术参数信息,同时有些供应商会给出产品可靠性测试报告。因此我们会从这几个要素去看规格书。 基础信息 基础信息一般会给变更…...
JS手写代码篇---手写节流函数
8、节流函数 什么是节流函数? 指规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。 与防抖函数有什么区别? 防抖函数是延…...
UE5 C++动态调用函数方法、按键输入绑定 ,地址前加修饰符
UE5 C动态调用函数方法、按键输入绑定 ,地址前加修饰符&,这个符号忘记输入的话,编译一直报错不通过 void ASnakeHead::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerIn…...

eBest智能价格引擎系统 助力屈臣氏饮料落地「价格大脑」+「智慧通路」数字基建
从价格策略到终端执行,数字化正在重构饮料行业竞争壁垒! 近日,eBest为屈臣氏饮料提供的智能价格引擎系统已正式上线并投入运营。同时,基于eBest SFA方案且与屈臣氏饮料业务场景深度耦合的Smart Field Operation智慧通路项目正式启…...
ubuntu mysql 8.0.42 基于二进制日志文件位置和GTID主从复制配置
目录 1 操作系统信息 2 MySql数据库版本 3 主机列表 4 MySQL服务器都安装依赖 5 主库服务器安装mysql软件步骤: 6 从服务器安装mysql软件步骤 7 基于二进制日志文件位置的主从复制配置 8 使用全局事务标识符进行主从复制(GTID) 9 部署过程遇到问题 1 操作系…...

Kettle 远程mysql 表导入到 hadoop hive
kettle 远程mysql 表导入到 hadoop hive (教学用 ) 文章目录 kettle 远程mysql 表导入到 hadoop hive创建 对象 执行 SQL 语句 -mysql 导出 CSV格式CSV 文件远程上传到 HDFS运行 SSH 命令远程登录 run SSH 并执行 hadoop fs -put 建表和加载数据总结 创…...

完整解析 Linux Kdump Crash Kernel 工作原理和实操步骤
完整解析 Linux Kdump Crash Kernel 工作原理和实操步骤 一、前言 在使用 Linux 操作系统进行内核开发或者系统维护时,内核 panic 是最常见的系统崩溃环节。如果想要在内核崩溃后立即分析环境和输出内核内存 dump,Kdump crashkernel 是最接近完美的解…...

菜鸟之路Day36一一Web开发综合案例(部门管理)
菜鸟之路Day36一一Web开发综合案例(部门管理) 作者:blue 时间:2025.5.28 文章目录 菜鸟之路Day36一一Web开发综合案例(部门管理)一.环境搭建二.开发规范三.部门管理3.1查询3.2删除3.3新增3.3修改根据id来…...
LangChain实战:MMR和相似性搜索技术应用
导读:在当今大数据和人工智能快速发展的背景下,向量数据库的搜索技术正成为技术人员必须掌握的核心技能。本文将深入探讨LangChain框架与Milvus向量数据库的整合实践,重点对比分析相似度搜索与最大边际相关性(MMR)搜索…...

第 1 章:学习起步
1. React Native前置知识要求 在开始学习React Native之前,有一些前置知识你需要了解。不过别担心,我会带你逐步掌握这些内容,让你顺利入门。 1.1. JavaScript是必须掌握的 学习React Native,JavaScript是基础。你需要了解Java…...

SQL查询——大厂面试真题
前言 本文总结了SQLite数据库的核心操作要点:1. 基础语法:SQL语句不区分大小写,多语句需用分号分隔,支持多种注释方式2. 表操作:包括创建表(定义主键、非空约束等)、插入/更新/删除数据、添加/…...