《OkHttp:工作原理 拦截器链深度解析》
目录
一、OKHttp 的基本使用
1. 添加依赖
2. 发起 HTTP 请求
3. 拦截器(Interceptor)
4. 高级配置
二、OKHttp 核心原理
1. 责任链模式(Interceptor Chain)
2. 连接池(ConnectionPool)
3. 请求调度(Dispatcher)
4. 缓存机制
5. 其他特性
三、拦截器工作原理
3.1 拦截器链的执行顺序
3.2 五大拦截器的工作原理
3.3 拦截器协作流程图
3.4 关键场景分析
3.5 总结
四、常见问题与优化
五、总结
OKHttp 是一款高效的 HTTP 客户端库,由 Square 公司开发,支持 Android 和 Java 应用。它简化了 HTTP 请求处理,支持同步/异步请求、连接池、缓存、拦截器等特性。以下是其使用流程图和原理的详细解析:
一、OKHttp 的基本使用
1. 添加依赖
在 Gradle 中添加依赖:
implementation 'com.squareup.okhttp3:okhttp:4.9.3' // 最新版本以官方为准
2. 发起 HTTP 请求
同步请求示例:
OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://api.example.com/data").build();try (Response response = client.newCall(request).execute()) {if (response.isSuccessful()) {String responseData = response.body().string();System.out.println(responseData);}
} catch (IOException e) {e.printStackTrace();
}
注意: 同步请求需在子线程执行(Android 中主线程禁止网络操作)。
异步请求示例:
client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();}@Overridepublic void onResponse(Call call, Response response) throws IOException {if (response.isSuccessful()) {String responseData = response.body().string();// 注意:回调在后台线程,需切换线程更新 UI}}
});
3. 拦截器(Interceptor)
拦截器用于监控、修改请求和响应。例如添加统一请求头:
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {@Overridepublic Response intercept(Chain chain) throws IOException {Request originalRequest = chain.request();Request newRequest = originalRequest.newBuilder().header("Authorization", "Bearer token").build();return chain.proceed(newRequest);}}).build();
4. 高级配置
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS) // 连接超时.readTimeout(30, TimeUnit.SECONDS) // 读取超时.writeTimeout(30, TimeUnit.SECONDS) // 写入超时.cookieJar(new CookieJar() { // Cookie 管理private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();@Overridepublic void saveFromResponse(HttpUrl url, List<Cookie> cookies) {cookieStore.put(url, cookies);}@Overridepublic List<Cookie> loadForRequest(HttpUrl url) {return cookieStore.getOrDefault(url, new ArrayList<>());}}).build();
二、OKHttp 核心原理
1. 责任链模式(Interceptor Chain)
OKHttp 的核心是 拦截器链,每个请求会依次经过多个拦截器处理:
-
自定义拦截器:开发者添加的拦截器,最先执行。
-
RetryAndFollowUpInterceptor:处理重定向和失败重试。
-
BridgeInterceptor:补全请求头(如
Content-Type
、Cookie
)。 -
CacheInterceptor:根据缓存策略返回缓存或请求网络。
-
ConnectInterceptor:建立与服务器的连接(复用连接池中的连接)。
-
CallServerInterceptor:向服务器发送请求并读取响应。
2. 连接池(ConnectionPool)
-
作用:复用 TCP 连接,减少握手开销。
-
默认配置:最大空闲连接数 5,存活时间 5 分钟。
-
实现:通过
RealConnectionPool
管理空闲连接,清理过期连接。
3. 请求调度(Dispatcher)
-
同步请求:直接执行,但需开发者自行管理线程。
-
异步请求:通过
Dispatcher
管理线程池,默认最大并发请求数 64,单个域名最大并发 5。
4. 缓存机制
-
基于 HTTP 缓存协议(如
Cache-Control
、ETag
)。 -
缓存目录需开发者指定,通过
Cache
类配置:Cache cache = new Cache(context.getCacheDir(), 10 * 1024 * 1024); // 10MB 缓存 OkHttpClient client = new OkHttpClient.Builder().cache(cache).build();
5. 其他特性
-
HTTP/2 支持:多路复用、头部压缩。
-
WebSocket:通过
okhttp-ws
模块支持长连接。 -
HTTPS:支持 TLS 1.3,可配置证书校验策略。
三、拦截器工作原理
OKHttp 的五大核心拦截器构成了其高效的网络请求处理链,每个拦截器职责明确,协同工作。以下是它们的详细工作流程和原理:
3.1 拦截器链的执行顺序
OKHttp 的请求处理基于责任链模式,五大核心拦截器按固定顺序依次处理请求和响应:请求从第一个拦截器进入,逐步传递到最后一个拦截器(CallServerInterceptor
),响应则逆向返回。
3.2 五大拦截器的工作原理
1. RetryAndFollowUpInterceptor
核心职责:处理请求失败的重试与重定向。
-
重试机制:
若请求因网络问题(如连接超时、IO 异常)失败,根据配置决定是否重试(默认最多 20 次)。 -
重定向处理:
若服务器返回 3xx 状态码(如 302 临时跳转),自动构建新请求并重新发起。 -
流程示例:
Request → RetryAndFollowUpInterceptor → 发送请求 → 失败 → 判断是否重试 → 重新执行链 Response ← 处理重定向 → 生成新 Request → 重新执行链
2. BridgeInterceptor
核心职责:桥接应用代码与网络请求,补充请求头、处理 Cookie 和响应编码。
-
请求头补充:
自动添加User-Agent
、Host
、Content-Type
等头信息。
若请求体为RequestBody
,自动计算Content-Length
。 -
Cookie 管理:
通过CookieJar
读取请求对应的 Cookie,写入Cookie
头;保存响应中的Set-Cookie
。 -
响应解码:
若响应头包含Content-Encoding: gzip
,自动解压响应体。
3. CacheInterceptor
核心职责:根据缓存策略管理本地缓存,减少重复请求。
-
缓存命中逻辑:
-
根据请求生成缓存 Key,检查本地是否有有效缓存。
-
若缓存未过期且有效(如
Cache-Control: max-age=3600
),直接返回缓存响应,不再执行后续拦截器。
-
-
缓存更新逻辑:
-
若缓存过期或需要验证(如
Cache-Control: no-cache
),添加条件头(如If-Modified-Since
)发起请求。 -
若服务器返回 304 Not Modified,更新缓存元数据并返回缓存响应。
-
若服务器返回新数据,写入缓存。
-
-
4. ConnectInterceptor
核心职责:建立与服务器的 TCP/TLS 连接,复用连接池。
-
连接复用机制:
-
根据请求的 URL、代理配置等生成连接标识(
Address
)。 -
从连接池(
ConnectionPool
)中查找可用连接,若存在则复用。 -
若无可用连接,创建新连接并加入连接池。
-
-
连接释放:
请求完成后,连接被标记为空闲,连接池根据策略(默认最大空闲连接数 5,存活时间 5 分钟)清理过期连接。
5. CallServerInterceptor
核心职责:执行实际的网络 I/O 操作,发送请求并读取响应。
-
请求发送:
-
将请求头写入网络流。
-
若有请求体(如 POST 数据),分块写入流。
-
-
响应接收:
-
读取响应头(如状态码、Content-Type)。
-
读取响应体,支持分块传输(
Transfer-Encoding: chunked
)。
-
-
资源管理:
确保请求和响应流正确关闭,异常时释放连接。
3.3 拦截器协作流程图
请求发起 → RetryAndFollowUpInterceptor(重试/重定向) ↓ BridgeInterceptor(补全请求头) ↓ CacheInterceptor(查询缓存) ↓ ConnectInterceptor(建立连接) ↓ CallServerInterceptor(发送请求) 响应返回 ← CallServerInterceptor(读取响应) ↑ ConnectInterceptor(释放连接) ↑ CacheInterceptor(更新缓存) ↑ BridgeInterceptor(解压响应) ↑ RetryAndFollowUpInterceptor(处理最终结果)
3.4 关键场景分析
场景 1:缓存命中
-
请求到达
CacheInterceptor
,发现有效缓存。 -
直接返回缓存响应,后续拦截器(如
ConnectInterceptor
)不再执行。 -
节省网络开销,提升响应速度。
场景 2:重定向处理
-
CallServerInterceptor
收到 302 响应。 -
响应返回到
RetryAndFollowUpInterceptor
,生成新请求。 -
重新执行整个拦截器链,直到成功或超出重试次数。
3.5 总结
OKHttp 通过五大拦截器的分工协作,实现了高效、灵活的网络请求处理:
-
RetryAndFollowUpInterceptor:保障请求的可靠性。
-
BridgeInterceptor:简化开发,自动处理协议细节。
-
CacheInterceptor:优化性能,减少重复请求。
-
ConnectInterceptor:从连接池中复用已有连接,跳过 TCP/TLS 握手,降低延迟。。
-
CallServerInterceptor:完成最终的网络 I/O。
理解拦截器链的流程,有助于开发者定制拦截器(如日志打印、加密)或优化网络行为(如缓存策略、连接池配置)。
四、常见问题与优化
-
内存泄漏
-
确保
Callback
或Call
在 Activity/Fragment 销毁时取消:private Call call; call = client.newCall(request); call.enqueue(callback);// 在 onDestroy() 中取消 if (call != null) call.cancel();
-
-
全局配置
-
推荐将
OkHttpClient
实例化为单例,避免重复创建连接池。
-
-
自定义 DNS
-
替换默认 DNS 以优化解析:
client = new OkHttpClient.Builder().dns(hostname -> {// 自定义 DNS 解析逻辑return InetAddress.getAllByName(hostname);}).build();
-
五、总结
OKHttp 的优势:
-
高效:连接池、HTTP/2 支持、缓存机制。
-
灵活:拦截器链可深度定制请求流程。
-
易用:简洁的 API 设计,支持同步/异步调用。
适用场景:移动端 API 调用、文件下载/上传、需要精细控制网络行为的场景。
通过理解其原理,开发者能更好地优化网络层设计(如统一日志、请求加密、性能监控),并高效解决实际问题。
其它推荐:
《RxJava 深度解析:工作原理、核心操作符与高效实践指南》
《Binder机制原理分析· AIDL示例详解》
《Android View 的事件分发机制解析》
相关文章:
《OkHttp:工作原理 拦截器链深度解析》
目录 一、OKHttp 的基本使用 1. 添加依赖 2. 发起 HTTP 请求 3. 拦截器(Interceptor) 4. 高级配置 二、OKHttp 核心原理 1. 责任链模式(Interceptor Chain) 2. 连接池(ConnectionPool) 3. 请求调度…...
Python 中多种方式获取屏幕的 DPI值
在 Python 中,可以通过多种方式获取屏幕的 DPI(每英寸点数)。以下是几种常见的方法: 方法 1:使用 tkinter 模块 tkinter 是 Python 的标准 GUI 库,可以通过它获取屏幕的 DPI。 import tkinter as tkdef …...
linux安装Mariadb10.5并修改端口
首先配置yum源 进入下方的文件进行配置 vim /etc/yum.repos.d/MariaDB.repo填写下方内容 [mariadb]name MariaDBbaseurl https:///mirrors.aliyun.com/mariadb/yum/10.5/centos8-amd64/gpgkeyhttps:///mirrors.aliyun.com/mariadb/yum/RPM-GPG-KEY-MariaDBmodule_hotfixes…...
Java EE 进阶:Spring IoCDI
IOC的简单介绍 什么是Spring?Spring是一个开源的框架,让我们的开发更加的简单,我们可以用一句更加具体的话来概括Spring,就是Spring是一个包含众多工具方法的IOC容器。 简单介绍一下IOC,我们之前说过通过ReqestContr…...
蓝桥杯备考:图论初解
1:图的定义 我们学了线性表和树的结构,那什么是图呢? 线性表是一个串一个是一对一的结构 树是一对多的,每个结点可以有多个孩子,但只能有一个父亲 而我们今天学的图!就是多对多的结构了 V表示的是图的顶点集…...
JVM类加载器面试题及原理
JVM只会运行二进制文件,类加载器的作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来。 1. 类加载器的种类 启动类加载器(BootStrap ClassLoader):加载JAVA_HOME/jre/lib目录下的库扩展类加载器ÿ…...
《V8 引擎狂飙,Node.js 续写 JavaScript 传奇》
”你没想过也许是这个镇子对你来说太小了吗? 对我而言,这个小镇容不下我的雄心壮志。 “ 什么是 Node.js? Node.js是一个跨平台JS运行环境,使开发者可以搭建服务器端的JS应用程序 作用:使用 Node.js 编写服务器端程序…...
关于Springboot 应配置外移和Maven个性化打包一些做法
期望达到的效果是每次更新服务器端应用只需要更新主程序jar 依赖jar单独分离。配置文件独立存放于文件夹内,更新程序并不会覆盖已有的配置信息。 一、配置外移 1、开发环境外移 做法:在项目同级或者上级创建config文件夹放置配置文件,具体m…...
Lab18_ SQL injection with filter bypass via XML encoding
文章目录 前言:进入实验室构造 payload 前言: 实验室标题为: 通关 XML 编码绕过过滤器的 SQL 注入 简介: 此实验室的库存检查功能中存在 SQL 注入漏洞。查询结果在应用程序的响应中返回,因此您可以使用 UNION 攻击…...
网络空间安全(21)验证码安全
一、基本概念 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。它通过…...
DMA在STM32中的应用
在STM32微控制器中,DMA(直接内存访问)是实现高效数据搬运的核心技术,能够显著减轻CPU负担并提升系统性能。以下是STM32中DMA的典型应用及配置方法: 1. STM32的DMA控制器架构 DMA控制器数量:不同系列配置不同,如STM32F1系列有1个DMA控制器(DMA1,7通道),F4系列有2个(…...
V8引擎中的垃圾回收机制如何工作?
V8引擎中的垃圾回收机制主要通过分代回收和增量标记清除算法来管理内存。以下是其工作原理的详细说明: V8 的垃圾回收机制基于以下核心设计原则: 1. 分代假设:大多数对象的生命周期很短,只有少数对象会存活较长时间;…...
汇编的伪指令
一、介绍 伪指令是用于对汇编过程进行控制的指令,该类指令并不是可执行指令,没有对应机器码,只用于汇编过程中为汇编程序提供汇编信息,帮助编译器编译。当汇编结束时,伪指令的使命也就结束了。伪操作可以实现如下功能…...
【TI】如何更改 CCS20.1.0 的 WORKSPACE 默认路径
参考链接: 如何更改 CCS Theia 中工作区的默认位置?- Code Composer Studio 论坛 - Code Composer Studio™︎ - TI E2E 支持论坛 --- How to change the default location for the workspace in CCS Theia? - Code Composer Studio forum - Code Comp…...
GStreamer —— 2.13、Windows下Qt加载GStreamer库后运行 - “教程13:播放控制“(附:完整源码)
运行效果(音频) 简介 上一个教程演示了GStreamer工具。本教程介绍视频播放控制。快进、反向播放和慢动作都是技术 统称为 Trick Modes,它们都有一个共同点 修改 Normal playback rate。本教程介绍如何实现 这些效果并在交易中添加了帧步进。特别是,它 显…...
推荐一款好用在线免费软件工具箱-传道软件箱
推荐一款好用在线免费软件工具箱-传道软件箱 传道软件箱 传道软件箱是一款在线免费软件工具箱,无需登录,无需费用,用完就走的软件工具,包有BMI计算、倒计时、单位转换、密码生成器、摩斯电码、代码编辑器、计算器、快递查询、二维…...
机器学习数学基础:40.结构方程模型(SEM)中卡方值与卡方自由度比
结构方程模型(SEM)中卡方值与卡方自由度比教程 在结构方程模型分析里,卡方值和卡方自由度比是评估模型拟合程度的重要指标,下面为大家详细介绍。 一、卡方值(CMIN) (一)基本概念与…...
【JavaEE进阶】Spring AOP详解
目录 🍃什么是AOP 🌳什么是Spring AOP 🌴上手Spring AOP 🚩引入依赖 🚩编写AOP程序 🎍Spring AOP核心概念 🚩切点(Pointcut) 🚩连接点(Join Point) 🚩通知(Advi…...
Docker 的基本概念和优势,以及在应用程序开发中的实际应用
Docker 是一种开源的容器化平台,让开发人员能够打包、发布和运行应用程序在轻量级、可移植的容器中。Docker 容器包含应用程序的代码、运行时环境、系统工具、系统库等,使得应用程序能在任何环境中快速部署和运行。 Docker 的基本概念包括以下几点&…...
python flask
安装 pip install flask 查看版本 pip show flask 启动服务器 设置环境变量,在控制台执行命令,app.py是创建的文件名 windows set FLASK_APPapp.py mac/linux export FLASK_APPapp.py 启动内置web服务器,注意要进入到app.py所在的文…...
关于tomcat使用中浏览器打开index.jsp后中文显示不正常是乱码,但英文正常的问题
如果是jsp文件就在首行加 “<% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8" %>” 如果是html文件 在head标签加入: <meta charset"UTF-8"> 以jsp为例子,我们…...
双向选择排序算法
一 概述 双向选择排序(又称鸡尾酒选择排序)是选择排序的优化版本,核心改进在于每轮遍历同时确定未排序部分的最小值和最大值,分别交换到序列两端,从而减少遍历轮数。 二 时间复杂度 时间复杂度为(O(n^2)),但实际比较次数约为标准选择排序的 (1/2)。 三 C++实现代…...
P8662 [蓝桥杯 2018 省 AB] 全球变暖--DFS
P8662 [蓝桥杯 2018 省 AB] 全球变暖--dfs 题目 解析讲下DFS代码 题目 解析 这道题的思路就是遍历所有岛屿,判断每一块陆地是否会沉没。对于这种图的遍历,我们首先应该想到DFS。 代码的注意思想就是,在主函数中遍历找出所有岛屿,…...
2-kafka集群环境搭建
本文介绍kafka集群环境的搭建,我利用三个虚拟机搭建。文中我一步步演示了过程中可能会碰到的问题,在文章的最后,利用jmx,能看到详细的各个kafka broker的运行情况。 -1、环境 ubuntu :22.04-ltskafka: 2.8java: 17 …...
ROS2与Navigation2入门教程:构建与安装Nav2
Navigation2(Nav2)是ROS2中用于机器人导航的核心框架,支持路径规划、避障、SLAM等功能。本教程将详细介绍Nav2的安装与构建方法,涵盖二进制安装、源码编译及Docker部署等多种方式,适用于不同开发需求。 一、通过APT安…...
MySQL入门手册
MySQL入门手册:从零开始掌握数据库管理 📖 一、MySQL是什么? MySQL 是一个开源的关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,现隶属于Oracle旗下。它使用**结构化查询语言ÿ…...
深度学习算法实战——风格迁移(主页有源码)
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ 1. 领域介绍 风格迁移(Style Transfer)是深度学习中的一个热门应用,旨在将一幅图像的风格迁移到…...
基于SpringBoot的智能问诊系统设计与隐私保护策略
通过SpringBoot框架,我们可以快速搭建一个智能问诊系统,为用户提供便捷的线上医疗服务。然而,在系统设计和实现过程中,如何保障用户的隐私和数据安全,始终是一个亟需关注的问题。本文将探讨基于SpringBoot的智能问诊系…...
开发ai模型最佳的系统是Ubuntu还是linux?
在 AI/ML 开发中,Ubuntu 是更优选的 Linux 发行版,原因如下: 1. 开箱即用的 AI 工具链支持 Ubuntu 预装了主流的 AI 框架(如 TensorFlow、PyTorch)和依赖库,且通过 apt 包管理器可快速部署开发环境。 提…...
Vue 3 ref(new Map()) 无法触发watch
现象 const map ref(new Map()); 通过 map.value.set(k, v); 不能触发watch 下面验证,map.value.set 并不能触发watch 的监听 代码 <script setup lang"ts"> import { ref, triggerRef, watch } from vue;const map ref(new Map<string, R…...
NoteGen是一款开源跨平台的 AI 笔记应用,专注于 recording 和 writing ,基于 Tauri 开发
一、软件介绍 文末提供程序和源码下载 NoteGen 是一款专注于记录和写作的跨平台 AI 笔记应用,基于 Tauri 开发。NoteGen 的核心理念是将记录、写作和 AI 结合使用,三者相辅相成。记录功能可以帮助用户快速捕捉和整理碎片化知识。整理功能是连接记录和写…...
repo访问gerrit.googlesource失败
编译openharmony的时候,repo阶段碰到一个问题,建议不要通过 apt install安装,里面的源来自google curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 -o ~/repo chmod 755 ~/repo 执行类似这样的操作 repo init -u gitgitee.com:…...
IDEA中Git版本回退终极指南:Reset与Revert双方案详解
目录 前言一、版本回退前置知识二、Reset方案:整体改写历史1、IDEA图形化操作(推荐)1.1、查看提交历史1.2、选择目标版本1.3、选择回退模式1.3.1、Soft(推荐)1.3.2、Mixed1.3.3、Hard(慎用)1.3.…...
【系统架构设计师】体系结构复审
目录 1. 说明2. 例题2.1 例题1 1. 说明 1.体系结构设计、文档化和复审是一个迭代过程。2.从这个方面来说,在一个主版本的软件体系结构分析之后,要安排一次由外部人员(用户代表和领域专家)参加的复审。3.鉴于体系结构文档标准化以…...
Unity之如何实现哔哩哔哩直播弹幕游戏
前言 什么是直播间互动? 当我们使用哔哩哔哩进行直播或者观看视频时,我们可以通过接入哔哩哔哩提供的 直播&互动玩法SDK,让直播和视频可以与Unity3D游戏客户端或者游戏服务器进行互动。 环境要求 Unity 2020.x或更高版本 依赖库:Newtonsoft Json Unity Package 在P…...
视觉图像处理
在MATLAB中进行视觉图像处理仿真通常涉及图像增强、滤波、分割、特征提取等操作。以下是一个分步指南和示例代码,帮助您快速入门: 1. MATLAB图像处理基础步骤 1.1 读取和显示图像 % 读取图像(替换为实际文件路径) img = imread(lena.jpg); % 显示原图 figure; subplot(2…...
学习LED驱动知识(二)
ppt来自B站周老师 使用普通元器件或者电源芯片构建电路驱动LED 1.电阻降压限流设计 案例一: USB供电电压为5V,因为LED的Vf为3v,所以电路只能6个LED并联,直接跟电源并联电流太大,LED会过流导致断路。所以要先串联一个…...
011---UART协议的基本知识(一)
1. 摘要 文章为学习记录。主要介绍 UART 协议的概述、物理层、协议层、关键参数。 2. UART概述 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART(串口),是一种异步****串…...
如何选择开源向量数据库
文章目录 评估维度查询性能索引与存储扩展性数据管理能力生态支持 常见向量数据库对比 评估维度 选择开源向量数据库时,需要综合考虑查询性能、数据规模、索引构建速度、生态支持等多个因素,以下是关键的评估维度:选择开源向量数据库时&…...
SpringBoot项目配置文件
SpringBoot项目提供了多种属性配置方式(properties、yaml、yml) yml配置文件 使用Apifox可以方便开发接口、前端测试等 工程搭建: 1.创建SpringBoot工程,并引入web开发起步依赖、mybatis、mysql驱动、lombok 2.创建数据库表&am…...
L33.【LeetCode笔记】循环队列(数组解法)
目录 1.题目 2.分析 方法1:链表 尝试使用单向循环链表模拟 插入节点 解决方法1:开辟(k1)个节点 解决方法2:使用变量size记录队列元素个数 获取队尾元素 其他函数的实现说明 方法2:数组 重要点:指针越界的解决方法 方法1:单独判断 方法2:取模 3.数组代码的逐步实现…...
前端知识点---库和包的概念
1. 什么是库(Library)? 库(Library) 是一组可复用的代码集合,提供特定功能(如网络请求、UI 组件、数据处理等)。 特点: 只是代码的集合,没有完整的应用结构…...
【CSS3】筑基篇
目录 复合选择器后代选择器子选择器并集选择器交集选择器伪类选择器 CSS 三大特性继承性层叠性优先级 背景属性背景色背景图背景图平铺方式背景图位置背景图缩放背景图固定背景复合属性 显示模式显示模式块级元素行内元素行内块元素 转换显示模式 结构伪类选择器结构伪类选择器…...
CentOS7 安装docker并配置镜像加速
一、Yum 安装docker【不推荐】 /var/lib/docker 路径主要用于存储容器数据,在使用和操作过程中数据量会逐渐增加。因此,在生产环境中,建议为 /var/lib/docker 单独挂载一个硬盘。也可以使用软连接的方式 1.1 安装必要的一些系统工具 yum i…...
【Go每日一练】统计字符出现的次数
👻创作者:丶重明 👻创作时间:2025年3月9日 👻擅长领域:运维 目录 1.😶🌫️题目:2.😶🌫️资源:3.😶🌫️代…...
正向代理与反向代理
代理: 通常称为代理、代理服务器或 Web 代理,代理一般是指正向代理,是位于一组客户端计算机之前的服务器。当这些计算机向 Internet 上的站点和服务发出请求时,代理服务器将拦截这些请求,然后代表客户端与 Web服务器进行通信&…...
报表DSL优化,享元模式优化过程,优化效果怎么样?
报表DSL优化与享元模式应用详解 一、报表DSL优化 1. 问题背景 报表系统通常使用领域特定语言(DSL)定义模板结构、数据绑定规则及样式配置。随着复杂度提升,DSL可能面临以下问题: 冗余配置:重复定义样式、布局或数据源…...
双击PPT文件界面灰色不可用,需要再次打开该PPT文件才能正常打开
双击PPT文件界面灰色不可用,需要再次打开该PPT文件才能正常打开 1. 软件环境⚙️2. 问题描述🔍3. 解决方法🐡解决步骤 4. 结果预览🤔 1. 软件环境⚙️ Windows10 或 Windows11 专业版64位,安装MotionGo软件(…...
学习前置知识第18和19天
今天要做什么? 1:显示数字要求格式 2:无符号除法指令:div 3:前面用vhd和img等格式进行系统界面启动,详细了解多种镜像格式文件的区别 一:显示数字要求格式 屏幕上显示的数字格式,三个颜色编码和数字属性 1&…...
C#运算符详解
一、运算符分类与功能 1.算术运算符 基本运算:(加)、-(减)、*(乘)、/(除)、%(取模) int a 10 / 3; // 结果为3(整数除…...