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

Retrofit核心源码分析(三)- Call逻辑分析和扩展机制

在前面的两篇文章中,我们已经对 Retrofit 的注解解析、动态代理、网络请求和响应处理机制有了一定的了解。在这篇文章中,我们将深入分析 Retrofit 的 Call 逻辑,并介绍 Retrofit 的扩展机制。

一、Call 逻辑分析

Call 是 Retrofit 中最基本的操作单元,它代表一个 HTTP 请求。在 Retrofit 中,我们通过接口定义请求的方式,并通过动态代理生成接口的实现类。这个实现类中的方法都会返回一个 Call 对象,通过这个对象我们可以发起网络请求,并获得响应结果。

Retrofit 的 Call 逻辑可以用以下代码来描述:

public interface Call<T> {Response<T> execute() throws IOException;void enqueue(Callback<T> callback);void cancel();boolean isExecuted();boolean isCanceled();Call<T> clone();
}

在这个接口中,我们可以看到 Retrofit 定义了五个方法,分别是 executeenqueuecancelisExecutedisCanceled。我们来逐一分析这些方法的作用。

execute 方法

execute方法用于同步发起 HTTP 请求,当我们调用execute()方法时,它会立即发起网络请求,并且阻塞当前线程直到请求结束,最后返回一个响应对象Response。这种方式适用于简单的网络请求,但不适合于在主线程中执行请求,因为会阻塞 UI 线程。

以下是execute()方法的部分代码:

@Override
public Response<T> execute() throws IOException {synchronized (this) {if (executed) throw new IllegalStateException("Already executed.");executed = true;}captureCallStackTrace();try {client.dispatcher().executed(this);Response<T> result = getResponseWithInterceptorChain();if (result == null) throw new IOException("Canceled");return result;} catch (IOException e) {throw timeoutExit(e);} finally {client.dispatcher().finished(this);}
}

上述代码中,我们可以看到该方法首先会检查当前请求是否已经执行过,如果已经执行过则会抛出一个异常。然后会将该请求加入到Dispatcher中的执行队列中。接下来会调用getResponseWithInterceptorChain()方法来获取响应结果。如果结果为null,则表示请求已经被取消,否则返回响应结果。最后,会将该请求从执行队列中移除。

enqueue 方法

enqueue方法用于异步发起 HTTP 请求,它会在后台线程中发起网络请求,并在请求结束后将结果返回到主线程中。因此,enqueue()方法适用于在主线程中执行网络请求。

以下是enqueue()方法的部分代码:

@Override
public void enqueue(Callback<T> callback) {synchronized (this) {if (executed) throw new IllegalStateException("Already executed.");executed = true;}captureCallStackTrace();client.dispatcher().enqueue(new AsyncCall(callback));
}

上述代码中,我们可以看到该方法首先会检查当前请求是否已经执行过,如果已经执行过则会抛出一个异常。然后会将该请求封装成一个AsyncCall对象,加入到Dispatcher中的异步队列中。

AsyncCall继承自RealCall,它实现了Runnable接口,表示可以在后台线程中执行。在AsyncCall中,我们可以看到它会在后台线程中执行网络请求,并将结果通过Callback回调返回到主线程中。

final class AsyncCall extends RealCall.AsyncCall {private final Callback<T> responseCallback;AsyncCall(Callback<T> responseCallback) {super();this.responseCallback = responseCallback;}@Override protected void execute() {boolean signalledCallback = false;try {Response<T> response = getResponseWithInterceptorChain();if (retryAndFollowUpInterceptor.isCanceled()) {signalledCallback = true;responseCallback.onFailure(RealCall.this, new IOException("Canceled"));} else {signalledCallback = true;responseCallback.onResponse(RealCall.this, response);}} catch (IOException e) {if (signalledCallback) {// Do not signal the callback twice!Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);} else {responseCallback.onFailure(RealCall.this, e);}} finally {client.dispatcher().finished(this);}}@Override public String toString() {return RealCall.this.toString();}
}

AsyncCall中,首先会调用getResponseWithInterceptorChain()方法来获取响应结果。如果请求被取消,则会调用onFailure()方法将结果返回到主线程中。否则,会调用onResponse()方法将结果返回到主线程中。无论请求成功或失败,都会调用finished()方法将该请求从异步队列中移除。

cancel 方法

cancel方法用于取消正在执行的请求。如果请求已经完成或已经取消,则该方法不会有任何效果。

isExecuted 方法

isExecuted方法用于判断请求是否已经执行。如果已经执行,则返回true,否则返回false。

isCanceled 方法

isCanceled方法用于判断请求是否已经取消。如果已经取消,则返回true,否则返回false。

clone 方法

clone方法用于创建一个当前 Call 对象的副本。这个方法一般用于发起多次相同的请求。

以上这些方法就构成了 Retrofit 的 Call 逻辑。在使用 Retrofit 时,我们一般会通过executeenqueue方法发起 HTTP 请求,并通过传入的Callback对象来处理响应结果。

二、扩展机制

Retrofit 是一个非常灵活的网络请求库,它提供了很多扩展机制,让我们可以根据自己的需要来定制请求和响应处理逻辑。下面介绍一些常用的扩展机制。

Converter

Converter 用于将 HTTP 请求和响应的数据类型转换成 Java 对象。Retrofit 默认提供了两种 Converter:GsonConverterJacksonConverter,它们分别使用GsonJackson库将数据类型转换成Java对象。如果我们需要使用其他类型的转换库,也可以自定义 Converter 来实现。

下面是一个自定义 Converter 的示例:

public class MyConverter implements Converter<ResponseBody, MyObject> {private Gson gson;public MyConverter(Gson gson) {this.gson = gson;}@Overridepublic MyObject convert(ResponseBody value) throws IOException {try {String json = value.string();MyObject obj = gson.fromJson(json, MyObject.class);return obj;} finally {value.close();}}
}

在上面的示例中,我们定义了一个MyConverter类,它实现了Converter接口,用于将ResponseBody类型的响应数据转换成MyObject类型的Java对象。在convert方法中,我们使用自己定义的转换逻辑来实现数据类型的转换。

Interceptor

Interceptor 用于对 HTTP 请求进行拦截和处理。在 Retrofit 中,我们可以通过 Interceptor 来对请求添加头信息、对响应进行缓存、打印请求日志等操作。Retrofit 提供了两种 Interceptor:OkHttpInterceptorRetrofitInterceptor,它们分别用于拦截 OkHttp 的请求和 Retrofit 的请求。我们也可以自定义 Interceptor 来实现自己的拦截逻辑。

下面是一个自定义 Interceptor 的示例:

public class MyInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {// 在这里可以对请求进行拦截和处理Request request = chain.request();Response response = chain.proceed(request);// 在这里可以对响应进行处理return response;}
}

在上面的示例中,我们定义了一个MyInterceptor类,它实现了Interceptor接口,用于对请求和响应进行拦截和处理。在intercept方法中,我们可以对请求进行处理,然后使用chain.proceed(request)方法将请求传递给下一个拦截器或处理器,最终获得响应结果并进行处理。

CallAdapter

CallAdapter 用于将 Call 对象转换成另一种类型的对象。在 Retrofit 中,我们可以通过 CallAdapter 将 Call 对象转换成 RxJava 的 Observable 对象,也可以将 Call 对象转换成 LiveData 对象。Retrofit 提供了两种CallAdapter:RxJavaCallAdapterLiveDataCallAdapter,它们分别用于将 Call 对象转换成 RxJava 的 Observable 对象和 LiveData 对象。我们也可以自定义 CallAdapter 来实现自己的转换逻辑。

下面是一个自定义 CallAdapter 的示例:

public class MyCallAdapter<T> implements CallAdapter<T, MyResult<T>> {@Overridepublic Type responseType() {// 返回响应数据的类型return new ParameterizedTypeImpl(MyResult.class, new Type[]{T.class});}@Overridepublic MyResult<T> adapt(Call<T> call) {// 在这里可以对Call对象进行处理,并返回自定义的结果对象try {Response<T> response = call.execute();return new MyResult<>(response.body(), response.code(), response.message());} catch (IOException e) {return new MyResult<>(e);}}
}

在上面的示例中,我们定义了一个MyCallAdapter类,它实现了CallAdapter接口,用于将Call对象转换成MyResult对象。在responseType方法中,我们返回了响应数据的类型,它是一个ParameterizedTypeImpl类型的对象,用于表示MyResult<T>类型。在adapt方法中,我们对Call对象进行处理,并返回自定义的MyResult对象,它包含了响应数据、状态码和错误信息。

总结

在本文中,我们深入分析了 Retrofit 的核心源码,特别是 Call 逻辑的实现细节,以及 Retrofit 的三个扩展机制:Converter、Interceptor 和 CallAdapter。

通过本文的学习,我们可以更加深入地理解 Retrofit 的工作原理,并可以根据需求自定义扩展 Retrofit 的功能。同时,本文提供了三个扩展机制的示例代码,可以帮助读者更加深入地了解 Retrofit 的扩展机制的使用。

相关文章:

Retrofit核心源码分析(三)- Call逻辑分析和扩展机制

在前面的两篇文章中&#xff0c;我们已经对 Retrofit 的注解解析、动态代理、网络请求和响应处理机制有了一定的了解。在这篇文章中&#xff0c;我们将深入分析 Retrofit 的 Call 逻辑&#xff0c;并介绍 Retrofit 的扩展机制。 一、Call 逻辑分析 Call 是 Retrofit 中最基本…...

源码分析spring如和对@Component注解进行BeanDefinition注册的

Spring ioc主要职责为依赖进行处理&#xff08;依赖注入、依赖查找&#xff09;、容器以及托管的(java bean、资源配置、事件)资源声明周期管理&#xff1b;在ioc容器启动对元信息进行读取&#xff08;比如xml bean注解等&#xff09;、事件管理、国际化等处理&#xff1b;首先…...

C语言--字符串函数1

目录前言strlenstrlen的模拟实现strcpystrcatstrcat的模拟实现strcmpstrcmp的模拟实现strncpystrncatstrncmpstrstrstrchr和strrchrstrstr的模拟实现前言 本章我们将重点介绍处理字符和字符串的库函数的使用和注意事项。 strlen 我们先来看一个我们最熟悉的求字符串长度的库…...

Webstorm使用、nginx启动、FinalShell使用

文章目录 主题设置FinalShellFinalShell nginx 启动历史命令Nginx页面发布配置Webstorm的一些常用快捷键代码生成字体大小修改Webstorm - gitCode 代码拉取webstorm 汉化webstorm导致CPU占用率高方法一 【忽略node_modules】方法二 【设置 - 代码编辑 - 快速预览文档 - 关闭】主…...

源码分析Spring @Configuration注解如何巧夺天空,偷梁换柱。

前言 回想起五年前的一次面试&#xff0c;面试官问Configuration注解和Component注解有什么区别&#xff1f;记得当时的回答是&#xff1a; 相同点&#xff1a;Configuration注解继承于Component注解&#xff0c;都可以用来通过ClassPathBeanDefinitionScanner装载Spring bean…...

vector的使用及模拟实现

目录 一.vector的介绍及使用 1.vector的介绍 2.vector的使用 1.vector的定义 2.vector iterator的使用 3. vector 空间增长问题 4.vector 增删查改 3.vector 迭代器失效问题&#xff08;重点&#xff09; 1. 会引起其底层空间改变的操作 2.指定位置元素的删除操作--erase 3. Li…...

“华为杯”研究生数学建模竞赛2007年-【华为杯】A题:基于自助法和核密度估计的膳食暴露评估模型(附获奖论文)

赛题描述 我国是一个拥有13亿人口的发展中国家,每天都在消费大量的各种食品,这批食品是由成千上万的食品加工厂、不可计数的小作坊、几亿农民生产出来的,并且经过较多的中间环节和长途运输后才为广大群众所消费,加之近年来我国经济发展迅速而环境治理没有能够完全跟上,以…...

刷题(第三周)

目录 [CISCN2021 Quals]upload [羊城杯 2020]EasySer [网鼎杯 2020 青龙组]notes [SWPU2019]Web4 [Black Watch 入群题]Web [HFCTF2020]BabyUpload [CISCN2021 Quals]upload 打开界面以后&#xff0c;发现直接给出了源码 <?php if (!isset($_GET["ctf"]))…...

新C++(14):移动语义与右值引用

当你在学习语言的时候&#xff0c;是否经常听到过一种说法,""左边的叫做左值&#xff0c;""右边的叫做右值。这句话对吗&#xff1f;从某种意义上来说&#xff0c;这句话只是说对了一部分。---前言一、什么是左右值?通常认为:左值是一个表示数据的表达式(…...

TCP相关概念

目录 一.滑动窗口 1.1概念 1.2滑动窗口存在的意义 1.3 滑动窗口的大小变化 1.4丢包问题 二.拥塞控制 三.延迟应答 四.捎带应答 五.面向字节流 六.粘包问题 七.TIME_WAIT状态 八.listen第2个参数 九.TCP总结 一.滑动窗口 1.1概念 概念&#xff1a;双方在进行通信时&a…...

MySQL锁篇

MySQL锁篇 一、一条update语句 我们的故事继续发展&#xff0c;我们还是使用t这个表&#xff1a; CREATE TABLE t (id INT PRIMARY KEY,c VARCHAR(100) ) EngineInnoDB CHARSETutf8;现在表里的数据就是这样的&#xff1a; mysql> SELECT * FROM t; —------- | id | c | —…...

SWF (Simple Workflow Service)简介

Amazon Simple Workflow Service (Amazon SWF) 提供了给应用程序异步、分布式处理的流程工具。 SWF可以用在媒体处理、网站应用程序后端、商业流程、数据分析和一系列定义好的任务上。 举个例子&#xff0c;下图表明了一个电商网站的工作流程&#xff0c;其中涉及了程序执行的…...

java(Class 常用方法 获取Class对象六种方式 动态和静态加载 类加载流程)

ClassClass常用方法获取Class对象六种方式哪些类型有Class对象动态和静态加载类加载流程加载阶段连接阶段连接阶段-验证连接阶段-准备连接阶段-解析初始化阶段获取类结构信息Class常用方法 第一步&#xff1a;创建一个实体类 public class Car {public String brand "宝…...

【数据结构】线性表和顺序表

Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 1.线性表 2.顺序表 2.1 静态顺序表 2.2 动态顺序表 2.3移除元素 1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线…...

Ubuntu数据库安装(mysql)

##1.下载mysql-apt-config_0.8.22-1_all.deb并且安装 wget https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb sudo dpkg -i mysql-apt-config_0.8.22-1_all.deb##2.更新apt-updata sudo apt update##3.如果出现如下图情况执行以下命令 [外链图片转存失败,源站可…...

MyBatis-Plus的入门学习

MyBatis-Plus入门学习简介特性快速开始MyBatis-Plus的注解详解Tableld主键生成策略1、数据库自动增长 AUTO2、UUID3、Redis生成id4、MP主键自动生成TableNameTableField自动填充测试方法&#xff1a;update乐观锁select查所有根据id查多个id批量查询简单条件查询&#xff08;通…...

华为OD机试题 - 内存池(JavaScript)

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:内存池题目输入输出示例一输入输出说明Code解题思路版权说明华为…...

数据库索引原理

数据库索引的作用是做数据的快速检索&#xff0c;而快速检索实现的本质是数据结构。像二叉树、红黑树、AVL树、B树、B树、哈希等数据结构都可以实现索引&#xff0c;但其中B树效率最高。MySQL数据库索引使用的是B树。二叉树&#xff1a;二叉树中&#xff0c;左子树比根节点小&a…...

字符函数和字符串函数详解(1)

目录前言strlen函数strlensizeofstrcpy函数strcat函数strcmp函数总结前言 最近要调整状态&#xff0c;写的文章质量不佳让大家失望&#xff0c;我现在也在反思我在做什么&#xff0c;我会什么&#xff0c;我学了什么。等我想明白的那天&#xff0c;我一定能跟大家顶峰相见的&a…...

【数据分析:工具篇】NumPy(1)NumPy介绍

【数据分析&#xff1a;工具篇】NumPy&#xff08;1&#xff09;NumPy介绍NumPy介绍NumPy的特点数组的基本操作创建数组索引和切片数组运算NumPy介绍 NumPy&#xff08;Numerical Python&#xff09;是Python的一个开源的科学计算库&#xff0c;它主要用于处理大规模的多维数组…...

mysql时区问题

设置mysql容器时间与服务器时间一致 问题背景&#xff1a; 今天测试发现一个问题&#xff0c;时间不一致&#xff0c;当工单入库时&#xff0c;其创建时间和更新时间应该是一样的&#xff0c;即使不一样最多只会错几秒的时间&#xff1b;实际上两个时间相差的大概8小时&#…...

磨金石教育摄影技能干货分享|高邮湖上观花海

江苏高邮&#xff0c;说到这里所有人能想到的&#xff0c;就是那烟波浩渺的高邮湖。高邮在旅游方面并不出名&#xff0c;但是这里的自然人文景观绝对不输于其他地方。高邮不止有浩瀚的湖泊&#xff0c;春天的油菜花海同样壮观。春日的午后&#xff0c;与家人相约游玩&#xff0…...

mysql navicat忘记密码

mysql忘记密码是常用的事情&#xff0c;那么如何解决它呢&#xff1f;1、首先将MySQL的服务关闭&#xff0c;两种方法&#xff1a;&#xff08;1&#xff09;打开命令行cmd输入net stop mysql命令即可关闭MySQL服务。&#xff08;2&#xff09;打开任务管理器&#xff0c;找到服…...

Git的下载、安装、配置、使用、卸载

前言 我是跟着狂神老师学的。该博客仅用于笔记所用。 下面是老师的B站和笔记 B站&#xff1a;https://www.bilibili.com/video/BV1FE411P7B3?p1&vd_source9266cf72b1f398b63abe0aefe358d7d6 笔记&#xff1a;https://mp.weixin.qq.com/s/Bf7uVhGiu47uOELjmC5uXQ 一、准备工…...

【博客631】监控网卡与进程网络IO使用情况

监控进程的网络IO使用情况 1、vnstat 由于 vnstat 依赖于内核提供的信息&#xff0c;因此执行以下命令来验证内核是否提供了 vnStat 所期望的所有信息&#xff1a; # vnstat --testkernel This test will take about 60 seconds. Everything is ok.不带任何参数的 vnstat 将…...

【Leetcode】【简单】35. 搜索插入位置

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2 示例 2: 输入:…...

sql面试题

mysql优化 优化准则&#xff1a; 建表时&#xff1a;合理选择字段的类型&#xff0c;单表字段数量 sql查询尽量单表操作&#xff0c;避免复杂操作&#xff0c;复杂的多表通过java代码实现 构建复合索引优化&#xff0c;索引尽量可以覆盖主要业务查询 sql避免索引失效 避免大…...

SQL 进阶刷题笔记

SQL 进阶刷题笔记 一、MySQL 进阶 这里主要是 MySQL 刷题相关笔记&#xff0c;方便后面温习和查阅&#xff0c;希望可以帮到大家&#xff01;&#xff01;&#xff01; 题1 请计算每张SQL类别试卷发布后&#xff0c;当天5级以上的用户作答的人数uv和平均分avg_score&#xff0…...

[网鼎杯 2020 朱雀组]Think Java

SqlDict.java ,其中sql语句处存在sql注入漏洞 package .sqldict;import cn.abc.core.sqldict.Row; import cn.abc.core.sqldict.Table; import java...

AIR32F103(十) 在无系统环境和FreeRTOS环境集成LVGL

目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告AIR32F103(二) Linux环境和LibOpenCM3项目模板AIR32F103(三) Linux环境基于标准外设库的项目模板AIR32F103(四) 27倍频216MHz,CoreMark跑分测试AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码AIR32F103(六) ADC,I2S…...

SpringBoot接口 - 如何统一异常处理

SpringBoot接口如何对异常进行统一封装&#xff0c;并统一返回呢&#xff1f;以上文的参数校验为例&#xff0c;如何优雅的将参数校验的错误信息统一处理并封装返回呢&#xff1f;为什么要优雅的处理异常如果我们不统一的处理异常&#xff0c;经常会在controller层有大量的异常…...

如何使用Python进行数据可视化

数据可视化是一种将数据呈现为图形或图表的技术&#xff0c;它有助于理解和发现数据中的模式和趋势。Python是一种流行的编程语言&#xff0c;有很多库可以帮助我们进行数据可视化。在本文中&#xff0c;我们将介绍使用Python进行数据可视化的基本步骤。 第一步&#xff1a;导…...

vue -- 自定义指令钩子函数补充 自定义过滤器filter参数

自定义指令补充 自定义指令通过钩子函数的形式来实现自定义的功能 这里是几个常用的钩子函数以及它的方法&#xff1a; bind&#xff1a;只调用一次&#xff0c;指令第一次绑定到元素时调用&#xff0c;在这里可以进行一次性的初始化设置。 inserted&#xff1a;被绑定元素插…...

Qt不会操作?Qt原理不知道? | Qt详细讲解

文章目录Qt界面开发必备知识UI界面与控件类型介绍Qt设计器原理控件类型的介绍信号与槽机制处理常用控件创建与设置常见展示型控件创建与设置常见动作型控件创建与设置常见输入型控件创建与设置常见列表控件创建于设置Qt中对象树的介绍项目源码结构刨析.pro.hmain.cpp.cppQt界面…...

LeetCode-面试题 17.05. 字母与数字【前缀和,哈希表】

LeetCode-面试题 17.05. 字母与数字【前缀和&#xff0c;哈希表】题目描述&#xff1a;解题思路一&#xff1a;前缀和。数字为-1&#xff0c;字母为1。我们需要找到的子数组是前缀和之差为0的&#xff0c;例如s[right]-s[left]0&#xff0c;那么s[right]s[left]&#xff0c;变为…...

华为OD机试题 - 叠放书籍(JavaScript)| 机考必刷

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:叠放书籍题目输入输出示例一输入输出Code解题思路版权说明华为O…...

【数据库概论】第十一章 数据库并发控制

第十一章 并发控制 在多处理机系统中&#xff0c;每个处理机可以运行一个事务&#xff0c;多个处理机可以同时运行多个事务&#xff0c;实现多个事务并行运行&#xff0c;这就是同时并发方式。当多个用户并发存取数据库时会产生多个事务同时存取同一事务的情况&#xff0c;如果…...

Nginx配置实例-反向代理案例二

实现效果&#xff1a;使用nginx反向代理&#xff0c;根据访问的路径跳转到不同端口服务 nginx监听端口为9000&#xff0c; 访问 http://127.0.0.1:9000/edu/ 直接跳转到127.0.0.1:8080 访问 http://127.0.0.1:9000/vod/ 直接跳转到127.0.0.1:8081 一、准备工作 1. 准备两个tom…...

HTML 字符集

为了正确显示 HTML 页面&#xff0c;Web 浏览器必须知道要使用哪个字符集。 从 ASCII 到 UTF-8 ASCII 是第一个字符编码标准。ASCII 定义了 128 种可以在互联网上使用的字符&#xff1a;数字&#xff08;0-9&#xff09;、英文字母&#xff08;A-Z&#xff09;和一些特殊字符…...

【C语言】每日刷题 —— 牛客语法篇(3)

前言 大家好&#xff0c;继续更新专栏c_牛客&#xff0c;不出意外的话每天更新十道题&#xff0c;难度也是从易到难&#xff0c;自己复习的同时也希望能帮助到大家&#xff0c;题目答案会根据我所学到的知识提供最优解。 &#x1f3e1;个人主页&#xff1a;悲伤的猪大肠9的博客…...

基于Vue3和element-plus实现一个完整的登录功能

先看一下最终要实现的效果:登录页面:注册页面:(1)引入element-plus组件库引入组件库的方式有好多种,在这里我就在main.js全局引入了.npm i element-plus -Smain.js中代码:import { createApp } from "vue"; //element-plus import ElementPlus from "element-pl…...

【java】Java 中泛型的实现原理

文章目录前序1. 泛型1.1 泛型方法1.2 泛型类1.3 泛型接口2. 泛型的基本原理3. 小结前序 泛型是 Java 开发中常用的技术&#xff0c;了解泛型的几种形式和实现泛型的基本原理&#xff0c;有助于写出更优质的代码。本文总结了 Java 泛型的三种形式以及泛型实现原理。 1. 泛型 …...

【C++提高编程】C++全栈体系(二十七)

C提高编程 第五章 STL- 常用算法 三、常用排序算法 算法简介&#xff1a; sort //对容器内元素进行排序random_shuffle //洗牌 指定范围内的元素随机调整次序merge // 容器元素合并&#xff0c;并存储到另一容器中reverse // 反转指定范围的元素 1. sort 功能描述&#…...

软考高级信息系统项目管理师系列之三十九:项目集管理

软考高级信息系统项目管理师系列之三十九:项目集管理 一、项目集管理内容二、项目集管理基础概述1.项目集定义2.项目集活动3.项目集管理三、项目集的管理过程四、项目集治理1.项目集治理概述2.项目集指导委员会的职责3.项目集治理功能五、项目集生命周期1.项目集生命周期三个阶…...

44-Golang中的channel

Golang中的channel为什么要使用channelchannel的介绍channel的基本使用定义/声明channel管道的遍历和关闭channel的关闭channel的遍历goroutine和channel结合应用实例1应用实例2案例注意事项为什么要使用channel 前面使用全局变量加锁同步来解决goroutine的通讯&#xff0c;但…...

80/20法则

80/20法则&#xff08;The 80/20 Rule&#xff09;又称为帕累托法则(Pareto Principle&#xff09;、二八定律、帕累托定律、最省力法则、不平衡原则、犹太法则、马特莱法则等一、什么是80/20法则80/20法则&#xff08;The 80/20 Rule&#xff09;&#xff0c;又称为帕累托法则…...

计算机网络高频面试题(四)

一、什么是计算机网络 是一个将分散的、具有独立功能的计算机系统&#xff0c;通过通信设备与线路连接起来&#xff0c;由功能完善的软件实现资源共享和信息传递的系统 按分布范围&#xff0c;计算机网络里有局域网LAN和广域网WAN, 其中局域网的代表以太网&#xff0c;以及这…...

[计算机组成原理(唐朔飞 第2版)]第三章 系统总线(学习复习笔记)

3.1 总线的基本概念 计算机系统的五大部件之间的互连方式有两种 各部件之间使用单独的连线&#xff0c;称为分散连接将各部件连到一组公共信息传输线上&#xff0c;称为总线连接 总线是连接多个部件的信息传输线&#xff0c;是各部件共享的传输介质。 当多个部件与总线相连时&…...

华为OD机试题 - 计算堆栈中的剩余数字(JavaScript)| 机考必刷

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:计算堆栈中的剩余数字题目输入输出描述示例一输入输出说明示例二…...

VB实现点爆炸效果

需在窗体放置以下 4 个控件&#xff0c;所有控件不用设置任何属性&#xff0c;均采用默认设置&#xff1a; ’ Picture1&#xff0c;Command1&#xff0c;Check1&#xff0c;Timer1 Option Explicit Dim I Dim ctD() As tyD, ctDs As Long, ctR As Single Private Type tyD x…...