【Iceberg分析】调研Iceberg中表的原地演变

news2024/10/1 16:59:53

调研Iceberg中表的原地演变

文章目录

  • 调研Iceberg中表的原地演变
    • 原生非分区表
      • 文件关系图
      • 表的原地演变之表schema演变
        • 新增字段new_column
        • 文件关系变化图
        • 为新增字段写入数据
        • 文件关系变化图
        • 删除新增字段
        • 文件关系变化图
        • 新增字段new_column2
        • 文件关系变化图
        • 删除数据
        • 文件关系变化图
    • 原生分区表
      • Iceberg支持如下几种分区转换
      • 文件关系变化图
      • 表的原地演变之分区演变
        • 新增分区
        • 文件关系变化图
        • 删除分区
        • 删除数据
        • 文件关系变化图
    • 小结

以《基于spark3.4.2+iceberg1.6.1搭建本地阅读调试环境》为基础环境,调研原地演变特性

工程中iceberg_warehousespark.sql.catalog.local.warehouse 指定了 Iceberg 数据文件和元数据文件的存放路径。

原生非分区表

创建非分区原生表,并插入数据。

        // 1.创建库
        spark.sql("create database iceberg_db");
        // 2.新建表
        spark.sql("CREATE TABLE local.iceberg_db.table1 (id bigint, data string) USING iceberg ");
        // 3.第1次新增数据
        spark.sql("INSERT INTO local.iceberg_db.table1 VALUES (1, 'a'), (2, 'b'), (3, 'c')");
        // 4.第2次新增数据
        spark.sql("INSERT INTO local.iceberg_db.table1 VALUES (4, 'd'), (5, 'e'), (6, 'f')");
        // 5.第3次新增数据
        spark.sql("INSERT INTO local.iceberg_db.table1 VALUES (7, 'g'), (8, 'h'), (9, 'i')");

在这里插入图片描述

文件关系图

数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table1

新建表时,会触发元数据的变化,此时是没有数据文件的,所以只有v1.metadata.json文件。

  • snap-开头的是清单列表文件(manifest list)
  • 紧接着snap之后的数字开头的是清单文件(manifest file)

表的原地演变之表schema演变

新增字段new_column
        // 6.新增字段new_column
        spark.sql("ALTER TABLE local.iceberg_db.table1 " +
                "ADD COLUMNS ( new_column string comment 'new_column docs' )");
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
v5.metadata.json
ceberg_db.table1

v5.metadata.jsonschemas以数组的形式记录了不同的表schema。以schema-id区分。new_column字段上有对应的字段id3current-schema-id中是当前生效的schema-id

 "current-schema-id" : 1,
"schemas" : [ {
    "type" : "struct",
    "schema-id" : 0,
    "fields" : [ {
      "id" : 1,
      "name" : "id",
      "required" : false,
      "type" : "long"
    }, {
      "id" : 2,
      "name" : "data",
      "required" : false,
      "type" : "string"
    } ]
  }, {
    "type" : "struct",
    "schema-id" : 1,
    "fields" : [ {
      "id" : 1,
      "name" : "id",
      "required" : false,
      "type" : "long"
    }, {
      "id" : 2,
      "name" : "data",
      "required" : false,
      "type" : "string"
    }, {
      "id" : 3,
      "name" : "new_column",
      "required" : false,
      "type" : "string",
      "doc" : "new_column docs"
    } ]
  } ]
为新增字段写入数据
        // 7.为新增字段new_column增加数据
        spark.sql("INSERT INTO local.iceberg_db.table1 VALUES (10, 'j','new1'), (11, 'k','new2'), (12, 'l','new3')");
        Dataset<Row> result = spark.sql("select * from local.iceberg_db.table1");
        result.show();

查询结果

表的schema中新增字段在之前的记录以null填充展示。

+---+----+----------+
| id|data|new_column|
+---+----+----------+
|  7|   g|      null|
|  8|   h|      null|
|  9|   i|      null|
|  1|   a|      null|
|  2|   b|      null|
|  3|   c|      null|
| 10|   j|      new1|
| 11|   k|      new2|
| 12|   l|      new3|
|  4|   d|      null|
|  5|   e|      null|
|  6|   f|      null|
+---+----+----------+
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
v5.metadata.json
v6.metadata.json
Manifest list
avro格式
Manifest file
avro格式
ceberg_db.table1
删除新增字段
        // 8.删除字段new_column
        spark.sql("ALTER TABLE local.iceberg_db.table1 DROP COLUMNS new_column");
        Dataset<Row> result = spark.sql("select * from local.iceberg_db.table1");
        result.show();

查询结果

表schema的删除字段在,之前的记录全部除了删除字段,全部可以查询展示。

+---+----+
| id|data|
+---+----+
|  4|   d|
|  5|   e|
|  6|   f|
|  1|   a|
|  2|   b|
|  3|   c|
| 10|   j|
| 11|   k|
| 12|   l|
|  7|   g|
|  8|   h|
|  9|   i|
+---+----+
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
v6.metadata.json
v7.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table1

v7.metadata.jsoncurrent-schema-id中是当前生效的schema-id改为了0

新增字段new_column2
        // 9.删除字段new_column
        spark.sql("ALTER TABLE local.iceberg_db.table1 " +
                "ADD COLUMNS ( new_column2 string comment 'new_column2 docs' )");
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
v6.metadata.json
v7.metadata.json
v8.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table1

v8.metadata.jsonschemas的变化,删除字段new_column的id3,不会再之后新增的new_column2不会再使用了。

"current-schema-id" : 2,
"schemas" : [ {
  "type" : "struct",
  "schema-id" : 0,
  "fields" : [ {
    "id" : 1,
    "name" : "id",
    "required" : false,
    "type" : "long"
  }, {
    "id" : 2,
    "name" : "data",
    "required" : false,
    "type" : "string"
  } ]
}, {
  "type" : "struct",
  "schema-id" : 1,
  "fields" : [ {
    "id" : 1,
    "name" : "id",
    "required" : false,
    "type" : "long"
  }, {
    "id" : 2,
    "name" : "data",
    "required" : false,
    "type" : "string"
  }, {
    "id" : 3,
    "name" : "new_column",
    "required" : false,
    "type" : "string",
    "doc" : "new_column docs"
  } ]
}, {
  "type" : "struct",
  "schema-id" : 2,
  "fields" : [ {
    "id" : 1,
    "name" : "id",
    "required" : false,
    "type" : "long"
  }, {
    "id" : 2,
    "name" : "data",
    "required" : false,
    "type" : "string"
  }, {
    "id" : 4,
    "name" : "new_column2",
    "required" : false,
    "type" : "string",
    "doc" : "new_column2 docs"
  } ]
} ]
删除数据
        // 10.删除字段new_column
        spark.sql("DELETE FROM local.iceberg_db.table1  where id in (2,5,10)");
        Dataset<Row> result = spark.sql("select * from local.iceberg_db.table1");
        result.show();
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
v6.metadata.json
v7.metadata.json
v8.metadata.json
v9.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table1

不同版本的metadata文件会使用不同的清单文件指向相同的数据文件,清单文件(manifest file)中的status字段取值说明,值1代表add,值2代表删除。

原生分区表

Iceberg支持如下几种分区转换

转换名称描述源字段类型结果类型
identityid值,默认没有转换函数。注意:如果用时间戳做为分区的话,每个时间戳是一个分区,随着数据的写入,元数据很快会崩溃AnySource type
bucket[N]哈希值],模Nint, long, decimal, date, time, timestamp, timestamptz, timestamp_ns, timestamptz_ns, string, uuid, fixed, binaryint
truncate[W]将字段按宽度截取int, long, decimal, string, binary与源字段类型一致,如果源字段是字符串则截取W长度,如果是int/long则相除W倍后取整
year将时间转换为年date, timestamp, timestamptz, timestamp_ns, timestamptz_nsint
month将时间转换为月date, timestamp, timestamptz, timestamp_ns, timestamptz_nsint
day将时间转换为日date, timestamp, timestamptz, timestamp_ns, timestamptz_nsint
hour将时间转换为小时timestamp, timestamptz, timestamp_ns, timestamptz_nsint
voidAlways produces nullAnySource type or int

创建分区原生表,使用分区转换进行隐藏分区,并插入数据。

        // 1.创建分区表,以month方法进行隐藏式分区
		spark.sql("CREATE TABLE local.iceberg_db.table2( id bigint, data string, ts timestamp) USING iceberg PARTITIONED BY (month(ts))");
		// 2.新增数据
        spark.sql("INSERT INTO local.iceberg_db.table2 VALUES (1, 'a', cast(1727601585 as timestamp)),(2, 'b', cast(1724923185 as timestamp)),(3, 'c', cast(1724919585 as timestamp))");

在这里插入图片描述

文件关系变化图

数据层
元数据层
catalog
ts_month=2024-08
ts_month=2024-09
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
Manifest list
avro格式
Manifest file
avro格式
ceberg_db.table2

Iceberg 通过获取列值并对其进行可选转换来生成分区值。建表时,ts字段类型是使用timestamp,默认使用带时区的timestamptz

v1.metadata.jsonpartition-specs以数组的形式记录了不同的表分区规则,以spec-id区分。default-spec-id中是当前生效的spec-id

  "default-spec-id" : 0,
  "partition-specs" : [ {
    "spec-id" : 0,
    "fields" : [ {
      "name" : "ts_month",
      "transform" : "month",
      "source-id" : 3,
      "field-id" : 1000
    } ]
  } ]

表的原地演变之分区演变

新增分区
        // 3.以day()方法新增分区
		spark.sql("ALTER TABLE local.iceberg_db.table2 ADD PARTITION FIELD day(ts)");
		// 4.新增数据
        spark.sql("INSERT INTO local.iceberg_db.table2 VALUES (4, 'd', cast(1727605185 as timestamp)),(5, 'e', cast(1725963585 as timestamp)),(6, 'f', cast(1726827585 as timestamp))");
文件关系变化图
数据层
元数据层
catalog
ts_month=2024-09
ts_month=2024-08
ts_day=2024-09-10
ts_day=2024-09-20
ts_day=2024-09-29
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table2

v3.metadata.jsonpartition-specs的变化,default-spec-id采用了新的分区组合spec-id1

  "default-spec-id" : 1,
  "partition-specs" : [ {
    "spec-id" : 0,
    "fields" : [ {
      "name" : "ts_month",
      "transform" : "month",
      "source-id" : 3,
      "field-id" : 1000
    } ]
  }, {
    "spec-id" : 1,
    "fields" : [ {
      "name" : "ts_month",
      "transform" : "month",
      "source-id" : 3,
      "field-id" : 1000
    }, {
      "name" : "ts_day",
      "transform" : "day",
      "source-id" : 3,
      "field-id" : 1001
    } ]
  } ]

可以发现:

  1. v3.metadata.json发现分区演变是一种元数据操作,并不急于重写文件。
  2. 表分区可以在现有表中更新
  3. 多个分区的共同存在。
删除分区
        spark.sql("ALTER TABLE local.iceberg_db.table2 DROP PARTITION FIELD month(ts)");
数据层
元数据层
catalog
ts_month=2024-09
ts_month=2024-08
ts_day=2024-09-10
ts_day=2024-09-20
ts_day=2024-09-29
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table2

v5.metadata.jsonpartition-specs的变化,default-spec-id采用了新的分区组合spec-id2

  "default-spec-id" : 2,
  "partition-specs" : [ {
    "spec-id" : 0,
    "fields" : [ {
      "name" : "ts_month",
      "transform" : "month",
      "source-id" : 3,
      "field-id" : 1000
    } ]
  }, {
    "spec-id" : 1,
    "fields" : [ {
      "name" : "ts_month",
      "transform" : "month",
      "source-id" : 3,
      "field-id" : 1000
    }, {
      "name" : "ts_day",
      "transform" : "day",
      "source-id" : 3,
      "field-id" : 1001
    } ]
  }, {
    "spec-id" : 2,
    "fields" : [ {
      "name" : "ts_day",
      "transform" : "day",
      "source-id" : 3,
      "field-id" : 1001
    } ]
  } ]
删除数据
        spark.sql("DELETE FROM local.iceberg_db.table2  where id in (2)");
文件关系变化图
数据层
元数据层
catalog
ts_month=2024-09
ts_month=2024-08
ts_day=2024-08-29
ts_day=2024-09-10
ts_day=2024-09-20
ts_day=2024-09-29
status=2
status=0
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
v6.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table2

删除数据操作会触发数据文件的变化,此时目录ts_day=2024-08-29已经于ts_month=2024-08平级。ts_day=2024-08-29中的数据文件会保留删除之后的数据。

由于分区的变化后,旧的分区规则产生的数据文件发生了数据变化,会产生一个新清单文件(maifest file)中的,会对旧的数据文件进行索引,以上述为例,v6.metadata.json对应的清单列表文件(maifest list)中存储了一个清单文件(maifest file)即虚线框展示的,其中存储了两个datafile的引用,status=2代表删除,status=0代表文件已经存在。

小结

  • 每一个操作都会产生一个新的元数据文件(metadata.json),需要配置自动清理元数据文件
  • 所有一个文件都伴有一个.crc文件,小文件的问题怎么办?
  • Iceberg使用唯一的id来跟踪表中的每一列。添加列时,将为其分配一个新ID,以便不会错误地使用现有数据。
  • 分区演变时,是元数据的操作,数据文件的操作是滞后的,有数据变动时才会进行文件的重写。

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

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

相关文章

无人机之数据提取篇

一、无人机平台与传感器 无人机是进行数据采集的基础设施&#xff0c;其稳定性、可靠性、灵活性和负载能力直接影响到数据采集的效果。根据实际需求&#xff0c;需选择适合的无人机类型&#xff0c;如固定翼无人机适合大范围、长时间的数据采集&#xff0c;而多旋翼无人机则更适…

从Fast-UMI到Diff-Control:分别改进UMI的硬件、UMI所用的扩散策略

前言 24年9.28日下午&#xff0c;微信上的好友丁研究员和我说 hi 周总&#xff0c;我们基于umi改进了一下——弄了一个用户友好的采集系统(当然&#xff0c;现在这个版本还比较初级 后续不断迭代)项目网站为&#xff1a;https://fastumi.com/ 技术报告见&#xff1a;https://…

docker和kafka连接Topic失败处理措施

使用 docker 镜像部署一套单节点的 Zookeeper Kafka&#xff0c;但是一直Java却连不上一些处理思路。 为了提高部署效率&#xff0c;这里提供一个简单可启动的docker-compose。 version: "3.3" services:zookeeper:image: zookeeper:3.5.5restart: alwayscontainer…

Global Illumination_VXGI(VCT) Deep Optimizations

之前针对RSM和LPV优化技术介绍后&#xff0c;我们可以看出来一个大致的思路的&#xff1a;就是减少计算量提升最大&#xff0c;因此VXGI的优化思路和之前两种算法几乎一样&#xff0c;之前也实现过Global Illumination_Voxel Global Illumintaion (VXGI)有兴趣的可以去简单了解…

软件系统可视化建设方案书(word原件)

第 一 章 系统总体设计 1.1 总体架构 1.1.1 系统拓扑 1.1.2 系统组成 1.2 设计概述 1.3 平台系统功能 1.3.1 总部数据看板 1.3.2 项目部数据看板 1.3.3 视频联网系统 1.3.4 实名制考勤系统 1.3.5 安全生产系统 1.3.6 塔吊安全监控子系统 1.3.7 施工升降机安全监控管系统 1.3.8 …

videojs 播放mp4视频只有声音没有画面问题

在使用Video.js播放MP4视频时&#xff0c;如果遇到只有声音没有画面的情况&#xff0c;这通常与视频文件的编码格式、浏览器兼容性或Video.js的配置有关。以下是一些可能的解决步骤和原因分析&#xff1a; 1. 检查视频编码 MP4视频支持多种编码格式&#xff0c;但并非所有编码…

Python 如何使用 Pandas 进行数据分析

Python 如何使用 Pandas 进行数据分析 在数据分析领域&#xff0c;Python 是非常流行的编程语言&#xff0c;而 Pandas 是其中最重要的库之一。Pandas 提供了高效、灵活的数据结构和工具&#xff0c;专门用于处理和分析数据。对于数据分析新手来说&#xff0c;理解如何使用 Pa…

Java增强for循环遍历集合删除指定值不安全问题

在这里因为remove方法有两种参数&#xff0c;一种是对象&#xff08;删除此元素&#xff09;&#xff0c;一种是Integer &#xff08;删除此下标对应的元素&#xff09;。恰好我对象类型就是Integer&#xff0c;所以或默认为删除下标对应元素&#xff0c;造成下标越界不安全。可…

RSA算法模拟实验报告(后篇,非常感谢橘味小奶糖的反馈)

有朋友说代码运行不出来&#xff0c;因为我是平板上写的&#xff0c;没在电脑上运行过&#xff0c;这也算是我的疏忽吧&#xff0c;今天尝试了一下&#xff0c;刚开始运行出来是乱码&#xff0c;改了一些东西&#xff0c;还是运行出来了。 我用的devc。 首先是文字显示&#…

【数据结构】---图

图 前言 本篇作为图的基础概念篇&#xff0c; 了解图的离散数学定义&#xff0c; 图的分类&#xff0c; 图模型解决的问题&#xff08;图的应用&#xff09;&#xff0c; 图的相关算法&#xff08;仅仅介绍&#xff0c;具体不在此篇展开&#xff09;。 学习基本路线&#xff…

计算两点结构的斜率

在行列可自由变换的条件下&#xff0c;平面上的2点结构只有3个 (A,B)---6*n*2---(0,1)(1,0) 分类A和B&#xff0c;A是3个2点结构&#xff0c;让B全是0。当收敛误差为7e-4&#xff0c;收敛199次取迭代次数平均值。让隐藏层节点数n分别为10&#xff0c;15&#xff0c;20&#xf…

【漏洞复现】泛微OA E-Office do_excel.php 任意文件写入漏洞

》》》产品描述《《《 泛微0-0fice是一款标准化的协同 OA办公软件&#xff0c;泛微协同办公产品系列成员之一,实行通用化产品设计&#xff0c;充分贴合企业管理需求&#xff0c;本着简洁易用、高效智能的原则&#xff0c;为企业快速打造移动化、无纸化、数字化的办公平台。 》》…

C# 变量与常量

一 变量与常量 1.1 内存如何存放数据 计算机使用内存来记忆计算时所使用的数据 内存如何存储数据&#xff1f; 数据各式各样&#xff0c;要先根据数据的需求&#xff08;即类型&#xff09;为它申请一块合适的空间 内存像宾馆 1.2 为什么需要变量 内存地址不好记&#x…

索尼MDR-M1:超宽频的音频盛宴,打造沉浸式音乐体验

在音乐的世界里&#xff0c;每一次技术的突破都意味着全新的听觉体验。 索尼&#xff0c;作为音频技术的先锋&#xff0c;再次以其最新力作——MDR-M1封闭式监听耳机&#xff0c;引领了音乐界的新潮流。 这款耳机以其超宽频播放和卓越的隔音性能&#xff0c;为音乐爱好者和专…

【优选算法】(第十二篇)

目录 搜索旋转排序数组中的最⼩值&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 0〜n-1中缺失的数字&#xff08;easy&#xff09; 题目解析 讲解算法原理 编写代码 搜索旋转排序数组中的最⼩值&#xff08;medium&#xff09; 题目解析 1.题目链接…

【C++ STL】领略vector之美,熟练掌握vector的使用

vector容器详解 一.vector容器简单介绍二.vector的构造函数三.vector中与容量和大小相关操作3.1接口函数说明3.2使用时的性能优化 四.vector中的元素访问与修改五.vector迭代器与遍历5.1迭代器5.2迭代器失效问题5.2.1 扩容导致的迭代器失效问题5.2.2删除导致的迭代器失效问题 一…

MySQL安装与环境配置(Windows系统 MySQL8.0.39)

目录 MySQL8.0.39工具下载安装开启方式可视化开启命令方式开启 环境配置 MySQL8.0.39 工具 系统&#xff1a;Windows 11 参考视频&#xff1a; 黑马程序员 MySQL数据库入门到精通&#xff0c;从mysql安装到mysql高级、mysql优化全囊括 P3 https://www.bilibili.com/video/BV1…

如何在Python中计算移动平均值?

在这篇文章中&#xff0c;我们将看到如何在Python中计算移动平均值。移动平均是指总观测值集合中固定大小子集的一系列平均值。它也被称为滚动平均。 考虑n个观测值的集合&#xff0c;k是用于确定任何时间t的平均值的窗口的大小。然后&#xff0c;移动平均列表通过最初取当前窗…

文件名称重命名批量操作:大量文件里的符号一键删除重命名

文件名重命名是一个常见需求&#xff0c;特别是在处理大量文件时&#xff0c;为了提高文件管理效率&#xff0c;文件批量改名高手实现批量重命名。把每个文件名里的符号删除。一起去试试。 1运行软件&#xff1a;在电脑里登录上文件批量改名高手&#xff0c;在三大功能中选择“…

力扣 —— 跳跃游戏

题目一(中等) 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&…