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

【Redis】深入探索 Redis 的数据类型 —— 哈希表 hash

文章目录

  • 前言
  • 一、hash 类型相关命令
    • 1.1 HSET 和 HSETNX
    • 1.2 HGET 和 HMGET
    • 1.3 HKEYS、HVALS 和 HGETALL
    • 1.4 HEXISTS 和 HDEL
    • 1.5 HLEN
    • 1.6 HINCRBY 和 HINCRBYFLOAT
    • 1.7 哈希相关命令总结
  • 二、hash 类型内部编码
  • 三、hash 类型的应用场景
  • 四、原生,序列化,哈希类型缓存方式对比
    • 4.1 原生字符串类型
    • 4.2 序列化字符串类型(例如JSON格式)
    • 4.3 哈希类型
    • 4.4 总结


前言

在构建和优化应用程序时,数据缓存是提高性能和降低数据库负载的关键策略之一。Redis(Remote Dictionary Server)是一个高性能的内存数据库,广泛用于数据缓存和快速数据访问。其中,哈希类型(Hash)是 Redis 中的一种强大数据结构,通常用于存储对象、映射关系和键值对等数据。

在本文中,我们将深入探讨Redis中的哈希类型。我们将从哈希类型的基本命令入手,逐步介绍它们的使用方法、内部编码方式以及在实际应用场景中的应用。通过学习和理解 Redis 哈希类型,可以帮助我们够更好地利用 Redis 来优化数据存储和访问,提高应用程序的性能。

接下来,让我们深入了解 Redis 哈希类型的相关内容。

一、hash 类型相关命令

1.1 HSET 和 HSETNX

  1. HSET
  • 作用 : 指定的哈希表中设置字段的值,如果字段存在则更新,否则创建。并且可以同时设置多组字段。

  • 语法:

    HSET key field value [field value ... ]
    
  1. HSETNX
  • 作用:仅在字段不存在时,在指定的哈希表中设置字段的值。设置成功返回 1,否则返回 0。
  • 语法:
    HSETNX key field value 
    
  1. 使用示例

1.2 HGET 和 HMGET

  1. HGET
  • 作用:获取指定哈希表中字段的值。
  • 语法:
    HGET key field
    
  1. HMGET
  • 作用:是获取指定哈希表中多个字段的值。
  • 语法:
    HMGET key field1 [field2 ...]
    
  1. 使用示例

当然,我会继续完善下面的部分,以涵盖哈希类型相关命令的详细说明:

1.3 HKEYS、HVALS 和 HGETALL

  1. HKEYS
  • 作用:获取指定哈希表中所有字段的名称。
  • 语法
    HKEYS key
    
  1. HVALS
  • 作用:获取指定哈希表中所有字段的值。
  • 语法
    HVALS key
    
  1. HGETALL
  • 作用:获取指定哈希表中所有字段和对应的值。
  • 语法
    HGETALL key
    
  1. 使用案例

1.4 HEXISTS 和 HDEL

  1. HEXISTS
  • 作用:检查指定哈希表中是否存在某个字段。
  • 语法
    HEXISTS key field
    
  1. HDEL
  • 作用:删除指定哈希表中的一个或多个字段。
  • 语法
    HDEL key field1 [field2 ...]
    
  1. 使用案例

1.5 HLEN

  1. HLEN
  • 作用:获取指定哈希表中字段的数量(即哈希表的大小)。
  • 语法
    HLEN key
    
  1. 使用案例

1.6 HINCRBY 和 HINCRBYFLOAT

  1. HINCRBY
  • 作用:将哈希表中指定字段的值增加一个整数。
  • 语法
    HINCRBY key field increment
    
  1. HINCRBYFLOAT
  • 作用:将哈希表中指定字段的值增加一个浮点数。
  • 语法
    HINCRBYFLOAT key field increment
    
  1. 使用案例

1.7 哈希相关命令总结

以下是哈希类型相关命令的总结,包括命令、作用和时间复杂度:

命令作用时间复杂度
HSET在哈希表中设置字段的值,存在则更新,否则创建。可同时设置多组字段。O(1)
HSETNX仅在字段不存在时,在哈希表中设置字段的值,成功返回1,否则返回0。O(1)
HGET获取指定哈希表中字段的值。O(1)
HMGET获取指定哈希表中多个字段的值。O(N),N为字段数
HKEYS获取指定哈希表中所有字段的名称。O(N),N为字段数
HVALS获取指定哈希表中所有字段的值。O(N),N为字段数
HGETALL获取指定哈希表中所有字段和对应的值。O(N),N为字段数
HEXISTS检查指定哈希表中是否存在某个字段。O(1)
HDEL删除指定哈希表中的一个或多个字段。O(N),N为被删除的字段数
HLEN获取指定哈希表中字段的数量(即哈希表的大小)。O(1)
HINCRBY将哈希表中指定字段的值增加一个整数。O(1)
HINCRBYFLOAT将哈希表中指定字段的值增加一个浮点数。O(1)

二、hash 类型内部编码

Redis 是一种高性能的内存数据库,支持多种数据结构,包括哈希(Hash)。在 Redis 中,哈希数据类型有两种内部编码方式,分别是 ziplist(压缩列表)和 hashtable(哈希表)。这两种编码方式的选择取决于哈希的大小和存储特性。

1. ziplist(压缩列表):

ziplist 是 Redis 中用于内部编码较小哈希的紧凑数据结构。以下是一些关于 ziplist 的关键特性:

  • 当哈希类型的元素个数相对较少,且所有字段和对应的值都满足一定的限制条件时,Redis 会使用 ziplist 作为哈希的内部实现。
  • 默认情况下,Redis 会选择 ziplist。具体来说,如果哈希的元素个数不超过 512 个,并且所有值都小于 64 字节,那么 ziplist 就是首选的编码方式。
  • Ziplist 是一种紧凑的数据结构,它能够在节省内存方面表现得比 hashtable 更出色。它将多个哈希元素连续存储在一起,有效地减少了内存占用。

2. hashtable(哈希表):

hashtable 是 Redis 中用于存储大规模哈希数据的内部编码方式。以下是 hashtable 的关键特性:

  • 当哈希类型的元素个数超过了 ziplist 的配置限制,或者有字段对应的值大于 64 字节时,Redis 会将内部编码切换为 hashtable。
  • Hashtable 是一种散列表数据结构,它具有 O(1) 的读写时间复杂度,适用于大规模的哈希数据集。
  • 切换到 hashtable 可以提供更好的性能和内存管理,特别是在处理大型哈希或包含大值的情况下。

根据上述描述,下面是一些示例演示哈希数据类型的内部编码以及在何种条件下会发生编码转换:

示例 1:使用 ziplist 编码

> hmset hashkey f1 v1 f2 v2
OK
> object encoding hashkey
"ziplist"

在此示例中,由于字段数较少且值满足条件,Redis 使用 ziplist 作为内部编码。

示例 2:切换到 hashtable 编码

> hset hashkey f3 "one string is bigger than 64 bytes ..." 1
OK
> object encoding hashkey
"hashtable"

在此示例中,因为有一个字段对应的值大于 64 字节,Redis 将内部编码切换为 hashtable。

示例 3:切换到 hashtable 编码

> hmset hashkey f1 v1 h2 v2 f3 v3 ... (超过 512 个字段) ...
OK
> object encoding hashkey
"hashtable"

在此示例中,由于字段数超过了 512 个,Redis 将内部编码转换为 hashtable。

这些内部编码方式的选择是为了在不同情况下平衡内存占用和性能。Redis 会根据需要自动进行这些编码转换,以优化存储和操作效率。无论您的哈希数据集大小如何,Redis 都会根据配置和数据特性智能地选择适当的内部编码方式。这种自动优化确保了 Redis 在各种工作负载下的出色性能表现。

三、hash 类型的应用场景

在本部分,我们将探讨哈希类型在应用程序中的实际应用场景。首先,让我们回顾一下关系型数据库中保存用户信息的结构。

关系型数据表保存用户信息

上图展示了关系型数据表记录的两条用户信息,其中用户的属性表现为表的列,每条用户信息则表现为行。如果我们想在 Redis 中映射这两个用户信息,可以使用哈希类型。

使用哈希类型映射用户信息:

映射关系表示用户信息

相比于使用 JSON 格式的字符串缓存用户信息,哈希类型更加直观,并且在更新操作上更加灵活。我们可以将每个用户的 ID 定义为键的后缀,然后使用多个 field-value 对应用户的各个属性,类似以下伪代码:

UserInfo getUserInfo(long uid) {// 根据 uid 得到 Redis 的键String key = "user:" + uid;// 尝试从 Redis 中获取对应的值userInfoMap = Redis 执行命令:hgetall key;// 如果缓存命中(hit)if (userInfoMap != null) {// 将映射关系还原为对象形式UserInfo userInfo = 利用映射关系构建对象(userInfoMap);return userInfo;}// 如果缓存未命中(miss)// 从数据库中,根据 uid 获取用户信息UserInfo userInfo = MySQL 执行 SQL:select * from user_info where uid = <uid>;// 如果表中没有 uid 对应的用户信息if (userInfo == null) {响应 404;return null;}// 将缓存以哈希类型保存Redis 执行命令:hmset key name userInfo.name age userInfo.age city userInfo.city;// 写入缓存,为了防止数据腐烂(rot),设置过期时间为 1 小时(3600 秒)Redis 执行命令:expire key 3600;// 返回用户信息return userInfo;
}

上述代码演示了一个常见的缓存策略,首先尝试从 Redis 缓存中获取数据,如果未命中则从数据库中检索,并将结果存储到 Redis 中以便后续访问。这种策略可以提高访问性能并减轻数据库负担。

然而,需要注意的是哈希类型和关系型数据库存在两个主要差异:

  • 哈希类型的稀疏性: 哈希类型允许每个键具有不同的 field,而关系型数据库在添加新的列时需要为所有行设置值,即使是 null。

  • 复杂关系查询的不适用性: 关系型数据库支持复杂的关系查询,而 Redis 不适用于模拟关系型复杂查询,例如联表查询和聚合查询,维护成本较高。

关系型数据库的稀疏性示例:

关系型数据库稀疏性

通过哈希类型,我们可以更直观地映射和存储用户信息,适应不同应用场景的需求。哈希类型的使用方式简单、直观、灵活,特别适合局部属性的变更和查询操作,同时也具有较好的内存效率。

四、原生,序列化,哈希类型缓存方式对比

当涉及到缓存用户信息时,有多种不同的缓存方式可供选择。以下是对三种常见的缓存方式进行详细比较和分析:原生字符串类型、序列化字符串类型(例如JSON格式),以及哈希类型。这里探讨它们的实现方法、优点和缺点,以帮助您更好地选择适用于您应用程序的缓存策略。

4.1 原生字符串类型

实现方法: 使用原生字符串类型,将每个用户属性存储为单独的键值对,例如:

set user:1:name James
set user:1:age 23
set user:1:city Beijing

优点:

  • 实现简单,每个属性都以单独的键存储,易于理解和维护。
  • 针对个别属性变更很灵活。

缺点:

  • 占用过多的键,导致内存占用量较大。
  • 用户信息在Redis中分散存储,缺少内聚性,不便于批量操作和管理。
  • 不适用于需要一次性获取完整用户信息的情况,需要大量的键操作。

适用场景: 这种方式适合于需要对用户属性进行个别、频繁变更的场景,但不适用于需要一次性获取完整用户信息的情况。

4.2 序列化字符串类型(例如JSON格式)

实现方法: 使用序列化字符串类型,将用户信息以JSON格式等方式序列化后存储为一个键值对,例如:

set user:1 {"name": "James", "age": 23, "city": "Beijing"}

优点:

  • 适用于以整体作为操作单元的信息存储,编程较为简单。
  • 可以高效地使用内存,特别适合存储大对象或数据结构。

缺点:

  • 序列化和反序列化需要一定开销。
  • 不适合频繁进行个别属性的更新或查询,缺乏灵活性。

适用场景: 这种方式适用于需要一次性获取完整用户信息的场景,特别是当用户信息是复杂对象或数据结构时。

4.3 哈希类型

实现方法: 使用哈希类型,将用户信息存储为Redis的哈希类型,例如:

hmset user:1 name James age 23 city Beijing

优点:

  • 简单、直观、灵活。
  • 适用于信息的局部变更或获取操作,支持对单个属性的读写。
  • 内部编码可以是 ziplist 或 hashtable,具有较好的灵活性和内存效率。

缺点:

  • 需要控制哈希在 ziplist 和 hashtable 两种内部编码之间的转换,可能会带来内存消耗。
  • 不适合需要一次性获取完整用户信息的情况,可能需要多次读取。

适用场景: 哈希类型适用于需要对用户属性进行局部变更或频繁单独属性操作的场景,也适合需要对属性进行灵活查询的情况。

4.4 总结

选择合适的缓存方式应根据具体的应用需求和访问模式来确定。通常情况下,可以根据不同的数据特点和操作需求,综合考虑这三种缓存方式,并在应用程序中进行适当的组合和使用,以获得最佳性能和灵活性。

例如,可以使用哈希类型缓存来处理局部属性的变更和查询,同时使用序列化字符串类型缓存来获取完整用户信息。这样,可以充分发挥Redis的优势,提高数据访问的效率,同时保持灵活性和可维性。

相关文章:

【Redis】深入探索 Redis 的数据类型 —— 哈希表 hash

文章目录 前言一、hash 类型相关命令1.1 HSET 和 HSETNX1.2 HGET 和 HMGET1.3 HKEYS、HVALS 和 HGETALL1.4 HEXISTS 和 HDEL1.5 HLEN1.6 HINCRBY 和 HINCRBYFLOAT1.7 哈希相关命令总结 二、hash 类型内部编码三、hash 类型的应用场景四、原生&#xff0c;序列化&#xff0c;哈希…...

网络安全应急响应典型案例-(DDOS类、僵尸网络类、数据泄露类)

一、DDOS类事件典型案例 DDOS攻击&#xff0c;即分布式拒绝服务攻击&#xff0c;其目的在于使目标电脑的网络或系统资源耗尽&#xff0c;使服务暂时中断或停止&#xff0c;导致其正常用户无法访问。CC攻击使用代理服务器向受害服务器发送大量貌似合法的请求&#xff08;通常…...

【测试开发】Mq消息重复如何测试?

本篇文章主要讲述重复消费的原因&#xff0c;以及如何去测试这个场景&#xff0c;最后也会告诉大家&#xff0c;目前互联网项目关于如何避免重复消费的解决方案。 Mq为什么会有重复消费的问题? Mq 常见的缺点之一就是消息重复消费问题&#xff0c;产生这种问题的原因是什么呢…...

C++和C#程序语言的区别

一直学习C++和C#,两者之间的区别总结一下 目录 一、两种语言概述 C++语言 C#语言 二、两种语言对比 2.1运行依赖...

CentOS配置Java环境报错-bash: /usr/local/jdk1.8.0_381/bin/java: 无法执行二进制文件

CentOS配置Java环境后执行java -version时报错&#xff1a; -bash: /usr/local/jdk1.8.0_381/bin/java: 无法执行二进制文件原因是所使用的jdk的版本和Linux内核架构匹配不上 使用以下命令查看Linux架构&#xff1a; [rootlocalhost ~]# cat /proc/version Linux version 3.1…...

MySQL进阶 —— 超详细操作演示!!!(上)

MySQL进阶 —— 超详细操作演示&#xff01;&#xff01;&#xff01;&#xff08;上&#xff09; 一、存储引擎1.1 MySQL 体系结构1.2 存储引擎介绍1.3 存储引擎特点1.4 存储引擎选择 二、索引2.1 索引概述2.2 索引结构2.3 索引分类2.4 索引语法2.5 SQL 性能分析2.6 索引使用2…...

一条爬虫抓取一个小网站所有数据

一条爬虫抓取一个小网站所有数据 ​ 今天闲来无事&#xff0c;写一个爬虫来玩玩。在网上冲浪的时候发现了一个搞笑的段子网&#xff0c;发现里面的内容还是比较有意思的&#xff0c;于是心血来潮&#xff0c;就想着能不能写一个Python程序&#xff0c;抓取几条数据下来看看&am…...

八大排序——快速排序

Hello&#xff0c;大家好&#xff0c;今天分享的八大排序里的快速排序&#xff0c;所谓快速排序是一个叫霍尔的人发明&#xff0c;有很多人可能会觉得为什么不叫霍尔排序&#xff0c;其中原因就是因为它快&#xff0c;快速则体现了它的特点&#xff0c;今天我们就来讲一下快速排…...

【ES】笔记-Class类剖析

Class Class介绍与初体验ES5 通过构造函数实例化对象ES6 通过Class中的constructor实列化对象 Class 静态成员实例对象与函数对象的属性不相通实例对象与函数对象原型上的属性是相通的Class中对于static 标注的对象和方法不属于实列对象&#xff0c;属于类。 ES5构造函数继承Cl…...

数学建模--Seaborn库绘图基础的Python实现

目录 1.绘图数据导入 2. sns.scatterplot绘制散点图 3.sns.barplot绘制条形图 4.sns.lineplot绘制线性图 5.sns.heatmap绘制热力图 6.sns.distplot绘制直方图 7.sns.pairplot绘制散图 8.sns.catplot绘制直方图 9.sns.countplot绘制直方图 10.sns.lmplot绘回归图 1.绘图数…...

lv3 嵌入式开发-2 linux软件包管理

目录 1 软件包管理 1.1流行的软件包管理机制 1.2软件包的类型 1.3软件包的命名 2 在线软件包管理 2.1APT工作原理 2.2更新软件源 2.3APT相关命令 3 离线软件包管理 1 软件包管理 1.1流行的软件包管理机制 Debian Linux首先提出“软件包”的管理机制---Deb软件包 …...

智能小区与无线网络技术

1&#xff0e;1 智能小区 智能小区指的是具有小区智能化系统的小区。所谓小区智能化系统&#xff0c;指的是在 现代计算机网络和通信技术的基础上&#xff0c;将传统的土木建筑技术与计算机技术、自动 控制技术、通信与信息处理技术、多媒体技术等先进技术相结合的自动化和综…...

如何传输文件流给前端

通过链接下载图片&#xff0c;直接http请求然后将文件流返回 注&#xff1a;music.ly是一个下载tiktok视频的免费接口 https://api19-core-c-useast1a.musical.ly/aweme/v1/feed/?aweme_idxxx func (m *FileBiz) DownloadFileV2(ctx *ctrl.Context, fileLink, fileName strin…...

Spring Security OAuth2 远程命令执行漏洞

文章目录 一、搭建环境二、漏洞验证三、准备payload四、执行payload五、变形payload 一、搭建环境 cd vulhub/spring/CVE-2016-4977/ docker-compose up -d 二、漏洞验证 访问 http://192.168.10.171:8080/oauth/authorize?response_type${233*233}&client_idacme&s…...

Python之并发编程介绍

一、并发编程介绍 1.1、串行、并行与并发的区别 串行(serial)&#xff1a;一个CPU上&#xff0c;按顺序完成多个任务并行(parallelism)&#xff1a;指的是任务数小于等于cpu核数&#xff0c;即任务真的是一起执行的并发(concurrency)&#xff1a;一个CPU采用时间片管理方式&am…...

GO语言网络编程(并发编程)并发介绍,Goroutine

GO语言网络编程&#xff08;并发编程&#xff09;并发介绍&#xff0c;Goroutine 1、并发介绍 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。 B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更…...

英语连词总结

前言 总结一些常用的英语连词&#xff0c;以下用法只是我希望我自己这么用。分类我可能分的不好&#xff0c;慢慢积累&#xff0c;慢慢改进。 1&#xff09;表递进: firstly、secondly、thirdly、finally、af first、at the beginning、in the end、to begin with&#xff0…...

LeetCode 92. Reverse Linked List II【链表,头插法】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

【图论】Floyd

算法提高课笔记&#xff09; 文章目录 例题牛的旅行题意思路代码 排序题意思路代码 观光之旅题意思路代码 例题 牛的旅行 原题链接 农民John的农场里有很多牧区&#xff0c;有的路径连接一些特定的牧区。 一片所有连通的牧区称为一个牧场。 但是就目前而言&#xff0c;你…...

SpringCloudAlibaba Gateway(三)-整合Sentinel功能路由维度、API维度进行流控

Gateway整合Sentinel ​ 前面使用过Sentinel组件对服务提供者、服务消费者进行流控、限流等操作。除此之外&#xff0c;Sentinel还支持对Gateway、Zuul等主流网关进行限流。 ​ 自sentinel1.6.0版开始&#xff0c;Sentinel提供了Gateway的适配模块&#xff0c;能针对路由(rou…...

Qwen3-14B-Int4-AWQ助力运维智能化:日志分析与故障排查实战

Qwen3-14B-Int4-AWQ助力运维智能化&#xff1a;日志分析与故障排查实战 1. 运维工程师的日常痛点 凌晨三点&#xff0c;你的手机突然响起。系统告警显示某核心服务出现异常&#xff0c;你需要立即登录服务器查看日志。面对几十GB的日志文件&#xff0c;你不得不用grep、awk等…...

uniapp圆环进度条组件实战:从零到一打造个性化数据展示

Uniapp圆环进度条组件实战&#xff1a;从零到一打造个性化数据展示 在移动应用开发中&#xff0c;数据可视化是提升用户体验的关键因素之一。圆环进度条作为一种直观的数据展示方式&#xff0c;广泛应用于健身追踪、学习进度、任务完成度等场景。Uniapp作为跨平台开发框架&…...

如何让扫描PDF变得可搜索?OCRmyPDF-Desktop完整解决方案

如何让扫描PDF变得可搜索&#xff1f;OCRmyPDF-Desktop完整解决方案 【免费下载链接】pdfocr-desktop PDF OCR Application, adds an OCR text layer to scanned PDF files, allowing them to be copied and searched. 项目地址: https://gitcode.com/gh_mirrors/oc/pdfocr-d…...

把Camunda流程引擎当SaaS用?多租户与外部任务实战指南(基于RuoYi改造)

基于Camunda构建企业级流程中心的架构设计与实战 在数字化转型浪潮中&#xff0c;业务流程自动化已成为企业提升运营效率的核心手段。当一家企业同时运行CRM、OA、ERP等多个业务系统时&#xff0c;每个系统都需要工作流支持&#xff0c;但为每个系统单独部署和维护Camunda引擎显…...

别再纠结模型了!用Python+Simulink快速搭建四旋翼无人机仿真(附完整代码)

用PythonSimulink快速搭建四旋翼无人机仿真实战指南 四旋翼无人机开发中最令人头疼的环节&#xff0c;往往不是控制算法设计&#xff0c;而是如何快速搭建一个可靠的仿真环境。我曾见过不少团队在模型选择上耗费数周时间&#xff0c;最终却陷入理论完美主义陷阱——他们反复纠结…...

Mermaid:文本驱动的可视化引擎深度指南

Mermaid&#xff1a;文本驱动的可视化引擎深度指南 【免费下载链接】mermaid mermaid-js/mermaid: 是一个用于生成图表和流程图的 Markdown 渲染器&#xff0c;支持多种图表类型和丰富的样式。适合对 Markdown、图表和流程图以及想要使用 Markdown 绘制图表和流程图的开发者。 …...

收藏!2026非科班/转行小白必看:3步切入AI大模型,月薪30w+实战路径

2026年的职场赛道&#xff0c;AI大模型依旧是绝对的“黄金风口”。 最新行业报告显示&#xff0c;AI相关岗位需求逆势增长37%&#xff0c;薪资领跑全行业&#xff0c;大厂校招起薪普遍突破25k。但一个残酷的现实是&#xff1a; 太多非科班、半路转行的程序员&#xff0c;还在门…...

OpenClaw多模态扩展:为nanobot添加图像识别能力

OpenClaw多模态扩展&#xff1a;为nanobot添加图像识别能力 1. 为什么需要图像识别能力 去年夏天&#xff0c;我接手了一个自动化内容审核的小项目。最初只是用OpenClaw处理文本内容&#xff0c;但很快发现一个致命缺陷——当需要审核带图片的帖子时&#xff0c;我的机器人就…...

科哥CAM++镜像入门指南:快速搭建中文语音识别系统

CAM镜像入门指南&#xff1a;快速搭建中文语音识别系统 1. 系统概述 CAM说话人识别系统是一个基于深度学习的声纹识别工具&#xff0c;由科哥封装为易用的Docker镜像。它能快速判断两段语音是否来自同一说话人&#xff0c;并提取语音特征向量&#xff0c;适用于身份验证、语音…...

智慧交通落地难题:为什么80%的智能信号灯项目效果不达预期?

智慧交通落地困境&#xff1a;从技术神话到现实瓶颈的深度解构 清晨7点30分&#xff0c;北京东三环的某个十字路口&#xff0c;20名交警正在手动调节信号灯——这个造价480万元的智能信号系统在早高峰时段被完全弃用。类似的场景正在全国至少17个城市重复上演&#xff0c;某头部…...