Flutter 状态管理调研总结
一, 候选状态管理组件简介
0. flutter_hooks
一个 React 钩子在 Flutter 上的实现:Making Sense of React Hooks
钩子是一种用来管理 Widget 生命周期的新对象,以减少重复代码、增加组件间复用性,允许将视图逻辑提取到通用的用例中并重用,这使得编写小部件更快、更容易。适用于需要在多个组件中共享状态逻辑的场景,例如管理动画控制器、处理用户输入、管理生命周期等。
可以帮助开发者更好地组织和管理Widget状态和生命周期。它可以提高代码的可读性和可维护性,并且减少了使用传统的 StatefulWidget 时的样板代码量。
Flutter Hooks 相对于传统的 StatefulWidget 带来了一系列改进,主要包括:
-
减少样板代码:Flutter Hooks 通过使用钩子(Hooks)允许在无状态(
StatelessWidget)中管理状态和生命周期,从而减少了创建StatefulWidget及其相应的State类所需的样板代码。 -
提高代码复用性:Hooks 可以在不同的 Widget 中共享,使得逻辑代码更易于复用,有助于代码组织和维护。
-
简化状态管理:Hooks 提供了如
useState和useEffect等函数,使得状态的管理和生命周期事件的处理更为直观和简洁。 -
改善可测试性:由于 Hooks 的逻辑与 Widget 的构造分离,这使得单元测试更加简单,因为可以单独测试 Hooks 的逻辑。
-
兼容现有的 Flutter 架构:Flutter Hooks 设计为与现有的 Flutter 架构兼容,可以在不改变现有代码结构的情况下逐步采用。
-
提高性能:Hooks 允许开发者更精细地控制何时以及如何重新构建 Widget,这可能导致性能优化。
-
促进声明式编程:Hooks 鼓励声明式编程风格,使得代码更易于理解和预测。
-
局部和响应式 状态管理 BLoC
变种:flutter_hooks_bloc , hydrated_bloc ,hooked_bloc ,velocity_bloc
BLoC 是一种流行的架构模式,通过使用流来管理状态,将 UI 组件与业务逻辑解耦。它涉及三个主要组件:Stream、Sink 和 BLoC 本身,后者充当 UI 和数据源之间的中间人。
Bloc 基于事件的概念。你需要定义事件和状态,然后实现事件到状态的映射,从 UI 层发出事件,Bloc 接受这些事件,并根据当前状态和接收到的事件通过 mapEventToState 函数来决定下一个状态。
hooked_bloc 简化了 Bloc/Cubit 的注入和使用,它基于在 React Native 中首次引入的 hook 概念,允许将视图逻辑提取到通用的用例中并重用,这使得编写小部件更快、更容易。hooked_bloc 通过提供一组基于 hook 的 API 来实现依赖注入和状态管理,这些 API 可以帮助开发者更有效地组织代码,减少冗余,并促进代码的可重用性。
优点:
分离关注点和改进代码组织。
增强的测试性和可维护性。
支持跨多个 UI 组件的业务逻辑重用。
缺点:
学习曲线陡峭,特别是对于刚接触响应式编程概念的开发人员。
与其他解决方案相比,增加了样板代码和复杂性。
需要额外的包,如 rxdart 或 flutter_bloc 库。
-
全局和声明式 状态管理 Riverpod
变种:hooks_riverpod,
Provider是一个流行的Flutter依赖注入库,主要是基于InheritedWidget实现的。ChangeNotifierProvider是它提供的一种Provider,用于将ChangeNotifier的实例提供给其子Widget,并在状态变化时通知它们。当你使用ChangeNotifierProvider时,你会在Widget树中的某个节点处提供一个ChangeNotifier实例,并且只有当notifyListeners被调用时,该Provider的依赖者(子Widget)才会重建。
Riverpod 是一种基于提 Provider 的状态管理解决方案,是 flutter_riverpod 包中提供程序的替代品。它利用 Provider 的概念来管理和共享部件间的状态,重点关注简单性、可扩展性和可测试性。
riverpod相比 Provider 不同的是,它不依赖于InheritedWidget。所有的providers都定义在全局范围内,你会使用ProviderScope来确保providers可以在Widget树中任何地方使用。
ProviderScope是一个状态容器,创建了一个状态存储,你可以在此之下的Widget树中任何地方通过context.read、context.watch或Consumer等API访问providers。
RiverPod 与 Flutter Hooks 库结合,提供了灵活的响应式状态管理解决方案,RiverPod 处理依赖注入和状态管理,而 Hooks 简化了小部件的组合和响应式更新。
优点:
与其他基于 provider 的解决方案相比,易于设置和减少样板代码。
通过模拟 provider 和依赖注入提高了可测试性。
允许对小部件的重建进行细粒度的控制。
缺点:
与其他状态管理选项相比,相对较新,可能导致社区资源较少。
与 Provider 或 BLOC 等更成熟的解决方案相比,生态系统和社区支持有限。
需要像 flutter_riverpod 这样的额外包进行集成。
-
Cubit
变种:async_cubits, side_effect_cubit,
Cubit 是 Flutter 团队提供的基于 BLoC 模式的状态管理库,它强调简单性,遵循单向数据流方法,使用 Stream 和 Sink 来处理状态变化和更新。
它不依赖于事件的概念,而是直接对函数调用做出响应。在 Cubit 中,你直接调用一个函数来改变状态。这个函数内部会执行一些逻辑,并最终调用 emit 来发出新的状态。
与 Bloc 相比,Cubit 不需要定义事件,也不需要通过事件来触发状态变化,因此在实现上更为简洁。由于其简洁性,特别适用于那些不需要复杂事件处理的场景,可快速实施状态管理。
优点:
轻量级且易于理解,特别是对于熟悉 BLoC 模式的开发人员。
与传统的 BLoC 相比,简化了语法并减少了样板文件。
性能和测试性良好。
缺点:
与更全面的状态管理解决方案相比,功能有限。
可能不适合高度复杂的状态管理场景。
较少的社区支持和第三方软件包。
-
RiverBloc
Bloc与Riverpod的结合使用
Bloc和Riverpod是两种流行的状态管理库,它们可以在Flutter应用中单独使用,也可以结合使用以发挥各自的优势。Bloc侧重于事件驱动的状态管理,适合处理复杂的业务逻辑,而Riverpod提供了依赖注入和状态管理的解决方案,强调简洁性和性能。
结合使用的策略
结合使用Bloc和Riverpod时,可以将Bloc用于管理应用的核心业务逻辑,而使用Riverpod来管理UI相关的状态或提供服务。例如,可以将Bloc用于处理用户输入、网络请求和数据转换等,而将Riverpod用于提供国际化、主题管理或数据缓存等服务。
Bloc和Riverpod的职责范围划分
在结合使用Bloc和Riverpod时,您可以根据它们各自的设计哲学和优势来划分职责范围。Bloc通常用于处理复杂的业务逻辑,它采用单向数据流模式,将状态管理和业务逻辑分离,有助于维护和测试。Riverpod则是一个状态管理库,它提供了更简洁的API和更好的性能,适合管理跨多个屏幕和组件的状态。
Bloc的职责
处理复杂的业务逻辑:Bloc适合处理那些需要响应用户输入、系统事件或其他状态变化的复杂逻辑。
状态和事件分离:Bloc通过区分状态和事件来管理应用状态,有助于保持代码的清晰结构。
可测试性:由于Bloc的状态和逻辑是分开的,因此它们更容易进行单元测试。
Riverpod的职责
管理共享状态:Riverpod擅长管理应用中的共享状态,特别是那些不经常变化的状态,如配置信息或用户偏好设置。
性能优化:Riverpod通过缓存和延迟计算来优化性能,减少不必要的渲染和计算。
灵活的状态管理:Riverpod提供了多种Provider类型,可以根据不同的需求选择合适的状态管理策略。
职责范围的划分建议
核心业务逻辑使用Bloc:对于应用的核心功能,如用户认证、商品购物车等,使用Bloc来处理相关的状态和事件。
共享状态和配置使用Riverpod:对于需要在多个屏幕间共享的状态,如语言设置、主题颜色等,使用Riverpod来管理。
数据流和状态更新:Bloc可以处理复杂的数据流和状态更新逻辑,而Riverpod可以用于简单的状态读取和监听。
通过上述分工,您可以充分利用Bloc和Riverpod的优点,构建一个既高效又可维护的Flutter应用状态管理体系。在实际应用中,这种组合可以提供更好的灵活性和可扩展性,适应不断变化的应用需求。
Riverbloc 是基于 Riverpod 提供的 BlocProvider 的实现,旨在简化从 flutter_bloc 到 flutter_riverpod 的迁移过程。Riverbloc 利用 Riverpod 的优势,如依赖注入和更简洁的 API,来提供一个更现代和灵活的状态管理解决方案。
是 Bloc 模式在 Riverpod 生态系统中的一个实现,结合了 BLoC 和 Riverpod 的概念,提供了一个简化和高效的状态管理解决方案,它利用 Riverpod 的提供者系统,并将其与 BLoC 的反应流相结合,使强大的状态管理功能成为可能。
Riverbloc 基于声明式编程,它允许开发者通过声明式的方式来管理应用的状态。Riverbloc 强调的是状态的单一来源原则,即每个状态都由一个唯一的提供者(Provider)管理。它提供了丰富的提供者类型,包括但不限于 StateProvider, FutureProvider, StreamProvider, ChangeNotifierProvider 等,以及一系列的构建器和消费者小部件来帮助开发者构建响应状态变化的 UI。
优点:
提供 BLoC 和 Riverpod 的优点,提供灵活而强大的状态管理解决方案。
允许对小部件的重建进行细粒度的控制。
与其他 Flutter 库(如 flutter_hooks )集成,以增强开发体验。
缺点:
相对较新的库,社区支持和资源有限。
需要熟悉 BLoC 和 Riverpod 的概念。
对于刚接触响应式编程的开发人员来说,学习曲线可能会更陡峭。
二,对比
| 对比维度 | hooks_riverpod | flutter_hooks_bloc | riverbloc |
| 状态管理框架 | 基于Riverpod的响应式缓存和数据绑定框架 | 结合Hooks和Bloc/Cubit的状态管理库 | 基于Riverpod的BlocProvider实现 |
| 目的 | 简化异步代码处理,提供高级场景支持,分离逻辑与UI,确保代码可测试、可扩展和可重用 | 简化Bloc/Cubit的注入和使用,利用Hooks提高代码复用性和开发效率 | 便于迁移自flutter_bloc到flutter_riverpod的BlocProvider实现 |
| 核心概念 | Riverpod Provider、HookConsumerWidget | Hooks、Bloc/Cubit,HookWidget | BlocProvider,StateNotifierProvider |
| 状态更新通知 | 使用StateNotifier或ChangeNotifier来管理状态,并提供了ref.watch和ref.read等方法来观察和读取状态 | 通过Bloc/Cubit的状态变化通知UI重建,使用事件(Event)来触发状态的变化,并通过Bloc的emit方法来更新状态 | 通过Riverpod Provider的变化自动通知UI重建 |
| 状态管理策略 | 提供多种Provider类型,如FutureProvider、StreamProvider等,使用ConsumerWidget或HookConsumerWidget来消费这些状态。 | 支持Bloc和Cubit模式,提供了Bloc类和BlocProvider,开发者可以通过这些类来创建Bloc实例,并使用BlocBuilder或BlocListener来构建响应Bloc状态变化的UI。 | 结合Riverpod的状态管理策略,适用于Riverpod生态系统 |
| 与Hooks的整合 | 提供HookConsumerWidget,结合Hooks的状态管理能力 | 使用Hooks提供的useBloc等函数简化Bloc/Cubit的使用 | 需要参考左边两个,依赖flutter_hooks,hooks_riverpod单独引用使用 |
| 社区支持和文档 | 活跃的社区支持,详细的官方文档 | 社区支持,官方文档提供Bloc/Cubit的使用指导 | 社区支持,官方文档提供Riverpod的使用指导 |
| 推荐场景 | 适合需要响应式数据绑定和缓存的应用程序 | 适合需要Bloc/Cubit模式和Hooks优势的应用程序 | 适合需要从flutter_bloc平滑过渡到Riverpod的应用程序 |
hooks_riverpod和hooks_bloc在代码可读性和维护性方面哪个更胜一筹?
hooks_riverpod和hooks_bloc都是用于Flutter应用程序的状态管理库,它们分别基于Riverpod和Bloc架构,并提供了与Hooks的集成,以提高代码的可读性和维护性。
特点对比
-
hooks_riverpod: -
Riverpod是一个状态管理库,它允许开发者以声明式的方式管理应用程序状态,并且可以与Hooks结合使用,以在函数组件中管理状态。Riverpod强调的是全局状态管理,并且提供了灵活的状态提供者和消费者机制。
-
hooks_riverpod通过Hooks提供了更简洁的API,允许开发者在不创建StatefulWidget的情况下管理状态,这有助于减少样板代码并提高代码的可重用性。 -
hooks_bloc: -
Bloc是一个响应式编程框架,它通过使用可观察的流和可转换的流来管理应用程序的状态。
hooks_bloc是Bloc的Hooks版本,它允许开发者在函数组件中使用Bloc的状态管理模式,从而提高代码的模块化和可测试性。 -
hooks_bloc的设计哲学是将状态管理封装在Bloc对象中,这有助于保持UI的简洁性,并且通过流的使用,可以清晰地处理状态的变化和用户的交互。
可读性和维护性
-
hooks_riverpod: -
Riverpod的声明式状态管理和Hooks的结合提供了一种直观的方式来处理状态,这可能有助于提高代码的可读性,尤其是在处理复杂的状态逻辑时。
-
Riverpod的状态提供者和消费者机制可以清晰地区分状态的来源和使用点,这有助于维护和追踪状态的流动。
-
hooks_bloc: -
Bloc的响应式编程模型通过流的使用,可以让状态变化的逻辑更加集中和清晰,这有助于维护状态逻辑,并且通过可转换的流,可以更容易地处理异步操作和复杂的业务逻辑。
-
hooks_bloc的模块化设计有助于隔离不同的业务逻辑,使得代码更加模块化,便于维护和扩展。
结论
选择hooks_riverpod还是hooks_bloc取决于个人或团队的偏好以及项目的具体需求。如果项目需要更灵活的全局状态管理和对状态提供者有更细粒度的控制,hooks_riverpod可能是更好的选择。而如果项目倾向于使用响应式编程模式来处理复杂的业务逻辑,并且需要清晰的状态流,hooks_bloc可能更适合。在实际应用中,两种库都可以提供良好的代码可读性和维护性。
三,后期迁移成本
要将Flutter Bloc转换为Riverpod,您需要遵循以下步骤:
-
识别Bloc的状态和事件:首先,您需要识别Bloc中的状态和事件。这些是Bloc逻辑的核心部分,您将在Riverpod中重建它们。
-
创建Riverpod
StateNotifier:使用Riverpod的StateNotifier来创建一个新的状态控制器。这个控制器将负责管理状态的逻辑,类似于Bloc中的Bloc类。 -
迁移Bloc的逻辑:将Bloc中的
mapEventToState逻辑迁移到StateNotifier中。这通常涉及到根据接收的事件更新状态。 -
替换BlocProvider:在您的应用程序中,将所有BlocProvider替换为Riverpod的
StateNotifierProvider。这意味着您需要更新所有使用Bloc的BlocProvider实例,以便它们使用新的RiverpodStateNotifierProvider。 -
更新UI绑定:修改您的UI代码,以便它使用Riverpod的
Consumer或HookConsumerWidget来订阅状态更改,而不是Bloc的BlocBuilder或BlocListener。
参考天工:
-
局部和响应式 状态管理 BLoC
https://www.tiangong.cn/result/7596e186-d8e9-4d05-a545-bf4f0c7f45df
-
全局和声明式 状态管理 Riverpod
https://www.tiangong.cn/result/6ec740bb-1f3f-4242-9d65-d22d67b04127
相关文章:
Flutter 状态管理调研总结
一, 候选状态管理组件简介 0. flutter_hooks 一个 React 钩子在 Flutter 上的实现:Making Sense of React Hooks 钩子是一种用来管理 Widget 生命周期的新对象,以减少重复代码、增加组件间复用性,允许将视图逻辑提取到通用的用例中并重用&…...
入门C语言只需一个星期(星期二)
点击上方"蓝字"关注我们 01、算术运算符 int myNum = 100 + 50;int sum1 = 100 + 50; // 150 (100 + 50)int sum2 = sum1 + 250; // 400 (150 + 250)int sum3 = sum2 + sum2; // 800 (400 + 400) + 加 将两个值相加 x + y - 减 从另一个值中减去一个值 …...
切换node版本
一、在Linux上切换Node.js版本有多种实现方法: 1.使用nvm(Node Version Manager): 安装nvm:可以通过curl或wget来安装nvm,具体请参考nvm的官方文档。 安装不同版本的Node.js:使用nvm可以轻松…...
【常见开源库的二次开发】基于openssl的加密与解密——Base的编解码(二进制转ascll)(二)
目录: 目录: 一、 Base64概述和应用场景 1.1 概述 1.2 应用场景 二、Base16 2.1 Base16编码 2.2 Base16编解码 三、Base64 四、OpenSSL BIO接☐ 4.1 Filter BIOs: 4.2 Source/Sink BIOs: 4.3 应用场景: 4.4 具体使用&…...
ssrf复习(及ctfshow351-360)
1. SSRF 概述 服务器会根据用户提交的URL发送一个HTTP请求。使用用户指定的URL,Web应用可以获取图片或者文件资源等。典型的例子是百度识图功能。 如果没有对用户提交URL和远端服务器所返回的信息做合适的验证或过滤,就有可能存在“请求伪造"的缺陷…...
请求通过Spring Cloud Gateway 503
最近想处理一个通用的网关服务。 但是我在处理好所有配置的时候发现,网络请求过网关的时候,一直503,我所有的配置都没问题。 环境: JDK: 17 Spring Cloud: 2023.0.2 在 Spring Cloud Gateway 的早期版本中ÿ…...
C++代码_让室友坑我
引子 今天古文波在外地上C集训营,结果却被一起学习的室友坑了。啊,好气,我要报复室友。 所以,我写出了死亡代码。 如果你也想报复某些人,可以看下去。 代码构造: 头文件 想要使用一些函数,如…...
AG32 的MCU与FPGA的主频可以达到568MHz吗
Customers: AG32/ AGRV2K 这个芯片主频和定时器最高速度是多少?用户期望 CPLD计时器功能0.1ns以下。 AGM RE: CPLD做不到 0.1ns的速率,这个需要10G以上的时钟。 那AGRV2K最高多少MHz呢? 一般200MHZ比较容易实现。 进一步说明࿱…...
怎样减少视频的容量 怎样减少视频内存保持清晰度
在数字媒体时代,视频内容已经成为人们日常交流和信息传递的重要方式。然而,视频往往占用大量存储空间,给我们的设备带来不小的负担。如何在不损失视频质量的前提下,减少视频文件的大小呢?本文将为你揭秘几个实用的技巧…...
谈一谈一条SQL的查询、更新语句究竟是如何执行的?
文章目录 理解执行流程衍生知识redo logbinlog 本篇文章是基于《MySQL45讲》来写的个人理解与感悟。 理解 先看下图: 上一篇文章我们讨论了一条SQL查询语句的执行流程,并介绍了执行过程中涉及的处理模块。 回顾一下: 大体来说,…...
自动驾驶AVM环视算法–全景和标定全功能算法实现和exe测试demo
参考:全景和标定全功能算法实现和exe测试demo-金书世界 1、测试环境 opencv310vs2022 2、使用的编程语言 c和c 3、测试的demo的获取 更新:测试的exe程序,无需解压码就可以体验算法测试效果 百度网盘: 链接:http…...
【Docker 系列】学习路线
学习基本概念: 了解容器化与虚拟化的区别了解Docker的基本概念、术语和架构 安装Docker: 根据所使用的操作系统,安装Docker Desktop(Windows、macOS)或Docker Engine(Linux) Docker镜像…...
蓝色系信息工作室建站网站源码系统 带模版手机端 带完整的源代码包以及搭建部署教程
系统概述 信息工作室建站网站源码系统是一款专为追求高效、灵活与个性化建站需求的用户设计的综合性平台。该系统不仅提供了丰富的网站构建模块和预设模版,还支持手机端自适应布局,确保网站在不同设备上都能展现出最佳效果。此外,系统附带完…...
什么是带宽限制,如何影响服务器数据传输?
什么是带宽限制? 带宽限制是指网络连接中的数据传输速率上限,通常以每秒传输的数据量(比特或字节)来衡量。例如,一个服务器的带宽限制为100 Mbps,意味着它在理想情况下每秒最多能传输100兆比特的数据。带宽限制由网络服务提供商或数据中心设…...
RISC-V在线反汇编工具
RISC-V在线反汇编工具: https://luplab.gitlab.io/rvcodecjs/#q34179073&abifalse&isaAUTO 不过,似乎,只支持RV32I、RV64I、RV128I指令集:...
从零手写实现 nginx-32-load balance 负载均衡算法 java 实现
前言 大家好,我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的,可以参考我的另一个项目: 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …...
基于STC89C51单片机的烟雾报警器设计(煤气火灾检测报警)(含文档、源码与proteus仿真,以及系统详细介绍)
本篇文章论述的是基于STC89C51单片机的烟雾报警器设计的详情介绍,如果对您有帮助的话,还请关注一下哦,如果有资源方面的需要可以联系我。 目录 摘要 原理图 实物图 仿真图 元件清单 代码 系统论文 资源下载 摘要 随着现代家庭用火、…...
SpringBoot整合阿里云RocketMQ对接,商业版
1.需要阿里云开通商业版RocketMQ 普通消息新建普通主题,普通组,延迟消息新建延迟消息主题,延迟消息组 2.结构目录 3.引入依赖 <!--阿里云RocketMq整合--><dependency><groupId>com.aliyun.openservices</groupId><artifactId>ons-client</…...
modbus slave 设备通过 网关thingsboard-gateway 将数据上传到thingsboard云平台
搭建thingsboard物联网云平台花了大量时间,从小白到最后搭建成功,折磨了好几天,也感谢网友的帮助,提供了思路最终成功搞定,特此记录。 一、thingsboard环境搭建(Ubuntu20.04LTS) 参考官方文档&a…...
安全防御:智能选路
目录 一、智能选路 1.1 就近选路 1.2 策略路由 1.3 虚拟系统---VRF 二、全局选路策略 1,基于链路带宽进行负载分担 2,基于链路质量进行负载分担 3,基于链路权重的负载分担 4,根据链路优先级的主备备份 DNS透明代理 一、…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
