Spark编程-RDD

news2024/12/23 4:00:38

RDD创建方式

第一种:

        读取外部数据集。例如:从本地文件加载数据集,或者从HDFS文件系统、HBase等外部数据源中加载数据集。

        Spark可以支持文本文件、SequenceFile文件(Hadoop提供的 SequenceFile是一个由二进制序列化过的key/value的字节流组成的文本存储文件)和其他符合Hadoop InputFormat格式的文件。
第二种:

        调用SparkContext的parallelize方法,在Driver中一个已经存在的集合(数组)上创建。

        eg:工作中基本上都是直接接口读取数据集,然后转换一下,例如下面代码

var gis_data = s.get(xxx).asInstanceOf[org.apache.spark.sql.DataFrame]

从本地文件中获取RDD

        Spark采用textFile()方法来从文件系统中加载数据创建RDD,该方法把文件的URI作为参数,这个URI可以是本地文件系统的地址,或者是分布式文件系统HDFS的地址,或者是Amazon S3的地址等等。

import org.apache.spark.{SparkConf, SparkContext}

object wcPerson {
  def main (args:Array[String]): Unit ={
    val conf = new SparkConf().setAppName("wcPerson").setMaster("local[1]")
    val sc = new SparkContext(conf)
    val inputFile = sc.textFile("D:\\workspace\\spark\\src\\main\\Data\\person")
    val wc = inputFile.flatMap(line => line.split(","))
      .map(word => (word,1)).reduceByKey((a,b) => a + b)
    wc.foreach(println)
  }
}

从HDFS文件系统中加载数据

在Spark-shell界面,sc读取hdfs上的文件

scala> val lines = sc.textFile("hdfs://localhost:9000/user/hadoop/testspark.txt")
scala> val lines = sc.textFile("/user/hadoop/testspark.txt")
scala> val lines = sc.textFile("testspark.txt")

 sc读取注意事项

        在使用Spark读取文件时,需要说明以下几点:
        (1)如果使用了本地文件系统的路径,那么,必须要保证在所有的worker节点上,也都能够采用相同的路径访问到该文件,比如,可以把该文件拷贝到每个worker节点上,或者也可以使用网络挂载共享文件系统。
        (2)textFile()方法的输入参数,可以是文件名,也可以是目录,也可以是压缩文件等。比如,textFile("/my/directory"), textFile("/my/directory/*.txt"), and textFile("/my/directory/*.gz").
        (3)textFile()方法也可以接受第2个输入参数(可选),用来指定分区的数目。默认情况下,Spark会为HDFS的每个block创建一个分区(HDFS中每个block默认是128MB)。你也可以提供一个比block数量更大的值作为分区数目,但是,你不能提供一个小于block数量的值作为分区数目。

并行集合创建RDD

        调用SparkContext的parallelize方法,在Driver中一个已经存在的集合(数组)上创建。

使用数组创建

scala> val array = Array(11,22,33,23,4,545)
array: Array[Int] = Array(11, 22, 33, 23, 4, 545)
scala> val rdd = sc.parallelize(array)
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[6] at parallelize at <console>:24

 使用列表创建

scala> val list = List(11,234,234,5425,342)
list: List[Int] = List(11, 234, 234, 5425, 342)
scala> val rdd1 = sc.parallelize(list)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[7] at parallelize at <console>:24

RDD操作(转换与行动)

        RDD的操作有两种,一种是 转换(Transformation),一种是行动类(action),对于RDD而言,每一次转换操作都会产生不同的RDD,供给下一个“转换”使用。转换得到的,RDD是惰性求值的,也就是说,整个转换过程只是记录了转换的轨迹,并不会发生真正的计算,只有遇到行动操作时,才会发生真正的计算,开始从血缘关系源头开始,进行物理的转换操作。
Spark常见的转换(Transformation)操作

filter(func):                 筛选出满足函数func的元素,并返回一个新的数据集
map(func):                 将每个元素传递到函数func中,并将结果返回为一个新的数据集
flatMap(func):            与map()相似,但每个输入元素都可以映射到0或多个输出结果
groupByKey():           应用于(K,V)键值对的数据集时,返回一个新的(K, Iterable)形式的数据集
reduceByKey(func):   应用于(K,V)键值对的数据集时,返回一个新的(K, V)形式的数据集,其中的每个值是将每个key传递到函数func中进行聚合

样例代码

// 创建一个包含整数的RDD
val nums = sc.parallelize(List(1, 2, 3, 4, 5))
// 使用filter()筛选出偶数
val even_nums = nums.filter(x => x % 2 == 0)
println(even_nums.collect().mkString(", "))  
// 输出 2, 4

// 使用map()将每个元素加倍
val doubled_nums = nums.map(x => x * 2)
println(doubled_nums.collect().mkString(", "))  
// 输出 2, 4, 6, 8, 10

// 使用flatMap()将每个元素拆分成多个字符
val words = sc.parallelize(List("hello", "world", "spark"))
val chars = words.flatMap(x => x.toList)
println(chars.collect().mkString(", "))  
// 输出 h, e, l, l, o, w, o, r, l, d, s, p, a, r, k

// 创建一个键值对的RDD
val pairs = sc.parallelize(List((1, "apple"), (2, "banana"), (1, "orange"), (2, "grape")))
// 使用groupByKey()按键分组
val grouped_pairs = pairs.groupByKey()
println(grouped_pairs.collect().mkString(", "))  
// 输出 (1, CompactBuffer(apple, orange)), (2, CompactBuffer(banana, grape))

// 使用reduceByKey()将相同键的值相加
val sum_by_key = pairs.reduceByKey((x, y) => x + y)
println(sum_by_key.collect().mkString(", "))  
// 输出 (1, appleorange), (2, bananagrape)

单value

(1)map
(2)mapPartitions
(3)mapPartitionsWithIndex
(4)flatMap
(5)glom
(6)groupBy
(7)filter
(8)sample
(9)distinct
(10)coalesce
(11)repartition
(12)sortBy
(13)pipe

双Value

(1)intersection
(2)union
(3)subtract
(4)zip

key-value

(1)partitionBy
(2)reduceByKey
(3)groupByKey
(4)aggregateByKey
(5)foldByKey
(6)combineByKey
(7)sortByKey
(8)mapValues
(9)join
(10)cogroup

        

Spark中的action算子

        行动操作是真正触发计算的地方。Spark程序执行到行动操作时,才会执行真正的计算,从文件中加载数据,完成一次又一次转换操作,最终,完成行动操作得到结果。
下面列出一些常见的行动操作(Action API):
count()                     返回数据集中的元素个数
collect()                    以数组的形式返回数据集中的所有元素
first()                        返回数据集中的第一个元素
take(n)                     以数组的形式返回数据集中的前n个元素
reduce(func)            通过函数func(输入两个参数并返回一个值)聚合数据集中的元素
foreach(func)           将数据集中的每个元素传递到函数func中运行

代码样例:

假设我们有一个包含整数的示例数据集:
val data = Seq(1, 2, 3, 4, 5)
// count() 返回数据集中的元素个数:
val count = data.count()
println(count)  // 输出 5

// collect() 以数组的形式返回数据集中的所有元素
val collected = data.collect()
println(collected.mkString(", "))  // 输出 1, 2, 3, 4, 5

// first() 返回数据集中的第一个元素:
val firstElement = data.first()
println(firstElement)  // 输出 1

// take(n) 以数组的形式返回数据集中的前n个元素:
val taken = data.take(3)
println(taken.mkString(", "))  // 输出 1, 2, 3

// reduce(func) 通过函数func(输入两个参数并返回一个值)聚合数据集中的元素:
val sum = data.reduce((x, y) => x + y)
println(sum)  // 输出 15,即 1 + 2 + 3 + 4 + 5

//foreach(func) 将数据集中的每个元素传递到函数func中运行:
data.foreach(x => println(x * 2))  // 输出每个元素的两倍值

惰性机制(懒加载-Lazy Loading)

val lines = sc.textFile("data.txt")
val lineLengths = lines.map(s => s.length)
val totalLength = lineLengths.reduce((a, b) => a + b)

        第一行首先从外部文件data.txt中构建得到一个RDD,名称为lines,但是,由于textFile()方法只是一个转换操作,因此,这行代码执行后,不会立即把data.txt文件加载到内存中,这时的lines只是一个指向这个文件的指针

        第二行代码用来计算每行的长度(即每行包含多少个单词),同样,由于map()方法只是一个转换操作,这行代码执行后,不会立即计算每行的长度。

        第三行代码的reduce()方法是一个“动作”类型的操作,这时,就会触发真正的计算。这时,Spark会把计算分解成多个任务在不同的机器上执行,每台机器运行位于属于它自己的map和reduce,最后把结果返回给Driver Program。

部分实例

1、filter操作

           实例:计算出结果集中的元素“山西”个数

import org.apache.spark.{SparkConf, SparkContext}

object RDD_transformation {
  def main(args:Array[String]):Unit = {
    val conf = new SparkConf().setAppName("transformation").setMaster("local[1]")
    val sc = new SparkContext(conf)
    val personData = sc.textFile("D:\\workspace\\spark\\src\\main\\Data\\person")
    //filter操作
    val lines = personData.filter(line => line.contains("山西")).count
    //包含山西的
    println("文件中包含山西字段的数量:"+ lines)
  }
}

     ​​​运行结果及解释

    上面的代码中,lines是一个RDD。lines.filter()会遍历lines中的每行文本,并对每行文本执行括号中的匿名函数,也就是执行Lamda表达式:line => line.contains("山西"),在执行Lamda表达式时,会把当前遍历到的这行文本内容赋值给参数line,然后,执行处理逻辑line.contains("山西"),也就是只有当改行文本包含“Spark”才满足条件,才会被放入到结果集中。最后,等到lines集合遍历结束后,就会得到一个结果集,这个结果集中包含了所有包含“山西”的行。最后,对这个结果集调用count(),这是一个行动操作,会计算出结果集中的元素个数。

2、map操作

        实例:找出文本文件中单行文本所包含的单词数量的最大值

import org.apache.spark.{SparkConf, SparkContext}

object RDD_transformation {
  def main(args:Array[String]):Unit = {
    val conf = new SparkConf().setAppName("transformation").setMaster("local[1]")
    val sc = new SparkContext(conf)
    val personData = sc.textFile("D:\\workspace\\spark\\src\\main\\Data\\person")
    //map操作,文本文件中单行文本所包含的单词数量的最大值
    val lines1 = personData.map(line => line.split(",")
      .size).reduce((a,b) => if (a > b) a else b)
    println("文本文件中单行文本所包含的单词数量的最大值为:" + lines1)

  }
}
//拆分代码拆开来看
lines.map(line => line.split(" "))
res8: org.apache.spark.rdd.RDD[Array[String]] = MapPartitionsRDD[19] at map at <console>:30
//从上面执行结果可以发现,lines.map(line => line.split(" "))返回的结果是一个
//Array[String]类型的RDD,
//也就是说,这个RDD中的每个元素都是一个Array[String]
//(一行文本被切分成多个单词后就是保存在这个数组中)
scala> lines.map(line => line.split(" ").size)
res9: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[20] at map at <console>:30
//从上面执行结果信息可以发现,lines.map(line => line.split(" ").size)得到的
//RDD是Int类型的RDD,
//这个RDD中的每个元素都是一个整数值(也就是一行文本包含的单词数)
scala> lines.map(line => line.split(" ").size).reduce((a,b) => if (a>b) a else b)
res10: Int = 5

        运行结果解释

         上面代码中,lines是一个RDD,是String类型的RDD,因为这个RDD里面包含了很多行文本。

        lines.map(),是一个转换操作,B站林子雨老师之前说过,map(func):将每个元素传递到函数func中,并将结果返回为一个新的数据集,所以,lines.map(line => line.split(" ").size)会把每行文本都传递给匿名函数,也就是传递给Lamda表达式line => line.split(" ").size中的line,然后执行处理逻辑line.split(" ").size。

        line.split(" ").size这个处理逻辑的功能是,对line文本内容进行单词切分,得到很多个单词构成的集合,然后,计算出这个集合中的单词的个数。

        因此,最终lines.map(line => line.split(" ").size)转换操作得到的RDD,是一个整型RDD,里面每个元素都是整数值(也就是单词的个数)。

        最后,针对这个RDD[Int],调用reduce()行动操作,完成计算。reduce()操作每次接收两个参数,取出较大者留下,然后再继续比较,例如,RDD[Int]中包含了1,2,3,4,5,那么,执行reduce操作时,首先取出1和2,把a赋值为1,把b赋值为2,然后,执行大小判断,保留2。下一次,让保留下来的2赋值给a,再从RDD[Int]中取出下一个元素3,把3赋值给b,然后,对a和b执行大小判断,保留较大者3.依此类推。最终,reduce()操作会得到最大值是5。

   

持久化操作

        在Spark中,RDD采用惰性求值的机制,每次遇到行动操作,都会从头开始执行计算。如果整个Spark程序中只有一次行动操作,这当然不会有什么问题。但是,在一些情形下,我们需要多次调用不同的行动操作,这就意味着,每次调用行动操作,都会触发一次从头开始的计算。这对于迭代计算而言,代价是很大的,迭代计算经常需要多次重复使用同一组数据。

案例1:多次计算同一个RDD,无cache

scala> val list = List("hadoop","spark","hive")
list: List[String] = List(hadoop, spark, hive)
scala> val rdd = sc.parallelize(list)
rdd: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[0] at parallelize at <console>:24

scala> println(rdd.count()) // 行动操作,触发一次真正从头到尾的计算
[Stage 0:>                                                          (0 + 0) / 1[Stage 0:>                                                          (0 + 1) / 1          
                                                                     3
scala> println(rdd.collect())
[Ljava.lang.String;@afcfc63
scala> println(rdd.collect().mkString(",")) //行动操作,触发一次真正从头到尾的计算
hadoop,spark,hive

        上面代码执行过程中,前后共触发了两次从头到尾的计算。
        实际上,可以通过持久化(缓存)机制避免这种重复计算的开销可以使用persist()方法对一个RDD标记为持久化,之所以说“标记为持久化”,是因为出现persist()语句的地方,并不会马上计算生成RDD并把它持久化,而是要等到遇到第一个行动操作触发真正计算以后,才会把计算结果进行持久化,持久化后的RDD将会被保留在计算节点的内存中被后面的行动操作重复使用。
        persist()的圆括号中包含的是持久化级别参数,比如,persist(MEMORY_ONLY)表示将RDD作为反序列化的对象存储于JVM中,如果内存不足,就要按照LRU原则替换缓存中的内容。

        persist(MEMORY_AND_DISK)表示将RDD作为反序列化的对象存储在JVM中,如果内存不足,超出的分区将会被存放在硬盘上。

        一般而言,使用cache()方法时,会调用persist(MEMORY_ONLY)。

 案例2:多次计算同一个RDD,有cache操作

scala> val list = List("Spark","OOzie","flink","Hive")
list: List[String] = List(Spark, OOzie, flink, Hive)
scala> val rdd = sc.parallelize(list)
rdd: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[0] at parallelize             at <console>:24
scala> rdd.cache()          //rdd.cache会调用persist(MEMORY_ONLY),但是,
                            //语句执行到这里,并不会缓存rdd,这是rdd还没有被计算生成
res0: rdd.type = ParallelCollectionRDD[0] at parallelize at <console>:24
                            
scala> println(rdd.count()) //第一次行动操作rdd.count(),触发一次真正从头到尾的计算,
                            // 这时才会执行上面的rdd.cache(),把这个rdd放到缓存中
[Stage 0:>                                                          (0 + 0) / 1            [Stage 0:>                                                          (0 + 1) / 1                                                                                                       4

scala> println(rdd.collect().mkString(","))
//第二次行动操作,不需要触发从头到尾的计算,只需要重复使用上面缓存的RDD
Spark,OOzie,flink,Hive

案例3:使用unpersist()方法手动地把持久化的RDD从缓存中移除

//创建一个名为rdd1的List对象,包含一些整数元素。
scala> val rdd1 = List(1,2,3,23,34,54,67,78,89) 
rdd1: List[Int] = List(1, 2, 3, 23, 34, 54, 67, 78, 89)
//将List对象rdd1转换为RDD对象rdd2,使用sc.parallelize()方法。
scala> val rdd2 = sc.parallelize(rdd1)
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[1] at parallelize at <console>:24
//使用cache()方法将RDD对象rdd2缓存到内存中。
scala> rdd2.cache()
res3: rdd2.type = ParallelCollectionRDD[1] at parallelize at <console>:24
//使用map()方法对RDD中的每个元素进行乘以2的操作,生成新的RDD对象squared_rdd。
scala> val squared_rdd = rdd2.map(elem => elem*2)
squared_rdd: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[2] at map at <console>:23
//使用filter()方法对新的RDD对象squared_rdd进行筛选,保留大于20的元素,生成新的RDD对象filteredRDD。
scala> val filteredRDD = squared_rdd.filter(elem => elem > 20)
filteredRDD: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[3] at filter at <console>:23
//使用collect()方法将筛选后的结果收集起来,并使用mkString()方法
//将结果转换为字符串并打印出来。
scala> println(filteredRDD.collect().mkString(","))
46,68,108,134,156,178
//使用collect()方法将筛选后的结果收集起来,并使用mkString()方法将结果转换为字符串,
//并使用下划线作为分隔符,并打印出来。
scala> println(filteredRDD.collect().mkString("_"))
46_68_108_134_156_178
//使用unpersist()方法释放缓存的RDD对象rdd2。
scala> rdd2.unpersist()
res7: rdd2.type = ParallelCollectionRDD[1] at parallelize at <console>:24
//使用stop()方法关闭SparkContext对象sc。
scala> sc.stop()

分区

RDD分区原则

        RDD是弹性分布式数据集,通常RDD很大,会被分成很多个分区,分别保存在不同的节点上。 RDD分区的一个分区原则是使得分区的个数尽量等于集群中的CPU核心(core)数目。
        对于不同的Spark部署模式而言(本地模式、Standalone模式、YARN模式、Mesos模式),都可以通过设置spark.default.parallelism这个参数的值,来配置默认的分区数目,一般而言:
        1、本地模式:默认为本地机器的CPU数目,若设置了local[N],则默认为N;
        2、Apache Mesos:默认的分区数为8;
        3、Standalone或YARN:在“集群中所有CPU核心数目总和”和“2”二者中取较大值作为默认值;

        因此,对于parallelize而言,如果没有在方法中指定分区数,则默认为spark.default.parallelism,比如:


scala> val seq =Seq(1,2,3,4,5,6,7,88,23)
seq: Seq[Int] = List(1, 2, 3, 4, 5, 6, 7, 88, 23)
//设置三个分区
scala> val rdd = sc.parallelize(seq,3)
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize
at <console>:24

textFile的rdd分区原则

        对于textFile而言,如果没有在方法中指定分区数,则默认为min(defaultParallelism,2),其中,defaultParallelism对应的就是spark.default.parallelism。
如果是从HDFS中读取文件,则分区数为文件分片数(比如,128MB/片)。

cpu核数怎么查看

        在Scala中,可以使用Runtime类的availableProcessors方法来获取当前系统的CPU核数。示例代码如下:

val numCores = Runtime.getRuntime.availableProcessors() println(s"当前系统的CPU核数为: $numCores")

打印RDD元素到控制台怎么做

本地模式打印(local)       

工作中,经常需要把RDD中的元素打印输出到屏幕上(标准输出stdout),一般会采用语句:

        1、rdd.foreach(println)

        2、rdd.map(println)。

        当采用本地模式(local)在单机上执行时,这些语句会打印出一个RDD中的所有元素。

//使用collect()方法将所有元素抓取到Driver Program中,并打印出来:
val rdd: RDD[String] = ...
val collected: Array[String] = rdd.collect()

collected.foreach(println)

集群模式打印(IM重要)

        但当采用集群模式执行时,在worker节点上执行打印语句是输出到worker节点的stdout中,而不是输出到任务控制节点Driver Program中,因此,任务控制节点Driver Program中的stdout是不会显示打印语句的这些输出内容的。

       1、 为了能够把所有worker节点上的打印输出信息也显示到Driver Program中,可以使用

        collect()方法,比如,rdd.collect().foreach(println),

        2、但由于collect()方法会把各个worker节点上的所有RDD元素都抓取到Driver Program中,因此,这可能会导致内存溢出。因此,当你只需要打印RDD的部分元素时,可以采用语句        

        rdd.take(100).foreach(println)。

//使用take()方法只获取RDD的部分元素,并打印出来:
val rdd: RDD[String] = ...
val taken: Array[String] = rdd.take(100)
taken.foreach(println)

val rdd: RDD[String] = ...
rdd.foreachPartition(iter => iter.foreach(println))

Scala如何进行遍历List(1,2,3,4,5,6)

scala> val list = List(11,22,33,4,43,2323)
list: List[Int] = List(11, 22, 33, 4, 43, 2323)
// foreach方法
scala> list.foreach(elem => println(list))
List(11, 22, 33, 4, 43, 2323)
List(11, 22, 33, 4, 43, 2323)
List(11, 22, 33, 4, 43, 2323)
List(11, 22, 33, 4, 43, 2323)
List(11, 22, 33, 4, 43, 2323)
List(11, 22, 33, 4, 43, 2323)
//for循环
scala> for (elem <- list)
     | {print(elem + " ")}
11 22 33 4 43 2323

scala> for (elem <- list)
     | {println(elem)}
11
22
33
4
43
2323
//map方法
scala> list.map(elem => println(elem))
11
22
33
4
43
2323
res5: List[Unit] = List((), (), (), (), (), ())

        注意:使用map方法时,它会返回一个新的List,该List包含了对原始List中的每个元素应用函数后的结果。因此,使用map方法来进行遍历时,需要注意返回的List是否需要被使用。如果只是为了遍历而不需要返回结果,使用foreachfor循环更为合适。

(注:部分内容参考林子雨老师课程,林子雨NB!)

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

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

相关文章

MySQL的数据备份与还原--练习题

MySQLdump MySQLdump是MySQL提供的一个非常有用的数据库备份工具。MySQLdump命令执行时&#xff0c;可以将数据库备份成一个文本文件&#xff0c;该文件中实际上包含了多个CREATE 和 INSERT语句&#xff0c;使用这些语句可以重新创建表和插入数据。 看题&#xff1a; 第一题&a…

开源共建,360推出WatchAD2.0域安全威胁感知系统新版本

不论是在攻防演练还是真实入侵对抗场景中&#xff0c;攻击者往往通过攻击域控获取特权管理权限进而横向控制企业内网&#xff0c;窃取重要资产和数据&#xff0c;凭借独特的管理优势&#xff0c;AD域被广泛应用于大型企业的IT基础设施的集中管理。 然而&#xff0c;传统的网络…

【手撕C语言基础】结构体(2)

(꒪ꇴ꒪(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误…

微服务-Nacos环境安装

文章目录 1. 微服务1.1 微服务概括 2. 微服务框架2.1 Spring Cloud2.2 Spring Cloud alibaba/Spring Cloud Netflix2.3微服务框架组件(alibaba) 3 Nacos3.1 Nacos介绍3.3 Naocs工作结构3.3 Nacos功能3.4 环境准备下载安装 1. 微服务 1.1 微服务概括 单体架构有问题,所以做项目…

【uniapp开发小程序】设置开屏广告,广告图片全屏、覆盖自带胶囊导航

效果图&#xff1a; 点击跳转其他小程序&#xff1a; uni.navigateToMiniProgram() 官方文档&#xff1a;uni.navigateToMiniProgram(OBJECT) | uni-app官网 // 示例代码 uni.navigateToMiniProgram({appId: ,path: pages/index/index?id123,extraData: {data1: test},succes…

最新AI换脸替换工具离线版,一张图实现视频或者图片换脸

最新AI换脸替换工具离线版&#xff0c;一张图实现视频或者图片换脸 AI换脸替换工具离线版 基于开源项目&#xff0c;做了如下的小工具&#xff0c;给定一张人脸图&#xff0c;即可实现将某视频或者图片的人脸替换成给定的人脸。 软件操作依然很简单&#xff0c;鼠标悬停问号都…

七大排序算法——冒泡排序,通俗易懂的思路讲解与图解(完整Java代码)

文章目录 一、排序的概念排序的概念排序的稳定性七大排序算法 二、冒泡排序核心思想代码实现 三、性能分析四、七大排序算法 一、排序的概念 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或…

Nacos注册与配置中心:使用详讲

文章目录 注册1. 引入依赖2. yaml配置设置命名空间注册信息在nacos中的内存状态总结nacos的服务注册发现机制 配置中心应用场景配置中心运行结构远程配置:1. 在本地进程添加config 依赖 和bootstrap依赖2. 需要引入一个bootstrap.yaml文件 案例练习 注册 所有组件配置步骤-大三…

面向Web开发人员的Linux实用入门(转)

从 web 开发的视角说一下在使用 Linux 时遇到的问题&#xff0c;主要是针对操作本身&#xff0c;因为指令在网上都可以查到&#xff0c;不会深入原理&#xff0c;但尽量实用。 基础认知 为什么使用 Linux 最初我使用 Linux 是因为我需要的应用在教程里只提供了 Linux 版本&a…

一、Dell服务器的iDRAC管理卡连接

Dell服务器的iDRAC管理卡图文教程 1、网线连接idrac口2、查看idrac地址3、匹配IP地址4、web登录idrac页面5、登录成功页面 带有集成戴尔远程访问控制器 &#xff08;idrac&#xff09;的系统具有默认用户名和密码&#xff0c;但您也可以使用安全密码对其进行配置。默认使用web浏…

【设计模式】简易俄罗斯转盘实现JAVA

大家好哇&#xff0c;我是梦辛工作室的灵&#xff0c;最近有些无聊&#xff0c;没得什么事情做&#xff0c;所以想再熟悉熟悉设计模式吧&#xff0c;然后就写了个俄罗斯转盘玩&#xff0c;还是老样子先看结果&#xff1a; 看上去还是不错的吧&#xff0c;最后那个只是打印&…

数学建模 插值算法

有问题 牛顿差值也有问题它们都有龙格现象&#xff0c;一般用分段插值。 插值预测要比灰色关联预测更加准确&#xff0c;灰色预测只有2次 拟合样本点要非常多&#xff0c;样本点少差值合适

Qt 桌面系统设计

文章目录 前言一、项目介绍二、界面布局三、按键图标四、桌面背景五、实现led功能总结 前言 这篇文章介绍 一个Qt 桌面系统的项目&#xff0c;大家可以在此基础上加以改进&#xff0c;实现更多的功能。 一、项目介绍 可以看到 这个桌面系统上分为两部分&#xff0c;左边是 三个…

在Linux上 USRP RIO 2944 使用 PCIe

支持的硬件 USRP-2900USRP-2901USRP-2920USRP-2921USRP-2922USRP-2930USRP-2932USRP-2940 40 MHzUSRP-2940 120 MHzUSRP-2942 40 MHzUSRP-2942 120 MHzUSRP-2943 40 MHzUSRP-2943 120 MHzUSRP-2944USRP-2945USRP-2950 40 MHzUSRP-2950 120 MHzUSRP-2952 40 MHzUSRP-2952 120 MH…

【Unity面试篇】Unity 面试题总结甄选 |算法相关 | ❤️持续更新❤️

前言 之前整理了一篇关于Unity面试题相关的所有知识点&#xff1a;2022年Unity 面试题 |五萬字 二佰道| Unity面试题大全&#xff0c;面试题总结【全网最全&#xff0c;收藏一篇足够面试】为了方便大家可以重点复习某个模块&#xff0c;所以将各方面的知识点进行了拆分并更新整…

山西电力市场日前价格预测【2023-07-14】

日前价格预测 预测明日&#xff08;2023-07-14&#xff09;山西电力市场全天平均日前电价为315.29元/MWh。其中&#xff0c;最高日前价格为386.08元/MWh&#xff0c;预计出现在21: 45。最低日前电价为232.93元/MWh&#xff0c;预计出现在14: 45。 价差方向预测 1&#xff1a;实…

利用windows恶意软件获取windows主机shell

实验目的&#xff1a; 模拟黑客利用windows恶意软件获取windows主机shell权限的过程 熟悉操作使用的命令实验准备&#xff1a; kali 同网段的windows主机&#xff08;关闭防火墙&#xff09; msfvenom是一个Metasploit独立的有效负载生成器&#xff0c;也是msfpayload和msfenco…

【大数据之Hive】二十二、HQL语法优化之Join优化

主要控制优化使用哪种join算法。 1 Common Join Common Join是Hive中最稳定的join算法也是默认的join算法&#xff0c;其通过一个MapReduce Job完成一个join操作。Map端负责读取join操作所需表的数据&#xff0c;并按照关联字段进行分区&#xff0c;通过Shuffle&#xff0c;将…

【动手学深度学习】--01.线性回归

文章目录 线性回归1.原理1.1线性模型1.2衡量预估质量——平方损失1.3训练数据1.4参数学习1.5优化算法 2.从零开始实现线性回归2.1生成数据集2.2批量读取数据集——Mini-batch思想2.3初始化模型参数2.4定义模型2.5定义损失函数2.6定义优化算法2.7训练模型 3.借助深度学习框架实现…

关于nginx学习记录(一)

系列文章目录 第一章 Nginx 学习入门——Nginx的概述及安装 系列文章目录 一、Nginx 概述 二、安装步骤 1.下载pcre安装包,并放入linux中,进行解压: 2.pcre解压完成后,进入解压后的文件,执行./configure命令 3.在当前目录执行命令:make && make install 4.由于到…