SparkSQL编程实践
文章目录
- SparkSQL编程实践
- 1.1. 编程模型介绍
- 1.2. SparkSQL编程
- 1.2.1. 第三方库安装
- 1.2.2. SparkSQL程序的结构
- 1.2.3. SparkSQL执行模式
- 1.2.3.1. Local模式
- 1.2.3.2. 集群模式
- 1.2.4. 数据加载
- 1.2.4.1. 通过RDD创建DataFrame
- 1.2.4.2. 通过读取数据外部数据创建DataFrame
- 标准读取方式
- 读取JSON数据
- 读取CSV数据
- 读取Parquet数据
- 读取orc数据
- 读取txt数据
- 读取数据库数据
- 1.2.5. DSL风格处理数据
- 1.2.5.1. printSchema
- 1.2.5.2. show
- 1.2.5.3. filter
- 1.2.5.4. where
- 1.2.5.5. select
- 1.2.5.6. groupBy
- 1.2.5.7. dropDuplicates
- 1.2.5.8. dropna
- 1.2.5.9. fillna
- 1.2.6. SQL风格处理数据
- 1.2.7. 数据落地
- 1.2.7.1. 标准落地方式
- 1.2.7.2. 落地JSON数据
- 1.2.7.3. 落地CSV数据
- 1.2.7.4. 落地Parquet数据
- 1.2.7.5. 落地orc数据
- 1.3.7.6. 落地txt数据
- 1.3.7.7. 落地数据库数据
SparkSQL编程实践
1.1. 编程模型介绍
在SparkCore中使用到的编程模型是RDD。RDD是一种弹性分布式数据集,是对我们需要处理的数据进行的抽象。其中可以存储任意的数据,没有标准的数据结构。
而SparkSQL使用到的编程模型是DataFrame,是在RDD的基础上添加了Schema信息。所谓的Scheme信息指的是描述数据的信息,也可以认为是“元数据”,DataFrame的前身就是SchemaRDD。
假设RDD中的几行数据长这样;
1 | 张三 | 20 |
---|---|---|
2 | 李四 | 21 |
3 | 王五 | 22 |
那么在DataFrame中数据就变成这样;
ID:Int | Name:String | Age:Int |
---|---|---|
1 | 张三 | 20 |
2 | 李四 | 21 |
3 | 王五 | 22 |
从上面两个表格可以看出,DataFrame比RDD多了一个表头信息(Schema),像一张表了,DataFrame还配套了新的操作数据的方法等,有了DataFrame这个高一层的抽象后,我们处理数据更加简单了,甚至可以用SQL来处理数据了,对开发者来说,易用性有了很大的提升。不仅如此,通过DataFrame API或SQL处理数据,会自动经过Spark优化器(Catalyst)的优化,即使你写的程序或SQL不高效,也可以运行的很快。
其实SparkSQL中的DataFrame是借鉴了Python的Pandas库中的DataFrame的思想而来的,都是将结构化的数据映射成为一张二维的表格对数据进行处理。只不过Pandas中的DataFrame只能够处理本地的一些数据文件,而SparkSQL中的DataFrame却是能够处理分布式数据集合的编程模型。
1.2. SparkSQL编程
1.2.1. 第三方库安装
Spark本身是使用Scala语言来编写的,原生支持Scala、Java编程语言。而我们现在需要使用Python来进行操作,就需要下载安装第三方库pyspark,这个库是Spark官方发布的一个专门使用Python来操作Spark的库,我们直接使用pip就可以安装。
pip install pyspark==3.1.2
**注意:**在安装的时候,一定要与你的Spark的版本是一致的,否则会出现兼容性的问题。
1.2.2. SparkSQL程序的结构
在SparkSQL的程序中,程序的入口是SparkSession对象。在上方的Spark任务提交的部分,提到过一个比较重要的类是SparkContext,而在SparkSession中,对SparkContext进行了封装。
# 导入依赖库
from pyspark.sql import SparkSession# 创建程序入口SparkSession对象
# .builder : 获取到SparkSessionBuilder对象,用于创建SparkSession对象
# .master : 设置Master是谁,可以设置为local表示本地模式
# .appName : Spark程序的名字
# .getOrCreate : 根据前面设置的属性,用来创建一个SparkSession对象
spark = SparkSession.builder.master("local[*]").appName("spark-sql").getOrCreate()# 使用SparkSQL对数据进行处理的过程# 在程序结束的时候,释放SparkSession对象,释放资源
spark.stop()
1.2.3. SparkSQL执行模式
1.2.3.1. Local模式
将master设置为local,即可开启local模式,使用这种模式进行程序的开发。在local模式下,一般用来做程序的测试的用途。
对于分布式计算程序的开发,local模式其实是必不可少的。我们需要在开发的过程中,不断的使用测试数据来测试我们的业务逻辑是否正确,对程序进行及时的调整。此时一般会使用与真实的数据相同格式的、数据量比较少的测试数据,来测试程序的正确性。测试通过之后,才会放到集群上使用Standalone或者YARN模式来运行。
在这种模式下,local有几种写法:
- local : 开启一个线程,相当于local[1]。
- local[N] : 自己设定线程的数量为N个,例如local[2]就表示使用2个线程。
- local[*] : 按照CPU的核数来设置线程数量。
同时,如果要使用local模式的话,需要在本地安装好Spark的本地环境。其实就是将Spark的安装包在本地解压,然后配置环境变量即可。因为Spark的程序在执行的时候,其实是需要使用到spark-submit这个脚本的。
1.2.3.2. 集群模式
如果想要将自己的代码提交到集群上,以Standalone或者YARN模式来执行的话,只需要将代码中SparkSession在创建时候的.master去掉即可。以Standalone模式或者YARN模式来提交任务即可,参考Spark任务提交的部分。
在后续的课程中,默认都是以local模式来运行程序。因为在local模式下,可以快速的对程序进行测试,快速的定位问题、解决问题。如果需要提交到集群运行,按照上述方式修改提交方式即可。
1.2.4. 数据加载
在我们使用到SparkSQL的时候,需要使用SparkSession作为程序的入口,同时以DataFrame作为我们的编程模型。其实就是使用DataFrame来抽象描述我们需要处理的数据。那么DataFrame是怎么创建出来的呢?
- 通过RDD对象进行创建。
- 通过读取数据文件进行创建。
1.2.4.1. 通过RDD创建DataFrame
RDD是SparkCore中的编程模型,虽然我们不使用SparkCore来进行编程开发,但是还是有必要了解一下如何通过RDD进行DataFrame的构建。通过RDD创建DataFrame有两种方式:
- <SparkSession对象>.createDataFrame()
- <RDD对象>.toDF()
# 1. 构建RDD
rdd = spark.sparkContext.parallelize([("xiaoming", 19, 99, "male"),("xiaohong", 20, 98, "female"),("xiaogang", 20, 89, "male"),("xiaojuan", 21, 88, "female")
])# 2. 通过RDD构建DataFrame,构建方式:createDataFrame
'''
# 直接通过createDataFrame创建DataFrame
df = spark.createDataFrame(rdd)
'''df = rdd.toDF()df.printSchema()
df.show()
但是这样创建出来的DataFrame对象的Schema信息中,每一个字段的类型可以由值进行推导,但是字段的名字无法手动定义,只能使用默认的_0、_1等来描述,可读性非常差。因此我们就可以在创建DataFrame的时候,同时设定表头信息。
-
**使用数组的方式:**可以设置字段的名字,类型是由值来进行推导。
# 通过RDD构建DataFrame,通过数组,定义表头 df1 = spark.createDataFrame(rdd, schema=['name', 'age', 'score', 'gender']) df2 = rdd.toDF(schema=['name', 'age', 'score', 'gender'])""" root|-- name: string (nullable = true)|-- age: long (nullable = true)|-- score: long (nullable = true)|-- gender: string (nullable = true)+--------+---+-----+------+ | name|age|score|gender| +--------+---+-----+------+ |xiaoming| 19| 99| male| |xiaohong| 20| 98|female| |xiaogang| 20| 89| male| |xiaojuan| 21| 88|female| +--------+---+-----+------+ """
-
**使用StructTypes:**可以设置字段的名字、类型等属性。
# StductTypes需要导入模块使用 from pyspark.sql.types import StructType, StringType, IntegerType# 实例化Schema信息 schema = StructType()\.add('name', StringType(), True)\.add('age', IntegerType(), True)\.add('score', IntegerType(), True)\.add('gender', StringType(), True)# 2. 通过RDD构建DataFrame,通过数组,定义表头 df1 = spark.createDataFrame(rdd, schema=schema) df2 = rdd.toDF(schema=schema)
1.2.4.2. 通过读取数据外部数据创建DataFrame
标准读取方式
# 加载数据的标准流程,是使用load函数来加载。此时默认加载的是parquet格式的数据。
df_parquet = spark.read.load("../../../data/users.parquet")
# 如果需要加载其他格式的数据,需要指定format格式。
df_json = spark.read.load("../../../data/account.json", format="json")
df_csv = spark.read.load("../../../data/country.csv", format="csv")
读取JSON数据
# 读取JSON格式的数据,读取JSON数据创建的DataFrame对象自带Schema信息
df_json = spark.read.json("../../../data/account.json")
读取CSV数据
# 读取CSV格式的数据,CSV在读取的时候,可以设置分隔符的格式和是否包含头部信息
# 分隔符:CSV文件中,默认的列分隔符是逗号,也可以替换成为其他的分隔符
# 头部信息:第一行的数据是否作为字段的Schema的名字,如果不包含,字段的名字默认为_c0, _c1...
df_csv = spark.read.csv("../../../data/ip-pprovince-count.csv", sep=";", header=True)
读取Parquet数据
# 读取Parquet格式的数据
df_parquet = spark.read.parquet("../../../data/users.parquet")
读取orc数据
# 读取orc格式的数据
df_orc = spark.read.orc("../../../data/student.orc")
读取txt数据
# 读取txt格式的数据,这种方式读取的数据,只能将一行的数据读成一列
df_txt = spark.read.text("../../../data/dailykey.txt")
读取数据库数据
# 读取数据库的数据
# 读取的时候需要使用JDBC来读取,因此需要将JDBC的jar包放到本地spark目录下的jars文件夹下
# 如果需要将代码提交到集群上运行,需要将JDBC的jar包放到集群的Spark目录下的jars文件夹下
df_jdbc = spark.read.jdbc(url="jdbc:mysql://localhost:3306/pydb",table="bank_account",properties={"user": "root","password": "123456","driver": "com.mysql.cj.jdbc.Driver"})
1.2.5. DSL风格处理数据
函数 | 函数描述 |
---|---|
printSchema() | 打印DataFrame的Schema信息 |
show() | 打印参数数量指定的行数据,默认20行 |
filter() | 对DataFrame中的数据进行过滤,保留满足条件的数据,等同于where() |
where() | 对DataFrame中的数据进行过滤,保留满足条件的数据,等同于filter() |
select() | 查询DataFrame中指定的列 |
groupBy() | 对DataFrame的数据,按照指定的字段进行分组 |
dropDuplicates() | 对DataFrame的数据进行去重,保留重复的第一条数据 |
dropna() | 删除有缺失值的行,删除逻辑可以设置 |
fillna() | 填充缺失值数据 |
1.2.5.1. printSchema
DataFrame将结构化的数据抽象成为一张表,使用printSchema打印这个虚拟的表的结构。
可以查看到“字段”的名字和类型。
# 读取本地JSON文件,创建DataFrame
df_json = ssc.read.json("../../../data/people.json")
# 打印Schema
df_json.printSchema()
1.2.5.2. show
打印DataFrame描述的若干行的数据,默认打印20行。
# 读取本地JSON文件,创建DataFrame
df_json = ssc.read.json("../../../data/people.json")
# 默认打印20行的数据
df_json.show()
# 打印5行数据
df_json.show(5)
1.2.5.3. filter
对DataFrame的数据按照条件进行过滤,保留满足条件的数据,删除不满足条件的数据。得到一个新的DataFrame。
filter的参数可以是一个字符串的判断条件,也可以是Column对象的比较。
# 读取本地JSON文件,创建DataFrame
df_json = ssc.read.json("../../../data/people.json")# 使用字符串描述规则
df_json.filter("age > 18").show()
# Column:是一个用来描述DataFrame中的"列、字段"的类,使用df_json['字段名']来获取
df_json.filter(df_json['age'] > 19).show()
1.2.5.4. where
等同于filter。
# 读取本地JSON文件,创建DataFrame
df_json = ssc.read.json("../../../data/people.json")# 使用字符串描述规则
df_json.where("age > 18").show()
# Column:是一个用来描述DataFrame中的"列、字段"的类,使用df_json['字段名']来获取
df_json.where(df_json['age'] > 19).show()
1.2.5.5. select
查询DataFrame中的指定的字段。
# 读取本地JSON文件,创建DataFrame
df_json = ssc.read.json("../../../data/people.json")# select的参数可以是字符串,也可以是Column对象
# 使用字符串参数
df_json.select('name', 'age').show()# 使用Column对象作为参数
df_json.select(df_json['name'], df_json['age']).show()# 如果需要对查询的字段进行操作,例如运算、别名等,必须要使用Column对象
df_json.select((df_json['age'] + 10).alias('new_age')).show()
1.2.5.6. groupBy
对DataFrame的数据,按照指定的字段进行分组,返回值是一个GroupedData。
GroupedData对象是一个特殊的DataFrame,是对DataFrame的数据进行分组之后的结果,其中记录了DataFrame中的数据分组之后形成的数据。对GroupedData对象,我们可以使用一些聚合函数来操作,例如max、min、count、sum、avg等。
# 读取本地JSON文件,创建DataFrame
df_json = ssc.read.json("../../../data/people.json")
# 按照省份进行分组
df = df_json.groupby('province')
# 每个省份的最大年龄
df.max('age').show()
# 每个省份的最小身高
df.min('height').show()
# 每个省份有多少人
df.count().show()
# 每个省份的总年龄
df.sum('age').show()
# 每个省份的平均身高
df.avg('height').show()
1.2.5.7. dropDuplicates
对DataFrame的数据进行去重,保留重复的第一条数据。
# 读取本地JSON文件,创建DataFrame
df_json = ssc.read.json("../../../data/people.json")# 去重,保留重复的第一条数据(每一列的值都得相同)
df_json.dropDuplicates().show()
# 指定重复判断的字段,如果age字段值相同,视为两行数据为重复数据
df_json.dropDuplicates(subset=['age']).show()
1.2.5.8. dropna
删除有缺失值的行,删除逻辑可以设置
# 读取本地JSON文件,创建DataFrame
df_json = ssc.read.json("../../../data/people.json")# 删除有缺失数据的行,默认规则:只要一行数据中有至少一列是null,就删除这一行
# df_json.dropna().show()# 删除有效字段不到两列的数据(至少需要有两列不是null,否则就删除)
# df_json.dropna(thresh=2).show()# 删除指定字段是null的行
df_json.dropna(subset=['name']).show()
1.2.5.9. fillna
填充缺失值数据
# 填充所有的null为 N/A
# 这里需要注意数据类型,在df_json中,age和height列分别为long和double类型,因此这个填充无法对这两个列生效
df_json.fillna("N/A").show()# 填充指定列的null
df_json.fillna(0, subset=['age', 'height']).show()# 使用指定规则进行填充
df_json.fillna({'age': 0, 'height': 0.0, 'name': '佚名', 'province': '未知省份'}).show()
1.2.6. SQL风格处理数据
在使用Spark SQL的时候,出了上述的DSL风格的方式之外,还有一种更为简单,也是在开发中使用的非常多的方式:SQL。
在SparkSQL部分,使用到的编程模型是DataFrame,相比较于RDD来说,DataFrame多出来了一个Schema信息,将结构化的数据抽象称为一张二维表格来处理。SparkSQL对这样的数据在处理的时候,可以直接使用SQL语句来做。
与Hive类似,SparkSQL可以将SQL语句解析成为SparkCore部分的RDD的处理逻辑,提交到Spark集群运行。因此我们在进行数据的处理的时候,可以直接使用SQL语句来完成。这里的SQL支持标准SQL语句、Hive SQL等。
# 在使用SQL风格的时候,首先要做的事情是注册一张虚拟表的名字。
# 在将DataFrame注册虚拟表的时候,有三个函数可以使用
# createTempView :注册一张虚拟表,如果这个表存在则报错。
# createOrReplaceTempView :注册一张虚拟表,如果这个表存在,则覆盖之前的表名。
# createGlobalTempView :注册一张全局的虚拟表。
# 前两个函数注册表,可以称为"临时表、局部表",这种表只能在当前的SparkSession会话环境中使用。
# 最后一个函数注册的表,可以称为"全局表",这种表可以跨SparkSession会话使用。
df_json.createOrReplaceTempView('people')# 注册完成之后,就可以使用这个表名,使用SQL语句来处理了
# 案例1:统计成年人的数量
spark.sql("select count(*) from people where age >= 18").show()
# 案例2:统计每一个省份有多少人
spark.sql("select province, count(1) from people group by province having province != 'null'").show()
1.2.7. 数据落地
在上述的操作中,我们最终都只是将处理之后的数据打印到了控制台上。但是在实际的使用场景下,有时候我们需要将数据导出,形成一个数据文件。那么此时我们只需要修改一下最终要用到的程序的落地的函数即可。
1.2.7.1. 标准落地方式
# 标准落地数据的格式,默认是parquet格式的数据
df_json.write.save('./output/standard')# 在向外写文件的时候,可以设置mode,参数为string类型
# append: 追加,如果指定的路径下有数据文件存在,本次的输出会追加到之前的数据文件的末尾
# overwrite: 覆盖,如果指定的路径下有数据文件,本次的输出会将之前的数据覆盖掉
# ignore: 忽略,如果指定的路径下有数据文件,本次的输出会被忽略掉,什么都都不做
# error: 异常,如果指定的路径下有数据文件,本次的输出会异常
df_json.write.mode("overwrite").save("./output/standard")
1.2.7.2. 落地JSON数据
# 将数据落地称为JSON格式的数据
df_json.write.json("./output/json")
1.2.7.3. 落地CSV数据
# 将数据落地成为CSV格式的数据
# header: 将DataFrame中的字段名序列到csv文件的首行
# sep: 指定字段之间的分隔符
df_json.write.csv("./output/csv", header=True, sep='|')
1.2.7.4. 落地Parquet数据
# 可以直接使用标准落地方式
df_json.write.save('./output/standard')
# 也可以直接使用parquet格式的数据
df_json.write.parquet('./output/parquet')
1.2.7.5. 落地orc数据
# 将数据落地成为orc格式的数据
df_json.write.orc('./output/orc')
1.3.7.6. 落地txt数据
# 将数据落地成为txt格式的数据
df_json.write.text("./output/txt")
1.3.7.7. 落地数据库数据
# 将DataFrame的数据通过JDBC写入到数据库中
# 写数据的时候的时候需要使用JDBC来完成,因此需要将JDBC的jar包放到本地spark目录下的jars文件夹下
# 如果需要将代码提交到集群上运行,需要将JDBC的jar包放到集群的Spark目录下的jars文件夹下
df_json.write.jdbc(url="jdbc:mysql://localhost:3306/pydb",table="people",properties={"user": "root","password": "123456","driver": "com.mysql.cj.jdbc.Driver"})
相关文章:
SparkSQL编程实践
文章目录 SparkSQL编程实践1.1. 编程模型介绍1.2. SparkSQL编程1.2.1. 第三方库安装1.2.2. SparkSQL程序的结构1.2.3. SparkSQL执行模式1.2.3.1. Local模式1.2.3.2. 集群模式 1.2.4. 数据加载1.2.4.1. 通过RDD创建DataFrame1.2.4.2. 通过读取数据外部数据创建DataFrame标准读取…...
模型训练数据-MinerU一款Pdf转Markdown软件
模型训练数据-MinerU一款Pdf转Markdown软件-说明 简介: MinerU是什么 MinerU是上海人工智能实验室OpenDataLab团队推出的开源智能数据提取工具,专注于复杂PDF文档的高效解析与提取。MinerU能将包含图片、公式、表格等元素的多模态PDF文档转化为易于分析…...
shell基础用法
shell基础知识 shell中的多行注释 :<<EOF read echo $REPLY # read不指定变量,则默认写入$REPLY EOF # :<<EOF ...EOF 多行注释,EOF可以替换为!# 等文件目录和执行目录 echo $0$0 # ./demo.sh echo $0的realpath$(realpath…...
Redisson分布式锁
概览 个人博客源地址 Redisson不只是一个 Java Redis 客户端,它是一个以内存 Redis 服务器作为后端的处理 Java 对象(如 java.util.List, java.util.Map, java.util.Set, java.util.concurrent.locks.Lock 等)的一个框架。 Redisson提供了使用Redis的最简单和最…...
【C语言--趣味游戏系列】--电脑关机整蛊小游戏
前言: 老铁们,还是那句话,学习很苦游戏来补, 为了提高大家与朋友之间的友谊,博主在这里分享一个电脑关机的恶作剧小游戏,快拿去试试吧!!! 目录: 1.电脑关机代…...
C#实现一个HttpClient集成通义千问-开发前准备
集成一个在线大模型(如通义千问),来开发一个chat对话类型的ai应用,我需要先了解OpenAI的API文档,请求和返回的参数都是以相关接口文档的标准进行的 相关文档 OpenAI API文档 https://platform.openai.com/docs/api-…...
二叉树优选算法(一)
一、根据二叉树创建字符串 题目介绍: 给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。 空节点使用一对空括号对 "()" 表示,转化后需…...
单片机C51--笔记8-STC89C51RC/RD-IIC协议
一、概述 IIC全称Inter-Integrated Circuit (集成电路总线) 是由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。IIC属于半双 工同步通信方式。 特点 简单性和有效性。 由于接口直接在组件之上,因此IIC总线占用的空间非常小…...
HttpUtil的get和post请求
Http工具类 import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.ht…...
leetcode 二进制数转字符串
1.题目要求: 2.题目代码: class Solution { public:string printBin(double num) {string result;double compare_value 1.0;//先给把0和.赋值给result;result.push_back(0);result.push_back(.);while(result.size() < 33){//利用十进制转换成二进制的方法//1.先给num …...
前端项目使用gitlab-cicd+docker实现自动化部署
GitLab CI/CD 是一个强大的工具,可以实现项目的自动化部署流程,从代码提交到部署只需几个步骤。本文将带你配置 GitLab CI/CD 完成一个前端项目的自动化部署。 前言 为什么使用cicddocker? 目前我们公司开发环境使用的shell脚本部署&#…...
【Linux】进程
🌻个人主页:路飞雪吖~ 🌠专栏:Linux 目录 一、冯诺依曼体系结构 🌟系统调用和库函数概念 二、操作系统OS 三、进程 🌟查看进程 🌟通过系统调用获取进程标示符 🌟通过系统调用创…...
transformers生成式对话机器人
简介 生成式对话机器人是一种先进的人工智能系统,它能够通过学习大量的自然语言数据来模拟人类进行开放、连贯且创造性的对话。与基于规则或检索式的聊天机器人不同,生成式对话机器人并不局限于预定义的回答集,而是可以根据对话上下文动态地…...
Text2SQL(NL2sql)对话数据库:设计、实现细节与挑战
Text2SQL(NL2sql)对话数据库:设计、实现细节与挑战 前言1.何为Text2SQL(NL2sql)2.Text2SQL结构与挑战3.金融领域实际业务场景4.注意事项5.总结 前言 随着信息技术的迅猛发展,人机交互的方式也在不断演进。…...
C# 关于加密技术以及应用(二)
AES(Advanced Encryption Standard)和 RSA(Rivest-Shamir-Adleman)是两种不同的加密算法,它们各自有特定的使用场景和优势。下面是它们的主要区别和适用场景: AES(高级加密标准) 特…...
四十四:Web如何关闭会话
在Web应用中,关闭会话(Session Termination)是一个重要的机制,用于确保用户的会话状态被安全地终止。无论是用户主动退出登录还是因超时被动登出,正确地管理会话关闭有助于提升安全性并释放服务器资源。 一、为什么需…...
在wsl2中安装archlinux
在之前的博客中,我介绍了如何在虚拟机或者真实机上安装archlinux并且进行一定的配置,但是实际上Linux不管怎么配置在日常使用中都没有Windows简单便利,在开发有关Linux的程序时过去用虚拟机或者直接在Windows上使用ssh在远程服务器上进行开发…...
在Goland中对goroutine协程断点调试
在Goland中对goroutine协程断点调试 环境: Goland 参考了 chatgpt 的回复 进行断点调试的代码 package mainimport ("fmt""sync""time" )// worker 模拟处理任务 func worker(id int, wg *sync.WaitGroup) {defer wg.Done() // 确保任务完成后…...
最长连续递增序列
问题分解 1:要求 要求找到最长的连续递增子序列,即在原数组中位置连续且数值严格递增的一段序列 2:输入和输出 输入是一个未经排序的整数数组nums 输出是该数组中最长连续递增子序列的长度 3:边界调节 数组为空则长度为0 …...
apt 包 源 的维护 和缓存 命令
APT 包源维护命令 更新软件包列表: sudo apt update:从配置的软件源中获取最新的软件包信息。这是安装、升级或删除软件包前通常要执行的步骤,以确保使用的是最新的软件包信息。 升级软件包: sudo apt upgrade:升级系…...
【排序方法的总结】
在数据结构中常见的排序方法有: 插入排序、交换排序、选择排序、归并排序和基数排序等。 插入排序 特点: 简单直观,对于小规模的数据排序效率较高。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后…...
工作中常用springboot启动后执行的方法
前言: 工作中难免会遇到一些,程序启动之后需要提前执行的需求。 例如: 初始化缓存:在启动时加载必要的缓存数据。定时任务创建或启动:程序启动后创建或启动定时任务。程序启动完成通知:程序启动完成后通…...
QT 中使用 QTableView 和 QStandardItemModel 实现将数据导出到Excel 和 从Excel导入到 QTableView 的功能
简介 在Qt中,使用QTableView和QStandardItemModel来实现将数据导出到Excel和从Excel导入到QTableView的功能,而不使用第三方库(如QXlsx)。 效果 将 QTableView 中的数据导出到Excel //从tableview 导出到 EXcle void MainInterfa…...
模版方法模式的理解和实践
在软件开发中,设计模式为我们提供了一套经过验证的解决方案,用于解决常见的设计问题。其中,模版方法模式(Template Method Pattern)是一种行为设计模式,它定义了一个算法的框架,并允许子类在不改…...
05-树莓派-交叉编译
交叉编译的概念 交叉编译是什么 来源百度百科: 交叉编译是在一个平台上生成另一个平台上的可执行代码。同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。 举例来说,我们常说的x86 Lin…...
杨振宁大学物理视频中黄色的字,c#写程序去掉
先看一下效果:(还有改进的余地) 我的方法是笨方法,也比较刻板。 1,首先想到,把屏幕打印下来。c#提供了这样一个函数: Bitmap bmp new Bitmap(640, 480, PixelFormat.Format32bppArgb); // 创…...
非归档模式下一个或多个数据文件损坏恢复
1. 介绍 有些时侯可能你的库处于非归档的模式下,而你的联机重做日志又currupted,你的数据文件不能完成完全的恢复,这里为大家介绍一个oracle的一个隐藏参数_allow_resetlogs_corruption,让数据库重生。 通过设置隐含参数恢复 alter system …...
k8s 之storageclass使用nfs动态申请PV
文章目录 配置角色权限部署nfs-client-provisioner创建 NFS StorageClass创建 PVC 来动态申请 PV在 Pod 中使用 PVC验证存储是否正确挂载使用 kubectl 和 jq 筛选 PVCwaiting for a volume to be created, either by external provisioner "nfs-diy" or manually cre…...
Spark实训
实训目的: 介绍本实训的基本内容,描述知识目标、,以及本实训的预期效果等。 1、知识目标 (1)了解spark概念、基础知识、spark处理的全周期,了解spark技术是新时代对人才的新要求。 (2)掌握Linux、hadoop、spark、hive集群环境的搭建、HDFS分布文件系统的基础知识与应用…...
Mitel MiCollab 企业协作平台 任意文件读取漏洞复现(CVE-2024-41713)
0x01 产品简介 Mitel MiCollab是加拿大Mitel(敏迪)公司推出的一款企业级协作平台,旨在为企业提供统一、高效、安全的通信与协作解决方案。通过该平台,员工可以在任何时间、任何地点,使用任何设备,实现即时通信、语音通话、视频会议、文件共享等功能,从而提升工作效率和…...
React学习笔记(一)
创建函数写法一: 重点:函数有几种写法 function DemoShow() {return (<div className"App">函数声明</div>); }export default DemoShow;对应js创建函数声明:function sum1(a,b){return ab } 创建函数写法二&#x…...
【H2O2|全栈】MySQL的基本操作(三)
目录 前言 开篇语 准备工作 案例准备 多表查询 笛卡尔积 等值连接 外连接 内连接 自连接 子查询 存在和所有 含于 分页查询 建表语句 结束语 前言 开篇语 本篇继续讲解MySQL的一些基础的操作——数据字段的查询中的多表查询和分页查询,与单表查询…...
SQL按指定字符分割字符串
在SQL中分割字符串通常需要使用特定的函数,因为SQL本身并不像编程语言那样直接支持字符串分割。不同的数据库系统有不同的函数来处理字符串分割。以下是一些常见数据库系统中分割字符串的方法: 1. MySQL 在MySQL中,你可以使用SUBSTRING_IND…...
NAT traversal 原理 | TCP / UDP/ P2P
注:本文为 “NAT traversal ”相关的几篇文章合辑。 未整理去重。 NAT 穿越技术原理 Li_yy123 于 2020-12-08 18:54:26 发布 一、NAT 由来 为了解决全球公有 IPv4 的稀缺,提出了 NAT 技术。NAT 是 Network Address Translation 网络地址转换的缩写。 …...
喜报!极限科技(INFINI Labs)通过国家高新技术企业认定
2024 年 10 月 29 日,国家高新技术企业认定管理工作网公示了北京市认定机构 2024 年认定报备的第一批高新技术企业备案名单,极限数据(北京)科技有限公司 顺利通过本次高新技术企业评审,并获得 国家级“高新技术企业”认…...
在Ubuntu 22.04上搭建Kubernetes集群
Kubernetes 简介 什么是 Kubernetes? Kubernetes(常简称为 K8s)是一个强大的开源平台,用于管理容器化应用程序的部署、扩展和运行。它最初由 Google 设计并捐赠给 Cloud Native Computing Foundation(CNCF࿰…...
【OpenCV】平滑图像
二维卷积(图像滤波) 与一维信号一样,图像也可以通过各种低通滤波器(LPF)、高通滤波器(HPF)等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。 opencv 提供了函数 **cv.filter2D()**&…...
Vue了解
MVVM和MVC区别是什么? MVC : 传统的设计模式。 设计模式: 一套广泛被使用的开发方式 M: model 模型 模型:就是数据的意思 V : view视图 视图:就是页面的意思 C:controlle…...
JS 深拷贝浅拷贝
一、浅拷贝 // 假设有一个JSON对象 let originalObject {name: "Alice",age: 25,interests: ["reading", "coding"] };// 将JSON对象赋值给另一个变量 let copiedObject originalObject;// 修改新变量的属性 copiedObject.age 26;// 输出原始…...
设计模式学习之——单例模式
单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。这个模式的主要目的是控制对象的创建,确保在程序的整个生命周期中,某个类只有一个实例被创…...
Linux Vi/Vim使用 ⑥
掌握 CentOS 7 下的 Vi/Vim 编辑器:从安装到精通 在 CentOS 7 系统的日常运维、编程开发以及各类文本处理场景中,Vi/Vim 编辑器都是不可或缺的得力工具。它以轻量、高效、功能强大著称,虽然初次上手有一定学习门槛,但掌握之后便能…...
【5G】5G技术组件 5G Technology Components
5G的目标设置非常高,不仅在数据速率上要求达到20Gbps,在容量提升上要达到1000倍,还要为诸如大规模物联网(IoT, Internet of Things)和关键通信等新服务提供灵活的平台。这些高目标要求5G网络采用多种新技术…...
Java 学习,字符串比较
Java 字符串比较通常使用 equals() 方法,而不是使用 运算符。因为 运算符,比较的是字符串对象的引用是否相同,而 equals() 方法比较的是字符串的内容是否相同。 使用equals()等方法,比较两个字符串: public class …...
普通算法——二维前缀和
二维前缀和 题目链接:https://www.acwing.com/problem/content/798/ 题目描述: 输入一个 n n n 行 m m m 列的整数矩阵,再输入 q q q 个询问,每个询问包含四个整数 ** x 1 , y 1 , x 2 , y 2 x1,y1,x2,y2 x1,y1,x2,y2 &…...
2024年API接口发展趋势:智能化、自动化引领潮流
随着信息技术的飞速发展,应用程序编程接口(API)已成为现代软件开发的核心组成部分。API作为不同系统之间的桥梁,使得数据、功能和服务能够在各种平台和设备之间无缝流动。在2024年,API接口正经历着一系列显著的变革和发…...
SQL中的通配符:使用LIKE操作符进行模式匹配
在SQL中,LIKE 操作符用于在查询中进行模式匹配。它常用于 WHERE 子句中,以便根据特定模式查找数据。与直接进行精确匹配的 操作符不同,LIKE 允许你使用通配符来对数据进行模糊查询,从而使查询更加灵活和强大。 常见的SQL通配符 …...
数据结构:数组
线性表: 线性表就是数据排成像一条线一样的结构.每个现行表上的数据最多只有前和后两个方向.常见的线性表结构:数组,链表、队列、栈等。 什么是数组: 数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储…...
2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判
2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判 完整代码请私聊 博主 一、背景 在各类学科竞赛中,常常要求参赛者提交 Excel 或/和 PDF 格式的竞赛作品。 本赛题以某届数据分析竞赛作品的评阅为背景,要求参赛者根据给定的评分准则和标准答案&a…...
java+ssm+mysql美妆论坛
项目介绍: 使用javassmmysql开发的美妆论坛,系统包含超级管理员,系统管理员、用户角色,功能如下: 用户:主要是前台功能使用,包括注册、登录;查看论坛板块和板块下帖子;…...
MySQL | 尚硅谷 | 第13章_约束
MySQL笔记:第13章_约束 文章目录 MySQL笔记:第13章_约束第13章_约束 1. 约束(constraint)概述1.1 为什么需要约束1.2 什么是约束1.3 约束的分类演示代码 2. 非空约束2.1 作用2.2 关键字2.3 特点2.4 添加非空约束2.5 删除非空约束演示代码 3. 唯一性约束3…...