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

redis中的hash

Redis中的hash是什么

Hash: 哈希,也叫散列,是一种通过哈希函数将键映射到表中位置的数据结构,哈希函数是关键,它把键转换成索引。

Redis Hash(散列表)是一种 field-value pairs(键值对)集合类型,类似于 Python 中的字典、Java 中的 HashMap。一个 field 对应一个value.

Hash冲突:两个不同的key可能会映射到同一个位置去,这种问题我们叫做哈希冲突,或者哈希碰撞
Hash冲突解决方法:主要有两种两种方法,开放定址法和链地址法。

开放定址法 :
在开放定址法中所有的元素都放到哈希表里,当一个关键字key用哈希函数计算出的位置冲突了,则按照某种规则找到一个没有存储数据
的位置进行存储。这里的规则有三种:线性探测、二次探测、双重探测。

链地址法:
开放定址法中所有的元素都放到哈希表里,链地址法中所有的数据不再直接存储在哈希表中,哈希表中存储一个指针,没有数据映射这个位置时,这个指针为空,有多个数据映射到这个位置时,我们把这些冲突的数据链接成一个链表,挂在哈希表这个位置下面,链地址法也叫做拉链法或者哈希桶。
在这里插入图片描述

Redis 的散列表 dict 由数组 + 链表构成,数组的每个元素占用的槽位叫做哈希桶,当出现散列冲突的时候就会在这个桶下挂一个链表,用“拉链法”解决散列冲突的问题。
简单地说就是将一个 key 经过散列计算均匀的映射到散列表上。
在这里插入图片描述

Hash数据类型底层存储数据结构实际上有两种。
1.dict结构。
2.在7.0版本之前使用ziplist,之后被listpack代替。

什么是listPack

Redis 在 5.0 新设计一个数据结构叫 listpack,目的是替代压缩列表,它最大特点是 listpack 中每个节点不再包含前一个节点的长度了,压缩列表每个节点正因为需要保存前一个节点的长度字段,就会有连锁更新的隐患.

listpack 也叫紧凑列表,它的特点就是用一块连续的内存空间来紧凑地保存数据,同时为了节省内存空间,listpack 列表项使用了多种编码方式,来表示不同长度的数据,这些数据包括整数和字符串。

Redis源码对于listpack的解释为 A lists of strings serialization format,一个字符串列表的序列化格式,也就是将一个字符串列表进行序列化存储。Redis listpack可用于存储字符串或者是整型

为了避免 ziplist 引起的连锁更新问题,listpack 中的每个列表项不再像 ziplist 列表项那样,保存其前一个列表项的长度,它只会包含三个方面内容,分别是当前元素的编码类型(entry-encoding)、元素数据 (entry-data),以及编码类型和元素数据这两部分的长度 (entry-len),如下图所示。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • slen,不同于ziplist,listpackEntry 中的 len 记录的是当前 entry 的编码类型和长度,而非上一个entry的长度。
  • *sval,当存储的数据为字符串时,使用该成员变量
  • lval,当存储的数据为整数,使用该成员变量
    通常情况下使用dict数据结构存储数据,每个field-va1 ue pairs构成一个dictEntry节点来保存。

只有同时满足以下两个条件的时候,才会使用listpack(7.O版本之前使用ziplist)数据结构来代替dict存储,把key-value键值对按照
field在前value在后,紧密相连的方式放到一次把每个键值对放到列表的表尾。

  • ·每个键值对中的field和value的字符串字节大小都小于hash-max-listpack-value配置的值(默认64)。
  • ·field-value pairs键值对数量小于hash-max-listpack-entries配置的值(默认512)。

每次向散列表写数据的时候,都会调用t_hash.c中的hashTypeConvertListpack()函数来判断是否需要转换底层数据结构。

当插入和修改的数据不满足以上两个条件时,就把散列表底层存储结构转换成dict结构。需要注意的是,不能由dict退化成listpack。

虽然使用了listpack就无法实现O(1)时间复杂度操作数据,但是使用listpack能大大减少内存占用,而且数据量比较,小,性能并不是有太大差异。

Redis数据库就是一个全局散列表。正常情况下,我只会使用ht_table[0]散列表,图2-20是一个没有进行rehash状态下的字典。
在这里插入图片描述

dict字典在源代码dict.h中使用dict结构体表示。
在这里插入图片描述

1.dictType *type

  • 这是一个指向 dictType 结构的指针,dictType 通常定义了哈希表的操作接口,包括哈希函数、键值的比较函数、释放键值的函数等。这使得哈希表可以针对不同的数据类型进行定制化操作。

2.dictEntry **ht_table[2]

  • 这是一个包含两个指针的数组,每个指针指向一个哈希表(ht_table[0] 和 ht_table[1])。这种设计是为了支持渐进式重新哈希(Incremental Rehashing)。当哈希表的负载因子(即 ht_used[0] / ht_table[0] 的大小)超过某个阈值时,Redis 会开始将数据从 ht_table[0] 重新哈希到 ht_table[1]。这种渐进式重新哈希可以避免一次性重新哈希带来的性能问题。
  • dictEntry是哈希表中存储键值对的结构,通常包含键、值和指向下一个哈希冲突的指针。

3.unsigned long ht_used[2]

  • 这是一个包含两个元素的数组,分别记录 ht_table[0] 和 ht_table[1] 中存储的键值对数量。ht_used[0] 表示 ht_table[0] 中的元素数量,ht_used[1] 表示 ht_table[1] 中的元素数量。

4.long rehashidx

  • 这是一个索引值,用于记录当前重新哈希操作的进度。当哈希表正在进行重新哈希时,rehashidx 表示当前正在处理的桶索引。如果 rehashidx 为 -1,表示没有正在进行的重新哈希操作。

5.int16_t pauserehash

  • 这是一个标志位,用于控制重新哈希操作是否暂停。在某些情况下,Redis 可能需要暂停重新哈希操作,以避免对性能的影响。例如,当 Redis 正在执行 RDB(Redis Database Backup)操作时,可能会暂停重新哈希。

6.signed char ht_size_exp[2]

  • 这是一个包含两个元素的数组,分别记录 ht_table[0] 和 ht_table[1] 的大小指数。Redis 的哈希表大小通常是 2 的幂次方,ht_size_exp[0] 和 ht_size_exp[1] 分别表示 ht_table[0] 和 ht_table[1] 的大小指数。例如,如果 ht_size_exp[0] 为 4,则 ht_table[0] 的大小为 24=16。
    在这里插入图片描述

·*key指针指向键值对中的键,实际上指向一个SDS实例。
虽然Redis是用c实现的,但是他们的string结构并不相同,Redis中的字符串是可以修改的字符串,在内存中它是以字节数组的形式存在的Redis 的。字符串叫sds,也就是 Simple Dynamic String,是一个带长度信息的字节数组
在这里插入图片描述

·v是一个uon联合体,表示键值对中的值,同一时刻只有一个字段有值,用联合体的目是节省内存。

  • ·val 如果值是非数字类型,那就使用这个指针存储。
  • ·uint64tu64, 值是无符号整数的时候使用这个字段存储。
  • ·int64ts64, 值是有符号整数时,使用该字段存储。
  • ·dob1ed, 值是浮点数是,使用该字段存储。
    *next指向下一个节点指针,当散列表数据增加,可能会出现不同的key得到的哈希值相等,也就是说多个key对应在一个哈希桶里面,这就是哈希冲突。Redis使用拉链法,也就是用链表将数据串起来。

为什么说v是一个uo联合体,表示键值对中的值,同一时刻只有一个字段有值,用联合体的目是节省内存?

1.节省内存

  • union 联合体是一种特殊的数据结构,它允许在同一个内存位置存储不同的数据类型。所有成员共享同一块内存,因此在任何时刻,union 中只有一个成员有值。写入一个成员会覆盖其他成员的内容.
  • 在 dictEntry 中,v 的大小由其最大的成员决定。例如,void *val、uint64_t u64、int64_t s64 和 double d 的大小都是 8 字节(在 64 位系统中)。因此,v 的大小也是 8 字节,无论存储哪种类型的数据,都不会占用额外的内存。

2.灵活存储不同类型的数据

  • Redis 的哈希表需要存储多种类型的数据,包括指针、整数和浮点数。通过使用 union,v 可以灵活地存储这些不同类型的数据,而不需要为每种类型分配单独的内存空间。
  • 这种设计使得 dictEntry 能够高效地处理不同类型的数据,同时保持内存占用的最小化。

为啥ht_table[2]存放了两个指向散列表的指针?用一个散列表不就够了吗?

默认使用ht_tab:1e[0]进行读写数据,当散列表的数据越来越多的时候,哈希冲突严重会出现哈希桶的链表比较长,导致查询性能下降。

为了唯快不破想了一个法子,当散列表保存的键值对太多或者太少的时候,需要通过「rehash(重新散列)对散列表进行扩容或者缩容。

扩容和缩容

1.为了高性能,减少哈希冲突,会创建一个大小等于ht_used[0]*2的散列表ht_tab1e[1],也就是每次扩容时根据散列表ht_tab1e[0]已使用空间扩大一倍创建一个新散列表ht_tab1e[1]。反之,如果是缩容操作,就根据ht_tab1e[0]已使用空间缩小一倍创建一个新的散列表。

2.重新计算键值对的哈希值,得到这个键值对在新散列表ht_tab1e[1]的桶位置,将键值对迁移到新的散列表上。

3.所有键值对迁移完成后,修改指针,释放空间。具体是把ht_tab1e[0]指针指向扩容后的散列表,回收原来小的散列表内存空间,ht_tab1e[1]指针指向NULL,为下次扩容或者缩容做准备。

什么时候会触发扩容?

1.当前没有执行BGSAVE或者BGREWRITEAOF命令,同时负载因子大于等于1。也就是当前没有RDB子进程和AOF重写子进程在工作,毕竞这俩操作还是比较容易对性能造成影响的,就不扩容火上浇油了。

2.正在执行BGSAVE或者BGREWRITEA0F命令,负载因子大于等于5。(这时候哈希冲突太严重了,再不触发扩容,查询效率太慢了)。负载因子=散列表存储dictEntry节点数量/散列表桶个数。完美情况下,每个哈希桶存储一个dictEntry节点,这时候负载因子=1。

BGSAVE 和 BGREWRITEAOF 是 Redis 中的两个重要命令,它们分别用于实现 Redis 的两种持久化机制:RDB(Redis Database Backup) 和 AOF(Append Only File)。这两种机制用于将内存中的数据持久化到磁盘,以防止数据丢失。

BGREWRITEAOF 命令触发一个后台进程(子进程)来重写 AOF 文件,以压缩和优化 AOF 文件的大小,同时避免阻塞主进程。

需要迁移数据量很大,rehash操作岂不是会长时间阻塞主线程?

为了防止阻塞主线程造成性能问题,我并不是一次性把全部的key迁移,而是分多次,将迁移操作分散到每次情求中,避免集中式rehash造成长时间阻塞,这个方式叫渐进式rehash。

在执行渐进式rehash期间,dict会同时使用ht_table[0]和ht_table[1]两个散列表,rehash具体步如下:

1.将rehashidxi设置成0,表示rehash开始执行。

2.在rehash期间,服务端每次处理客户端对dict散列表执行添加、查找、删除或者更新操作时,除了执行指定操作以外,还会检查当前dict是否处于rehash状态,是的话就把散列表ht_table[0]上索引位置为rehashidx的桶的链表的所有键值对rehash到散列表ht_table[1]上,这个哈希桶的数据迁移完成,就把rehashidx的值加1,表示下一次要迁移的桶所在位置。

3.当所有的键值对迁移完成后,将rehashidxi设置成-1,表示rehash操作已完成。

rehash过程中,字典的删除、查找、更新和添加操作,要从两个ht_table都搞一遍吗?

删除、修改和查找可能会在两个散列表进行,第一个散列表没找到就到第二个散列表进行查找。但是增加操作只会在新的散列表上进行。

如果请求比较少,岂不是会很长时间都要使用两个散列表?

在Redis Server园初始化时,会注册一个时间事件,定时执行serverCron函数,其中包含rehash操作用于辅助迁移,避免这个问题。
serverCron函数除了做rehash以外,主要处理如下工作。

  • 过期key删除。
  • 监控服务运行状态。
  • 更新统计数据。
  • 渐进式rehash。
  • 触发BGSAVE/AOF rewrite以及停止子进程。
  • 处理客户端超时。

扩容过程:

在 Redis 的哈希表(Hash)rehash 过程中,数据迁移是分步骤、渐进式进行的,这样做是为了避免一次性迁移大量数据造成的服务器阻塞。以下是 rehash 过程中数据迁移的具体步骤:
1. 创建新的哈希表
当触发 rehash 条件时(例如,负载因子超过设定阈值),Redis 会创建一个新的哈希表 ht[1],其大小通常是 ht[0](当前哈希表)大小的两倍。

2. 初始化 rehash 索引
在 dict 结构中,rehashidx 被初始化为 0。这个索引用于跟踪 rehash 过程中已经迁移的桶的数量。

3. 渐进式迁移
Redis 使用一个定时任务或者在处理命令时的空闲时间来执行 rehash 操作。在每次 rehash 操作中,会迁移一定数量的桶(通常是一个或几个),而不是一次性迁移所有桶。具体步骤如下:

  • 从 ht[0] 中取出一个桶(通过 rehashidx 定位)。
  • 遍历桶中的所有 dictEntry(如果有链表,则遍历链表中的所有条目)。
  • 重新计算每个 dictEntry 的哈希值,并将其插入到 ht[1] 中对应的桶中。
  • 更新 rehashidx,指向下一个需要迁移的桶。

4. 更新 rehash 状态
每次迁移一定数量的桶后,Redis 会更新 rehashidx,使其指向下一个桶。这样,下一次 rehash 操作可以从上次停止的地方继续。

5. 完成 rehash
当 rehashidx 超过 ht[0] 的大小时,表示所有桶都已迁移到 ht[1]。此时,Redis 会进行以下操作:

  • 将 ht[1] 设置为新的 ht[0],即让新的哈希表成为当前使用的哈希表。
  • 释放旧的 ht[0] 占用的内存。
  • 将 rehashidx 重置为 -1,表示 rehash 操作已完成。

6. 处理命令时的 rehash
在 rehash 过程中,Redis 仍然可以处理客户端的命令。当命令涉及到哈希表操作时,Redis 会同时在 ht[0] 和 ht[1] 中查找或插入数据,确保数据的一致性。
通过这种渐进式的 rehash 机制,Redis 能够在不影响服务器性能的情况下,平滑地完成哈希表的扩容操作。

BGSAVE和BGREWRITEAOF是什么意思?

BGSAVE 和 BGREWRITEAOF 是 Redis 中的两个重要命令,它们分别用于实现 Redis 的两种持久化机制:RDB(Redis Database Backup) 和 AOF(Append Only File)。这两种机制用于将内存中的数据持久化到磁盘,以防止数据丢失。
1. BGSAVE(RDB 持久化)
RDB 持久化

  • 定义:RDB 是一种快照持久化机制,它会定期将内存中的数据集快照保存到磁盘上的一个 RDB 文件中。

  • 优点:

    • 数据恢复速度快:RDB 文件是一个紧凑的二进制文件,恢复数据时速度较快。
    • 适合全量备份:适合用于全量数据备份,可以方便地将数据备份到其他存储介质或远程服务器。
  • 缺点:

  • 数据丢失风险:如果 Redis 服务器在两次快照之间发生故障,可能会丢失最后一次快照之后的数据。

  • 阻塞风险:生成 RDB 文件的过程可能会阻塞主进程,尤其是在数据量较大时。

BGSAVE 命令

  • 作用:触发一个后台进程(子进程)来生成 RDB 文件,而主进程继续处理客户端请求,避免阻塞。

  • 执行过程:

    a.主进程创建一个子进程。
    b.子进程将当前内存中的数据集快照写入到一个新的 RDB 文件中。
    c.子进程完成写入后,用新生成的 RDB 文件替换旧的 RDB 文件。

  • 触发方式:

    • 手动触发:可以通过命令 BGSAVE 手动触发。
    • 自动触发:Redis 会根据配置的策略自动触发 BGSAVE。例如,可以配置 Redis 每隔一定时间或在数据变更达到一定数量时自动执行 BGSAVE。

2. BGREWRITEAOF(AOF 持久化)
AOF 持久化

  • 定义:AOF 是一种日志持久化机制,它会将每个写操作命令追加到一个日志文件(AOF 文件)中。
  • 优点:
    • 数据安全性高:AOF 文件记录了每个写操作,即使 Redis 服务器发生故障,也可以通过重放 AOF 文件中的命令恢复数据。
    • 可配置性强:可以配置不同的同步策略(如每秒同步一次、每次写操作同步一次等),以平衡性能和数据安全性。
  • 缺点:
    • 文件体积大:AOF 文件会不断增长,可能会占用大量磁盘空间。
    • 恢复速度慢:AOF 文件是文本格式,恢复数据时速度相对较慢。

BGREWRITEAOF 命令

  • 作用:触发一个后台进程(子进程)来重写 AOF 文件,以压缩和优化 AOF 文件的大小,同时避免阻塞主进程。

  • 执行过程:

    a.主进程创建一个子进程。
    b.子进程读取当前内存中的数据集,并将其转换为一系列优化后的写操作命令,写入到一个新的 AOF 文件中。
    c.子进程完成写入后,用新生成的 AOF 文件替换旧的 AOF 文件。

  • 触发方式:

    • 手动触发:可以通过命令 BGREWRITEAOF 手动触发。
    • 自动触发:Redis 会根据配置的策略自动触发 BGREWRITEAOF。例如,可以配置 Redis 在 AOF 文件大小达到一定比例时自动执行 BGREWRITEAOF。

总结

  • BGSAVE:用于生成 RDB 文件,适合全量数据备份,恢复速度快,但可能会丢失最后一次快照之后的数据。
  • BGREWRITEAOF:用于重写 AOF 文件,优化 AOF 文件的大小,数据安全性高,但文件体积大,恢复速度相对较慢。
    这两种持久化机制可以单独使用,也可以结合使用,具体选择取决于应用场景和对数据安全性的要求。

相关文章:

redis中的hash

Redis中的hash是什么 Hash: 哈希,也叫散列,是一种通过哈希函数将键映射到表中位置的数据结构,哈希函数是关键,它把键转换成索引。 Redis Hash(散列表)是一种 field-value pairs(键值对&#x…...

【学习笔记】李沐斯坦福21秋季:实用机器学习中文版

这里写自定义目录标题 数据处理数据获取数据标注数据清洗特征工程 数据处理 数据获取 爬虫 实际工作中大部分都是从数据库里取数 数据标注 只有一小部分有标签 大部分无标签的话 半监督学习:没标注数据和有标注数据共同使用 做法1:半监督学习 基于有标签的小部分…...

UE5学习笔记 FPS游戏制作43 UI材质

文章目录 实现目标制作UI材质使用UI材质 实现目标 把图片变为灰色 制作UI材质 右键新建一个材质 左侧细节栏,材质域改为用户界面,混合模式改为半透明 此时输出节点应该有两个属性 在内容浏览器里找到要用的图片,然后向上拖动到材质标题…...

QT控件 修改QtTreePropertyBrowser自定义属性编辑器源码,添加第一列标题勾选,按钮,右键菜单事件等功能

头阵子遇到一个需要修改QtTreePropertyBrowser控件的需求,QT开发做这么久了,这个控件倒是第一次用,费了点时间研究,在这里做个简单的总结。 QtTreePropertyBrowser控件 是 Qt 解决方案 (Qt Solutions) 中的一个组件,用…...

MFC工具栏CToolBar从专家到小白

CToolBar m_wndTool; //创建控件 m_wndTool.CreateEx(this, TBSTYLE_FLAT|TBSTYLE_NOPREFIX, WS_CHILD | WS_VISIBLE | CBRS_FLYBY | CBRS_TOP | CBRS_SIZE_DYNAMIC); //加载工具栏资源 m_wndTool.LoadToolBar(IDR_TOOL_LOAD) //在.rc中定义:IDR_TOOL_LOAD BITMAP …...

Golang 项目平滑重启

引言 平滑重启(Graceful Restart)技术作为一种常用的解决方案,通过允许新进程接管而不中断现有的请求,确保了系统的稳定运行和业务连续性。同时目前公司的服务重启绝大部分也都适用的 go 的平滑重启技术。 本部分将对平滑重启的…...

Vue2 插槽 Slot

提示:插槽的目的是让我买原来的设备具备更多的扩展性。 文章目录 前言在组件中定义插槽(子组件视角)1. 默认插槽2. 具名插槽(带名称的插槽)3. 作用域插槽(带数据的插槽) 使用插槽(父…...

关于sqlsugar实体多层List映射的问题

如上图所示&#xff0c;当一个主表&#xff08;crm_fina_pay_req&#xff09;的子表list<文件附件关系表>&#xff08; List<crm_fina_payreq_evidofpay_relation> &#xff09;中&#xff0c;还包含有sysfile&#xff08;SysFile SysFiles&#xff09;类型的文件信…...

使用stm32cubeide stm32f407 lan8720a freertos lwip 实现udp client网络数据转串口数据过程详解

1前言 项目需要使用MCU实现网络功能&#xff0c;后续确定方案stm32f407 外接lan8720a实现硬件平台搭建&#xff0c;针对lan8720a也是用的比较多的phy&#xff0c;网上比较多的开发板&#xff0c;硬件上都是选用了这个phy&#xff0c;项目周期比较短&#xff0c;选用了这个常用…...

LangChain4j(4):预设角色(系统消息SystemMessage)

1 预设角色(系统消息SystemMessage) 基础大模型是没有目的性的&#xff0c; 你聊什么给什么&#xff0c;但是如果我们开发的事一个智能票务助手&#xff0c; 我需要他以一个票务助手的角色跟我对话&#xff0c; 并且在我跟他说”退票”的时候&#xff0c; 让大模型一定要告诉我…...

自然语言处理利器NLTK:从入门到核心功能解析

文章目录 一、NLP领域的基石工具包二、NLTK核心模块全景解析1 数据获取与预处理2 语言特征发现3 语义与推理 三、设计哲学与架构优势1 四维设计原则2 性能优化策略 四、典型应用场景1 学术研究2 工业实践 五、生态系统与未来演进 一、NLP领域的基石工具包 自然语言工具包&…...

常见接口协议介绍

1. I2C&#xff08;Inter-Integrated Circuit&#xff09; 定义&#xff1a;两线制串行总线&#xff08;SDA数据线 SCL时钟线&#xff09;&#xff0c;支持主从模式多设备通信。特点&#xff1a; 地址机制&#xff1a;每个设备有唯一地址&#xff0c;主设备通过地址选择从设备…...

宝塔面板使用CDN 部署后获取真实客户端 IP教程

在宝塔面板环境中配置 CDN 加速服务后&#xff0c;服务器日志默认记录的是 CDN 节点 IP&#xff0c;这给网站流量分析带来不便。本文将为您提供多种解决方案&#xff0c;帮助您在 CDN 生效的同时获取真实访客 IP。 一、Nginx 配置调整方案 日志格式优化 在宝塔面板中打开 Ngi…...

生鲜果蔬便利店实体零售门店商城小程序

——线上线下融合赋能社区零售新生态 随着新零售模式的深化和消费者需求的升级&#xff0c;生鲜果蔬便利店亟需通过数字化工具实现经营效率与用户体验的双重提升。结合线下实体门店与线上商城的一体化小程序&#xff0c;成为行业转型的核心工具。以下从功能模块、运营策略及行…...

C++(初阶)(十)——vector模拟实现

vector vector构造尾插&#xff08;删&#xff09;和扩容inert&#xff08;插入&#xff09;迭代器失效erase&#xff08;删除&#xff09;resize&#xff08;调整空间&#xff09;深浅拷贝迭代器拷贝和赋值&#xff08;v2(v1)和v1 v3&#xff09;多个数据插入迭代器区间初始化…...

利用解析差异SSRF + sqlite注入 + waf逻辑漏洞 -- xyctf 2025 fate WP

本文章附带TP(Thinking Process)! #!/usr/bin/env python3 # 导入所需的库 import flask # Flask web框架 import sqlite3 # SQLite数据库操作 import requests # HTTP请求库 import string # 字符串处理 import json # JSON处理app flask.Flask(__name__) # 创建Flask应…...

VScode无法激活conda虚拟环境,不显示虚拟环境名称

在VScode中终端中激活环境时出现下面的情况 PS F:\Model\stMMR-main> conda activate env_mamba usage: conda-script.py [-h] [--no-plugins] [-V] COMMAND ... conda-script.py: error: argument COMMAND: invalid choice: activate (choose from clean, compare, config…...

vscode Colipot 编程助手

1、登录到colipot&#xff0c;以github账号&#xff0c;关联登录 点击【continue】按钮&#xff0c;继续。 点击【打开Visual Studio Code】&#xff0c;回到vscode中。 2、问一下11? 可以看出&#xff0c;很聪明&#xff0c;一下子就算出来了。 3、帮我们写一个文件&#xf…...

vscode中REST Client插件

最近发现vscode中REST Client插件也可以测试接口 简介 在 VS Code 中&#xff0c;REST Client 是一个非常受欢迎的插件&#xff0c;用于测试和调试 RESTful API。以下是关于该插件的安装、使用和功能的详细介绍&#xff1a; 安装 REST Client 插件 打开 VS Code。点击左侧的扩…...

路由器工作在OSI模型的哪一层?

路由器主要工作在OSI模型的第三层&#xff0c;即网络层。网络层的主要功能是将数据包从源地址路由到目标地址&#xff0c;路由器通过检查数据包中的目标IP地址&#xff0c;并根据路由表确定最佳路径来实现这一功能。 路由器的主要功能&#xff1a; a、路由决策&#xff1a;路…...

(PROFINET 转 EtherCAT)EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

型号 协议转换通信网关 PROFINET 转 EtherCAT MS-GW31 概述 MS-GW31 是 PROFINET 和 EtherCAT 协议转换网关&#xff0c;为用户提供两种不同通讯协议的 PLC 进行数据交互的解决方案&#xff0c;可以轻松容易将 EtherCAT 网络接入 PROFINET 网络中&#xff0c;方便扩展&…...

【教程】MacBook 安装 VSCode 并连接远程服务器

目录 需求步骤问题处理 需求 在 Mac 上安装 VSCode&#xff0c;并连接跳板机和服务器。 步骤 Step1&#xff1a;从VSCode官网&#xff08;https://code.visualstudio.com/download&#xff09;下载安装包&#xff1a; Step2&#xff1a;下载完成之后&#xff0c;直接双击就能…...

Solidity基础入门—web3

Remix介绍 官网地址 Remix 是一个基于浏览器的 Solidity 开发环境&#xff0c;主要用于编写、测试、调试和部署以太坊智能合约。 Solidity基本数据类型 类型说明示例uint / int无符号 / 有符号整数uint256, int8, int256bool布尔类型&#xff08;true / false&#xff09;bo…...

微信小程序 request 流式数据处理

什么是流式数据处理&#xff1f; 流式数据处理&#xff08;Streaming Data&#xff09;指逐步接收并处理数据片段的技术&#xff0c;无需等待全部数据加载完成。适用于大文件下载、实时日志、AI生成报告等场景&#xff0c;可显著降低内存占用并提升用户体验。 微信小程序中的…...

Kotlin与HttpClient编写视频爬虫

想用Apache HttpClient库和Kotlin语言写一个视频爬虫。首先&#xff0c;我需要确定用户的具体需求。视频爬虫通常涉及发送HTTP请求&#xff0c;解析网页内容&#xff0c;提取视频链接&#xff0c;然后下载视频。可能需要处理不同的网站结构&#xff0c;甚至可能需要处理动态加载…...

数据结构:通俗解释AOE 网中事件的最早发生时间和最迟发生时间

1. 事件的最早发生时间 在 AOE 网&#xff08;Activity On Edge Network&#xff0c;边表示活动的网络&#xff09;中&#xff0c;事件的最早发生时间指从源点&#xff08;起点&#xff09;到该事件结点的最长路径长度&#xff08;即所需时间&#xff09;。它决定了所有以该事…...

爬虫中遇到的问题

网页假请求导致的阻塞 可以在requests请求当中添加timeout参数&#xff0c;来让网站重新请求 在爬虫请求中&#xff0c;timeout参数的主要作用是控制请求的最大等待时间&#xff0c;避免因服务器响应缓慢或网络问题导致程序长时间阻塞&#xff0c;从而提升爬虫的效率和稳定性…...

聊一聊没有接口文档时如何开展测试

目录 一、前期准备与信息收集 二、使用抓包工具分析接口 三、逆向工程构造测试用例 四、安全测试 五、 模糊测试&#xff08;Fuzz Testing&#xff09; 六、记录并维护发现的接口信息 七、 推动团队规范流程 其它注意事项 在我们进行接口测试时&#xff0c;总会遇到各种…...

第一部分:MCP协议与多智能体系统基础-第1课:MCP服务协议核心架构解析

以下是为《MCP服务协议核心架构解析》设计的课件内容&#xff0c;采用“概念解析→代码实践→运行验证”三段式教学结构&#xff0c;结合可视化图表与可运行代码示例&#xff0c;增强学生对MCP协议核心组件的理解与实操能力&#xff1a; 一、课程导入&#xff1a;MCP协议定位与…...

WEB安全--内网渗透--捕获NET-NTLMv2 Hash

一、前言 在LM&NTLM基础篇中我们了解到了NTLM协议的流程与加密的方式&#xff0c;以及具体的在type3的response中Net-ntlm hash v2的生成方式。 思考&#xff1a; 如果我们入侵的服务器中有域管理员的登录后的密码缓存&#xff0c;那就能用工具&#xff08;mimikatz&…...

使用 J-Flash 读取芯片 Flash 数据的方法

基本读取步骤 硬件连接 确保 J-Link 调试器正确连接到目标板 给目标板供电&#xff08;可通过 J-Link 供电或外部电源&#xff09; 创建/打开项目 启动 J-Flash 软件 选择 "File" > "New Project" 创建新项目 选择正确的目标芯片型号&#xff08;或…...

Spring MVC 返回 JSON 视图的方式及对比(6种)

Spring MVC 返回 JSON 视图的方式及对比&#xff08;新增 MappingJackson2JsonView&#xff09; 1. 方式一&#xff1a;ResponseBody 注解 作用&#xff1a;直接返回对象&#xff0c;由消息转换器&#xff08;如 Jackson&#xff09;序列化为 JSON。 适用场景&#xff1a;简单…...

SpringMVC的数据响应

1)页面跳转 直接返回字符串 通过ModelAndView对象返回 //方式三(model和view拆开)RequestMapping("/quick4")public String save4(Model model){model.addAttribute("username","lisi3");return "success";}//方式二RequestMapping(&…...

GraphRAG与知识图谱

一、GraphRAG介绍 1.1 什么是 Graph RAG&#xff1f; Graph RAG&#xff08;Retrieval-Augmented Generation&#xff09;&#xff0c;是一种基于知识图谱的检索增强技术&#xff0c; 通过构建图模型的知识表达&#xff0c;将实体和关系之间的联系用图的形式进行展示&#xff…...

hive通过元数据库删除分区操作步骤

删除分区失败&#xff1a; alter table proj_60_finance.dwd_fm_ma_kpi_di_mm drop partition(year2025,month0-3,typeADJ); 1、查询分区的DB_ID、TBL_ID – 获取数据库ID-26110 SELECT DB_ID FROM DBS WHERE NAME ‘proj_60_finance’; – 获取表ID-307194 SELECT TBL_ID FR…...

LINUX 5 cat du head tail wc 计算机拓扑结构 计算机网络 服务器 计算机硬件

计算机网络 计算机拓扑结构 计算机按性能指标分&#xff1a;巨型机、大型机、小型机、微型机。大型机、小型机安全稳定&#xff0c;小型机用于邮件服务器 Unix系统。按用途分&#xff1a;专用机、通用机 计算机网络&#xff1a;局域网‘、广域网 通信协议’ 计算机终端、客户端…...

flink 增量快照同步文件引用关系和恢复分析

文章目录 文件引用分析相关代码分析从state 恢复&#xff0c;以rocksdb为例不修改并行度修改并行度keyGroupRange过程问题 文件引用分析 每次生成的checkpoint 里都会有所有文件的引用信息 问题&#xff0c;引用分析里如何把f1,f2去掉了&#xff0c;可以参考下面的代码&#…...

属性修改器 (AttributeModifier)

主页面设置组件 import { MyButtonModifier } from ../datastore/MyButtonModifier;Entry ComponentV2 struct MainPage {// 支持用状态装饰器修饰&#xff0c;行为和普通的对象一致Local modifier: MyButtonModifier new MyButtonModifier();build() {Column() {Button(&quo…...

汽车BMS技术分享及其HIL测试方案

一、BMS技术简介 在全球碳中和目标的战略驱动下&#xff0c;新能源汽车产业正以指数级速度重塑交通出行格局。动力电池作为电动汽车的"心脏"&#xff0c;其性能与安全性不仅直接决定了车辆的续航里程、使用寿命等关键指标&#xff0c;更深刻影响着消费者对电动汽车的…...

电网电能质量分析:原理、算法及实际应用

一、引言 在现代社会&#xff0c;电力供应的稳定性和可靠性对工业生产、社会生活的各个方面都至关重要。电能质量作为衡量电力系统供电能力的关键指标&#xff0c;其优劣直接影响到电力设备的运行效率、使用寿命以及生产过程的稳定性。随着电力系统规模的不断扩大&#xff0c;新…...

PyCharm Community社区版链接WSL虚拟环境

#记录工作 在过去&#xff0c;PyCharm Community Edition&#xff08;社区版&#xff09;不具备链接 WSL 虚拟环境的功能&#xff0c;该功能仅在 PyCharm Professional&#xff08;专业版&#xff09;和企业版中提供。如今&#xff0c;从 PyCharm Community Edition 2024.3.5 …...

2026考研数学张宇武忠祥复习视频课,高数基础班+讲义PDF

2026考研数学武忠祥老师课&#xff08;网盘&#xff09;&#xff1a;点击下方链接 2026考研数学武忠祥网课&#xff08;最新网盘&#xff09; 一、基础阶段&#xff08;3-5个月&#xff09; 目标&#xff1a;搭建知识框架掌握基础题型 教材使用&#xff1a; 高数&#xff1a;…...

Spring Boot嵌入前端静态资源:从原理到实战的完整指南

在Java Spring Boot项目中集成前端静态资源是构建现代Web应用的必备技能。本文将深入解析Spring Boot的静态资源处理机制&#xff0c;通过实战案例演示完整的集成流程&#xff0c;并分享性能优化与安全加固的最佳实践。 一、Spring Boot静态资源处理原理 1.1 默认资源路径 S…...

DeepSeek对比ChatGPT有何改进,可以用更低成本计算

下面是基于DeepSeek公开论文和代码&#xff0c;与ChatGPT对比后总结的改进点&#xff0c;以及其为何能用更少算力训练大模型的解析。 https://arxiv.org/pdf/2412.19437 1. 改进点对比 1.1 架构稀疏化与混合专家&#xff08;MoE&#xff09;设计 DeepSeek采用稀疏激活与混合…...

JavaScript双问号操作符(??)详解,解决使用 || 时因类型转换带来的问题

目录 JavaScript双问号操作符&#xff08;??&#xff09;详解&#xff0c;解决使用||时因类型转换带来的问题 一、双问号操作符??的基础用法 1、传统方式的痛点 2、双问号操作符??的精确判断 3、双问号操作符??与逻辑或操作符||的对比 二、复杂场景下的空值处理 …...

Go语言从零构建SQL数据库(5)-Pratt解析算法:SQL表达式解析的核心引擎

Pratt解析算法&#xff1a;SQL表达式解析的核心引擎 1. 算法概述与工作原理 Pratt解析算法&#xff08;自顶向下运算符优先级解析&#xff09;是一种优雅的表达式解析方法&#xff0c;特别适合处理具有不同优先级运算符的复杂表达式。在我们的SQL解析器中&#xff0c;它负责解…...

数字政府与电子政务综合分析报告

数字政府与电子政务综合分析报告 一、引言 随着信息技术的飞速发展&#xff0c;数字政府和电子政务成为全球公共管理领域的重要趋势。数字政府和电子政务的建设不仅是提升政府治理能力的必然选择&#xff0c;也是推动国家治理现代化的重要途径。本文将对数字政府和电子政务进…...

服务器虚拟化技术深度解析:医药流通行业IT架构优化指南

一、服务器虚拟化的定义与原理 &#xff08;一&#xff09;技术定义&#xff1a;从物理到虚拟的资源重构 服务器虚拟化是通过软件层&#xff08;Hypervisor&#xff09;将物理服务器的CPU、内存、存储、网络等硬件资源抽象为逻辑资源池&#xff0c;分割成多个相互隔离的虚拟机…...

QT ARM 开发环境搭建

搭建 QT ARM 开发环境主要包括主机环境配置、交叉编译工具链安装、QT 库交叉编译和 QT Creator 配置几个步骤。以下是详细流程: 一. 主机环境准备 系统要求 推荐 Ubuntu 18.04/20.04 LTS 或更高版本 至少 50GB 可用磁盘空间 8GB 以上内存 安装基础依赖 sudo apt update sud…...

【设计模式】外观模式

简介 想象你要在家里看电影&#xff0c;需要做以下操作&#xff1a; 打开电视启动音响调暗灯光关闭窗帘 如果每次都要手动操作这些步骤会很麻烦。外观模式可以帮你将这些步骤封装成一个统一的接口&#xff0c;比如“一键观影模式”&#xff0c;你只需按一个按钮&#xff0c;…...