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

多线程代码案例 - 2

阻塞队列

阻塞队列,我们熟悉的概念是队列,即一种先进先出的数据结构。阻塞队列,就是基于普通队列做出的扩展。

特点

        1. 线程安全的

        2. 具有阻塞特性

        (a)如果针对一个已经满了的队列进行入队列,此时入队操作就会阻塞,一直阻塞到队列不满(即有其他线程进行出队操作)之后

        (b)如果针对一个已经空了的队列进行出队列,此时出队操作就会阻塞,一直阻塞到队列不空(即有其他线程进行入队操作)之后

阻塞队列的作用非常大,因为基于阻塞队列,就可以实现“生产者消费者模型”!!!‘

什么是生产者消费者模型???

举个栗子:

包饺子的流程:

        1.和面(一般都是一个人负责,没办法多线程完成)

        2. 擀饺子皮

        3. 包饺子 (第二步和第三步,这两步就可以多线程完成了)

现在有 A B C 三位大兄弟,共同完成上面包饺子的步骤,擀面杖,一般一个家庭中,只有一个擀面杖,所以会发生,三个线程都去竞争这个擀面杖,A 大兄弟,拿到擀面杖擀皮了,B C 就需要阻塞等待,所以,很明显,包饺子的方式适合用多线程的方式来实现,即A 是和面的,B C 负责擀皮和包饺子。每次都是 B C 的一位大兄弟擀一个皮,然后另一个大兄弟包一个饺子,再擀一个皮,再包一个饺子...

于是就可以分工协作:和面之后,三位大兄弟就要研究 擀皮 和 包饺子了:

这里的分工协作,就构成了生产者消费者模型,擀饺子皮的线程就是生产者(生产饺子皮),擀完一个饺子皮,饺子数目 +1,另外两个包饺子的线程,就是消费者(消费饺子皮),包完一个饺子,饺子皮的数目 -1。

而中间的桌子,就起到了“传递饺子皮”的效果。这个桌子的角色就相当于“阻塞队列”。

假设:擀饺子皮的非常快,包饺子的人包的很慢。就会导致桌子上的饺子皮越来越多,一直这样下去,桌子上的饺子皮就会满了。此时擀饺子皮的人就得停下来等一等,等这俩包饺子的人,消费一波之后,再接着擀...

又或许:擀饺子皮的非常满,包饺子的人包的非常快,就会导致桌子上的饺子皮,越来越少,一直这样下去,桌子上的饺子皮就会没有了。此时包饺子的人就得停下来等一等,等擀饺子皮的人,再擀出来一波,再接着包...

上述的栗子,大概就是模拟了生产者消费者模型。

意义

这个生产者消费者模型,在实际开发中,非常有意义。

1. 解耦合

        1. 引入生产着消费者模型,就可以更好的做到“解耦合”。

(耦合程度:指的是代码中不同模块,类,函数之间相互依赖,相互关联的紧密程度,耦合度低:模块之间的依赖关系就少,相互影响就小。一个模块的修改不容易影响到其他模块,各个模块之间可以相对独立的进行开发...耦合度高:模块之间存在很强的依赖关系,一个模块的修改往往会导致其他多个模块也需要相应修改,代码的维护和扩展难度比较大...)(而我们一般是期望我们的代码耦合度低一些,即使用这个消费者生产者模型可以降低代码的耦合程度)

实际开发中,经常会涉及到“分布式系统”,即服务器整个功能不是由一个服务器全部完成的,而是每个服务器负责一部分功能,通过服务器之间的网络通信,最终完成整个功能。

上述模型中:A 和 B,A 和 C 之间的耦合性是比较强的!!!A 的代码中就需要设计到一些和 B 相关的操作,B 的代码中也涉及到一些和 A 的操作。同样的,A 的代码中也需要设计和 C 的操作,C 的代码也涉及到和 A 的操作。另外,如果 B 或者 C “挂了”,此时对于 A 的影响就很大,A 也可能就跟着 “挂” 了。

引入生产者消费者模型,就可以降低上述耦合度:

A 和 B,A 和 C 之间都不是直接交互了,而是通过队列在中间进行传话。此时,A 的代码中,只需要和队列交互就可以了,A 是并不知道 B 和 C 的存在的,同样的,B C 的代码,也只需要和队列进行交互,他们也是不知道 A 的存在的。

如果 B C “挂了”,对于 A 的影响是微乎其微的...假设后续如果要增加一个 D,A 的代码也是不用发生任何变化的。

引入生产者消费者模型,降低耦合度之后,也是需要付出一些代价的 ==》 需要加机器,即需要引入更多的硬件资源。

        1. 上述描述的阻塞队列,并非是简单的数据结构,而是基于这个数据结构实现的服务器程序,又被部署到单独的主机上了。我们称这种未“消息队列(message queue)”

        2. 整个系统的结构更复杂了。即我们要维护的服务器更多了。

        3. 效率问题。引入了中间商“阻塞队列”,是存在差价的。请求从 A 发出来到 B 收到,这个过程中就需要经历队列的转发,这个过程中是存在一定开销的...

2. 削峰填谷

在讲代码之前,让我们先用一个栗子,来引入削峰填谷:

三峡水坝,大家应该都直到,是一个非常牛 x 的工程。

它的其中一项工作,就是可以使得上流的水流,按照固定的速率往下流去放水。

如下图所示:

如果上游的降雨量突然增大,那上游的洪水,就会以一个极其快的速度冲向下游,对中下游,造成很大的冲击,从而引起洪灾。三峡工程呢,就是在中间,建立了一个水库。

有了这个三峡水库之后,即使上游的水,非常的湍急,但在冲向下游的途中被三峡水库给拦住了,三峡大坝本身就是一个水库,可以存储很多的水,然后,我们就可以进行调控,使得三峡按照一定的速率,往下游放水。

即:上游降雨骤增,三峡大坝就可以关闸蓄水。

        上游降雨骤减,三峡大坝就可以开闸放水。

上面的栗子就是对削峰填谷的大概比喻。(此处所谓的 峰 和 谷,都不是长时间持续的,而是短时间内所出现的...)

回到代码中,以我们的工作举栗子:

上面是一个分布式系统的大致模型,但我们要考虑到的是,当外网的请求突然增多时,即入口服务器 A 接收到的请求数量增加很多,A 的压力就会变大,但因为 A 做的工作一般比较简单,每个请求消耗的资源是比较少的,但是 B 和 C 服务器就不一定了,他们的压力同样会很大,且假设:B 是用户服务器,需要从数据库中找到对应的用户信息,C 是商品服务器,也需要从数据库找到对应的商品,还需要一些规则进行匹配,过滤等等...

A 的抗压能力比较强,B C 的抗压能力比较弱(他们需要完成的工作可能更加复杂,每个请求消耗的资源多...) ==》 一旦外界的请求出现突发的峰值,就会直接到导致 B C 服务器挂了...

那为什么,当请求多的时候,服务器就会挂了呢???

服务器处理每个请求,都是需要消耗硬件资源的!!!(包括但不限于 cpu 内存 硬盘 网络带宽等等...)即使一个请求消耗的资源比较少,但也无法承受住,同时会有很多的请求,加到一起来,这样消耗的总资源就多了。 ==》 上述任何一种硬件资源达到瓶颈,服务器都会挂(即客户端给服务器发出请求,但服务器不会再进行相应返回了)....

外界客服端发起的请求的数量,并不是固定的,有多少请求,是属于‘客户的请问“。有多少的请求,都是属于”客户的行为“...

我们就可以使用阻塞队列 / 消息队列了(阻塞队列:是以数据结构的视角命名的。消息队列:是基于阻塞队列实现服务器程序的视角命名的)...

当在 A 与 B C 之间添加一个阻塞队列之后,因为阻塞队列的特性,即使外界的请求出现峰值,也是由队列来承担峰值的请求,B 和 C(下游)仍然可以按照之前的速度来获得请求,这样就可以有效的防止 B 和 C 被高峰值的冲击导致服务器”挂了“。

补充:当请求太多的时候,接收请求的服务器也会挂的。请求一直往上增加,A 肯定也会有顶不住的时候,也可以给 A 前面再加一个阻塞队列,但当请求进一步的增加,队列也是可能挂的...(引入更多的硬件资源,避免上述情况...)

阻塞队列对应的数据结构

BlockingQueue 的使用

Java 标准库中提供了线程的阻塞队列的数据结果:

BlockingQueue 是一个总的 interface(接口),下面有三个具体的实现类:ArrayBlockingQueue LinkedBlockingQueue PriorityBlockingQueue

代码示例如下:

注意:使用 put 和 offer 一样都是入队列,但是 put 是带有阻塞功能的,offer 是没有阻塞功能的(队列满了之后就会返回 false),take 方法是用来出队列的,也是带有阻塞功能的。

但在阻塞队列中,并没有提供带有阻塞功能的,获取队首元素的方法。

实现一个 MyBlockingQueue

我们可以基于数组来实现其数据结构(环形队列)

环形队列:有两个指向头尾的引用 head 和 tail

每次插入数据的时候,将数据插入 tail 的位置,然后 tail 向后走

一直这样走

直到数组满了之后

因为我们要实现的是环形队列,所以要判断是否为满:

        1. 浪费一个格子,tail 最多走到 head 的前一个位置。

        2. 引入 size 变量

代码实现:(put 方法中,使用 size 来判断队列是否为满)

在 put 方法中的判断是否为满中,是由两种写法的,第一中就是我们上述所示:if(tail >= elems.length) 第二种是 tail = tail % elems.length,即(如果 tail < length,此时求余的量,就是 tail 原来的值,如果 tail == length,求余的值就是 0)

上述两种方法都能满足我们的目标,那如何评价某个代码段好还是不好呢?

        1. 开发效率(代码是否容易被理解)

        2. 运行效率(代码执行速度快不快)

让我们分析上面两种代码,if 代码,只要是个程序员,就认识 if 条件(大学生都认识...),但不理解 % 的,还是可能的,尤其是,在不同编程语言中,% 的作用可能还不一样...

而且,if 是条件跳转语句(执行速度非常快),大多情况下,并不会触发方法体中的赋值。但 % 本质上是除法运算指令,除法运算,是属于比较低效的指令(CPU 更加擅长计算 + -,计算 * / 的速度要比 + - 逊色一些),而且,第二种代码,是会百分百触发赋值操作的,运行效率会更低一些...

引入锁,解决线程安全问题

在 put 方法中,使得队列阻塞的代码先不提,就后面的代码:均是写操作,这几个代码都必须用锁包裹起来。

上述直接这样加锁,是线程安全的吗?

如下图为两个线程,如果随机调度成这样的情况

并且,此时这个 put 正好是添加最后一个元素,就会出现下面的情况:

所以我们的 synchronized 是需要加在最外面的,锁加到这里和加到方法上,本质上就都是一样的

阻塞部分的代码:

提起阻塞,我们就要想到使用 wait 来进行阻塞。

把 wait 加入到 if 的函数体中,巧了,正好这个 if 在 synchronized 的内部!!!

光有 wait 还不够,还需要有其他线程来对 wait 进行唤醒操作(队列如果没有满,就可以进行唤醒操作了)。这里有个问题是,什么叫做”队列不满“呢?什么情况下,是队列不满呢? ==》 出队成功,就是队列不满!对于满了的队列,就是在出队列成功之后唤醒。同样的,队列空了,再出队列,同样也需要阻塞(take 方法),同样是在另一个入列成功后的线程中唤醒...

 put 代码

take 代码

这样看起来,wok,好像线程太安全了,锁也上了,操蛋的情况也排除了,我们的期望是,take 操作中的唤醒操作,将 wait 方法中的 wait 成功唤醒,wait 方法中的 notify 将 take 中的 wait 唤醒。但是!

可能会出现下图的情况:

不同线程之间的,put 和 take 方法中的 notify 可能会不正确的将错误的 wait 给唤醒。

或者出现如下情况:入队列的唤醒操作,把其他线程的入队列的 wait 唤醒了。在第一步中,两个 wait 都执行到 put 了(注意:wait 之后会有三步操作,第一步就是释放锁,所以可以出现两个 wait 都执行到 put 了),第二步,有一个 take 方法执行到了 notify,将其中一个 put 的 wait 唤醒了,然后这个 put 操作向下执行代码,执行到 notify 之后,将另一个 put 方法的 wait 唤醒了...

如上两种,又是不符合我们预期的两种 bug,并且似乎还很麻烦,锁的对象又必须是 locker 这一个对象,如果我们定义两个 locker1 和 locker2,那又无法实现锁竞争 ==》 线程不安全了...如何解决呢?

其实解决方案很简单,但是问题是为什么,一定要想明白。

在进行阻塞的时候,我们是都只是用了 if 来进行条件判断,在 put 方法中,使用 if(size >= elems.length) 判断,在 take 方法中,使用 if(size == 0) 来判断,if 是 “一锤子买卖”,只判定一次条件,一旦程序进入阻塞之后,再被唤醒,这中间隔的时间,就是沧海桑田了,阻塞状态的过程中,发生的时候,会导致出现很多变数。有了这些变数之后,就很难以保证,()中的条件是否仍然满足了,入队列的条件是否仍然具备了...

我们可以将 if 改为 while,改为 while 之后,意味着 wait 唤醒之后,还需要再判定一次条件。即,wiat 之前判定一次,唤醒之后,再判定一次(相当于多做了一步确认操作!!!)

如果再次判定条件,发现队列还是满的,即是在 wait 等待过程中,出现了变数,此时就应该继续等待!

Java 标准库也是推荐,wait 要 搭配 while 进行使用,多 N 次确认操作!!!

上面英文的大概意思是: wait 可能被提前唤醒,即明明条件还没满足,就被唤醒了,所以经常是一个循环,所以我们可以使用 while 进行确认操作!

基于阻塞队列,写一个简单的生产者消费者模型

前言:在实际的开发中,生产者消费者模型,往往是多个生产者和多个消费者。这里的生产者和消费者往往不仅仅是一个线程,也可能是一个独立的服务器程序,甚至是一组服务器程序...但最核心的仍然是阻塞队列,使用 synchronized 和 wiat / notify 达到线程安全 and 阻塞

如下图,在 t2 中有 Thread.sleep(500) ==》 这对应的是生产者非常快,消费者非常慢的情况,即生产者生产 1000 个之后,消费者消费一个,生产者生产一个...

运行如下:

相关文章:

多线程代码案例 - 2

阻塞队列 阻塞队列&#xff0c;我们熟悉的概念是队列&#xff0c;即一种先进先出的数据结构。阻塞队列&#xff0c;就是基于普通队列做出的扩展。 特点 1. 线程安全的 2. 具有阻塞特性 &#xff08;a&#xff09;如果针对一个已经满了的队列进行入队列&#xff0c;此时入队操…...

Qt实现鼠标右键弹出弹窗退出

Qt鼠标右键弹出弹窗退出 1、鼠标右键实现1.1 重写鼠标点击事件1.2 添加头文件1.3 添加定义2、添加菜单2.1添加菜单头文件2.2创建菜单对象2.3 显示菜单 3、添加动作3.1添加动作资源文件3.2 添加头文件3.3 创建退出动作对象3.4菜单添加动作对象 4、在当前鼠标位置显示菜单4.1当前…...

AI绘画中的LoRa是什么?

Lora是一个多义词&#xff0c;根据不同的上下文可以指代多种事物。以下将详细介绍几种主要的含义&#xff1a; LoRa技术 LoRa&#xff08;Long Range Radio&#xff09;是一种低功耗广域网&#xff08;LPWAN&#xff09;无线通信技术&#xff0c;以其远距离、低功耗和低成本的特…...

LaTeX、KaTeX、Markdown 的用法

文章目录 1. LaTeX 用法概述1.1 LaTeX简介1.2 优点与应用场景2. LaTeX 基础语法2.1 文档结构2.2 文本格式化2.3 数学公式3. KaTeX 用法3.1 KaTeX简介3.2 基本使用方法3.2.1 引入KaTeX3.2.2 渲染数学公式3.2.3 自定义配置3.3 与LaTeX的兼容性4. Markdown 用法4.1 Markdown简介4.…...

Python 如何高效实现 PDF 内容差异对比

Python 如何高效实现 PDF 内容差异对比 1. 安装 PyMuPDF 库2. 获取 PDF 内容通过文件路径获取通过 URL 获取 3. 提取 PDF 每页信息4. 内容对比metadata 差异文本对比可视化对比 5. 提升对比效率通过哈希值快速判断页面是否相同早停机制多进程机制 6. 其他 最近有接触到 PDF 内容…...

JJJ:generic netlink例程分析

接嵌入式毕设、课设辅导、技术咨询&#xff0c;欢迎私信 完整代码&#xff1a;github代码仓链接 若想要和指定的generic netlink family通信&#xff0c;如: 994 static struct genl_family genl_ctrl __ro_after_init { // generic netlink子协议995 .module THIS_MODU…...

3D图像重建中Bundle Adjustment的推导与实现

介绍 捆集调整(Bundle Adjustment),也称为光束平差法,是一种利用来自多台相机的图像数据同时优化相机位置和姿态以及 3D 点位置的技术。该技术历史相当悠久,于 1958 年由 DC Brown1 首次提出。 最初这是美国空军正在进行的从航拍照片中恢复环境的研究,随着视觉SLAM和Sf…...

【代码模板】C语言如何修改文件权限?读写执行权限对应值是多少?(chmod(“./a.out“, 0741);bit 2 1 0表示 读 写 执行)

#include "stdio.h" #include "unistd.h"int main(int argc, char *argv[]) {if (chmod("./a.out", 0741) ! 0) {perror("Failed to set exec permission");return -1;}return 1; }0741中0是8进制&#xff0c;7是 0111&#xff0c; 4是…...

新版pycharm如何实现debug调试需要参数的python文件

在最顶上有这个选项 把鼠标移上去 点击号 选择python 具体长这样 名字随便取 script选择你要调试的python文件 脚本形参填入参数&#xff0c;如&#xff1a;--arg1 value1 --arg2 value2 点击应用确定 最后给文件打上断点&#xff0c;再点击调试按键&#xff0c;就可以调试了…...

赚钱模拟器-百宝库v0.1.1

#include<bits/stdc.h> #include<windows.h> using namespace std; int n,i,j; void welcome(); void zhuye(); void GAME(); int main(){welcome();zhuye();return 0; }void welcome(){cout<<"欢迎您使用更多资源-百宝库v0.1.1"<<endl;sys…...

实战打靶集锦-38-inclusiveness

文章目录 1. 主机发现2. 端口扫描&服务枚举3. 服务探查4.系统提权 靶机地址&#xff1a;https://download.vulnhub.com/inclusiveness/Inclusiveness.ova 1. 主机发现 目前只知道目标靶机在192.168.56.xx网段&#xff0c;通过如下的命令&#xff0c;看看这个网段上在线的主…...

01人工智能基础入门

一、AI应用场景和发展历程 1.1行业应用 1、deepdream图像生成、yolo目标检测 2、知识图谱、画风迁移 3、语音识别、计算机视觉 4、用户画像 5、百度人工智能布局 1.2发展历程 人工智能的发展经历了 3 个阶段&#xff1a; 1980年代是正式成形期&#xff0c;尚不具备影响力。 …...

SortedSet结构之用户积分实时榜单实战

Redis 中的SortedSet结构非常适合用于实现实时榜单的场景&#xff0c;它根据成员的分数自动进行排序&#xff0c;支持高效的添加、更新和查询操作。 SortedSet实时榜单的一些典型应用场景&#xff1a; 游戏中的玩家排行榜&#xff1a;在多人在线游戏中&#xff0c;使用 Sorte…...

C++_类和对象(上)

【本节目标】 面向过程和面向对象初步认识类的引入类的定义类的访问限定符及封装类的作用域.类的实例化类的对象大小的计算类成员函数的this指针 1. 面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过…...

vllm作为服务启动,无需额外编写sh文件,一步到位【Ubuntu】

看到网上有的vllm写法&#xff0c;需要额外建立一个.sh文件&#xff0c;还是不够简捷。这里提供一种直接编写service文件一步到位的写法&#xff1a; vi /etc/systemd/system/vllm.service [Unit] DescriptionvLLM Service Afternetwork.target[Service] Typesimple Userroot…...

Mathematics | Branch

注&#xff1a;本文为“遇见数学”翻译的 “数学分支概览” 两篇文章合辑。 数学世界的版图&#xff1a;主要分支概览&#xff08;上&#xff09; 原创 遇见数学 2025 年 04 月 03 日 12:02 河南 数学的分支&#xff08;Areas of Mathematics&#xff09; 在文艺复兴之前&am…...

8.5/Q1,Charls最新文章解读

文章题目&#xff1a;Associations of estimated glucose disposal rate with frailty progression: results from two prospective cohorts DOI&#xff1a;10.1186/s12933-025-02650-7 中文标题&#xff1a;估计葡萄糖处理率与虚弱进展的关系&#xff1a;两个前瞻性队列的结果…...

PCL学习(5)随机采样一致性算法RANSAC

一、RANSAC概念及作用 1.1 基本概念 RANSAC是一种鲁棒的参数估计方法&#xff0c;用于从包含大量异常值的数据中拟合数学模型。其核心思想是通过随机采样和迭代验证&#xff0c;找到最优的模型参数&#xff0c;避免异常值的干扰。 1.2 核心思想 随机采样&#xff1a;每次从数…...

app逆向专题一:如何下载app

app逆向专题一&#xff1a;如何下载app 一、打开豌豆荚官网 一、打开豌豆荚官网 打开豌豆荚官网豌豆荚&#xff0c;在右上角搜索框中输入要下载的app名称 依次点击搜索–查看–普通下载&#xff0c;即可将apk文件下载到本地电脑上。...

将 DataFrame 中某一列的列表拆分成多个独立的列的方式

要将 DataFrame 中某一列的列表拆分成多个独立的列&#xff0c;可以使用以下方法&#xff0c;具体取决于数据结构和需求&#xff1a; 场景示例 假设 DataFrame 中 genres 列存储的是列表&#xff08;如 [drama, action]&#xff09;&#xff0c;目标是将每个列表元素拆分成多列…...

VUE+SPRINGBOOT+语音技术实现智能语音歌曲管理系统

语音控制歌曲的播放、暂停、增删改查 <template><div class"Music-container"><div style"margin: 10px 0"><!--检索部分--><el-input style"width: 200px;" placeholder"请输入歌曲名称"v-model"sen…...

安卓开发工程师-自定义 View

1. 如何创建一个简单的自定义 View&#xff1f; 创建自定义 View 的基本步骤如下&#xff1a; 继承 View 或其子类&#xff1a;自定义 View 可以继承自 View 或其他更具体的视图类&#xff08;如 ImageView、Button 等&#xff09;。重写构造方法&#xff1a;通常需要重写三个…...

Vue中权限控制的方案

文章目录 源码&#xff1a;一、页面级1.1、路由守卫1.2、动态路由 二、按钮级别2.1、通过v-if来判断2.2、通过组件包裹的方式来判断2.3、通过自定义指令的方式 三、接口级别 源码&#xff1a; https://gitee.com/liu-qiang-yyds/sysPermission 一、页面级 1.1、路由守卫 前端…...

磁盘分析工具合集:告别C盘焦虑!

今天李师傅带大家盘点五款硬盘空间分析利器&#xff0c;帮你精准定位那些"吃空间"的元凶&#xff0c;让C盘告别臃肿烦恼&#xff01; 一、WizTree 这款NTFS磁盘的"透视眼"堪称效率典范。它通过直接读取硬盘主文件表(MFT)实现秒级扫描&#xff0c;1TB机械…...

硬件学习之器件篇-蜂鸣器

根据工作原理的不同&#xff0c;可以分为电磁式蜂鸣器和压电式蜂鸣器。 1、电磁式蜂鸣器 电磁式蜂鸣器根据内部是否有震荡源&#xff0c;又可以分为有源电磁式蜂鸣器和无源电磁式蜂鸣器。 1.1 外观区别 有源电磁式蜂鸣器从底部看是&#xff0c;是黑胶密封的。 无源电磁式蜂…...

紫檀博物馆一游与软件开发

今天去逛了中国紫檀博物馆&#xff0c;里边很多层展品&#xff0c;也有一些清代的古物&#xff0c;檀木&#xff0c;黄花梨木家具和各种摆件&#xff0c;馆主陈丽华女士也是发心复原、保留和弘扬中国的传统文化&#xff0c;和西游记唐僧扮演者迟成瑞先生一家。 每一件展品都精…...

Cribl 新建Datatype

Cribl 数据dataset 有个很重要的就是datatype, 下面来新建一下: 先看一下原来的datatype : 再点击Add Datatype: Rule...

开源 LLM 应用开发平台 Dify 全栈部署指南(Docker Compose 方案)

开源 LLM 应用开发平台 Dify 全栈部署指南&#xff08;Docker Compose 方案&#xff09; 一、部署环境要求与前置检查 1.1 硬件最低配置 组件要求CPU双核及以上内存4GB 及以上磁盘空间20GB 可用空间 1.2 系统兼容性验证 ✅ 官方支持系统&#xff1a; Ubuntu 20.04/22.04 L…...

医药档案区块链系统

1. 医生用户模块​​ ​​目标用户​​&#xff1a;医护人员 ​​核心功能​​&#xff1a; ​​检索档案​​&#xff1a;通过关键词或筛选条件快速定位患者健康档案。​​请求授权​​&#xff1a;向个人用户发起档案访问权限申请&#xff0c;需经对方确认。​​查看档案​…...

Redis常见命令

(一)常见命令① 一、数据结构 二、通用命令 ①KEYS查询语句 pattern代表模板,有点像匹配表达式(不是正则),是redis的一种内置表达式,可以在里面使用通配符 底层存在一种模糊查询机制,效率并不高。当redis的数据量达到一定规模时(数百万上千万甚至更多),使用这种模糊查询机制会…...

Qt的window注册表读写以及删除

Qt的window注册表读写以及删除 1. 使用 QSettings&#xff08;Qt推荐方式&#xff09;基本操作关键点限制 2. 调用Windows原生API示例&#xff1a;创建/读取键值常用API注意事项 3. 高级场景(1) 递归删除键(2) 注册表权限修改 4. 安全性建议总结其他QT文章推荐 在Qt中操作Windo…...

纯css实现环形进度条

需要在中实现一个定制化的环形进度条&#xff0c;最终效果如图&#xff1a; 使用代码 <divclass"circular-progress":style"{--progress: nextProgress,--color: endSliderColor,--size: isFull ? 60rpx : 90rpx,}"><div class"inner-conte…...

20250405周赛-S

链接 A. 日历 我的&#xff1a; #include<bits/stdc.h> using namespace std; int n,d[105],ans; bool check(int x,int y){if(x<10){if(y<10){return xy;}else{return xy%10&&xy/10;}}else{if(y<10){return yx%10&&yx/10;}else{return y/10…...

某碰瓷国赛美赛,号称第三赛事的数模竞赛

首先我非常不能理解的就是怎么好意思自称第三赛事的呢&#xff1f;下面我们进行一个简单讨论&#xff0c;当然这里不对国赛和美赛进行讨论。首先我们来明确一点&#xff0c;比赛的含金量由什么来定&#xff1f;这个可能大家的评价指标可能不唯一&#xff0c;我通过DeepSeek选取…...

希象传屏下载

2025年4月5日&#xff0c;11~22℃ 免费软件&#xff0c;功能&#xff1a;手机、个人笔记本和智慧黑板可以双向控制。要求在同一网络下或者同一WiFi下。 目的&#xff1a;自己下载的时候比较方便。 1、希沃易官网 2、如何下载&#xff1f; 被投屏&#xff1a;接收端&#xff1…...

解决 PDF 难题:批量处理、文档清理与自由拆分合并

软件介绍 在日常办公与学习中&#xff0c;处理 PDF 文件常常让人头疼不已&#xff0c;不过别担心&#xff0c;今天有一款堪称神器的国产老牌 PDF 工具要分享给大家。它就是 PDF 补丁丁&#xff0c;凭借其强大功能&#xff0c;为大家排忧解难。 界面体验 初次打开 PDF 补丁丁&…...

SQL Server 2022 数据同步到 Elasticsearch 思考

公司的老项目了&#xff0c;采用的是sqlserver 2022作为数据卡做的&#xff0c;但是产品对接客户&#xff0c;发现对搜索的要求很高&#xff0c;尤其是全文检索&#xff0c;考虑到ES采用倒排所以效率上的优势和整体开发的成本&#xff0c;大佬们商量之后&#xff0c;果断的采用…...

基于Spark的哔哩哔哩舆情数据分析系统

【Spark】基于Spark的哔哩哔哩舆情数据分析系统 &#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 本项目基于Python和Django框架进行开发&#xff0c;为了便于广大用户针对舆情进行个性化分析处…...

分布式事务解决方案全解析:从经典模式到现代实践

前言 在分布式系统中&#xff0c;数据一致性是一个核心问题。随着微服务架构的普及&#xff0c;跨服务、跨数据库的操作变得越来越普遍&#xff0c;如何保证这些操作的原子性、一致性、隔离性和持久性&#xff08;ACID&#xff09;成为了一个极具挑战性的任务。本文将全面介绍…...

迈向未来:数字化工厂管理如何重塑生产力

迈向未来:数字化工厂管理如何重塑生产力 随着工业4.0的浪潮席卷全球,“数字化工厂管理”成为制造业转型的关键一步。从传统生产模式到数据驱动的智能制造,企业在追求生产效率、质量与灵活性方面实现了飞跃式发展。然而,实施数字化管理不仅仅是技术问题,更关乎流程优化、数…...

LeetCode 1863.找出所有子集的异或总和再求和

题解 根据上述图可以根据二进制运算获取所有的子集&#xff0c;但是可以使用二进制获取所有子集需要有题目的这一句话才能够使用注意&#xff1a;在本题中&#xff0c;元素相同的不同子集应多次计数。 也就是对于{2,2,3,4,5}的子集不会简化成{2,3,4,5} public static int sub…...

蓝桥云客---蓝桥速算

3.蓝桥速算【算法赛】 - 蓝桥云课 问题描述 蓝桥杯大赛最近新增了一项娱乐比赛——口算大赛&#xff0c;目的是测试选手的口算能力。 比赛规则如下&#xff1a; 初始给定一个长度为 N 的数组 A&#xff0c;其中第 i 个数字为 Ai​。随后数组会被隐藏&#xff0c;并进行 Q 次…...

Kafka 概念

&#x1f300; Kafka 是什么&#xff1f; Kafka 是一个分布式流处理平台&#xff0c;可以用来&#xff1a; &#x1f69a; 高效地收集、传输、存储、处理 实时数据流。 它最初由 LinkedIn 开发&#xff0c;用于解决海量日志处理的问题&#xff0c;后来开源给 Apache&#xff0…...

双向链表增删改查的模拟实现

本章目标 0.双向链表的基本结构 1.双向链表的初始化 2.头插尾插 3.头删尾删 4.查找与打印 5.在指定位置之前插入数据/在指定位置之后插入数据 6.在指定位置之前删除数据/在指定位置之后删除数据 7.销毁链表 0.双向链表的基本结构 本章所实现的双向链表是双向循环带头链表,是…...

配置ASP.NET Core+NLog配置日志示例

以下是一个精简且实用的 NLog 配置文件示例,适用于 ASP.NET Core 项目,包含文件日志、控制台日志和自动归档功能: NLog.config 示例‌ (保存到项目根目录) xml Copy Code <?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http:…...

Roo Code使用MCP服务(大模型上下文协议)

MCP概念火爆&#xff0c;但是理解起来有点难度&#xff0c;使用起来也有点难度。 启用MCP RooCode直接支持使用MCP服务&#xff0c;甚至可以帮助写MCP&#xff0c;为我们提供了很大的方便。单击 Roo Code 窗格顶部导航栏中的类似三个插座的图标&#xff0c;显示如下MCP的配置…...

【项目管理】第一部分 信息技术 1/2

相关文档&#xff0c;希望互相学习&#xff0c;共同进步 风123456789&#xff5e;-CSDN博客 概要 知识点&#xff1a; 现代化基础设施、数字经济、工业互联网、车联网、智能制造、智慧城市、数字政府、5G、常用数据库类型、数据仓库、信息安全、网络安全态势感知、物联网、大数…...

《UNIX网络编程卷1:套接字联网API》第6章 IO复用:select和poll函数

《UNIX网络编程卷1&#xff1a;套接字联网API》第6章 I/O复用&#xff1a;select和poll函数 6.1 I/O复用的核心价值与适用场景 I/O复用是高并发网络编程的基石&#xff0c;允许单个进程/线程同时监控多个文件描述符&#xff08;套接字&#xff09;的状态变化&#xff0c;从而高…...

Three.js 系列专题 1:入门与基础

什么是 Three.js? Three.js 是一个基于 WebGL 的 JavaScript 库,它简化了 3D 图形编程,让开发者无需深入了解底层 WebGL API 就能创建复杂的 3D 场景。它广泛应用于网页游戏、可视化、虚拟现实等领域。 学习目标 理解 Three.js 的核心组件:场景(Scene)、相机(Camera)…...

Qt框架深度解析:核心技术、应用场景与实战指南

Qt&#xff08;发音同“cute”&#xff09;是一个跨平台的C应用程序开发框架&#xff0c;广泛用于开发图形用户界面&#xff08;GUI&#xff09;程序&#xff0c;但也支持非GUI的后台服务、命令行工具等。它由挪威的Trolltech公司于1995年推出&#xff0c;后由诺基亚、Digia等公…...