OkHttp、Retrofit、RxJava:一文讲清楚
一、okHttp的同步和异步请求
Call 是 OkHttp 的核心接口,代表一个已准备好执行的 HTTP 请求。它支持 同步 和 异步 两种模式:
enqueue——>okHttp异步
OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://example.com").build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onResponse(Call call, Response response) throws IOException {System.out.println("Response: " + response.body().string());}@Overridepublic void onFailure(Call call, IOException e) {System.err.println("Request failed: " + e.getMessage());}
});
execute——>同步请求
特点
-
阻塞线程
请求发送后,当前线程会阻塞,直到服务器返回响应或超时。 -
直接返回结果
通过execute()
方法直接返回Response
对象,无需回调。 -
线程管理
不能在主线程中执行,否则会触发NetworkOnMainThreadException
异常。同步请求必须在后台线程中执行,可以使用Thread
、ExecutorService
或 RxJava 等工具管理线程。 -
资源释放
Response
对象实现了Closeable
接口,使用try-with-resources
语法确保资源释放。 -
超时设置
默认超时为 10 秒,可通过OkHttpClient.Builder
自定义:
OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://example.com").build();
try (Response response = client.newCall(request).execute()) {if (response.isSuccessful()) {System.out.println("Response: " + response.body().string());} else {System.err.println("Request failed: " + response.code());}
} catch (IOException e) {System.err.println("Request error: " + e.getMessage());
}
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {try (Response response = client.newCall(request).execute()) {if (response.isSuccessful()) {System.out.println
特性 | 同步请求(execute ) | 异步请求(enqueue ) |
---|---|---|
线程阻塞 | 阻塞当前线程,直到请求完成 | 不阻塞线程,后台执行 |
结果获取 | 直接返回 Response 对象 | 通过 Callback 回调处理结果 |
线程管理 | 需手动管理线程,避免主线程阻塞 | 自动在后台线程执行,主线程无影响 |
适用场景 | 需立即获取结果的场景(如单元测试) | 需异步处理的场景(如网络请求) |
二、okHttp+Rxjava
Observable<Response> observable = Observable.create(emitter -> {Call call = client.newCall(request);call.enqueue(new Callback() {@Overridepublic void onResponse(Call call, Response response) {if (!emitter.isDisposed()) {emitter.onNext(response);emitter.onComplete();}}@Overridepublic void onFailure(Call call, IOException e) {if (!emitter.isDisposed()) {emitter.onError(e);}}});emitter.setCancellable(call::cancel);
});observable.subscribeOn(Schedulers.io()) // 在 IO 线程执行.observeOn(AndroidSchedulers.mainThread()) // 在主线程处理结果.subscribe(new Observer<Response>() {@Overridepublic void onSubscribe(Disposable d) {// 订阅时调用}@Overridepublic void onNext(Response response) {System.out.println("Response: " + response.body().string());}@Overridepublic void onError(Throwable e) {System.err.println("Error: " + e.getMessage());}@Overridepublic void onComplete() {// 请求完成时调用}});
二、Retrofit 的同步与异步用法,用Call发起请求
Retrofit 内部使用 OkHttp 作为 HTTP 客户端,这意味着在 Retrofit 的配置中,你可以定制 OkHttp 的各种参数(如超时设置、拦截器等)。
为了更好地支持异步编程,Retrofit 提供了 RxJava 的 CallAdapter。通过这个适配器,你可以让 API 接口直接返回 Observable、Single 等 RxJava 类型,从而使用 RxJava 的强大操作符来处理请求结果和错误。
public interface ApiService {@GET("users")Call<List<User>> getUsers();
}
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.example.com/").addConverterFactory(GsonConverterFactory.create()) // 使用 Gson 进行 JSON 转换.build();ApiService apiService = retrofit.create(ApiService.class);
Retrofit同步请求
需在子线程中调用,否则会触发 NetworkOnMainThreadException
new Thread(new Runnable() {@Overridepublic void run() {try {Call<List<User>> call = apiService.getUsers();Response<List<User>> response = call.execute();if (response.isSuccessful() && response.body() != null) {List<User> users = response.body();// 处理返回的数据} else {Log.e("Retrofit", "Response error: " + response.code());}} catch (IOException e) {e.printStackTrace();}}
}).start();
Retrofit异步请求
Call<List<User>> call = apiService.getUsers();
call.enqueue(new Callback<List<User>>() {@Overridepublic void onResponse(Call<List<User>> call, Response<List<User>> response) {if (response.isSuccessful() && response.body() != null) {List<User> users = response.body();// 处理返回的数据,比如更新 UI} else {// 请求成功,但是服务器返回错误码,比如 404、500 等Log.e("Retrofit", "Response error: " + response.code());}}@Overridepublic void onFailure(Call<List<User>> call, Throwable t) {// 请求失败,比如网络错误或解析错误Log.e("Retrofit", "Request failed", t);}
});
三、Retrofit + RxJava 的同步/异步与线程统一处理,用Observable发起请求
Observable 是 RxJava 的响应式编程模型,用于处理异步数据流。其优势包括:
- 链式调用:通过操作符(如
map
、flatMap
)简化复杂逻辑。 - 线程调度:通过
subscribeOn
和observeOn
控制线程切换。 - 错误处理:通过
onErrorReturn
或retry
实现容错。
同步请求
public interface ApiService {@GET("users/{id}")Observable<User> getUserRx(@Path("id") int id); // 返回 Observable
}apiService.getUserRx(1).subscribeOn(Schedulers.io()) // 指定请求线程.observeOn(Schedulers.io()) // 指定响应处理线程.blockingSubscribe(user -> {// 同步阻塞获取结果});
异步请求
// 1. 定义 API 接口,使用 RxJava 的 Observable 作为返回类型
public interface ApiService {@GET("users")Observable<List<User>> getUsers();
}// 2. 配置 OkHttp 客户端(可添加拦截器、日志打印等)
OkHttpClient okHttpClient = new OkHttpClient.Builder()// 例如:添加日志拦截器// .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).build();// 3. 配置 Retrofit,同时添加 Gson 转换器和 RxJava 适配器
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.example.com/").client(okHttpClient).addConverterFactory(GsonConverterFactory.create()) // JSON 数据解析.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // RxJava 适配器.build();// 4. 创建 API 服务实例
ApiService apiService = retrofit.create(ApiService.class);// 5. 使用 RxJava 进行网络请求
apiService.getUsers().subscribeOn(Schedulers.io()) // 在 IO 线程执行网络请求.observeOn(AndroidSchedulers.mainThread()) // 在主线程处理返回结果.subscribe(users -> {// 成功回调,处理用户数据}, throwable -> {// 错误回调,处理异常情况});
方案 | 线程管理 | 代码复杂度 | 适用场景 |
---|---|---|---|
OkHttp 原生 | 手动切换 | 低 | 简单请求、低耦合场景 |
Retrofit 原生 | 手动切换 | 中 | 接口化请求、中等复杂度 |
Retrofit+RxJava | 自动统一管理 | 高 | 复杂异步流、高可维护性 |
四、具体使用Retrofit+RxJava
// 1. 定义服务接口
public interface UserService {@POST("/user/{userId}/profile")Observable<BaseResponse<UserProfile>> updateProfile(@Path("userId") String userId,@Body ProfileParams params);
}// 2. 发起请求
NetworkApi.createService(UserService.class, ServiceType.User.name()).updateProfile("123", new ProfileParams("Kimi", "avatar.jpg")).compose(NetworkApi.applySchedulers()).subscribe(new BaseObserver<UserProfile>() {@Overridepublic void onSuccess(UserProfile profile) {// 更新UI}@Overridepublic void onBusinessError(int code, String msg) {// 显示错误提示}});
设计优势:
- 责任链模式:每个方法专注单一职责(创建→配置→调度→响应)
- 类型安全:通过泛型确保数据模型一致性
- 异常隔离:BaseObserver集中处理网络/业务异常
- 线程透明:applySchedulers()隐藏线程切换细节
该模式常见于需要支持多环境、多服务类型的现代移动应用架构,特别适合企业级应用开发中需要统一管理API请求的场景。
这是典型的Retrofit+RxJava组合的网络请求链式调用写法,结合了工厂模式、建造者模式和响应式编程思想。其核心结构可分为四个关键部分:
1.服务实例创建
NetworkApi.createService(ApiService.class, ServiceType.License.name())
NetworkApi
是自定义的工厂类,封装了Retrofit实例的创建过程createService()
方法通过动态代理生成ApiService接口的实现类ServiceType.License.name()
指定服务类型,通常用于动态配置baseUrl(如区分认证服务、业务服务等)
2.具体API操作
.action(id, params)
action()
对应ApiService接口中定义的端点方法:
@POST("/api/{serviceType}/actions")
Observable<BaseResponse<T>> action(@Path("serviceType") String serviceType,@Body ActionParams params
);
id
参数可能用于路径替换(@Path注解),params
作为请求体(@Body注解)
3.线程调度组合
.compose(NetworkApi.applySchedulers(...))
compose()
是RxJava的操作符,统一应用线程切换规则applySchedulers()
典型实现:
4.观察者封装
new BaseObserver<BaseResponse<AccessConsentRecordDetailBean>>()
- 自定义的BaseObserver处理通用逻辑:
public abstract class BaseObserver<T> implements Observer<T> {@Overridepublic void onError(Throwable e) {// 统一错误处理(网络异常、业务异常等)}@Overridepublic void onNext(T response) {if (response.isSuccess()) {onSuccess(response.getData());} else {onBusinessError(response.getCode(), response.getMessage());}}
}
五、Flowable与Observable
Flowable与Observable是RxJava中两种核心的响应式数据流类型,结合Retrofit使用时需要根据具体场景进行选型。以下是两者的核心区别及在Retrofit中的实践建议:
类型 | 特性 | Retrofit集成场景 |
---|---|---|
Observable | 无背压机制的异步数据流,支持同步/异步操作,适合轻量级请求 | 简单API调用(如获取用户信息、配置数据) |
Flowable | 支持背压控制的响应式流,内置5种策略处理生产消费速度差异 | 大文件传输、实时数据推送等高并发场景 |
核心区别
1. 背压处理机制
- Flowable
通过BackpressureStrategy
配置策略(ERROR/BUFFER/DROP/LATEST/MISSING),在Retrofit中处理大数据流时需显式指定策略:
@GET("api/sensor-data")
Flowable<Data> getSensorData(@Query("deviceId") String id); // 默认使用ERROR策略[5](@ref)
- Observable
无背压控制,Retrofit接口直接返回Observable时需确保数据量可控,否则可能引发OOM
2. 线程模型
Flowable
强制异步订阅,Retrofit需配合subscribeOn(Schedulers.io())
使用:
api.getSensorData("DEV001").subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
Observable
支持同步调用,适合快速响应的本地缓存查询:
@GET("api/profile")
Observable<User> getUserProfile(); // 同步获取用户数据[9](@ref)
3. 性能表现
- Flowable
因背压检测机制,吞吐量比Observable低约15-30%,但内存更安全 - Observable
无额外性能损耗,适合高频低数据量请求(如按钮点击事件统计)
4.集成实现
- BUFFER:文件下载(需注意内存监控)
Flowable.create(emitter -> {...}, BackpressureStrategy.BUFFER)
- DROP:实时股票行情推送(丢弃过时数据)
- LATEST:即时聊天消息(保留最新消息)
5.错误处理对比
- Observable需手动捕获异常:
.subscribe(data -> {...},error -> { // 需处理所有异常 }
)
- Flowable通过
onBackpressureXXX
操作符自动处理:
.onBackpressureDrop(dropped -> log("丢弃数据:" + dropped))
性能优化建议
-
混合使用策略
对核心业务接口使用Flowable+BUFFER策略,非核心功能使用Observable -
动态缓存控制
通过rx2.buffer-size
参数调整Flowable缓存池:System.setProperty("rx2.buffer-size", "256"); // 默认128[7](@ref)
-
生命周期管理
使用CompositeDisposable
统一释放资源:CompositeDisposable disposables = new CompositeDisposable();disposables.add(api.getDataStream().subscribe(data -> {...}));
通过合理选择Flowable与Observable,可使Retrofit网络层在保证稳定性的同时获得最佳性能。可以在金融交易、物联网等高频场景优先采用Flowable,而在常规业务API中使用Observable以降低复杂度。
相关文章:
OkHttp、Retrofit、RxJava:一文讲清楚
一、okHttp的同步和异步请求 Call 是 OkHttp 的核心接口,代表一个已准备好执行的 HTTP 请求。它支持 同步 和 异步 两种模式: enqueue——>okHttp异步 OkHttpClient client new OkHttpClient();Request request new Request.Builder().url("…...
AI前端加速科学研究:ScriptEcho赋能科研新纪元
科学研究正面临前所未有的挑战。数据以前所未有的速度爆炸式增长,研究课题也变得日益复杂。如何高效地处理海量数据、构建复杂模型、并将其转化为有意义的结论,成为摆在科研人员面前的一道难题。传统的科研模式往往需要耗费大量的时间和精力在数据处理、…...
从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?
本文首发:从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)? 阿里云百炼和火山引擎都推出了免费的 DeepSeek 模型体验额度,今天我和大家一起搭建一个本地的专属 AI 助手。 阿里云百炼为 …...
ChatGPT背后的理论基础:从预训练到微调的深度解析
友情提示:本文内容由银河易创(https://ai.eaigx.com)AI创作平台GPT-4o-mini模型生成,仅供参考。请根据具体情况和需求进行适当的调整和验证。 随着人工智能特别是自然语言处理技术的飞速发展,ChatGPT作为一种强大的对话…...
Java八股文(下)
Java八股文下篇 八、JVM高级篇1、JVM的内存模型以及分区介绍一下?2、四种引用方式有什么?3、判断是否为垃圾算法?4、垃圾回收算法介绍一下?5、类的生命周期以及类加载过程6、加载器种类有什么?7、什么是双亲委派模型以…...
软考高级【网络规划设计师】 综合知识
引言:软考高级【网络规划设计师】共分为3个部分,综合知识,案例分析,论文。这里主要讲诉综合知识的相关内容。综合知识一共75道单选,题目跟网工类似,稍难。 第1章 计算机网络基础 考点分析: 本…...
django框架使用
一、app注册: pycharm使用django框架,注意在注册界面时就创建app,如果没有创建app。就在终端中运行 python manage.py startapp [app名] 然后再在settings.py里注册。 格式为: [app名].apps.[首字母大写的app名]Config 二、创…...
Linux主机用户登陆安全配置
Linux主机用户登陆安全配置 在Linux主机上进行用户登录安全配置是一个重要的安全措施,可以防止未经授权的访问。以下是如何创建用户hbu、赋予其sudo权限,以及禁止root用户SSH登录,以及通过ssh key管理主机用户登陆。 创建用户hbu 使用具有…...
MySQL | MySQL库、表的基本操作
MySQL库、表的基本操作01 一、库操作1.1 查看数据库1.2 创建数据库1.3 选择数据库1.4 查看创建数据库的SQL语句1.5 修改数据库1.6 删除数据库 二、表操作2.1 创建数据表2.2 查看表2.3 查看表结构2.4 查看创建数据库的SQL语句2.5 修改表2.6 删除表 ⚠️MySQL版本 8.0 一、库操作…...
【Uniapp-Vue3】在uniapp中使用pinia的基本用法
引入pinia: 在main.js中对pinia进行引入,使用和导出 import * as Pinia from pinia; // 引入pinia app.use(Pinia.createPinia()); // 使用pinia 在项目根目录下创建一个stores文件夹,里面创建一个counter.js文件 我们在counter.js中定义…...
mysql中的计算日期函数 理解、用法
三种计算日期的函数 函数用途示例DATEDIFF()计算两个日期的天数差DATEDIFF(2023-10-05, 2023-10-01) → 4TIMESTAMPDIFF()按指定单位(年、月、小时等)计算差TIMESTAMPDIFF(MONTH, 2023-01-01, 2023-03-01) → 2DATE_ADD()日期加法DATE_ADD(2023-10-01, …...
HTTP实验(ENSP模拟器实现)
目录 HTTP概述 HTTP实验 HTTPS 实验 HTTP概述 HTTP(HyperText Transfer Protocol,超文本传输协议),设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。 HTTP定义了多种请求方法,常用的包括: …...
Ubuntu指令(一)
一、终端操作指令 打开终端,有两种便捷方式: 直接点击系统中的终端按钮;使用快捷键ctrl alt T。 关闭终端,同样有多种选择: 在终端输入exit指令;使用快捷键ctrl d;直接点击终端窗口的关闭…...
结构型模式 - 装饰者模式 (Decorator Pattern)
结构型模式 - 装饰者模式 (Decorator Pattern) 在展开讲装饰者模式之前,不得不提一下代理模式,因为这两者在一定的层度上是有相似性的, 通过对比可以让我们更好的理解装饰者. 定义与核心目的 装饰者模式 定义:动态地将责任附加到对象上。若要扩展功能,…...
11.Docker 之分布式仓库 Harbor
Docker 之分布式仓库 Harbor Docker 之分布式仓库 Harbor1. Harbor 组成2. 安装 Harbor Docker 之分布式仓库 Harbor Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器,由 VMware 开源,其通过添加一些企业必需的功能特性,例…...
vue2使用xlsx依赖导出excel并封装组件
1. 安装 npm install xlsx file-saver --save2. 简单封装 import * as XLSX from xlsx; import { saveAs } from file-saver;export function exportExcel(data, fileName) {return new Promise((resolve, reject) > {if (!data || !data.length) {return reject(new Erro…...
Python入门12:面向对象的三大特征与高级特性详解
面向对象编程(OOP)是Python编程中非常重要的一部分,它通过封装、继承和多态这三大特征,帮助我们更好地组织和管理代码。除此之外,Python还提供了一些其他特性,如类属性、类方法和静态方法,进一步…...
JVM之JVM的组成
Java 虚拟机(JVM)是 Java 程序的运行核心,它主要由类加载系统、运行时数据区、执行引擎和本地方法接口这几个关键部分组成。 类加载系统(Class Loading System) 类加载系统负责在程序运行时动态地将 Java 类加载到 J…...
计算机毕业设计SpringBoot+Vue.js中小型医院网站(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
滑动验证组件-微信小程序
微信小程序-滑动验证组件,直接引用就可以了,效果如下: 组件参数: 1.enable-close:是否允许关闭,默认true 2.bind:onsuccess:验证后回调方法 引用方式: <verification wx:if&qu…...
【DeepSeek问答】QProcess::start是异步的吗?会使UI卡顿吗?
好的,我现在需要回答用户关于QProcess::start是否是异步的,以及它是否会导致UI卡顿的问题。用户之前已经询问过如何开发一个调用7-Zip的Qt应用,并且我给出了示例代码。现在用户可能在使用过程中遇到了问题,或者想更深入了解QProce…...
WebXR教学 01 基础介绍
什么是WebXR? 定义 XR VR AR Web上使用XR技术的API WebXR 是一组用于在 Web 浏览器中实现虚拟现实(VR)和增强现实(AR)应用的技术标准。它由 W3C 的 Immersive Web 工作组开发,旨在提供跨设备的沉浸式体验…...
数据开发面试:DQL,
DQL常见面试题 where 和 having 的区别 三个排序开窗函数的区别 left join 用where 筛选 和 用on筛选的区别 ON 子句:用于定义连接条件,不会丢失左表的行。 WHERE 子句:用于过滤连接后的结果集,可能会丢失左表中没有匹配的行 …...
sage-huga改进SITAN
Sage-Husa自适应滤波算法 Sage-Husa自适应滤波算法是一种在递推滤波过程中实时估计和修正系统噪声和观测噪声统计特性的算法,从而降低系统模型误差,提高滤波精度。该算法基于卡尔曼滤波,并通过自适应调整噪声协方差矩阵来优化滤波效果。 算法原理 Sage-Husa滤波器的核心思…...
深入解析React useEffect与useLayoutEffect:区别、原理与实践
🌌 深入解析React useEffect与useLayoutEffect:区别、原理与实践 在React函数组件中,useEffect和useLayoutEffect是处理副作用的两个核心Hook。它们看似相似,但在执行时机和应用场景上有本质区别。本文将通过原理剖析、对…...
1分钟用DeepSeek编写一个PDF转Word软件
一、引言 如今,在线工具的普及让PDF转Word成为了一个常见需求,常见的pdf转word工具有收费的wps,免费的有pdfgear,见下文: PDFgear:一款免费的PDF编辑、格式转化软件-CSDN博客 还有网上在线的免费pdf转word工具smallp…...
百度觉醒,李彦宏渴望光荣
文 | 大力财经 作者 | 魏力 2025年刚刚开年,被一家名为DeepSeek的初创公司强势改写。在量化交易出身的创始人梁文锋的带领下,这支团队以不到ChatGPT 6%的训练成本,成功推出了性能可与OpenAI媲美的开源大模型。 此成果一经问世,…...
MySQL知识
1.Navicat客户端连接 打开navicat,点击连接,点击MySQL 输入连接名与密码,如果连接的mysql是windows下的mysql主机号就填写localhost 填写好后点击测试连接 点击确定,mysql连接navicat成功 2.MySQL数据定义语言(DDL) DDL用于数据库…...
从零开始用react + tailwindcs + express + mongodb实现一个聊天程序(三) 实现注册 登录接口
1.划分文件夹 在src目录下创建controllers middleware models routes controllers 放具体的方法 signup login middleware 里面是中间件 请求的验证 models 放对象实体 routes 处理访问路径像/signup /login 等等 2. 接口开发 系统的主要 有用户认证 和 消息 2种类型…...
Pytorch实现之浑浊水下图像增强
简介 简介:这也是一篇非常适合GAN小白们上手的架构文章!提出了一种基于GAN的水下图像增强网络。这种网络与其他架构类似,生成器是卷积+激活函数+归一化+残差结构的组成,鉴别器是卷积+激活函数+归一化以及全连接层。损失函数是常用的均方误差、感知损失和对抗损失三部分。 …...
代码异常(js中forEach)NO.3
1. 环境 Vue3,Element Plsu 2. 示例代码 dataList.value.forEach((x) > {if (x.id ids.value[0]) {x { id: ids.value[0], ...form.value }}})3. 情景描述 循环不能正确改变dataList.value里面的值 4. 原因 在 JavaScript 中,forEach 的回调函…...
Vue 报错error:0308010C:digital envelope routines::unsupported 解决方案
Vue 报错error:0308010C:digital envelope routines::unsupported 解决方案 拿了一个比较老的项目部署在本地,然后先安装依赖npm install,最后npm run serve,在run serve的时候报错:报错error:0308010C:digital envelope routines::unsupportedÿ…...
stm32108键C-B全调性_动态可视化乐谱钢琴
108键全调性钢琴 一 基本介绍1 项目简介2 实现方式3 项目构成 二 实现过程0 前置基本外设驱动1 声音控制2 乐谱录入&基础乐理3 点阵屏谱点动态刷新4 项目交互控制5 录入新曲子过程 三 展示,与链接视频地址1 主要功能函数一览2 下载链接3 视频效果 一 基本介绍 …...
OpenIPC开源FPV之Adaptive-Link安装
OpenIPC开源FPV之Adaptive-Link安装 1. 源由2. 介绍2.1 天空端安装2.2 地面端安装 3. 问题汇总3.1 安装脚本问题3.2 网络安装问题3.3 非SSC30KQ/SSC338Q硬件3.4 代码疑问 4. 总结5. 后续 1. 源由 鉴于飞行过程,发现一些马赛克现象,且60FPS桌面30FPS的录…...
2016年下半年试题二:论软件设计模式及其应用
论文库链接:系统架构设计师论文 论文题目 软件设计模式(Software DesignPatter)是一套被反复使用的、多数人知晓的、经过分类编目的代码设计经验的总结。使用设计模式是为了重用代码以提高编码效率增加代码的可理解性、保证代码的可靠性。软件设计模式是软件开发中的…...
UE(虚幻)学习(五)初学创建NPC移动和遇到的问题
最近在学习UE中遇到一些问题,把这些问题记录一下,因为实在废了很大功夫。 在学习了UE5的例子中的第三人称移动Demo,想实现几个NPC在场景内移动。 本来想自己写一个类,遇到一堆问题花费了好几天时间,所以我把问题写下来…...
《Keras 2 :使用 RetinaNet 进行对象检测》:此文为AI自动翻译
《Keras 2 :使用 RetinaNet 进行对象检测》 作者:Srihari Humbarwadi 创建日期:2020/05/17 最后修改日期:2023/07/10 描述:实施 RetinaNet:用于密集对象检测的焦点损失。 (i) 此示例使用 Keras 2 在 Colab 中查看 • 介绍 目标检测是计算机中非常重要的问题 视觉。在…...
mfy学习笔记
创建表并导入数据 CREATE TABLE sales (id INT,salesperson STRING,region STRING,sales_amount INT,sale_date DATE );INSERT INTO sales (id, salesperson, region, sales_amount, sale_date) VALUES (1, Alice, North, 1000, 2023-01-01), (2, Bob, South, 1500, 2023-01-0…...
mysql 学习19 MYSQL管理以及使用工具
系统数据库 常用工具 mysql [rootCentOS7 home]# mysql -h192.168.245.131 -P3306 -uroot -pmimaroot -e "select * from tb_sanguo_user;" centositcast [rootCentOS7 home]# mysql -h192.168.245.131 -P3306 -uroot -pmimaroot centositcast -e "select * fr…...
Linux | RHEL / CentOS 中 YUM history / downgrade 命令回滚操作
注:英文引文,机翻未校。 在 RHEL/CentOS 系统上使用 YUM history 命令回滚升级操作 作者: 2daygeek 译者: LCTT DarkSun 为服务器打补丁是 Linux 系统管理员的一项重要任务,为的是让系统更加稳定,性能更加…...
JavaScript基础(函数及面向对象)
函数 定义函数 Java定义方法: public 返回值类型 方法名(){ return 返回值 } 定义函数方法一 eg:定义一个绝对值函数 function abs(x) {if (x>0){return x;}else {return -x;}} 调用函数: 注意:一旦执行到return代表函数…...
Open WebUI中的Pipelines是什么
Open WebUI中的Pipelines是什么 Open WebUI中的Pipelines(管道或流水线)是一种允许开发者定制使用大模型流程的机制,能为OpenAI兼容的UI客户端带来模块化、定制化的工作流。以下是一些Pipelines实例及使用方法: 函数调用管道(Function Calling Pipeline) 实例:假设要让…...
伪404兼容huawei生效显示404
根据上述思考,以下是详细的中文分步说明: --- **步骤 1:获取目标设备的User-Agent信息** 首先,我们需要收集目标设备的User-Agent字符串,包括: 1. **iPhone设备的User-Agent**: Mozi…...
Linux 病毒扫描工具 ClamAV 使用
Linux 病毒扫描工具 ClamAV 使用 功能安装包管理器安装手动安装RPM/DEB包配置用户与目录更新病毒库 基本使用命令扫描文件/目录常用参数 高级配置实时监控(clamd服务)定时自动扫描 常见问题解决病毒库更新失败权限错误扫描速度慢 功能 官网:h…...
Mobaxterm服务器常用命令(持续更新)
切换文件夹 cd path # for example, cd /gpu03/deeplearning/进入不同GPU ssh mgmt ssh gpu01 ssh gpu03寻找文件位置 find /path -name file_name #for example, find / -name lib #在根目录下搜寻名为lib文件 #for example, find /home/deeplearning -name "lib"…...
[特殊字符]《封印adb的黑暗通道:让系统文件成为魔法禁书区的终极指南》[特殊字符]
第一章:当adb变成泄密特洛伊木马 "曾经,adb是程序员的阿拉丁神灯,如今却成了产品经理的噩梦!" —— 某秃头CTO的血泪控诉 某日,产品经理惊恐发现:自家黑科技APP竟被竞争对手用adb pull轻松窃取…...
LangChain教程 - RAG - 支持的100种向量数据库
系列文章索引 LangChain教程 - 系列文章 随着人工智能和机器学习应用的快速发展,尤其是在自然语言处理(NLP)、图像识别、推荐系统等领域,对高效的向量存储和检索需求日益增长。向量存储用于保存来自深度学习模型或其他机器学习算…...
如何使用tushare pro获取股票数据——附爬虫代码以及tushare积分获取方式
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据 总结 一、Tushare 介绍 Tushare 是一个提供中国股市数据的API接口服务,它允许用户…...
ESP32S3:解决RWDT无法触发中断问题,二次开发者怎么才能使用内部RTC看门狗中断RWDT呢?
目录 基于ESP32S3:解决RWDT无法触发中断问题引言解决方案1. 查看报错日志2. 分析报错及一步一步找到解决方法3.小结我的源码基于ESP32S3:解决RWDT无法触发中断问题 引言 在嵌入式系统中,RWDT(看门狗定时器)是确保系统稳定性的重要组件。然而,在某些情况下,RWDT可能无法…...
如何在视频中提取关键帧?
在视频处理中,提取关键帧是一项常见的任务。下面将介绍如何基于FFmpeg和Python,结合OpenCV库来实现从视频中提取关键帧的功能。 实现思路 使用FFmpeg获取视频的关键帧时间戳:FFmpeg是一个强大的视频处理工具,可以通过命令行获取…...