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

从 Set、Map 到 WeakSet、WeakMap 的进阶之旅

在 ES5 时代,JavaScript 的数据结构主要依赖于两种类型:数组和对象。然而,随着应用规模的增长和复杂性上升,传统的数据结构越来越难以满足开发需求。比如,需要一个能自动去重的集合、一个支持任意类型键名的字典、一个不会造成内存泄漏的弱引用映射……

为了解决这些问题,ECMAScript 2015(也称 ES6)正式引入了四个全新的内建数据结构:Set、Map、WeakSet 和 WeakMap。这些结构不是对旧有数据结构的简单补充,而是为现代 JavaScript 编程量身定制的“加强型武器”。

一、Set

1. 定义与特点

Set 是一种集合类型的数据结构,用于存储唯一的值。它类似于数组,但成员的值都是唯一的,没有重复的值。Set 中的值可以是各种类型的值,包括原始值和对象引用。

2. 基本操作
const mySet = new Set();// 添加元素
mySet.add(1);
mySet.add(5);
mySet.add(5); // 重复的值不会被添加// 检查元素是否存在
console.log(mySet.has(1)); // true
console.log(mySet.has(3)); // false// 删除元素
mySet.delete(5);// 获取集合大小
console.log(mySet.size); // 1// 清空集合
mySet.clear();
3. 遍历方法

Set 提供了多种遍历方法:

  • mySet.keys():返回一个包含集合中所有键的迭代器。
  • mySet.values():返回一个包含集合中所有值的迭代器。
  • mySet.entries():返回一个包含集合中所有键值对的迭代器。
  • mySet.forEach(callbackFn, thisArg):对集合中的每个元素执行一次给定的函数。
const mySet = new Set([1, 2, 3]);for (let item of mySet) console.log(item); // 1 2 3mySet.forEach((value) => {console.log(value);
});
4. 使用场景

1、数组去重

const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]

2、集合操作:交集、并集、差集等。

const setA = new Set([1, 2, 3]);
const setB = new Set([3, 4, 5]);// 并集
const union = new Set([...setA, ...setB]);// 交集
const intersection = new Set([...setA].filter(x => setB.has(x)));// 差集
const difference = new Set([...setA].filter(x => !setB.has(x)));
5. 底层原理

1、底层实现结构

JavaScript 是高级语言,无法直接查看内部源码,但根据 ECMAScript 规范与主流 JS 引擎实现(如 V8),可以推断出 Set 的底层结构大致如下:内部使用类似哈希表的数据结构存储数据。

  • Set 使用了一种哈希集合(HashSet)的数据结构实现。
  • 它为每个加入的元素计算哈希值,用这个哈希值来判断是否为重复项。
  • 通过哈希定位数据插入/查询的位置,从而实现 插入、查找、删除的高性能操作。

2、Set 的去重原理:SameValueZero 算法

Set 判定两个值是否相同,是使用了 ECMAScript 中定义的 SameValueZero 算法,而不是 =====

SameValueZero 的特点:

  • NaN === NaN 是 false,但在 Set 中 NaN 和 NaN 被认为是相等的。
  • +0 和 -0 被认为是相等的。
  • 基本上和 === 一样,只是 NaN 也等于自己。

🌰

const s = new Set();
s.add(NaN);
s.add(NaN);
s.add(+0);
s.add(-0);
console.log(s); // Set(2) { NaN, 0 }

3、Set 的插入逻辑(伪代码)

class MySet {constructor(iterable) {this._storage = {}; // 哈希桶if (iterable) {for (const item of iterable) {this.add(item);}}}add(value) {const hash = this._hash(value); // 简化哈希逻辑if (!this._storage.hasOwnProperty(hash)) {this._storage[hash] = value;}return this;}has(value) {const hash = this._hash(value);return this._storage.hasOwnProperty(hash);}delete(value) {const hash = this._hash(value);if (this._storage.hasOwnProperty(hash)) {delete this._storage[hash];return true;}return false;}_hash(value) {// 简化处理:真实引擎内部使用复杂引用检查和哈希函数if (typeof value === 'object') {return JSON.stringify(value); // 仅示意,不可用于真实应用}return String(value);}
}
6. Set 的实际性能如何?
  • 插入(add)复杂度:O(1)
  • 查找(has)复杂度:O(1)
  • 删除(delete)复杂度:O(1)

相比数组的 O(n) 查找,Set 在处理大量数据的去重或快速查找时效率更高。

二、Map

1. 定义与特点

Map 是一种键值对的集合,类似于对象(Object),但键的范围不限于字符串,任何值(包括对象)都可以作为键。Map 中的键值对是有序的,按插入的顺序进行迭代。

2. 基本操作
const myMap = new Map();// 设置键值对
myMap.set('name', 'Alice');
myMap.set(1, 'number one');
myMap.set(true, 'boolean true');// 获取值
console.log(myMap.get('name')); // Alice// 检查键是否存在
console.log(myMap.has(1)); // true// 删除键值对
myMap.delete(true);// 获取Map大小
console.log(myMap.size); // 2// 清空Map
myMap.clear();
3. 遍历方法

​Map 提供了多种遍历方法:

  • ​myMap.keys():返回一个包含Map中所有键的迭代器。
  • myMap.values():返回一个包含Map中所有值的迭代器。
  • myMap.entries():返回一个包含Map中所有键值对的迭代器。
  • myMap.forEach(callbackFn, thisArg):对Map中的每个键值对执行一次给定的函数。
const myMap = new Map([['name', 'Bob'],['age', 25],
]);for (let [key, value] of myMap) {console.log(`${key}: ${value}`);
}
4. 应用场景

1、存储关联数据

当需要将键值对关联在一起,并且键可以是对象时,Map 是更好的选择。

const user1 = { name: 'Alice' };
const user2 = { name: 'Bob' };const userRoles = new Map();
userRoles.set(user1, 'admin');
userRoles.set(user2, 'editor');
console.log(userRoles); //  Map(2) { { name: 'Alice' } => 'admin', { name: 'Bob' } => 'editor' }

2、缓存数据

const cache = new Map();function fetchData(id) {if (cache.has(id)) return cache.get(id);const data = loadFromServer(id);cache.set(id, data);return data;
}

3、频繁添加和删除键值对:Map 在这方面性能优于对象。

5. 为什么要引入 Map?

传统的 Object 有如下局限:

  • 键只能是字符串或 Symbol
  • 无法保证键值对顺序
  • 原型污染风险存在
  • 获取长度需要额外操作(Object.keys(obj).length)

因此,ES6 引入了 Map,更适合用作结构化数据的容器。

6. 底层实现原理

Map 是基于一种哈希表(Hash Table)+ 双向链表(Linked List)组合的数据结构实现的。哈希表存储键值映射,双向链表记录插入顺序。

伪代码来模拟内部结构(简化版,仅作理解用)

class SimpleMap {constructor() {this._buckets = {}; // 哈希桶,用于键值映射this._order = [];   // 保证插入顺序}_hash(key) {// 简化处理:真实 JS 引擎会对对象引用地址做处理return typeof key === 'object' ? JSON.stringify(key) : String(key);}set(key, value) {const hash = this._hash(key);if (!(hash in this._buckets)) {this._order.push(hash); // 插入顺序}this._buckets[hash] = { key, value };}get(key) {const hash = this._hash(key);return this._buckets[hash]?.value;}has(key) {return this._hash(key) in this._buckets;}delete(key) {const hash = this._hash(key);const exists = hash in this._buckets;if (exists) {delete this._buckets[hash];this._order = this._order.filter(h => h !== hash);}return exists;}keys() {return this._order.map(hash => this._buckets[hash].key);}values() {return this._order.map(hash => this._buckets[hash].value);}entries() {return this._order.map(hash => [this._buckets[hash].key, this._buckets[hash].value]);}
}

⚠️ 真正引擎会对对象键使用内部标识管理,而不会 JSON 序列化对象。

与 Set 类似,Map 也使用 SameValueZero 来比较键是否相等:

const map = new Map();
map.set(NaN, 'a');
map.set(NaN, 'b'); // 覆盖上面的值console.log(map.size); // 1
console.log(map.get(NaN)); // 'b'

内部存储示意图

      Map 实例   ↓哈希表(键 -> 值)      "name"    → "Alice"     objId123  → "UserData" funcId456  → "Func"    ↓插入顺序链表["name", objId123, funcId456]
7.  Map 和 Object 的关键区别
对比点MapObject
键类型支持任意类型(对象、函数等)仅字符串和 Symbol
键值对有序有序(插入顺序)无序(规范不保证)
内存泄漏风险高(强引用键)低(仅原始键)
原型污染风险无(无默认属性)

有(需注意 __proto__)

获取长度性能常数 .size需手动计算长度
是否可迭代

是(可 for...of, .entries())

否(需手动提取)
8. Map 的实际性能如何?
  • set 时间复杂度:O(1)
  • get 时间复杂度:O(1)
  • has 时间复杂度:O(1)
  • delete 时间复杂度:O(1)
  • 遍历 时间复杂度:O(n)

适合场景:大数据量的键值管理,尤其是非字符串键。

三、有了 Map 和 Set,为什么还需要 WeakMap 和 WeakSet?

1. 背景导入:为什么会用 Map 和 Set?

在日常开发中,Map 和 Set 是 ES6 提供的强大数据结构:

  • Map:可以用对象作为键,解决了传统对象只能用字符串作为键的局限。
  • Set:可以存储唯一值(包括对象、原始类型等),用于去重、快速查找等场景。

但它们的一个问题是——强引用(Strong Reference)

2. 强引用 vs 弱引用

Strong Reference vs Weak Reference

什么是“强引用”?

在 JavaScript 中,默认的引用都是强引用

只要某个对象被一个变量强引用着,垃圾回收器(GC)就不会回收这个对象的内存。 

比如:

const obj = { name: 'Tom' };
const map = new Map();
map.set(obj, 'hello');

这里,map 对 obj 的引用是强引用,就算 obj 原始变量被设为 null,obj 也依然不会被 GC,因为 map 还引用着它。

什么是“弱引用”?

弱引用是一种不会阻止垃圾回收器回收对象的引用。 

const obj = { name: 'Tom' };
const weakMap = new WeakMap();
weakMap.set(obj, 'hello');

当 obj = null 且没有其他引用指向这个对象时,这个对象会被 GC 自动清理掉,哪怕它还作为 weakMap 的键。

本质差别总结

对比项强引用 (Map, Set)弱引用 (WeakMap, WeakSet)
是否阻止 GC
可被枚举是(可遍历)否(不可遍历)
键支持类型任意值(Map)只能是对象(WeakMap)
使用场景普通缓存/字典结构私有数据/临时缓存/监听器等
3. 为什么 WeakMap 和 WeakSet 是必要的?

1、防止内存泄露

在一些临时数据或缓存管理场景中,如果使用 Map 或 Set 来存储对象,一旦忘记清除,内存就泄漏了。

let obj = {};
let map = new Map();
map.set(obj, 'data');obj = null; // 虽然变量 obj 已被置空,但 map 还在引用它,这个对象永远不会被回收!

但如果使用 WeakMap:

let obj = {};
let weakMap = new WeakMap();
weakMap.set(obj, 'data');obj = null; // 此时没有强引用,GC 会自动回收 obj 对应的内存

这样可以 自动释放内存,防止内存泄漏

2、封装私有属性(隐藏实现)

WeakMap 被广泛用于 JS 类或组件内部存储私有数据,不暴露给外部。

const _privateData = new WeakMap();class Person {constructor(name) {_privateData.set(this, { name });}getName() {return _privateData.get(this).name;}
}const p = new Person('Alice');
console.log(p.getName()); // Alice

3、事件监听管理、DOM 元素缓存

比如在做页面事件绑定时,经常会给 DOM 元素绑定元数据,并确保在 DOM 被删除后自动清理内存,防止内存泄漏。

const elementMeta = new WeakMap();function bindMeta(el, meta) {elementMeta.set(el, meta);
}function getMeta(el) {return elementMeta.get(el);
}

这里的键(key)只能是对象类型,通常是 DOM 元素。值(value)是想要绑定的元数据,可以是任何内容(对象、字符串、状态等)。

🌰

const btn = document.querySelector('#submit');
bindMeta(btn, { clicked: false });

一旦 DOM 被移除并置空,相关元数据也会被自动清理,无需手动解绑,非常适合短生命周期对象管理

4. 底层实现原理简述

Map 的实现:

  • 底层是哈希表(Hash Table),键和值存储在内部分开的结构。
  • 键是强引用,对象不会被 GC。

WeakMap 的实现:

  • 同样是哈希结构,但键是 弱引用对象。
  • 键必须是对象(不能是原始值),这样才能与对象生命周期绑定。
  • 键不可遍历:无法使用 forEach 或 keys(),因为这样就可能阻止 GC。

为什么不能遍历 WeakMap?

如果允许遍历 WeakMap,GC 就必须保留所有键的引用,违背了“弱引用”的设计初衷。 所以为了确保安全,WeakMap 是不可枚举的。同理 WeakSet 也是一样的。

四、WeakSet

1. 定义与特点

WeakSet 是一种集合类型的数据结构,类似于 Set,但只能存储对象,并且这些对象是弱引用的。这意味着,如果没有其他变量引用某个对象,该对象会被垃圾回收机制回收。

2. 基本操作
const ws = new WeakSet();const obj = {};
ws.add(obj);console.log(ws.has(obj)); // truews.delete(obj);
console.log(ws.has(obj)); // false

特点:

  •  只能存储对象,不能存储原始值。
  • 对象是弱引用的,不会阻止垃圾回收。
  • 不可遍历,没有 size 属性。
  • 不支持迭代,没有 forEach、values、keys、entries 方法。
  • 没有 clear() 方法。
3. 应用场景
  • 存储DOM节点:当需要存储DOM节点,并且不希望这些节点被垃圾回收机制阻止时,可以使用 WeakSet。
  • 私有数据的存储:在类中使用 WeakSet 存储私有数据,防止外部访问。

五、WeakMap

1. 定义与特点

WeakMap 是一种键值对的集合,类似于 Map,但键必须是对象,值可以是任意类型。键是弱引用的,这意味着如果没有其他变量引用该键对象,该键值对会被垃圾回收机制回收。

2. 基本操作
const wm = new WeakMap();const obj = {};
wm.set(obj, 'some value');console.log(wm.get(obj)); // 'some value'wm.delete(obj);
console.log(wm.has(obj)); // false

特点:

  • 键必须是对象,不能是原始值。
  • 键是弱引用的,不会阻止垃圾回收。
  • 不可遍历,没有 size 属性。
  • 没有 clear() 方法。
3. 应用场景
  • 私有属性的存储:在类中使用 WeakMap 存储私有属性,防止外部访问。
  • 缓存机制:缓存某些对象的计算结果,当对象被垃圾回收时,缓存也会自动清除。

相关文章:

从 Set、Map 到 WeakSet、WeakMap 的进阶之旅

在 ES5 时代,JavaScript 的数据结构主要依赖于两种类型:数组和对象。然而,随着应用规模的增长和复杂性上升,传统的数据结构越来越难以满足开发需求。比如,需要一个能自动去重的集合、一个支持任意类型键名的字典、一个…...

TTL (Time-To-Live) 解析

文章目录 TTL (Time-To-Live) 解析:网络与Java中的应用一、TTL的定义二、TTL在网络中的应用1. **路由和数据包的生命周期**2. **DNS中的TTL**3. **防止环路** 三、TTL在Java中的应用1. **缓存管理**2. **Java中的ThreadLocal**3. **网络通信中的TTL** 四、TTL的注意…...

Qt/C++开发监控GB28181系统/录像文件查询/录像回放/倍速播放/录像文件下载

一、前言 搞定了实时预览后,另一个功能就是录像回放,录像回放和视频点播功能完全一致,唯一的区别就是发送点播的sdp信息中携带了开始时间和结束时间,因为是录像文件,所以有这个时间,而实时视频预览这个对应…...

季报中的FPGA行业:U型反转,春江水暖

上周Lattice,AMD两大厂商相继发布2025 Q1季报,尽管恢复速度各异,但同时传递出FPGA行业整体回暖的复苏信号。 5月5日,Lattice交出了“勉强及格”的答卷,报告季度营收1亿2000万,与华尔街的预期基本相符。 对于这家聚焦在中小规模器件的领先厂商而言,按照其CEO的预期,长…...

嵌入式机器学习平台Edge Impulse图像分类 – 快速入门

陈拓 2025/05/08-2025/05/11 1. 简介 官方网址 https://edgeimpulse.com/ 适用于任何边缘设备的人工智能: Gateways - 网关 Sensors & Cameras - 传感器和摄像头 Docker Containers - Docker容器 MCUs, NPUs, CPUs, GPUs 构建数据集、训练模型并优化库以…...

web 自动化之 yaml 数据/日志/截图

文章目录 一、yaml 数据获取二、日志获取三、截图 一、yaml 数据获取 需要安装 PyYAML 库 import yaml import os from TestPOM.common import dir_config as Dir import jsonpathclass Data:def __init__(self,keyNone,file_name"test_datas.yaml"):file_path os…...

ARMV8 RK3399 u-boot TPL启动流程分析 --start.S

上电后运行的第一支文件&#xff1a;arch/arm/cpu/armv8/start.S CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK1 #include <asm/arch/boot0.h> 跳转到 arch/arm/include/asm/arch-rockchip/boot0.h CONFIG_SPL_BUILD1 b 1f ROCKCHIP_EARLYRETURN_TO_BROMno TINY_FRAMEWORKno …...

zst-2001 上午题-历年真题 计算机网络(16个内容)

网络设备 计算机网络 - 第1题 ac 计算机网络 - 第2题 d 计算机网络 - 第3题 集线器不能隔离广播域和冲突域&#xff0c;所以集线器就1个广播域和冲突域 交换机就是那么的炫&#xff0c;可以隔离冲突域&#xff0c;有4给冲突域&#xff0c;但不能隔离广播域&#xf…...

使用termius连接腾讯云服务器

使用termius连接腾讯云服务器 1.下载termius termius官网 安装配置教程 这里安装的window版本> 默认安装到C盘&#xff0c;不建议修改路径 可以选择谷歌登录&#xff0c;也可以不登录&#xff0c;软件是免费的&#xff0c;试用的是付费版本&#xff0c;不需要点 2.配置 这里…...

redis 命令大全整理

http://doc.redisfans.com/ 原网址 Redis 命令分类 Key(键) Key(键)命令 exists/del/keys/type/scanobject/move/dump/migratettl/pttl/persist/expireat/pexpireat/expire/pexpirerename/renamenxsort/randomkey/restoreexists 语法:exists key [key ...] 检查一个或多…...

实景三维建模软件应用场景(众趣科技实景三维建模)

实景三维建模软件应用场景概述 实景三维建模软件&#xff0c;作为数字化时代的重要工具&#xff0c;不仅能够真实、立体、时序化地反映和表达物理世界&#xff0c;还为国家的基础设施建设和数字化发展提供了有力的支撑。 在测绘与地理信息领域&#xff0c;实景三维建模软件是构…...

Mac M系列 安装 jadx-gui

安装 Homebrew在终端中执行以下命令&#xff08;需管理员密码&#xff09;&#xff1a; 安装 Homebrew&#xff08;官方源&#xff09; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"国内用户可用镜像源加速&…...

软考 系统架构设计师系列知识点之杂项集萃(56)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;55&#xff09; 第91题 商业智能关注如何从业务数据中提取有用的信息&#xff0c;然后采用这些信息指导企业的业务开展。商业智能系统主要包括数据预处理、建立&#xff08;&#xff09;、数据分…...

Ubuntu20.04 搭建Kubernetes 1.28版本集群

环境依赖 以下操作,无特殊说明,所有节点都需要执行 安装 ssh 服务安装 openssh-server复制代码 sudo apt-get install openssh-server修改配置文件复制代码 vim /etc/ssh/sshd_config找到配置项 复制代码 LoginGraceTime 120 PermitRootLogin prohibit-password StrictModes…...

【Linux】基础指令(Ⅱ)

目录 1. mv指令 2. cat指令 3.echo指令 补&#xff1a;输出重定向 4. more指令 5. less指令 6. head指令和tail指令 7.date指令 时间戳&#xff1a; 8. cal指令 9. alias指令 10.grep指令 1. mv指令 语法&#xff1a;mv [选项]... 源文件/目录 目标文件/目录 …...

RAG之大规模解析 PDF 文档全流程实战

PDF 文档在商业、学术和政府领域无处不在,蕴含着大量宝贵信息。然而,从 PDF 中提取结构化数据却面临着独特的挑战,尤其是在处理数千甚至数百万个文档时。本指南探讨了大规模解析 PDF 的策略和工具。 PDF解析挑战 PDF 的设计初衷是为了提供一致的视觉呈现,而非数据提取。这…...

vue-ganttastic甘特图label标签横向滚动固定方法

这个甘特图之前插件里&#xff0c;没有找到能固定label标签在屏幕上的办法&#xff0c;用css各种办法都没有实现&#xff0c;所以我我直接手写定位&#xff0c;用js监听滚动条滚动的距离&#xff0c;然后同步移动甘特图label标签&#xff0c;造成一种定位的错觉&#xff0c;以下…...

AcroForm JavaScript Promise 对象应用示例: 异步加载PDF文件

这段代码演示了在Adobe Acrobat DC Pro 的 JavaScript 环境中如何使用 Promise 对象处理异步操作。具体功能是&#xff1a; 定义了一个loadFile函数&#xff0c;模拟异步加载PDF文件的操作使用Promise对象封装异步操作&#xff0c;提供成功(resolve)和失败(reject)两种状态通过…...

MySQL 8.0 OCP 1Z0-908 题目解析(2)

题目005 Choose two. Which two actions can obtain information about deadlocks? □ A) Run the SHOW ENGINE INNODB MUTEX command from the mysql client. □ B) Enable the innodb_status_output_locks global parameter. □ C) Enable the innodb_print_all_deadlock…...

【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件

问题场景&#xff1a; 提示&#xff1a;ipa是用于苹果设备安装的软件包资源 设备&#xff1a;iphone 13(未越狱) 安装包类型&#xff1a;ipa包 调试工具&#xff1a;hbuilderx 问题描述 提要&#xff1a;ios包无法安装 uniapp导出ios包无法安装 相信有小伙伴跟我一样&…...

【嵌入模型与向量数据库】

目录 一、什么是向量&#xff1f; 二、为什么需要向量数据库&#xff1f; 三、向量数据库的特点 四、常见的向量数据库产品 FAISS 支持的索引类型 vs 相似度 五、常见向量相似度方法对比 六、应该用哪种 七、向量数据库的核心逻辑 &#x1f50d; 示例任务&#xff1a;…...

【东枫科技】使用LabVIEW进行NVIDIA CUDA GPU 开发

文章目录 工具包 CuLab - LabVIEW 的 GPU 工具包特性和功能功能亮点类似 LabVIEW 的 GPU 代码开发支持的功能数值类型和维数开发系统要求授权售价 工具包 CuLab - LabVIEW 的 GPU 工具包 CuLab 是一款非常直观易用的 LabVIEW 工具包&#xff0c;旨在加速 Nvidia GPU 上的计算密…...

基于策略的强化学习方法之策略梯度(Policy Gradient)详解

在前文中&#xff0c;我们已经深入探讨了Q-Learning、SARSA、DQN这三种基于值函数的强化学习方法。这些方法通过学习状态值函数或动作值函数来做出决策&#xff0c;从而实现智能体与环境的交互。 策略梯度是一种强化学习算法&#xff0c;它直接对策略进行建模和优化&#xff0c…...

1.Redis-key的基本命令

&#xff08;一&#xff09;Redis的基本类型 String&#xff0c;List&#xff0c;Set&#xff0c;Hash&#xff0c;Zset 三种特殊类型&#xff1a;geospatial&#xff08;地理空间数据&#xff09;、hyperloglog[基数估算&#xff08;去重计数&#xff09;]、bitmaps(位图&…...

JavaScript 中级进阶技巧之map函数

作为一名初级 JavaScript 开发者&#xff0c;你可能已经熟悉了基础语法、变量和简单的循环。但要从初级迈向中级&#xff0c;掌握一些高效、优雅的编码技巧是关键。其中&#xff0c;map 函数是中级开发者常用的工具&#xff0c;它不仅能简化代码&#xff0c;还能提升代码的可读…...

PROFIBUS DP转ModbusTCP网关模块于污水处理系统的成功应用案例解读​

在当今的工业生产领域&#xff0c;众多企业在生产过程中会产生大量工业废水。若这些废水未经处理直接排放&#xff0c;将会引发严重的工业污染问题。因此&#xff0c;借助科技手段对污水进行有效处理显得尤为重要。在一个污水处理系统中&#xff0c;往往包含来自不同厂家、不同…...

Java实现桶排序算法

1. 桶排序原理图解 桶排序是一种基于分桶思想的非比较排序算法&#xff0c;适用于数据分布较为均匀的场景。其核心思想是将数据分散到有限数量的“桶”中&#xff0c;每个桶再分别进行排序&#xff08;通常使用插入排序或其他简单的排序算法&#xff09;。以下是桶排序的步骤&a…...

《Effective Python》第2章 字符串和切片操作——深入理解 Python 中 __repr__ 与 __str__

引言 本文基于学习《Effective Python》第三版 Chapter 2: Strings and Slicing 中的 Item 12: Understand the Difference Between repr and str When Printing Objects 后的总结与延伸。在 Python 中&#xff0c;__repr__ 和 __str__ 是两个与对象打印密切相关的魔术方法&am…...

电脑开机提示按f1原因分析及解决方法(6种解决方法)

经常有网友问到一个问题,我电脑开机后提示按f1怎么解决?不管理是台式电脑,还是笔记本,都有可能会遇到开机需要按F1,才能进入系统的问题,引起这个问题的原因比较多,今天小编在这里给大家列举了比较常见的几种电脑开机提示按f1的解决方法。 电脑开机提示按f1原因分析及解决…...

复现:DemoGen 用于数据高效视觉运动策略学习的 合成演示生成 (RSS) 2025

https://github.com/TEA-Lab/DemoGen?tabreadme-ov-file 复现步骤很简单&#xff0c;按照readme配置好conda环境即可运行。 运行&#xff1a; cd demo_generation bash run_gen_demo.sh 等待生成&#xff1a; 查看data文件夹...