【复习】Redis
数据结构
Redis常见的数据结构
- String:缓存对象
- Hash:缓存对象、购物车
- List:消息队列
- Set:点赞、共同关注
- ZSet:排序
Zset底层?
Zset底层的数据结构是由压缩链表或跳表实现的
- 如果有序集合的元素 < 128,并且每个元素 < 64字节时,会用压缩列表作为Zset类型的底层数据结构
- 如果有序集合的元素不满足上面的条件,会用跳表作为Zset类型的底层数据结构
跳表是怎么实现的?
跳表在创建节点时,随机生成每个节点的层数。
跳表在创建节点时,先生成[0, 1]的随机数,如果随机数 < 0.25,层数就会增加一层;然后继续生成下一个随机数,直到随机数 > 0.25结束,最终确定该节点的层数
为什么Zset使用跳表而不是B+树?
- B+树的设计目标是优化磁盘,通过减少树的高度来降低磁盘寻道次数;跳表是基于链表,通过多级索引加速查询,内存访问模式更符合CPU缓存局部性。Redis是内存数据库,数据完全存储在内存中,不需要优化磁盘IO,B+树的磁盘特性对Redis意义不大,跳表的设计更优
- 跳表相比B+树实现起来更简单,B+树插入和删除可能需要触发节点的分裂和合并,跳表插入时只需要随机生成层高,删除时直接移除节点并调整指针即可。
- B+树每个节点需要存储多个键值和叶子节点,存在内存碎片;跳表每个节点只需要存储键值、层高、多个前向指针,内存占用更紧凑。
压缩列表是怎么实现的?
压缩列表是由连续内存块组成的顺序型数据结构,类似数组。
- 查找第一个元素和最后一个元素时间复杂度:O(1)
- 查找其他元素:只能逐个查找,复杂度O(n)
压缩列表的缺点:会发生连锁更新,导致压缩列表占用的内存空间要多次重新分配,这回直接影响到压缩列表的访问性能。
压缩列表只适合保存数据量不多的场景。
quicklist和listpack这两种数据结构就是为了尽可能地保持压缩列表节省内存的优势
哈希表怎么扩容的?
在正常服务请求阶段,插入的数据都会写到哈希表1中,此时哈希表2没有被分配空间,随着数据量的增多,触发了rehash操作:
- 给哈希表2分配空间,一般比哈希表1大2倍
- 将哈希表1的数据移动到哈希表2中
- 迁移完成后,把哈希表1的空间释放,并把哈希表2设置为哈希表1,在哈希表1新创建一个空白的哈希表,为下次rehash做准备。
存在问题:如果哈希表1非常大,那么每次迁移到哈希表2的时候,可能会对redis造成阻塞,无法响应其他请求。
解决:在rehash进行期间,每次进行新增、删除、查找操作,redis除了操作哈希表1,还会操作redis2,这样就把一次大量数据的迁移工作分摊到了多个请求中。
注:哈希表扩容时,如果来了一个读请求,会现在哈希表1里查找;如果没找到,才会到哈希表2里查找。
String是用什么存储的?为什么不用c语言的字符串?
redis中的string字符串使用SDS数据结构存储的,SDS结构如下:
- len:记录了字符串的长度
- alloc:分配给字节数组的空间长度
- flags:用来表示不同类型的SDS(sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64)
- buf[]:字符数组,用来保存实际数据
SDS数据结构可以O(1)获取字符串长度,c语言的字符串需要O(n)
SDS不需要"\0"来表示字符串结尾,有个len来记录字符串的长度(但是她为了兼容部分c的库函数,还是加了"\0")
C语言的字符串在追加的时候是不安全的,程序内部不会判断缓冲区大小是否够用,当缓冲区发生溢出后会导致程序异常;SDS结构里加入alloc和len,这样可以通过alloc - len来判断剩余缓冲区的大小,当缓冲区大小不够用时,redis会自动扩大SDS的空间大小。
线程模型
Redis为什么快?
单线程的redis吞吐量可以达到10w/s
- Redis大部分的操作都在内存中完成的,redis的瓶颈可能是机器的内存或网络带宽而非CPU
- Redis采用单线程模型可以避免多线程之间的竞争,省去了多线程切换带来的开销
- Redis采用IO多路复用机制处理大量客户端的Socket请求,在只运行单线程的情况下,该机制允许内核同时存在多个监听Socket和已连接Socket。
Redis的单线程指的是”接收客户端请求 -> 解析请求 -> 进行读写数据操作 -> 发送数据给客户端“这个过程是一个线程完成的,但是Redis程序不是单线程的,Redis在启动时,会启动后台线程
关闭文件、AOF刷盘、释放内存这些任务会创建单独的线程来处理,如果放在主线程来处理,Redis主线程就会发生阻塞。
Redis6也采用多个IO线程来处理网络请求,因为随着硬件的升级,Redis的性能瓶颈出现在网络IO的处理上
Redis怎么实现IO多路复用
因为Redis是单线程的,所有的操作都是按顺序进行,由于读写操作等待用户的输入和输出都是阻塞的,IO多路复用就是为了单线程的服务同时处理多个客户端的请求。
多路:指多个网络连接客户端
复用:指复用同一个进程
IO多路复用是使用一个线程来检查多个Socket的就绪状态,在单个线程中通过记录跟踪每个Socket的状态来管理处理多个IO流
日志
Redis的持久化方式?
Redis的读写操作都是发生在内存的,但是redis重启后,内存中的数据就会丢失,为了保证内存中的数据不丢失,就需要持久化机制,把数据存储到磁盘,这样Redis重启后就能从磁盘中恢复数据,Redis主要有两种持久化方式,分别是:
-
AOF日志:每执行一条写操作,就会把该命令以追加的方式写入文件中,redis重启时,会逐一执行这个文件里的命令将数据恢复。redis由三种写回磁盘的策略:
- Always:每次写操作命令执行完后,同步将AOF日志数据写回磁盘
- Everysec:每次写操作命令执行完后,先将命令写到缓冲区中,再每隔一秒将数据写回磁盘
- No:Redis不控制写回磁盘的时机,交给操作系统控制,每次写操作后先将命令写到缓冲区,由操作系统决定何时将命令写回磁盘。
-
RDB快照:RDB快照只记录一瞬间的内存数据,记录的是实际的数据。Redis有两个命令来生成RDB快照:
- save命令:在主线程中生成RDB文件(会阻塞主线程)
- bgsave命令:创建一个子线程来生成RDB文件(避免阻塞主线程)
AOF日志记录的是操作命令,用AOF做故障恢复时,需要全量把日志全部执行一遍,一旦AOF日志非常多,会造成Redis恢复操作慢。所以引入了RDB快照(记录一瞬间的内存数据,记录的是实际数据,AOF文件记录的是命令操作的日志,而不是实际数据)
内存淘汰和过期删除
内存淘汰和过期删除的区别?
内存淘汰是在内存满时会触发内存淘汰策略来淘汰一些不必要的资源
过期删除是将已过期的键值对进行删除
内存淘汰策略有哪些?
内存淘汰:当Redis内存达到设置的阈值时,Redis就会主动挑选部分key删除以释放更多的内存。
Redis在每次处理客户端命令时,都会对内存使用情况判断,如果必要,则执行内存淘汰。内存淘汰的策略有:
- 前缀:
- allkeys:对所有的key进行淘汰,从dict的哈希表中挑选
- volatile:只对设置了TTL的key进行淘汰,从expires的哈希表中挑选
- 后缀:
- ttl:淘汰ttl小的
- random:随机挑选
- lru:基于LRU算法
- lfu:基于LFU算法
过期删除策略?
redis的失效缓存不会立即删除,而是使用惰性删除 + 定期删除这两种策略配合
- 惰性删除:在访问或修改key时,判断key是否过期,如果过期就删除key;如果没有过期,就不做处理,返回正常的键值对
- 定期删除:每隔一段时间随机从数据库中取出一部分key进行检查,删除过期的key,如果过期的key≥选举的key的四分之一,则再次选取,直到<四分之一,这个过程可能会很长时间,所以需要设置循环的上限。
集群
Redis主从同步
-
全量同步:以下情况会发生全量同步
- 主从集群首次建立连接
- 从服务器断开连接时间过长
步骤:
- 从服务器发送SYNC命令,开始请求同步
- 主服务器收到SYNC命令后,生成RDB快照,并将生成的RDB文件发送到从服务器中
- 从服务器收到RDB文件后,先清空当前的数据集,并载入RDB文件中的数据
- 在RDB文件传输的过程中,如果又有新的指令,主服务器会将新的指令先放在缓冲区中,一旦RDB文件传输完成,主服务器又会将缓冲区里的命令发给从服务器,保证数据的一致性。
-
增量同步:允许从服务器从断点处继续同步
步骤:
- 从服务器在网络恢复后,发送psync命令
- 主服务器收到psync命令后,告诉从服务器接下来要用增量同步的方式同步数据
- 主服务器将从服务器断开这段时间内执行的命令,发送给从服务器。
(断开这段时间内执行的命令会存在主服务器的环形缓冲区中,主要存放的是最近传播的写命令,如果缓冲区里的一部分数据还没同步给从服务器,就已经被覆盖了,主服务器就会再次采取全量同步)
哨兵机制的原理?
redis的主从集群中,主从模式是读写分离的,如果主节点挂了,需要选择一个主节点变成从节点,如果没有哨兵机制,那么只能人工选择一个主节点变成从节点,还要通知其他从节点现在主节点的变更。
哨兵机制主要是实现了主从节点的故障转移,他会检测主节点是否存活,如果主节点挂了,就会选取一个从节点当成主节点,并且把新的主节点信息通知给其他的从节点。
哨兵机制选择主节点的算法?
-
故障节点主观下线:哨兵节点会定时对redis集群里的所有节点发送心跳包检测节点是否正常,如果一个节点没有恢复哨兵节点的心跳包,则认为该节点主观下线
-
故障节点客观下线:当一个节点被标记成故障,不代表这个节点下线了,但是如果哨兵集群中有超过quorum数量的哨兵节点认为该redis节点主观下线,则该redis客观下线
如果下线的redis节点是从节点或哨兵节点,则没有后续操作了;如果是主节点,则开始故障转移,从剩下的从节点中选出一个节点升级为主节点
-
哨兵集群中选择Leader:要从redis集群中选择一个节点变成主节点,必须先从哨兵节点中选取leader,一个哨兵节点至少要拿到quorunm个赞成票,才能成为Leader
-
哨兵Leader选择新主节点:哨兵Leader从redis从节点中选择一个redis节点作为主节点
- 首先判断slave节点与master节点断开时间长短,如果超过指定值(down-after-milliseconds * 10)则会排除该slave节点。
- 然后判断slave节点的slave-priority值,值越小优先级越高。(如果是0则用不参与选举,默认是0)
- 如果slave-priority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高。
- 最后是判断slave节点的运行id大小,越小优先级越高。
Redis集群的模式?
Redis缓存数据量大到一台服务器无法缓存时,就需要使用Redis切片集群,将数据分布在不同的服务器上,降低对单主节点的依赖。
一个切片有16384个哈希插槽,这些哈希插槽类似数据分区,根据他的key被映射到一个哈希槽中。
场景
为什么使用Redis
- Redis具备高性能:如果用户第一次访问Mysql中的某些数据,这个过程比较慢,因为是从磁盘上读取的;如果将该用户的数据缓存在Redis中,下次在访问这些数据的时候就可以直接从Redis中读取了,操作Redis缓存就是直接操作内存,速度快。【需要考虑Mysql和Redis中的数据一致性】
- Redis具备高并发:单台Redis的QPS是Mysql的10倍,所以访问Redis能承受的请求远远大于Mysql,因此可以考虑将数据库中一部分数据缓存到Redis中,这样就不需要每次请求都到数据库中查了。
为什么Redis比Mysql快?
- Redis是基于内存存储、Mysql是基于磁盘存储
- Redis是基于键值对结构,支持简单的数据结构;Mysql需要定义表结构、索引等复杂的数据结构
- Redis采用单线程可以避免多线程之间的竞争,省去了多线程切换带来的开销。
本地缓存和分布式缓存的区别
本地缓存:将数据存储在本地应用程序或服务器上,用于加速数据访问,本地缓存通常是使用内存作为存储介质,利用内存的高速读写来提高访问速度。
本地缓存:由于本地缓存是存储在本地内存中,访问速度快,而且能够降低对远程服务器的访问次数;但是本地缓存的可扩展性收到硬件资源的限制,无法支持大规模的数据存储。
分布式缓存:将数据存储在多个分布式节点上,通过协同工作来提供高性能的数据访问服务,利用多台服务器来分担数据存储和访问的压力。
分布式缓存:节点可以动态扩展,能够支持大规模数据存储和访问的需求;但是相对本地缓存,分布式存储的访问速度相对慢,因为数据需要从多个节点进行访问,且需要通过网络进行数据传输。
Redis分布式锁的实现原理?
分布式锁是分布式环境下并发控制的一种机制,用来控制某个资源在同一时刻只能被一个应用使用。
Redis本身可以被多个客户端共享,可以用来保存分布式锁,而且Redis的读写性能高,可以应对高并发锁的场景。
redis的set命令有个nx参数可以实现”key不存在时插入“,所以可以使用它实现分布式锁:
- 如果key不存在,则表示插入成功(加锁成功)
- 如果key存在,则表示插入失败(加锁失败)
加锁的操作要注意:
- 加锁包括了:读取锁变量、检查锁变量值、设置锁变量三个操作,需要以原子操作的方式完成,所以使用set命令要带上nx选项来实现加锁。
- 锁变量需要设置过期时间,以免客户端拿到锁后发生异常,导致锁一直无法释放
- 锁变量的值需要能够区分来自不同客户端的加锁操作。
大Key问题?
字符串类型的Key对应的Value值占用空间很大就是大Key问题
大Key问题会导致:内存占用过高,从而触发内存淘汰策略;大Key会占用大量内存,导致性能下降;会造成网络拥堵;会导致主从同步延迟
解决:
- 对大Key进行拆分,将一个含有数万成员的hashkey拆分成多个hashkey;
- 将不适用Redis的数据移到别的地方存储,并在Redis中异步删除这个数据
什么是热key?
一般是以key的请求频率来判断的,例如:
- QPS集中在特定的key
- 带宽使用率集中在特定的Key
- CPU使用时间占比集中在特定的Key
解决:
- 将对应的热ky进行复制并迁移到其他的数据分片,来解决单个数据分片的热key压力
- 如果热key的产生来自读请求,可以使用读写分离架构来降低每个数据分片的读请求,也可以不断增加从节点。
怎么保证redis和mysql数据缓存的一致性?
- 对于读数据,如果redis不命中,会先去数据库中查询后加载到redis中
- 对于写数据,会更新数据库后去删除缓存
缓存系统就是CAP中的AP,通过牺牲强一致性来提高性能,如果需要数据库和缓存保持强一致性,就不适合用缓存。
缓存的过期时间设置是太短、太长都不好:
- 太短的话,请求可能会比较多的落在数据库上,就失去了缓存的意义
- 太长的话,缓存中的脏数据会让系统长时间处于一个延迟的状态,会浪费内存。
通过一些方案是可以达到最终一致性的(针对删除缓存异常的情况):
- 删除缓存重试策略(消息队列):如果删除缓存失败,可以从消息队列中重新读取数据,然后再删除缓存;如果删除缓存成功,就要把数据从消息队列中移除,避免重复操作。
- 订阅MySQL binlog,再操作缓存:正常操作是先更新数据库,再删除缓存,一旦数据库更新成功,就会产生一条变更日志记录再binlog里,我们通过订阅binlog日志,拿到要操作的数据,然后执行缓存删除。
缓存雪崩、缓存击穿、缓存穿透是什么?
-
缓存雪崩:大量缓存数据同时失效,或redis宕机,如果有大量的用户请求,都无法在redis中处理,于是请求直接访问数据库,造成数据库的压力,严重的会导致数据库宕机
- 如果要给缓存设置过期时间,应该避免大量的数据设置同一个过期时间,可以在设置过期时间的时候给这些数据加上随机数,这样数据就不会在同一时间过期
- 当业务线程在处理用户请求时,如果访问的数据不在redis里,就加个互斥锁,保证同一时间只能由一个请求来构建缓存(未能获取互斥锁的请求要么锁释放后重新读取缓存,要么返回空值或默认值),互斥锁一定要设置过期时间,不然一个请求拿到锁可能因为一些意外而阻塞,这时其他请求也一直拿不到锁。
- 让缓存“永久有效”,将更新缓存的工作交给后台线程定时更新
-
缓存击穿:缓存中某个热点数据过期,大量的请求访问该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易被高并发的请求冲垮。
- 当业务线程在处理用户请求时,如果访问的数据不在redis里,就加个互斥锁,保证同一时间只能由一个请求来构建缓存(未能获取互斥锁的请求要么锁释放后重新读取缓存,要么返回空值或默认值),互斥锁一定要设置过期时间,不然一个请求拿到锁可能因为一些意外而阻塞,这时其他请求也一直拿不到锁。
- 不给热点数据设置过期时间,由后台异步更新缓存,或者在热点数据过期前,提前通知后台线程更新缓存
缓存击穿可以理解成时缓存雪崩的一个子集,缓存雪崩指的是大量的key过期,而缓存击穿特指的是热点key过期。
-
缓存穿透:用户访问的数据即不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库,数据库也没有对应的数据,当有大量的这种请求到来,数据库的压力就会很大。
- 在Api入口处判断要请求的参数是否合法,如果不合法直接返回错误,防止进一步去访问数据库和缓存
- 可以争对查询的数据,在缓存中也设置一个空值或默认值,这样后续的请求就可以从缓存中获取空值或默认值返回给应用,而不会继续查询数据库
- 布隆过滤器:在写入数据库数据时,先用布隆过滤器做个标记,在用户请求到来时,业务线程确认缓存失效后,可以通过查询布隆过滤器快速判断数据是否存在,不存在就不通过查询数据库来判断数据库来判断数据是否存在。即使发生了缓存穿透,大量的请求只会查询Redis和布隆过滤器,而不会查询数据库。
介绍一下布隆过滤器的原理
在写入数据库数据时,先用布隆过滤器做个标记。
请求过来会先经过布隆过滤器,布隆过滤器先判断数据库中是否存在这条数据,如果不存在,就会拒绝这个请求。
注意,布隆过滤器判断一个元素不存在时,它绝对不存在;但是如果它判断一个元素存在,这个元素可能会不存在。
如何实现秒杀场景处理高并发以及超卖现象?
-
在数据库层面:
- 在查询商品库存时加排他锁,比如“select * from goods where id = #{id} for update”,此时相当于对id为#{id}的数据行加锁,其他线程可以使用select读取数据,但是如果是select for update、update、delete都会阻塞,直到线程A提交事务,其他线程才能获得锁。
- 在更新数据库的时候,可以通过加一个库存限制的条件“select * from goods where id = #{id} and stock > 0”
-
利用分布式锁:同一个key,同一个时间只有一个客户端拿到锁,其他客户端会陷入无限等待来尝试获取锁,只有获得锁的客户端才能执行接下来的业务逻辑
缺点:同一个商品在多个用户同时下单时,会基于分布式锁串行化处理,导致没法同时处理用同一个商品的大量下单请求。
-
利用Redis的incr、decr的原子性 + 异步性:
- 系统初始化时,将商品库存加到Redis中
- 收到秒杀请求时,再redis中进行预减库存(利用incr、decr的原子性),当redis中库存不足时,直接返回秒杀失败
- 把秒杀请求放入异步队列,返回正在排队中
- 服务端异步请求出队(有些商品规定用户只能购买一次,防止重复秒杀),出队成功的商品可以生成秒杀订单,扣减库存
- 用户在客户端申请秒杀请求后,会有个定时任务进行查询,查看秒杀是否成功,如果秒杀成功就进入秒杀订单详情,否则就会提示秒杀失败。
相关文章:
【复习】Redis
数据结构 Redis常见的数据结构 String:缓存对象Hash:缓存对象、购物车List:消息队列Set:点赞、共同关注ZSet:排序 Zset底层? Zset底层的数据结构是由压缩链表或跳表实现的 如果有序集合的元素 < 12…...
【Docker】如何在Linux、Windows、MacOS中安装Docker
Linux安装Docker 在终端中执行一键安装脚本命令安装dockersudo curl -fsSL https://gitee.com/tech-shrimp/docker_installer/releases/download/latest/linux.sh | bash -s docker --mirror Aliyun1.1 配置docker镜像源 在终端执行 一行命令,编辑配置文件sudo tee /etc/docke…...
Linux System V - 消息队列与责任链模式
概念 消息队列是一种以消息为单位的进程间通信机制,允许一个或多个进程向队列中发送消息,同时允许一个或多个进程从队列中接收消息。消息队列由内核维护,具有以下特点: 异步通信:发送方和接收方不需要同时运行&#x…...
k2路由器登录校园网
教程1刷入Breed,并手动刷入Padavan固件:斐讯K1、K2、K2P 刷机、刷入Breed 辅助工具 | tb (tbvv.net) Padavan下载网址: 我用的是: Padavan 登录的网址是 192.168.123.1 Padavan配置教程: 先用网线连上校园网&#…...
Docker基础实践与应用举例
Docker 是一个轻量级容器化平台,通过将应用及其依赖打包到容器中,实现快速部署和环境一致性。以下是 Docker 的实践与应用场景举例,结合具体操作步骤: 一、基础实践 1. 快速启动一个容器 # 运行一个Nginx容器,映射宿…...
EndNote与Word关联:科研写作的高效助力
在科研领域,文献管理与论文写作是紧密相连的重要环节。EndNote作为一款强大的文献管理工具,与Word实现有效关联后,能极大地提升科研写作效率。本文将详细介绍EndNote与Word关联的方法、关联后的优势、常见问题及解决办法,助力科研…...
用PyTorch从零构建 DeepSeek R1:模型架构和分步训练详解
DeepSeek R1 的完整训练流程核心在于,在其基础模型 DeepSeek V3 之上,运用了多种强化学习策略。 本文将从一个可本地运行的基础模型起步,并参照其技术报告,完全从零开始构建 DeepSeek R1,理论结合实践,逐步…...
SOME/IP-SD -- 协议英文原文讲解2
前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 5.1.2.2 S…...
Matlab——图像保存导出成好看的.pdf格式文件
点击图像的右上角,点击第一个保存按钮键。...
Mybatis常用动态 SQL 相关标签
1. <if> 用于条件判断,当满足条件时执行对应的 SQL 片段。 示例: <select id"findUser" resultType"User">SELECT * FROM usersWHERE 11<if test"name ! null and name ! ">AND name #{name}</if><if…...
计算机网络与通讯知识总结
计算机网络与通讯知识总结 基础知识总结 1)FTP:文件传输 SSH:远程登录 HTTP:网址访问 2)交换机 定义:一种基于MAC地址实现局域网(LAN)内数据高速转发的网络设备,可为接入设备提供独享通信通道。 - 核心功能: 1.数据链路层(OSI第二层)工作,通过MAC地址…...
Redis 通用命令
Redis 通用命令 文章目录 Redis 通用命令 1. 启动redis 1.1 前台启动1.2 后台启动1.3 开机自启 2.Redis命令行客户端3. 常见命令 3.1 help3.2 KEYS3.3 DEL3.4 EXISTS3.5 EXPIRE&TTL 1. 启动redis 1.1 前台启动 在安装好redis后,我们可以在任意目录输入以…...
【idea问题排查技巧】
以下是针对 IDEA 中 日志打标(动态标记) 和 全链路追踪 功能的分步详解,结合具体场景和操作截图说明,帮助快速掌握实战技巧。 一、动态日志打标:不修改代码输出关键信息 1. 断点日志打印(非侵入式打标) 场景:在调试时,需要临时查看某个变量的值,但不想修改代码添加…...
VSCode自定义快捷键和添加自定义快捷键按键到状态栏
VSCode自定义快捷键和添加自定义快捷键按键到状态栏 📄在VSCode中想实现快捷键方式执行与某些指令操作进行绑定,可以通过配置组合式的键盘按键映射来实现,另外一种方式就是将执行某些特定的指令嵌入在面板菜单上,在想要执行的时候…...
【Redis 原理】通信协议 内存回收
文章目录 通信协议--RESP内存回收内存过期策略惰性删除周期删除 内存淘汰策略 通信协议–RESP Redis是一个CS架构的软件,通信一般分两步(不包括pipeline和PubSub): 客户端(client)向服务端(se…...
AWS - Redshift - 外部表读取 Parquet 文件中 timestamp 类型的数据
问题: 通过 Redshift Spectrum 功能可以读取 S3 中的文件,当读取 Parquet 文件时,如果列格式设置为 timestamp, 通过 psql 客户端读取会出现以下错误: testdb# select * from myspectrum_schema_0219.test_ns; ERROR…...
H5--开发适配
在 H5 开发中,适配不同设备和屏幕尺寸至关重要,它能确保页面在各种环境下都有良好的显示效果和用户体验。以下介绍几种常见的 H5 开发适配方案: 视口(Viewport)设置 视口单位是相对于浏览器视口的尺寸进行度量的单位&…...
llama-factory部署微调方法(wsl-Ubuntu Windows)
llama-factory项目GitHub地址:GitHub - hiyouga/LLaMA-Factory: Unified Efficient Fine-Tuning of 100 LLMs & VLMs (ACL 2024) wsl-Ubuntu: 1.获取项目 git clone https://github.com/hiyouga/LLaMA-Factory.gitcd LLaMA-Factory/ 2.安装环境…...
【Unity】鱼群效果模拟
鱼群效果模拟 文章目录 鱼群效果模拟Boid算法实现方式version1_CPUversion2_GPUversion3_Multilaterationversion4_Bitonic_Sorting (GPU友好)version5_Skinning (TODO) 细节项优化项参考链接 Boid算法 Boid算法是一种模拟群体行…...
C++ 编程语言简介
C 是一种通用编程语言,它是作为 C 语言的增强而开发的,以包含面向对象的范例。它是一种命令式和编译语言。 C 是一种高级的通用编程语言,专为系统和应用程序编程而设计。它由贝尔实验室的 Bjarne Stroustrup 于 1983 年开发,作为…...
Day15-后端Web实战-登录认证——会话技术JWT令牌过滤器拦截器
目录 登录认证1. 登录功能1.1 需求1.2 接口文档1.3 思路分析1.4 功能开发1.5 测试 2. 登录校验2.1 问题分析2.2 会话技术2.2.1 会话技术介绍2.2.2 会话跟踪方案2.2.2.1 方案一 - Cookie2.2.2.2 方案二 - Session2.2.2.3 方案三 - 令牌技术 2.3 JWT令牌2.3.1 介绍2.3.2 生成和校…...
迪威模型:引领 3D 模型轻量化技术革新
在数字化时代,3D 模型的应用领域愈发广泛,从影视制作、游戏开发到工业设计、建筑仿真等,都离不开 3D 模型的支持。然而,随着模型复杂度的不断提高,文件体积也日益庞大,这给存储、传输和加载带来了极大的挑战…...
大学本科教务系统设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点
以下是大学本科教务系统的设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点: 大学本科教务系统设计方案 一、需求分析 1. 核心用户角色 角色功能需求学生选课/退课、成绩查询、课表查看、学分统计、考试报名、学业预警教师成绩录入、课程大纲上传、教学进度管理、…...
安装Liunx(CentOS-6-x86_64)系统
一:下载与安装Liunx(CentOS-7-x86_64) 1.下载: CentOS-6.10-x86_64-bin-DVD1.iso 2.安装: 按照自己的需求来 下载的镜像文件地址 加载完成后设置 查看网络和本地ip 3.配置仓库(用于yum下载࿰…...
DeepSeek开源周 Day01:从FlashMLA背后原理回顾KV Cache
FlashMLA 今天DeepSeek开源周第一天,开放了FlashMLA仓库,1小时内星标1.6k! FlashMLA 是一个高效的 MLA 解码内核,专为 Hopper GPU 优化,适用于可变长度序列。该项目目前发布了 BF16 和具有 64 块大小分页 kvcache 的功…...
java23种设计模式-工厂方法模式
工厂方法模式(Factory Method Pattern)学习笔记 🌟 定义 工厂方法模式属于创建型设计模式,定义一个创建对象的接口,但让子类决定实例化哪一个类。将类的实例化操作延迟到子类,是面向对象设计中"开闭…...
数据驱动未来!天合光能与永洪科技携手开启数字化新篇章
在信息化时代的今天,企业间的竞争早就超越了传统产品与服务的范畴,新的核心竞争力即——数据处理能力和信息技术的应用。作为数据技术领域的领军者,永洪科技凭借其深厚的技术积累和丰富的行业经验,成功助力天合光能实现数字化升级…...
【C++设计模式】工厂方法设计模式:深入解析从基础到进阶
1. 引言 在软件开发的世界里,设计模式如同巧妙的建筑蓝图,为解决常见问题提供了行之有效的方案。工厂方法模式作为一种广受欢迎的创建型设计模式,以其独特的优势在众多项目中得到广泛应用。它不仅能够为对象的创建提供通用且灵活的方式,还能有效隐藏实现细节,提升代码的可…...
Vue 3 + Vite 项目中配置代理解决开发环境中跨域请求问题
在 Vue 3 Vite 项目中,配置代理是解决开发环境中跨域请求问题的常见方法。通过在 Vite 的配置文件中设置代理,可以将前端请求转发到后端服务器,从而避免浏览器的同源策略限制。 1. 创建 Vue 3 Vite 项目 首先,确保你已经安装了…...
2.3 变量
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 变量是用来存放某个值的数据,它可以表示一个数字、一个字符串、一个结构、一个类等。变量包含名称、类型和值。在代码中…...
16、Python面试题解析:python中的浅拷贝和深拷贝
在 Python 中,浅拷贝(Shallow Copy) 和 深拷贝(Deep Copy) 是处理对象复制的两种重要机制,它们的区别主要体现在对嵌套对象的处理方式上。以下是详细解析: 1. 浅拷贝(Shallow Copy&a…...
BUUCTF-Web方向21-25wp
目录 [HCTF 2018]admin弱口令session伪造 [MRCTF2020]你传你🐎呢[护网杯 2018]easy_tornado[ZJCTF 2019]NiZhuanSiWei[MRCTF2020]Ez_bypass第一层第二层 [HCTF 2018]admin 打开环境,有三处提示,一个跳转链接,一个登录注册&#x…...
elementPlus 中表单验证方法(手机号、正整数、邮箱)
1、手机号验证 <el-form ref"formRef" :model"form" :rules"rule" label-width"100px"><el-form-item label"联系电话" prop"mobile"><el-input type"tel" v-model"form.mobile&q…...
阿里云 ACS:高效、弹性、低成本的容器计算解决方案
阿里云的 容器计算服务(Alibaba Cloud Container Service, ACS) 是一种 Serverless 容器计算 解决方案,提供高度弹性、低成本、易管理的 Kubernetes(K8s)容器运行环境。用户无需关注底层服务器资源,而是直接…...
启动Redis报错记录
突然启动Redis就报了个错:‘Could not create server TCP listening socket 127.0.0.1:6379: bind: 操作成功完成。‘ 查了下解决方案,应该是6379端口已绑定,服务没有关闭。 需要输入命令redis-cli 再输入shutdown 但又出现了新的问题&…...
springBoot统一响应类型2.0版本
前言: 通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往…...
ubuntu离线安装Ollama并部署Llama3.1 70B INT4
文章目录 1.下载Ollama2. 下载安装Ollama的安装命令文件install.sh3.安装并验证Ollama4.下载所需要的大模型文件4.1 加载.GGUF文件(推荐、更容易)4.2 加载.Safetensors文件(不建议使用) 5.配置大模型文件 参考: 1、 如…...
Unity游戏制作中的C#基础(4)数组声明和使用
一、数组的声明 在 C# 中,声明数组有多种方式,每种方式都有其适用的场景,下面为你逐一详细介绍: 1. 直接初始化声明 这种方式直观且便捷,在声明数组的同时就为其赋初值,让数组从诞生之初就拥有了具体的数据…...
自定义SpringBoot Starter
✅自定义SpringBoot Starter SpringBoot 的 starter 可以帮我们简化配置,非常的方便,定义起来其实也不复杂,我的项目中定义了很多 starter,比如business-job就是一个 stater,以他为例,介绍下如何定义 star…...
电脑经常绿屏(蓝屏)怎么办(解决方法)?
一、排查系统与驱动问题 进入安全模式修复系统 强制重启电脑 3 次触发恢复环境,选择 疑难解答 > 高级选项 > 启动设置 > 重启,按 F5 或 5 进入带网络连接的安全模式3。 在安全模式下,尝试卸载最近安装的软件或更新,尤其…...
IO/网络IO基础全览
目录 IO基础CPU与外设1. 程序控制IO(轮询)2. 中断中断相关知识中断分类中断处理过程中断隐指令 3. DMA(Direct Memory Access) 缓冲区用户空间和内核空间IO操作的拷贝概念传统IO操作的4次拷贝减少一个CPU拷贝的mmap内存映射文件(m…...
DPVS-5: 后端服务监控原理与测试
后端监控原理 被动监测 DPVS自带了被动监控,通过监控后端服务对外部请求的响应情况,判断服务器是否可用。 DPVS的被动监测,并不能获取后端服务器的详细情况,仅仅通过丢包/拒绝情况来发觉后端服务是否可用。 TCP session state…...
前端基础知识
1. 变量和常量 1.1 变量 // 变量let name Jacklet age 20name lisiage 18 1.2 常量 // 常量const PI 3.14// PI 3.1415926 // error,常量不可重新赋值const articleList []const user {name: vue3,age: 10} 1.3 const 声明的数组和对象 因为数组和对象在…...
从零到一学习c++(基础篇--筑基期十一-类)
从零到一学习C(基础篇) 作者:羡鱼肘子 温馨提示1:本篇是记录我的学习经历,会有不少片面的认知,万分期待您的指正。 温馨提示2:本篇会尽量用更加通俗的语言介绍c的基础,用通俗的语言去…...
Linux 第三次脚本作业
源码编译安装httpd 2.4,提供系统服务管理脚本并测试(建议两种方法实现) 一、第一种方法 1、把 httpd-2.4.63.tar.gz 这个安装包上传到你的试验机上 2、 安装编译工具 (俺之前已经装好了) 3、解压httpd包 4、解压后的httpd包的文…...
C#与AI的交互(以DeepSeek为例)
C#与ai的交互 与AI的交互使用的Http请求的方式,通过发送请求,服务器响应ai生成的文本 下面是完整的代码,我这里使用的是Ollama本地部署的deepseek,在联网调用api时,则url会有不同 public class OllamaRequester {[Se…...
Sky Hackathon 清水湾的水 AI美食助手
这里写自定义目录标题 视频 视频 video...
基于SpringBoot的校园消费点评管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
企业财务数据分析-投资回报指标ROA
上一篇文章主要介绍了关于投资回报的核心指标ROE,其实还有一个比较关键的指标资产回报率指标(ROA),资产收益率是用来衡量企业盈利能力的重要财务分析指标。资产收益率越高,说明企业资产的利用效率越高,利用…...
PostgreSQL 支持字段类型
PostgreSQL 支持多种字段类型,以下是常见的主要类别和具体类型的简要概述: 数值类型 SMALLINT:2字节整数,范围 -32768 到 32767 INTEGER:4字节整数,范围 -2147483648 到 2147483647 BIGINT:8字节…...