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

智能座舱进阶-应用框架层-Jetpack主要组件

Jetpack的分类
在这里插入图片描述

1. DataBinding:以声明方式将可观察数据绑定到界面元素,通常和ViewModel配合使用。
2. Lifecycle:用于管理Activity和Fragment的生命周期,可帮助开发者生成更易于维护的轻量级代码。
3. LiveData: 在底层数据库更改时通知视图。它是一个可观察的数据持有者,与常规observable不同,LiveData是生命周期感知的。
4. Navigation:处理应用内导航。
5. Paging:可以帮助开发者一次加载和显示小块数据,按需加载部分数据可减少网络带宽和系统资源的使用。
6. Room:友好、流畅的访问SQLite数据库。它在SQLite的基础上提供了一个抽象层,允许更强大的数据库访问。
7. ViewModel: 以生命周期的方式管理界面相关的数据,通常和DataBinding配合使用,为开发者实现MVVM架构提供了强有力的支持。
8. WorkManager: 管理Android的后台的作业,即使应用程序退出或设备重新启动也可以运行可延迟的异步任务。

Android 标准架构框架图:
在这里插入图片描述

Android官方架构部分的知识 https://developer.android.google.cn/topic/architecture/intro?hl=zh-cn

ViewBinding&DataBinding篇

ViewBinding介绍和使用

大家还是不要把ViewBinding和DataBinding这两个不要混淆了.
ViewBindling 这是一个负责绑定View到代码,减少 findViewId降低空引用资源ID错误。使用起来也较为简单, 流程是:
第一、 在 app模块下的build.gradle.kts下,打开使用ViewBinder的开关:

Android{
…
buildFeatures {ViewBinding = true}
}

第二就是需要在使用的Activity、fragment、view里面去初始化一下,inflate“

class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)}
}

第三步就可以直接引用使用了

binding.button.text="helloworld"

注意: viewBinding 目前能够支持所有Xml的控件进行自动绑定, 包含Activity、Fragment以及其他View等。

ViewBinding原理

开启后会自动生成【xml的文件名 自动大驼峰】+Binding.kt 文件。例如ActivityMainBinding.kt。可以看一下自动生成文件代码,我只看inflate最后执行的部分:

public static ActivityMainBinding bind(@NonNull View rootView) { 
int id; 
id = R.id.tv1; 
TextView tv1 = ViewBindings.findChildViewById(rootView, id);if (tv1 == null) { 
break missingId; 
} 
id = R.id.tv2; 
TextView tv2 = ViewBindings.findChildViewById(rootView, id);
if (tv2 == null) { 
break missingId; 
} 
return new ActivityMainBinding((ConstraintLayout) rootView, tv1, tv2);} 
}

可以看到自动生成的代码里,会把XML里控件的每个id都会塞进去,并且调findViewById进行绑定。

DataBinding的介绍和使用

Android 开发中体现 MVVM 架构思想的 Data Binding,其核心是 观察者模式 的特定实现。首先,它有三个主要的实体:

  1. Data:与 View 相关的数据,它可以是 View 的可观察者对象;
  2. View:展示给用户的视图,如果有交互功能且能更新数据,它可以是 Data 的可观察者对象;
  3. ViewDataBinding:连接 Data 和 View 的中介,当 Data 或 View 作为可观察者对象时,它充当可观察者对象的代理。假如当我们写了一个名为 demo.xml 的 Data Binding 的 layout 文件后,编译工具会生成一个相应的类——DemoBinding,它的原型就是 ViewDataBinding。我们通常通过 DataBindingUtil.inflate(inflater, R.layout.demo, container, false) 来实例化的 DemoBinding 对象,即 ViewDataBinding。

主要是三个方面的功能:
• 将特定的 View 与特定的 Data 进行绑定,便于模块化;
• View 自动感知和响应 Data 的变化,使得处理数据的业务层不必关心 View 的状态,便于解耦;
• Data 也可以自动同步带有交互功能的 View 对数据的修改,使得 UI 层的交互不必担心数据是否能同步 View 状态的问题,仍然便于解耦

使用类似ViewBinding:
第一是,在 app模块下的build.gradle.kts下,打开使用ViewBinder的开关:

Android{
…
buildFeatures {DataBinding = true}
}

第二就可以直接在需要使用Xml文件里使用就行了,但是前提现有已经新简的Data类:

class User(var firstName: String, var lastName: String) {}
<?xml version="1.0" encoding="utf-8"?> 
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data> <variable name="user" type="com.example.User"/></data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.firstName}"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.lastName}"/> </LinearLayout></layout>

基础用法很简单, 但是这只是单项View-Data绑定。
比较好的功能是 它还能帮助我们做到通过感知Data的局部变量来进行局部刷新,还有可以可以绑定View,进行双向绑定。使用方法就是将Data转化成observe 对象,并且添加@Bindable 的竹节,通过notifyPropertyChanged()方法来达成局部刷新,如下:

public class DemoData extends BaseObservable {private int element;
// 定义其它成员,省略
@Bindablepublic int getElement() {return this.element;}
public void setElement(int e) {this.element = e;notifyPropertyChanged(BR.element);}
// 省略其它成员操作
}

ViewModel篇

viewModel 的使用, viewModel继承子类使用, 数据存储在内存中,可以和acitivty 生命周期进行绑定,也独立于Activity;onSaveInstanceState(Bundle) 存储的数据,仅在当前应用进程哪有效, 当退出重新进入, Bundle重新恢复成初始状态。或者在 OnStop中保存永久性数据

存储作用域
实例化 ViewModel 时,您会向其传递实现 ViewModelStoreOwner 接口的对象。它可能是 Navigation 目的地、Navigation 图表、activity、fragment 或实现接口的任何其他类型。然后,ViewModel 的作用域将限定为 ViewModelStoreOwner 的 Lifecycle。它会一直保留在内存中,直到其 ViewModelStoreOwner 永久消失。
有一系列类是 ViewModelStoreOwner 接口的直接或间接子类。直接子类为 ComponentActivity、Fragment 和 NavBackStackEntry。如需查看间接子类的完整列表,请参阅 ViewModelStoreOwner 参考文档。
当 ViewModel 的作用域 fragment 或 activity 被销毁时,异步工作会在作用域限定到该 fragment 或 activity 的 ViewModel 中继续进行。这是持久性的关键。
如需了解详情,请参阅下文有关 ViewModel 生命周期的部分

我这里不去赘述 如何使用它, 我曾在上一家公司中对的Alios系统平台, 使用TS语言设计了一个跟viewModel类似的 组件库DataManager .主要的设计原则是观察者绑定和职责分离原则。 本质上来讲ViewModel 就是一个独立的数据储存类, 设计者在里面做了跟Activity的destory来消亡的【非因为配置改变导致的destory】,其实也可以做到完全独立,消亡由开发者自己决定, 这样就会很有趣了,多个activty可以共一个ViewModel实例.只是里面做了一些对象传递的封装,就可以和LiveData进行配合使用。

  • ViewModelStore:用于存储ViewModel实例的类,内部持有一个HashMap保存实例,ViewModelProvider会将创建好的ViewModel实例保存到ViewModelStore中,之后再需要此类ViewModel的实例时就直接从中读取。
  • ViewModelProvider.Factory:前文已经提到,这是用于创建ViewModel实例的工厂,ViewModelProvider当需要ViewModel的实例又在ViewModelStore中没有找到对应实例时就会调用工厂的create方法创建。
  • CreationExtras:前文也已提到,它用于在创建ViewModel实例时从外界向构造过程传递参数,内部持有一个MutableMap,以key-value的形式存储和查找参数

ViewModelStore中的HashMap 设计应该是至少两层以上的,在当初我设计的空间中,这里用的两层, 并且因为是量产项目的原因, 加了一个些状态机key值进行了耦合。 Android官方是直接保存的ViewModel的对象,这样就只有一层了。
每个Acitivty都会有一个ViewModelStoreOwner ,这样在开发者做项目的时候,就不需要关系每个Activity的获取ViewModel的时候,就是绑定的哪一个。

public class ComponentActivity extends androidx.core.app.ComponentActivity implements

// 实现了 ViewModelStoreOwner 接口
ViewModelStoreOwner,
…{
private ViewModelStore mViewModelStore;
// 重写了 ViewModelStoreOwner 接口的唯一的方法 getViewModelStore()
@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (getApplication() == null) {
throw new IllegalStateException("Your activity is not yet attached to the "
+ “Application instance. You can’t request ViewModel before onCreate call.”);
}
ensureViewModelStore();
return mViewModelStore;
}
ViewModelProvider 的构造方法时 ,获取 ViewModelStore 对象时,实际调用了 MainActivity#getViewModelStore() ,而 getViewModelStore() 实现在 MainActivity 的父类 ComponentActivity 中。
在返回 mViewModelStore 对象之前调用了 ensureViewModelStore()
void ensureViewModelStore() {
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// Restore the ViewModelStore from NonConfigurationInstances
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
}


- onRetainNonConfigurationInstance 方法和 getLastNonConfigurationInstance 是成对出现的,跟 onSaveInstanceState 机制类似,只不过它是仅用作处理配置更改的优化。
- 返回的是 onRetainNonConfigurationInstance 返回的对象Activity 在因配置更改而销毁重建过程中会先调用 onRetainNonConfigurationInstance 保存 viewModelStore 实例。 在重建后可以通过 getLastNonConfigurationInstance 方法获取之前的 viewModelStore 实例。
另外,我們可以看一下 mViewModelStore ,销毁的时机,其实是在生命周期的判断Lifecycle.Event.ON_DESTROY 被摧毁并且 判断是否是配置改变引起的isChangingConfigurations()来进行区分:
getLifecycle().addObserver(new LifecycleEventObserver() {@Overridepublic void onStateChanged(@NonNull LifecycleOwner source,@NonNull Lifecycle.Event event) {if (event == Lifecycle.Event.ON_DESTROY) {// Clear out the available contextmContextAwareHelper.clearAvailableContext();// And clear the ViewModelStoreif (!isChangingConfigurations()) {getViewModelStore().clear();}}}});...}

ViewModel 出现之前,Activity 可以使用 onSaveInstanceState() 方法保存,然后从 onCreate() 中的 Bundle 恢复数据,但此方法仅适合可以序列化再反序列化的少量数据(IPC 对 Bundle 有 1M 的限制),而不适合数量可能较大的数据,如用户信息列表或位图。 ViewModel 的出现完美解决这个问题。

LiveData篇

通常情况下LiveData都是配合viewModel使用,在某个具体的ViewModel类中定义LiveData数据,然后在对应的Activity或Fragment中观察LiveData数据的变化,LiveData的使用使得我们不再将数据保存在Activity或Fragment中,减轻了Activity或Fragment的工作量,使得Activity或Fragment只负责界面的管理和显示,而不在保存数据也不会受到数据的影响。但是也可以使用oberveForever()不绑定生命周期, 那就需要自己手动管理它的消亡。
核心方法

通过 observe(owner,observer) 向 LiveData 注册观察者
• 通过 observe(owner,observer) 向 LiveData 注册观察者,并且把 observer 包装成一个 LifecycleBoundObserver,它是一个具有生命周期边界的观察者,因为这个观察者只有当宿主处于 STARTED 或者 RESUMED 状态的它才会接收数据,其他时候它是不会接收数据的。
• 把包装好的 Observer 注册到 Lifecycle 当中,handlerLifecycleEvent(event) 利用 Lifecycle 能力,它能感知宿主生命周期能力的关键地方。注册时和宿主每次生命周期变化都会回调 onStateChanged() 方法,刚进去的时候会触发方法的同步。
• 会判断这个事件宿主是否被销毁了,从而主动地把 Observer 从 LiveData 中移除掉,流程结束。如果不是 DESTORY,说明宿主当前的状态发生了变化,它会触发 activeStateChanged(boolean newActive) 方法,它会判断当前 Observer 是否处于活跃的状态,如果宿主的状态为 STARTED,RESUMED 则会分发最新数据到每个观察者。
• 进而调用 dispatchingValue(ObserverWrapper) 分发数据,如果 ObserverWrapper 为空则分发数据给 liveData 中存储的所有观察者,如果不为空,则分发数据给该 Observer。
• considerNotify(ObserverWrapper) 中先判断观察者所在的宿主不活跃,则不分发;接着如果 observer 的 mLastVersion 大于或等于 LiveData 的 mVersion 则不分发,防止重复发送数据;最后通过 observer.mObserver.onChanged((T) mData) 分发数据,同步 mVersion 数据。
• 那么 LiveData 先发送数据,后注册的 Observer 能接收到数据吗? 答案是可以的。

普通消息的发送
• postValue() 发送一条数据,它可以在任意线程使用的,里面实际使用了 Handler.post 先把这个事件发送到主线程,然后在调用 setValue() 发送数据;
• setValue() 代表着 LiveData 发送数据,每发送一次 mVersion++,另外 LifecycleBoundObserver 中也有一个,它代表这个 Observer 接收了几次数据,在分发数据的时候,这两个 version 会进行比对,防止数据重复发送;
• setValue() 里面也会触发 dispatchingValue(ObserverWrapper),ObserverWrapper 为 null,dispatchingValue() 它会遍历 Observer 集合里面所有观察者,然后逐一调用 considerNotify(ObserverWrapper) 去做消息的分发。

此外,LiveData和 Room配合使用 时候,
LiveData 就是为了简化room 的Dao查询对象到 viewModel的过程, 返回LiveData对象, 查询数据的操作就不需要自己去创建后台线程 。 LiveData能够自动完成。至于为什么Room的查询使用LiveData对象就不需要自己起子线程。 是因为 当liveData做返回对象的时候,room的 查询方法,会多使用一个ComputableLiveData类, 这里面会判断是否有子线程,如果没有,自己会自动起一个子线程去查询,普通类型就会直接走SupportSQLiteDatabase#query(SupportSQLiteQuery)方法,看下面代码:

并且使用LiveData.observe.能够添加观察者, 绑定fragment周期和数据的更新,只要LiveData的数据发生变化, 就会实时刷新:
普通数据类型的查询:

/*** Wrapper for {@link SupportSQLiteDatabase#query(SupportSQLiteQuery)}.** @param query The Query which includes the SQL and a bind callback for bind arguments.* @return Result of the query.*/public Cursor query(SupportSQLiteQuery query) {assertNotMainThread();return mOpenHelper.getWritableDatabase().query(query);}

使用LiveData作为返回值时用到了ComputableLiveData类,此类在构造的时候就将RoomDatabase中的mQueryExecutor传入了。如果在构造的时候没有传入自定义的Executor,那么会自动生成一个。会走这个方法:

 if (mQueryExecutor == null) {mQueryExecutor = ArchTaskExecutor.getIOThreadExecutor();}

相关文章:

智能座舱进阶-应用框架层-Jetpack主要组件

Jetpack的分类 1. DataBinding&#xff1a;以声明方式将可观察数据绑定到界面元素&#xff0c;通常和ViewModel配合使用。 2. Lifecycle&#xff1a;用于管理Activity和Fragment的生命周期&#xff0c;可帮助开发者生成更易于维护的轻量级代码。 3. LiveData: 在底层数据库更…...

2024年底-Sre面试回顾

前言 背景: 2024.11月底 公司不大行了, 裁员收缩, 12月初开始面试, 2周大概面试了十几家公司, 3个2面要去线下, 有1个还不错的offer, 想结束战斗但还没到时候 个人情况: base上海 5年经验(2年实施3年运维半年开发) 面试岗位: Sre、云原生运维、驻场运维、高级运维、实施交付 …...

vue2使用render,js中写html

1、js部分table.js export default {name: "dadeT",data() {return {dades: 6666};},render(h) {return h(div, [h(span, 组件数据&#xff1a;${this.dades}), // 利用data里的dades数据&#xff0c;展示在页面上h(span, 89855545)]);} };2、vue部分 <templat…...

L2tp环境搭建笔记- Openwrt平台

L2tp环境搭建笔记- Openwrt平台 安装L2tp服务配置L2tp serverL2TP客户端配置(使用配置文件)L2TP客户端配置(LUCI)客户端 拔号(命令行方式)defaultroute路由问题L2TP(Layer 2 Tunneling Protocol)是一种工作在二层的隧道协议,是一种虚拟专用网络(VPN)协议。L2TP通常基…...

解决Nginx + Vue.js (ruoyi-vue) 单页应用(SPA) 404问题的指南

问题描述 在使用Vue.js构建的单页应用&#xff08;SPA&#xff09;中&#xff0c;特别是像ruoyi-vue这样的框架&#xff0c;如果启用了HTML5历史记录模式进行路由管理&#xff0c;那么用户直接访问子路径或刷新页面时可能会遇到404错误。这是因为当用户尝试访问一个非根路径时…...

Leetcode打卡:找到稳定山的下标

执行结果&#xff1a;通过 题目&#xff1a; 3258 找到稳定山的下标 有 n 座山排成一列&#xff0c;每座山都有一个高度。给你一个整数数组 height &#xff0c;其中 height[i] 表示第 i 座山的高度&#xff0c;再给你一个整数 threshold 。 对于下标不为 0 的一座山&#xf…...

51c嵌入式~单片机~合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/12362395 一、STM32代码远程升级之IAP编程 IAP是什么 有时项目上需要远程升级单片机程序&#xff0c;此时需要接触到IAP编程。 IAP即为In Application Programming&#xff0c;解释为在应用中编程&#xff0c;用户自己的…...

基于vue3实现小程序手机号一键登录

在Vue 3中实现小程序手机号一键登录&#xff0c;你需要结合小程序的API和Vue 3的框架特性。以下是一个基本的实现步骤和示例代码&#xff1a; 步骤 创建Vue 3项目&#xff1a;如果你还没有Vue 3项目&#xff0c;你需要先创建一个。这可以通过Vue CLI或者其他方式来完成。 集成…...

车辆重识别代码笔记12.19

1、resnet_ibn_a和resnet网络的区别 ResNet-IBN-A 是在 ResNet 基础上进行了一些改进的变种&#xff0c;具体来说&#xff0c;它引入了 Instance Batch Normalization (IBN) 的概念&#xff0c;这在某些任务中&#xff08;如图像识别、迁移学习等&#xff09;有显著的性能提升。…...

c语言---预处理

预处理的概念 预处理是C语言编译过程的第一个阶段。在这个阶段&#xff0c;预处理器会根据预处理指令对源程序进行处理&#xff0c;这些指令以#开头&#xff0c;比如#include、#define等。预处理的主要目的是对源程序进行文本替换和文件包含等操作&#xff0c;为后续的编译步骤…...

Spring Cloud Sleuth 分布式链路追踪入门

您好&#xff0c;我是今夜写代码,今天学习下分布式链路组件Spring Cloud Sleuth。 本文内容 介绍了分布式链路的思想 Sleuth 和 Zipkin 简单集成Demo,并不涉及 Sleuth原理。 为什么要用链路追踪&#xff1f; 微服务架构下&#xff0c;一个复杂的电商应用&#xff0c;完成下…...

无人机航测系统技术特点!

一、无人机航测系统的设计逻辑 无人机航测系统的设计逻辑主要围绕实现高效、准确、安全的航空摄影测量展开。其设计目标是通过无人机搭载相机和传感器&#xff0c;利用先进的飞行控制系统和数据处理技术&#xff0c;实现对地表信息的全方位、高精度获取。 需求分析&#xff1…...

uniapp使用腾讯地图接口的时候提示此key每秒请求量已达到上限或者提示此key每日调用量已达到上限问题解决

要在创建的key上添加配额 点击配额之后进入分配页面&#xff0c;分配完之后刷新uniapp就可以调用成功了。...

【Prompt Engineering】3.文本概括

一、引言 文本信息量大&#xff0c;LLM在文本概括任务上展现出强大能力。本章介绍如何通过编程方式调用API接口实现文本概括功能。 首先&#xff0c;我们需要引入 zhipuAI 包&#xff0c;加载 API 密钥&#xff0c;定义 getCompletion 函数。 from zhipuai import ZhipuAIke…...

5G 模组 初始化状态检测

5G 模组 上电检测 5G 模组 上电检测 #终端上电后&#xff0c;待模组正常启动&#xff0c;再进入 控制台。 #vim /etc/profile##新增 until [ -c /dev/ttyUSB1 ] doecho -e "Wait module[5G] up ... "sleep 5 done ##新增The End....

常用的前端框架介绍

在前端开发中&#xff0c;有几个常用的框架技术&#xff0c;它们各自具有独特的特点和优势。 1. React&#xff1a; • 组件化开发&#xff1a;React 鼓励将 UI 拆分成可复用的组件&#xff0c;每个组件负责渲染 UI 的一部分。 • 虚拟 DOM&#xff1a;React 使用虚拟 DOM 来提…...

python飞机大战游戏.py

python飞机大战游戏.py import pygame import random# 游戏窗口大小 WINDOW_WIDTH 600 WINDOW_HEIGHT 800# 颜色定义 BLACK (0, 0, 0) WHITE (255, 255, 255)# 初始化Pygame pygame.init()# 创建游戏窗口 window pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))…...

PPO: 一种通过近端策略优化提高模型性能的方法

PPO: 一种通过近端策略优化提高模型性能的方法 PPO&#xff08;Proximal Policy Optimization&#xff09;是一种强化学习中的策略优化算法&#xff0c;主要用于训练智能体以改善在环境中表现的能力。PPO通过以下几个关键点来提高模型性能&#xff1a; 近端优化&#xff1a;PP…...

Docker创建一个mongodb实例,并用springboot连接 mongodb进行读写文件

一、通过Docker 进行运行一个 mongodb实例 1、拉取镜像 docker pull mongo:5.0.5 2、创建 mongodb容器实例 docker run -d --name mongodb2 \-e MONGO_INITDB_ROOT_USERNAMEsalaryMongo \-e MONGO_INITDB_ROOT_PASSWORD123456 \-p 27017:27017 \mongo:5.0.5 3、进入容器&am…...

[IT项目管理]九.项目质量管理

九&#xff0e;项目质量管理 9.1项目质量管理的重要性 对于很多IT项目的差劲&#xff0c;大多数人只可以忍受。项目质量管理是IT项目管理的重要组成部分&#xff0c;对于提高项目成功率、降低项目成本、提升客户满意度至关重要。尽管很多人对IT项目的质量问题感到无奈&#x…...

Unity中的委托和事件(UnityAction、UnityEvent)

委托和事件 &#x1f392;什么是委托&#xff0c;委托的关键字是Delegate&#xff0c;委托是一种函数的容器&#xff0c;运行将函数做为变量来进行传递 通过Delegate关键字我们声明了一个无参无返回的委托&#xff0c;通过这个委托我们可以存储无参无返回的函数 public deleg…...

图像生成工具WebUI

介绍 Stable Diffusion WebUI&#xff08;AUTOMATIC1111&#xff0c;简称A1111&#xff09;是一个为高级用户设计的图形用户界面&#xff08;GUI&#xff09;&#xff0c;它提供了丰富的功能和灵活性&#xff0c;以满足复杂和高级的图像生成需求。如今各种人工智能满天飞&…...

Python面试常见问题及答案12

问题&#xff1a; 请解释Python中的GIL&#xff08;全局解释器锁&#xff09;是什么&#xff1f; ○ 答案&#xff1a; GIL是Python解释器中的一种机制&#xff0c;用于确保任何时候只有一个线程在执行Python字节码。这在多线程场景下可能影响性能优化&#xff0c;但对于单线程…...

javalock(六)CyclicBarrier

注意&#xff1a;CyclicBarrier不是AQS的派生类&#xff0c;而是CyclicBarrier内部使用了ReentrantLock.Condition 和CountDownLatch一样&#xff0c;都是计数减为0就可以成功获取锁 和CountDownLatch不同的是&#xff1a; 1&#xff1a;CountDownLatch的await和countdown操作…...

React 19有哪些新特性?

写在前面 2024.12.5&#xff0c;React 团队在 react.dev/blog 上发表了帖子 react.dev/blog/2024/1… React 19 正式进入了 stable 状态 React 团队介绍了一些新的特性和 Breaking Changes&#xff0c;并提供了升级指南&#xff0c; React 19: 新更新、新特性和新Hooks Reac…...

大数据治理:构建数据驱动的智慧教学体系

随着大数据技术在教育领域的逐渐渗透&#xff0c;大数据治理在教学中的应用日益广泛&#xff0c;它为提升教学质量、优化教学资源配置以及实现个性化教学提供了有力支持。 一、大数据治理在教学数据管理中的应用 在教学过程中&#xff0c;会产生海量的数据&#xff0c;如学生的…...

梳理你的思路(从OOP到架构设计)_浅尝架构师的滋味03

目录 1、分与合&#xff1a; 强龙与地头蛇的分工 分工 & 合作 分工的时间点 客人来之前做「分」&#xff0c;客人来之后做「合」 2、结语 肯德基餐厅 火锅店 汽车 从分工到外包模式 1、分与合&#xff1a; 强龙与地头蛇的分工 EIT造形用来表达架构师的先「分」与买…...

ChatGPT与领域特定语言的集成

用ChatGPT做软件测试 领域特定语言&#xff08;Domain-Specific Language&#xff0c;DSL&#xff09;是一种编程语言&#xff0c;专门设计用于满足特定领域或问题领域的需求。它是一种定制的语言&#xff0c;通常包括特定领域的专业术语以及相应的语法规则。DSL的设计旨在让领…...

sql server msdb数据库备份恢复

备份 BACKUP DATABASE [msdb] TO DISK ND:\liyuanshuai\test\sqlserver_bakfile\msdb20241219.bak WITH NOFORMAT, NOINIT, NAME Nlys-完整 数据库 备份, SKIP, NOREWIND, NOUNLOAD, COMPRESSION, STATS 10 GO然后删除2个测试的job&#xff0c;停止 SQL Server 代理…...

MyBatis(二)

一、MyBatis 和 JDBC 有什么区别&#xff1f; JDBC 是 Java 访问数据库的基础 API&#xff0c;它需要大量的样板代码。比如&#xff0c;使用 JDBC 进行查询时&#xff0c;需要加载驱动、建立连接、创建语句、执行查询、处理结果集和关闭资源等操作。代码比较繁琐且容易出错。M…...

Docker:Dockerfile(补充四)

这里写目录标题 1. Dockerfile常见指令1.1 DockerFile例子 2. 一些其他命令 1. Dockerfile常见指令 简单的dockerFile文件 FROM openjdk:17LABEL authorleifengyangCOPY app.jar /app.jarEXPOSE 8080ENTRYPOINT ["java","-jar","/app.jar"]# 使…...

Hexo博客生成标签和分类页

个人博客地址&#xff1a;Hexo博客生成标签和分类页 | 一张假钞的真实世界。 标签页 默认情况下&#xff0c;Hexo站点创建后&#xff0c;需手动生成标签页。如不生成&#xff0c;在点击“标签”菜单时会出现以下错误&#xff1a; Cannot GET /tags/ 执行以下命令创建标签页…...

Linux基础 -- 使用Linux Shell通过TCP发送消息

使用Linux Shell通过TCP发送消息 本文档介绍如何使用Linux Shell命令&#xff0c;通过TCP协议向服务器发送消息&#xff0c;示例中的目标服务器地址为 192.168.1.32&#xff0c;端口为 15000。 示例代码 使用 printf 和 netcat&#xff08;简称 nc&#xff09;工具实现&…...

联表查询相关语法

1.查询sql语句的执行顺序 sql:语法 select distinct * from 左表名 (left/inner/right)join 右表名 on 连接条件 where 筛选条件 group by 分组的列表(按什么字段分组) having 分组条件 order by 排序的字段 limit 分页 以上为语法结构&#xff0c;顺序不能乱执行顺序&#x…...

upload-labs(1-19关)通关攻略

Pass-01 本关思路&#xff1a;删除前端js校验 进入第一关环境 桌面新建一个php文件&#xff0c;命名为1.php <?php eval($_POST[a]);?> 我们上传此文件&#xff0c;发现不允许上传&#xff0c;且页面没有变化&#xff0c;说明前端进行了拦截 这时我们打开 F12 &…...

C语言小练习-求数组的最大子数组

#include <stdio.h>/***暴力求解最大子数组&#xff0c;使用两重循环&#xff0c;把所有情况全部遍历一遍。*/ int subArr1(int *arr,int size) {int sum 0, max arr[0];int i,j;for(i 0;i < size; i){for(j i; j < size; j){sum arr[j];if(sum > max){max…...

初识C语言之二维数组(中)

一.二维数组练习 ①题目描述:打印多个字符从两端移动&#xff0c;向中间汇聚。 eg. ################ H###############! He##############!! Hel#############!!! Hell############!!!! Hello##########t!!!! ................................................. He…...

Ubuntu下迁移Conda环境

Ubuntu下快速迁移Conda环境到其他电脑 安装conda-pack pip install conda-packOr conda install conda-pack压缩conda环境 解压到目标电脑或者目标文件下 conda pack -n your_envs_name -o your_envs_name.tar.gz解压conda环境 mkdir your_new_envs_name tar -zxvf your_e…...

数据可视化-1. 折线图

目录 1. 折线图适用场景分析 1. 1 时间序列数据展示 1.2 趋势分析 1.3 多变量比较 1.4 数据异常检测 1.5 简洁易读的数据可视化 1.6 特定领域的应用 2. 折线图局限性 3. 折线图代码实现 3.1 Python 源代码 3.2 折线图效果&#xff08;网页显示&#xff09; 1. 折线图…...

MATLAB绘图基础12:地理信息可视化

参考书&#xff1a;《 M A T L A B {\rm MATLAB} MATLAB与学术图表绘制》(关东升)。 12.地理信息可视化 12.1 地理散点图 地理散点图用于可视化地理坐标点分布的图形&#xff0c;适用于在地图上显示离散地理坐标点&#xff0c;每个点可以代表不同的实体、地点或其他类型的观测…...

C语言与C++

文件概念 在C语言中&#xff0c;文件是一个重要的概念&#xff0c;用于组织和存储数据。文件主要分为两类&#xff1a; 程序文件 &#xff1a;包含源代码、目标文件和可执行文件。 数据文件 &#xff1a;存储程序运行时读写的各类数据。 文件名通常由三部分组成&#xff1a;…...

C# 中的闭包

文章目录 前言一、闭包的基本概念二、匿名函数中的闭包1、定义和使用匿名函数2、匿名函数捕获外部变量3、闭包的生命周期 三、Lambda 表达式中的闭包1、定义和使用 Lambda 表达式2、Lambda 表达式捕获外部变量3、闭包的作用域 四、闭包的应用场景1、事件处理2、异步编程3、迭代…...

基于DockerCompose搭建Redis主从哨兵模式

linux目录结构 内网配置 哨兵配置文件如下&#xff0c;创建3个哨兵配置文件 # sentinel26379.conf sentinel26380.conf sentinel26381.conf 内容如下 protected-mode no sentinel monitor mymaster redis-master 6379 2 sentinel down-after-milliseconds mymaster 60000 s…...

UIP协议栈 TCP通信客户端 服务端,UDP单播 广播通信 example

文章目录 1. TCP通信 客户端&#xff08;关键配置&#xff09;2. TCP 服务端配置3. UDP 点播通信4. UDP 广播通信5. UIP_UDP_APPCALL 里边的处理example6. TCP数据处理 &#xff0c;UIP_APPCALL调用的函数 UIP_APPCALL TCP的数据都在这个宏定义的函数里进行数据处理的 UDP 数据…...

LeetCode:226.翻转二叉树

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;226.翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 …...

Visual Studio 使用 GitHub Copilot 扩展

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…...

Unity实现Root Motion动画的Navigation自动导航

Root motion动画可以将角色的根节点&#xff08;通常是角色的骨盆或脚部&#xff09;的运动直接应用到游戏对象上&#xff0c;从而实现角色的自然移动和旋转&#xff0c;避免出现脚底打滑的现象。采用Root motion动画的游戏对象&#xff0c;通常是重载了onAnimatorMove函数&…...

vulnhub靶场【DriftingBlues】之9 final

前言 靶机&#xff1a;DriftingBlues-6&#xff0c;IP地址192.168.1.66 攻击&#xff1a;kali&#xff0c;IP地址192.168.1.16 都采用虚拟机&#xff0c;网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1/24 信息收集 使用nmap扫描端口 网站探测 访…...

Python连接和操作Elasticsearch详细指南

Python连接和操作Elasticsearch详细指南 一、服务器端配置1. 修改 Elasticsearch 配置文件2. 开放防火墙端口 二、本地 Python 连接 Elasticsearch1. 连接 Elasticsearch2. 索引操作3. 文档操作4. 搜索内容5. 聚合查询6. 批量操作 三、注意事项四、故障排除结论 Elasticsearch …...

JMeter 使用详解

JMeter 使用详解 Apache JMeter 是一款开源的性能测试工具&#xff0c;可用于对静态和动态资源&#xff08;如 Web 应用、数据库、REST API 等&#xff09;进行负载测试和性能测试。以下是 JMeter 的详细使用指南&#xff1a; 1. JMeter 安装 下载 JMeter&#xff1a; 从 Apac…...