spark中RDD的转化操作和行动操作
本文主要是讲解spark里RDD的基础操作。RDD是spark特有的数据模型,谈到RDD就会提到什么弹性分布式数据集,什么有向无环图,本文暂时不去展开这些高深概念,在阅读本文时候,大家可以就把RDD当作一个数组,这样的理解对我们学习RDD的API是非常有帮助的。本文所有示例代码都是使用scala语言编写的。
Spark里的计算都是操作RDD进行,那么学习RDD的第一个问题就是如何构建RDD,构建RDD从数据来源角度分为两类:第一类是从内存里直接读取数据,第二类就是从文件系统里读取,当然这里的文件系统种类很多常见的就是HDFS以及本地文件系统了。
第一类方式从内存里构造RDD,使用的方法:makeRDD和parallelize方法,如下代码所示:
/* 使用makeRDD创建RDD */
/* List */
val
rdd
01
=
sc.makeRDD(List(
1
,
2
,
3
,
4
,
5
,
6
))
val
r
01
=
rdd
01
.map { x
=
> x * x }
println(r
01
.collect().mkString(
","
))
/* Array */
val
rdd
02
=
sc.makeRDD(Array(
1
,
2
,
3
,
4
,
5
,
6
))
val
r
02
=
rdd
02
.filter { x
=
> x <
5
}
println(r
02
.collect().mkString(
","
))
val
rdd
03
=
sc.parallelize(List(
1
,
2
,
3
,
4
,
5
,
6
),
1
)
val
r
03
=
rdd
03
.map { x
=
> x +
1
}
println(r
03
.collect().mkString(
","
))
/* Array */
val
rdd
04
=
sc.parallelize(List(
1
,
2
,
3
,
4
,
5
,
6
),
1
)
val
r
04
=
rdd
04
.filter { x
=
> x >
3
}
println(r
04
.collect().mkString(
","
))
大家看到了RDD本质就是一个数组,因此构造数据时候使用的是List(链表)和Array(数组)类型。
第二类方式是通过文件系统构造RDD,代码如下所示:
val
rdd
:
RDD[String]
=
sc.textFile(
"file:///D:/sparkdata.txt"
,
1
)
val
r
:
RDD[String]
=
rdd.flatMap { x
=
> x.split(
","
) }
println(r.collect().mkString(
","
))
这里例子使用的是本地文件系统,所以文件路径协议前缀是file://。
构造了RDD对象了,接下来就是如何操作RDD对象了,RDD的操作分为转化操作(transformation)和行动操作(action),RDD之所以将操作分成这两类这是和RDD惰性运算有关,当RDD执行转化操作时候,实际计算并没有被执行,只有当RDD执行行动操作时候才会促发计算任务提交,执行相应的计算操作。区别转化操作和行动操作也非常简单,转化操作就是从一个RDD产生一个新的RDD操作,而行动操作就是进行实际的计算。
下面是RDD的基础操作API介绍:
常见的转化操作
示例数据{1,2,3,3}
- map
目的:将函数应用于RDD中的每个元素, 将返回值构成新的RDD
示例:rdd.map(x=>x+1)
结果:{2,3,4,4}
- flatMap
目的:将函数应用于RDD中的每个元素, 将返回的迭代器的所有内容构成新的RDD。通常用来切分单词
示例:rdd.flatMap(x => x.to(3))
结果:{1,2,3,2,3,3}
函数名 | 目的 | 示例 | 结果 | 备注 |
---|---|---|---|---|
map() | 将函数应用于RDD中的每个元素, 将返回值构成新的RDD | rdd.map(x=>x+1) | {2,3,4,4} | |
flatMap() | 将函数应用于RDD中的每个元素, 将返回的迭代器的所有内容构成新的RDD。通常用来切分单词 | rdd.flatMap(x => x.to(3)) | {1,2,3,2,3,3} | |
filter() | 返回一个由通过传给filter()的函数的元素组成的RDD | rdd.filter(x => x!=1) | {2,3,3} | |
distinct() | 去重 | rdd.distinct() | {1,2,3} | 开销很大,因为需要将所有数据通过网络进行混洗 |
sample(withReplacement, fraction, [seed]) | 对RDD采样,以及是否替换 | rdd.sample(false, 0.5) | 非确定 |
示例数据{1,2,3}{3,4,5}
函数名 | 目的 | 示例 | 结果 | 备注 |
---|---|---|---|---|
union() | 生成一个包含两个RDD中所有元素的RDD | rdd.union(other) | {1,2,3,3,4,5} | |
intersection() | 求两个RDD共同元素的RDD | rdd.intersection(other) | {3} | 性能差,需要网络混洗数据来发现共同元素 |
subtract() | 移除一个RDD中的内容 | rdd.subtract(other) | {1,2} | 需要数据混洗 |
cartesian() | 与另一个RDD的笛卡尔积 | rdd.cartesian(other) | {{1,3},{1,4},...,{3,5}} | 求大规模RDD开销巨大 |
常见的行为操作
示例数据{1,2,3,3}
函数名 | 目的 | 示例 | 结果 | 备注 |
---|---|---|---|---|
collect() | 返回RDD中的所有元素 | rdd.collect() | {1,2,3,3} | |
count() | RDD中的元素个数 | rdd.count() | 4 | |
countByValue() | 各元素在RDD中出现的次数 | rdd.countByValue() | {(1,1),(2,1),(3,2)} | |
take(num) | 从RDD中返回num个元素 | rdd.take(2) | {1,2} | |
top(num) | 从RDD中返回最前面的num个元素 | rdd.top(2) | {3,3} | |
takeOrdered(num)(ordering) | 从RDD中按照提供的顺序返回最前面的num个元素 | rdd.takeOrdered(2)(myOrdering) | (3,3) | |
takeSample(withReplacement, num, [seed]) | 从RDD中返回任意一些元素 | rdd.takeSample(false, 1) | ||
reduce(func) | 并行整合RDD中所有数据(例如sum) | rdd.reduce((x,y)=>x+y) | 9 | |
fold(zero)(func) | 和reduce一样,但需要提供初始值 | rdd.fold(0)((x,y)=>x+y) | 9 | |
aggregate(zeroValue)(seqOp, combOp) | 和reduce相似,但通常不返回同类型的函数 | rdd.aggregate(0,0)((x,y)=>(x._1+y,x._2+1),(x,y)=>(x._1+y._1,x._2+y._2)) | {9,4} | |
foreach(func) | 对RDD中的每个元素使用给定的函数 | rdd.foreach(func) |
持久化
val result = input.map(x => x * x)
result.persist(StorageLevel.DISK_ ONLY)
println(result.count())
println(result.collect().mkString(","))
级别 | 使用的空间 | CPU时间 | 是否在内存中 | 是否在硬盘中 | 备注 |
---|---|---|---|---|---|
MEMORY_ONLY | 高 | 低 | 是 | 否 | |
MEMORY_ONLY_SER | 低 | 高 | 是 | 否 | |
MEMORY_AND_DISK | 高 | 中等 | 部分 | 部分 | 如果数据在内存中放不下, 则溢写到磁盘上 |
MEMORY_AND_DISK_SER | 低 | 高 | 部分 | 部分 | 如果数据在内存中放不下, 则溢写到磁盘上。在内存中存放序列化后的数据 |
DISK_ONLY | 低 | 高 | 否 | 是 |
下面是以上API操作的示例代码,如下:
转化操作:
val
rddInt
:
RDD[Int]
=
sc.makeRDD(List(
1
,
2
,
3
,
4
,
5
,
6
,
2
,
5
,
1
))
val
rddStr
:
RDD[String]
=
sc.parallelize(Array(
"a"
,
"b"
,
"c"
,
"d"
,
"b"
,
"a"
),
1
)
val
rddFile
:
RDD[String]
=
sc.textFile(path,
1
)
val
rdd
01
:
RDD[Int]
=
sc.makeRDD(List(
1
,
3
,
5
,
3
))
val
rdd
02
:
RDD[Int]
=
sc.makeRDD(List(
2
,
4
,
5
,
1
))
/* map操作 */
println(
"======map操作======"
)
println(rddInt.map(x
=
> x +
1
).collect().mkString(
","
))
println(
"======map操作======"
)
/* filter操作 */
println(
"======filter操作======"
)
println(rddInt.filter(x
=
> x >
4
).collect().mkString(
","
))
println(
"======filter操作======"
)
/* flatMap操作 */
println(
"======flatMap操作======"
)
println(rddFile.flatMap { x
=
> x.split(
","
) }.first())
println(
"======flatMap操作======"
)
/* distinct去重操作 */
println(
"======distinct去重======"
)
println(rddInt.distinct().collect().mkString(
","
))
println(rddStr.distinct().collect().mkString(
","
))
println(
"======distinct去重======"
)
/* union操作 */
println(
"======union操作======"
)
println(rdd
01
.union(rdd
02
).collect().mkString(
","
))
println(
"======union操作======"
)
/* intersection操作 */
println(
"======intersection操作======"
)
println(rdd
01
.intersection(rdd
02
).collect().mkString(
","
))
println(
"======intersection操作======"
)
/* subtract操作 */
println(
"======subtract操作======"
)
println(rdd
01
.subtract(rdd
02
).collect().mkString(
","
))
println(
"======subtract操作======"
)
/* cartesian操作 */
println(
"======cartesian操作======"
)
println(rdd
01
.cartesian(rdd
02
).collect().mkString(
","
))
println(
"======cartesian操作======"
)
val
rddInt
:
RDD[Int]
=
sc.makeRDD(List(
1
,
2
,
3
,
4
,
5
,
6
,
2
,
5
,
1
))
val
rddStr
:
RDD[String]
=
sc.parallelize(Array(
"a"
,
"b"
,
"c"
,
"d"
,
"b"
,
"a"
),
1
)
/* count操作 */
println(
"======count操作======"
)
println(rddInt.count())
println(
"======count操作======"
)
/* countByValue操作 */
println(
"======countByValue操作======"
)
println(rddInt.countByValue())
println(
"======countByValue操作======"
)
/* reduce操作 */
println(
"======countByValue操作======"
)
println(rddInt.reduce((x ,y)
=
> x + y))
println(
"======countByValue操作======"
)
/* fold操作 */
println(
"======fold操作======"
)
println(rddInt.fold(
0
)((x ,y)
=
> x + y))
println(
"======fold操作======"
)
/* aggregate操作 */
println(
"======aggregate操作======"
)
val
res
:
(Int,Int)
=
rddInt.aggregate((
0
,
0
))((x,y)
=
> (x.
_
1
+ x.
_
2
,y),(x,y)
=
> (x.
_
1
+ x.
_
2
,y.
_
1
+ y.
_
2
))
println(res.
_
1
+
","
+ res.
_
2
)
println(
"======aggregate操作======"
)
/* foeach操作 */
println(
"======foeach操作======"
)
println(rddStr.foreach { x
=
> println(x) })
println(
"======foeach操作======"
)
RDD操作暂时先学习到这里,剩下的内容在下一篇里再谈了,下面我要说说如何开发spark,安装spark的内容我后面会使用专门的文章进行讲解,这里我们假设已经安装好了spark,那么我们就可以在已经装好的spark服务器上使用spark-shell进行与spark交互的shell,这里我们直接可以敲打代码编写spark程序。但是spark-shell毕竟使用太麻烦,而且spark-shell一次只能使用一个用户,当另外一个用户要使用spark-shell就会把前一个用户踢掉,而且shell也没有IDE那种代码补全,代码校验的功能,使用起来很是痛苦。
不过spark的确是一个神奇的框架,这里的神奇就是指spark本地开发调试非常简单,本地开发调试不需要任何已经装好的spark系统,我们只需要建立一个项目,这个项目可以是java的也可以是scala,然后我们将spark-assembly-1.6.1-hadoop2.6.0.jar这样的jar放入项目的环境里,这个时候我们就可以在本地开发调试spark程序了。
大家请看我们装有scala插件的eclipse里的完整代码:
package
cn.com.sparktest
import
org.apache.spark.SparkConf
import
org.apache.spark.SparkConf
import
org.apache.spark.SparkContext
import
org.apache.spark.rdd.RDD
object
SparkTest {
val
conf
:
SparkConf
=
new
SparkConf().setAppName(
"xtq"
).setMaster(
"local[2]"
)
val
sc
:
SparkContext
=
new
SparkContext(conf)
/**
* 创建数据的方式--从内存里构造数据(基础)
*/
def
createDataMethod()
:
Unit
=
{
/* 使用makeRDD创建RDD */
/* List */
val
rdd
01
=
sc.makeRDD(List(
1
,
2
,
3
,
4
,
5
,
6
))
val
r
01
=
rdd
01
.map { x
=
> x * x }
println(
"===================createDataMethod:makeRDD:List====================="
)
println(r
01
.collect().mkString(
","
))
println(
"===================createDataMethod:makeRDD:List====================="
)
/* Array */
val
rdd
02
=
sc.makeRDD(Array(
1
,
2
,
3
,
4
,
5
,
6
))
val
r
02
=
rdd
02
.filter { x
=
> x <
5
}
println(
"===================createDataMethod:makeRDD:Array====================="
)
println(r
02
.collect().mkString(
","
))
println(
"===================createDataMethod:makeRDD:Array====================="
)
/* 使用parallelize创建RDD */
/* List */
val
rdd
03
=
sc.parallelize(List(
1
,
2
,
3
,
4
,
5
,
6
),
1
)
val
r
03
=
rdd
03
.map { x
=
> x +
1
}
println(
"===================createDataMethod:parallelize:List====================="
)
println(r
03
.collect().mkString(
","
))
println(
"===================createDataMethod:parallelize:List====================="
)
/* Array */
val
rdd
04
=
sc.parallelize(List(
1
,
2
,
3
,
4
,
5
,
6
),
1
)
val
r
04
=
rdd
04
.filter { x
=
> x >
3
}
println(
"===================createDataMethod:parallelize:Array====================="
)
println(r
04
.collect().mkString(
","
))
println(
"===================createDataMethod:parallelize:Array====================="
)
}
/**
* 创建Pair Map
*/
def
createPairRDD()
:
Unit
=
{
val
rdd
:
RDD[(String,Int)]
=
sc.makeRDD(List((
"key01"
,
1
),(
"key02"
,
2
),(
"key03"
,
3
)))
val
r
:
RDD[String]
=
rdd.keys
println(
"===========================createPairRDD================================="
)
println(r.collect().mkString(
","
))
println(
"===========================createPairRDD================================="
)
}
/**
* 通过文件创建RDD
* 文件数据:
* key01,1,2.3
key02,5,3.7
key03,23,4.8
key04,12,3.9
key05,7,1.3
*/
def
createDataFromFile(path
:
String)
:
Unit
=
{
val
rdd
:
RDD[String]
=
sc.textFile(path,
1
)
val
r
:
RDD[String]
=
rdd.flatMap { x
=
> x.split(
","
) }
println(
"=========================createDataFromFile=================================="
)
println(r.collect().mkString(
","
))
println(
"=========================createDataFromFile=================================="
)
}
/**
* 基本的RDD操作
*/
def
basicTransformRDD(path
:
String)
:
Unit
=
{
val
rddInt
:
RDD[Int]
=
sc.makeRDD(List(
1
,
2
,
3
,
4
,
5
,
6
,
2
,
5
,
1
))
val
rddStr
:
RDD[String]
=
sc.parallelize(Array(
"a"
,
"b"
,
"c"
,
"d"
,
"b"
,
"a"
),
1
)
val
rddFile
:
RDD[String]
=
sc.textFile(path,
1
)
val
rdd
01
:
RDD[Int]
=
sc.makeRDD(List(
1
,
3
,
5
,
3
))
val
rdd
02
:
RDD[Int]
=
sc.makeRDD(List(
2
,
4
,
5
,
1
))
/* map操作 */
println(
"======map操作======"
)
println(rddInt.map(x
=
> x +
1
).collect().mkString(
","
))
println(
"======map操作======"
)
/* filter操作 */
println(
"======filter操作======"
)
println(rddInt.filter(x
=
> x >
4
).collect().mkString(
","
))
println(
"======filter操作======"
)
/* flatMap操作 */
println(
"======flatMap操作======"
)
println(rddFile.flatMap { x
=
> x.split(
","
) }.first())
println(
"======flatMap操作======"
)
/* distinct去重操作 */
println(
"======distinct去重======"
)
println(rddInt.distinct().collect().mkString(
","
))
println(rddStr.distinct().collect().mkString(
","
))
println(
"======distinct去重======"
)
/* union操作 */
println(
"======union操作======"
)
println(rdd
01
.union(rdd
02
).collect().mkString(
","
))
println(
"======union操作======"
)
/* intersection操作 */
println(
"======intersection操作======"
)
println(rdd
01
.intersection(rdd
02
).collect().mkString(
","
))
println(
"======intersection操作======"
)
/* subtract操作 */
println(
"======subtract操作======"
)
println(rdd
01
.subtract(rdd
02
).collect().mkString(
","
))
println(
"======subtract操作======"
)
/* cartesian操作 */
println(
"======cartesian操作======"
)
println(rdd
01
.cartesian(rdd
02
).collect().mkString(
","
))
println(
"======cartesian操作======"
)
}
/**
* 基本的RDD行动操作
*/
def
basicActionRDD()
:
Unit
=
{
val
rddInt
:
RDD[Int]
=
sc.makeRDD(List(
1
,
2
,
3
,
4
,
5
,
6
,
2
,
5
,
1
))
val
rddStr
:
RDD[String]
=
sc.parallelize(Array(
"a"
,
"b"
,
"c"
,
"d"
,
"b"
,
"a"
),
1
)
/* count操作 */
println(
"======count操作======"
)
println(rddInt.count())
println(
"======count操作======"
)
/* countByValue操作 */
println(
"======countByValue操作======"
)
println(rddInt.countByValue())
println(
"======countByValue操作======"
)
/* reduce操作 */
println(
"======countByValue操作======"
)
println(rddInt.reduce((x ,y)
=
> x + y))
println(
"======countByValue操作======"
)
/* fold操作 */
println(
"======fold操作======"
)
println(rddInt.fold(
0
)((x ,y)
=
> x + y))
println(
"======fold操作======"
)
/* aggregate操作 */
println(
"======aggregate操作======"
)
val
res
:
(Int,Int)
=
rddInt.aggregate((
0
,
0
))((x,y)
=
> (x.
_
1
+ x.
_
2
,y),(x,y)
=
> (x.
_
1
+ x.
_
2
,y.
_
1
+ y.
_
2
))
println(res.
_
1
+
","
+ res.
_
2
)
println(
"======aggregate操作======"
)
/* foeach操作 */
println(
"======foeach操作======"
)
println(rddStr.foreach { x
=
> println(x) })
println(
"======foeach操作======"
)
}
def
main(args
:
Array[String])
:
Unit
=
{
println(System.getenv(
"HADOOP_HOME"
))
createDataMethod()
createPairRDD()
createDataFromFile(
"file:///D:/sparkdata.txt"
)
basicTransformRDD(
"file:///D:/sparkdata.txt"
)
basicActionRDD()
Spark执行时候我们需要构造一个SparkContenxt的环境变量,构造环境变量时候需要构造一个SparkConf对象,例如代码:setAppName("xtq").setMaster("local[2]")
appName就是spark任务名称,master为local[2]是指使用本地模式,启动2个线程完成spark任务。
在eclipse里运行spark程序时候,会报出如下错误:
ava.io.IOException
:
Could not locate executable
null
\bin\winutils.exe in the Hadoop binaries.
at org.apache.hadoop.util.Shell.getQualifiedBinPath(Shell.java
:
355
)
at org.apache.hadoop.util.Shell.getWinUtilsPath(Shell.java
:
370
)
at org.apache.hadoop.util.Shell.<clinit>(Shell.java
:
363
)
at org.apache.hadoop.util.StringUtils.<clinit>(StringUtils.java
:
79
)
at org.apache.hadoop.security.Groups.parseStaticMapping(Groups.java
:
104
)
at org.apache.hadoop.security.Groups.<init>(Groups.java
:
86
)
at org.apache.hadoop.security.Groups.<init>(Groups.java
:
66
)
at org.apache.hadoop.security.Groups.getUserToGroupsMappingService(Groups.java
:
280
)
at org.apache.hadoop.security.UserGroupInformation.initialize(UserGroupInformation.java
:
271
)
at org.apache.hadoop.security.UserGroupInformation.ensureInitialized(UserGroupInformation.java
:
248
)
at org.apache.hadoop.security.UserGroupInformation.loginUserFromSubject(UserGroupInformation.java
:
763
)
at org.apache.hadoop.security.UserGroupInformation.getLoginUser(UserGroupInformation.java
:
748
)
at org.apache.hadoop.security.UserGroupInformation.getCurrentUser(UserGroupInformation.java
:
621
)
at org.apache.spark.util.Utils$$anonfun$getCurrentUserName$
1
.apply(Utils.scala
:
2160
)
at org.apache.spark.util.Utils$$anonfun$getCurrentUserName$
1
.apply(Utils.scala
:
2160
)
at scala.Option.getOrElse(Option.scala
:
120
)
at org.apache.spark.util.Utils$.getCurrentUserName(Utils.scala
:
2160
)
at org.apache.spark.SparkContext.<init>(SparkContext.scala
:
322
)
at cn.com.sparktest.SparkTest$.<init>(SparkTest.scala
:
10
)
at cn.com.sparktest.SparkTest$.<clinit>(SparkTest.scala)
at cn.com.sparktest.SparkTest.main(SparkTest.scala)
该错误不会影响程序的运算,但总是让人觉得不舒服,这个问题是因为spark运行依赖于hadoop,可是在window下其实是无法安装hadoop,只能使用cygwin模拟安装,而新版本的hadoop在windows下使用需要使用winutils.exe,解决这个问题很简单,就是下载一个winutils.exe,注意下自己操作系统是32位还是64位,找到对应版本,然后放置在这样的目录下:
D:\hadoop\bin\winutils.exe
然后再环境变量里定义HADOOP_HOME= D:\hadoop
环境变量的改变要重启eclipse,这样环境变量才会生效,这个时候程序运行就不会报出错误了。
转自:http://www.cnblogs.com/sharpxiajun/p/5506822.html
spark中RDD的转化操作和行动操作的更多相关文章
- [Spark] Pair RDD常见转化操作
本篇博客中的操作都在 ./bin/pyspark 中执行. 对单个 Pair RDD 的转化操作 下面会对 Pair RDD 的一些转化操作进行解释.先假设我们有下面这些RDD(在pyspark中操作 ...
- Spark中RDD的常用操作(Python)
弹性分布式数据集(RDD) Spark是以RDD概念为中心运行的.RDD是一个容错的.可以被并行操作的元素集合.创建一个RDD有两个方法:在你的驱动程序中并行化一个已经存在的集合:从外部存储系统中引用 ...
- Spark 中 RDD的运行机制
1. RDD 的设计与运行原理 Spark 的核心是建立在统一的抽象 RDD 之上,基于 RDD 的转换和行动操作使得 Spark 的各个组件可以无缝进行集成,从而在同一个应用程序中完成大数据计算任务 ...
- 关于Spark中RDD的设计的一些分析
RDD, Resilient Distributed Dataset,弹性分布式数据集, 是Spark的核心概念. 对于RDD的原理性的知识,可以参阅Resilient Distributed Dat ...
- 【原创】大叔问题定位分享(27)spark中rdd.cache
spark 2.1.1 spark应用中有一些task非常慢,持续10个小时,有一个task日志如下: 2019-01-24 21:38:56,024 [dispatcher-event-loop-2 ...
- spark中RDD的transformation&action
简介: 1,transformation是得到一个新的RDD,方式很多,比如从数据源生成一个新的RDD,从RDD生成一个新的RDD 2,action是得到一个值,或者一个结果(直接将RDDcache到 ...
- Spark中RDD转换成DataFrame的两种方式(分别用Java和Scala实现)
一:准备数据源 在项目下新建一个student.txt文件,里面的内容为: ,zhangsan, ,lisi, ,wanger, ,fangliu, 二:实现 Java版: 1.首先新建一个s ...
- Spark之 RDD
简介 RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可并行计算的集合. Resilien ...
- Spark核心RDD、什么是RDD、RDD的属性、创建RDD、RDD的依赖以及缓存、
1:什么是Spark的RDD??? RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可并行 ...
随机推荐
- Maven 那点事儿(转)
0. 前言 Jason Van Zyl,在 Java 十大风云人物排行榜上或许会看到他. 这兄弟是干嘛的? 他就是 Maven 的创始人,人们都尊称他为“Maven 他爸”. 毋庸置疑,Jason 也 ...
- 算法-链的操作(一)-合并两个排序的链接(no.25)
合并两个排序的链接(no.25) 把下面连个排好序的链,从小到大排序链接. list1 : 1 -> 6 -> 8 list2 : 2-> 5 -> 9 def merge(h ...
- 编写Python脚本进行ARP欺骗
1.系统环境:Ubuntu 16.04 Python版本:2.7 2.攻击机器:Ubuntu(192.16.0.14) 目标机器:Windows 7(192.168.0.9) 网关:(192.168. ...
- C/C++ assert()函数用法总结
1. 简介 assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行. 原型定义: #include <assert.h>void ass ...
- MySQL主从复制报错1594处理【转】
一.问题描述 Mysql主从复制模式中,slave上报错 “relay log read failure”,导致主从同步停止. mysql> show slave status\G ****** ...
- replicate_wild_do_table和replicate-wild-ignore-table的使用【转】
使用replicate_do_db和replicate_ignore_db时有一个隐患,跨库更新时会出错. 如在Master(主)服务器上设置 replicate_do_db=test(my.conf ...
- vue中原生file上传图片
效果 视图层 <el-form-item class="file-box" label="微信分享图片url链接" prop="wx_share ...
- python3+requests库框架设计06-测试脚本
在项目下新建TestCase文件夹,然后新建.py文件在文件中写关于接口具体的测试脚本,一般我喜欢按照模块来分,一个模块一个.py文件,建议以test开头命名文件 把配置文件改成这样 url:http ...
- Python3学习笔记28-HtmlTestRunner
HtmlTestRunner是unittest模块下的一个拓展,用来生成测试报告.原生的可以自己找下下载地址,原生的看着比较丑.这次使用的是经过一些大佬优化之后的.具体GitHub地址:https:/ ...
- VS2008中 ATL CLR MFC Win32 区别
ATL用于编写COM程序,CLR是.NET的公共语言运行库,MFC是指MFC类库,MFC程序是用这些类库做出的程序,WIN32常规就是不用MFC,使用API函数编的程序.MFC.ATL和CLR是VC2 ...