influxDB 时序数据库安装 flux语法 restful接口 nodjsAPI

安装

Install InfluxDB | InfluxDB OSS v2 Documentation

Debian和Ubuntu用户可以用apt-get包管理来安装最新版本的InfluxDB。

对于Ubuntu用户,可以用下面的命令添加InfluxDB的仓库,添加之后即可apt-get 安装influxdb2

wget -q https://repos.influxdata.com/influxdata-archive_compat.key
echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo apt-get update && sudo apt-get install influxdb2

通过yum/apt-get安装的软件基本都可以用systemctl命令(也可自行配置到systemctl中)

systemctl start influxdb  //如果你的系统不支持Systemd:service influxdb2 start

influxd version

生成API Token:

访问http://localhost:8086/

用户名ecmaster 密码 xxxxxxx      org:ecmaster      bucket:ecmaster

默认的ecmaster bucket存在一些系统参数,故新建一个ecsmart bucket存储桶。

进入系统后创建bucket(存储桶是存储时间序列数据):ecsmart

进入API Token,复制token 替换项目文件backend/setting.js中的token

influxdb配置文件默认在: /etc/influxdb/config.toml (修改配置文件位置: export INFLUXD_CONFIG_PATH=/path/to/custom/config/directory)
query-max-memory-bytes = 10737418240 //设置总查询内存最大为10G 默认是无限制

在InfluxDB中实现多用户隔离,通常是通过组织(Org)和存储桶(Bucket)的组合来处理的。

使用组织(Org)可以实现对用户的逻辑隔离,每个用户可以被分配到一个具体的组织,并且不同组织之间的数据是隔离的。这样可以确保不同用户之间的数据相互隔离,各自在独立的组织中进行管理和访问。

使用存储桶(Bucket)可以进一步细分和隔离不同类型或不同权限要求的数据。每个组织可以创建多个存储桶,用于逻辑上组织和隔离不同类型的数据。可以为每个用户创建独立的存储桶,确保他们的数据在存储桶层面上进行隔离和管控。

综合来说,组织用于逻辑上隔离不同用户,每个用户在独立的组织中进行管理;存储桶用于进一步隔离不同类型或不同权限要求的数据,确保数据在存储桶层面上进行隔离和管理。通过组织和存储桶的组合使用,可以实现更细粒度、更灵活的多用户隔离和数据管理。

基本概念

时序数据库特点是写多读少相对于传统数据库新增和查询多,基本没有更新和删除。常用的一种使用场景:监控数据统计。每毫秒记录一下电脑内存的使用情况,然后就可以根据统计的数据,利用图形化界面制作内存使用情况的折线图;可以理解为按时间记录一些数据(常用的监控数据、埋点统计数据等),然后制作图表做统计。

数据的修改和删除:

1.InfluxDB 不支持对已有的数据进行直接修改。相反,它采用覆盖写入(overwrite)的方式来实现近似的修改效果。使用INSERT语句将修改后的数据重新写入,并确保时间戳与原始数据相同。

2-1.数据保存策略retention policy可指定数据保留时间,超过指定时间,就删除这部分数据。

2-2.可以使用 DELETE 语句来删除指定时间范围内的数据。DELETE FROM measurement_name WHERE time > '2023-06-28' AND time < '2023-06-30'

支持类sql查询语句,但推荐使用2.0的flux语句

1.organization:InfluxDB组织是一组用户的工作区。所有仪表板、任务、存储桶和用户都属于一个组织。

2.bucket:数据桶(即database数据库+Retention Policy保留策略),所有 InfluxDB 数据都存储在一个存储桶中。

2-1.retention policy:存储策略,用于设置数据保留的时间、集群中存放副本数量以及shard group覆盖的时间范围。每个数据库刚开始会自动创建一个默认的存储策略 autogen,数据保留时间为永久,副本数量为1,shard group持续时间为7天,之后用户可以自己设置。InfluxDB 会定期清除过期的数据。

3.measurement:类似mysql中表

4.column: tag(带索引的,非必须)、field(不带索引)、timestemp(唯一主键)

5.Point表里的一行数据InfluxDB 中单条插入语句的数据结构。由同一时间戳(time)、数据(field)集合和标签(tags)集合组成。

INSERT 系统监控 ,device=CPU,variable=数量 系统监控.CPU.数量=2

insert measurement,tag=value,tag=value field=value,field=value

_measurement _time _start _end _field _value为内置字段。

6.Seriesseries 相当于是 InfluxDB 中一些数据的集合,在同个 bucket 中,retention policy、measurement、tag完全相同的数据同属于一个 series,同个series的数据在物理上会按照时间顺序排列存储在一起。

series的key为measurement + 所有 tags 的序列化字符串,这个key在之后会经常用到

下面这些概念了解即可:

7.Shard shard是在 tsm 存储引擎之上的一个概念。在 InfluxDB 中按照数据的时间戳所在的范围,会去创建不同的 shard(比如RP保留时间为24小时每个shard就保存1小时的数据),每一个 shard 都有自己的 cache、wal、tsm file 以及 compactor,这样做的目的就是为了可以通过时间来快速定位到要查询数据的相关资源,加速查询的过程,并且也让之后的批量删除数据的操作变得非常简单且高效。

每个shard有且只有一个shard group。 单个shard group中可能存在多个shard。 每个shard包含特定的series集合。

7-1.Shard duration 决定了每个shard group的时间跨度。具体由retention policy的 SHARD DURATION决定

7-2.Shard groupshard group按照time、retention policy进行组织。每个包含数据的retention policy至少有一个关联的shard group。给定的shard group包含时间区间内所有shard数据。 每个shard group跨越的间隔是shard duration。

8.Continuous Query

CQ 是预先配置好的一些查询命令,定期自动执行这些命令并将查询结果写入指定的 measurement 中,这个功能主要用于数据聚合

注意

在influxdb中,字段必须存在。因为字段是没有索引的。如果使用字段作为查询条件,会扫描符合查询条件的所有字段值,性能不及tag。类比一下,fields相当于SQL的没有索引的列。tags是可选的,但是强烈建议你用上它,因为tag是有索引的,tags相当于SQL中的有索引的列。

tag 只能为字符串类型

field 类型无限制

不支持join

存储引擎

存储引擎(TSM)

InfluxDB存储引擎看起来非常类似于LSM树。它主要由cache、wal、tsm file、compactor组成。

Cache

cache是当前存储在WAL中的所有数据的内存副本。point由metric,tag和唯一字段组成。每个字段保持其自己的时间有序范围。cache中的数据未被压缩。对存储引擎的查询将合并Cache和TSM中的数据。

当influxDB启动时,会遍历所有的wal文件,重新构造cache,这样即使系统出现故障,也不会导致数据的丢失。

Wal(Write Ahead Log)

wal的内容与cache相同,其作用就是为了持久化数据,当系统崩溃后可以通过wal文件恢复还没有写入到tsm文件中的数据。

由于数据是被顺序插入到wal文件中,所以写入效率非常高。但是如果写入的数据没有按照时间顺序排列,而是以杂乱无章的方式写入,数据将会根据时间路由到不同的shard中,每一个shard都有自己的wal文件,这样就不再是完全的顺序写入,对性能会有一定影响。官方社区有说后续会进行优化,只使用一个 wal,而不是为每一个shard 创建 wal。

wal单个文件达到一定大小后会进行分片,创建一个新的wal分片文件用于写入数据。

TSM file

TSM文件是内存映射的只读文件的集合。 这些文件的结构看起来与LevelDB或其他LSM树变体中的SSTable非常相似。

一个TSM文件由4个区域组成:header,blocks,index,footer

Compactor

compactor是一个持续的过程,优化存储,提升查询性能,具体做以下几件事:

将已关闭的WAL文件转换为TSM文件并删除已关闭的WAL文件

将较小的TSM文件合并为较大的文件以提高压缩率

删除series data

写入最新的数据,确保TSM文件中point的唯一性。

influxdb-cli & restful接口

mac安装:

brew install influxdb-cli

influx config create --config-name onboarding \--host-url "http://10.1.1.115:8086" \--token "zTQfDoeRo6C92S_6qjIhvq4KlDp9o-a8wgTMOCBY5Qb-DYVL4WIKr533QtbLgebwLmxtnYscFrR_9fCEEbsvmw==" \--active
influx config list  
influx config delete onboarding

org相关操作:

influx org list 查询 默认limit只显示20个。

influx org list --name pppp_ecmaster //超过20个指定name可查询到

influx org delete -i 07668febbebcbbbd //删除org -i 指定id

bucket相关操作

influx bucket list -o undefined_ecmaster //查看指定org的bucket

influx bucket delete -i 6d10e05825be0228 -o undefined_ecmaster

API Token相关操作

influx auth list -o ecmaster //查看指定org的APIToken

user相关操作

influx user list  查询 默认limit只显示20个

influx user list --name pppp_ecmaster //超过20个 指定name才可查询到

influx user delete -i 0ba14fd3b1efe000 //删除用户 指定id

读写数据

influx write --bucket undefined_ecmaster -o undefined_ecmaster  --url https://influx-testdata.s3.amazonaws.com/air-sensor-data-annotated.csv //往bucket中写入数据

influx query -o undefined_ecmaster 'from(bucket:"undefined_ecmaster") |> range(start:-1d,stop:-1ms)' //读取数据

curl方式调用

查询org
curl --request GET "10.1.1.115:8086/api/v2/orgs" \

    --header "Authorization: Token zTQfDoeRo6C92S_6qjIhvq4KlDp9o-a8wgTMOCBY5Qb-DYVL4WIKr533QtbLgebwLmxtnYscFrR_9fCEEbsvmw=="

新增 org

curl --request POST "http://10.1.1.115:8086/api/v2/orgs" \

  --header "Authorization: Token zTQfDoeRo6C92S_6qjIhvq4KlDp9o-a8wgTMOCBY5Qb-DYVL4WIKr533QtbLgebwLmxtnYscFrR_9fCEEbsvmw==" \

  --header "Accept: application/json" \

  --header "Content-Type: application/json" \

  --data '{"name": "personal_ecmaster1" }'

删除org

curl --request DELETE "10.1.1.115:8086/api/v2/orgs/f70722a047489640" \

    --header "Authorization: Token zTQfDoeRo6C92S_6qjIhvq4KlDp9o-a8wgTMOCBY5Qb-DYVL4WIKr533QtbLgebwLmxtnYscFrR_9fCEEbsvmw=="

文档:https://docs.influxdata.com/influxdb/v2/api/#operation/DeleteAuthorizationsID

nodejs 操作influxdb

const { OrgsAPI, BucketsAPI, UsersAPI, AuthorizationsAPI } = require( '@influxdata/influxdb-client-apis');
const { InfluxDB } = require('@influxdata/influxdb-client');创建 org user APIToken
const url = `http://${influxHost}:${influxPort}`;
const token = 'zTQfDoeRo6C92S_6qjIhvq4KlDp9o-a8wgTMOCBY5Qb-DYVL4WIKr533QtbLgebwLmxtnYscFrR_9fCEEbsvmw==';
const influxDB = new InfluxDB({url, token});const name = `ecmaster`; //orgName// org create
const orgsAPI = new OrgsAPI(influxDB);
const organization = await orgsAPI.postOrgs({body: {name}});
const orgID = organization.id;//bucket create
const bucketsAPI = new BucketsAPI(influxDB);
const bucket = await bucketsAPI.postBuckets({body: {orgID, name }});// user create
const usersAPI = new UsersAPI(influxDB);
const user = await usersAPI.postUsers({body: {name}});
const userID = user.id;
const password = uuid.v4();
await usersAPI.postUsersIDPassword({userID, body: {password}});
await orgsAPI.postOrgsIDOwners({ orgID, body: { id: user.id } }); // 当前orgID的所有者,拥有此org中所有资源的权限,没有org的write权限。 此用户登陆web界面创建的API Token分配的资源权限均是此org的。//APIToken create
const authorizationsAPI = new AuthorizationsAPI(influxDB);
const apiToken = await authorizationsAPI.postAuthorizations({ body : {orgID, userID: user.id, permissions: [{"action": "read","resource": {"orgID": `${orgID}`,"type": "authorizations"}},{"action": "read","resource": {"orgID": `${orgID}`,"type": "buckets"}},{"action": "read","resource": {"orgID": `${orgID}`,"type": "users"}},{"action": "write","resource": {"orgID": `${orgID}`,"type": "buckets"}}
]}
});
API Token相关参数解释:
// name 可选: 如果设置了名称,则是该名称的资源的权限。如果未设置,则为该资源类型的所有资源的权限。
// id 可选: 如果设置了 ID,则是 该 ID 资源的权限。如果未设置,则为该资源类型的所有资源的权限。
//orgID 可选: 如果设置了 orgID,则这是该orgID组织拥有的所有资源的权限。如果未设置,则为该资源类型的所有资源的权限。
//type 必填: "authorizations" "buckets" "dashboards" "orgs" "sources" "tasks" "telegrafs" "users" "variables" "scrapers" "secrets" "labels" "views" "documents" "notificationRules" "notificationEndpoints" "checks" "dbrp" "notebooks" "annotations" "remotes" "replications"const influxSetting= {org: organization.name,bucket: bucket.name,url,token: apiToken.token,username: user.name,password: password
}    
console.log(influxSetting);清除influxdb org user APIToken
async function influxDBClear(){const url = `http://${influxHost}:${influxPort}`;const token = `${influxAdminToken}`;const influxDB = new InfluxDB({url, token});const name = `${serviceName}_ecmaster`;// org delete  删除org之后 bucket APIToken 无const orgsAPI = new OrgsAPI(influxDB);const orgs = (await orgsAPI.getOrgs({org: name})).orgs;//默认只显示20条。指定orgName检索for(const org of orgs){await orgsAPI.deleteOrgsID({orgID: org.id});}// user createconst usersAPI = new UsersAPI(influxDB);const users = (await usersAPI.getUsers({name: username})).users;//默认只显示20条。// console.log(users, name);for(const user of users){await usersAPI.deleteUsersID({userID: user.id});}console.log('influxDB 清除完成');
}

flux函数库

Flux作为一个独立于InfluxDB的代码库,因为它将拥有自己的开源生命周期,无论你是否使用InfluxDB,它都是有用的。为此,我们采用了MIT许可,并接受将Flux与第三方系统进行集成的拉取请求,即使这些系统可能是InfluxDB的竞争对手。

每个 Flux 查询都需要以下内容:

1.数据源

from(bucket:"example-bucket")

  1. 时间范围

start 值和stop 值可以使用负持续时间是相对值,也可以是使用时间戳的绝对值。

|> range(start: -1h)

|> range(start: 2021-01-01T00:00:00Z, stop: 2021-01-01T12:00:00Z)

注意:influxdb事件默认是utc格式。start:0 表示查所有数据

3.数据过滤器

 |> filter(fn: (r) => (r._measurement == "cpu") and (r._field != "usage_system" ) )

过滤出cpu表且filed!=usage_system的数据

4.开窗函数

|> aggregateWindow(every: 1d, fn: last,createEmpty:true)  //开窗函数,按1天开窗,取1天内的last值。开窗处理后Row为一天的最后一条数据。createEmpty: 是否显示空数据行

开窗前:每个Row的_time为精确到毫秒时间戳

开窗后:每个Row的_time为精确到天的时间戳

5.排序

|> sort(columns:["_time"], desc: true)

6.限制数量

|> limit(n:1)

7.yield函数
Flux 的yield()函数将过滤后的表作为查询结果输出。

Flux 会yield()在每个脚本的末尾自动假设一个函数,以便输出和可视化数据。yield()只有在同一个 Flux 查询中包含多个查询时,才需要显式调用。

from(bucket:"example-bucket")

  |> range(start: -15m)

  |> filter(fn: (r) =>   r._measurement == "cpu" )

  |> yield()

完整demo:

from(bucket: "ecsmart")

|> range(start: -0, stop: -1ns)   //start:0 表示查所有数据

|> filter(fn: (r) => r["_measurement"] == "正晨冷热源站")

|> filter(fn: (r) => r["variableID"] == "冷热源系统.冷热站.1号冷热站.室外温度")

|> drop(columns: ["_start","_stop","_field","device","deviceID","variable","variableID"])

|> aggregateWindow(every: 1d, fn: last)  //开窗函数,按1天开窗,取1天内的last值。开窗处理后Row为一天的最后一条数据,_time精确到天

|> yield(name: "last")

自定义函数

普通函数

例如:

squared = (x) => x*x  //square(x:3)  Returns 9

from(bucket: "ecsmart")

|> range(start: v.timeRangeStart, stop: v.timeRangeStop)

|> filter(fn: (r) => r["_measurement"] == "正晨冷热源站")

|> filter(fn: (r) => r["device"] == "1#C4用户侧循环水泵")

|> map(fn: (r) => ({ _value: squared(x: r._value)}))

转换函数 (<-)

转换是一个函数,它将流作为输入,对输入进行操作,然后输出新的流。

管道转发运算符 |> 将数据从先前的标识符或函数转发到转换函数中。

语法:

函数 x() 接收管道转发的数据并将其分配给 t 参数。

x = (t=<-) => t |> //...

例如:以下示例定义了一个 myFn 函数,该函数将每个输入行的 _value 列乘以 x 参数。 该示例使用 map() 函数遍历每一行,修改 _value,然后返回更新后的行

import "influxdata/influxdb/sample"

myFn = (tables=<-, x) =>

  tables

    |> map(fn: (r) => ({r with  _value: r._value * x}))

// 空气传感器样本数据

a = sample.data(set: "airSensor")

  |> range(start: -1h)

  |> filter(fn: (r) => r["_measurement"] == "airSensors")

  |> keep(columns: ["_value", "sensor_id"])  

  |> myFn(x: 10.0)

influxQL 类sql查询

使用InfluxQL(一种类似SQL的查询语言)与InfluxDB交互,查询和分析您的时间序列数据。

比如:SELECT field_key FROM measurement_name

详细见官方教程: Query data with InfluxQL | InfluxDB OSS v2 Documentation

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

丹摩征文活动|丹摩智算平台使用指南

目录 1. 登录平台与工作环境设置1.1 访问与登录1.2 创建或选择项目1.3 初始化项目环境 2. 数据上传与管理2.1 数据上传2.2 数据管理与预处理2.3 数据可视化 3. 模型构建与训练3.1 模型选择3.2 参数配置3.3 模型训练与评估 4. 模型部署与应用4.1 模型部署4.2 接口调用与集成4.3 …

NAT网络工作原理和NAT类型

NAT基本工作流程 通常情况下&#xff0c;某个局域网中&#xff0c;只有路由器的ip是公网的&#xff0c;局域网中的设备都是内网ip&#xff0c;内网ip不具备直接与外部应用通信的能力。 处于内网的设备如何借助NAT来实现访问外网的应用&#xff1f; 对于开启了NAT功能的局域网…

LLMs 如何处理相互矛盾的指令?指令遵循优先级实验

编者按&#xff1a;想象一下&#xff0c;你正在开发一个 AI 助手&#xff0c;突然发现 system message 和用户提示词存在冲突&#xff0c;这时 AI 会听谁的&#xff1f;这种情况不仅困扰着开发者&#xff0c;还可能导致 AI 系统的不稳定和不可预测&#xff0c;影响用户体验和系…

qt QProcess详解

1、概述 QProcess是Qt框架提供的一个类&#xff0c;它用于在应用程序中执行外部进程。QProcess提供了一系列函数来启动、控制和与外部进程进行交互&#xff0c;使得开发者能够在自己的应用程序中集成和调用其他程序或服务。这个类在需要执行系统命令、启动其他应用程序或进行文…

Appium配置2024.11.12

百度得知&#xff1a;谷歌从安卓9之后不再提供真机layout inspector查看&#xff0c;仅用于支持ide编写的app调试用 所以最新版android studio的android sdk目录下已经没有了布局查看工具... windows x64操作系统 小米k30 pro手机 安卓手机 Android 12 第一步&#xff1a…

《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明

参考 《element plus 使用 icon 图标(两种方式)》使用 icon 升级 Vue2 升级 Vue3 项目时&#xff0c;遇到命名时的实心与空心点差异&#xff01; ElementUI&#xff1a; 实心是 el-icon-more空心是 el-icon-more-outline ElementPlus&#xff1a; 实心是 el-icon-more-fill…

WebSocket和HTTP协议的性能比较与选择

WebSocket和HTTP协议的性能比较与选择 引言&#xff1a; 在web应用开发中&#xff0c;无论是实时聊天应用、多人在线游戏还是实时数据传输&#xff0c;网络连接的稳定性和传输效率都是关键要素之一。目前&#xff0c;WebSocket和HTTP是两种常用的网络传输协议&#xff0c;它们…

【数据结构与算法】第11课—数据结构之选择排序和交换排序

文章目录 1. 选择排序1.1 直接选择排序1.2 堆排序 2. 交换排序2.1 冒泡排序2.2 快速排序(找基准值法1----Hoare版本)2.2.1 特殊场景12.2.2 特殊场景22.2.3 代码2.2.4 快速排序的时间复杂度 2.3 快速排序(找基准值法2---挖坑法)2.3.1 特殊情况1处理2.3.2 特殊情况2处理 2.4 快速…

MySQL技巧之跨服务器数据查询:进阶篇-从A数据库复制到B数据库的表中

MySQL技巧之跨服务器数据查询&#xff1a;进阶篇-从A数据库复制到B数据库的表中 基础篇已经描述&#xff1a;借用微软的SQL Server ODBC 即可实现MySQL跨服务器间的数据查询。 而且还介绍了如何获得一个在MS SQL Server 可以连接指定实例的MySQL数据库的连接名: MY_ODBC_MYSQ…

UVC 输出视频格式修改和windows下数据分析

文章目录 前言一、UVC MJPEG视频帧描述符1.MJPG视频帧格式示例 二、UVC YUV2、NV12、M420、I420无压缩视频帧描述符GUID1.如YUV2数据参数初始为: 三、UVC Windows下UVC摄像头数据分析总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 项目需要&#…

大数据开发面试宝典

312个问题&#xff0c;问题涵盖广、从自我介绍到大厂实战、19大主题&#xff0c;一网打尽、真正提高面试成功率 一、Linux 1. 说⼀下linux的常⽤命令&#xff1f; 说一些高级命令即可 systemctl 设置系统参数 如&#xff1a;systemctl stop firewalld关闭防火墙 tail / hea…

更改Ubuntu22.04锁屏壁纸

更改Ubuntu22.04锁屏壁纸 sudo apt install gnome-shell-extensions gnome-shell-extension-manager安装Gnome Shell 扩展管理器后&#xff0c;打开“扩展管理器”并使用搜索栏找到“锁屏背景”扩展

GxtWaitCursor:Qt下基于RAII的鼠标等待光标类

有时我们需要以阻塞的方式执行一点耗时的操作&#xff0c;这时需要主窗口光标呈现忙状态&#xff0c;GxtWaitCursor正是为此设计&#xff1b;重载的构造函数&#xff0c;可以让光标呈现忙状态一定时间后自动恢复。 GxtWaitCursor.h #pragma once#include <QObject>// // …

Unity3D实现视频和模型融合效果

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、效果展示如下👉二、VideoPlayer播放视频(一)👉2-1、Hieraechy面板右键创建videoPlayer👉2-2、Assets面板右键创建RenderTexture👉2-3、把设置好的RenderTexture拖到videoPlayer里面还有本地视频视频�…

探索Pillow库:Python图像处理的瑞士军刀

文章目录 **探索Pillow库&#xff1a;Python图像处理的瑞士军刀**1. 背景&#xff1a;为何选择Pillow&#xff1f;2. Pillow是什么&#xff1f;3. 如何安装Pillow&#xff1f;4. 五个简单的库函数使用方法4.1 打开图像4.2 显示图像4.3 转换图像格式4.4 调整图像大小4.5 旋转图像…

HelloMeme 上手即用教程

HelloMeme是一个集成空间编织注意力的扩散模型&#xff0c;用于生成高保真图像和视频。它提供了一个代码库&#xff0c;包含实验代码和预训练模型&#xff0c;支持PyTorch和FFmpeg。用户可以通过简单的命令行操作来生成图像和视频。 本文将详细介绍&#xff0c;如何在GPU算力租…

JVM详解:JVM的系统架构

计算机语言大致可以分为两类&#xff0c;一直是编译性语言&#xff0c;典型的如C&#xff0c;他会先有编译器编译成可执行文件&#xff08;操作系统可读&#xff0c;不同的操作系统需要编译成不同的可执行文件&#xff09;&#xff0c;而另一种则是翻译性语言&#xff0c;这种语…

21. Drag-Drop拖放操作(二) - 文件、表格和树的拖放实现

本了继上节内容&#xff0c;讲述几种常用的拖放场景示例&#xff0c;包括文件、表格和树的拖放实现。 文件拖放 实现从系统目录拖放文件到App中。 自定义接收视图 自定义应用内部接收拖放的view视图类FileDragView&#xff0c;注册拖放类型&#xff0c;实现目标拖放协议NS…

力扣515:在每个树行中找最大值

给定一棵二叉树的根节点 root &#xff0c;请找出该二叉树中每一层的最大值。 示例1&#xff1a; 输入: root [1,3,2,5,3,null,9] 输出: [1,3,9]示例2&#xff1a; 输入: root [1,2,3] 输出: [1,3]提示&#xff1a; 二叉树的节点个数的范围是 [0,104]-231 < Node.val &l…

vivo 游戏中心包体积优化方案与实践

作者&#xff1a;来自 vivo 互联网大前端团队- Ke Jie 介绍 App 包体积优化的必要性&#xff0c;游戏中心 App 在实际优化过程中的有效措施&#xff0c;包括一些优化建议以及优化思路。 一、包体积优化的必要性 安装包大小与下载转化率的关系大致是成反比的&#xff0c;即安装…