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

Flutter中的Future和Stream

在 Flutter 中,FutureStream 都是用于处理异步操作的类,它们都基于 Dart 的异步编程模型,但是它们的使用场景和工作方式有所不同。以下是它们的区别以及各自适用的场景。

目录

    • 一、Future
      • 1、基本使用
      • 2、异常处理
        • 1. catchError
        • 2. onError
        • 3、`catchError` 和 `onError` 的区别
        • 4. 捕获多个错误
        • 5. 错误的传播
      • 总结
    • 二、Stream
      • 1、基本使用
      • 2、异常处理
        • 1. `onError` 处理器
        • 2. `try-catch` 语句
        • 3. 异常后流的状态
        • 4. 流的中断
        • 5. 恢复流
        • 6. 流异常的示例
      • 总结
    • 三、 结合使用 `Future` 和 `Stream`
    • 四、总结
      • 1、区别
      • 2、选择 `Future` 还是 `Stream`
    • 四、疑问
      • 1、Stream 流是按照顺序执行的吗?
        • 1. 顺序性
        • 2. 顺序的保证
      • 2、Stream async* 和 yield 的解释这三个必须要配套使用吗?,不适用 yield 行吗?
        • 1. `Stream` 与 `async*`
        • 2. `async*` 和 `yield` 必须配合使用吗?
        • 3. 不使用 `yield` 行不行?
        • 4. 如何使用 `async*` 生成异步数据流?
        • 总结

一、Future

1、基本使用

Future 是一个表示一个可能还未完成的异步操作的对象。它表示一个将来某个时间点会返回一个结果或错误的计算。

  • 特点
    • Future 代表的是一个 单次 异步操作。
    • 只能返回一次结果或错误,不会再有后续的值。
    • 在调用时,它会返回一个 Future 对象,可以通过 thenawait 等方法获取结果。
    • 如果操作失败,可以通过 catchErroronError 进行错误处理。
  • 使用场景
    • 当你需要等待一个单一的异步结果时,使用 Future
    • 比如从网络获取数据,执行一个数据库查询,或读取一个文件等一次性的操作。
  • 示例代码
// 使用 Future 的示例
Future<String> fetchData() async {// 模拟异步操作await Future.delayed(Duration(seconds: 2));return "Data fetched successfully!";
}void main() async {try {String data = await fetchData();print(data); // 输出 "Data fetched successfully!"} catch (e) {print("Error: $e");}
}

在上面的示例中,fetchData 返回一个 Future<String>,它表示一个将来完成的异步操作。使用 await 来等待这个操作完成并获得结果。

2、异常处理

1. catchError

catchError 是用于捕获和处理 Future 发生错误的一种方式。当 Future 执行失败时,它会触发传给 catchError 的回调函数。这个回调函数可以接受错误和栈跟踪信息。

示例:

Future<int> divide(int a, int b) {return Future.delayed(Duration(seconds: 1), () {if (b == 0) {throw Exception('Cannot divide by zero!');}return a ~/ b;});
}void main() {divide(10, 0).catchError((e) {print('Error: $e');});// Output: Error: Exception: Cannot divide by zero!
}

在这个例子中,当 b 为 0 时,Future 会抛出一个 Exception,并且 catchError 捕获并打印这个错误。

catchError 的用法细节:

  • 返回值的传递catchError 会继续执行 Future 链中的后续操作,因此如果你想在错误发生时返回一个默认值,可以在 catchError 中指定。
Future<int> divide(int a, int b) {return Future.delayed(Duration(seconds: 1), () {if (b == 0) {throw Exception('Cannot divide by zero!');}return a ~/ b;}).catchError((e) {print('Handled error: $e');return -1;  // 返回默认值});
}void main() async {var result = await divide(10, 0);print('Result: $result');  // 输出: Handled error: Exception: Cannot divide by zero!//         Result: -1
}
2. onError

onErrorFuture 的另一种错误处理方式。它与 catchError 类似,但它是 Future 构造函数的一部分,通常用于直接在 Future 构造时附加错误处理。

示例:

Future<int> divide(int a, int b) {return Future.delayed(Duration(seconds: 1), () {if (b == 0) {throw Exception('Cannot divide by zero!');}return a ~/ b;}).onError((error, stackTrace) {print('Caught an error: $error');return -1;  // 返回默认值});
}void main() async {var result = await divide(10, 0);print('Result: $result');  // 输出: Caught an error: Exception: Cannot divide by zero!//         Result: -1
}
3、catchErroronError 的区别
  • catchError 是用于捕获在 Future 执行时抛出的异常,它通常用于链式调用中捕获错误。
  • onErrorFuture 的一种附加错误处理机制,它将错误处理直接嵌入到 Future 构造中。

尽管 catchErroronError 都可以捕获错误并返回一个默认值或执行某些操作,但 catchError 更灵活,通常在复杂的异步链式操作中使用。

4. 捕获多个错误

如果你需要捕获多个错误,可以将 catchErroronError 绑定到多个 Future 链条上。这样可以对不同类型的错误进行不同的处理。

示例:

Future<void> asyncFunction() {return Future.delayed(Duration(seconds: 1), () {throw Exception('Something went wrong!');});
}void main() {asyncFunction().catchError((e) {print('Caught error: $e');}).catchError((e) {print('Another handler for errors: $e');});// Output: Caught error: Exception: Something went wrong!
}
5. 错误的传播

如果在 Future 中没有处理错误,错误将会被传播,直到被外部捕获或程序崩溃。因此,适当的错误处理不仅可以帮助捕获问题,还可以避免未捕获的异常导致程序崩溃。

总结

在 Dart 中,catchErroronError 都可以用于处理异步操作中的错误。它们的主要区别在于用法和灵活性,选择哪一个取决于你的代码结构和需求。

二、Stream

1、基本使用

Stream 是一个表示一系列异步事件的对象,它允许你在未来的时间点接收多个值。

  • 特点
    • Stream 代表的是 多个异步事件
    • 它会按顺序提供一系列的结果(可以是零个或多个),通常用于处理实时数据流。
    • 可以是单向的,也可以是广播流(多个监听者可以订阅)。
    • 你可以通过 listen 方法来监听事件流。
    • Stream 还支持 await for 语法,可以等待并处理每个事件。
  • 使用场景
    • 当你需要处理一个 数据流多个值 时,使用 Stream
    • 比如处理实时数据(如 WebSocket 数据流、用户输入事件流、文件变化等)。
  • 示例代码
// 使用 Stream 的示例
Stream<int> generateNumbers() async* {for (int i = 0; i < 5; i++) {await Future.delayed(Duration(seconds: 1));yield i; // 每秒产生一个数字}
}void main() async {await for (var number in generateNumbers()) {print(number); // 输出:0, 1, 2, 3, 4}
}

在这个示例中,generateNumbers 返回一个 Stream<int>,它每秒返回一个整数。通过 await for 循环,我们可以逐个接收流中的数据。

2、异常处理

当流中发生异常时,有几种方式来处理这些异常,使得流能够继续工作或适当地终止。

1. onError 处理器

如果你使用 Stream.listen 方法来监听流,可以通过传入 onError 回调来处理流中的异常。当流抛出异常时,onError 处理器会被触发。

Stream<int> generateNumbersWithError() async* {yield 1;yield 2;throw Exception('Something went wrong');yield 3;  // 这一行永远不会执行
}void main() {generateNumbersWithError().listen((data) {print('Received: $data');},onError: (error) {print('Caught error: $error');},onDone: () {print('Stream is done');},);
}

输出:

Received: 1
Received: 2
Caught error: Exception: Something went wrong
Stream is done

在这个例子中,当 Stream 中的 Exception 被抛出时,onError 回调会捕获并打印出错误信息。yield 3 后的代码不会执行,因为流在抛出异常后被中断。

2. try-catch 语句

在异步生成器(如 async*)中,你可以使用 try-catch 来捕获异常,这可以防止异常导致流中断。

Stream<int> generateNumbersWithErrorHandled() async* {try {yield 1;yield 2;throw Exception('Something went wrong');yield 3;  // 这一行不会执行} catch (e) {print('Caught error: $e');}
}void main() async {await for (var data in generateNumbersWithErrorHandled()) {print('Received: $data');}
}

输出:

Received: 1
Received: 2
Caught error: Exception: Something went wrong

在这个例子中,即使抛出异常,Stream 仍然能够继续执行,只是异常会被捕获并处理。

3. 异常后流的状态

Stream 抛出异常后,流会进入错误状态,并且不再发出任何数据,除非你有合适的机制来恢复流。

  • 如果流中的 onError 回调没有捕获异常,流会直接终止。
  • 如果你在 Stream 中使用 try-catch 捕获了异常,流可以继续正常工作,继续发送后续的数据。
4. 流的中断

流的中断意味着流不再继续发出事件。中断的原因通常有以下几种:

  • 异常抛出:如果流中的某个操作抛出了异常,流会被中断,后续的事件不会再触发。
  • 用户主动取消订阅:如果你使用 StreamSubscription 来订阅流,并主动调用 cancel(),流也会中断。
  • 流结束:如果流完成(即没有更多的事件要发出),流会进入完成状态。
5. 恢复流

如果你希望在流发生异常后恢复流的工作,可以通过重新订阅流或使用一些复合的错误处理机制。

例如,在监听流时使用 onError 捕获错误并在错误发生时重新启动流:

Stream<int> generateNumbersWithError() async* {yield 1;yield 2;throw Exception('Something went wrong');yield 3;
}void main() {Stream<int> stream = generateNumbersWithError();stream.listen((data) {print('Received: $data');},onError: (error) {print('Caught error: $error');// 重新启动流stream.listen((data) => print('Retry received: $data'),onError: (e) => print('Retry error: $e'),onDone: () => print('Retry stream is done'),);},onDone: () => print('Stream is done'),);
}

在这种情况下,流会在错误发生时重新启动。这允许你捕获错误并尝试恢复流的执行。

6. 流异常的示例

假设有一个 Stream 生成器,它在生成某个事件时发生异常:

Stream<int> generateNumbersWithError() async* {yield 1;yield 2;throw Exception('Unexpected error');yield 3;  // 这行永远不会执行
}void main() async {try {await for (var number in generateNumbersWithError()) {print('Received: $number');}} catch (e) {print('Caught error: $e');}
}

输出:

Received: 1
Received: 2
Caught error: Exception: Unexpected error

在这个例子中,异常会导致流中断,后续的事件不会被处理,且异常被捕获。

总结

  • 流中断:当流遇到异常时,流会进入错误状态并停止发出事件。
  • 异常处理:你可以通过 onError 回调或 try-catch 语句捕获和处理异常。
  • 恢复流:在流发生异常时,可以选择恢复流的工作,例如通过重新订阅流。

三、 结合使用 FutureStream

在某些情况下,FutureStream 可以结合使用。例如,如果你有一个 Future 返回一个数据集,而这个数据集可以被逐步处理,那么你可以将 Future 的结果转换成一个 Stream 来进行逐项处理。

Future<List<int>> fetchData() async {return [1, 2, 3, 4, 5];
}Stream<int> fetchDataAsStream() async* {List<int> data = await fetchData();for (var item in data) {yield item;}
}void main() async {await for (var number in fetchDataAsStream()) {print(number); // 输出 1, 2, 3, 4, 5}
}

在这个例子中,fetchData 是一个 Future,而 fetchDataAsStream 将其转换成了一个 Stream,使得我们能够以流的形式逐项处理数据。

总结

  • Future 适合用于处理 单次 的异步操作,返回一个值或错误。
  • Stream 适合用于处理 多次 的异步事件或数据流,允许你持续接收多个值。

了解它们的区别和使用场景可以帮助你更好地选择异步操作的方式,从而提高代码的可读性和性能。

四、总结

1、区别

特性FutureStream
返回值只返回一个值或一个错误持续返回多个值或错误
生命周期一次性操作,完成后不再有新的值持续发出多个值(或者是事件)
异步操作适用于单次异步操作适用于多次异步事件或数据流
操作方式thencatchErrorawaitlistenawait foraddaddError

2、选择 Future 还是 Stream

  • 使用 Future
    • 你在处理一个单次的异步操作时。
    • 比如从网络获取数据、计算结果、执行数据库操作等。
    • 示例:登录请求、获取单个 API 响应、读取文件内容。
  • 使用 Stream
    • 当你需要处理 多个异步事件,例如实时数据流或变化时。
    • 比如 WebSocket 消息、实时位置更新、文件读取(大文件分片)等。
    • 示例:实时聊天消息、连续的数据更新、传感器数据流等。

四、疑问

1、Stream 流是按照顺序执行的吗?

是的,Stream 在 Dart 中是 按顺序 执行的。具体来说,Stream 中的事件(数据或错误)会按照它们被 产生发出 的顺序进行传递和处理。

1. 顺序性

在 Dart 中,Stream 会按照 事件发出的顺序 将这些事件传递给订阅者。也就是说,先发出的事件会先被监听器处理。

例如,如果你有一个 Stream 生成数据流,并且在每个数据项之间有延时,那么监听器将会按照数据产生的顺序处理每个事件。

示例代码:顺序执行的 Stream

Stream<int> generateNumbers() async* {for (int i = 0; i < 3; i++) {await Future.delayed(Duration(seconds: 1));  // 模拟延时yield i;  // 按顺序发出数据}
}void main() async {await for (var number in generateNumbers()) {print('Received: $number');  // 按顺序输出}
}

输出:

Received: 0
Received: 1
Received: 2

在这个例子中,数据流是按顺序传递给监听器的,即 012 按照生成的顺序被逐个输出。

2. 顺序的保证

Stream 本身的设计保证了事件的顺序。无论你是通过 await for 或者 listen 来处理事件,事件会按照发出顺序依次传递给你。

通过 listen 监听的顺序

Stream<int> generateNumbers() async* {for (int i = 0; i < 3; i++) {await Future.delayed(Duration(seconds: 1));yield i;}
}void main() {generateNumbers().listen((data) {print('Received: $data');  // 按顺序输出});
}

这段代码会输出:

Received: 0
Received: 1
Received: 2

如上所示,数据按照顺序传递。

2、Stream async* 和 yield 的解释这三个必须要配套使用吗?,不适用 yield 行吗?

在 Dart 中,Streamasync*yield 是紧密关联的,但它们不一定是必须同时使用的。它们之间的关系可以分开解释,看看如何组合使用,或者是否可以在没有 yield 的情况下使用 async*

1. Streamasync*

Stream 是 Dart 中用于处理异步数据流的核心概念。Stream 对象用于处理一系列异步事件,而 async* 是定义异步生成器(异步迭代器)的一种语法。async* 允许你生成一个 Stream,并通过 yield 来发出数据。

  • async* 标识一个异步生成器函数,它返回一个 Stream
  • yield 用于在异步生成器中逐个发出数据。
2. async*yield 必须配合使用吗?
  • async*yield 一般是配套使用的,但你也可以只使用 async*,并没有强制要求一定要用 yield
  • 如果你不需要发出数据(即你不想使用 yield),你也可以用 async* 作为一个简单的异步函数来返回一个空的 Stream,或者使用 await 来发出异步的结果。
3. 不使用 yield 行不行?

是的,可以在没有 yield 的情况下使用 async*,但通常这样做的结果是流不会发出任何数据。在这种情况下,Stream 会是一个空的流,或者说它在没有任何数据的情况下完成。

示例 1:不使用 yield,生成一个空的流

Stream<int> generateEmptyStream() async* {// 什么都不发出
}void main() async {await for (var value in generateEmptyStream()) {print(value);  // 这里不会有任何输出}
}

在这个例子中,async* 只是声明了一个异步生成器,但是没有 yield,因此返回的 Stream 是空的,不会有任何数据输出。

4. 如何使用 async* 生成异步数据流?

async* 用于返回 Stream,可以通过 yield 来逐个发出数据。你也可以结合 await 来进行异步操作后再发出数据。这是一个典型的用法:

Stream<int> generateNumbers() async* {for (int i = 1; i <= 5; i++) {await Future.delayed(Duration(seconds: 1));  // 模拟异步操作yield i;  // 发出数据}
}void main() async {await for (var number in generateNumbers()) {print(number);}
}

输出:

1
2
3
4
5

在这个例子中,async* 通过 yield 发出了多个数字,每次发出时都延迟 1 秒。

总结
  • async*yield 通常一起使用来生成和发出异步数据流。
  • 不一定非要有 yield (但不使用 yield 意义不大),但如果你希望生成一个有数据的流,就需要使用 yield 或其他发出数据的方式(例如 yield*)。
  • 如果你在 async* 中没有 yield,返回的 Stream 将不会发出任何数据,通常这种情况用于创建空流或只执行异步操作的函数。

因此,虽然 async*yield 是紧密相关的,但它们不必总是同时使用。如果不使用 yield,可以生成一个空流或执行异步操作,但不会有数据发出。

相关文章:

Flutter中的Future和Stream

在 Flutter 中&#xff0c;Future 和 Stream 都是用于处理异步操作的类&#xff0c;它们都基于 Dart 的异步编程模型&#xff0c;但是它们的使用场景和工作方式有所不同。以下是它们的区别以及各自适用的场景。 目录 一、Future1、基本使用2、异常处理1. catchError2. onError…...

107.【C语言】数据结构之二叉树求总节点和第K层节点的个数

目录 1.求二叉树总的节点的个数 1.容易想到的方法 代码 缺陷 思考:能否在TreeSize函数内定义静态变量解决size的问题呢? 其他写法 运行结果 2.最好的方法:分而治之 代码 运行结果 2.求二叉树第K层节点的个数 错误代码 运行结果 修正 运行结果 其他写法 1.求二…...

spring boot支持那些开发工具?

Spring Boot 支持多种开发工具&#xff0c;以帮助开发者更高效地进行应用开发。以下是小编给大家分享几种常用的开发工具及其特点&#xff1a; IntelliJ IDEA&#xff1a; IntelliJ IDEA 是一款非常流行的 Java IDE&#xff0c;它提供了对 Spring Boot 的全面支持&#xff0c;…...

Go-MediatR:Go语言中的中介者模式

在Go语言中&#xff0c;确实存在一个与C#中的MediatR类似的组件包&#xff0c;名为Go-MediatR。 Go-MediatR是一个受.NET中MediatR库启发的Go语言实现&#xff0c;它专注于通过中介者模式简化命令查询责任分离&#xff08;CQRS&#xff09;模式的处理和在事件驱动架构中的应用…...

5.11【机器学习】

先是对图像进行划分 划分完后&#xff0c; 顺序读取文件夹&#xff0c;在文件夹里顺序读取图片&#xff0c; 卷积层又称为滤波器&#xff0c;通道是说滤波器的个数&#xff0c;黑白通道数为1&#xff0c;RGB通道个数为3 在输入层&#xff0c;对于输入层而言&#xff0c;滤波…...

在 CentOS 上安装 Docker:构建容器化环境全攻略

一、引言 在当今的软件开发与运维领域&#xff0c;Docker 无疑是一颗璀璨的明星。它以轻量级虚拟化的卓越特性&#xff0c;为应用程序的打包、分发和管理开辟了崭新的高效便捷之路。无论是开发环境的快速搭建&#xff0c;还是生产环境的稳定部署&#xff0c;Docker 都展现出了…...

Python练习(2)

重复元素判定续。利用集合的无重复性来编写一个程序如果有一个元素出现了不止一次则返回true但不要改变原来列表的值&#xff1a; 一&#xff1a; def has_duplicates(lst): # 使用集合来存储已经见过的元素 seen set() for item in lst: if item in seen: # 如果元素已经在…...

如何实现一套键盘鼠标控制两台计算机(罗技Options+ Flow功能快速实现演示)

需求背景 之前我写过一篇文章如何实现一套键盘鼠标控制两台计算机&#xff08;Mouse Without Borders快速上手教程&#xff09;_一套键鼠控制两台电脑-CSDN博客 当我们在局域网内有两台计算机&#xff0c;想使用一套键鼠操控时&#xff0c;可以安装Mouse Without Borders软件…...

现代应用程序中基于 Cell 架构的安全防护之道

在飞速发展的软件开发领域&#xff0c;基于 Cell 的架构日益流行起来。其概念源自船舶舱壁的设计准则&#xff0c;即单独的水密舱室能允许故障孤立存在。通过将这个概念应用于软件&#xff0c;我们创建了一个架构&#xff0c;将应用程序划分为离散的、可管理的组件&#xff0c;…...

【导航查询】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…...

【基础分析】——Qt 信号和槽的机制 优点

QT信号和槽机制的优点包括&#xff1a; 1、类型安全&#xff1a; 信号和槽的签名必须是等同的&#xff0c;即信号的参数类型和参数个数必须与接收该信号的槽的参数类型和参数个数相同。 2、松散耦合&#xff1a; 信号和槽机制减弱了Qt对象的耦合度。激发信号的Qt对象无须知道…...

Vue3学习宝典

1.ref函数调用的方式生成响应式数据&#xff0c;可以传复杂和简单数据类型 <script setup> // reactive接收一个对象类型的数据 import { reactive } from vue;// ref用函数调用的方式生成响应式数据&#xff0c;可以传复杂和简单数据类型 import { ref } from vue // 简…...

leecode96.不同的二叉搜索树

在画的过程中发现规律&#xff0c;每次选择不同的节点作为根节点&#xff0c;左右两边的节点再排列组合一下就能求出总数 class Solution { public:int numTrees(int n) {vector<int> dp(n1,0);dp[0]1;for(int i1;i<n;i)for(int j0;j<i;j)dp[i]dp[i-j-1]*dp[j];ret…...

树莓派基本配置-基础配置配置

树莓派基本配置 文章目录 树莓派基本配置前言硬件准备树莓派刷机串口方式登录树莓派接入网络ssh方式登录树莓派更换国内源xrdp界面登录树莓派远程文件传输FileZilla 前言 树莓派是一款功能强大且价格实惠的小型计算机&#xff0c;非常适合作为学习编程、物联网项目、家庭自动化…...

手机卡限速丨中国移动5G变3G,网速500kb

以下猜测错误&#xff0c;又有新的猜测&#xff1a;河南移动的卡出省限速。可能是因为流量结算。 “2024年7月1日起&#xff0c;中国移动集团内部将开启跨省流量结算” 在深圳四五年了&#xff0c;之前没有过&#xff0c;就从上个月开始。11月底解除限速&#xff0c;12月刚开…...

SpringCloud之OpenFeign:OpenFeign与Feign谁更适合你的SpringCloud项目?

目录 一、OpenFeign简介1、OpenFeign是什么&#xff08;1&#xff09;核心概念&#xff08;2&#xff09;工作原理&#xff08;3&#xff09;主要特点&#xff08;4&#xff09;使用场景&#xff08;5&#xff09;与Feign的区别&#xff08;6&#xff09;总结 2、OpenFeign与Fe…...

yt6801 ubuntu有线连接驱动安装

耀世16pro的有线网卡驱动安装 下载地址: YT6801 千兆PCIE以太网控制器芯片 1. 创建安装目录 mkdir yt68012. 解压驱动文件 unzip yt6801-linux-driver-1.0.27.zip -d yt68013. 进入驱动目录 cd yt68014. 安装驱动 以 root 权限运行安装脚本&#xff1a; sudo su ./yt_ni…...

算法日记 36-38day 动态规划

今天把动态规划结束掉&#xff0c;包括子序列以及编辑距离 题目&#xff1a;最长公共子序列 1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09; 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &…...

hdlbits系列verilog解答(Dff16e-同步复位上升沿16位触发器)-85

文章目录 一、问题描述二、verilog源码三、仿真结果一、问题描述 本节学习如何创建16位D触发器。有时仅修改一组触发器一部分是有用的。字节使能控制16位寄存器的哪一个字节应当被修改,其中teena[1]控制高位字节[15:8],teena[0]控制低位字节[7:0]。restn是一个同步低电平有效…...

HTTPTomcatServlet

今日目标: 了解JavaWeb开发的技术栈理解HTTP协议和HTTP请求与响应数据的格式掌握Tomcat的使用掌握在IDEA中使用Tomcat插件理解Servlet的执行流程和生命周期掌握Servlet的使用和相关配置1,Web概述 1.1 Web和JavaWeb的概念 Web是全球广域网,也称为万维网(www),能够通过浏览…...

IDEA连接Apifox客户端

IDEA连接Apifox客户端 一、下载Apifox安装包二、IDEA配置三、配置Apifox和IDEA项目同步 一、下载Apifox安装包 Apifox官网&#xff0c;根据自己的操作系统下载对应的Apifox安装包&#xff0c;我是windows系统所以下载的是windows版。 下载 默认仅为我安装&#xff0c;点击下一…...

Linux的奇妙冒险——进程PCB第一讲

进程 1.进程的基本概念2.进程的描述3.查看进程4.通过系统调用获得pid和ppid5.通过fork()系统调用创建子进程6.进程状态1.浅度睡眠 S2.深度睡眠 D3 暂停状态T4.僵尸状态 Z5.死亡状态 X 7.僵尸进程8.孤儿进程9.进程优先级 1.进程的基本概念 任何计算机系统都包含一个基本的程序…...

阿里巴巴热土计划企划金:点燃贫困地区可持续发展的希望之火

在当今社会&#xff0c;扶贫工作已不再仅仅停留在简单的物质援助层面&#xff0c;而是更加注重通过资金支持和资源整合&#xff0c;推动贫困地区的可持续发展。阿里巴巴集团&#xff0c;作为全球领先的电子商务巨头&#xff0c;凭借其强大的影响力和社会责任感&#xff0c;推出…...

2-6 C浮点数指针运算案例

1.0 浮点数指针 float f 1.2f:如何将它对应的4个字节地址空间的数值以十六进制打印出来? 数据在所有计算机中都是以二进制形式存储的&#xff0c;然后以8个位为一个单元称作“字节”&#xff0c;作为计 量和运算处理单元&#xff0c;比如我们说一个文件大小是1MB&#xff0c;指…...

开源的跨平台SQL 编辑器Beekeeper Studio

一款开源的跨平台 SQL 编辑器&#xff0c;提供 SQL 语法高亮、自动补全、数据表内容筛选与过滤、连接 Web 数据库、存储历史查询记录等功能。该编辑器支持 SQLite、MySQL、MariaDB、Postgres 等主流数据库&#xff0c;并兼容 Windows、macOS、Linux 等桌面操作系统。 项目地址…...

07《缓存》计算机组成与体系结构 系列课

目录 深入了解缓存内存 缓存的重要性 游戏中的存储需求与主内存 虚拟内存和按需分页 现代系统中的多级缓存 缓存级别的大小与速度 缓存相关的术语 缓存命中与未命中 页面命中与缺页 局部性原理 结语 深入了解缓存内存 大家好&#xff0c;欢迎来到今天的课程。上节课…...

Java个人博客系统项目文档

项目名称 Java个人博客系统 项目概述 该博客系统是一个多功能的Java应用程序。该系统支持用户发布新文章、浏览他人文章、管理个人文章收藏和删除不再需要的文章。通过该博客系统&#xff0c;用户可以享受一个安全、便捷的在线写作和阅读体验。 运行环境 编程语言&#xff1…...

如何手动设置ubuntu服务器的ip、子网掩码、网关、DNS

在 Ubuntu 服务器上手动设置 IP 地址、子网掩码、网关和 DNS&#xff0c;通常有两种方式&#xff1a;使用传统的 ifconfig 命令和配置文件&#xff0c;或者使用现代的 netplan 配置方式&#xff08;对于 Ubuntu 17.10 及以后版本&#xff0c;netplan 是默认的网络配置工具&…...

SVN clean up失效的一种解决办法

1、进入.svn 2、进入wc.db数据库 sqlite3.exe wc.db sqlite> select * from WC_LOCK; 若有输出则可采用下面的方式来清理 a、delete from WC_LOCK; b、如果删除失败就采用丢弃并重新创建WC_LOCK表的方式清理 drop table WC_LOCK; create table WC_LOCK ( wc_id INTEGER…...

S4 UPA of AA :新资产会计概览

通用并行会计&#xff08;Universal Parallel Accounting&#xff09;可以支持每个独立的分类账与其他模块集成&#xff0c;UPA主要是为了支持平行评估、多货币类型、财务合并、多准则财务报告的复杂业务需求 在ML层面UPA允许根据不同的分类账规则对物料进行评估&#xff0c;并…...