Spark编程基础

一、RDD入门

1.RDD是什么?

RDD是一个容错的、只读的、可进行并行操作的数据结构,是一个分布在集群各个节点中的存放元素的集合,即弹性分布式数据集。

2.RDD的三种创建方式

  • 第一种是将程序中已存在的集合(如集合、列表、数组)转换成RDD。
  • 第二种是读取外部数据集来创建RDD。
  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.1准备数据:将程序中已存在的集合(如集合、列表、数组)转换成RDD
    val rdd1 = sc.parallelize(List(1,2,3,4))
    val rdd2 = sc.makeRDD(List(1,2,3,4))
    //2.2准备数据:读取外部数据集来创建RDD
    val rdd3 = sc.textFile("dataset/words.txt")
    //3.查看数据
    rdd1.collect().foreach(println)
    println("-------------------------")
    rdd2.collect().foreach(println)
    println("-------------------------")
    rdd3.collect().foreach(println)
    }
  • 第三种是对已有RDD进行转换得到新的RDD(在RDD的操作方法中讲解)。

 二、单个RDD的转换操作

Spark RDD提供了丰富的操作方法(函数)用于操作分布式的数据集合,包括转换操作和行动操作两部分。

  • 转换操作:可以将一个RDD转换为一个新的RDD,但是转换操作是懒操作,不会立刻执行计算;
  • 行动操作:是用于触发转换操作的操作,这时才会真正开始进行计算。

1)map()方法

作用:把 RDD 中的数据 一对一 的转为另一种形式。

格式:def map[U: ClassTag](f: T ⇒ U): RDD[U]

Map 算子是 原RDD → 新RDD 的过程, 传入函数的参数是原 RDD 数据, 返回值是经过函数转换的新 RDD 的数据。

 def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(1,2,3,4))
    //3.RDD的转换操作map
    var rdd2 = rdd1.map(x => x * 10)
    //4.打印数据
    rdd2.collect().foreach(println)//10 20 30 40
    }

2)flatMap()方法

作用:flatMap 算子和 Map 算子类似, 但是 flatMap 是一对多。

格式:def flatMap[U: ClassTag](f: T ⇒ List[U]): RDD[U]

参数是原 RDD 数据, 返回值是经过函数转换的新 RDD 的数据, 需要注意的是返回值是一个集合, 集合中的数据会被展平后再放入新的 RDD。

  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List("How are you","I am fine","What about you"))
    //3.RDD的转换操作flatMap
    var rdd2 = rdd1.flatMap(x => x.split(" "))
    //4.打印数据
    rdd2.collect().foreach(println) //How are you I am fine What about you
    }

3)sortBy()方法

作用:用于对标准RDD进行排序,有3个可输入参数。

格式:def sortBy(func, ascending, numPartitions)

参数:func指定按照哪个字段来排序,通过这个函数返回要排序的字段;scending 是否升序,默认是true,即升序排序,如果需要降序排序那么需要将参数的值设置为false。;numPartitions 分区数。

  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List((1,3),(45,2),(7,6)))
    //3.RDD的转换操作sortBy,按照元组第二个值进行false降序
    val rdd2 = rdd1.sortBy(x =>x._2,false,1)
    //4.打印数据 
    rdd2.collect().foreach(println) //(7,6) (1,3) (45,2)
    }

4)mapPartitionsWithIndex()方法

作用:对RDD中的每个分区(带有下标)进行操作,通过自己定义的一个函数来处理。

格式:def mapPartitionsWithIndex[U](f: (Int, Iterator[T]) => Iterator[U])

参数:f 是函数参数,接收两个参数:
       (1)Int:代表分区号
       (2)Iterator[T]:分区中的元素
       (3)返回:Iterator[U]:操作完后,返回的结果

  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据,并设置为2个分区
    val rdd1 = sc.parallelize(List(1,2,3,4,5),2)
    //3.RDD的转换操作mapPartionsWithIndex
    val rdd2 = rdd1.mapPartitionsWithIndex(
      (index,it)=>{
        it.toList.map(x=>"["+index+","+x+"]").iterator
      }
    )
    //4.打印数据:【分区编号,数据】
    rdd2.collect().foreach(println) //[0,1] [0,2] [1,3] [1,4] [1,5]
    }

5)filter()方法

作用:是一种转换操作,用于过滤RDD中的元素。

格式:def filter(f: T => Boolean): RDD[T]

将返回值为true的元素保留,将返回值为false的元素过滤掉,最后返回一个存储符合过滤条件的所有元素的新RDD。

  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(1,2,3,4))
    //3.RDD的转换操作filter,过滤偶数
    val rdd2 = rdd1.filter(x => x%2==0)
    //4.打印数据
    rdd2.collect().foreach(println) //2 4
    }

6)distinct()方法

作用:是一种转换操作,用于RDD的数据去重,去除两个完全相同的元素,没有参数。

格式:def distinct(): RDD[T]

将数据集中重复的数据去重,返回一个没有重复元素的新RDD。

def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(1,1,2,3,3))
    //3.RDD的转换操作filter
    val rdd2 = rdd1.distinct()
    //4.打印数据
    rdd2.collect().foreach(println) //1 2 3
    }

三、多个RDD的集合操作

1)union()方法

作用:是一种并集转换操作,用于将两个RDD合并成一个,不进行去重操作,而且两个RDD中每个元素中的值的数据类型需要保持一致

格式:def union(other: RDD[T]): RDD[T]

对源 RDD 和参数 RDD 求并集后返回一个新的 RDD。

def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(1,2,3,4))
    val rdd2 = sc.parallelize(List(1,3,5,6))
    //3.RDD的转换操作union
    val rdd3 = rdd1.union(rdd2)
    //4.打印数据
    rdd3.collect().foreach(println) //1,2,3,4,1,3,5,6
    }

2)intersection()方法

作用:是一种交集转换操作,用于将求出两个RDD的共同元素。

格式:def intersection(other: RDD[T]): RDD[T]

对源 RDD 和参数 RDD 求交集后返回一个新的 RDD,两个RDD的顺序不会影响结果。

def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(1,2,3,4))
    val rdd2 = sc.parallelize(List(1,2))
    //3.RDD的转换操作intersection
    val rdd3 = rdd1.intersection(rdd2)
    //4.打印数据
    rdd3.collect().foreach(println) //1,2
    }

3)subtract()方法

作用:是一种补集转换操作,用于将前一个RDD中在后一个RDD出现的元素删除,返回值为前一个RDD去除与后一个RDD相同元素后的剩余值所组成的新的RDD。

格式:def subtract(other: RDD[T]): RDD[T]

将原RDD里和参数RDD里相同的元素去掉后返回一个新的 RDD,两个RDD的顺序会影响结果。

def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(1,2,3,4))
    val rdd2 = sc.parallelize(List(1,2,5))
    //3.RDD的转换操作subtract
    val rdd3 = rdd1.subtract(rdd2)
    val rdd4 = rdd2.subtract(rdd1)
    //4.打印数据
    rdd3.collect().foreach(println) //3,4
    println("----------------------")
    rdd4.collect().foreach(println) //5
    }

4)cartesian()方法

作用:是一种求笛卡儿积操作,用于将两个集合的元素两两组合成一组。

格式:def cartesian(other: RDD[T]): RDD[T]

将原RDD里的每个元素都和参数RDD里的每个组合成一组,返回一个新的RDD。两个RDD的顺序会影响结果。

 def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(1,3,4))
    val rdd2 = sc.parallelize(List(1,2))
    //3.RDD的转换操作cartesian
    val rdd3 = rdd1.cartesian(rdd2)
    val rdd4 = rdd2.cartesian(rdd1)
    //4.打印数据
    rdd3.collect().foreach(println) //(1,1)    (1,2)    (3,1)    (3,2)    (4,1)    (4,2)
    println("----------------------")
    rdd4.collect().foreach(println) //(1,1)    (1,3)    (1,4)    (2,1)    (2,3)    (2,4)
    }

四、单个键值对RDD的转换操作

Spark的大部分RDD操作都支持所有种类的单值RDD,但是有少部分特殊的操作只能作用于键值对类型的RDD。键值对RDD由一组组的键值对组成,这些RDD被称为PairRDD。PairRDD提供了并行操作各个键或跨节点重新进行数据分组的操作接口。

1)创建键值对RDD

1.将一个普通RDD通过map转化为Pair RDD。当需要将一个普通的RDD转化为一个PairRDD时可以使用map函数来进行操作,传递的函数需要返回键值对。

2.通过List直接创建Pair RDD。

3.使用zip()方法用于将两个RDD组成Pair RDD。要求两个及元素数量相同,否则会抛出异常。 

  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List("I like spark","He likes spark"))
    //3.1 通过flatMap和map方法将一个普通的RDD转化为一个键值对RDD
    val rdd2 = rdd1.flatMap(x => x.split(" "))
    val rdd3 = rdd2.map(x => (x,1))
    //3.2 通过List直接创建Pair RDD
    val rdd4 = sc.parallelize(List(("张三",100),("李四",90),("王五",80)))
    //3.3 使用zip()方法用于将两个RDD组成Pair RDD
    val dataRdd1 = sc.parallelize(List(1,2,3),2)
    val dataRdd2 = sc.parallelize(List("A","B","C"),2)
    val dataRdd3 = dataRdd1.zip(dataRdd2)
    //4.打印数据
    rdd2.collect().foreach(println) //(I,like,spark,He,likes,spark)
    println("---------------------")
    rdd3.collect().foreach(println) //(I,1) (like,1) (spark,1) (He,1) (likes,1) (spark,1)
    println("---------------------")
    rdd4.collect().foreach(println) //(张三,100) (李四,90)  (王五,80)
    println("---------------------")
    dataRdd3.collect().foreach(println) //(1,A) (2,B) (3,C)
    }

2)键值对RDD的keys和values方法

键值对RDD,包含键和值两个部分。 Spark提供了两种方法,分别获取键值对RDD的键和值。

  • keys方法返回一个仅包含键的RDD。
  • values方法返回一个仅包含值的RDD。
  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(("张三",100),("李四",90),("王五",80)))
    //3.1 获取keys
    val rdd2 = rdd1.keys
    //3.2 获取values
    val rdd3 = rdd1.values
    //3.打印数据
    rdd2.collect().foreach(println) //张三 李四 王五
    println("---------------------")
    rdd3.collect().foreach(println) //100 90  80
  }

3)键值对RDD的reduceByKey()

作用:将相同键的前两个值传给输入函数,产生一个新的返回值,新产生的返回值与RDD中相同键的下一个值组成两个元素,再传给输入函数,直到最后每个键只有一个对应的值为止。

格式:def reduceByKey(func: (V, V) => V): RDD[(K, V)]

可以将数据按照相同的 Key 对 Value 进行聚合。

def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List("I like spark","He likes spark"))
    //3.1 通过flatMap和map方法将一个普通的RDD转化为一个键值对RDD
    val rdd2 = rdd1.flatMap(x => x.split(" "))
    val rdd3 = rdd2.map(x => (x,1)) // (I,1) (like,1) (spark,1) (He,1) (likes,1) (spark,1)
    //3.2 使用reduceByKey将相同键的值进行相加,统计词频
    val rdd4 = rdd3.reduceByKey((a,b) => a+b)
    //4.打印数据
    rdd4.collect().foreach(println) //(I,1) (He,1) (spark,2) (like,1) (likes,1)
  }

3)键值对RDD的groupByKey()

作用:按照 Key 分组, 和 reduceByKey 有点类似, 但是 groupByKey 并不求聚合,只是列举 Key 对应的所有 Value。

格式:def groupByKey(): RDD[(K, Iterable[V])]

对于一个由类型K的键和类型V的值组成的RDD,通过groupByKey()方法得到的RDD类型是[K,Iterable[V]],可以将数据源的数据根据 key 对 value 进行分组。

  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(("a",1),("a",2),("b",1),("c",1),("c",1)))
    //3.使用groupByKey进行分组
    val rdd2 = rdd1.groupByKey()
    //4.使用map方法查看分组后每个分组中的值的数量
    val rdd3 = rdd2.map(x => (x._1,x._2.size))
    //5.打印数据
    rdd2.collect().foreach(println) //(a,CompactBuffer(1, 2)) (b,CompactBuffer(1)) (c,CompactBuffer(1, 1))
    rdd3.collect().foreach(println) //(a,2) (b,1) (c,2)
  }

五、多个键值对RDD的转换操作

在Spark中,键值对RDD提供了很多基于多个RDD的键进行操作的方法。

1)join()方法

作用:用于根据键,对两个RDD进行内连接,将两个RDD中键相同的数据的值存放在一个元组中,最后只返回两个RDD中都存在的键的连接结果。

格式:def join[W](other: RDD[(K, W)]): RDD[(K, (V, W))]

在类型为(K,V)和(K,W)的 RDD 上调用,返回一个相同 key 对应的所有元素连接在一起的。

def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(("a",1),("b",2),("c",3)))
    val rdd2 = sc.parallelize(List(("a",2),("b",4),("e",5)))
    //3.使用join进行内连接
    val rdd3 = rdd1.join(rdd2)
   //4.打印数据
    rdd3.collect().foreach(println) //(a,(1,2)) (b,(2,4))
  }

2)rightOuterJoin()方法

作用:用于根据键,对两个RDD进行右外连接,连接结果是右边RDD的所有键的连接结果,不管这些键在左边RDD中是否存在。

格式:def rightOuterJoin[W](other: RDD[(K, W)]): RDD[(K, (V, Option[W]))]

类似于 SQL 语句的右外连接。如果在左边RDD中有对应的键,那么连接结果中值显示为Some类型值;如果没有,那么显示为None值。

3)leftOuterJoin()方法

作用:用于根据键,对两个RDD进行左外连接,连接结果是左边RDD的所有键的连接结果,不管这些键在右边RDD中是否存在。

格式:def leftOuterJoin[W](other: RDD[(K, W)]): RDD[(K, (V, Option[W]))]

类似于 SQL 语句的右外连接。如果在右边RDD中有对应的键,那么连接结果中值显示为Some类型值;如果没有,那么显示为None值。

4)fullOuterJoin()方法

作用:用于对两个RDD进行全外连接,保留两个RDD中所有键的连接结果。

格式:def fullOuterJoin[W](other: RDD[(K, W)]): RDD[(K, (V, Option[W]))]

类似于 SQL 语句的全外连接。

  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(("a",1),("b",2),("c",3)))
    val rdd2 = sc.parallelize(List(("a",2),("b",4),("e",5)))
    //3.使用rightOuterJoin进行右外连接
    val rdd3 = rdd1.rightOuterJoin(rdd2)
    //4.使用leftOuterJoin进行左外连接
    val rdd4 = rdd1.leftOuterJoin(rdd2)
    //5.使用fullOuterJoin进行全外连接
    val rdd5 = rdd1.fullOuterJoin(rdd2)
    //6.打印数据
    rdd3.collect().foreach(println) //(a,(Some(1),2)) (b,(Some(2),4)) (e,(None,5))
    println("--------------------")
    rdd4.collect().foreach(println) //(a,(1,Some(2))) (b,(2,Some(4))) (c,(3,None))
    println("--------------------")
    rdd5.collect().foreach(println) //(a,(Some(1),Some(2))) (b,(Some(2),Some(4))) (c,(Some(3),None)) (e,(None,Some(5)))
  }

5)sortByKey()方法

作用:作用于Key-Value形式的RDD,并对Key进行排序。

格式:def sortByKey(ascending: Boolean = true, numPartitions: Int = self.partitions.length)
 : RDD[(K, V)]

参数:scending 是否升序,默认是true,即升序排序,如果需要降序排序那么需要将参数的值设置为false。numPartitions 为分区数。

  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List((1,3),(45,2),(7,6)))
    //3.RDD的转换操作sortByKey
    val rdd2 = rdd1.sortByKey(true) //按key进行升序
    val rdd3 = rdd1.sortByKey(false) //按key进行降序
    //4.打印数据
    rdd2.collect().foreach(println)
    println("---------------------")
    rdd3.collect().foreach(println)
    }

6)lookup()方法

作用:作用于键值对RDD,返回指定键的所有值。

格式:def lookup(key : K) : scala.Seq[V]

作用于K-V类型的RDD上,返回指定K的所有V值

  def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //2.准备数据
    val rdd1 = sc.parallelize(List(("张三",100),("李四",90),("王五",80)))
    //3.使用lookup()方法查找指定键的值
    val result = rdd1.lookup("李四")
    //4.打印数据
    println(result) //WrappedArray(90)
  }

7)combineByKey()方法

作用:用于将键相同的数据聚合,并且允许返回,类型与输入数据的类型不同的返回值。

格式:def combineByKey[C](
                 createCombiner: V => C,
                 mergeValue: (C, V) => C,
                 mergeCombiners: (C, C) => C): RDD[(K, C)]

combineByKey()方法接收3个重要的参数,具体说明如下:

  • createCombiner:V=>C,V是键值对RDD中的值部分,将该值转换为另一种类型的值C,C会作为每一个键的累加器的初始值。
  • mergeValue:(C,V)=>C,该函数将元素V聚合到之前的元素C(createCombiner)上(这个操作在每个分区内进行)。
  • mergeCombiners:(C,C)=>C,该函数将两个元素C进行合并(这个操作在不同分区间进行)。

小练习:将数据 List(("zhangsan", 99.0), ("zhangsan", 96.0), ("lisi", 97.0), ("lisi", 98.0), ("zhangsan", 97.0)),求每个 key的平均值。

 def main(args: Array[String]): Unit = {
    //1.入口:创建SparkContext
    val conf = new SparkConf().setMaster("local[*]").setAppName("spark")
    val sc = new SparkContext(conf)
    //需求:将数据 List(("zhangsan", 99.0), ("zhangsan", 96.0), ("lisi", 97.0), ("lisi", 98.0), ("zhangsan", 97.0)),求每个 key的平均值
    //2.准备数据
    val rdd1 = sc.parallelize(List(("zhangsan", 99.0), ("zhangsan", 96.0), ("lisi", 97.0), ("lisi", 98.0), ("zhangsan", 97.0)))
    //3.1 通过combineByKey方法将RDD安装key进行聚合,返回值形式:(key,(值总和,key个数))
    val rdd2 = rdd1.combineByKey(
      score => (score,1),
      (scoreCount:(Double,Int),newScore:Double) => (scoreCount._1+newScore,scoreCount._2+1),
      (scoreCount1:(Double,Int),scoreCount2:(Double,Int)) => (scoreCount1._1+scoreCount2._1,scoreCount1._2+scoreCount2._2)
    )
    //打印combineByKey聚合之后的数据,形式:(key,(值总和,key个数))
    rdd2.collect().foreach(println) //(zhangsan,(292.0,3)) (lisi,(195.0,2))
    //3.2 将按值聚合相加后的结果(zhangsan,(292.0,3)) (lisi,(195.0,2)),求每个人的平均值,返回值形式:(key,平均值)
    val result = rdd2.map(item =>(item._1,item._2._1/item._2._2))
    //4 打印数据
    println("------------------")
    result.collect().foreach(println)
  }

combineByKey()方法执行过程的图解:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【JavaSE零基础】00-基础语法(1-12章)

1 第一章 Java开发环境搭建 1.1 章节目标与知识框架 1.1.1 章节目标 掌握Java的开发环境搭建,会编写HelloWorld程序,并能够准确的进行编译和运行;理解path和classpath环境变量并可以自行配置。 1.1.2 知识框架 1.2 Java语言概述(了解) J…

Uniapp/HTML5 上传文件到腾讯云Cos图片存储(Demo)

Uniapp引入方式 npm install cos-js-sdk-v5 HTML引入方式 <script type"text/javascript" src"js/cos-js-sdk-v5.min.js"></script> 在腾讯官网中找到cosJs放到本地项目中引入在项目中util工具类目录下封装一个upload.js用于公共上传Js impo…

操作系统②——内存管理

1. 栈、堆 1.1 程序的内存分配 栈区&#xff08;stack&#xff09;&#xff1a;由编译器自动分配释放 &#xff0c;存放函数的参数值&#xff0c;局部变量的值等。其操作方式类似于数据结构中的栈。堆区&#xff08;heap&#xff09;&#xff1a;一般由程序员分配释放&#x…

C++:stack类和queue类

stack的介绍和使用 1. stack 是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2. stack 是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;并…

H265码率控制(一)之HM代码R-λ model介绍

前言 在HM中R-λ的码率控制引入是在k0103提案中开始引入的&#xff0c;代码是HM-8.0以后的版本出现的&#xff0c;后面经过多个提案不断的修改&#xff0c;如M0257提案&#xff0c;M0036提案等&#xff1b;笔者建议研究HM代码的R-λ码率控制从HM10.0版本开始这个版本的R-λ已经…

1.基础乐理-唱名与记住唱名的方法

首先有 0、1、2、3、4、5、6、7&#xff0c;这八个数字 在音乐中要用笔来记录音乐就要用到 0、1、2、3、4、5、6、7&#xff0c;这八个数字&#xff0c;如果我们要唱出来 或 说出来&#xff0c;只要用嘴巴说出来就不是用 0、1、2、3、4、5、6、7&#xff0c;这八个数字了&…

雄安新区:创新引领,未来产业的摇篮

雄安新区&#xff1a;创新引领&#xff0c;未来产业的摇篮 随着雄安新区的建设不断推进&#xff0c;这座未来之城正逐渐成为创新的高地和创业的热土。在这片充满希望的土地上&#xff0c;全过程创新生态链正在形成&#xff0c;为未来产业的发展提供了坚实的基础。 创新高地&a…

机器学习(五) -- 监督学习(3) -- 朴素贝叶斯

系列文章目录及链接 目录 前言 一、朴素贝叶斯通俗理解及定义 二、原理理解及公式 1、概率基础 2、贝叶斯公式 3、拉普拉斯平滑系数 三、**算法实现 四、接口实现 1、新闻数据集介绍 2、API 3、流程 3.1、获取数据 3.2、数据预处理 3.3、特征工程 3.4、朴素贝叶…

java代码混淆,保护源码的重要性

Java代码混淆是一种重要的安全措施&#xff0c;用于保护Java应用程序的源代码免受恶意攻击和逆向工程的影响。下面是关于Java代码混淆以及保护源码重要性的详细说明&#xff1a; 1. 什么是Java代码混淆&#xff1f; Java代码混淆是指通过对Java代码进行一系列的转换和优化&am…

SD卡误删怎么恢复?5个恢复方法助你找回数据!

“我刚刚在清理sd卡时突然发现sd卡里的部分文件误删了&#xff0c;大家有什么方法可以恢复sd卡重要文件吗&#xff1f;” SD卡&#xff0c;作为一种常见的存储设备&#xff0c;经常用于手机、相机等电子设备中&#xff0c;存储着大量的数据。然而&#xff0c;误删操作往往会导致…

容器和K8s常见概念

【容器】 1、Open Container Initiative&#xff08;OCI&#xff09;&#xff1a;制定和推动容器格式和运行时的开放标准。容器运行时需要遵循此标准。主要的产出物包括&#xff1a; OCI Image Specification: 定义容器镜像格式的规范&#xff0c;统一描述容器镜像的内容和结…

CSS - 你能尽量多的说出两边固定,中间自适应的三栏布局如何做吗

难度级别:初级及以上 提问概率:65% 前端面试中,布局类题目被问道的频次会非常高,这道题,我们通过以下四种方式来实现。 目录 1 使用flex布局 2 使用绝对定位和margin配合的方式

CSS属性计算逻辑

CSS 属性计算逻辑 首先&#xff0c;假设在 HTML 中有这么一段代码&#xff0c;在 body 中有一个 h1 标题&#xff1a; <body><h1>这是一个h1标题</h1> </body>目前我们没有设置该 h1 的任何样式&#xff0c;但是却能看到该 h1 有一定的默认样式&…

ArcGIS Server 数据存储之注册文件夹及数据库

使用 ArcGIS Server 管理器将数据目录和数据库注册到 ArcGIS Server。数据注册为服务器提供了服务源数据的来源位置列表。数据注册具有以下优点&#xff1a; 数据注册可帮助您验证服务是否引用服务器管理员已知和批准的数据位置。数据注册允许 ArcGIS Server 在将地图、模型或…

QT软件开发: 点击鼠标在窗口里绘制矩形(窗口透明背景)

QT软件开发: 点击鼠标在窗口里绘制矩形(窗口透明背景)-腾讯云开发者社区-腾讯云 一、功能需求 一般在软件开发中&#xff0c;需要都有选择区域的需求&#xff0c;比如&#xff1a; 1. 截图软件&#xff0c;需要鼠标选择指定区域截图 2. 屏幕录像软件&#xff0c;需要鼠标选…

在git上先新建仓库-把本地文件提交远程

一.在git新建远程项目库 1.选择新建仓库 以下以gitee为例 2.输入仓库名称&#xff0c;点击创建 这个可以选择仓库私有化还公开权限 3.获取仓库clone链接 这里选择https模式就行&#xff0c;就不需要配置对电脑进行sshkey配置了。只是需要每次提交输入账号密码 二、远…

QT 线程之movetothread

上文列举了qt中线程的几种方法&#xff0c;其中2种方法最为常见。 本文以实例的方式描述了movetothread&#xff08;&#xff09;这种线程的方法&#xff0c;将QObject的子类移动到指定的线程。 一、例子 1. Worker类 1.1Worker类头文件 #ifndef WORKER_H #define WORKER_H…

量化《水手》

量化技术的两个指标是压缩比和保真度。这里使用郑智化《水手》中的一段音乐&#xff0c;对Lloyd标量量化方法和LBG矢量量化方法做对比。 原始的音乐是WAV格式&#xff0c;时长9秒钟&#xff0c;单声道&#xff0c;采样率为44.1KHz&#xff0c;每个采样点的比特数为16。 首先对…

HTTPS证书是什么?怎么获取?

HTTPS证书&#xff0c;全称是安全套接层&#xff08;SSL&#xff09;或传输层安全&#xff08;TLS&#xff09;证书&#xff0c;是一种数字证书&#xff0c;用于在互联网上建立安全的加密连接&#xff0c;确保数据在客户端&#xff08;如Web浏览器&#xff09;与服务器端&#…

评论列表信息删除功能的实现

需求&#xff1a;删除当前评论&#xff0c;并且在列表中不再显示 核心思路&#xff1a;拿到即将被删除的列表信息id,对列表进行filter过滤 1.定义渲染列表信息 2.添加渲染删除条件&#xff08;如果当前登录用户信息的uid和渲染列表信息里的uid保持一致&#xff0c;那么就将删…