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

Redis源码学习 -- 基本数据结构 -- Quicklist - -蓝蜗牛

1. 什么是 Quicklist?

Quicklist​​是Redis自主研发的一种双向表数据结构,是List的底层数据结构之一。设计的核心思想是在时间和空间之间取一个平衡点。

2. Quicklist vs 普通链表 vs Listpack

List系列命令的设计目标:两端操作O(1),随机操作O(n)

  • 普通链表存在的问题?
    普通链表实现双向遍历需要保存两个指针,浪费内存空间。

  • Listpack存在的问题?
    头部增删改操作是O(n),只有元素少的时候才能看成O(1)

为了解决上述问题,Quicklist的设计思想是将两者结合起来。将数据分割成多个Listpack,然后用普通链表将Listpack串起来。Quicklist基本结构如图:

Quicklist-1-datastruct

如此一来,不仅节省大量空间,而且随机操作的速度比原来更快。
最好情况下是O(n^0.5),如:1000000个元素均匀拆分成了1000个Listpack,访问最中间的元素需要遍历 500个Node + 500个元素。
最坏情况下是O(n),每个Listpack只有1个元素退化成普通链表。

3. Quicklist 的优化方法

3.1 Listpack 分割策略

Quicklist基本结构上,高效的核心是避免每个Listpack的元素过多或过少。
避免元素过多的方法:配置阈值,使得Listpack元素数量不能超过阈值或者Listpack占用的空间不能超过阈值。如果超过阈值则分割成两个Listpack
避免元素过少的方法:在合适的时机进行Listpack合并。

typedef struct quicklist {quicklistNode *head;quicklistNode *tail;signed int fill : 16;/* ...... */
} quicklist;

Redis设计了fill字段来保存阈值:

  • 如果 (fill > 0), 表示数量阈值为fill个元素。空间阈值为默认值 8 KB
  • 如果 (-1 >= fill >= -5), 表示没有数量阈值,空间阈值为等级1~5,5个等级分别是{4KB, 8KB, 16KB, 32KB, 64KB}

fill转化为实际阈值的接口为quicklistNodeLimit()

#define SIZE_SAFETY_LIMIT 8192
static const size_t optimization_level[] = {4096, 8192, 16384, 32768, 65536};/* Calculate the size limit of the quicklist node based on negative 'fill'. */
static size_t quicklistNodeNegFillLimit(int fill) {assert(fill < 0);size_t offset = (-fill) - 1;size_t max_level = sizeof(optimization_level) / sizeof(*optimization_level);if (offset >= max_level) offset = max_level - 1;return optimization_level[offset];
}/* Calculate the size limit or length limit of the quicklist node* based on 'fill', and is also used to limit list listpack. */
void quicklistNodeLimit(int fill, size_t *size, unsigned int *count) {*size = SIZE_MAX;*count = UINT_MAX;if (fill >= 0) {/* Ensure that one node have at least one entry */*count = (fill == 0) ? 1 : fill;} else {*size = quicklistNodeNegFillLimit(fill);}
}

增删改查操作如何触发分割和合并?

  • 查询
    查询操作是读操作,只需要遍历元素,不会触发分割和合并。

  • 修改
    修改有可能导致长度变大或变小,可以分别按增加和删除的情况处理。

  • 删除
    删除操作显然不会触发分割。那么删除后元素变少是否需要合并?不需要!!!链表的使用场景是以两端操作为主,各个Listpack均匀删除的情况几乎不可能发生,删除后大概率是无法合并的。

  • 增加
    增加元素后有可能会超过阈值。超过阈值后如果是两端新增,直接增加一个node,不会触发分割;如果是随机插入,原本的一个Listpack需要分割成2个或者3个,此时是唯一触发合并的时机,会尝试将相邻的5个node两两合并。合并代码如下:

/* Attempt to merge listpacks within two nodes on either side of 'center'.** We attempt to merge:*   - (center->prev->prev, center->prev)*   - (center->next, center->next->next)*   - (center->prev, center)*   - (center, center->next)* * Returns the new 'center' after merging.*/
REDIS_STATIC quicklistNode *_quicklistMergeNodes(quicklist *quicklist, quicklistNode *center) {int fill = quicklist->fill;quicklistNode *prev, *prev_prev, *next, *next_next, *target;prev = prev_prev = next = next_next = target = NULL;if (center->prev) {prev = center->prev;if (center->prev->prev)prev_prev = center->prev->prev;}if (center->next) {next = center->next;if (center->next->next)next_next = center->next->next;}/* Try to merge prev_prev and prev */if (_quicklistNodeAllowMerge(prev, prev_prev, fill)) {_quicklistListpackMerge(quicklist, prev_prev, prev);prev_prev = prev = NULL; /* they could have moved, invalidate them. */}/* Try to merge next and next_next */if (_quicklistNodeAllowMerge(next, next_next, fill)) {_quicklistListpackMerge(quicklist, next, next_next);next = next_next = NULL; /* they could have moved, invalidate them. */}/* Try to merge center node and previous node */if (_quicklistNodeAllowMerge(center, center->prev, fill)) {target = _quicklistListpackMerge(quicklist, center->prev, center);center = NULL; /* center could have been deleted, invalidate it. */} else {/* else, we didn't merge here, but target needs to be valid below. */target = center;}/* Use result of center merge (or original) to merge with next node. */if (_quicklistNodeAllowMerge(target, target->next, fill)) {target = _quicklistListpackMerge(quicklist, target, target->next);}return target;
}

在增加了分割策略后,有可能会出现一个元素大小比Listpack占用空间的阈值还要大。
对这种特殊情况,让该元素单独一个Node,并禁止该Node参与分割和合并。由于Node只有一个元素,Listpack无法进行压缩,直接保存二进制数据更节省空间。使用一个模式标志位container区分普通的Node,container = 1表示该Node只有一个大元素。container = 2表示数据是Listpack

typedef struct quicklistNode {struct quicklistNode *prev;struct quicklistNode *next;unsigned char *entry;  /* container = 1 指向二进制数组数据, container = 2 指向 listpack */size_t sz;             /* entry size in bytes */unsigned int count : 16;     /* count of items in listpack */unsigned int container : 2;  /* PLAIN==1 or PACKED==2 *//* ...... */
} quicklistNode;

3.2 Node 压缩策略

由于Listpack关注的是对长度字段进行压缩,实际的二进制数据并没有压缩。
为了进一步压缩空间,Quicklist结构增加了一个压缩Listpack的功能,该功能是可选的。
压缩算法采用LZF算法,在保持较高压缩速度的同时,提供合理的压缩率​​,尤其适合对时间和内存资源敏感的场景(如:实时数据处理)

但是,不是所有的Node都适合压缩!!!

  1. 元素长度超过阈值不压缩(即: container = 1),元素太大时压缩和解压的时间将成为性能瓶颈。
  2. 元素压缩后节省空间少时不压缩,元素太小(size <= 48字节)或者 (压缩空间 <= 8字节)
typedef struct quicklistLZF {size_t sz; /* LZF size in bytes*/char compressed[];
} quicklistLZF;REDIS_STATIC int __quicklistCompressNode(quicklistNode *node) {if (node->sz < MIN_COMPRESS_BYTES) // sz < 64 不压缩return 0;quicklistLZF *lzf = zmalloc(sizeof(*lzf) + node->sz); // 申请压缩后的空间, 按压缩前的大小申请if (((lzf->sz = lzf_compress(node->entry, node->sz, lzf->compressed, node->sz)) == 0) ||lzf->sz + MIN_COMPRESS_IMPROVE >= node->sz) { // 压缩收益小于8则不压缩zfree(lzf);return 0;}lzf = zrealloc(lzf, sizeof(*lzf) + lzf->sz); // 裁剪空间为压缩后的空间 zfree(node->entry);node->entry = (unsigned char *)lzf;node->encoding = QUICKLIST_NODE_ENCODING_LZF; // 标记为已压缩return 1;
}
  1. 两端的Node不压缩,两端的Node是频繁操作的,压缩后每次操作都需要解压影响较大。同时允许配置压缩深度,允许两边的N个node不压缩。

完整的结构体定义如下:

typedef struct quicklistNode {struct quicklistNode *prev;struct quicklistNode *next;unsigned char *entry;        /* 指向实际的保存的元素结构 */size_t sz;                   /* entry 字段的字节数 */unsigned int count : 16;     /* listpack 元素总数 */unsigned int encoding : 2;   /* 1: 不压缩, 2: LZF压缩 (entry是listpack时有效) */unsigned int container : 2;  /* 1: entry直接存二进制(元素大小超阈值), 2: entry是listpack */unsigned int recompress : 1;unsigned int attempted_compress : 1;unsigned int dont_compress : 1;unsigned int extra : 9; /* 填充字段, 位域4字节对齐 */
} quicklistNode;typedef struct quicklist {quicklistNode *head;quicklistNode *tail;unsigned long count;        /* 所有 listpack 的元素总和 */unsigned long len;          /* Node 的总数 */signed int fill : QL_FILL_BITS;       /* listpack 分割阈值( >0 表示元素数量上限, <0 表示占用空间上限等级) */unsigned int compress : QL_COMP_BITS; /* 压缩深度, 两端的N个node不压缩. 0: 表示全部禁用压缩 */unsigned int bookmark_count: QL_BM_BITS;  /* 书签, 已废弃 */quicklistBookmark bookmarks[];            /* 书签, 已废弃 */
} quicklist;

quicklistNode有3个内部状态字段:

  • recompress:Node临时解压标记。如插入数据时:先临时解压,再插入数据,然后压缩。临时解压将字段标记1,避免触发所有Node都需要检查是否压缩。
  • attempted_compress:Redis运行测试用例时使用的标记字段,正常运行时永远为0。
  • dont_compress:为了修复Replace操作的bug的规避字段,否则可能需要大改动才能修复。详见: https://github.com/redis/redis/pull/11242

quicklist的废弃功能bookmark
bookmark是Redis 6版本用于优化ziplist批量迭代的产物,Redis 7版本优化了迭代器的实现,bookmark模块已经被废弃。

4. Redis 8 Quicklist 前瞻

  1. 优化了LZF压缩算法的实现,压缩速度提升​​20%​,同时支持动态调整压缩深度list-compress-depth
  2. 允许对Quicklist的中间节点按需压缩。
  3. 控制节点负载因子超过阈值时触发拆分 list-node-auto-split-threshold(默认 0.75)。
  4. 支持通过LPUSH/RPUSH一次性插入多个元素时,自动合并到同一节点的Listpack中,减少内存碎片。
  5. 新增quicklist-fragment-threshold 参数,允许自定义碎片触发回收的阈值。

相关文章:

Redis源码学习 -- 基本数据结构 -- Quicklist - -蓝蜗牛

1. 什么是 Quicklist? Quicklist​​是Redis自主研发的一种双向表数据结构,是List的底层数据结构之一。设计的核心思想是在时间和空间之间取一个平衡点。 2. Quicklist vs 普通链表 vs Listpack List系列命令的设计目标:两端操作O(1),随机操作O(n)。普通链表存在的问题? 普…...

动态修改线程池参数

import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit;/*** 动态线程池*/ public class DynamicThreadPool extends ThreadPoolExecutor {private …...

力扣70题 爬楼梯

1.确定dp数组以及下标的含义 dp[i]:爬到第i层楼梯,有dp[i]种方法 2.确定递推公式 dp[i]=dp[i-1]+dp[i-2] 3.dp数组如何初始化 dp[1]=1,dp[2]=2 4.确定遍历顺序 从前向后遍历的 5.举例推导dp数组 class Solution { public:int climbStairs(int n) {if (n <= 1) return n; /…...

PHP(Laravel)+ ImageMagick + Tesseract 实现验证码识别

一、概述与适用场景 本文演示如何在 PHP 服务端用 ImageMagick 做图像预处理,再调用系统安装的 Tesseract 做 OCR,最后用 Laravel 封装为 REST API。适合把验证码识别功能接入测试工具、后台自动化流程或内部管理平台。 优点: PHP 技术栈贴合多数 Web 后端; ImageMagick 提…...

表格识别技术:“唤醒”沉睡在纸质文档中的海量结构化数据

在日常工作和生活中,我们无处不在与表格打交道。从财务报表、发票收据,到科研论文中的数据表、医疗报告,表格以其清晰、结构化的方式,承载着大量关键信息。然而,当这些表格以纸质或图片等非结构化形式存在时,如何高效、准确地将它们转换为可编辑、可分析的数据,便成了一…...

【大三下】资料,仅内部学习使用

参考&推荐资料: 1.小金学长资料(微信公众号“小金同学HEI”) 2.朝阳医院22级课件 免责声明: 1.仅个人编写,可能出错,欢迎补充及捉虫 (作者只是勉强前十的本科生,比不了其它资料的作者) 2.仅供学习交流使用 3.若有条件请观看推荐资料或其它资料 4.该文档无任何医学…...

fastboot工具的常见命令

Fastboot是一个在Android开发环境中常用的工具,它是一个诊断工具,用于修改Android手机的固件。fastboot devices:显示当前连接到计算机的设备。此命令用于检查设备是否成功进入fastboot模式并通过USB正确连接到计算机。 fastboot oem unlock:解锁设备的 bootloader。这是在…...

《软件需求最佳实践》阅读笔记一

这本书主要从软件需求实践中出现的主要问题和困难入手,指出了改造的主要方法,然后逐一说明了需求定义、需求捕获、需求分析与建模、编写规约、需求验证等需求开发活动的任务、要点和具体手段。还对包括需求基线、变更管理、需求跟踪在内的需求管理活动的操作要点进行了阐述。…...

挖掘PDF生成器中的SSRF漏洞:从发现到利用

本文详细介绍了如何在PDF生成器中寻找和利用服务器端请求伪造(SSRF)漏洞,涵盖HTML注入、远程服务器访问、JavaScript执行等技术细节,并提供了针对云环境(如AWS IMDS)的具体攻击方法和实战技巧。挖掘PDF生成器中的SSRF漏洞 如果你在网站上看到以下功能之一,很可能遇到了服…...

做题记录 2

F. Shift and Revers 题意 给定 \(a_i\) ,操作有让 \(a_n\) 移到第一位和翻转整个序列,问最小操作数使得 \(a_i\) 从小到大排序。 做法 (不)容易发现可以正反都做一次取 min。 P6617 查找 Search 一道有点折磨的分讨题 理不清思路容易WA 给定 \(n\) 个垃圾桶,你需要维护一个…...

计数原理与排列组合

加法原理:做一件事情,有 \(n\) 类办法,第 \(1\) 类办法有 \(m_1\) 种方法,第 \(2\) 类办法有 \(m_2\) 种方法,第 \(n\) 类办法有 \(m_n\) 种方法,则完成这件事情的办法有 \(m_1+m_2+\cdots+m_n\) 种。 加法原理属于分类计数原理,分类需要包含所有情况,类与类之间不会产…...

9.16动态用例设计方法 笔记

...

深入解析:ESP32三种主流的开发环境

深入解析:ESP32三种主流的开发环境pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; …...

js

js...

9.16电商状态迁移图

...

c# ConcurrentDictionary

using System.Collections.Concurrent;internal class Program {static void Main(string[] args){ConcurrentDictionary<string, RedisConnection> redisConnectionDic = new ConcurrentDictionary<string, RedisConnection>();int redisConn =10;//会多次创建//P…...

核桃OJ【S组 第二轮】信息学竞赛10w选手模拟考

赤石,爽!核桃OJ【S组 第二轮】信息学竞赛10w选手模拟考 什么糖丸的名字 还是pvz专场。 植物部队哈基米 哦哦哦,感觉就不难,无非是一个连续段成环和特殊植物两种,复杂度能过。哈哈哈,预处理跑2s,太帅了吧!卡常!最后跑1.5s,过了。可是你大样例只有一个不满的,这是什么…...

第一次个人编程作业

第一次个人编程作业 作业GitHub链接https://github.com/useful-Tree/3123004757/tree/main 一、PSP表格(预估与实际耗时)PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)Planning 计划 15 20 Estimate估计任务所需时间 15 20Development 开发 …...

【初赛】软件系统 - Slayer

软件系统 (主要是之前做到了几次 全错 来记一下 系统软件 操作系统、Windows、dos、unix、各种计算机语言处理程序、机器语言、汇编语言、高级语言、数据库管理系统、支持软件 应用软件 程序库、软件包、套装软件、用户程序 常见:字处理软件、电子制表软件、计算机辅助设计软…...

漏洞详解--XXE 从入门到精通!

一、漏洞原理 1.1 核心 XXE(XML External Entity injection),名为XML外部实体注入。其核心在于XML解析器默认允许外部实体/DTD,攻击者通过构造特殊的XML使其包含恶意外部实体。外部实体可以为服务器敏感文件,也可以为网络请求等,之后利用方式类似于文件包含和SSRF,有时甚…...

数学分析习题课 note

ohno,这很难第一讲:实数系 我们可以定义有序域 \(F\) 。一些有序域 \((F,+,\cdot,\le )\) 满足以下所谓连续公理: 连续公理 阿基米德公理:\(\forall x,y\in F,x>0,\exists n\in N^{+}\) 使得 \(nx>y\) 完备公理:若存在代数结构 \((F,+,\cdot,\le )\) 满足 \(F\subse…...

总结-CDQ 分治

关于 CDQ 分治 CDQ 分治是一种思想而不是具体的算法,并且必须离线处理,用于维护具有偏序限制的问题。 偏序可以理解为大小关系。 经典三维偏序 CDQ 分治的经典应用。 给定每个元素,每个元素都有三个属性 \((x,y,z)\),要求统计所有满足三个偏序条件时的价值。 标准方法:sor…...

【初赛】计算机语言 - Slayer

计算机语言 编译性语言 c c++ pascal 解释性预言 py java JavaScript ruby PHP...

深入浅出RocketMQ客户端编程

深入理解RocketMQ:从架构到实战的全方位指南 在当今分布式系统日益普及的时代,消息队列已成为支撑高并发、高可靠业务的核心组件。RocketMQ作为阿里巴巴开源的高性能消息中间件,凭借其卓越的性能和稳定性,在电商、金融等高要求场景中得到了广泛应用。今天,让我们一起深入探…...

Win10玩LOL弹窗

将红框内关闭关闭后,可以按win+g快捷键,如果不弹出那个窗口,在LOL里面应该也不会弹出...

溢出存储变量

这个 negative(i) 表示的就是 (-i) 这个数(其中 i>=0),在二进制下的编码。 这个编码满足 \(i+negative(i)=2^k\),可是由于我们二进制下只有 \(k\) 位,最高位是 \(2^{k-1}\),所以那个 \(1\) 会被丢掉,所以加起来结果为 \(0\)。 那如何确定一个数被存储为多少,因为前面…...

retrieving repo key for OS unencrypted from

在服务器上安装mkfontscale工具时,下载成功但是再安装过程中一直提示: retrieving repo key for OS unencrypted from http://repo.openeuler.org/openEuler-22.03-LTS-SP3/OS/x86_64/RPM-GPG-KEY-openEuler。 手动下载RPM-GPG-KEY-openEuler文件,将其上传到服务器/etc/yum.…...

3. Explain详解与索引最佳实践

3.1 Explain使用与详解id select_type table partitions type possible_keys key key_len ref rows filtered Extra1 SIMPLE user NULL ref idx_name_age_dpt idx_name_age_dpt 1023 const 1 100.0 NULL中 重要 中 低 重要 重要 重要 重要一般 一般 一般通过EXPLAIN或DESC命令获…...

软工个人项目作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience/homework/13477这个作业的目标 制作论文查重工具论文查重工具项目文档 项目概述 本项目是一…...

异地办公文件同步,多台设备如何无缝同步最新教程

如何实现异地电脑文件同步?本文对比了坚果云与Syncthing等复杂技术方案。讲解如何使用坚果云,无需繁琐配置,即可在Windows/Mac等多设备间实现文件自动、实时同步。是解决远程办公和多设备管理难题的简单、高效选择。异地电脑文件同步?告别复杂技术,一招搞定! 身处不同城市…...

CSP-S模拟22

前言: 哈哈哈,又是一场爆零的模拟赛~~ \(T1:\) 木棍 思路: 机房出现了两种思路: 第一种:我们不难发现,一共就只有五种情况\({334}{2233}{2224}{244}{22222}\)...

详细介绍:【系统分析师】2025年上半年真题:论文及解题思路

详细介绍:【系统分析师】2025年上半年真题:论文及解题思路pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New",…...

实战有效的Web时序攻击技术剖析

本文深入探讨了Web时序攻击的实际应用,包括参数发现、服务器端注入和反向代理配置错误检测,通过真实案例展示了高精度时序分析技术在安全测试中的突破性进展。倾听低语:实际有效的Web时序攻击 | PortSwigger研究 James Kettle 研究总监 @albinowax 发布时间:2024年8月7日 1…...

22222222 - idle

//为什么要攀登?因为山就在那里。 #include<bits/stdc++.h> #define mrx 0x7f7f7f7f7f7f7f7f //#define int long long using namespace std; inline int read(){int num=0,flag=1;char ch=getchar();while(ch<0||ch>9){if(ch==-) flag=-1;ch=getchar();}while(ch…...

表格如何设置多人在线编辑?坚果云实时编辑,告别版本冲突!

还在为Excel表格多人协作的版本混乱、数据冲突而烦恼吗?本文深入对比坚果云、在线Office等三大解决方案,并提供坚果云实战教程。教你如何利用其强大的实时同步、版本管理和权限控制功能,彻底告别协作难题,实现高效、安全的团队文件管理。告别表格协作难题:三大高效解决方案…...

白嫖党狂喜!爆肝一下午搞定 URL 转 HTML 幻灯片神器,ISlide 9900 资源点从此是路人

原文:白嫖党狂喜!爆肝一下午搞定 URL 转 HTML 幻灯片神器,ISlide 9900 资源点从此是路人家人们谁懂啊!之前分享的 ISlide 插件做 PPT 一次要耗 9900 个资源点【从 url 到 PPT 一键生成:Coze 工作流,颠覆你的内容创作方式!】,作为资深白嫖党看着资源点的大量消耗实在心疼…...

继承

1.概述 子类和父类的区分需要根据实际情况,不能随便使用 2.子类只能继承一个父类,(单继承),但是可以多级继承 所有类都简介或直接继承Object类(java虚拟机自动生成) 3继承的内容 成员变量 继承的private内容可以被继承但是不能直接使用,需要用get()方法 继承中成员变量的访问特…...

我们究竟在用钱交换什么?

钱,藏着哪些我们没说透的用途?"穷人用健康换钱,富人用钱买健康",而最残忍的是,后者永远买不完 这个世界上,钱不是万能的,但有钱的确能解决99%的问题,包括给我们带来自尊和底气!中国有句老话:和气生财,我认为,和气不一定生财,但有钱确实能为家庭带来一…...

jupyterLab如何使用

好的,JupyterLab 是一个非常强大的交互式开发环境(IDE)。下面我将从安装、启动、核心功能到高级技巧,为你提供一个完整的入门指南。一、安装 JupyterLab 首先,你需要安装 JupyterLab。强烈建议在虚拟环境中安装,以避免包冲突。 1. 使用 pip 安装(最常用) # 1. 创建并激…...

HyperWorks许可监控

在当今竞争激烈的工程设计和仿真领域,资源的高效利用至关重要。HyperWorks作为一款业界领先的工程仿真软件,其许可监控功能为用户提供了强大的资源管理和优化工具。本文将向您介绍HyperWorks许可监控的重要性以及如何利用它确保您的资源得到充分利用。 什么是HyperWorks许可监…...

C++拷贝构造函数详解:从浅拷贝到深拷贝

什么是拷贝构造函数? 拷贝构造函数是C++中的一种特殊构造函数,用于创建一个新对象作为现有对象的副本。当我们使用一个对象来初始化同类型的另一个对象时,拷贝构造函数就会被调用。 基本语法 class MyClass { public:// 拷贝构造函数MyClass(const MyClass& other) {// …...

K8S探针

https://blog.csdn.net/weixin_28820113/article/details/148380309 HTTP探测实战(最常用) 向容器发送 HTTP 请求,若返回状态码为 200-399,则表示检查成功[root@master ~/probe]# cat readiness.yaml kind: Pod apiVersion: v1 metadata:name: nginxlabels:app: nginx spec…...

模拟赛

波波牛的惩罚 我们先处理出每个数可能影响的数,可以用链式前向星或 vector 我们维护一个队列,在最开始的时候放入最小值。 每次取出一个数,然后遍历所有可以影响的数,并把影响成功的数放进队列。 在最后判一下是否相同即可。 复杂度 \(O(n)\)。点击展开代码 #include<bi…...

bug1

9.16 修复报错字体大小bug 补充日志 TeXmacs/progs/debug/debug-widgets.scm 修改build-message 为以下 (define (build-message m)(let* ((k (tm->stree (tm-ref m 0)))(s (utf8->cork (tm->stree (tm-ref m 1))))(t (tm->stree (tm-ref m 2))))(cond ((string-e…...

C#第十二天 025

父类如果只有有参构造器,子类会默认去调用父类的无参构造器,如果子类要有无参构造器需要这样 子类构造器():base(参数)你的理解​​完全正确​​!当父类​​只有有参构造器​​时,子类必须​​显式调用父类的有参构造器​​,否则会编译错误。 类成员的访问级别不能超…...

选择语句的机器级表示

无条件转移指令--jmp 格式: jmp <地址> #pc无条件跳转到<地址> <地址>可以由常数直接给出:jmp 5 <地址>可以来自于寄存器:jmp eax <地址>可以来自于主存 :jmp [999] <地址>可以用“标号”锚定:jmp NEXT 100 mov eax,7 104 mov ebx,6 …...

pip常用命令

好的,这是 Python 包管理工具 pip 的常用命令大全,涵盖了从安装、升级、查询到问题排查的所有核心操作。一、核心命令:安装与卸载命令 描述 示例pip install <package_name> 安装最新版本的包 pip install requestspip install <package_name>==<version>…...

Nginx auth_request 模块使用

Nginx auth_request 模块使用笔记 📌 模块概述 nginx-auth-request-module(官方名:http_auth_request_module)用于在请求处理前向外部服务进行认证验证。 🔧 安装与启用 # 编译时添加模块 ./configure --add-module=/path/to/nginx-auth-request-module# 检查是否已安装…...

用nssm将minio和srs注册成服务

首先,要注意一个关键问题,不要在nssm中直接调用batNSSM 与 Bat 文件的问题:当NSSM启动一个批处理文件(.bat)时,它实际启动的是cmd.exe进程,而批处理中的命令(如minio.exe)则是其子进程。NSSM会监视cmd.exe的状态。一旦批处理中的命令执行完毕,cmd.exe进程就会退出,N…...

Mac上的Markdown学习

Markdown学习 标题 一个#+空格表示一级标题 两个#+空格表示二级标题 ……同理,几个#+空格表示几级标题 字体 粗体 Hello World 前后两个*表示粗体 斜体 Hello World 前后一个*表示斜体 斜体加粗 Hello World 前后三个*表示斜体加粗 删除线 Hello world 前后两个英文字符~表示删…...