鸿蒙开发——键值型数据库的基本使用与跨设备同步

news2025/1/19 23:16:17

1、简 述

❓ 什么是键值型数据库

键值型数据库(KV-Store)是一种非关系型数据库,其数据以“键值”对的形式进行组织、索引和存储,其中“键”作为唯一标识符。

键值型数据库适合很少数据关系和业务关系的业务数据存储。

另外,因键值型数据库在分布式场景中降低了解决数据库版本兼容问题的复杂度,和数据同步过程中冲突解决的复杂度而被广泛使用。相比于关系型数据库,更容易做到跨设备跨版本兼容。

当需要存储的数据没有复杂的关系模型,比如存储商品名称及对应价格、员工工号及今日是否已出勤等,由于数据复杂度低,更容易兼容不同数据库版本和设备类型,因此推荐使用键值型数据库持久化此类数据。

📢 使用键值型数据库时,需要注意以下几点:

    • 设备协同数据库,针对每条记录,Key的长度≤896 Byte,Value的长度<4 MB。

    • 单版本数据库,针对每条记录,Key的长度≤1 KB,Value的长度<4 MB。

    • 每个应用程序最多支持同时打开16个键值型分布式数据库。

    • 键值型数据库事件回调方法中不允许进行阻塞操作,例如修改UI组件。

    • 单个数据库最多支持注册8个订阅数据变化的回调。

    • 键值型数据库不支持应用程序自定义冲突解决策略。

2、键值型数据库的基本使用

键值型数据库的能力主要是由 @ohos.data.distributedKVStore 模块提供,实现不同设备间数据库的分布式协同能力。通过调用分布式键值数据库各个接口,应用程序可将数据保存到分布式键值数据库中,并可对分布式键值数据库中的数据进行增加、删除、修改、查询、同步等操作。

该模块提供以下分布式键值数据库相关的常用功能:

    • KVManager:分布式键值数据库管理实例,用于获取数据库的相关信息。

    • KVStoreResultSet:提供获取数据库结果集的相关方法,包括查询和移动数据读取位置等。

    • Query:使用谓词表示数据库查询,提供创建Query实例、查询数据库中的数据和添加谓词的方法。

    • SingleKVStore:单版本分布式键值数据库,不对数据所属设备进行区分,提供查询数据和同步数据的方法。

    • DeviceKVStore:设备协同数据库,继承自SingleKVStore,以设备维度对数据进行区分,提供查询数据和同步数据的方法。

以下是键值型数据库持久化功能的相关接口,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下面均以callback形式为例:

// 创建一个KVManager对象实例,用于管理数据库对象。createKVManager(config: KVManagerConfig): KVManager// 指定options和storeId,创建并得到指定类型的KVStore数据库。getKVStore<T>(storeId: string, options: Options, callback: AsyncCallback<T>): void// 添加指定类型的键值对到数据库。put(key: string, value: Uint8Array | string | number | boolean, callback: AsyncCallback<void>): void// 获取指定键的值。get(key: string, callback: AsyncCallback<boolean | string | number | Uint8Array>): void// 从数据库中删除指定键值的数据。delete(key: string, callback: AsyncCallback<void>): void// 通过storeId的值关闭指定的分布式键值数据库。closeKVStore(appId: string, storeId: string, callback: AsyncCallback<void>): void// 通过storeId的值删除指定的分布式键值数据库。deleteKVStore(appId: string, storeId: string, callback: AsyncCallback<void>): void

使用示例

👉🏻 step 1:若要使用键值型数据库,首先要获取一个KVManager实例,用于管理数据库对象。示例代码如下所示(代码13 ~ 25行):

// 导入模块import { distributedKVStore } from '@kit.ArkData';import { window } from '@kit.ArkUI';import { UIAbility } from '@kit.AbilityKit';import { BusinessError } from '@kit.BasicServicesKit';let kvManager: distributedKVStore.KVManager | undefined = undefined;export default class EntryAbility extends UIAbility {  onCreate() {    let context = this.context;    const kvManagerConfig: distributedKVStore.KVManagerConfig = {      context: context,      bundleName: 'com.example.datamanagertest'    };    try {      // 创建KVManager实例      kvManager = distributedKVStore.createKVManager(kvManagerConfig);      console.info('Succeeded in creating KVManager.');      // 继续创建获取数据库    } catch (e) {      let error = e as BusinessError;      console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`);    }  }}if (kvManager !== undefined) {   kvManager = kvManager as distributedKVStore.KVManager;  //进行后续操作  //...}

👉🏻 step 2:基于step 1创建的kvManager,我们可以创建并获取键值数据库。示例代码如下所示:​​​​​​​

let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;try {  const options: distributedKVStore.Options = {    createIfMissing: true,    encrypt: false,    backup: false,    autoSync: false,    // kvStoreType不填时,默认创建多设备协同数据库    kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,    // 多设备协同数据库:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION,    securityLevel: distributedKVStore.SecurityLevel.S1  };  kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', options, (err, store: distributedKVStore.SingleKVStore) => {    if (err) {      console.error(`Failed to get KVStore: Code:${err.code},message:${err.message}`);      return;    }    console.info('Succeeded in getting KVStore.');    kvStore = store;    // 请确保获取到键值数据库实例后,再进行相关数据操作  });} catch (e) {  let error = e as BusinessError;  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);}if (kvStore !== undefined) {  kvStore = kvStore as distributedKVStore.SingleKVStore;    //进行后续操作    //...}

👉🏻 基于step 2创建的kvStore对象,我们可以调用put()方法向键值数据库中插入数据。示例代码如下所示:​​​​​​​

const KEY_TEST_STRING_ELEMENT = 'key_test_string';const VALUE_TEST_STRING_ELEMENT = 'value_test_string';try {  kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {    if (err !== undefined) {      console.error(`Failed to put data. Code:${err.code},message:${err.message}`);      return;    }    console.info('Succeeded in putting data.');  });} catch (e) {  let error = e as BusinessError;  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);}

👉🏻 基于step 2创建的kvStore对象,我们调用get()方法获取指定键的值。示例代码如下所示:​​​​​​​

try {  kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {    if (err !== undefined) {      console.error(`Failed to put data. Code:${err.code},message:${err.message}`);      return;    }    console.info('Succeeded in putting data.');    kvStore = kvStore as distributedKVStore.SingleKVStore;    kvStore.get(KEY_TEST_STRING_ELEMENT, (err, data) => {      if (err != undefined) {        console.error(`Failed to get data. Code:${err.code},message:${err.message}`);        return;      }      console.info(`Succeeded in getting data. Data:${data}`);    });  });} catch (e) {  let error = e as BusinessError;  console.error(`Failed to get data. Code:${error.code},message:${error.message}`);}

👉🏻 基于step 2创建的kvStore对象,我们调用delete()方法删除指定键值的数据。示例代码如下所示:​​​​​​​

try {  kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {    if (err !== undefined) {      console.error(`Failed to put data. Code:${err.code},message:${err.message}`);      return;    }    console.info('Succeeded in putting data.');    kvStore = kvStore as distributedKVStore.SingleKVStore;    kvStore.delete(KEY_TEST_STRING_ELEMENT, (err) => {      if (err !== undefined) {        console.error(`Failed to delete data. Code:${err.code},message:${err.message}`);        return;      }      console.info('Succeeded in deleting data.');    });  });} catch (e) {  let error = e as BusinessError;  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);}

👉🏻 基于step 1创建的kvManager对象,我们通过storeId的值关闭指定的分布式键值数据库。示例代码如下所示:​​​​​​​

try {  kvStore = undefined;  kvManager.closeKVStore('appId', 'storeId', (err: BusinessError)=> {    if (err) {      console.error(`Failed to close KVStore.code is ${err.code},message is ${err.message}`);      return;    }    console.info('Succeeded in closing KVStore');  });} catch (e) {  let error = e as BusinessError;  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);}

👉🏻 基于step 1创建的kvManager对象,我们通过storeId的值删除指定的分布式键值数据库。示例代码如下所示:​​​​​​​

try {  kvStore = undefined;  kvManager.deleteKVStore('appId', 'storeId', (err: BusinessError)=> {    if (err) {      console.error(`Failed to close KVStore.code is ${err.code},message is ${err.message}`);      return;    }    console.info('Succeeded in closing KVStore');  });} catch (e) {  let error = e as BusinessError;  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);}

3、键值型数据库跨设备数据同步

数据管理服务提供了两种同步方式:手动同步和自动同步。键值型数据库可选择其中一种方式实现同应用跨设备数据同步。

手动同步

由应用程序调用sync接口来触发,需要指定同步的设备列表和同步模式。同步模式分为:

  • PULL_ONLY(将远端数据拉取到本端);

  • PUSH_ONLY(将本端数据推送到远端);

  • PUSH_PULL(将本端数据推送到远端同时也将远端数据拉取到本端)。

自动同步

在跨设备Call调用实现的多端协同场景中,在应用程序更新数据后,由分布式数据库自动将本端数据推送到远端,同时也将远端数据拉取到本端来完成数据同步,应用不需要主动调用sync接口。

键值型数据库分为两种类型:单版本数据库、多设备协同分布式数据库。两种类型介绍如下:

  • 单版本数据库

单版本是指数据在本地是以单个条目为单位的方式保存,当数据在本地被用户修改时,不管它是否已经被同步出去,均直接在这个条目上进行修改。

多个设备全局只保留一份数据,多个设备的相同记录(主码相同)会按时间最新保留一条记录,数据不分设备,设备之间修改相同的key会覆盖。同步也以此为基础,按照它在本地被写入或更改的顺序将当前最新一次修改逐条同步至远端设备,常用于联系人、天气等应用存储场景。

图片

  • 多设备协同分布式数据库

多设备协同分布式数据库建立在单版本数据库之上,对应用程序存入的键值型数据中的Key前面拼接了本设备的DeviceID标识符,这样能保证每个设备产生的数据严格隔离。数据以设备的维度管理,不存在冲突;支持按照设备的维度查询数据。

底层按照设备的维度管理这些数据,多设备协同数据库支持以设备的维度查询分布式数据,但是不支持修改远端设备同步过来的数据。需要分开查询各设备数据的可以使用设备协同版本数据库。常用于图库缩略图存储场景。

图片

以下是单版本键值型分布式数据库跨设备数据同步功能的相关接口,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下面均以callback形式为例。​​​​​​​

// 创建一个KVManager对象实例,用于管理数据库对象。createKVManager(config: KVManagerConfig): KVManager// 指定options和storeId,创建并得到指定类型的KVStore数据库。getKVStore<T>(storeId: string, options: Options, callback: AsyncCallback<T>): void// 插入和更新数据。put(key: string, value: Uint8Array | string | number | boolean, callback: AsyncCallback<void>): void// 订阅数据库中数据的变化。on(event: 'dataChange', type: SubscribeType, listener: Callback<ChangeNotification>): void// 查询指定Key键的值。get(key: string, callback: AsyncCallback<boolean | string | number | Uint8Array>): void// 在手动模式下,触发数据库同步。sync(deviceIds: string[], mode: SyncMode, delayMs?: number): void

使用分布式键值数据库需要申明权限:ohos.permission.DISTRIBUTED_DATASYNC,同时需要在应用首次启动时弹窗向用户申请授权

👉🏻 step 1:根据配置构造分布式数据库管理实例​​​​​​​

import { distributedKVStore } from '@kit.ArkData';import { window } from '@kit.ArkUI';import { UIAbility } from '@kit.AbilityKit';import { BusinessError } from '@kit.BasicServicesKit';let kvManager: distributedKVStore.KVManager | undefined = undefined;class EntryAbility extends UIAbility {  onWindowStageCreate(windowStage:window.WindowStage) {    let context = this.context;  }} // .... // 获取context之后,构造分布式数据库管理类实例try {  const kvManagerConfig: distributedKVStore.KVManagerConfig = {    bundleName: 'com.harmonyclassroom.datamanagertest',    context: context  }  kvManager = distributedKVStore.createKVManager(kvManagerConfig);  console.info('Succeeded in creating KVManager.');  // todo 继续创建获取数据库} catch (e) {  let error = e as BusinessError;  console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`);}if (kvManager !== undefined) {  kvManager = kvManager as distributedKVStore.KVManager;  // 进行后续创建数据库等相关操作  // ...}

👉🏻 step 2:获取并得到指定类型的键值型数据库。

    1. 声明需要创建的分布式数据库ID描述(例如示例代码中的'storeId')。

    2. 创建分布式数据库,建议关闭自动同步功能(autoSync:false),方便后续对同步功能进行验证,需要同步时主动调用sync接口

let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;try {  let child1 = new distributedKVStore.FieldNode('id');  child1.type = distributedKVStore.ValueType.INTEGER;  child1.nullable = false;  child1.default = '1';  let child2 = new distributedKVStore.FieldNode('name');  child2.type = distributedKVStore.ValueType.STRING;  child2.nullable = false;  child2.default = 'zhangsan';  let schema = new distributedKVStore.Schema();  schema.root.appendChild(child1);  schema.root.appendChild(child2);  schema.indexes = ['$.id', '$.name'];  // 0表示COMPATIBLE模式,1表示STRICT模式。  schema.mode = 1;  // 支持在检查Value时,跳过skip指定的字节数,且取值范围为[0,4M-2]。  schema.skip = 0;  const options: distributedKVStore.Options = {    createIfMissing: true,    encrypt: false,    backup: false,    autoSync: false,    // kvStoreType不填时,默认创建多设备协同数据库    // 多设备协同数据库:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION,    kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,    // schema 可以不填,在需要使用schema功能时可以构造此参数,例如:使用谓词查询等。    schema: schema,    securityLevel: distributedKVStore.SecurityLevel.S1  };  kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', options, (err, store: distributedKVStore.SingleKVStore) => {    if (err) {      console.error(`Failed to get KVStore: Code:${err.code},message:${err.message}`);      return;    }    console.info('Succeeded in getting KVStore.');    kvStore = store;    // 请确保获取到键值数据库实例后,再进行相关数据操作  });} catch (e) {  let error = e as BusinessError;  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);}if (kvStore !== undefined) {  kvStore = kvStore as distributedKVStore.SingleKVStore;    // 进行后续相关数据操作,包括数据的增、删、改、查、订阅数据变化等操作    // ...}

👉🏻 step 3:订阅分布式数据变化

如需关闭订阅分布式数据变化,调用off('dataChange')关闭。​​​​​​​

try {  kvStore.on('dataChange', distributedKVStore.SubscribeType.SUBSCRIBE_TYPE_ALL, (data) => {    console.info(`dataChange callback call data: ${data}`);  });} catch (e) {  let error = e as BusinessError;  console.error(`An unexpected error occurred. code:${error.code},message:${error.message}`);}

👉🏻 step 4:将数据写入分布式数据库。

    1. 构造需要写入分布式数据库的Key(键)和Value(值)。

    2. 将键值数据写入分布式数据库

const KEY_TEST_STRING_ELEMENT = 'key_test_string';// 如果未定义Schema则Value可以传其他符合要求的值。const VALUE_TEST_STRING_ELEMENT = '{"id":0, "name":"lisi"}';try {  kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {    if (err !== undefined) {      console.error(`Failed to put data. Code:${err.code},message:${err.message}`);      return;    }    console.info('Succeeded in putting data.');  });} catch (e) {  let error = e as BusinessError;  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);}

👉🏻 step 5:查询分布式数据库数据。

    1. 构造需要从单版本分布式数据库中查询的Key(键)。

    2. 从单版本分布式数据库中获取数据

try {  kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {    if (err !== undefined) {      console.error(`Failed to put data. Code:${err.code},message:${err.message}`);      return;    }    console.info('Succeeded in putting data.');    kvStore = kvStore as distributedKVStore.SingleKVStore;    kvStore.get(KEY_TEST_STRING_ELEMENT, (err, data) => {      if (err != undefined) {        console.error(`Failed to get data. Code:${err.code},message:${err.message}`);        return;      }      console.info(`Succeeded in getting data. Data:${data}`);    });  });} catch (e) {  let error = e as BusinessError;  console.error(`Failed to get data. Code:${error.code},message:${error.message}`);}

👉🏻 step 6:同步数据到其他设备。

选择同一组网环境下的设备以及同步模式(需用户在应用首次启动的弹窗中确认选择同步模式),进行数据同步。​​​​​​​

import { distributedDeviceManager } from '@kit.DistributedServiceKit'; let devManager: distributedDeviceManager.DeviceManager;try {  // create deviceManager  devManager = distributedDeviceManager.createDeviceManager(context.applicationInfo.name);  // deviceIds由deviceManager调用getAvailableDeviceListSync方法得到  let deviceIds: string[] = [];  if (devManager != null) {    let devices = devManager.getAvailableDeviceListSync();    for (let i = 0; i < devices.length; i++) {      deviceIds[i] = devices[i].networkId as string;    }  }  try {    // 1000表示最大延迟时间为1000ms    kvStore.sync(deviceIds, distributedKVStore.SyncMode.PUSH_ONLY, 1000);  } catch (e) {    let error = e as BusinessError;    console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);  }} catch (err) {  let error = err as BusinessError;  console.error("createDeviceManager errCode:" + error.code + ",errMessage:" + error.message);}
在手动同步的方式下,其中的deviceIds通过调用devManager.getAvailableDeviceListSync方法得到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2255906.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32一keil5更换芯片后报错问题的解决。

目录 一、STM32型号认识二、报错问题三、常用的启动配置文件四、问题解决 一、STM32型号认识 二、报错问题 当我们在原来工程下修改芯片时&#xff0c;原本可以编译通过的代码突然很多报错。如下所示&#xff0c;这是因为我们的启动文件配置错误。对于不同型号的芯片其flash容量…

CentOS安装Nginx并配置为系统服务

前言 Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器 [13]&#xff0c;同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.ru站点&#xff08;俄文&#xff1a;Рамблер&#xff09;开发的&#xff0c;公开版本1.19.6发布…

部署loki,grafana 以及springcloud用法举例

文章目录 场景docker 部署grafanadocker-compose部署loki维护配置文件 local-config.yaml维护docker-compose.yml配置启动 grafana 添加loki数据源springcloud用法举例查看loki的explore,查看日志 场景 小公司缺少运维岗位&#xff0c;需要研发自己部署日志系统&#xff0c;elk…

快速学习selenium基础操作

全篇大概19000字&#xff08;含代码&#xff09;&#xff0c;建议阅读时间1h 什么是Selenium&#xff1f; Selenium是一系列自动化工具集的统称&#xff0c;官方工具有 Selenium IDE、Selenium WebDriver、Selenium Grid&#xff0c; 主要用于桌面端Web应用程序的自动化。能够通…

使用uniapp开发小程序场景:在百度地图上调用接口返回的设备相关信息并展示

首先在百度地图开发者平台注册微信小程序开发密钥下载百度地图SDK-bmap-wx.min.js,下载地址在项目入口index.html页面进行引入页面中进行调用&#xff0c;代码示例如下<map id"map" longitude"108.95" latitude"34.34" scale"3" :m…

SPI驱动模型框架及spidev.c分析---学习记录

目录 SPI设备如何使用 SPI驱动模型框架 SPI 控制器/SPI Master分析 SPI 设备端/SPI Slave分析 SPI 控制器/SPI Master与SPI 设备端/SPI Slave驱动模型 Linux内核自带的SPI 设备端/SPI Slave代码spidev.c 小结 SPI设备如何使用 一般我们使用spi设备驱动是类似文件操作&#xff0…

WordPress XStore Elementor 前端与编辑器内容不同步的问题

最近在新站更换成XStore的Elementor模板后&#xff0c;在编辑器修改完的内容前端网页部分没有同步&#xff0c;一开始清除了缓存没有解决。后面尝试重新安装也还是存在这个问题。 后续又在服务器上删除了Elementor插件缓存文件&#xff0c;问题依然存在。 最后通过在Elemento…

第四届全国过程模拟与仿真大会召开,积鼎科技相伴大会6年成长

第四届全国过程模拟与仿真学术会议于2024年11月29日-12月2日在广州圆满召开。积鼎科技&#xff0c;作为自主流体仿真软件研发的领航企业&#xff0c;与大会相伴四年&#xff0c;自首届以来一直积极参与其中&#xff0c;见证了大会从初创到逐渐壮大的全过程。每一次参会&#xf…

SAP导出表结构并保存到Excel 源码程序

SAP导出表结构并保存到Excel,方便写代码时复制粘贴 经常做接口,需要copy表结构,找到了这样一个程程,特别有用。 01. 先看结果

Hadoop生态圈框架部署 伪集群版(四)- Zookeeper单机部署

文章目录 前言一、Zookeeper单机部署&#xff08;手动部署&#xff09;1. 下载Zookeeper安装包到Linux2. 解压zookeeper安装包3. 配置zookeeper配置文件4. 配置Zookeeper系统环境变量5. 启动Zookeeper6. 停止Zookeeper在这里插入图片描述 注意 前言 本文将详细介绍Zookeeper的…

文件IO——01

1. 认识文件 1&#xff09;文件概念 “文件”是一个广义的概念&#xff0c;可以代表很多东西 操作系统里&#xff0c;会把很多的硬件设备和软件资源抽象成“文件”&#xff0c;统一管理 但是大部分情况下的文件&#xff0c;都是指硬盘的文件&#xff08;文件相当于是对“硬…

Spring完整知识点二

Spring注解开发 Spring是轻代码而重配置的框架&#xff0c;配置比较繁重&#xff0c;影响开发效率&#xff0c;所以注解开发是一种趋势&#xff0c;它能够代替xml配置文件&#xff0c;可以简化配置&#xff0c;提高开发效率Spring注解根据出现时间分类 Spring原始注解&#xf…

阻塞队列详解

阻塞队列介绍 队列 是限定在一端进行插入&#xff0c;另一端进行删除的特殊线性表。先进先出(FIFO)线性表。允许出队的一端称为队头&#xff0c;允许入队的一端称为队尾。 数据结构演示网站&#xff1a; https://www.cs.usfca.edu/~galles/visualization/Algorithms.html Q…

使用Java将PDF文件解析成Excel文件

安装pom依赖 <!-- 解析pdf--><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.27</version> <!-- 请检查并使用最新版本 --></dependency>测试读取pdf文件…

web前端设计1

熟悉流行框架、熟练掌握CSS的写法&#xff0c;以及JAVASCRIPT库的应用&#xff0c;最主要的是能按要求改出相应的界面&#xff0c;因为我们基本没有自己手写代码的&#xff0c;所以得会拿别的界面改成想要的界面。 前端比较吃能力的就是CSS的写法&#xff0c;如何用已写好的框…

贪心算法part05

文章参考来源代码随想录 (programmercarl.com) 56. 合并区间 本题和前几题类似&#xff0c;都是判断上一个元素的右边界与当前元素的左边界大小关系 但是需要注意是&#xff1a;本题需要更新结果数组元素的右边界&#xff0c;因此比较的是数组最后一个元素右边界与当前元素左…

EasyAnimateV5 视频生成大模型原理详解与模型使用

在数字内容创作中&#xff0c;视频扮演的角色日益重要。然而&#xff0c;创作高质量视频通常耗时且昂贵。EasyAnimate 系列旨在利用人工智能技术简化这一过程。EasyAnimateV5 建立在其前代版本的基础之上&#xff0c;不仅在质量上有所提升&#xff0c;还在多模态数据处理和跨语…

【大语言模型】LangChain LCEL 表达式语言

【大语言模型】LangChain LCEL 表达式语言 一、简介二、LCEL的优势三、LCEL 的基本使用1、Runnable 对象 四、实战实例 一、简介 LangChain LCEL 的全称为 LangChain Expression Language 即可直译为 LangChain 表达式。 为了构造更复杂的 LLM 应用并且更为简便快捷的构造 LLM…

java中的递归

大家好&#xff0c;今天我们来学习一下java中的递归&#xff0c;相信大家应该也对递归有一点了解吧&#xff0c;如果没有也没有关系&#xff0c;我们现在就来了解一下。 五、递归 自身中包含了自己,遇到的问题直接并不好解决,但是发现将原问题拆分成其子问题之后,子问题与原问…

【pyspark学习从入门到精通23】机器学习库_6

目录 分割连续变量 标准化连续变量 分类 分割连续变量 我们经常处理高度非线性的连续特征&#xff0c;而且只用一个系数很难拟合到我们的模型中。 在这种情况下&#xff0c;可能很难只通过一个系数来解释这样一个特征与目标之间的关系。有时&#xff0c;将值划分到离散的桶中…