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

Java多级缓存是为了解决什么的?

前言
  提到缓存,想必每一位软件工程师都不陌生,它是目前架构设计中提高性能最直接的方式。
  缓存技术存在于应用场景的方方面面。从网站提高性能的角度分析,缓存可以放在浏览器,可以放在反向代理服务器,还可以放在应用程序进程内,同时可以放在分布式缓存系统中。
  从用户请求数据到数据返回,数据经过了浏览器,CDN,Nginx代理缓存,应用服务器,以及数据库各个环节。每个环节都可以运用缓存技术。

在这里插入图片描述
缓存的请求顺序是:用户请求 → HTTP 缓存 → CDN 缓存 → Nginx代理缓存 → 进程内缓存 → 分布式缓存。
  在技术的架构每个环节都可以加入缓存,我们看看每个环节是如何应用缓存技术的。
  
  2. HTTP缓存
  
  通常 HTTP 缓存策略分为两种:
  - 强缓存
  - 协商缓存。
  从字面意思我们可以很直观的看到它们的差别:
  - 强缓存即强制直接使用缓存。
  - 协商缓存就得和服务器协商确认下这个缓存能不能用。
  强缓存
  强缓存不会向服务器发送请求,直接从缓存中读取资源,在 chrome 控制台的 network 选项中可以看到该请求返回 200 的状态码,并且size显示from disk cachefrom memory cache;
  协商缓存
  协商缓存会先向服务器发送一个请求,服务器会根据这个请求的 request header 的一些参数来判断是否命中协商缓存,如果命中,则返回 304 状态码并带上新的 response header 通知浏览器从缓存中读取资源。
  
  2.1 HTTP 缓存控制
  
  在 HTTP 中,我们可以通过设置响应头以及请求头来控制缓存策略。
  强缓存可以通过设置ExpiresCache-Control 两种响应头实现。如果同时存在,Cache-Control优先级高于Expires
  Expires
  Expires 响应头,它是 HTTP/1.0 的产物。代表该资源的过期时间,其值为一个绝对时间。它告诉浏览器在过期时间之前可以直接从浏览器缓存中存取数据。由于是个绝对时间,客户端与服务端的时间时差或误差等因素可能造成客户端与服务端的时间不一致,将导致缓存命中的误差。如果在Cache-Control响应头设置了 max-age 或者 s-max-age 指令,那么 Expires 会被忽略。

Expires: Wed, 21 Oct 2015 07:28:00 GMT

Cache-Control
  Cache-Control 出现于 HTTP/1.1。可以通过指定多个指令来实现缓存机制。主要用表示资源缓存的最大有效时间。即在该时间端内,客户端不需要向服务器发送请求。优先级高于 Expires。其过期时间指令的值是相对时间,它解决了绝对时间的带来的问题。

Cache-Control: max-age=315360000

Cache-Control 有很多属性,不同的属性代表的意义也不同。
  可缓存性
  - public 表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。
  - private 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)
  - no-cache 不使用强缓存,需要与服务器验协商缓存验证。
  - no-store 缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。
  过期
  - max-age= 缓存存储的最大周期,超过这个周期被认为过期。
  - s-maxage= 设置共享缓存。会覆盖max-ageexpires,私有缓存会忽略它
  - max-stale[=] 客户端愿意接收一个已经过期的资源,可以设置一个可选的秒数,表示响应不能已经过时超过该给定的时间。
  - min-fresh= 客户端希望在指定的时间内获取最新的响应

重新验证和重新加载
  - must-revalidate 如页面过期,则去服务器进行获取。
  - proxy-revalidatemust-revalidate 作用相同,但是用于共享缓存。
  其他
  - only-if-cached 不进行网络请求,完全只使用缓存。
  - no-transform 不得对资源进行转换和转变。例如,不得对图像格式进行转换。
  协商缓存可以通过 Last-Modified/If-Modified-SinceETag/If-None-Match这两对 Header 来控制。
  
  2.2 Last-Modified、If-Modified-Since
  
  Last-ModifiedIf-Modified-Since 的值都是 GMT 格式的时间字符串,代表的是文件的最后修改时间。
1.在服务器在响应请求时,会通过Last-Modified告诉浏览器资源的最后修改时间。
  2. 浏览器再次请求服务器的时候,请求头会包含Last-Modified字段,后面跟着在缓存中获得的最后修改时间。
  3. 服务端收到此请求头发现有if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果一致则返回 304 和响应报文头,浏览器只需要从缓存中获取信息即可。如果已经修改,那么开始传输响应一个整体,服务器返回:200 OK

<img src="images/image-20220718222822409.png" alt="image-20220718222822409" style="zoom:80%;" />

但是在服务器上经常会出现这种情况,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。为了解决这个问题,HTTP/1.1 推出了Etag。Etag 优先级高与Last-Modified
 
 2.3 Etag、If-None-Match
  
  Etag都是服务器为每份资源生成的唯一标识,就像一个指纹,资源变化都会导致 ETag 变化,跟最后修改时间没有关系,ETag可以保证每一个资源是唯一的。
  在浏览器发起请求,浏览器的请求报文头会包含 If-None-Match 字段,其值为上次返回的Etag发送给服务器,服务器接收到次报文后发现 If-None-Match 则与被请求资源的唯一标识进行对比。如果相同说明资源没有修改,则响应返 304,浏览器直接从缓存中获取数据信息。如果不同则说明资源被改动过,则响应整个资源内容,返回状态码 200。
  
 3. CDN缓存
  
  CDN:Content Delivery Network,即内容分发网络,它是构建在现有网络基础上的虚拟智能网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、调度及内容分发等功能模块,使用户在请求所需访问的内容时能够就近获取,以此来降低网络拥塞,提高资源对用户的响应速度。
  本地存储和浏览器缓存带来的性能提升主要针对的是浏览器端已经缓存了所需的资源,当发生二次请求相同资源时便能够进行快速响应,避免重新发起请求或重新下载全部响应资源。
  这些方法对于首次资源请求的性能提升是无能为力的,若想提升首次请求资源的响应速度,除了资源压缩、图片优化等方式,还可借助CDN技术。

在这里插入图片描述
 3.1 使用CDN网络资源获取过程
 
  如果使用了CDN网络,则资源获取的大致过程是这样的。
1.由于DNS服务器将对CDN的域名解析权交给了CNAME指向的专用DNS服务器,所以对用户输入域名的解析最终是在CDN专用的DNS服务器上完成的。
2. 解析出的结果IP地址并非确定的CDN缓存服务器地址,而是CDN的负载均衡器的地址。
3. 浏览器会重新向该负载均衡器发起请求,经过对用户IP地址的距离、所请求资源内容的位置及各个服务器复杂状况的综合计算,返回给用户确定的缓存服务器IP地址。
4. 对目标缓存服务器请求所需资源的过程。
  这个过程也可能会发生所需资源未找到的情况,那么此时便会依次向其上一级缓存服务器继续请求查询,直至追溯到网站的根服务器并将资源拉取到本地。
  
 3.2 CDN网络的核心功能包括两点:
 
  缓存与回源
  缓存指的是将所需的静态资源文件复制一份到CDN缓存服务器上;
  回源指的是如果未在CDN缓存服务器上查找到目标资源,或CDN缓存服务器上的缓存资源已经过期,则重新追溯到网站根服务器获取相关资源的过程。
  
  4. Nginx代理缓存
  
  用户请求在达到应用服务器之前,会先访问 Nginx 负载均衡器,如果发现有缓存信息,直接返回给用户。
  如果没有发现缓存信息,Nginx 回源到应用服务器获取信息。
  另外,有一个缓存更新服务,定期把应用服务器中相对稳定的信息更新到 Nginx 本地缓存中。
  Nginx设置缓存有两种方式:
  - proxy_cache_path和proxy_cache
  - Cache-Control和Pragma
  对于站点中不经常修改的静态内容(如图片,JS,CSS),可以在服务器中设置expires过期时间,控制浏览器缓存,达到有效减小带宽流量,降低服务器压力的目的。

<img src="images/image-20220718224542963.png" alt="image-20220718224542963" style="zoom: 67%;" />

第一步:客户端第一次向Nginx请求数据A;
  第二步:当Nginx发现缓存中没有数据A时,会向服务端请求数据A;
  第三步:服务端接收到Nginx发来的请求,则返回数据A到Nginx,并且缓存在Nginx;
  第四步:Nginx返回数据A给客户端应用;
  第五步:客户端第二次向Nginx请求数据A;
  第六步:当Nginx发现缓存中存在数据A时,则不会请求服务端;
  第七步:Nginx把缓存中的数据A返回给客户端应用。
  默认情况下,NGINX尊重Cache-Control源服务器的标头。它不缓存响应Cache-Control设置为Private,No-Cache或No-Store或Set-Cookie在响应头。NGINX只缓存GET和HEAD客户端请求。
  如下配置可覆盖这些默认值:
  - proxy_buffering默认为on,若proxy_buffering设置为off,则NGINX不会缓存响应。
  - proxy_ignore_headers可以配置忽略Cache-Control:

location /images/ {proxy_cache my_cache;proxy_ignore_headers Cache-Control;proxy_cache_valid any 30m;# ...
}

5. 进程缓存
 
  通过了客户端,CDN,Nginx代理缓存,我们终于来到了应用服务器。应用服务器上部署着一个个应用,这些应用以进程的方式运行着,那么在进程中的缓存是怎样的呢?
  进程内缓存又叫托管堆缓存,以 Java 为例,这部分缓存放在 JVM 的托管堆上面,同时会受到托管堆回收算法的影响。
  由于其运行在内存中,对数据的响应速度很快,通常我们会把热点数据放在这里。
  在进程内缓存没有命中的时候,我们会去搜索进程外的缓存或者分布式缓存。这种缓存的好处是没有序列化和反序列化,是最快的缓存。缺点是缓存的空间不能太大,对垃圾回收器的性能有影响。
  目前比较流行的实现有 Ehcache、GuavaCache、Caffeine。这些架构可以很方便的把一些热点数据放到进程内的缓存中。
  这里我们需要关注几个缓存的回收策略,具体的实现架构的回收策略会有所不同,但大致的思路都是一致的:
  - FIFO(First In First Out):先进先出算法,最先放入缓存的数据最先被移除。
  - LRU(Least Recently Used):最近最少使用算法,把最久没有使用过的数据移除缓存。
  - LFU(Least Frequently Used):最不常用算法,在一段时间内使用频率最小的数据被移除缓存。
  在分布式架构的今天,多应用中如果采用进程内缓存会存在数据一致性的问题。
  这里推荐两个方案:
  - 消息队列方案
  应用在修改完自身缓存数据和数据库数据之后,给消息队列发送数据变化通知,其他应用订阅了消息通知,在收到通知的时候修改缓存数据。

- 定时任务修改方案
  为了避免耦合,降低复杂性,对“实时一致性”不敏感的情况下。每个应用都会启动一个定时任务,定时从数据库拉取最新的数据,更新缓存。
  进程内缓存有哪些使用场景呢?
  - 场景一:只读数据,可以考虑在进程启动时加载到内存。当然,把数据加载到类似 Redis 这样的进程外缓存服务也能解决这类问题。
  - 场景二:高并发,可以考虑使用进程内缓存,例如:秒杀。
  
  6. 分布式缓存
  
  说完进程内缓存,自然就过度到进程外缓存了。
  与进程内缓存不同,进程外缓存在应用运行的进程之外,它拥有更大的缓存容量,并且可以部署到不同的物理节点,通常会用分布式缓存的方式实现。
  分布式缓存是与应用分离的缓存服务,最大的特点是,自身是一个独立的应用/服务,与本地应用隔离,多个应用可直接共享一个或者多个缓存应用/服务。
  为了提高缓存的可用性,会在原有的缓存节点上加入 Master/Slave 的设计。当缓存数据写入 Master 节点的时候,会同时同步一份到 Slave 节点。
  一旦 Master 节点失效,可以通过代理直接切换到 Slave 节点,这时 Slave 节点就变成了 Master 节点,保证缓存的正常工作。
  每个缓存节点还会提供缓存过期的机制,并且会把缓存内容定期以快照的方式保存到文件上,方便缓存崩溃之后启动预热加载。
  
  6.1 缓存雪崩
  
  当缓存失效,缓存过期被清除,缓存更新的时候。请求是无法命中缓存的,这个时候请求会直接回源到数据库。
  如果上述情况频繁发生或者同时发生的时候,就会造成大面积的请求直接到数据库,造成数据库访问瓶颈。我们称这种情况为缓存雪崩。

从如下两方面来思考解决方案:
  缓存方面:
  - 避免缓存同时失效,不同的 key 设置不同的超时时间。
  - 增加互斥锁,对缓存的更新操作进行加锁保护,保证只有一个线程进行缓存更新。缓存一旦失效可以通过缓存快照的方式迅速重建缓存。对缓存节点增加主备机制,当主缓存失效以后切换到备用缓存继续工作。
  设计方面,这里给出了几点建议供大家参考:
  - 熔断机制:某个缓存节点不能工作的时候,需要通知缓存代理不要把请求路由到该节点,减少用户等待和请求时长。
  - 限流机制:在接入层和代理层可以做限流,当缓存服务无法支持高并发的时候,前端可以把无法响应的请求放入到队列或者丢弃。
  - 隔离机制:缓存无法提供服务或者正在预热重建的时候,把该请求放入队列中,这样该请求因为被隔离就不会被路由到其他的缓存节点。

- 如此就不会因为这个节点的问题影响到其他节点。当缓存重建以后,再从队列中取出请求依次处理。
  
  62. 缓存穿透
  
  缓存一般是 Key,Value 方式存在,一个 Key 对应的 Value 不存在时,请求会回源到数据库。
  假如对应的 Value 一直不存在,则会频繁的请求数据库,对数据库造成访问压力。如果有人利用这个漏洞攻击,就麻烦了。
  解决方法:如果一个 Key 对应的 Value 查询返回为空,我们仍然把这个空结果缓存起来,如果这个值没有变化下次查询就不会请求数据库了。
  将所有可能存在的数据哈希到一个足够大的 Bitmap 中,那么不存在的数据会被这个 Bitmap 过滤器拦截掉,避免对数据库的查询压力。

6.3 缓存击穿
  
  在数据请求的时候,某一个缓存刚好失效或者正在写入缓存,同时这个缓存数据可能会在这个时间点被超高并发请求,成为“热点”数据。
  这就是缓存击穿问题,这个和缓存雪崩的区别在于,这里是针对某一个缓存,前者是针对多个缓存。
  解决方案:导致问题的原因是在同一时间读/写缓存,所以只有保证同一时间只有一个线程写,写完成以后,其他的请求再使用缓存就可以了。
  比较常用的做法是使用 mutex(互斥锁)。在缓存失效的时候,不是立即写入缓存,而是先设置一个 mutex(互斥锁)。当缓存被写入完成以后,再放开这个锁让请求进行访问。

Java最新课程:

Java零基础视频教程(2022最新Java入门,含斯坦福大学练习题+力扣算法题

Java基础入门:

java零基础自学首Java入门教程(含Java项目和Java真题)

Javaweb核心基础

JavaWeb基础教程,Java web从入门到企业实战完整版

Spring Cloud最全微服务架构

史上最全面的springcloud微服务技术栈

SSM框架教程:

SSM框架教程_Spring+SpringMVC+Maven高级+Spring

SpringBoot2全套视频教程:

SpringBoot2全套视频教程,springboot零基础到项目实战

相关文章:

Java多级缓存是为了解决什么的?

前言   提到缓存&#xff0c;想必每一位软件工程师都不陌生&#xff0c;它是目前架构设计中提高性能最直接的方式。   缓存技术存在于应用场景的方方面面。从网站提高性能的角度分析&#xff0c;缓存可以放在浏览器&#xff0c;可以放在反向代理服务器&#xff0c;还可以放…...

MongoDB--》索引的了解及具体操作

目录 索引—index 索引的类型 索引的管理操作 索引的使用 索引—index 使用索引的原因&#xff1a;索引支持在MongoDB中高效地执行查询。如果没有索引&#xff0c;MongoDB必须执行全集合扫描&#xff0c;即扫描集合中的每个文档&#xff0c;以选择与查询语句匹配的文档。这…...

Python open()函数详解:打开指定文件

在 Python 中&#xff0c;如果想要操作文件&#xff0c;首先需要创建或者打开指定的文件&#xff0c;并创建一个文件对象&#xff0c;而这些工作可以通过内置的 open() 函数实现。open() 函数用于创建或打开指定文件&#xff0c;该函数的常用语法格式如下&#xff1a;file ope…...

CentOS Stream 9尝鲜安装教程

作者&#xff1a;IT圈黎俊杰 一、下载CentOS Stream 9安装介质 在CentOS官网可以下载到CentOS Stream 9的安装介质&#xff0c;正面列出ISO介质的下载链接地址&#xff1a; https://download.cf.centos.org/9-stream/BaseOS/x86_64/iso/CentOS-Stream-9-20221019.0-x86_64-dv…...

Ambire AdEx 2023 年路线图

Ambire AdEx 是为简化 web3 显示广告而建立的&#xff0c;领先于时代。到 2023 年&#xff0c;它将专注于服务用户需求&#xff0c;同时保持其作为区块链隐私解决方案的核心&#xff0c;反对传统的数字广告模式。 回顾 2022 年 2022 年&#xff0c;AdEx 网络处理了超过 1 亿次展…...

两种特征提取方法与深度学习方法对比的小型金属物体分类分析研究

本文讨论了用于对包括螺丝、螺母、钥匙和硬币在内的小型金属物体进行分类的两种特征提取方法的效率&#xff1a;定向梯度直方图 (HOG) 和局部二进制模式 (LBP)。首先提取标记图像的所需特征并以特征矩阵的形式保存。使用三种不同的分类方法&#xff08;非参数 K 最近邻算法、支…...

传奇私服搭建网站的几种方法

搭建网站的几种方法&#xff1a;一些人&#xff0c;连简单的搭建网站都不会&#xff0c;还要请技术帮忙&#xff0c;真是牛B&#xff0c;这里简单介绍下几种办法一&#xff1a;2003系统下&#xff0c;直接使用IIS&#xff0c;这个太简单了&#xff0c;桌面上就有IIS&#xff0c…...

i.MX8MP平台开发分享(clock篇)- 各类clock的注册

专栏目录:专栏目录传送门 平台内核i.MX8MP5.15.71文章目录 1、关键数据结构1.1 clk_hw1.2 clk_hw_onecell_data2.一个clk的注册过程2.1 fixed clk2.2 pll14xx2.3 fixed factor2.4 mux2.5 composite2.6 gate1、关键数据结构 1.1 clk_hw clk_hw是描述一个时钟信息的最小单元。…...

java ssm计算机系统在线考试平台idea

本系统主要包括以下功能模块学生、教师、班级、考试评阅、在线考试、试题内容、考试等模块&#xff0c;通过这些模块的实现能够基本满足日常计算机系统平台的操作。 本文着重阐述了计算机系统平台的分析、设计与实现&#xff0c;首先介绍开发系统和环境配置、数据库的设计&…...

C语言(字符串函数)

这章的内容记得引用<string.h>头文件 目录 1.strlen&#xff08;&#xff09; 2.strcat() 3.strncat() 4.strcmp() 5.strncmp() 6.strcpy() 7.strncpy() 8.sprintf() 8.strchr() 9.strpbrk() 10.strrchr() 11.strstr() 1.strlen&#xff08;&#xff09; 用于统计字符串的…...

Maxwell工作流程详解

要介绍maxwell的工作原理&#xff0c;首先需要讲一下mysql主从复制的原理 mysql主从复制原理&#xff1a; 如上图&#xff0c;左边是master主节点&#xff0c;右边是slave从节点 工作流程&#xff1a; 1.往主节点mysql的数据库中写入数据&#xff0c;产生数据变化&#xff0c…...

13- EM算法与GMM高斯混合 (聚类算法) (算法)

最大期望算法(EM算法) &#xff0c;曾入选“数据挖掘十大算法”中&#xff0c;是最常见的隐变量估计方法&#xff0c;在机器学习中有极为广泛的用途&#xff0c;例如常被用来学习高斯混合模型的参数。EM算法是在概率模型中寻找参数最大似然估计或者最大后验估计的算法&#xff…...

【新】华为OD机试 - 二叉树层次遍历(Python)| 刷完获取OD招聘渠道

二叉树层次遍历 题目 有一棵二叉树 每一个节点用一个大写字母标识 最多26个节点 现有两组字母 分别表示后序遍历(左孩子指向右孩子指向父节点) 和中序遍历(左孩子指向父节点指向右孩子) 请输出层次遍历的结果 输入 输入为两个字符串 分别为二叉树的后序遍历和中序遍历结…...

工作记录------@Accessors(chain = true)引起的BUG,Excel导入时获取不到值

工作记录------Accessors(chain true)引起的BUG&#xff0c;Excel导入时获取不到值 如题所示 背景&#xff1a;在进行文件excel文件导入时&#xff0c;发现实体类获取到的属性值都为null。 框架&#xff1a;com.alibaba.excel 2.2.0的版本。 结论&#xff1a;首先说下结论 如…...

JavaEE-HTTP协议(二)

目录HTTP请求的方法GET方法POST 方法其他方法“报头”User-AgentRefererCookieHTTP响应200 OK404 Not Found403 Forbidden405 Method Not Allowed500 Internal Server Error504 Gateway Timeout302 Move temporarily301 Moved PermanentlyHTTP请求的方法 GET方法 GET 是最常用…...

代理的基本原理和多线程的基本原理

目录爬虫代理常见代理多线程并发和并行Python中的多进程和多线程爬虫时我们不到一杯茶的功夫就出现了403.打开网页一看会说您的IP访问频率太高&#xff0c;出现这种情况是因为网站采取了一些反爬虫措施&#xff0c;限制某个IP在一定时间内的请求次数&#xff0c;如果超过一定的…...

T38,数的递归

描述 输入一棵节点数为 n 二叉树&#xff0c;判断该二叉树是否是平衡二叉树。 在这里&#xff0c;我们只需要考虑其平衡性&#xff0c;不需要考虑其是不是排序二叉树 平衡二叉树&#xff08;Balanced Binary Tree&#xff09;&#xff0c;具有以下性质&#xff1a;它是一棵空…...

QT+ OpenGL 变换

文章目录QT OpenGL变换向量的运算矩阵矩阵与向量相乘代码实现QT OpenGL 本篇完整工程见gitee:QTOpenGL 对应点的tag&#xff0c;由turbolove提供技术支持&#xff0c;您可以关注博主或者私信博主。 变换 我们需要改变物体的位置 现有解决办法&#xff08;每一帧&#xff0c…...

【算法】前缀和

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;要学会在纸上打草稿&#xff0c;这个很重要&#x1f43e; 文章目录1.什么是前缀和&#xff1f;2.怎么求前缀和&#xff1f;3.前缀和有什么用&#xff1f;4.进阶二维:矩阵和前缀和 主打一个记公式 1.什么是前…...

《Redis实战篇》七、Redis消息队列

7.1 Redis消息队列-认识消息队列 什么是消息队列&#xff1a;字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色&#xff1a; 消息队列&#xff1a;存储和管理消息&#xff0c;也被称为消息代理&#xff08;Message Broker&#xff09;生产者&#xff1a;发送消息…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...