【Redis】数据类型详解及其应用场景
目录
- Redis 常⻅数据类型
- 预备知识
- 基本全局命令
- 小结
- 数据结构和内部编码
- 单线程架构
- 引出单线程模型
- 为什么单线程还能这么快
Redis 常⻅数据类型
Redis 提供了 5 种数据结构,理解每种数据结构的特点对于 Redis 开发运维⾮常重要,同时掌握每种数据结构的常⻅命令,会在使⽤ Redis 的时候做到游刃有余。本章内容如下:
- 预备知识:⼏个全局(generic)命令,数据结构和内部编码,单线程模式机制分析。
- 5 种数据结构的特点、命令使⽤、应⽤场景⽰例。
- 键遍历、数据库管理。
预备知识
在正式介绍 5 种数据结构之前,了解⼀下 Redis 的⼀些全局命令、数据结构和内部编码、单线程命令处理机制是⼗分必要的,它们能为后⾯内容的学习打下⼀个良好的基础.主要体现在两个⽅⾯:
- Redis 的命令有上百个,如果纯靠死记硬背⽐较困难,但是如果理解 Redis 的⼀些机制,会发现这些命令有很强的通⽤性。
- Redis 不是万⾦油,有些数据结构和命令必须在特定场景下使⽤,⼀旦使⽤不当可能对 Redis 本⾝或者应⽤本⾝造成致命伤害。
基本全局命令
Redis 有 5 种数据结构,但它们都是键值对种的值,对于键来说有⼀些通⽤的命令。
必须要进入 redis-cli 客户端程序,才能输入 redis 命令
全局命令就是能够搭配任意一个数据结构使用的命令
KEYS
keys
查询当前服务器上匹配的 key,返回所有满⾜样式(pattern)的 key。⽀持如下统配样式。
通过一些特殊符号(通配符)来描述的模样,匹配上述模样的 key 就能被查询出来
pattern 包含特殊符号的字符串,是去描述另外的字符串是什么样的
h?llo
匹配hello
,hallo
和hxllo
h*llo
匹配hllo
和heeeello
h[ae]llo
匹配hello
和hallo
但不匹配hillo
h[^e]llo
匹配hallo
,hbllo
, … 但不匹配hello
h[a-b]llo
匹配hallo
和hbllo
?匹配任意一个字符
- 匹配任意零个或者多个字符
[abcde]只能匹配 abcde 的任意一个,相当于给出固定选项
[^e]排除 e,只有 e 匹配不了,其他都能匹配
[a-e]匹配 a 到 e 之间的字符,包括 a 和 e
语法:
KEYS pattern
命令有效版本:1.0.0 之后
时间复杂度:O(N)
所以在生产环境上,一般禁止使用 keys 命令,尤其是像 keys _ 这种,这是查询 Redis 存储所有的 key。Redis 经常被用于做缓存,挡在 MySQL 前面,如果 Redis 被 keys _ 这样一个命令阻塞住了,其他查询 Redis 操作间超时了,此时这些请求就会直接查数据库,如果请求过多 MySQL 就容易挂了。
- 办公环境:办公的电脑
- 开发环境:有时就是和办公环境一样的(前端/客户端),有时开发环境就是一个单独的服务器(后端,因为有些程序比较复杂)
- 编译一次时间比较久,比如 C++,就需要一台高性能的服务器
- 有些程序一启动就消耗很多 CPU 和内存资源
- 有的程序比较依赖 Linux,在 Windows 环境搭不起来
- 测试环境:一般是比较好的服务器,测试工程师用的
- 生产环境(线上环境):与前面三个环境相对的,前面三个是线下环境,线上环境是外界用户访问的,线下环境是外界用户无法访问的,这是影响公司营收的
返回值:匹配 pattern 的所有 key。
⽰例:
redis> MSET firstname Jack lastname Stuntman age 35
"OK"
redis> KEYS *name*
1) "firstname"
2) "lastname"
redis> KEYS a??
1) "age"
redis> KEYS *
1) "age"
2) "firstname"
3) "lastname"
EXISTS
exists
判断某个 key 是否存在。
语法:
EXISTS key [key ...]
命令有效版本:1.0.0 之后
时间复杂度:O(1),严谨点应该是多少个 key 就多少个 O(1)
Redis 组织这些 key 就是按照哈希表的方式来组织的。
Redis 支持很多数据结构指的是一个 value 可以是一些复杂的数据结构。Redis 自身的这些键值对是通过哈希表组织的,具体的某个值又可以是一些数据结构。
返回值:key 存在的个数。
⽰例:
redis> SET key1 "Hello""OK"redis> EXISTS key1(integer) 1redis> EXISTS nosuchkey(integer) 0redis> SET key2 "World""OK"redis> EXISTS key1 key2 nosuchkey(integer) 2
DEL
del
删除指定的 key。
语法:
DEL key [key ...]
命令有效版本:1.0.0 之后
时间复杂度:O(1)
返回值:删除掉的 key 的个数。
⽰例:
redis> SET key1 "Hello""OK"redis> SET key2 "World""OK"redis> DEL key1 key2 key3(integer) 2
在 MySQL ,像删除一类的操作,都是比较危险的,删除后数据就没有了。但在 Redis 主要的应用场主要是作为缓存,此时存的是一个热点数据,全量数据在 MySQL 之类的数据库中,此时直接把 Redis 的 key 删除了几个,一般来说问题不大,除非是删除了很多,这样就会导致请求直接发送到 MySQL,就容易把 MySQL 搞挂。
如果把 Redis 作为数据库存储,这样误删数据就问题大了。
如果把 Redis 作为消息队列,影响大不大就具体情况具体分析了。
EXPIRE
expire
为指定的 key 添加秒级的过期时间(Time To Live TTL),单位是秒,超过时间 key 就被自动删除了,比如手机验证码,基于 Redis 实现分布式锁(为避免不能正确解锁的情况,通常都会在加锁的时候设置过期时间,Redis 实现分布式锁就是给 Redis 里写一个特殊的 key value)。
pexpire 单位是毫秒,其他和 expire 是一样的
语法:
EXPIRE key seconds
key 必须存在
命令有效版本:1.0.0 之后
时间复杂度:O(1)
返回值:1 表⽰设置成功。0 表⽰设置失败。
⽰例:
TTL
ttl
time to live
获取指定 key 的过期时间,秒级。
pttl 单位是毫秒,其他和 ttl 是相似的
语法:
TTL key
命令有效版本:1.0.0 之后
时间复杂度:O(1)
返回值:剩余过期时间。-1 表⽰没有关联过期时间,-2 表⽰ key 不存在。
⽰例:
redis> SET mykey "Hello""OK"redis> EXPIRE mykey 10(integer) 1redis> TTL mykey(integer) 10
EXPIRE 和 TTL 命令都有对应的⽀持毫秒为单位的版本:PEXPIRE 和 PTTL,详细⽤法就不再介绍了
一个 Redis 中可能同时存在很多 key,很大一部分可能都有过期时间,Redis 服务器是怎么知道哪些 key 已经过期要被删除,哪些 key 还没过期?
如果直接遍历所有的 key,肯定是效率很低的。
Redis 整体的策略:
- 定期删除:这个定期删除也采用了一个抽取样本的方式,每次只抽取一部分,保证这个抽取检查的过程足够快,不要浪费太多时间
- 惰性删除:过期了不会立即删除,但一旦访问到了 Redis 就立刻出发删除 key 的操作,同时返回一个 nil
以上策略的原因:因为 Redis 是单线程的程序,主要的任务是处理每个命令,如果扫描过期 key 太耗费时间就导致正常处理请求命令被阻塞了
以上策略的效果是一般的,仍然可能有很多过期的 key 被残留。对以上 Redis 也是有补充的,比如一系列的内存淘汰策略
注意:
- Redis 中没有采取定时器的方式来实现过期 key 的删除
- 如果有多个 key 过期,也可以通过一个定时器(基于优先级队列或者时间轮)来高效/节省 CPU 的前提下来处理多个 key
作者没有采用定时器的原因?可能是因为如果基于定时器实现就要引入多线程了,而 Redis 早期版本就是奠定了单线程的基调,多线程就不符合作者初衷
定时器的实现方式(Redis 并没有这个做):
- 优先级队列:
- 假定很多 key 都设置了过期时间,放入优先级队列后,指定优先级规则是过期时间早的先出队列,此时扫描线程只需要盯着队首元素即可
- 但这个是扫描线程也不需要检查得太频繁,可以根据当前时刻和队首元素的过期时间设置一个等待
- 此时如果有新任务添加进来,就唤醒一下刚才的线程,重新检查一下队首元素,再根据时间差距重新调整阻塞时间即可
- 时间轮:
- 把时间划分成很多的格子,划分的粒度看实际需求
- 每个格子都挂着一个链表,每个链表都代表一个要执行的任务
- 此时设置一个指针遍历这个轮,每隔固定的时间走一个格子
- 此时添加一个 key 时,把其过期时间除以指针移动的固定时间,放到对应的格子
- 对于时间轮多少个格子以及移动的固定时间都是根据需求设置的
Redis 源码中,一个比较核心的机制是事件循环
关于键过期机制,可以参考图 2-1 所⽰。
图 2-1 键的过期机制
TYPE
返回 key 对应的数据类型。
Redis 所有的 key 都是 string,但 key 对应的 value 可能有多种类型
语法:
TYPE key
命令有效版本:1.0.0 之后
时间复杂度:O(1)
返回值: none
, string
, list
, set
, zset
, hash
,stream
(这个是 Redis 作为消息队列使用的 value)。
⽰例:
redis> SET key1 "value""OK"redis> LPUSH key2 "value"(integer) 1redis> SADD key3 "value"(integer) 1redis> TYPE key1"string"redis> TYPE key2"list"redis> TYPE key3"set"
小结
- keys:用来查看匹配规则的 key
- exists:用来判定指定 key 是否存在
- del:删除指定的 key
- expire:给 key 设置过期时间
- ttl:查询 key 的过期时间
- type:查询 key 对应的 value 的类型
以上只是给出⼏个通⽤的命令,为 5 种数据结构的使⽤(实际上 Redis 支持10个数据类型)做⼀个热⾝,后续将对键管理做⼀个更为详细的介绍。
数据结构和内部编码
type 命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、list(列表)、hash(哈希)、set(集合)、zset(有序集合),但这些只是 Redis 对外的数据结构,如图 2-2 所⽰。
图 2-2 Redis 的 5 种数据类型
这5种数据结构相当于 Java 中的:
- String
- HashMap
- List
- Set
- 这个找不太到,除了存储 member 外还需要存储一个 score(权重)
实际上 Redis 针对每种数据结构都有⾃⼰的底层内部编码实现,⽽且是多种实现,这样 Redis 会在合适的场景选择合适的内部编码,如表 2-1 所⽰。
表 2-1 Redis 数据结构和内部编码
数据类型 | 内部编码 | 说明 |
---|---|---|
string | raw | 最基本的字符串 |
string | int | 当 value 是一个整数时,Redis 很可能直接用 int 保存 |
string | embstr | 针对短字符串进行的特殊优化 |
hash | hashtable | 最基本的哈希表,但这并不是 Java 标准库的那个 HashTable |
hash | ziplist | 压缩列表,针对哈希表里面元素较少的情况,能够节省空间 |
list | linkedlist | 链表 |
list | ziplist | 压缩列表 |
set | hashtable | |
set | intset | 针对集合中存的都是整数 |
zset | skiplist | 跳表,也是链表,但每个节点上有多个指针域 |
zset | ziplist |
可以看到每种数据结构都有⾄少两种以上的内部编码实现,Redis 会自动根据当前的实际情况选择内部的编码方式,自动适应的,例如 list 数据结构包含了 linkedlist 和 ziplist 两种内部编码。同时有些内部编码,例如 ziplist,可以作为多种数据结构的内部实现,可以通过 object encoding
命令查询内部编码:
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> lpush mylist a b c
(integer) 3
127.0.0.1:6379> object encoding hello
"embstr"
127.0.0.1:6379> object encoding mylist
"quicklist"
可以看到 hello 对应值的内部编码是 embstr,键 mylist 对应值的内部编码是 ziplist。
从 Redis 3.2 开始,对于 list 引入了新的实现方式 quicklist,就直接代替了 linkedlist 和 ziplist,同时兼顾了两个的优点,quicklist 就是一个链表,每个元素又是一个 ziplist,把空间和效率都折中兼顾到。
注意,只是对于 list 这个数据类型是这样,别的还是按照上述表格
Redis 这样设计有两个好处:
- 可以改进内部编码,⽽对外的数据结构和命令没有任何影响,这样⼀旦开发出更优秀的内部编码,⽆需改动外部数据结构和命令,例如 Redis 3.2 提供了 quicklist,结合了 ziplist 和 linkedlist 两者的优势,为列表类型提供了⼀种更为优秀的内部编码实现,⽽对⽤⼾来说基本⽆感知。
- 多种内部编码实现可以在不同场景下发挥各⾃的优势,例如 ziplist ⽐较节省内存,但是在列表元素⽐较多的情况下,性能会下降,这时候 Redis 会根据配置选项将列表类型的内部实现转换为linkedlist,整个过程⽤⼾同样⽆感知。
单线程架构
Redis 使⽤了单线程架构来实现⾼性能的内存数据库服务,本节⾸先通过多个客⼾端命令调⽤的例⼦说明 Redis 单线程命令处理机制,接着分析 Redis 单线程模型为什么性能如此之⾼,最终给出为什么理解单线程模型是使⽤和运维 Redis 的关键。
Redis 只使用一个线程处理所有的命令请求,而不是 Redis 服务器进程内部真的只有一个线程,有多个线程,多个线程是在处理网络IO
引出单线程模型
现在开启了三个 redis-cli 客⼾端同时执⾏命令。
客⼾端 1 设置⼀个字符串键值对:
客⼾端 2 对 counter 做⾃增操作:
客⼾端 3 对 counter 做⾃增操作:
我们已经知道从客⼾端发送的命令经历了:发送命令、执行命令、返回结果三个阶段,其中我们重点关注第 2 步。我们所谓的 Redis 是采⽤单线程模型执⾏命令的是指:虽然三个客户端看起来是同时要求 Redis 去执行命令的,但微观⻆度,这些命令还是采⽤线性⽅式去执⾏的,只是原则上命令的执⾏顺序是不确定的,但⼀定不会有两条命令被同步执⾏,如图 2-3、2-4、2-5 所⽰,可以想象 Redis 内部只有⼀个服务窗⼝,多个客⼾端按照它们达到的先后顺序被排队在窗⼝前,依次接受 Redis 的服务,所以两条 incr 命令⽆论执⾏顺序,结果⼀定是 2,不会发⽣并发问题,这个就是 Redis 的单线程执⾏模型。
图 2-3 宏观上同时要求服务的客⼾端
图 2-4 微观上客⼾端发送命令的时间有先后次序的
图 2-5 Redis 的单线程模型
为什么单线程还能这么快
这是个重要的面试题
通常来讲,单线程处理能⼒要⽐多线程差,例如有 10000 公⽄货物,每辆⻋的运载能⼒是每次 200 公⽄,那么要 50 次才能完成;但是如果有 50 辆⻋,只要安排合理,只需要依次就可以完成任务。那么为什么 Redis 使⽤单线程模型会达到每秒万级别的处理能⼒呢?可以将其归结为三点:
- 纯内存访问。Redis 将所有数据放在内存中,内存的响应时⻓⼤约为 100 纳秒,这是 Redis 达到每秒万级别访问的重要基础。
- 核心功能更简单。Redis 核心功能比数据库的核心功能更简单,数据库对于数据的插入删除查询都有更复杂的功能支持,这样的功能势必要花费更多的开销。
- 非阻塞 IO。Redis 使⽤ epoll 作为 I/O 多路复⽤技术的实现,再加上 Redis ⾃⾝的事件处理模型将 epoll 中的连接、读写、关闭都转换为事件,不在⽹络 I/O 上浪费过多的时间,如图 2-6 所⽰。
一个线程就可以管理多个 socket,对于 TCP 来说,服务器每次要服务一个客户端就要安排一个 socket,一个服务器服务多个客户端,就需要多个 socket,但很多情况下每个客户端和服务器之间的通信也没那么频繁,此时很多 socket 大部分时间都是静默的,是没有数据需要传输的,同一时刻只有少数 socket 是活跃的,因此就用个 IO多路复用,一个线程来处理多个 socket。
这是操作系统给程序员提供的机制,提供了一套 API,内部的功能都是操作系统实现的。
Linux 提供的 IO多路复用 主要是三套 API:
- select
- poll
- epoll
epoll 是个事件通知/回调机制,一个线程可以同时做多件事情,能高效完成多件事,但前提是这多件事交互是互不影响的,大部分时间都在等。
C++ 可以直接使用 Linux 原生的 epoll API;Java 可以使用 NIO,这是标准库提供的一组类,底层就是封装了 epoll。
- 单线程避免了线程切换和竞态产生的消耗。单线程可以简化数据结构和算法的实现,让程序模型更简单;其次多线程避免了在线程竞争同⼀份共享数据时带来的切换和等待消耗。
图 2-6 Redis 使⽤ I/O 多路复⽤模型
虽然单线程给 Redis 带来很多好处,但还是有⼀个致命的问题:对于单个命令的执⾏时间都是有要求的。如果某个命令执⾏过⻓,会导致其他命令全部处于等待队列中,迟迟等不到响应,造成客⼾端的阻塞,对于 Redis 这种⾼性能的服务来说是⾮常严重的,所以 Redis 是面向快速执行场景的数据库。
相关文章:
【Redis】数据类型详解及其应用场景
目录 Redis 常⻅数据类型预备知识基本全局命令小结 数据结构和内部编码单线程架构引出单线程模型为什么单线程还能这么快 Redis 常⻅数据类型 Redis 提供了 5 种数据结构,理解每种数据结构的特点对于 Redis 开发运维⾮常重要,同时掌握每种数据结构的常⻅…...
PARA-Drive:设计并行模型实现端到端自动驾驶
论文链接 https://openaccess.thecvf.com/content/CVPR2024/papers/Weng_PARA-Drive_Parallelized_Architecture_for_Real-time_Autonomous_Driving_CVPR_2024_paper.pdfhttps://openaccess.thecvf.com/content/CVPR2024/papers/Weng_PARA-Drive_Parallelized_Architecture_fo…...
vs2022 x64 C/C++和汇编混编 遇到的坑
vs2022 x64 C/C和汇编混编 遇到的坑 遇到的问题二、问题复现1.出错代码2.问题分析2.1 堆栈对齐问题 3.解决方案 总结奇数和偶数个寄存器的影响为什么 sub rsp, 8 对奇数个寄存器有用?结论 遇到的问题 0x00007FFFFAE24A29 (msvcp140.dll)处(位于 TestCompileConsole…...
PHP概述、环境搭建与基本语法讲解
目录 【学习目标、重难点知识】 什么是网站? 1. PHP 介绍 1.1. PHP 概述 1.1.1. PHP 是什么? 1.1.2. PHP 都能做什么? 1.2. PHP 环境搭建 1.2.1. PhpStudy 2. PHP 基本语法 2.1. PHP 语法入门 2.1.1. 第一个 PHP 程序 2.1.2. PHP …...
实现信创Linux麦克风摄像头录制(源码,银河麒麟、统信UOS)
随着信创国产化浪潮的来临,在国产操作系统上的应用开发的需求越来越多,其中一个就是需要在银河麒麟或统信UOS上实现录制摄像头视频和麦克风声音,将它们录制成一个mp4文件。那么这个要如何实现了? 一. 技术方案 要完成这些功能&a…...
深度学习9--目标检测
1.概念介绍 目标检测不仅可以检测数字,而且可以检测动物的种类、汽车的种类等。例如,自动驾驶车辆需要自动识别前方物体是车辆还是行人,需要自动识别道路两 旁的指示牌和前方的红绿灯颜色。对于自动检测的算法,有两个要求…...
第131天:内网安全-横向移动Kerberos 攻击SPN扫描WinRMWinRSRDP
案例一:域横向移动-RDP-明文&NTLM RDP利用的三种方式 1.直接在当前被控主机上进行远程连接 2.建立节点进行连接 3.端口转发,(访问当前主机的2222端口等于访问目标的3389) 第一种方式(动静太大) 直接利用被控主机进行远程连接…...
微信小程序的四种弹窗使用
在做小程序的过程中,弹窗也算是非常实用的功能了,这几天写的几个功能就用到了弹窗,也可能是初学者的问题,比较菜,想找一个可以带图片的自定义的弹窗,,这里简单介绍一下官方封装好的四个弹窗…...
我的第一个CUDA程序
MatAdd算法 实现两个矩阵对应元素相加 #include <stdio.h> #include <stdlib.h>// 矩阵加法函数 void MatAdd(int height, int width) {// 在主机内存中为 A、B 和 C 分配内存float* A (float*)malloc(height * width * sizeof(float));float* B (float*)malloc…...
workerman下的webman路由浏览器跨域的一种问题
软件版本 "php": ">7.2", "workerman/webman-framework": "^1.5.0",问题情景 使用“分组路由”做API接口前后端分离跨域,在接口测试工具调试是能正常获取数据的;但在网页浏览器上调试就遇到了CORS、404的错…...
Windows11 -MASKRCNN-部署测试
文章目录 Detectron2环境配置搭建python 环境安装Cuda \CUDNN 、PyTorch、 torchvision、cudatoolkit1、Cuda \CUDNN2、 PyTorch、 torchvision、cudatoolkit进入python测试:错误信息 3、detectron2环境在安装detecteron中,遇到报错:编译的时…...
函数(子程序)的常见、易混淆概念详解【对初学者有帮助】
C语⾔中的函数也被称做子程序,意思就是⼀个完成某项特定的任务的⼀小段代码。 C语⾔标准中提供了许多库函数,点击下面的链接可以查看c语言的库函数和头文件。 C/C官⽅的链接:https://zh.cppreference.com/w/c/header 目录 一、函数头与函…...
TiDB-从0到1-DM工具
TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇TiDB-从0到1-集群扩缩容TiDB-从0到1-数据导出导入TiDB-从0到1-BR工具 一、DM原理 支持全量抽取数据\检测新的数据变化同步到下游实例…...
AppScan——Web 应用安全扫描的得力工具
一、引言 在当今数字化时代,Web 应用成为企业业务的重要支撑,但同时也面临着各种安全威胁。AppScan 作为一款专业的 Web 应用安全扫描工具,为保障 Web 应用的安全性提供了有力的支持。本文将对 AppScan 进行详细介绍,包括其功能、…...
虚幻5|AI行为树,进阶篇
一,打开敌人的角色蓝图,编写以下蓝图,该蓝图只是创建一个敌人并非ai行为树 1.编写蓝图 2.打开主界面,创建一个导航网格体积,上一章都有讲,在添加体积这里面,找到导航网格体积,点击创…...
在 Spring Boot 中配置 Tomcat 监听多个端口
在现代微服务架构中,应用程序可能需要监听多个端口,以支持不同的服务或协议。Spring Boot 提供了灵活的配置选项,使得这一需求变得简单而高效。本文将介绍如何在 Spring Boot 中配置 Tomcat 以监听多个端口,并简要说明其中一些关键…...
stm32f407新建项目工程及烧录
1、新建一个文件夹,打开keil5将项目工程放入文件夹中 2、弹出选择对应型号设备 3、弹出选择对应库 可以看见出现下图:感叹号表示有错 最后如图所示:点击ok就行了 4、创建对应的文件夹存放文件 4、建立main.c 5、添加对应的设置 最后写一个空白…...
c++中加不加const的值传递和引用传递的区别
文章目录 可以修改参数值的比较值传递(int x)和引用传递(int &x)使用const不修改参数值的比较值传递(const int x)和引用传递(const int &x)1. const int x 示例2. const int &x 示例 可以修改参数值的比较值传递(int x)和引用传递(int &x) #include <iost…...
Qt的窗口设置
本文介绍Qt的窗口设置。 采用Qt开发界面程序,会涉及到窗口的设置,如窗口标题栏是否显示,是否有最小,最大化按钮等,窗口当前显示最小化,最大化等。本文简要介绍常用的窗口设置方法。 1.窗口属性 窗口属性…...
51单片机-LCD1602显示屏
简介 是一个液晶显示屏,通过电压对显示区域进行控制,有电就显示。 能够同时显示32个字符,分为两行,一行显示16个字符。可以显示的内容只能是字母、数字或者一些特殊符号。 使用ASCII码来让LCD1602来显示对应的字符。 电路图 …...
多模态分析代理 MAIA:多智能体解决 视觉模型 黑盒问题
多模态分析代理 MAIA:多智能体解决 视觉模型 黑盒问题 论文:https://arxiv.org/pdf/2404.14394 代码:https://github.com/multimodal-interpretability/maia 提出背景 神经网络方法提取的特征,没有可解释性。 数据在通过多个层…...
AT360-6T杭州中科微单频高精度授时模块场景应用
AT360-6T是一款高性能多系统卫星定位授时模块,基于自主研发的北斗多系统SOC芯片,可以同时接收中国的BDS(北斗二号和北斗三号)、美国的GPS、俄罗斯的GLONASS、欧盟的 GALILEO 和日本的QZSS等多个卫星导航系统的GNSS信号来实现多系统联合定位授时ÿ…...
Python酷库之旅-第三方库Pandas(081)
目录 一、用法精讲 336、pandas.Series.str.rpartition方法 336-1、语法 336-2、参数 336-3、功能 336-4、返回值 336-5、说明 336-6、用法 336-6-1、数据准备 336-6-2、代码示例 336-6-3、结果输出 337、pandas.Series.str.slice方法 337-1、语法 337-2、参数 …...
C语言基础⑩——构造类型(结构体)
一、数据类型分类 1、基本类型 整数型 短整型:short(2个字节);整型(默认):int(4个字节);长整型:long(8个字节)…...
宝兰德荣获openEuler项目群青铜捐赠人称号,共筑开源生态繁荣新篇章
近日,开放原子开源基金会正式公布了新增捐赠人名单,宝兰德凭借在开源领域的卓越贡献与深厚实力,被授予openEuler项目群青铜捐赠人称号。 开放原子开源基金会是致力于推动全球开源事业发展的非营利机构,于2020年6月在北京成立。开放…...
【Python单元测试】学习笔记3
文章目录 08.PyTest框架什么是PyTestPyTest的优点PyTest的测试环境PyTest常用参数跳过测试 09.PyTest fixture基础PyTest fixture定义和使用引用多个Fixture 10. conftest.pyconftest.py的用途 11. 参数化测试用例为什么需要参数化测试用例使用parameterizer插件实现使用pytest…...
OpenSSL源码编译及Debug
** 1. 环境 Linux 5.19.0-14-generic 22.04.1-Ubuntu 2. 所需工具 gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04) cmake version 3.22.1 3. 步骤 3.1 获取openssl源码 方法可以git clone获得源码,或者直接去GitHub上下载压缩包,GitHub网址…...
go之goburrow/modbus 学习
goburrow/modbus 是一个用Go语言实现的Modbus协议库,提供了Modbus主机(Master)和从机(Slave)的实现,支持两种主要的Modbus传输模式:Modbus TCP和Modbus RTU。 功能介绍 1. 支持的传输模式 Mod…...
开放词汇目标检测(Open-Vocabulary Object Detection, OVOD)算法是什么?
开放词汇目标检测(Open-Vocabulary Object Detection, OVOD)算法是什么? 随着计算机视觉技术的快速发展,目标检测(Object Detection)已经在各种应用场景中得到了广泛的应用。然而,传统的目标检…...
【教程】Ubuntu给pycharm添加侧边栏快捷方式
转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 以下教程不仅限于pycharm,其他软件也是一样操作 1、进入到pycharm的目录,先通过命令行打开pycharm: ./bin/pycharm…...
地方政府门户网站的建设/在线建站网页制作网站建设平台
在Windows server 2003上配置DHCP服务<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />实验二DHCP中继代理配置★ 实验环境1.准备三台电脑,一台作为客户机(XP),一台为DH…...
迪虎科技网站建设/怎么做好seo推广
这里需要注意include的两种不同写法,#include<***.h> 和 #include"***.h" 采用"< >"方式进行包含的头bai文件表示让编译器在编译器的预设标准路径下去搜索相应的头文件,如果找不到则报错。 例如:VS2008的安…...
网站的首页页面布局怎么做/谷歌浏览器app下载安装
如图 行尾空格不能使用下划线 解决方法 点击右上角的“文件” 选择“选项” 找到常规与保存 找到兼容性选项 勾选为尾部空格添加下划线 然后确定即可...
网站建设与运营考试/百度url提交
Flask > 目录结构 一:目标 1.要求: 1. 熟悉Flask的目录结构。 2. 了解应用,装上新的组件往里面放,改怎么弄? 2.作业: 1.基于flask实现权限管理 2.笔记: - flask的请求周期 二:…...
爱做的小说网站/网络软文推广平台
今天给大家推荐一个Android垂直型的SeekBar,可能对于你们在项目中有所帮助。这个已经有人具体实现。本人只是在这里稍做推荐。有关更多的好的控件本人在网上已建了一个网站专门做Android开源控件的收录以及示例代码的各种使用用法,目的是帮助更多的Android开发者&am…...
国外装修效果图网站/新公司做网站多少钱
最近在调74HC595,单片机IO直连控制74HC595,单片机输出3.3v, 而74HC595是5v供电。 将 74HC595改成3.3V供电可以完美控制,但是输出的电压为3.3V导致不能驱动继电器,所以还是得用5V供电,然后用三极管抬高单片机IO电压。 …...