横扫Spark之 - 22个常见的转换算子

水善利万物而不争,处众人之所恶,故几于道💦

文章目录

      • 1. map()
      • 2. flatMap()
      • 3. filter()
      • 4. mapPartitions()
      • 5. mapPartitionsWithIndex()
      • 6. groupBy()
      • 7. distinct()
      • 8. coalesce()
      • 9. repartition()
      • 10. sortBy()
      • 11. intersection()
      • 12.union()
      • 13. subtract()
      • 14. zip()
      • 15. partitionBy()
      • 16. groupByKey()
      • 17. reduceByKey()
      • 18. aggregateByKey()()
      • 19. sortByKey()
      • 20. mapValues()
      • 21. join()
      • 22. cogroup()

1. map()

  用于对数据进行映射转换,返回一个新的RDD
  操作的是RDD中的每个元素
例:创建一个List集合的RDD,将其中的每个数字映射为二元元组,(“偶数”, 4)、(“奇数”, 1)这样的形式

  @Testdef map(): Unit ={// 创建一个RDD,2个分区val rdd1 = sc.parallelize(List(1, 4, 6, 7),2)// 使用map()转换结构val rdd2 = rdd1.map(x => {if (x % 2 == 0)("偶数", x)else ("奇数", x)})// 遍历RDD并打印rdd2.foreach(println)}

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

2. flatMap()

  转化+压平操作,先对RDD中的每个元素进行转换,然后将转换的结果(数组、列表等)进行压平,返回一个新的RDD
  操作的单位是RDD中的每个元素
例:将RDD中的元素进行切割,然后进行扁平化处理:

@Test
def flatMap(): Unit ={val rdd1 = sc.parallelize(List("spark,scala", "python,java", "hadoop,java"),3)val rdd2 = rdd1.flatMap(x=>{// 切割后的每个元素都是一个数组,然后将多个数组进行扁平化处理x.split(",")})
// 将扁平化后的结果数组,收集到Driver端,转成List然后打印(不转换为List也能打印,只不过打印的是地址值,没有重写toString方法)println(rdd2.collect().toList)
}

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

3. filter()

  过滤数据,参数是一个返回值是Boolean类型的函数,将返回为true的元素保留
  操作的单位是每一个元素
例:过滤出RDD中奇数元素

@Test
def filter(): Unit ={val rdd1 = sc.parallelize(List(1, 2, 3, 4, 7, 8))val rdd2: RDD[Int] = rdd1.filter(x => {// 过滤奇数x % 2!=0})println(rdd2.collect().toList)
}

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

4. mapPartitions()

  以分区为单位,执行map,它拿到的是一个分区内所有数据的迭代器对象(iterator类型的迭代器),你要遍历这个迭代器对象才能拿到这个分区里面的每个数据
  这个的应用场景一般是读取数据库操作的时候用,可以减少数据库连接的创建、销毁次数,提高效率
  普通的map是一个元素一个元素的操作,如果操作每个元素的时候都创建、销毁一次数据库连接,效率太差了,可以在每个分区创建一个连接,分区内的数据操作都用这一个连接,然后处理数据,并以批的形式执行操作这样效率比较高。
  为啥不能将数据库的连接抽取出来在map函数外面创建,map里面使用连接?因为函数体外的代码是在Driver执行的(Driver负责执行main方法),函数体内处理数据的逻辑是在Executor中task去执行的task和Driver不在一台机器上,如果task想用Driver上的对象,就要Driver把这个对象通过网络传给task,网络传递肯定要序列化,执行sql的PrepareStatement对象是根本没有继承序列化接口,无法序列化,所以就会报错

例:RDD里的是学生id,要求从数据库中查出学生姓名和家庭住址并打印 - (3,test3,陕西)
map写法:

    @Testdef map(): Unit = {//  学生idval rdd1 = sc.parallelize(List(1, 3, 5, 77, 6, 34))// 对每个元素进行操作val rdd2 = rdd1.map(id=>{var connection: Connection = nullvar statement:PreparedStatement = nullvar name:String = nullvar address:String = nulltry{// 在map()函数体里面创建连接对象,因为map()是针对每个元素进行操作的,//	所以处理每个元素的时候都会进行连接的创建、销毁,效率低的要命connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123456")statement = connection.prepareStatement("select id,name,address from student where id=?")statement.setInt(1,id)val resultSet = statement.executeQuery()while (resultSet.next()) {name = resultSet.getString("name")address = resultSet.getString("address")}}catch {case e:Exception => e.printStackTrace()}finally {if (connection != null) {connection.close()}if (statement != null) {statement.close()}}(id,name,address)})println(rdd2.collect().toList)}

mapPartitions写法:

  @Testdef mapPartitions(): Unit = {val rdd1 = sc.parallelize(List(1, 3, 5, 77, 6, 34))// 每个分区进行操作val rdd2 = rdd1.mapPartitions(idIterator => {// 每个分区创建一个对象var connection: Connection = nullvar statement: PreparedStatement = null// 将查到的数据缓存起来val listBuffer: ListBuffer[(Int, String, String)] = ListBuffer[(Int, String, String)]()try {// 这个连接对象在每个分区只会创建一次connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456")statement = connection.prepareStatement("select id,name,address from student where id=?")println(connection)var name: String = nullvar address: String = null// idIterator.map(id=>{ 不能用map,因为用statement的时候连接已经被关闭了   // map()是转换算子,是延迟执行的,执行到这的时候还没有执行,而main方法已经把连接关闭了idIterator.foreach(id => {statement.setInt(1, id)val resultSet = statement.executeQuery()while (resultSet.next()) {name = resultSet.getString("name")address = resultSet.getString("address")}listBuffer += ((id, name, address))})} catch {case e: Exception => e.printStackTrace()} finally {if (connection != null) {connection.close()}if (statement != null) {statement.close()}}listBuffer.toIterator})println(rdd2.collect().toList)}

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

5. mapPartitionsWithIndex()

  和mapPartitions()类似,只不过它可以取到分区号
例:rdd1设置为2个分区,打印分区号和每个分区内的数据

  @Testdef mapPartitionsWithIndex(): Unit = {val rdd1 = sc.parallelize(List(1, 3, 99, 56, 76, 7), 2)val rdd2 = rdd1.mapPartitionsWithIndex((index, iterator) => {println(s"分区号: ${index} === 区内数据:${iterator.toList}")iterator})// 这个为啥输出空,是因为iterator迭代器只能调用一次,用过后里面就没有数据了  前面println的时候已经toList()用过了,所以后面返回的iterator本来就是个空的....println(rdd2.collect().toList)}

结果:
在这里插入图片描述  这个为啥输出空,是因为iterator迭代器只能调用一次,用过后里面就没有数据了 前面println的时候已经toList()用过了,所以后面返回的iterator本来就是个空的…

6. groupBy()

  通过传入函数的参数进行分组,分组后的value还是完整的整个元素
例:按照三元元组中第三个元素进行分组

  @Testdef groupBy(): Unit = {val rdd1 = sc.parallelize(List(("zhangsan", "man", "beijing"), ("lisi", "woman", "xian"), ("zhaoliu", "man", "xian")))val rdd2 = rdd1.groupBy(_._3)println(rdd2.collect().toList)}

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

7. distinct()

  对RDD中的元素进行去重,返回一个去重后的RDD,新的RDD默认的分区数与原RDD分区数相同,也可以指定新RDD的分区数
  去重也可以用groupBy实现,直接按照元素分组,然后把元组中的第一个元素取出来就是去重后的结果

  @Testdef distinct(): Unit = {val rdd1 = sc.parallelize(List(1, 2, 3, 4, 5, 3, 2, 1, 1))val rdd2 = rdd1.distinct()/*val rdd3 = rdd1.groupBy(w => w)val rdd4 = rdd3.map(_._1)
*/println(rdd2.collect().toList)}

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

8. coalesce()

  合并分区,不会走shuffle,分区数比原来的小才能生效,如果想要将分区变多,要开启第二个参数,它会走shuffle将分区变多
  

  @Testdef coalesce(): Unit = {// 将算子分区数设置为6个分区val rdd1 = sc.parallelize(List(3, 454, 566, 7, 5657, 6734545, 4, 5), 6)// 将分区合并为4个
//    val rdd2 = rdd1.coalesce(4)val rdd2 = rdd1.coalesce(8,true)println(rdd2.collect().toList)Thread.sleep(900000000)}

结果:通过web页面查看,可以看到分区变为了8个
在这里插入图片描述

9. repartition()

  重分区,它可以增大或者减少分区数,它底层调用的就是coalesce() 只不过把是否shuffle恒设置为了true
  

  @Testdef repartition(): Unit = {val rdd1 = sc.parallelize(List(2, 3, 4, 5, 6, 3, 3, 4, 5, 4), 4)val rdd2 = rdd1.repartition(6)println(s"rdd1分区数:${rdd1.getNumPartitions}\nrdd2分区数:${rdd2.getNumPartitions}")}

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

10. sortBy()

  排序,默认升序排序,他会走shuffle,它使用的分区器是RangePartitioner

  @Testdef sortBy(): Unit = {val rdd1 = sc.parallelize(List(1, 4, 5, 6, 7, 4, 2, 2, 5, 7, 8), 6)
// 第二个参数默认是true,也就是升序排序,降序的话就falseval rdd2 = rdd1.sortBy(x => x, false) println(rdd2.collect().toList)}

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

11. intersection()

  交集,取两个RDD的相同元素,会有两次shuffle,因为要想取出交集,就要把相同的元素聚在一起才能知道有没有相同的元素,那就rdd1落盘,rdd2落盘,然后rdd3再把两个数据拉过来,所以有两次shuffle

  @Testdef intersection(): Unit = {val rdd1 = sc.parallelize(List(1, 2, 3, 4, 5), 6)val rdd2 = sc.parallelize(List(4, 5, 6, 7, 8), 4)val rdd3 = rdd1.intersection(rdd2)println(rdd3.collect().toList)Thread.sleep(10000000)}

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

12.union()

  并集,并集没有shuffle,他只是单纯的将两个RDD的数据放到一起,不关心有没有相同的数据。新RDD的分区数是原来两个RDD分区数之和

  @Testdef union(): Unit = {val rdd1 = sc.parallelize(List(1, 2, 3, 4, 5), 5)val rdd2 = sc.parallelize(List(4, 5, 6, 7, 8), 4)val rdd3 = rdd1.union(rdd2)println(rdd3.collect().toList)println(rdd3.getNumPartitions) // 并集的分区数是两个RDD集合的分区数之和Thread.sleep(10000000)}

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

13. subtract()

  差集合,它会产生shuffle,取方法调用者的分区数,因为衍生RDD的分区数取决于依赖的第一个RDD的分区数

  @Testdef subtract(): Unit = {val rdd1 = sc.parallelize(List(1, 2, 3, 4, 5), 3)val rdd2 = sc.parallelize(List(4, 5, 6, 7, 8), 4)val rdd3 = rdd1.subtract(rdd2)println(rdd3.collect().toList)println(rdd3.getNumPartitions) //取方法调用者的分区数,衍生RDD的分区数取决于依赖的第一个RDD的分区数Thread.sleep(10000000)}

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

14. zip()

  拉链,spark中的拉链要求两个RDD的分区数和数据条数都必须一样才能拉起来
  

  @Testdef zip(): Unit = {val rdd1 = sc.parallelize(List("hello", "spark", "xian", "beijign"), 5)val rdd2 = sc.parallelize(List(1, 2, 3, 4), 5)val rdd3 = rdd1.zip(rdd2)println(rdd3.collect().toList)}

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

15. partitionBy()

  它的参数是一个分区器,按照给定的分区器重新分区。注意他这个要求操作的RDD必须是k-v键值对才能使用
  

  @Testdef partitionBy(): Unit = {val rdd1 = sc.parallelize(List(1, 3, 4, 5, 6, 7, 9), 4)//    4个分区,集合长度为7            0: (0*7)/4 - (1*7)/4  =>  0-1   => 1//                                1: (1*7)/4 - (2*7)/4  =>  1-3   => 3 4//                                2: 3 - (3*7)/4        =>  3-5   => 5 6//                                3: 5 - (4*7)/4        =>  5-6   => 7 9//val rdd2 = rdd1.map(x => {(x, null)})val rdd3 = rdd2.partitionBy(new HashPartitioner(5))//                                                        1%5 = 1 1在1号分区//                                                        3%5 = 3////                  0:  5//                  1: 1  6//                  2: 7//                  3: 3//                  4:  4  9//rdd3.mapPartitionsWithIndex((index, it) => {println(s"${index} ==  ${it.toList}")it}).collect()}

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

16. groupByKey()

  根据key分组,返回的新的RDD是KV键值对,value是所有key相同的value值。会走shuffle
  

  @Testdef groupByKey(): Unit = {val rdd1 = sc.parallelize(List(("spark", 200), ("spark", 10), ("hadoop", 700), ("scala", 50), ("flink", 90000)), 3)val rdd2 = rdd1.groupByKey(2)//    println(rdd2.getNumPartitions)rdd2.mapPartitionsWithIndex((index, it) => {println(s"groupByKey:  ${index} == ${it.toList}")it}).collect()// groupBy实现groupByKey的功能val rdd3 = rdd1.groupBy(x => x._1)val rdd4 = rdd3.map(y => (y._1, y._2.map(z => z._2)))rdd4.mapPartitionsWithIndex((index,it)=>{println(s"groupBy:  ${index} == ${it.toList}")it}).collect()}

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

17. reduceByKey()

  参数是一个函数参数,函数有两个参数,分别表示当前value的聚合结果和待聚合的value值
  

  @Testdef reduceByKey(): Unit ={
//       wc.txt
//       hello bigdata
//       spark flink
//       hbase hadoop spark flinkval rdd1 = sc.textFile("datas/wc.txt")val rdd2 = rdd1.flatMap(line => line.split(" "))val rdd3 = rdd2.map((_, 1))// reduceByKey()的函数的两个参数的含义是当前value的聚合结果和待聚合的valueval rdd4 = rdd3.reduceByKey((agg, cur) => agg + cur)println(rdd4.collect().toList)}

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

18. aggregateByKey()()

  聚合规约,他和ReduceByKey的区别是这个他的combiner逻辑和reduce的逻辑可以不一样,ReduceByKey的combiner逻辑和reduce逻辑一样
  分区内combiner的逻辑和分区间reduce的逻辑不一样

  aggregateByKey(a)(b,c)  柯里化形式第一个参数列表a是默认值第二个参数列表有两个参数:b参数是combiner逻辑,他有两个参数,第一个参数是上次聚合的结果,第一次聚合时候的初始值=默认值第二个参数是当前分组中等待聚合的value的值!!!c参数是最终reduce的逻辑,他也有两个参数,第一个参数是该组上一次的聚合结果,第一次聚合的值=第一个value的值第二个参数是当前分组中待聚合的value值
  @Testdef aggregateByKey(): Unit ={val rdd1 = sc.textFile("datas/stu_score.txt")val rdd2 = rdd1.map(line => {val arr = line.split(" ")val name = arr(1)val score = arr(2).toInt(name, score)})//    默认值是(0,0)表示课程成绩为0 ,次数为0次val rdd3 = rdd2.aggregateByKey((0, 0))(// combiner的逻辑,agg是上次combiner的结果,刚开始的时候等于刚才设置的默认值;curValue是当前分组中等待聚合的value的值也就是score成绩(agg, curValue) => {// 将成绩和当前待聚合的成绩累加,次数标记+1(agg._1 + curValue, agg._2 + 1)},// 这里就是reduce的逻辑,也就是combiner聚合后的结果最终的reduce// agg是以前预聚合的结果,cur是当前的结果  ,需要进行成绩的累加和次数的累加(agg, cur) => {(agg._1 + cur._1, agg._2 + cur._2)})val rdd4 = rdd3.map(x => {(x._1, x._2._1 / x._2._2)})println(rdd4.collect().toList)}

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

19. sortByKey()

  通过key排序,默认升序,这个可以用sortBy代替

  @Testdef sortByKey(): Unit ={val rdd1 = sc.parallelize(List(6, 12, 4, 6, 8, 2, 4, 89, 1))val rdd2 = rdd1.map((_, null))val rdd3 = rdd2.sortByKey(false)val rdd4 = rdd2.sortBy(_._1, false)println(rdd3.collect().toList)println(rdd4.collect().toList)}

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

20. mapValues()

  对value进行操作,这个也比较局限,可以用map代替

  @Testdef mapValues(): Unit ={val rdd1 = sc.parallelize(List("xian" -> 10, "beijing" -> 40, "shanghai" -> 60, "qcln" -> 100))val rdd2 = rdd1.mapValues(_ / 10)val rdd2_1 = rdd1.map(x => {(x._1, x._2 / 10)})println(rdd2.collect().toList)println(rdd2_1.collect().toList)}

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

21. join()

  join连接,也分为内连接,左外,右外,全外

  @Testdef join(): Unit ={val rdd1 = sc.parallelize(List(("aa",11),("bb",12),("aa",13),("cc",14)))val rdd2 = sc.parallelize(List(("aa",1.1),("cc",2.2),("dd",3.3),("cc",4.4)))// todo inner join = 左表和右表能够连接的数据val rdd3 = rdd1.join(rdd2)println(rdd3.collect().toList)// todo left join = 左表和右表能够连接的数据 + 左表不能连接的数据val rdd4 = rdd1.leftOuterJoin(rdd2)println(rdd4.collect().toList)// todo right join = 左表和右表能够连接的数据 + 右表不能连接的数据val rdd5 = rdd1.rightOuterJoin(rdd2)println(rdd5.collect().toList)// todo full join = 左表和右表能够连接的数据 + 左表和右表不能连接的数据val rdd6 = rdd1.fullOuterJoin(rdd2)println(rdd6.collect().toList)}

22. cogroup()

  这个相当于先对rdd1进行groupByKey然后与rdd2进行full outer join

  @Testdef cogroup(): Unit ={val rdd1 = sc.parallelize(List(("aa",11),("bb",12),("aa",13),("cc",14)))val rdd2 = sc.parallelize(List(("aa",1.1),("cc",2.2),("dd",3.3),("cc",4.4)))val rdd3 = rdd1.cogroup(rdd2)println(rdd3.collect().toList)}

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

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

相关文章

蓝桥杯每日一练(python)B组

###来源于dotcpp的蓝桥杯真题 题目 2735: 蓝桥杯2022年第十三届决赛真题-取模&#xff08;Python组&#xff09; 给定 n, m &#xff0c;问是否存在两个不同的数 x, y 使得 1 ≤ x < y ≤ m 且 n mod x n mod y 。 输入格式&#xff1a; 输入包含多组独立的询问。 第一…

二维差分---三维差分算法笔记

文章目录 一.二维差分构造差分二维数组二维差分算法状态dp求b[i][j]数组的二维前缀和图解 二.三维前缀和与差分三维前缀和图解:三维差分核心公式图解:模板题 一.二维差分 给定一个原二维数组a[i][j],若要给a[i][j]中以(x1,y1)和(x2,y2)为对角线的子矩阵中每个数都加上一个常数…

绕过系统访问控制

我们研究了最近NSA/CISA 联合网络安全咨询&#xff0c;该咨询涉及这些组织在红/蓝团队演习中发现的首要网络安全问题。在本文中&#xff0c;您将更深入地了解特定问题&#xff0c;包括适用的实际场景&#xff0c;以及可用于限制或克服该问题的缓解策略。这扩展了 NSA/CISA 报告…

C++自幂数判断<GESP C++ 二级>

题目&#xff1a; 代码&#xff1a; #include <iostream> using namespace std; int main() {int m 0;cin >> m;for (int i 0; i < m; i) {int n 0;cin >> n;// 数一下 n 有多少位数&#xff0c;记为 lint t n, l 0;while (t > 0) {t / 10;l;}/…

boot::process::child::wait_until 线程不安全

最近在项目中需要多线程调用子程序。子程序可能工作时间很长&#xff0c;故用 boost::process::child::wait_until 来实现超时功能。 然而&#xff0c;多线程压力测试时&#xff0c;发现有可能导致 core dump。 经查证&#xff0c;是 boost::process::child::wait_until 的一个…

Linux中断编程

大家好&#xff0c;今天给大家介绍Linux中断编程&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 Linux中断编程涉及到操作系统层面的中断处理机制&#xff0c;它是Linux内核与硬…

SPSS基础操作:对数据按照样本观测值进行排序

在整理数据资料或者查看分析结果时&#xff0c;我们通常希望样本观测值能够按照某一变量的大小进行升序或者降序排列&#xff0c;比如我们想按照学生的学习成绩进行排序&#xff0c;按照销售额的大小对各个便利店进行排序等。以本章附带的数据4为例&#xff0c;如果要按照y4体重…

JavaWeb02-MyBatis

目录 一、MyBatis 1.概述 2.JavaEE三层架构简单介绍 &#xff08;1&#xff09;表现层 &#xff08;2&#xff09;业务层 &#xff08;3&#xff09;持久层 3.框架 4.优势 &#xff08;1&#xff09;JDBC的劣势 &#xff08;2&#xff09;MyBatis优化 5.使用 &#…

第六章:纹理贴图

本文是《从0开始图形学》笔记的第六章,介绍模型纹理的实现,涉及到重心坐标的计算方式和作用,本章之后,我们的模型将从单色变成更为丰富的彩色。 纹理贴图数据格式 前面几章我们已经可以将复杂的模型渲染出来了,但是模型还是单色的,这显然是不够的,模型还需要各种各样的…

除夕快乐(前端小烟花)

家人们&#xff0c;新的一年好运常在&#xff0c;愿大家在新的一年里得偿所愿&#xff0c;发财暴富&#xff0c;愿大家找到属于自己的那个公主&#xff0c;下面就给大家展示一下给公主的烟花 前端烟花 新的一年&#xff0c;新的挑战&#xff0c;愿我们不忘初心&#xff0c;砥砺…

【C生万物】数组

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有…

教你如何生成自己的专属动态龙新年图像 - Python实现摘要

引言 新年将至&#xff0c;为了给大家带来一丝喜庆和神秘的气氛&#xff0c;我决定用Python编写一个生成专属动态龙图像的小程序。通过这个程序&#xff0c;你可以生成一个独一无二的龙图像&#xff0c;并为它添加动态效果&#xff0c;让它在新年的时刻为你带来好运和祝福。 正…

生成式人工智能攻击的一年:2024

趋势科技最近公布了其关于预期最危险威胁的年度研究数据。生成人工智能的广泛可用性和质量将是网络钓鱼攻击和策略发生巨大变化的主要原因。 趋势科技宣布推出“关键可扩展性”&#xff0c;这是著名年度研究的新版本&#xff0c;该研究分析了安全形势并提出了全年将肆虐的网络…

学习Android的第七天

目录 Android EditText 输入框 设置默认提示文本 范例 获得焦点后全选组件内所有文本内容 范例 限制EditText输入类型 android:inputType 值列表 范例 设置最小行&#xff0c;最多行&#xff0c;单行&#xff0c;多行&#xff0c;自动换行 范例 设置文字间隔 范例 …

力扣231. 2 的幂(数学,二分查找,位运算)

Problem: 231. 2 的幂 文章目录 题目描述思路即解法复杂度Code 题目描述 思路即解法 思路1&#xff1a;位运算 1.易验证2的幂为正数&#xff1b; 2.易得2的幂用二进制表示只能有一个位为数字1 3.即将其转换为二进制统计其二进制1的个数 思路2&#xff1a;数学 当给定数n大于1时…

MATLAB实现LSTM时间序列预测

LSTM模型可以在一定程度上学习和预测非平稳的时间序列&#xff0c;其具有强大的记忆和非线性建模能力&#xff0c;可以捕捉到时间序列中的复杂模式和趋势[4]。在这种情况下&#xff0c;LSTM模型可能会自动学习到时间序列的非平稳性&#xff0c;并在预测中进行适当的调整。其作为…

Maui blazor ios 按设备类型设置是否启用safeArea

需求&#xff0c;新做了个app&#xff0c; 使用的是maui blazor技术&#xff0c;里面用了渐变背景&#xff0c;在默认启用SafeArea情况下&#xff0c;底部背景很突兀 由于现版本maui在SafeArea有点bug&#xff0c;官方教程的<ContentPage SafeAreafalse不生效&#xff0c;于…

攻防世界 CTF Web方向 引导模式-难度1 —— 11-20题 wp精讲

PHP2 题目描述: 暂无 根据dirsearch的结果&#xff0c;只有index.php存在&#xff0c;里面也什么都没有 index.phps存在源码泄露&#xff0c;访问index.phps 由获取的代码可知&#xff0c;需要url解码(urldecode )后验证id为admin则通过 网页工具不能直接对字母进行url编码 …

物联网数据隐私保护技术

在物联网&#xff08;IoT&#xff09;的世界中&#xff0c;无数的设备通过互联网连接在一起&#xff0c;不断地收集、传输和处理数据。这些数据有助于提高生产效率、优化用户体验并创造新的服务模式。然而&#xff0c;随着数据量的剧增&#xff0c;数据隐私保护成为了一个不能忽…

centos中docker操作

一、安装docker 确保系统是CentOS 7并且内核版本高于3.10,可以通过uname -r命令查看内核版本。 更新系统软件包到最新版本,可以使用命令yum update -y。 安装必要的软件包,包括yum-utils、device-mapper-persistent-data和lvm2。使用命令yum install -y yum-utils devic…