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

【Redis学习2】Redis常用数据结构与应用场景

Redis常用数据结构与应用场景

redis中存储数据是以key-value键值对的方式去存储的,其中key为string字符类型,value的数据类型可以是string(字符串)、list(列表)、hash(字典)、set(集合) 、 zset(有序集合)。 这5种数据类型在开发中可以应对大部分场景的存储
在这里插入图片描述

拓展:key的底层存储方式SDS

这里有一个问题,当我们使用一条redis命令set key value的时候,redis进行了什么操作?
其实当我们使用命令操作redis的时候,也是会经过redis客户端到redis服务端的过程,这些命令相当于一个请求

  • redis客户端通过socket传输这些命令
  • redis服务端通过io读取到这些请求命令,把所有的命令解析成一个字符串,并执行对应命令操作,然后再经过socket写回操作结果!

同时redis是使用c语言写的,但它底层在存放redis的key时,并没有用c语言原生的字符串数据结构,而是定义了一个属于redis的数据结构SDS(Simple Dynamic String),

struct sdshdr{//记录buf数组中已使用字节的数量//等于 SDS 保存字符串的长度int len;//记录 buf 数组中未使用字节的数量int free;//字节数组,用于保存字符串char buf[];
}

为什么要用这样的一个数据结构去存储字符串呢?

  • 二进制安全的数据结构。 比如是操作命令是get aaa\0 :获取 aaa\0的值。如果是c语言的字符数组就会把\0吞掉,变为get aaa,而使用SDS就会完整的操作aaa\0SDS把所有接受到的数据都转成字符串,即使是一些特殊字符!
  • SDS提供了内存预分配机制,避免频繁的内存分配。 如果是c语言,在修改一个key时,会分配一个新的字符数组,然后进行内存赋值,而SDS则采用预先分配机制,直接把字符串容量扩大两倍,key的长度变化时,直接在已分配的内存中修改即可,如果不够继续扩大2倍
    思考:SDS采用的也是一种空间换时间的思路,无论是扩展之后分配多余空间从而降低下次扩展时需要再次内存分配的概率,还是缩容之后并不立即回收空间而是留给下次扩容,这两种操作都会导致空闲空间增大,内存占用提升,而Redis又了很多数据压缩策略来控制内存。
  • 杜绝缓冲区溢出。 在C语言原生的字符串中,当需要修改字符串且修改后的长度大于修改前的长度时,在修改之前需要先对原数组申请空间扩容,否则可能导致数组溢出,内容写入到相邻的下一个数组中从而改变下一个字符串的值。
    在SDS中,SDS屏蔽了用户对数组空间的分配,SDS在增长之前会根据free属性自动检测是否足够修改之后的字符串所需空间,如果足够则直接修改,并更新修改之后的len和free属性,如果当前剩余空间不够,SDS会根据空间分配策略自动进行扩容,无需用户关心。
    思考:类似于Java中的String类,高级容器等,会提供自动扩容,缩容的功能,具体的细节对使用者透明,能减少开发者的编码负担。

string+应用场景

常用操作

命令说明
SET key value存入字符串键值对
MSET key value [key value …]批量存储字符串键值对
SETNX key value存入一个不存在的字符串键值对
GET key获取一个字符串键值
MGET key [key …]批量获取字符串键值
EXPIRE key seconds设置一个键的过期时间(秒)
DEL key [key …]删除一个键
INCR key将key中储存的数字值加1
DECR key将key中储存的数字值减1
INCRBY key increment将key所储存的值加上increment
DECRBY key decrement将key所储存的值减去decrement
  • 设置和获取键值对
> SET key value
OK
> GET key
"value"

值得注意的是, 当key存在时,set命令会覆盖掉你上一次设置的值

> SET key newValue
OK
> GET key
"newValue"
  • 使用 EXISTSDEL 关键字来查询是否存在和删除键值对:
> EXISTS key
(integer) 1
> DEL key
(integer) 1
> GET key
(nil)
  • 批量设置键值对
> SET key1 value1
OK
> SET key2 value2
OK
> MGET key1 key2 key3    # 返回一个列表
1) "value1"
2) "value2"
3) (nil)
> MSET key1 value1 key2 value2
> MGET key1 key2
1) "value1"
2) "value2"
  • 过期和 SET 命令扩展
    可以对 key 设置过期时间,到时间会被自动删除,这个功能常用来控制缓存的失效时间。(过期可以是任意数据结构)
> SET key value1
> GET key
"value1"
> EXPIRE name 5    # 5s 后过期
...                # 等待 5s
> GET key
(nil)
  • 返回原值的 GETSET 命令
    对字符串,还有一个 GETSET 比较让人觉得有意思,它的功能跟它名字一样:为 key 设置一个值并返回原值:
> SET key value
> GETSET key value1
"value"

这可以对于某一些需要隔一段时间就统计的 key 很方便的设置和查看,例如:系统每当由用户进入的时候你就是用 INCR 命令操作一个 key,当需要统计时候你就把这个 key 使用 GETSET 命令重新赋值为 0,这样就达到了统计的目的。

使用场景

  • 单值缓存
SET key value
GET key

使用这两条命令可以做用户id存储、商品库存存储等等!

  • 对象存储
    以缓存user对象为例,有以下两种方式:
    (1)SET user:1 value(json格式数据):把对象转json存入redis,也是当下常用的方式,获取数据需要做数据转换
    (2)MSET user:1:name zhuge user:1:balance 1888
    MGET user:1:name user:1:balance
    使用Mset命令,把对象拆开存储,每一个key只保存对象的一个字段信息,适用于经常修改user的某个字段的场景
  • 分布式锁
SETNX product:10001 true //操作product:10001
##执行业务操作...
DEL product:10001 //删除product:10001

其中SETNX key value 命令要求如果key已存在,则其他的setnx命令无法对当前key进行操作。

在使用分布式锁时通常还会通过
SET product:10001 true ex 10 nx 命令设置key的超时时间,防止死锁!

  • 计数器
NCR 文章id

可以使用INCR命令实现数量自增,可以用于文章阅读量、热度人数统计等,用户每点进去一次执行一次INCR命令

  • 分布式系统全局序列号
    在分布式系统下,如果需要分库分表, mysql的数据库自增id已经无法满足分库分表下的id自增,这时就需要一个独立于数据库之外的中间件来实现id的分配。

redis的INCR命令可以实现id、序列号的生成,但如果用户量非常大,每生成一个id、序列号都去redis会给redis添加不小的压力,我们可以一次性从redis中自增1000次,把序列号放入本地内存中,这1000个id用完了,再去redis再取1000个,可有效降低redis的压力!

hash+应用场景

Redis 中的字典(hash)相当于 Java 中的 HashMap,内部实现也差不多类似,都是通过 “数组 + 链表” 的链地址法来解决部分 哈希冲突,同时这样的结构也吸收了两种不同数据结构的优点。

常用操作

命令说明
HSET key field value存储一个哈希表key的键值
HGET key field获取哈希表key对应的field键值
HMSET key field value [field value …]在一个哈希表key中存储多个键值对
HMGET key field [field …]批量获取哈希表key中多个field键值
HSETNX key field value存储一个不存在的哈希表key的键值
HDEL key field [field …]删除哈希表key中的field键值
HLEN key返回哈希表key中field的数量
HGETALL key返回哈希表key中所有的键值
HINCRBY key field increment为哈希表key中field键的值加上增量increment

字典相关操作

> HSET books java "think in java"    # 命令行的字符串如果包含空格则需要使用引号包裹
(integer) 1
> HSET books python "python cookbook"
(integer) 1
> HGETALL books    # key 和 value 间隔出现
1) "java"
2) "think in java"
3) "python"
4) "python cookbook"
> HGET books java
"think in java"
> HSET books java "head first java"  
(integer) 0        # 因为是更新操作,所以返回 0
> HMSET books java "effetive  java" python "learning python"    # 批量操作
OK

使用场景

  • 电商购物车
    1)以用户id为key === cart:1001
    2)以商品id为field===10088
    3)商品数量为value === 1
    因此,购物车操作可以如下:
    1)添加商品:hset cart:1001 10088 1
    2)增加数量 hincrby cart:1001 10088 1
    3)商品总数 hlen cart:1001
    4)删除商品 hdel cart:1001 10088
    5)获取购物车所有商品 hgetall cart:1001
    在这里插入图片描述

思考-优点:
1)同类数据归类整合储存,方便数据管理
2)相比string操作消耗内存与cpu更小
因为:string类型通过set key - val 的方式存储数据,通过对key进行hash运算决定当前key是存储在数组哪个位置。如果把hash类型的数据变成string类型来存储,则需要更多的key,同时在存放时也需要更多的hash(key)运算,消耗更多的cpu资源!
3)相比string储存更节省空间
如果把hash类型的数据变成string类型来存储,将需要存储更多key,如果数据量很多的情况下,redis底层那么存储数据的数组将很快会被占满,占满就会进行扩容,加大内存消耗。由此可见,string结构与hash结构只存储一个key相比,需要更多的内存空间!
思考-缺点:
1)过期功能不能使用在field上,只能用在key上
redis的过期时间只能用在key上,而hash的key是一个大的概念,里面的map型结构才是重要数据,但过期时间只能用在外边的大key上,hash结构相比于string不能实现精准过期!
2)hash结构在Redis集群架构下不适合大规模使用
因为如果一个hash的key中的属性很多的话,只能存在一个redis节点上,那么这个节点压力会比其他节点压力大很多,造成redis集群下压力分配不均衡!

list+应用场景

Redis 的列表相当于 Java 语言中的 LinkedList,注意它是链表而不是数组。这意味着 list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为 O(n)。

常用操作

命令说明
LPUSH key value [value …]将一个或多个值value插入到key列表的表头(最左边)
RPUSH key value [value …]将一个或多个值value插入到key列表的表尾(最右边)
LPOP key移除并返回key列表的头元素
RPOP key移除并返回key列表的尾元素
LRANGE key start stop返回列表key中指定区间内的元素,区间以偏移量start和stop指定
BLPOP key [key …] timeout从key列表表头弹出一个元素,若列表中没有元素,阻塞等待
timeout:秒,如果timeout=0,一直阻塞等待
BRPOP key [key …] timeout从key列表表尾弹出一个元素,若列表中没有元素,阻塞等待
timeout:秒,如果timeout=0,一直阻塞等待

list相关

  • LPUSHRPUSH分别可以向list的左边(头部)和右边(尾部)添加一个新元素
  • LRANGE命令可以从list中取出一定范围的元素
  • LINDEX命令可以从list中取出指定下标的元素,相当于java量表操作中的get(int index)操作
> rpush mylist A
(integer) 1
> rpush mylist B
(integer) 2
> lpush mylist first
(integer) 3
> lrange mylist 0 -1    # -1 表示倒数第一个元素, 这里表示从第一个元素到最后一个元素,即所有
1) "first"
2) "A"
3) "B"
  • list 实现队列
    队列是先进先出的数据结构,常用于消息排队和异步逻辑处理,它会确保元素的访问顺序:
> RPUSH books python java golang
(integer) 3
> LPOP books
"python"
> LPOP books
"java"
> LPOP books
"golang"
> LPOP books
(nil)
  • list 实现栈
    栈是先进后出的数据结构,跟队列正好相反
> RPUSH books python java golang
> RPOP books
"golang"
> RPOP books
"java"
> RPOP books
"python"
> RPOP books
(nil)

list的使用场景

  • 模拟分布式系统数据结构
    ①:Stack(栈) = LPUSH(左边放) + LPOP(左边取)
    ②:Queue(队列)= LPUSH(左边放) + RPOP(右边取)
    ③:Blocking MQ(阻塞队列)= LPUSH(左边放) + BRPOP(右边阻塞取:没有数据就阻塞!)
    思考:那么redis实现的数据结构和jdk中提供的数据结构有什么区别呢?
    答:jdk提供的数据结构仅在本服务中有用,如果在分布式环境下,则需要借助redis等中间件,模拟数据结构来统一管理数据。
  • 微博、朋友圈、公众号等,关注的文章列表展示
    假如 小明 关注了 中国青年报、三太子敖丙 等大V的订阅号,当这些大V发布订阅号时,通过推或拉的方式把消息LPUSH放入redis中属于小明的list中。其中key为msg:{小明_ID}。当小明要获取大V们发的消息时,使用LRANGE 命令从队列中获取指定个数的订阅号信息!!
# ①:MacTalk发微博,消息ID为10010
LPUSH msg:{小明_ID} 10010# ②:备胎说车发微博,消息ID为10086
LPUSH msg:{小明_ID} 10086# ③:查看最新微博消息(前4条)
LRANGE msg:{小明_ID} 0 4

思考:大V发了消息的是怎么存储在粉丝的redis中呢?一般有两种处理方案!
(1)推送,博主发了消息,通过线程先推送到在线粉丝的队列中,其他不在线的粉丝等后面系统在空闲的时候再慢慢推送过去
(2)拉取,如果粉丝太多,推的方案还是要很长时间去处理,还有一种方案就是拉,每一个粉丝上线后就去关注的博主那里拉取他发送的最新的消息,在使用LRANGE取出即可。

set+应用场景

Redis 的集合相当于 Java 语言中的 HashSet,它内部的键值对是无序、唯一的。它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 NULL。

set 的常用操作

命令说明
SADD key member [member …]往集合key中存入元素,元素存在则忽略,若key不存在则新建
SREM key member [member …]从集合key中删除元素
SMEMBERS key获取集合key中所有元素
SCARD key获取集合key的元素个数
SISMEMBER key member判断member元素是否存在于集合key中
SRANDMEMBER key [count]从集合key中选出count个元素,元素不从key中删除
SPOP key [count]从集合key中选出count个元素,元素从key中删除

set 的运算操作

命令说明
SINTER key [key …]交集运算
SINTERSTORE destination key [key …]将交集结果存入新集合destination中
SUNION key [key …]并集运算
SUNIONSTORE destination key [key …]将并集结果存入新集合destination中
SDIFF key [key …]差集运算
SDIFFSTORE destination key [key …]SDIFFSTORE destination key [key …]

集合set的基本使用

> SADD books java
(integer) 1
> SADD books java    # 重复
(integer) 0
> SADD books python golang
(integer) 2
> SMEMBERS books    # 注意顺序,set 是无序的
1) "java"
2) "python"
3) "golang"
> SISMEMBER books java    # 查询某个 value 是否存在,相当于 contains
(integer) 1
> SCARD books    # 获取长度
(integer) 3
> SPOP books     # 弹出一个
"java"

set的使用场景

  • 抽奖活动
    1)点击参与抽奖加入集合
    SADD key {userlD}
    2)查看参与抽奖所有用户
    SMEMBERS key
    3)随机抽取count名中奖者
    SRANDMEMBER key [count] ------元素不从集合中删除
    SPOP key [count] ------ 元素从集合中删除
  • 朋友圈点赞
    当某人在朋友圈发布消息,可用set来点赞展示
    在这里插入图片描述
    1)点赞
    SADD like:{消息ID} {用户ID}
    2)取消点赞
    SREM like:{消息ID} {用户ID}
    3)检查用户是否点过赞
    SISMEMBER like:{消息ID} {用户ID}
    4)获取点赞的用户列表
    SMEMBERS like:{消息ID}
    5)获取点赞用户数
    SCARD like:{消息ID}
  • 利用set的交、并、差集实现微博、微信关注模型
    关注模型如下图:

首先了解一下set的集合操作,假如有三个集合
set1:(a、b、c)
set2:(b、c、d)
set3:(c、d、e)

三个集合的
交集为:SINTER set1 set2 set3 ==> { c }
并集为:SUNION set1 set2 set3 ==> { a,b,c,d,e }
差集为:SDIFF set1 set2 set3 ==> { a }
差集计算方式:set1 - (set2并set3) = {a、b、c} - {b、c、d、e} = {a} 只保留a中单独存在的元素

共同关注A的人:可以用交集来实现
我可能认识的人:可以使用差集来实现,把我的好友求差集,例如a的好友={b,c},b的好友={a,c,d},那么a可能认识的人可以是,b-a={a,b,c,d}-{a,b,c} = {d}。当然这只是一个简单又不大现实的想法,相当于把对方的好友全部推荐给你了,真实情况的还需要考虑到关系网络,好友的权重数等

zset+应用场景

这可能使 Redis 最具特色的一个数据结构了,它类似于 Java 中 SortedSet 和 HashMap 的结合体,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以为每个 value 赋予一个 score 值,用来代表排序的权重。
zset相比于set多一个score 分值,正是根据这个分值进行排序,所以zset才能展示有序的数据

zset 的常用操作

命令说明
ZADD key score member [[score member]…]往有序集合key中加入带分值元素
ZREM key member [member …]从有序集合key中删除元素
ZSCORE key member返回有序集合key中元素member的分值
ZINCRBY key increment member为有序集合key中元素member的分值加上increment
ZCARD key返回有序集合key中元素个数
ZRANGE key start stop [WITHSCORES]正序获取有序集合key从start下标到stop下标的元素
ZREVRANGE key start stop [WITHSCORES]倒序获取有序集合key从start下标到stop下标的元素

zset的基本使用

> ZADD books 9.0 "think in java"
> ZADD books 8.9 "java concurrency"
> ZADD books 8.6 "java cookbook"> ZRANGE books 0 -1     # 按 score 排序列出,参数区间为排名范围
1) "java cookbook"
2) "java concurrency"
3) "think in java"> ZREVRANGE books 0 -1  # 按 score 逆序列出,参数区间为排名范围
1) "think in java"
2) "java concurrency"
3) "java cookbook"> ZCARD books           # 相当于 count()
(integer) 3> ZSCORE books "java concurrency"   # 获取指定 value 的 score
"8.9000000000000004"                # 内部 score 使用 double 类型进行存储,所以存在小数点精度问题> ZRANK books "java concurrency"    # 排名
(integer) 1> ZRANGEBYSCORE books 0 8.91        # 根据分值区间遍历 zset
1) "java cookbook"
2) "java concurrency"> ZRANGEBYSCORE books -inf 8.91 withscores  # 根据分值区间 (-∞, 8.91] 遍历 zset,同时返回分值。inf 代表 infinite,无穷大的意思。
1) "java cookbook"
2) "8.5999999999999996"
3) "java concurrency"
4) "8.9000000000000004"> ZREM books "java concurrency"             # 删除 value
(integer) 1
> ZRANGE books 0 -1
1) "java cookbook"
2) "think in java

zset应用场景

  • 实现热搜排行榜
    ①:点击 “国庆放假” 新闻时,为其分值+1
    ZINCRBY hotNews:20190819 1 国庆放假
    ②:展示当日排行前十
    ZREVRANGE hotNews:20190819 0 9 WITHSCORES
    ③:七日搜索榜单计算
    取7天的key求并集放入新的key=hotNews:20190813-20190819中,就得出这7天中的访问量排行榜
    ZUNIONSTORE hotNews:20190813-20190819 7
    hotNews:20190813 hotNews:20190814… hotNews:20190819
    ④:展示七日排行前十
    根据上边的并集,从新的key=hotNews:20190813-20190819中取出前10名
    ZREVRANGE hotNews:20190813-20190819 0 9 WITHSCORES

相关文章:

【Redis学习2】Redis常用数据结构与应用场景

Redis常用数据结构与应用场景 redis中存储数据是以key-value键值对的方式去存储的,其中key为string字符类型,value的数据类型可以是string(字符串)、list(列表)、hash(字典)、set(集合) 、 zset(有序集合)。 这5种数据类型在开发中可以应对大部分场景的…...

踩了大坑:https 证书访问错乱

文章目录一、问题排查及解决问题一:证书加载错乱问题二:DNS 解析污染问题问题三:浏览器校验问题二、终极解决方法2.1 可外网访问域名2.2 只能内网访问域名2.3 内网自动化配置2.4 错误解决一、问题排查及解决 今天遇到这样一个问题&#xff0…...

大数据技术之Hive(四)分区表和分桶表、文件格式和压缩

一、分区表和分桶表1.1 分区表partitionhive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录,每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择式选择查询所需要的分区,这样的查询效率辉提高很多。1.1.1 分区表基本语…...

环形缓冲区(c语言)

1、概念介绍 在我们需要处理大量数据的时候,不能存储所有的数据,只能先处理先来的,然后将这个数据释放,再去处理下一个数据。 如果在一个线性的缓冲区中,那些已经被处理的数据的内存就会被浪费掉。因为后面的数据只能…...

创建自助服务知识库的指南

在SaaS领域,自助文档是你可以在客户登录你的网站时为他们提供的最灵活的帮助方式,简单来说,一个自助知识库是一个可以帮助许多客户的文档,拥有出色的自助服务知识库,放在官网或者醒目的地方,借助自助服务知…...

分层测试(1)分层测试是什么?【必备】

1. 什么是分层测试? 分层测试是通过对质量问题分类、分层来保证整体系统质量的测试体系。 模块内通过接口测试保证模块质量,多模块之间通过集成测试保证通信路径和模块间交互质量,整体系统通过端到端用例对核心业务场景进行验证&#xff0c…...

开源ZYNQ AD9361软件无线电平台

(1) XC7Z020-CLG400 (2) AD9363 (3) 单发单收,工作频率400MHz-2.7GHz (4) 发射带PA,最大输出功率约20dbm (5) 接收带LNA,低…...

第四阶段-12关于Spring Security框架,RBAC,密码加密原则

关于csmall-passport项目 此项目主要用于实现“管理员”账号的后台管理功能,主要实现: 管理员登录添加管理员删除管理员显示管理员列表启用 / 禁用管理员 关于RBAC RBAC:Role-Based Access Control,基于角色的访问控制 在涉及…...

JPA——Date拓展之Calendar

Java Calendar 是时间操作类,Calendar 抽象类定义了足够的方法,在某一特定的瞬间或日历上,提供年、月、日、小时之间的转换提供方法 一、获取具体时间信息 1. 当前时间 获取此刻时间的年月日时分秒 Calendar calendar Calendar.getInstance(); int …...

一文吃透 Spring 中的 AOP 编程

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

Apple主推的智能家居是什么、怎么用?一篇文章带你从零完全入门 HomeKit

如果你对智能家居有所了解,那应该或多或少听人聊起过 HomeKit。由 Apple 开发并主推的的 HomeKit 既因为产品选择少、价格高而难以成为主流,又因其独特的优秀体验和「出身名门」而成为智能家居领域的焦点。HomeKit 究竟是什么?能做什么&#…...

SpringCloud系列知识快速复习 -- part 1(SpringCloud基础知识,Docker,RabbitMQ)

SpringCloud知识快速复习SpringCloud基础知识微服务特点SpringCloud常用组件服务拆分和提供者与消费者概念Eureka注册中心原理Ribbon负载均衡原理负载均衡策略饥饿加载Nacos注册中心服务分级存储模型权重配置环境隔离Nacos与Eureka的区别Nacos配置管理拉取配置流程配置热更新配…...

2023上半年北京/上海/广州/深圳NPDP产品经理认证报名

产品经理国际资格认证NPDP是国际公认的唯一的新产品开发专业认证,集理论、方法与实践为一体的全方位的知识体系,为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会(PDMA)成立于1979年…...

面试半年,总结了1000道2023年Java架构师岗面试题

半年前还在迷茫该学什么,怎样才能走出现在的困境,半年后已经成功上岸阿里,感谢在这期间帮助我的每一个人。 面试中总结了1000道经典的Java面试题,里面包含面试要回答的知识重点,并且我根据知识类型进行了分类&#xf…...

通过MySQL驱动拦截器实现执行sql耗时计算

文章目录背景具体实现MySQL5MySQL6MySQL8使用方法测试结果背景 公司的一个需求,公司既有的链路追踪日志组件要支持MySQL的sql执行时间打印,要实现链路追踪常用的手段就是实现第三方框架或工具提供的拦截器接口或者是过滤器接口,对于MySQL也不…...

易基因|独家分享:高通量测序后的下游实验验证方法——DNA甲基化篇

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。此前,我们分享了DNA甲基化研究的测序数据挖掘思路(点击查看详情),进而鉴定出研究的目的基因或目标区域的DNA甲基化。做完测序后,…...

java基础系列(七) 同步和异步理解

一. 问题描述 同步传输和异步传输是web和数据库的重要知识点,会被很多老师强调。那么,它们有什么相同点和不同点?它们对于我们学习编程的意义在哪里? 二. 概念 首先什么是同步和异步? 这里的同步是指&…...

吉林大学 程序设计基础 2022级 OJ期末考试 2.23

本人能力有限,发出只为帮助有需要的人。 以下为实验课的复盘,内容会有大量失真,请多多包涵。 1.双手剑士的最优搭配 每把剑有攻击力和防御力两个属性。双手剑士可以同时拿两把剑,其得到攻击力为两把剑中的攻击力的最大值&#…...

【项目实战】SpringMVC拦截器实战 - 自定义拦截器防止重复提交

一、背景说明 如何能够实现防止重复提交呢?以下是一种可选的方式。 二、代码实战 2.1 注册重复提交拦截器到SpringMVC中 @Configuration @AllArgsConstructor public class ResourcesConfig implements WebMvcConfigurer {private final RepeatSubmitInterceptor repeatSu…...

C++ STL:容器 Container

文章目录1、序列容器1.1、容器共性1.2、vectorvector 结构* vector 扩容原理* vector 迭代器失效1.3、dequedeque 结构deque 迭代器deque 模拟连续空间1.4、listlist 特殊操作list 结构list 迭代器2、关联式容器2.1、容器共性2.2、容器特性3、无序关联式容器3.1、容器共性3.2、…...

urllib之urlopen和urlretrieve的headers传入以及parse、urlparse、urlsplit的使用

urllib库是什么?urllib库python的一个最基本的网络请求库,不需要安装任何依赖库就可以导入使用。它可以模拟浏览器想目标服务器发起请求,并可以保存服务器返回的数据。urllib库的使用:1、request.urlopen(1)只能传入url的方式from http.clie…...

【C++】二叉搜索树的模拟实现

一、概念 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别…...

HNU工训中心:元器件及测量基础实验报告

工训中心的牛马实验 1.实验目的 1.熟悉测量验证常用元器件参数、 并采用替代法(测量回路电流)测量其伏安特性的方法。 2.熟悉测量误差及减小测量误差注意事项 2.实验仪器和器材 1.实验仪器. 直流稳压电源型号:IT6302 台式多用表型号:UT805A 2.实验( 箱)器材 电路实验箱…...

博客系统--自动化测试

项目体验地址(账号:123,密码:123)http://120.53.20.213:8080/blog_system/login.html项目后端说明:http://t.csdn.cn/32Nnv项目码云Gitee地址:https://gitee.com/GoodManSS/project/tree/master…...

Day903.自增主键不能保证连续递增 -MySQL实战

自增主键不能保证连续递增 Hi,我是阿昌,今天学习记录的是关于自增主键不能保证连续递增的内容。 MySql保证了主键是自增,但不相对连续;帮助开发人员快速识别每个行的唯一性,并提高查询效率。 自增主键可以让主键索引…...

02-MyBatis查询-

文章目录Mybatis CRUD练习1,配置文件实现CRUD1.1 环境准备Debug01: 别名mybatisx报错1.2 查询所有数据1.2.1 编写接口方法1.2.2 编写SQL语句1.2.3 编写测试方法1.2.4 起别名解决上述问题1.2.5 使用resultMap解决上述问题1.2.6 小结1.3 查询详情1.3.1 编写接口方法1.…...

外盘国际期货招商:2023年3月关注日历,把握重要投资机会

2023年3月大事件日历 关注大事日历,把握重要投资机会 3月1日:马斯克推出特斯拉宏图第三篇章 3月1-2日:G20外长会议 3月4-5日:全国两会召开 3月9日:中国2月CPI、PPI数据 待定(前次进行日期&#xff1a…...

Linux学习(9.1)文件系统的简单操作

以下内容转载自鸟哥的Linux私房菜 原文:鸟哥的 Linux 私房菜 -- Linux 磁盘与文件系统管理 (vbird.org) 磁盘与目录的容量 df:列出文件系统的整体磁盘使用量;du:评估文件系统的磁盘使用量(常用在推估目录所占容量) df du 实体…...

Hadoop综合案例 - 聊天软件数据

目录1、聊天软件数据分析案例需求2、基于Hive数仓实现需求开发2.1 建库2.2 建表2.3 加载数据2.4 ETL数据清洗2.5 需求指标统计---都很简单3、FineBI实现可视化报表3.1 FineBI介绍3.2 FineBI配置数据3.3 构建可视化报表1、聊天软件数据分析案例需求 MR速度慢—引入hive 背景&a…...

Python进阶-----面向对象1.0(对象和类的介绍、定义)

目录 前言: 面向过程和面向对象 类和对象 Python中类的定义 (1)类的定义形式 (2)深层剖析类对象 前言: 感谢各位的一路陪伴,我学习Python也有一个月了,在这一个月里我收获满满…...

天猫淘宝企业服务为中小微企业打造供应链智能协同网络,让采购不再将就!丨爱分析报告

编者按:近日天猫淘宝企业服务&爱分析联合发布《2023中小微企业电商采购白皮书》,为中小微企业采购数字化带来红利。 某水泵企业:线上客户主要是中小微企业,线上业绩遇到瓶颈,如何突破呢?某焊割设备企业…...

基于四信网络摄像机的工业自动化应用

方案背景 随着数控机床被广泛的应用在工业生产中,数控技术发展成为制造业的核心。 鉴于数控机床的复杂性,以及企业人力储备有限,设备的监控和维护必须借助外部力量,而如何实现车间实时监测成了目前迫切解决的问题。 方案需求 ①兼…...

软件测试2

一 web掐断三大核心技术 HTML:负责网页的结构 CSS:负责网页的美化 JS:负责网页的行为 二 工具的使用 改变HBuilder文字的大小: 工具-视觉主题设置-大小22-确定 三 html简介 中文定义:超文本标记语言 新建一个html…...

(二分查找)leetcode162. 寻找峰值

文章目录一、题目1、题目描述2、基础框架3、原题链接二、解题报告1、思路分析2、时间复杂度3、代码详解三、本题小知识一、题目 1、题目描述 峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值…...

spring boot 配合element ui vue实现表格的批量删除(前后端详细教学,简单易懂,有手就行)

目录 一.前言: 二. 前端代码: 2.1.element ui组件代码 2.2删除按钮 2.3.data 2.4.methods 三.后端代码: 一.前言: 研究了其他人的博客,找到了一篇有含金量的,进行了部分改写实现前后端分离&#xff0…...

hiveSQL开窗函数详解

hive开窗函数 文章目录hive开窗函数1. 开窗函数概述1.1 窗口函数分类1.2 窗口函数和普通聚合函数的区别2. 窗口函数的基本用法2.1 基本用法2.2 设置窗口的方法2.2.1 window_name2.2.2 partition by2.2.3 order by 子句2.2.4 rows指定窗口大小窗口框架2.3 开窗函数中加 order by…...

深度学习基础实例与总结

一、神经网络 1 深度学习 1 什么是深度学习? 简单来说,深度学习就是一种包括多个隐含层 (越多即为越深)的多层感知机。它通过组合低层特征,形成更为抽象的高层表示,用以描述被识别对象的高级属性类别或特征。 能自生成数据的中…...

在 WIndows 下安装 Apache Tinkerpop (Gremlin)

一、安装 JDK 首先安装 Java JDK,这个去官网下载即可,我下载安装的 JDK19(jdk-19_windows-x64_bin.msi),细节不赘述。 二、去 Tinkerpop 网站下载 Gremlin 网址:https://tinkerpop.apache.org/ 点击下面…...

从软件的角度看待PCI和PCIE(一)

1.最容易访问的设备是什么? 是内存! 要读写内存,知道它的地址就可以了,不需要什么驱动程序; volatile unsigned int *p 0xffff8811; unsigned int val; *p val; val *p;只有内存能这样简单、方便的使用吗&#xf…...

DSP_TMS320F28377D_ADC学习笔记

前言 DSP各种模块的使用,基本上就是 GPIO复用配置、相关控制寄存器的配置、中断的配置。本文主要记录本人对ADC模块的学习笔记。TMS320F28377D上面有24路ADC专用IO,这意味着不需要进行GPIO复用配置。 只需要考虑相关控制寄存器和中断的配置。看代码请直…...

springcloud3 Nacos中namespace和group,dataId的联系

一 Namespance和group和dataId的联系 1.1 3者之间的联系 话不多说,上答案,如下图: namespance用于区分部署环境,group和dataId用于逻辑上区分两个目标对象。 二 案例:实现读取注册中心的不同环境下的配置文件 …...

[YOLO] yolo理解博客笔记

YOLO v2和V3 关于设置生成anchorbox,Boundingbox边框回归的过程详细解读 YOLO v2和V3 关于设置生成anchorbox,Boundingbox边框回归的个人理解https://blog.csdn.net/shenkunchang1877/article/details/105648111YOLO v1网络结构计算 Yolov1-pytorch版 …...

清华源pip安装Python第三方包

一、更换PIP源PIP源在国外,速度慢,可以更换为国内源,以下是国内一些常用的PIP源。豆瓣(douban) http://pypi.douban.com/simple/ (推荐)清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/阿里云 http://mirrors.aliyun.com/pypi/simple/中…...

python线程池【ThreadPoolExecutor()】批量获取博客园标题数据

转载:蚂蚁学python 网址:【【2021最新版】Python 并发编程实战,用多线程、多进程、多协程加速程序运行】 https://www.bilibili.com/video/BV1bK411A7tV/?p8&share_sourcecopy_web&vd_sourced0ef3d08fdeef1740bab49cdb3e96467实战案…...

LearnOpenGL-入门-8.坐标系统

本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正 我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject LearnOpenGL中文官网:https://learnopengl-cn.github.io/ 文章目录坐标系统概述局部空间世界空…...

windows10使用wsl2安装docker

配环境很麻烦,想利用docker的镜像环境跑一下代码整个安装过程的原理是:windows使用docker,必须先安装一个linux虚拟机,才可运行docker,而采用wsl2安装虚拟机是目前最好的方法第一步 windows安装wsl2控制面板->程序-…...

Javascript的API基本内容(六)

一、正则表达式 1.定义规则 const reg /表达式/ 其中/ /是正则表达式字面量正则表达式也是对象 2.使用正则 test()方法 用来查看正则表达式与指定的字符串是否匹配如果正则表达式与指定的字符串匹配 ,返回true,否则false 3.元字符 比如&#xff0…...

电压放大器和电流放大器的区别是什么意思

在日常电子实验测试中,很多电子工程师都会使用到电压放大器和电流放大器,但是很多新手工程师却无法区分两者的区别,下面就让安泰电子来为我们讲解电压放大器和电流放大器的区别是什么意思。 一、电压放大器介绍: 电压放大器是一种…...

cast提前!最简单有效的神经网络优化方法,没有之一!

做优化有时候真的很头疼,绞尽脑汁的想怎么做算法等价,怎么把神经网络各层指令流水起来,在确保整网精度的同时,又有高性能。 但有时做了半天,却发现流水根本就流不起来,总是莫名其妙地被卡住。 真的是一顿…...

LeetCode刷题——动态规划(C/C++)

文章目录[简单]买股票的最佳时机[简单]爬楼梯[中等]最长递增子序列[中等]最大连续子数组和[简单]买股票的最佳时机 原题链接 题解 min:今天之前买股的最低价 res:最大利润 每一天比较今天和往前的最低价差值能否比最大利润还大 class Solution { publ…...