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

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是一种弹性分布式数据集,是对我们需要处理的数据进行的抽象。其中可以存储任意的数据,没有标准的数据结构。

image-20230207151820022

image-20230207151927965

而SparkSQL使用到的编程模型是DataFrame,是在RDD的基础上添加了Schema信息。所谓的Scheme信息指的是描述数据的信息,也可以认为是“元数据”,DataFrame的前身就是SchemaRDD。

假设RDD中的几行数据长这样;

1张三20
2李四21
3王五22

那么在DataFrame中数据就变成这样;

ID:IntName:StringAge:Int
1张三20
2李四21
3王五22

从上面两个表格可以看出,DataFrame比RDD多了一个表头信息(Schema),像一张表了,DataFrame还配套了新的操作数据的方法等,有了DataFrame这个高一层的抽象后,我们处理数据更加简单了,甚至可以用SQL来处理数据了,对开发者来说,易用性有了很大的提升。不仅如此,通过DataFrame API或SQL处理数据,会自动经过Spark优化器(Catalyst)的优化,即使你写的程序或SQL不高效,也可以运行的很快。

image-20230207154935852

其实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软件-说明 简介&#xff1a; MinerU是什么 MinerU是上海人工智能实验室OpenDataLab团队推出的开源智能数据提取工具&#xff0c;专注于复杂PDF文档的高效解析与提取。MinerU能将包含图片、公式、表格等元素的多模态PDF文档转化为易于分析…...

shell基础用法

shell基础知识 shell中的多行注释 :<<EOF read echo $REPLY # read不指定变量&#xff0c;则默认写入$REPLY EOF # :<<EOF ...EOF 多行注释&#xff0c;EOF可以替换为&#xff01;# 等文件目录和执行目录 echo $0$0 # ./demo.sh echo $0的realpath$(realpath…...

Redisson分布式锁

概览 个人博客源地址 Redisson不只是一个 Java Redis 客户端&#xff0c;它是一个以内存 Redis 服务器作为后端的处理 Java 对象(如 java.util.List, java.util.Map, java.util.Set, java.util.concurrent.locks.Lock 等)的一个框架。 Redisson提供了使用Redis的最简单和最…...

【C语言--趣味游戏系列】--电脑关机整蛊小游戏

前言&#xff1a; 老铁们&#xff0c;还是那句话&#xff0c;学习很苦游戏来补&#xff0c; 为了提高大家与朋友之间的友谊&#xff0c;博主在这里分享一个电脑关机的恶作剧小游戏&#xff0c;快拿去试试吧&#xff01;&#xff01;&#xff01; 目录&#xff1a; 1.电脑关机代…...

C#实现一个HttpClient集成通义千问-开发前准备

集成一个在线大模型&#xff08;如通义千问&#xff09;&#xff0c;来开发一个chat对话类型的ai应用&#xff0c;我需要先了解OpenAI的API文档&#xff0c;请求和返回的参数都是以相关接口文档的标准进行的 相关文档 OpenAI API文档 https://platform.openai.com/docs/api-…...

二叉树优选算法(一)

一、根据二叉树创建字符串 题目介绍&#xff1a; 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对 "()" 表示&#xff0c;转化后需…...

单片机C51--笔记8-STC89C51RC/RD-IIC协议

一、概述 IIC全称Inter-Integrated Circuit (集成电路总线) 是由PHILIPS公司在80年代开发的两线式串行总线&#xff0c;用于连接微控制器及其外围设备。IIC属于半双 工同步通信方式。 特点 简单性和有效性。 由于接口直接在组件之上&#xff0c;因此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 是一个强大的工具&#xff0c;可以实现项目的自动化部署流程&#xff0c;从代码提交到部署只需几个步骤。本文将带你配置 GitLab CI/CD 完成一个前端项目的自动化部署。 前言 为什么使用cicddocker&#xff1f; 目前我们公司开发环境使用的shell脚本部署&#…...

【Linux】进程

&#x1f33b;个人主页&#xff1a;路飞雪吖~ &#x1f320;专栏&#xff1a;Linux 目录 一、冯诺依曼体系结构 &#x1f31f;系统调用和库函数概念 二、操作系统OS 三、进程 &#x1f31f;查看进程 &#x1f31f;通过系统调用获取进程标示符 &#x1f31f;通过系统调用创…...

transformers生成式对话机器人

简介 生成式对话机器人是一种先进的人工智能系统&#xff0c;它能够通过学习大量的自然语言数据来模拟人类进行开放、连贯且创造性的对话。与基于规则或检索式的聊天机器人不同&#xff0c;生成式对话机器人并不局限于预定义的回答集&#xff0c;而是可以根据对话上下文动态地…...

Text2SQL(NL2sql)对话数据库:设计、实现细节与挑战

Text2SQL&#xff08;NL2sql&#xff09;对话数据库&#xff1a;设计、实现细节与挑战 前言1.何为Text2SQL&#xff08;NL2sql&#xff09;2.Text2SQL结构与挑战3.金融领域实际业务场景4.注意事项5.总结 前言 随着信息技术的迅猛发展&#xff0c;人机交互的方式也在不断演进。…...

C# 关于加密技术以及应用(二)

AES&#xff08;Advanced Encryption Standard&#xff09;和 RSA&#xff08;Rivest-Shamir-Adleman&#xff09;是两种不同的加密算法&#xff0c;它们各自有特定的使用场景和优势。下面是它们的主要区别和适用场景&#xff1a; AES&#xff08;高级加密标准&#xff09; 特…...

四十四:Web如何关闭会话

在Web应用中&#xff0c;关闭会话&#xff08;Session Termination&#xff09;是一个重要的机制&#xff0c;用于确保用户的会话状态被安全地终止。无论是用户主动退出登录还是因超时被动登出&#xff0c;正确地管理会话关闭有助于提升安全性并释放服务器资源。 一、为什么需…...

在wsl2中安装archlinux

在之前的博客中&#xff0c;我介绍了如何在虚拟机或者真实机上安装archlinux并且进行一定的配置&#xff0c;但是实际上Linux不管怎么配置在日常使用中都没有Windows简单便利&#xff0c;在开发有关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&#xff1a;要求 要求找到最长的连续递增子序列&#xff0c;即在原数组中位置连续且数值严格递增的一段序列 2&#xff1a;输入和输出 输入是一个未经排序的整数数组nums 输出是该数组中最长连续递增子序列的长度 3&#xff1a;边界调节 数组为空则长度为0 …...

apt 包 源 的维护 和缓存 命令

APT 包源维护命令 更新软件包列表&#xff1a; sudo apt update&#xff1a;从配置的软件源中获取最新的软件包信息。这是安装、升级或删除软件包前通常要执行的步骤&#xff0c;以确保使用的是最新的软件包信息。 升级软件包&#xff1a; sudo apt upgrade&#xff1a;升级系…...

【排序方法的总结】

在数据结构中常见的排序方法有&#xff1a; 插入排序、交换排序、选择排序、归并排序和基数排序等。 插入排序 特点&#xff1a; 简单直观&#xff0c;对于小规模的数据排序效率较高。它的工作原理是通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后…...

工作中常用springboot启动后执行的方法

前言&#xff1a; 工作中难免会遇到一些&#xff0c;程序启动之后需要提前执行的需求。 例如&#xff1a; 初始化缓存&#xff1a;在启动时加载必要的缓存数据。定时任务创建或启动&#xff1a;程序启动后创建或启动定时任务。程序启动完成通知&#xff1a;程序启动完成后通…...

QT 中使用 QTableView 和 QStandardItemModel 实现将数据导出到Excel 和 从Excel导入到 QTableView 的功能

简介 在Qt中&#xff0c;使用QTableView和QStandardItemModel来实现将数据导出到Excel和从Excel导入到QTableView的功能&#xff0c;而不使用第三方库&#xff08;如QXlsx&#xff09;。 效果 将 QTableView 中的数据导出到Excel //从tableview 导出到 EXcle void MainInterfa…...

模版方法模式的理解和实践

在软件开发中&#xff0c;设计模式为我们提供了一套经过验证的解决方案&#xff0c;用于解决常见的设计问题。其中&#xff0c;模版方法模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一个算法的框架&#xff0c;并允许子类在不改…...

05-树莓派-交叉编译

交叉编译的概念 交叉编译是什么 来源百度百科&#xff1a; 交叉编译是在一个平台上生成另一个平台上的可执行代码。同一个体系结构可以运行不同的操作系统&#xff1b;同样&#xff0c;同一个操作系统也可以在不同的体系结构上运行。 举例来说&#xff0c;我们常说的x86 Lin…...

杨振宁大学物理视频中黄色的字,c#写程序去掉

先看一下效果&#xff1a;&#xff08;还有改进的余地&#xff09; 我的方法是笨方法&#xff0c;也比较刻板。 1&#xff0c;首先想到&#xff0c;把屏幕打印下来。c#提供了这样一个函数&#xff1a; Bitmap bmp new Bitmap(640, 480, PixelFormat.Format32bppArgb); // 创…...

非归档模式下一个或多个数据文件损坏恢复

1. 介绍 有些时侯可能你的库处于非归档的模式下&#xff0c;而你的联机重做日志又currupted,你的数据文件不能完成完全的恢复&#xff0c;这里为大家介绍一个oracle的一个隐藏参数_allow_resetlogs_corruption&#xff0c;让数据库重生。 通过设置隐含参数恢复 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学习笔记(一)

创建函数写法一&#xff1a; 重点&#xff1a;函数有几种写法 function DemoShow() {return (<div className"App">函数声明</div>); }export default DemoShow;对应js创建函数声明&#xff1a;function sum1(a,b){return ab } 创建函数写法二&#x…...

【H2O2|全栈】MySQL的基本操作(三)

目录 前言 开篇语 准备工作 案例准备 多表查询 笛卡尔积 等值连接 外连接 内连接 自连接 子查询 存在和所有 含于 分页查询 建表语句 结束语 前言 开篇语 本篇继续讲解MySQL的一些基础的操作——数据字段的查询中的多表查询和分页查询&#xff0c;与单表查询…...

SQL按指定字符分割字符串

在SQL中分割字符串通常需要使用特定的函数&#xff0c;因为SQL本身并不像编程语言那样直接支持字符串分割。不同的数据库系统有不同的函数来处理字符串分割。以下是一些常见数据库系统中分割字符串的方法&#xff1a; 1. MySQL 在MySQL中&#xff0c;你可以使用SUBSTRING_IND…...

NAT traversal 原理 | TCP / UDP/ P2P

注&#xff1a;本文为 “NAT traversal ”相关的几篇文章合辑。 未整理去重。 NAT 穿越技术原理 Li_yy123 于 2020-12-08 18:54:26 发布 一、NAT 由来 为了解决全球公有 IPv4 的稀缺&#xff0c;提出了 NAT 技术。NAT 是 Network Address Translation 网络地址转换的缩写。 …...

喜报!极限科技(INFINI Labs)通过国家高新技术企业认定

2024 年 10 月 29 日&#xff0c;国家高新技术企业认定管理工作网公示了北京市认定机构 2024 年认定报备的第一批高新技术企业备案名单&#xff0c;极限数据&#xff08;北京&#xff09;科技有限公司 顺利通过本次高新技术企业评审&#xff0c;并获得 国家级“高新技术企业”认…...

在Ubuntu 22.04上搭建Kubernetes集群

Kubernetes 简介 什么是 Kubernetes&#xff1f; Kubernetes&#xff08;常简称为 K8s&#xff09;是一个强大的开源平台&#xff0c;用于管理容器化应用程序的部署、扩展和运行。它最初由 Google 设计并捐赠给 Cloud Native Computing Foundation&#xff08;CNCF&#xff0…...

【OpenCV】平滑图像

二维卷积(图像滤波) 与一维信号一样&#xff0c;图像也可以通过各种低通滤波器&#xff08;LPF&#xff09;、高通滤波器&#xff08;HPF&#xff09;等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。 opencv 提供了函数 **cv.filter2D()**&…...

Vue了解

​​​​​​​MVVM和MVC区别是什么? MVC &#xff1a; 传统的设计模式。 设计模式&#xff1a; 一套广泛被使用的开发方式 M&#xff1a; model 模型 模型&#xff1a;就是数据的意思 V &#xff1a; view视图 视图&#xff1a;就是页面的意思 C&#xff1a;controlle…...

JS 深拷贝浅拷贝

一、浅拷贝 // 假设有一个JSON对象 let originalObject {name: "Alice",age: 25,interests: ["reading", "coding"] };// 将JSON对象赋值给另一个变量 let copiedObject originalObject;// 修改新变量的属性 copiedObject.age 26;// 输出原始…...

设计模式学习之——单例模式

单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。这个模式的主要目的是控制对象的创建&#xff0c;确保在程序的整个生命周期中&#xff0c;某个类只有一个实例被创…...

Linux Vi/Vim使用 ⑥

掌握 CentOS 7 下的 Vi/Vim 编辑器&#xff1a;从安装到精通 在 CentOS 7 系统的日常运维、编程开发以及各类文本处理场景中&#xff0c;Vi/Vim 编辑器都是不可或缺的得力工具。它以轻量、高效、功能强大著称&#xff0c;虽然初次上手有一定学习门槛&#xff0c;但掌握之后便能…...

【5G】5G技术组件 5G Technology Components

5G的目标设置非常高&#xff0c;不仅在数据速率上要求达到20Gbps&#xff0c;在容量提升上要达到1000倍&#xff0c;还要为诸如大规模物联网&#xff08;IoT&#xff0c; Internet of Things&#xff09;和关键通信等新服务提供灵活的平台。这些高目标要求5G网络采用多种新技术…...

Java 学习,字符串比较

Java 字符串比较通常使用 equals() 方法&#xff0c;而不是使用 运算符。因为 运算符&#xff0c;比较的是字符串对象的引用是否相同&#xff0c;而 equals() 方法比较的是字符串的内容是否相同。 使用equals()等方法&#xff0c;比较两个字符串&#xff1a; public class …...

普通算法——二维前缀和

二维前缀和 题目链接&#xff1a;https://www.acwing.com/problem/content/798/ 题目描述&#xff1a; 输入一个 n n n 行 m m m 列的整数矩阵&#xff0c;再输入 q q q 个询问&#xff0c;每个询问包含四个整数 ** x 1 , y 1 , x 2 , y 2 x1,y1,x2,y2 x1,y1,x2,y2 &…...

2024年API接口发展趋势:智能化、自动化引领潮流

随着信息技术的飞速发展&#xff0c;应用程序编程接口&#xff08;API&#xff09;已成为现代软件开发的核心组成部分。API作为不同系统之间的桥梁&#xff0c;使得数据、功能和服务能够在各种平台和设备之间无缝流动。在2024年&#xff0c;API接口正经历着一系列显著的变革和发…...

SQL中的通配符:使用LIKE操作符进行模式匹配

在SQL中&#xff0c;LIKE 操作符用于在查询中进行模式匹配。它常用于 WHERE 子句中&#xff0c;以便根据特定模式查找数据。与直接进行精确匹配的 操作符不同&#xff0c;LIKE 允许你使用通配符来对数据进行模糊查询&#xff0c;从而使查询更加灵活和强大。 常见的SQL通配符 …...

数据结构:数组

线性表: 线性表就是数据排成像一条线一样的结构.每个现行表上的数据最多只有前和后两个方向.常见的线性表结构&#xff1a;数组&#xff0c;链表、队列、栈等。 什么是数组: 数组&#xff08;Array&#xff09;是一种线性表数据结构。它用一组连续的内存空间&#xff0c;来存储…...

2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判

2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判 完整代码请私聊 博主 一、背景 在各类学科竞赛中&#xff0c;常常要求参赛者提交 Excel 或/和 PDF 格式的竞赛作品。 本赛题以某届数据分析竞赛作品的评阅为背景&#xff0c;要求参赛者根据给定的评分准则和标准答案&a…...

java+ssm+mysql美妆论坛

项目介绍&#xff1a; 使用javassmmysql开发的美妆论坛&#xff0c;系统包含超级管理员&#xff0c;系统管理员、用户角色&#xff0c;功能如下&#xff1a; 用户&#xff1a;主要是前台功能使用&#xff0c;包括注册、登录&#xff1b;查看论坛板块和板块下帖子&#xff1b;…...

MySQL | 尚硅谷 | 第13章_约束

MySQL笔记&#xff1a;第13章_约束 文章目录 MySQL笔记&#xff1a;第13章_约束第13章_约束 1. 约束(constraint)概述1.1 为什么需要约束1.2 什么是约束1.3 约束的分类演示代码 2. 非空约束2.1 作用2.2 关键字2.3 特点2.4 添加非空约束2.5 删除非空约束演示代码 3. 唯一性约束3…...