Redis Hash 介绍
Redis Hash 介绍
从基础命令、内部编码和使用场景三个维度分析如下:
一、基础命令
Redis Hash 提供了丰富的操作命令,适用于字段(field)级别的增删改查:
-
设置与修改
-
HSET:设置单个字段值(
HSET key field value)。# 存储用户信息(用户ID=1001) HSET user:1001 name "Alice" age 28 email "alice@example.com" # 返回3(表示成功设置3个字段) -
HSETNX:仅当字段不存在时设置值,避免覆盖。
# 防止覆盖已存在的字段 HSETNX user:1001 email "new@example.com" # 返回0(字段已存在,未修改) HSETNX user:1001 address "New York" # 返回1(新增字段) -
HINCRBY:对数值型字段进行增减操作(如计数器场景)。
场景:计数器(库存、销量、点击量),支持原子增减,避免并发问题。
# 商品ID=2001的库存增减 HINCRBY product:2001 stock -5 # 减少库存5(返回新值,如95) HINCRBY product:2001 sales 10 # 增加销量10(返回新值,如150)
-
-
查询与检索
-
HGET:获取单个字段值。
HGET user:1001 name # 返回"Alice" -
HMGET:批量获取多个字段值。
HMGET user:1001 name age email # 返回["Alice", "28", "alice@example.com"] -
HGETALL:获取所有字段及值(需谨慎使用,大数据量可能阻塞服务)。
HGETALL user:1001 # 返回所有字段和值(适用于小规模数据) -
HKEYS/HVALS:分别获取所有字段名或值。
HKEYS user:1001 # 返回["name", "age", "email", "address"] HVALS user:1001 # 返回["Alice", "28", "alice@example.com", "New York"]
-
-
删除与判断
-
HDEL:删除指定字段。
场景:清理过期字段,例如用户注销后删除敏感信息。
-
HEXISTS:判断字段是否存在。
场景:检查字段是否存在,例如权限校验或防止重复操作。
-
HLEN:统计字段数量。
统计对象属性数量,例如监控购物车商品种类数。
-
二、内部编码
Redis Hash 根据数据规模和配置动态选择底层数据结构,以平衡性能与内存效率:
-
ziplist(压缩列表)
- 条件:当字段数 ≤
hash-max-ziplist-entries(默认 512)且所有字段值 ≤hash-max-ziplist-value(默认 64 字节)时启用。 - 特点:连续内存存储,无指针开销,内存利用率高,但插入/删除效率随数据量增长而下降。
- 条件:当字段数 ≤
-
hashtable(哈希表)
- 触发条件:超出 ziplist 配置限制时自动转换。
- 特点:通过哈希表实现 O(1) 复杂度的读写操作,适合大规模数据,但内存占用较高。
-
Redis 7.0 及以上版本已弃用 ziplist,改用 listpack 作为默认的紧凑数据结构。
-
数据结构设计对比
特性 ziplist listpack 存储结构 连续内存块,元素通过 prevlen字段记录前一个元素的长度,形成隐式链表。连续内存块,每个元素独立存储自身长度信息,无前后依赖。 连锁更新风险 存在:插入/删除元素时,可能触发后续元素的 prevlen字段更新,导致级联内存重分配。不存在:元素长度独立编码,无需依赖前驱元素,彻底避免连锁更新。 内存布局 通过 prevlen和encoding字段实现变长编码。通过 element-total-len字段统一记录元素总长度,结构更简单。安全性 易因 prevlen计算错误导致内存越界(历史漏洞)。长度信息自包含,访问更安全,减少内存越界风险。 -
性能与内存效率
维度 ziplist listpack 插入/删除效率 平均 O(n),可能触发连锁更新(最坏 O(n^2))。 平均 O(n),无连锁更新,性能更稳定。 随机访问速度 O(n),需遍历查找元素。 O(n),与 ziplist 相同,但遍历更高效(长度解析更快)。 内存占用 较低(但存在 prevlen字段冗余)。与 ziplist 接近,甚至更优(更紧凑的长度编码)。 并发操作适应性 高并发写入时,连锁更新可能导致性能抖动。 无连锁更新,高并发下性能更稳定。 -
ziplist 的缺陷
- 连锁更新问题:
在中间位置插入元素时,若后续元素的prevlen 字段因长度变化需要扩展(例如从 1 字节变为 5 字节),会触发后续元素的连续内存重分配,导致性能骤降。
示例:插入一个长度超过 254 字节的元素,导致后续元素的prevlen 从0xFE(1 字节)变为0xFF + 4字节长度(5 字节)。 - 安全性风险:
prevlen 解析错误可能引发内存越界(如 Redis 早期版本中的 CVE-2018-11213 漏洞)。
- 连锁更新问题:
-
listpack 的改进
-
自包含长度信息:
每个元素头部使用element-total-len 字段记录自身总长度(包含编码类型、数据长度等),解析时无需依赖前驱元素。 -
编码优化:
长度字段采用更紧凑的变长编码(类似 UTF-8),例如:- 长度 ≤ 127:1 字节。
- 长度 ≤ 16383:2 字节。
- 更大长度:5 字节(1 字节标记 + 4 字节长度)。
-
-
使用场景对比
场景 推荐结构 原因 小规模只读数据 ziplist/listpack 内存紧凑,适合存储用户基础信息、配置项等(Redis 7.0+ 优先使用 listpack)。 高频写入/随机修改 listpack 无连锁更新问题,适合计数器、动态元数据等场景(Redis 7.0+ 默认使用 listpack)。 大规模数据存储 hashtable 数据量大时 O(1) 哈希表更高效(无论底层是 ziplist 还是 listpack,超阈值后均转为 hashtable)。 高并发写入场景 listpack 避免 ziplist 的连锁更新抖动,性能更稳定。
-
-
数据结构特性对比
特性 ziplist(压缩列表) hashtable(哈希表) 存储方式 连续内存块存储,无指针开销,通过偏移量访问数据。 散列桶结构,每个键值对通过哈希函数分配到桶中,通过指针链接。 内存占用 内存紧凑,无额外指针开销,内存利用率高。 内存占用较高(存储指针、哈希表扩容时的冗余空间)。 查询复杂度 O(n)(需要遍历字段查找) O(1)(哈希表直接定位) 插入/删除效率 平均 O(n),数据量大时效率低(需移动后续元素,可能触发连锁更新)。 O(1)(哈希表直接操作,扩容时可能触发 rehash 耗时)。 扩容机制 不可动态扩容,超出阈值后直接转换为 hashtable。 动态扩容(负载因子超过阈值时翻倍扩容,缩容时按需减少)。 适用数据规模 字段数少(默认 ≤512)且字段值小(默认 ≤64 字节)。 字段数多或字段值大。 -
适用场景对比
场景 推荐编码 原因 小型对象存储 ziplist 字段数少且值小(如用户基础信息),内存利用率高。 高频写入/随机访问 hashtable 避免 ziplist 的遍历开销和连锁更新问题(如频繁修改的计数器)。 只读或低频修改数据 ziplist 利用内存紧凑特性减少内存占用(如静态配置数据)。 大规模数据存储 hashtable 数据量大时 O(1) 查询效率显著优于 ziplist(如购物车、社交关系链)。 需要遍历所有字段 ziplist(小数据) 连续内存布局遍历更快;大数据量时 hashtable 的 HSCAN更安全(避免HGETALL阻塞)。 -
配置调优建议
hash-max-ziplist-entries 512 # 字段数阈值,默认 512 hash-max-ziplist-value 64 # 单个字段值最大字节数,默认 64- 降低阈值:若需优先保障读写性能,可调小阈值(如
entries 128),让更多 Hash 使用 hashtable。(空间) - 提高阈值:若内存紧张且数据规模可控,可增大阈值(如
entries 1024),延长 ziplist 的使用。(时间)
- 降低阈值:若需优先保障读写性能,可调小阈值(如
三、使用场景
案例所需依赖 :
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.1</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.2</version></dependency></dependencies>
-
对象属性存储
-
将对象的多个属性(如用户信息、商品详情)聚合存储为一个 Hash,键为对象 ID,字段为属性名,简化键管理并减少内存碎片。
package com.example.redis.hash;/*** 描述: 将对象的多个属性(如用户信息、商品详情)聚合存储为一个 Hash,键为对象 ID,字段为属性名,简化键管理并减少内存碎片** @author ZHOUXIAOYUE* @date 2025/4/17 09:52*/ import redis.clients.jedis.Jedis; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Map; class User {private String id;private String name;private String age;private String email;private String phone;// 构造器、getter、setter 略public User(String id, String name, String age, String email, String phone) {this.id = id;this.name = name;this.age = age;this.email = email;this.phone = phone;}public String getId() { return id; }public String getName() { return name; }public String getAge() { return age; }public String getEmail() { return email; }public String getPhone() { return phone; } } public class RedisHashExample {public static void main(String[] args) throws Exception {//创建链接Jedis jedis = new Jedis("localhost", 6379);// 定义对象User user = new User("user:1001", "Alice", "30", "alice@example.com", "1234567890");// 使用 Jackson 将对象转换为 Map<String, String>ObjectMapper objectMapper = new ObjectMapper();Map<String, String> userMap = objectMapper.convertValue(user, new TypeReference<Map<String, String>>() {});// 从 Map 中移除 id 字段(如果不需要存储到 Hash 中)userMap.remove("id");// 存储到 Redis 中jedis.hmset(user.getId(), userMap);System.out.println("存储用户信息成功,查询结果为:");Map<String, String> storedUserInfo = jedis.hgetAll(user.getId());storedUserInfo.forEach((field, value) -> System.out.println(field + ": " + value));jedis.close();} }
-
-
部分更新与原子操作
-
支持单个字段的原子更新(如用户年龄修改),避免序列化整个对象。
package com.example.redis.hash;/*** 描述: 支持单个字段的原子更新(如用户年龄修改),避免序列化整个对象。** @author ZHOUXIAOYUE* @date 2025/4/17 10:12*/ import redis.clients.jedis.Jedis; import java.util.Map; import java.util.HashMap; public class RedisHashUpdateExample {public static void main(String[] args) {// 创建 Jedis 连接,连接到本地 Redis 服务Jedis jedis = new Jedis("localhost", 6379);// 假设已经存储了用户信息,键为 "user:1001"String userId = "user:1001";// 如果未事先存储用户数据,可以先初始化对象(仅供测试)if (!jedis.exists(userId)) {Map<String, String> userInfo = new HashMap<>();userInfo.put("name", "Alice");userInfo.put("age", "30");userInfo.put("email", "alice@example.com");userInfo.put("phone", "1234567890");jedis.hmset(userId, userInfo);System.out.println("初始化用户信息成功。");}// 查询更新前的年龄String oldAge = jedis.hget(userId, "age");System.out.println("更新前用户年龄: " + oldAge);// 对单个字段进行原子更新,这里更新年龄为 31jedis.hset(userId, "age", "31");// 查询更新后的年龄String newAge = jedis.hget(userId, "age");System.out.println("更新后用户年龄: " + newAge);// 关闭 Jedis 连接jedis.close();} }
-
-
计数器与统计
-
利用
HINCRBY 实现实时计数(如商品销量、页面访问量)。package com.example.redis.hash;/*** 描述: 利用 HINCRBY 实现实时计数(如商品销量、页面访问量)** @author ZHOUXIAOYUE* @date 2025/4/17 10:15*/ import redis.clients.jedis.Jedis; public class RedisCounterExample {public static void main(String[] args) {// 连接 Redis 服务器Jedis jedis = new Jedis("localhost", 6379);// 示例1:统计商品销量// 商品 ID 为 product:2001,对应的销量字段为 "sales"String productKey = "product:2001";// 初始化销量字段,注意如果该字段不存在,则 hincrby 会默认其值为 0// jedis.hset(productKey, "sales", "0");// 模拟一次商品销售,使用 HINCRBY 将销量加 1long salesCount = jedis.hincrBy(productKey, "sales", 1);System.out.println("商品 " + productKey + " 当前销量为:" + salesCount);// 示例2:统计页面访问量// 页面标识为 page:homepage,对应的访问量字段为 "views"String pageKey = "page:homepage";// 初始化访问量字段,若不存在则 hincrby 默认从 0 开始计数// jedis.hset(pageKey, "views", "0");// 模拟页面访问,使用 HINCRBY 将访问量加上 5(比如一次批量更新)long viewCount = jedis.hincrBy(pageKey, "views", 5);System.out.println("页面 " + pageKey + " 当前访问量为:" + viewCount);// 关闭 Jedis 连接jedis.close();} }
-
-
购物车实现
-
以用户 ID 为键,商品 ID 为字段,数量为值,便于动态增删商品。
package com.example.redis.hash;/*** 描述: 以用户 ID 为键,商品 ID 为字段,数量为值,便于动态增删商品。** @author ZHOUXIAOYUE* @date 2025/4/17 10:18*/ import redis.clients.jedis.Jedis; import java.util.Map; public class ShoppingCartDemo {public static void main(String[] args) {// 创建 Jedis 连接,连接到本地 Redis 服务,默认端口 6379Jedis jedis = new Jedis("localhost", 6379);// 以用户ID构建购物车的 key(建议加上 cart 前缀以示区分)String cartKey = "cart:user:1001";// -------------------------------// 示例1:添加商品到购物车// -------------------------------// 将商品 product:2001 添加至购物车,数量 2jedis.hset(cartKey, "product:2001", "2");System.out.println("添加商品 product:2001 数量 2 到购物车 " + cartKey);// 添加另一个商品 product:2002,数量 3jedis.hset(cartKey, "product:2002", "3");System.out.println("添加商品 product:2002 数量 3 到购物车 " + cartKey);printCart(jedis, cartKey);// -------------------------------// 示例2:动态增加已有商品的数量// -------------------------------// 将商品 product:2001 的数量原子性增加 1jedis.hincrBy(cartKey, "product:2001", 1);System.out.println("将商品 product:2001 的数量增加 1");printCart(jedis, cartKey);// -------------------------------// 示例3:删除商品// -------------------------------// 从购物车中删除商品 product:2002jedis.hdel(cartKey, "product:2002");System.out.println("从购物车中删除商品 product:2002");printCart(jedis, cartKey);// 关闭 Jedis 连接jedis.close();}// 打印购物车中所有商品信息private static void printCart(Jedis jedis, String cartKey) {System.out.println("购物车 " + cartKey + " 当前内容:");Map<String, String> cartItems = jedis.hgetAll(cartKey);if(cartItems.isEmpty()){System.out.println("购物车为空。");} else {cartItems.forEach((productId, quantity) ->System.out.println("商品ID:" + productId + ", 数量:" + quantity));}System.out.println("--------------------------------------------------");} }
-
-
分布式锁与缓存
-
通过
HSETNX 实现轻量级锁,或缓存计算结果减少重复计算。package com.example.redis.hash;/*** 描述: 通过 HSETNX 实现轻量级锁,或缓存计算结果减少重复计算* 连接 Redis 后,使用哈希 key "cache:calc" 保存缓存数据和锁信息。* 首先通过 hget 检查是否已经有计算结果存入缓存,如果存在则直接返回。* 如果未命中缓存,通过 HSETNX 尝试对字段 "lock" 加锁。如果返回 1,则表示当前线程获得锁,然后执行耗时计算,将结果存入 "result" 字段,最后释放锁(删除 "lock" 字段)。* 若 HSETNX 返回 0,则表示已有线程在计算,当前线程等待一段时间后轮询 "result" 字段,直到获取到已缓存的计算结果。\* @author ZHOUXIAOYUE* @date 2025/4/17 10:26*/ import redis.clients.jedis.Jedis; public class CacheLockExample {// 模拟一个耗时计算,例如求 1~1000000 的和private static long doExpensiveComputation() {long sum = 0;for (int i = 1; i <= 1_000_000; i++) {sum += i;}// 模拟延迟try {Thread.sleep(1000);} catch (InterruptedException e) {// 忽略异常处理}return sum;}public static void main(String[] args) {// 连接 Redis 服务Jedis jedis = new Jedis("localhost", 6379);// 使用哈希结构保存缓存与锁信息String hashKey = "cache:calc";String lockField = "lock";String resultField = "result";// 判断缓存中是否已有计算结果String cachedResult = jedis.hget(hashKey, resultField);if (cachedResult != null) {System.out.println("直接从缓存中获取结果: " + cachedResult);jedis.close();return;}// 尝试通过 HSETNX 获取轻量级锁(lockField 不存在时设置锁)long lockAcquired = jedis.hsetnx(hashKey, lockField, String.valueOf(System.currentTimeMillis()));if (lockAcquired == 1) {// 获取锁成功,执行耗时计算System.out.println("获取锁成功,开始计算...");long computedValue = doExpensiveComputation();// 将计算结果缓存到 resultField 中jedis.hset(hashKey, resultField, String.valueOf(computedValue));// 释放锁(删除 lockField)jedis.hdel(hashKey, lockField);System.out.println("计算完成并缓存结果: " + computedValue);} else {// 获取锁失败,其他线程正在计算,等待缓存结果System.out.println("其他线程正在计算,等待获取结果...");int maxWaitTime = 10; // 最长等待时间(单位:循环次数,每次 100 毫秒)int waited = 0;while (waited < maxWaitTime) {try {Thread.sleep(100); // 每次等待100毫秒} catch (InterruptedException e) {// 忽略异常}cachedResult = jedis.hget(hashKey, resultField);if (cachedResult != null) {System.out.println("等待期间缓存中获取结果: " + cachedResult);break;}waited++;}if (cachedResult == null) {System.out.println("等待超时,还未获取到计算结果。");}}jedis.close();} }
-
总结
Redis Hash 通过灵活的字段操作、高效的内存管理和多样化的应用场景,成为存储结构化数据的理想选择。
相关文章:
Redis Hash 介绍
Redis Hash 介绍 从基础命令、内部编码和使用场景三个维度分析如下: 一、基础命令 Redis Hash 提供了丰富的操作命令,适用于字段(field)级别的增删改查: 设置与修改 HSET:设置单个字段值(HSET…...
[redis进阶一]redis的持久化(2)AOF篇章
目录 一 为什么有了RDB持久化机制还要有AOF呢 板书介绍具体原因: 编辑二 详细讲解AOF机制 (1)AOF的基本使用 1)板书如下 2)开启AOF机制: 3) AOF工作流程 (2)AOF是否会影响到redis性能 编辑 (3)AOF缓冲区刷新策略 (4)AOF的重写机制 板书如下: 为什么要有这个重写机…...
【Linux我做主】探秘gcc/g++和动静态库
TOC Linux编译器gcc/g的使用 github地址 有梦想的电信狗 前言 在软件开发的世界中,编译器如同匠人的工具,将人类可读的代码转化为机器执行的指令。 对于Linux开发者而言,gcc和g是构建C/C程序的核心工具链,掌握它们的原理和使…...
Linux `init 0` 相关命令的完整使用指南
Linux init 0 相关命令的完整使用指南—目录 一、init 系统简介二、init 0 的含义与作用三、不同 Init 系统下的 init 0 行为1. SysVinit(如 CentOS 6、Debian 7)2. systemd(如 CentOS 7、Ubuntu 16.04)3. Upstart(如 …...
【英语语法】基本句型
目录 前言一:主谓二:主谓宾三:主系表四:主谓双宾五:主谓宾补 前言 英语基本句型是语法体系的基石,以下是英语五大基本句型。 一:主谓 结构:主语 不及物动词 例句: T…...
Vue3中发送请求时,如何解决重复请求发送问题?
文章目录 前言一、问题演示二、使用步骤1.One组件2.Two组件封装工具函数处理请求 总结 前言 在开发过程中,重复请求发送问题可能会导致数据不一致、服务器压力增加或用户操作异常。以下是解决重复请求问题的常见方法和最佳实践: 一、问题演示 我们看着…...
信息学奥赛一本通 1622:Goldbach’s Conjecture | 洛谷 UVA543 Goldbach‘s Conjecture
【题目链接】 ybt 1622:Goldbach’s Conjecture 洛谷 UVA543 Goldbach’s Conjecture 【题目考点】 1. 筛法求质数表 埃筛线性筛(欧拉筛) 知识点讲解见信息学奥赛一本通 2040:【例5.7】筛选法找质数 【解题思路】 首先使用埃…...
在极狐GitLab 身份验证中如何使用 OIDC?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 使用 OpenID Connect 作为认证提供者 (BASIC SELF) 您可以使用极狐GitLab 作为客户端应用程序,与 OpenID Connec…...
计算机视觉与深度学习 | 基于YOLOv8与光流法的目标检测与跟踪(Python代码)
===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 目标检测与跟踪 关键实现逻辑检测-跟踪协作机制特征点选择策略运动…...
解决 VSCode 中 NVM 配置后无法识别 Node 和 NPM 的问题
在开发中,我们经常需要使用 Node.js 和 NPM 来管理 JavaScript 项目依赖,而 NVM(Node Version Manager)是开发者在本地环境中管理多个 Node.js 版本的得力工具。不过,有时候在 VSCode 中配置完 NVM 后,可能…...
观察者模式:从博客订阅到消息队列的解耦实践
观察者模式:从博客订阅到消息队列的解耦实践 一、模式核心:用事件驱动实现对象间松耦合 在新闻 APP 中,当热点事件发生时需要实时通知所有订阅用户;在电商系统中,库存变化需触发价格监控模块重新计算。这类场景的核心…...
ReportLab 导出 PDF(页面布局)
ReportLab 导出 PDF(文档创建) ReportLab 导出 PDF(页面布局) ReportLab 导出 PDF(图文表格) PLATYPUS - 页面布局和排版 1. 设计目标2. 开始3. Flowables3.1. Flowable.draw()3.2. Flowable.drawOn(canvas,x,y)3.3. F…...
qt与html通信
**Cef视图(CefView)**是指在使用Chromium Embedded Framework(CEF)时,嵌入到应用程序中的浏览器视图。CEF是一个开源项目,它基于Google的Chromium浏览器,允许开发者将Web浏览器功能嵌入到自己的…...
git 根据http url设置账号密码
1. 原因 场景:有一种情况,比如在github上面有多个账号,并且每个账号都有些仓库的内容需要修改,并且这些账号自己,不是协作者的关系。这个时候需要针对每个仓库的url设置用户名密码, 2. 设置 2.1 第一步:…...
【CVE-2024-10929】ARM CPU漏洞安全通告
安全之安全(security)博客目录导读 目录 一、概述 二、CVE详情 三、受影响产品 四、建议措施 五、致谢 六、版本历史 一、概述 在部分基于Arm架构的CPU中发现了一个潜在安全问题,称为Spectre-BSE(Branch Status Eviction,分支状态驱逐…...
OpenCV 图形API(33)图像滤波-----高斯模糊函数gaussianBlur()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 使用高斯滤波器对图像进行模糊处理。 该函数使用指定的高斯核对源图像进行滤波。输出图像必须与输入图像具有相同的类型和通道数。 cv::gapi::g…...
【Android】 如何将 APK 内置为系统应用(适用于编辑设置属性)
如何将 APK 内置为系统应用(适用于编辑设置属性) 在 Android 中,将 APK 文件内置为系统应用涉及到一系列的命令和步骤。以下是详细的操作流程,帮助您解决常见问题,如 /system not in /proc/mounts 的错误。 挂载system/app获取可读写权限 …...
【2025最新版】火鸟门户v8.5系统源码+PC、H5、小程序 +数据化大屏插件
一.介绍 火鸟地方门户系统V8.5源码 系统包含4端: PCH5小程序APP 二.搭建环境 系统环境:CentOS、 运行环境:宝塔 Linux 网站环境:Nginx 1.2.22 MySQL 5.6 PHP-7.4 常见插件:fileinfo ; redis 三.测…...
关于 传感器 的详细解析,涵盖定义、分类、工作原理、常见类型、应用领域、技术挑战及未来趋势,结合实例帮助理解其核心概念
以下是关于 传感器 的详细解析,涵盖定义、分类、工作原理、常见类型、应用领域、技术挑战及未来趋势,结合实例帮助理解其核心概念: 一、传感器的定义与核心功能 1. 定义 传感器(Sensor)是一种能够将物理量ÿ…...
EtherCAT转ProfiNet边缘计算网关配置优化:汽车制造场景下PLC与机器人协同作业案例
1.行业背景与需求分析 智能汽车焊装车间是汽车制造的核心工艺环节,某德国豪华品牌在其上海MEB工厂新建的焊装车间中,采用西门子S7-1500PLC作为ProfiNet主站,负责整线协调与质量追溯;同时部署KUKAKR1500Titan机器人(Eth…...
极狐GitLab CI/CD 流水线计算分钟数如何管理?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 计算分钟管理 (PREMIUM SELF) 在极狐GitLab 16.1 中,从 CI/CD 分钟数重命名为计算配额或计算分钟数。 管理员可…...
HTTP协议 --- 超文本传输协议 和 TCP --- 传输控制协议
是基于 TCP 协议的 80 端口的一种 C/S 架构协议。 特点:无状态 --- 数据传输完成后,会断开 TCP 连接,哪怕浏览器还正常运行。 请求报文 --- 方法 响应报文 --- 状态码 是一种面向连接的可靠传输协议 。 面向连接 --- 在传输数据之前&am…...
类和对象(下篇)(详解)
【本节目标】 1. 再谈构造函数 2. Static成员 3. 友元 4. 内部类 5. 再次理解封装 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。 #include <iostream> using name…...
Uniapp:获取当前定位坐标
目录 一、出现场景二、具体使用 一、出现场景 在项目的开发中,会出现打卡、定位当前位置的功能,那我们如何获取当前位置呢?这就需要使用getLocation来获取当前位置坐标 二、具体使用 uni.getLocation({type: wgs84, // 返回可以用于uni.op…...
最大子序和问题——动态规划/贪心算法解决
目录 一:问题描述 二:解决思路1——动态规划思想 三:C 语言代码实现 四:复杂度分析 五:解决思路2——贪心算法思想 六:具体步骤 七: C语言代码实现 八:复杂度分析 一:问题描述 …...
【Unity】JSON数据的存取
这段代码的结构是为了实现 数据的封装和管理,特别是在 Unity 中保存和加载玩家数据时。以下是对代码设计的逐步解释: 1. PlayerCoin 类 PlayerCoin 是一个简单的数据类,用于表示单个玩家的硬币信息。它包含以下字段: count&…...
LeetCode【剑指offer】系列(位运算篇)
剑指offer15.二进制中1的个数 题目链接 题目:编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为 汉明重量).)。 思路一ÿ…...
unity socket 客户端和c#服务器通信
服务器 using BarrageGrab; using System; using System.Collections.Concurrent; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading;namespace Lyx {class Server{private TcpListener listener;private Concurre…...
如何在Vue中实现取消聚焦el-select——从零到部署的完整指南
如何在Vue中实现取消聚焦el-select——从零到部署的完整指南 在开发Vue项目时,经常会遇到需要处理用户交互和组件状态管理的情况。特别是在使用Element UI组件库时,如何优雅地管理组件的状态显得尤为重要。本文将详细介绍如何在取消对话框时自动取消el-s…...
网络安全领域的AI战略准备:从概念到实践
网络安全领域的AI准备不仅涉及最新工具和技术的应用,更是一项战略必需。许多企业若因目标不明确、数据准备不足或与业务重点脱节而未能有效利用AI技术,可能面临严重后果,包括高级网络威胁数量的激增。 AI准备的核心要素 构建稳健的网络安全…...
