Spark Schema、Hive和Python的数据类型关系,以及Pyspark数据类型详解

2023-11-05

文章目录

1 概念阐述

Spark SQL使用时需要有若干“表”或“视图”的存在,这些“表”可以来自于Hive,也可以来来自RDD创建的DataFrame。如果“表”来自于Hive,它的模式(列名、列类型等)在创建时已经确定,一般情况下我们直接通过Spark SQL分析表中的数据即可;如果“表”来自DataFrame,我们就需要考虑两个要素:

通过Spark的官方文档可以了解到,生成一张DataFrame需要两个要素:

  1. RDD中的数据;
  2. 定义的数据模式,即Schema;

也就是说,我们需要将数据模式应用于关联着数据的RDD,然后就可以将该RDD注册为一张DataFrame。在这个过程中,最为重要的就是数据(模式)的数据类型,它直接影响着Pyspark的计算过程以及计算结果的正确性。

1.1 Spark中支持的数据类型

目前pyspark.sql.types支持的数据类型:NullType、StringType、BinaryType、BooleanType、DateType、TimestampType、DecimalType、DoubleType、FloatType、ByteType、IntegerType、LongType、ShortType、ArrayType、MapType、StructType(StructField)。

其中ArrayType、MapType、StructType我们称之为“复合类型”,其余称之为“基本类型”,“复合类型”在是“基本类型”的基础上构建而来的。

1.2 Spark中的基本类型与Python数据类型、Hive表数据类型的对应关系

这里的“Spark中的基本类型”指Spark-Sql模块下的,DataFrame里的Schema中的数据类型。

Spark中的基本类型 Python数据类型 Hive数据类型(未经过源码验证,仅猜测) 值范围
NullType None
StringType basestring STRING、VARCHAR、CHAR
BinaryType bytearray BINARY 字节数组
BooleanType bool BOOLEAN
DateType datetime.date DATE yyyy-MM-dd格式,其余格式都是错误的,会变为NULL
TimestampType datetime.datetime TIMESTAMPS yyyy-MM-dd HH:mm:ss.fffffffff,即最多支持纳秒级,如果长度超出,则会变成NULL
DecimalType decimal.Decimal decimal 任意精度的最大38位的十进制数字
DoubleType float(double precision floats) double [4.9E-324, 1.7976931348623157E308]
FloatType float(single precision floats) float [1.4E-45, 3.4028235E38]
ByteType int(a signed integer) tinyint [-128, 127](-2^7, 2^7-1)
ShortType int(a signed 16-bit integer) smallint [-32768, 32767](-2^15, 2^15-1)
IntegerType int(a signed 32-bit integer) int [-2147483648, 2147483647](-2^31,2^31-1)
LongType long(a signed 64-bit integer) bigint [-9223372036854775808, 9223372036854775807](-2^63,2^63-1)

注意在Hive表中保存的Spark Schema缓存信息中,类型信息中的’Type’都要删除,即StringType是String。

1.3 Hive中数字类型各自的表示范围

基于以下官方文档中的数字类型的范围,笔者推断出了其和Spark中DataFrame里的Schema中的数据类型的对应关系。
在这里插入图片描述
关于更多Hive数据类型的介绍,可以查看这篇文章,不过注意其中对数字范围的描述有一些是错的:Hive数据类型详解

将Hive中各数据类型的数字范围和Spark基本类型中的数字范围做对比,我们可以猜想Hive tinyint、smallint、int、bigint、float、double与Java Byte、Short、Integer、Long、Float、Double是一一对应的(仅仅是猜想,并没有实际查看源码验证)。所以得出了前文表格中的结论。

2 分类型介绍每种数据类型的详情

2.1 数字类型(ByteType、ShortType、IntegerType、LongType、FloatType、DoubleType、DecimalType)

数字类型可分为两类:

  1. 整数类型:ByteType、ShortType、IntegerType、LongType,使用时需要注意各自的整数表示范围;
  2. 浮点类型:FloatType、DoubleType、DecimalType,使用时不但需要注意各自的浮点数表示范围,还需要注意各自的精度范围。

2.1.1 PySpark创建RDD对象,并通过SQL接口查询的示例

我们以常见的数据类型IntegerType来说明数字类型的使用方法:

%pyspark
# 如果是通过Zeppelin (Apache开源框架)来运行,那么SparkSession和SparkContext对象应该是提前创建好的,不用再创建。
# 所以创建sc对象部分注释掉了
# from pyspark import SparkConf, SparkContext
from pyspark.sql.types import StructType, StructField, IntegerType

# spark = SparkSession.builer\
#         appName('test').\
#         master('yarn').\
#         getOrCreate()
# sc = spark.sparkContext


# Step1:模拟“一行两列”的数据,并通过parallelize方法将其转换为一个RDD source,这个RDD就是关联着数据的RDD。
# 两个数字为-2^31,2^31-1,即IntergerType的数字范围
source = sc.parallelize([(-2147483648, 2147483647)])

'''
Step2:
创建数据模式,需要分别为这两列指定列名、列类型、可否包含空(Null)值;
其中模式(Schema)需要使用StructType表示,每一列的各个属性(列名称、列类型、可否包含空(Null)值)需要使用StructField表示;
第一列的列名为col1,列类型为IntegerType,不可包含空(Null)值(False);第二列的列名为col2,列类型为IntegerType,不可包含空(Null)值(False)。
(注意:实际使用中每列的数据类型并不一定相同)
'''

schema = StructType([StructField('col1', IntegerType(), False),
                    StructField('col2', IntegerType(), False)])

# Step3:通过rdd的toDF方法,可以创建一个DataFrame;
df = source.toDF(schema)
df.printSchema()
df.show()

# Step4:可以将DataFrame注册为临时视图
df.createOrReplaceTempView('temp_table')


rows = spark.sql(
    'select col1+col2 from temp_table').collect()
    
print(rows)

for row in rows:
    print(row[0], type(row[0]))

程序返回结果如下:
在这里插入图片描述

到此我们就完成了创建RDD、创建Schema、注册Table的整个过程,接下来就可以使用这张表(temp_table)通过Spark(Hive) SQL完成分析。其它数字类型的使用方式类似。

从前文中各数据类型的范围可以看出,虽然我们使用Python编写程序,然而这些数据类型的表示范围与Java中的Byte、Short、Integer、Long、Float、Double是一致的。其原因是,Spark是Scala实现的,而Scala运行于Java虚拟机之上,因此Spark SQL中的数据类型ByteType、ShortType、IntegerType、LongType、FloatType、DoubleType、DecimalType在运行过程中对应的数据实际上是由Java中的Byte、Short、Integer、Long、Float、Double表示的。

2.1.2 数据溢出现象

在使用Python编写Spark Application时需要牢记:为分析的数据选择合适的数据类型,避免因为数据溢出导致输入数据异常,但这仅仅能够解决数据输入的溢出问题,还不能解决数据在计算过程中可能出现的溢出问题。

我们将上述例子中的示例数据修改为(9223372036854775807, 9223372036854775807),数据类型修改为LongType,现在的示例数据实际是LongType所能表示的最大值,如果我们将这两例值相加,是否会出现溢出的情况呢?

%pyspark
# 如果是通过Zeppelin (Apache开源框架)来运行,那么SparkSession和SparkContext对象应该是提前创建好的,不用再创建。
# 所以创建sc对象部分注释掉了
# from pyspark import SparkConf, SparkContext
from pyspark.sql.types import StructType, StructField, LongType

# spark = SparkSession.builer\
#         appName('test').\
#         master('yarn').\
#         getOrCreate()
# sc = spark.sparkContext


# Step1:模拟“一行两列”的数据,并通过parallelize方法将其转换为一个RDD source,这个RDD就是关联着数据的RDD。
source = sc.parallelize([(9223372036854775807,9223372036854775807)])

'''
Step2:
创建数据模式,需要分别为这两列指定列名、列类型、可否包含空(Null)值;
其中模式(Schema)需要使用StructType表示,每一列的各个属性(列名称、列类型、可否包含空(Null)值)需要使用StructField表示;
第一列的列名为col1,列类型为LongType,不可包含空(Null)值(False);第二列的列名为col2,列类型为LongType,不可包含空(Null)值(False)。
(注意:实际使用中每列的数据类型并不一定相同)
'''

schema = StructType([StructField('col1', LongType(), False),
                    StructField('col2', LongType(), False)])

# Step3:通过rdd的toDF方法,可以创建一个DataFrame;
df = source.toDF(schema)
df.printSchema()
df.show()

# Step4:可以将DataFrame注册为临时视图
df.createOrReplaceTempView('temp_table')


rows = spark.sql(
    'select col1+col2 from temp_table').collect()
    
print(rows)

for row in rows:
    print(row[0], type(row[0]))

程序返回结果如下:
在这里插入图片描述
可以看出,实际计算结果与我们预想的完全一样,这是因为col1与col2的类型为LongType,那么col1 + col2的类型也应为LongType(原因见后文),然而col1 + col2的结果值18446744073709551614已经超过LongType所能表示的范围([-9223372036854775808, 9223372036854775807]),必然导致溢出。

尝试在查询时,在SQL语句中将该数字转换为bingint,看看是否还会出现数据溢出的情况。

rows = spark.sql(
    'select cast(col1 as bigint)+cast(col2 as bigint) from temp_table').collect()

发现结果如下:
在这里插入图片描述
即数据还是溢出的。原因就是:Hive BIGINT的表示范围与LongType是一致的,毕竟Hive是Java实现的。所以我们将LongType的数据类型转换为BIGINT的方式是行不通的。

2.1.3 解决数据溢出问题

2.1.3.1 通过在SQL查询中使用decimal格式来解决

那么我们应该如何解决溢出问题呢?注意到Hive Numeric Types中的最后一个数字类型:DECIMAL,从Hive 0.11.0引入,Hive 0.13.0开始支持用户可以自定义“precision”和“scale”。Decimal基于Java BigDecimal实现,可以表示不可变的任务精度的十进制数字,支持常规的数学运算(+,-,*,/)和UDF(floor、ceil、round等),也可以与其它数字类型相互转换(cast)。使用示例如下:

rows = spark.sql(
    'select cast(col1 as decimal(38,0))+cast(col2 as decimal(38,0)) from temp_table').collect()

使用Decimal时需要注意“precision”和“scale”值的选取,Java BigDecimal(BigInteger,后续会提到)取值范围理论上取决于(虚拟)内存的大小,可见它们是比较消耗内存资源的,因此我们需要根据我们的实际需要为它们选取合适的值,并且需要满足下述条件:

整数部分位数(precision - scale) + 小数部分位数(scale) = precision

LongType所能表示的最大位数:19,因为在我们的示例中会导致溢出问题,因此我们将数值转换为Decimal,并指定precision为38,scale为0,这样我们便可以得到正确的结果:
在这里插入图片描述
需要注意的是计算结果类型也变成decimal.Decimal(Python)

2.1.3.1 通过在pyspark定义RDD和DataFrame时使用decimal格式来解决

使用Python编写Spark Application时,pyspark也提供了DecimalType,它是一种比较特殊的数据类型,它不是Python内建的数据类型,使用时需要导入模块decimal,使用方式如下:

%pyspark
# 如果是通过Zeppelin (Apache开源框架)来运行,那么SparkSession和SparkContext对象应该是提前创建好的,不用再创建。
# 所以创建sc对象部分注释掉了
# from pyspark import SparkConf, SparkContext
from pyspark.sql.types import StructType, StructField, DecimalType
from decimal import Decimal

# spark = SparkSession.builer\
#         appName('test').\
#         master('yarn').\
#         getOrCreate()
# sc = spark.sparkContext


# Step1:模拟“一行两列”的数据,并通过parallelize方法将其转换为一个RDD source,这个RDD就是关联着数据的RDD。
source = sc.parallelize([(Decimal('1.0'),Decimal('2.0'))])

'''
Step2:
创建数据模式,需要分别为这两列指定列名、列类型、可否包含空(Null)值;
其中模式(Schema)需要使用StructType表示,每一列的各个属性(列名称、列类型、可否包含空(Null)值)需要使用StructField表示;
第一列的列名为col1,DecimalType,不可包含空(Null)值(False);第二列的列名为col2,列类型为LongType,不可包含空(Null)值(False)。
(注意:实际使用中每列的数据类型并不一定相同)
'''

schema = StructType([StructField('col1', DecimalType(), False),
                    StructField('col2', DecimalType(), False)])

# Step3:通过rdd的toDF方法,可以创建一个DataFrame;
df = source.toDF(schema)
df.printSchema()
df.show()

# Step4:可以将DataFrame注册为临时视图
df.createOrReplaceTempView('temp_table')


rows = spark.sql(
    'select col1+col2, col2+1.0 from temp_table').collect()
    
print(rows)

for row in rows:
    print(row[0], type(row[0]))

程序返回结果:
在这里插入图片描述
**注意红字标识出来的两种不同的计算过程:**在将decimal数字转为DataFrame之后,一个是直接用两个值相加;而另一个是将一个值和小数常量相加。两者显示出来的计算结果不同,一个是不带小数点,一个是带的。然而,即便是不带小数点的结果,其类型仍然是decimal.Decimal(Python)。

在Pyspark中使用数据类型DecimalType时有两个地方需要注意:

  1. 创建RDD时需要使用模块decimal中的Decimal生成数据;

  2. DecimalType在Spark 1.2.0环境下使用时会出现异常:java.lang.ClassCastException: java.math.BigDecimal cannot be cast to org.apache.spark.sql.catalyst.types.decimal.Decimal,在Spark 1.5.0环境下可以正常使用,但需要将模块名称由“pyspark.sql”修改为“pyspark.sql.types”。

2.1.4 数据运算后的数据类型是如何决定的

我们明确指定数据的类型是什么,那么什么决定我们常规数学运算(+,-,*,/)之后的结果类型呢?这些数学运行在Hive中实际都是由UDF实现的(org.apache.hadoop.hive.ql.exec.FunctionRegistry)
在这里插入图片描述

  1. +类型
    在这里插入图片描述
  2. -类型
    在这里插入图片描述
  3. *类型
    在这里插入图片描述
  4. /类型
    在这里插入图片描述
  5. %类型(取模)
    在这里插入图片描述

从上述代码可以看出:“+”,“-”,“*”,“%”通过重载支持的数据类型:byte、short、int、long、float、double、decimal,而“/”通过重载仅仅支持数据类型:double、decimal,计算的结果类型与输入类型是相同的,这也意味着:

  1. 数学运算“+”、“-”,“*”,“%”时可能会出现隐式转换(如int + long => long + long);
  2. 数学运算“/”则统一将输入数据转换为数据类型double或decimal进行运算,这一点也意味着,计算结果相应地为数据类型double或decimal。

2.2 时间类型(DateType,TimestampType)

DateType可以理解为年、月、日,TimestampType可以理解为年、月、日、时、分、秒,它们分别对着着Python datetime中的date,datetime,使用示例如下:

%pyspark
# 如果是通过Zeppelin (Apache开源框架)来运行,那么SparkSession和SparkContext对象应该是提前创建好的,不用再创建。
# 所以创建sc对象部分注释掉了
# from pyspark import SparkConf, SparkContext
from datetime import datetime, date
from pyspark.sql.types import StructType, StructField, DateType, TimestampType


# spark = SparkSession.builer\
#         appName('test').\
#         master('yarn').\
#         getOrCreate()
# sc = spark.sparkContext


# Step1:模拟“一行两列”的数据,并通过parallelize方法将其转换为一个RDD source,这个RDD就是关联着数据的RDD。
source = sc.parallelize([(date(2022, 4, 4), datetime(2022, 4, 4, 19, 25, 30))])

'''
Step2:
创建数据模式,需要分别为这两列指定列名、列类型、可否包含空(Null)值;
其中模式(Schema)需要使用StructType表示,每一列的各个属性(列名称、列类型、可否包含空(Null)值)需要使用StructField表示;
第一列的列名为col1,DecimalType,不可包含空(Null)值(False);第二列的列名为col2,列类型为LongType,不可包含空(Null)值(False)。
(注意:实际使用中每列的数据类型并不一定相同)
'''

schema = StructType([StructField('date', DateType(), False),
                    StructField('datetime', TimestampType(), False)])

# Step3:通过rdd的toDF方法,可以创建一个DataFrame;
df = source.toDF(schema)
df.printSchema()
df.show()

# Step4:可以将DataFrame注册为临时视图
df.createOrReplaceTempView('temp_table')


rows = spark.sql(
    'select date, datetime from temp_table').collect()
    
print(rows)

for row in rows:
    print(row[0], type(row[0]))

程序结果如下:
在这里插入图片描述

2.3 其他类型:StringType、BooleanType、BinaryType、NoneType

这几种数据类型的使用方法大致相同,就不一一讲解了,注意BinaryType对应着使用了Python中的bytearray。

%pyspark
# 如果是通过Zeppelin (Apache开源框架)来运行,那么SparkSession和SparkContext对象应该是提前创建好的,不用再创建。
# 所以创建sc对象部分注释掉了
# from pyspark import SparkConf, SparkContext
from pyspark.sql.types import StructType, StructField, StringType, BooleanType, BinaryType, NullType


# spark = SparkSession.builer\
#         appName('test').\
#         master('yarn').\
#         getOrCreate()
# sc = spark.sparkContext


# Step1:模拟“一行两列”的数据,并通过parallelize方法将其转换为一个RDD source,这个RDD就是关联着数据的RDD。
# 两个数字为-2^31,2^31-1,即IntergerType的数字范围
source = sc.parallelize([('str', False, bytearray(range(0, 10)), None)])

'''
Step2:
创建数据模式,需要分别为这两列指定列名、列类型、可否包含空(Null)值;
其中模式(Schema)需要使用StructType表示,每一列的各个属性(列名称、列类型、可否包含空(Null)值)需要使用StructField表示;
'''

schema = StructType([StructField('str', StringType()),
                    StructField('bool', BooleanType()),
                    StructField('bytes', BinaryType()),
                    StructField('none', NullType())])

# Step3:通过rdd的toDF方法,可以创建一个DataFrame;
df = source.toDF(schema)
df.printSchema()
df.show()

# Step4:可以将DataFrame注册为临时视图
df.createOrReplaceTempView('temp_table')


rows = spark.sql(
    'select str, bool, bytes, none from temp_table').collect()
    
print(rows)

for row in rows:
    print((row[0], type(row[0])), (row[1], type(row[1])), (row[2], type(row[2])), sep='|')

运行结果如下:
在这里插入图片描述

2.4 复合数据类型(ArrayType、MapType、StructType)

复合数据类型共有三种:数组(ArrayType)、字典(MapType)、结构体(StructType)。其中:

  • 数组(ArrayType)要求数组元素类型一致;
  • 字典(MapType)要求所有“key”的类型一致,所有“value”的类型一致,但“key”、“value”的类型可以不一致;
  • 结构体(StructType)的元素类型可以不一致。

2.4.1 ArrayType

ArrayType要求指定数组元素类型。

%pyspark
# 如果是通过Zeppelin (Apache开源框架)来运行,那么SparkSession和SparkContext对象应该是提前创建好的,不用再创建。
# 所以创建sc对象部分注释掉了
# from pyspark import SparkConf, SparkContext
from pyspark.sql.types import StructType, StructField, ArrayType, IntegerType


# spark = SparkSession.builer\
#         appName('test').\
#         master('yarn').\
#         getOrCreate()
# sc = spark.sparkContext


# Step1:模拟“一行两列”的数据,并通过parallelize方法将其转换为一个RDD source,这个RDD就是关联着数据的RDD。
# 两个数字为-2^31,2^31-1,即IntergerType的数字范围
source = sc.parallelize([([1, 2, 3], )])

'''
Step2:
创建数据模式,需要分别为这两列指定列名、列类型、可否包含空(Null)值;
其中模式(Schema)需要使用StructType表示,每一列的各个属性(列名称、列类型、可否包含空(Null)值)需要使用StructField表示;
'''

schema = StructType([StructField('array', ArrayType(IntegerType(), False), False)])

# Step3:通过rdd的toDF方法,可以创建一个DataFrame;
df = source.toDF(schema)
df.printSchema()
df.show()

# Step4:可以将DataFrame注册为临时视图
df.createOrReplaceTempView('temp_table')


rows = spark.sql(
    'select array[0], array[1], array[2] from temp_table').collect()
    
print(rows)

结果如下:
在这里插入图片描述

2.4.2 MapType

MapType要求指定键(key)类型和值(value)类型。

%pyspark
# 如果是通过Zeppelin (Apache开源框架)来运行,那么SparkSession和SparkContext对象应该是提前创建好的,不用再创建。
# 所以创建sc对象部分注释掉了
# from pyspark import SparkConf, SparkContext
from pyspark.sql.types import StructType, StructField, MapType, StringType, IntegerType


# spark = SparkSession.builer\
#         appName('test').\
#         master('yarn').\
#         getOrCreate()
# sc = spark.sparkContext


# Step1:模拟“一行两列”的数据,并通过parallelize方法将其转换为一个RDD source,这个RDD就是关联着数据的RDD。
# 两个数字为-2^31,2^31-1,即IntergerType的数字范围
source = sc.parallelize([({'key1': 1, 'key2': 2}, )])

'''
Step2:
创建数据模式,需要分别为这两列指定列名、列类型、可否包含空(Null)值;
其中模式(Schema)需要使用StructType表示,每一列的各个属性(列名称、列类型、可否包含空(Null)值)需要使用StructField表示;
'''

schema = StructType([StructField('col_map', MapType(StringType(), IntegerType(), False), False)])

# Step3:通过rdd的toDF方法,可以创建一个DataFrame;
df = source.toDF(schema)
df.printSchema()
df.show()

# Step4:可以将DataFrame注册为临时视图
df.createOrReplaceTempView('temp_table')


rows = spark.sql(
    'select col_map["key1"], col_map["key2"] from temp_table').collect()
    
print(rows)

结果如下:
在这里插入图片描述

2.4.3 StructType

StructType包含的元素类型可不一致,需要根据元素的次序依次为其指定合适的名称与数据类型。

%pyspark
# 如果是通过Zeppelin (Apache开源框架)来运行,那么SparkSession和SparkContext对象应该是提前创建好的,不用再创建。
# 所以创建sc对象部分注释掉了
# from pyspark import SparkConf, SparkContext
from pyspark.sql.types import StructType, StructField, MapType, IntegerType, FloatType, StringType


# spark = SparkSession.builer\
#         appName('test').\
#         master('yarn').\
#         getOrCreate()
# sc = spark.sparkContext


# Step1:模拟“一行两列”的数据,并通过parallelize方法将其转换为一个RDD source,这个RDD就是关联着数据的RDD。
# 两个数字为-2^31,2^31-1,即IntergerType的数字范围
source = sc.parallelize([((1, 2.0, '3.0'), )])

'''
Step2:
创建数据模式,需要分别为这两列指定列名、列类型、可否包含空(Null)值;
其中模式(Schema)需要使用StructType表示,每一列的各个属性(列名称、列类型、可否包含空(Null)值)需要使用StructField表示;
'''

schema = StructType([StructField('struct', StructType([StructField('first', IntegerType(), False),
                                                        StructField('second', FloatType(), False),
                                                        StructField('third', StringType(), False)]), False)])

# Step3:通过rdd的toDF方法,可以创建一个DataFrame;
df = source.toDF(schema)
df.printSchema()
df.show()

# Step4:可以将DataFrame注册为临时视图
df.createOrReplaceTempView('temp_table')


rows = spark.sql(
    'select struct.first, struct.second, struct.third from temp_table').collect()
    
print(rows)

结果如下:
在这里插入图片描述

综上所述,Spark(Hive)SQL为我们提供了丰富的数据类型,我们需要根据分析数据的实际情况为其选取合适的数据类型(基本类型、复合类型)、尤其是数据类型各自的表示(精度)范围以及数据溢出的情况处理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spark Schema、Hive和Python的数据类型关系,以及Pyspark数据类型详解 的相关文章

随机推荐

  • 【转载】解读USB-IF电池充电规范

    最近学电源管理驱动这一步分 对于电池充电规范不太理解 转载下来自己看 http www eechina com thread 4943 1 1 html 电池充电规范 原有USB2 0规范并没有考虑到使用USB接口为便携式设备的电池进行充电
  • 最基本的根据文本信息生成二维码的源代码

    public class TwoDimensionCode 生成二维码 QRCode 图片 param content 存储内容 param imgPath 图片路径 public void encoderQRCode String con
  • 多元高斯分布(二)——更多关于多元高斯分布

    注意 本文内容来自于吴恩达老师cs229课堂笔记的中文翻译项目 https github com Kivy CN Stanford CS 229 CN 中部分的内容进行翻译学习 更多关于多元高斯分布 介绍 到目前为止的课堂上 多元高斯分布已
  • JAVAFX_Effect效果介绍

    JAVAFX Effect介绍 学习记录 慢慢完善 Bloom 发光效果 InnerShadow 内阴影 Lighting 光照 BoxBlur 方框模糊 DisplacementMap 位移置换 DropShadow 阴影 Perspec
  • 一个动态添加panel 和 删除panel的例子

    unit Unit1 interface uses Windows Messages SysUtils Variants Classes Graphics Controls Forms Dialogs StdCtrls ExtCtrls t
  • python中.item()的讲解

    在pytorch训练时 一般用到 item 比如loss item 我们可以做个简单测试代码看看它的区别 import torch x torch randn 2 2 print x print x 1 1 print x 1 1 item
  • python倒序遍历字符串

    Hello大家好 今天我想和大家分享一个小tips 就是快速倒序遍历字符串 比如现在有一个小需求 是让我们找到一个长字符串里面的最后一个单词 并且返回这个单词的长度 每个单词用空格隔开 那么我们会如何去做这道题呢 我觉得使用倒序遍历 当如果
  • VS2017学习C++问题二(没有与这些操作数匹配的 “<<“ 运算符)

    添加要在此处预编译的标头 ifndef GZDEMO H define GZDEMO H pragma once include
  • 【javascript】2048小游戏

    目录 什么是2048 游戏状态机 游戏界面绘制 3 1 界面 3 2 数字的背景颜色 分数逻辑 4 1 加分 4 2 更新最高分 方向控制逻辑 5 1 数组 5 2 随机数 5 3 初始化 5 4 判断数组是否全部填满 5 5 判断方格是否
  • vue img video src动态设置

    图片存放位置 前端 img data中 url created中 created this select method中 async select var data res await this axios get select this
  • 手写Spring框架(二)

    目录 IOC相关类 BeanDefinitionReader BeanDefinition ApplicationContext BeanWrapper 简化后的DispatcherServlet 本章源码 https github com
  • nodejs require() of ES Module xxxxx not supported.

    某些 npm 库在 typescript 中使用时会存在这种情况 说一个解决方法 就是在 npm 官网中查看对应库的 version 看看是否有 cjs 版本 或者回退到上一个大版本
  • Java面试面经大合集(含答案),大厂越来越简单进了,

    Java面试笔记 尝到甜头的他开始得寸进尺 说5K的工资在北京根本生活不下去 没办法 我这人就是心软 在他一顿苦苦哀求后就答应再帮他想想办法 开会的时候灵光一闪想到了在阿里内部给他找两份大佬写的面试笔记 于是就有了最开始的一幕 被大佬逮到的
  • 前缀和实例4(和可被k整除的子数组)

    题目 给定一个整数数组 nums 和一个整数 k 返回其中元素之和可被 k 整除的 连续 非空 子数组 的数目 子数组 是数组的 连续 部分 示例 1 输入 nums 4 5 0 2 3 1 k 5 输出 7 解释 有 7 个子数组满足其元
  • 三个方法解决php并发问题

    福利 网络安全重磅福利 入门 进阶全套282G学习资源包免费分享 解决php并发问题的方法有很多 具体可以使用MySQL的行级锁 乐观锁和Redis的分布式锁等技术来解决 此外 还可以使用消息队列 多进程 多线程等技术来解决php并发问题
  • 人机交互-2-交互设计的原则与方法

    交互设计的原则与方法 交互设计中的问题 尽量减少用户需要记忆的部分 缺乏反馈 1 目标Goal vs 意图Intention 单个目标可对应多个意图 举例 删除文档中的部分内容的目标 意图1 通过编辑菜单删除 意图2 通过删除按钮删除 每个
  • CTF_Web_[GXYCTF2019]Ping Ping Ping

    一 题目 Ping Ping Ping 二 靶机信息链接 靶机信息 剩余时间 10072s http 70284b15 7c4e 4548 8b04 aadbc6e669f5 node4 buuoj cn 81 三 靶机链接页面 四 分析
  • Hector-SLAM初使用

    Hector SLAM初使用 首先把二维雷达的包拷贝到笔记本上 编译一次通过 连接也没有问题 rviz中可以看到原始激光 想演示一下二维激光雷达的SLAM建图 Hector SLAM相对比较容易 主要参考了下面的几篇博客 SLAM hect
  • 如何使用PowerDesigner软件进行数据库设计(多对多关系)

    如何使用PowerDesigner软件进行数据库设计 多对多关系 1 多对多关系示例 2 创建CDM 3 建立实体之间的联系 4 检查CDM 5 将CDM转换成PDM 6 由PDM生成sql文件 1 多对多关系示例 1 表名和字段 学生表
  • Spark Schema、Hive和Python的数据类型关系,以及Pyspark数据类型详解

    文章目录 1 概念阐述 1 1 Spark中支持的数据类型 1 2 Spark中的基本类型与Python数据类型 Hive表数据类型的对应关系 1 3 Hive中数字类型各自的表示范围 2 分类型介绍每种数据类型的详情 2 1 数字类型 B