当前位置: 首页 > news >正文

sparkRDD教程之基本命令

作者:nchu可乐百香果

指导者:nchu-YoungDragon

1.前期准备

(1)从迅雷网盘上面下载这个项目,并且把scala,maven和java环境配置好

网盘链接:

分享文件:SparkRDD.zip
链接:https://pan.xunlei.com/s/VOGUwt7hVp1ZQB6V7n1j6e70A1?pwd=q87r#
复制这段内容后打开迅雷,查看更方便

打开项目后,其目录结构如下:

(2)新建一个scala object文件 (点击新建scala文件后选择第三个选项object)

固定模版

.appName("task5"),这个名字建议改为自己当前的文件名
package com.itheimaimport org.apache.spark.sql.SparkSessionobject task5 {def main(args: Array[String]): Unit = {// 创建SparkSessionval spark = SparkSession.builder.appName("task5").master("local").getOrCreate()val sc = spark.sparkContext//在这里写代码spark.stop()}}

2.sparkRDD的基本命令

x._1表示元组的第一项(从1开始数这里,反正这样的写法是从1开始数的)

当然,x(0)是从0开始数的

(1)创建sparkRDD和打印输出

第一种方式
    val rdd1=sc.parallelize(List(1,2,3,4))println(rdd1.collect().mkString("\n"))

 结果

第二种方式
    val rdd2=sc.makeRDD(List(1,2,3,4))println(rdd2.collect().mkString("\n"))

 结果

第三种方式
    var score_path="src\\main\\resources\\score.txt"val rdd3=sc.textFile(score_path)println(rdd3.collect().mkString("\n"))

score.txt

student_id,course_code,score
108,3-105,99
105,3-105,88
107,3-105,77
105,3-245,87
108,3-245,89
107,3-245,82
106,3-245,74
107,6-101,75
108,6-101,82
106,6-101,65
109,6-102,99
101,6-102,79
105,9-106,81
106,9-106,97
107,9-106,65
108,9-106,100
109,9-106,82
105,6-102,85

(2)map命令

代码1 

    var rdd1=sc.parallelize(List(1,2,3,4))var res1=rdd1.map(x=>x*x*x)println(res1.collect().mkString("\n"))

结果 1

代码2

    var rdd2=sc.parallelize(List("a","b","c"))var res2=rdd2.map(x=>(x,1))println(res2.collect().mkString("\n"))

结果2

(3)flatmap命令(这个用起来有一些限制,所以使用的很少,我感觉不太好用,不如map简单直接)

代码 1

    val rdd2 = sc.parallelize(List("a b c", "d e f", "g h i"))val map_res = rdd2.map(x => x.split(" "))println(map_res.collect().mkString("\n"))val flatMap_res = rdd2.flatMap(x => x.split(" "))println(flatMap_res.collect().mkString("\n"))

结果1 

(4)sortBy命令(默认值是true,表示升序排序)

代码1

    val rdd = sc.parallelize(List('a','b','c','d','e'))val res = rdd.map(x =>(x,1)).sortBy(x=>x._1, true)//true可以省略println(res.collect().mkString("\n"))

截图1

代码2

    val rdd = sc.parallelize(List('a','b','c','d','e'))val res = rdd.map(x =>(x,1)).sortBy(x=>x._1, false)println(res.collect().mkString("\n"))

截图2

代码3

    val rdd = sc.parallelize(1 to 10)val res = rdd.map(x =>(x,1)).sortBy(x=>x._1, false)println(res.collect().mkString("\n"))

截图3

(5)filter命令(满足条件的留下来,和sql中的where命令类似)

代码1

    val rdd = sc.parallelize(1 to 10)val res = rdd.filter(x=>x<=5)println(res.collect().mkString("\n"))

截图1

代码2

    val rdd = sc.parallelize(1 to 10)val res = rdd.filter(x=>x>=3 && x<=5)println(res.collect().mkString("\n"))

截图2

(6)distinct命令(去重)

代码1

    val rdd = sc.parallelize(List(1,2,2,3,3))val res = rdd.distinct()println(res.collect().mkString("\n"))

截图1

(7)union命令(类似于求并集,但是不会自动去重)

代码1

    val rdd1 = sc.parallelize(List(1,2,3,4))val rdd2 = sc.parallelize(List(3,4,5,6))val res = rdd1.union(rdd2)println(res.collect().mkString("\n"))

截图1

(8)intersection(类似于求交集)

代码1

    val rdd1 = sc.parallelize(List(1,2,3,4))val rdd2 = sc.parallelize(List(3,4,5,6))val res = rdd1.intersection(rdd2)println(res.collect().mkString("\n"))

截图1

(9)subtract(类似于求差集)

代码1

    val rdd1 = sc.parallelize(List(1,2,3,4))val rdd2 = sc.parallelize(List(3,4,5,6))val res1_2 = rdd1.subtract(rdd2)println(res1_2.collect().mkString("\n"))

截图1

代码2

    val rdd1 = sc.parallelize(List(1,2,3,4))val rdd2 = sc.parallelize(List(3,4,5,6))val res2_1 = rdd2.subtract(rdd1)println(res2_1.collect().mkString("\n"))

截图2

(10)cartesion(求笛卡尔积)

代码1

    val rdd1 = sc.parallelize(List(1,2,3,4))val rdd2 = sc.parallelize(List(3,4,5,6))val res = rdd1.cartesian(rdd2)println(res.collect().mkString("\n"))

截图1

(11)keyBy命令

代码1-3的前期准备,初始化rdd

val rdd = sc.parallelize(List('a','b','c','d','e'))

代码1

    val res1 = rdd.map(x => (1, 2, x)).keyBy(x => x._1)println(res1.collect().mkString("\n"))

截图1

代码2

    val res2 = rdd.map(x => (1, 2, x)).keyBy(x => x._2)println(res2.collect().mkString("\n"))

截图2

代码3

    val res3 = rdd.map(x => (1, 2, x)).keyBy(x => x._3)println(res3.collect().mkString("\n"))

截图3

总结

    val rdd = sc.parallelize(List('a', 'b', 'c', 'd', 'e'))val res1 = rdd.map(x => (1, 2, x)).keyBy(x => x._1)val res11 = rdd.map(x => (1, 2, x)).map(x=>(x._1,x)) //这2行代码等价println(res1.collect().mkString("\n"))println(res11.collect().mkString("\n"))

(12)mapValues(对所有值进行相同的操作,同时要求是二元组结构)

代码1

    val rdd = sc.parallelize(List('a', 'b', 'c', 'd', 'e'))val rdd2=rdd.map(x=>(x,1))println(rdd2.collect().mkString("\n"))

截图1  (显然此时它们的value都为1)

代码2

    val rdd = sc.parallelize(List('a', 'b', 'c', 'd', 'e'))val rdd2=rdd.map(x=>(x,1)).mapValues(x=>x*20)println(rdd2.collect().mkString("\n"))

截图2

(13)reduceByKey(对相同键的值进行操作,同时要求是二元组结构)

代码1

    val rdd = sc.parallelize(List('a', 'b', 'c', 'd', 'e'))val rdd2=rdd.map(x=>(x,1)).mapValues(x=>x*20)var rdd4=rdd2.union(rdd2).union(rdd2)println(rdd4.collect().mkString("\n"))

截图1

代码2

    val rdd = sc.parallelize(List('a', 'b', 'c', 'd', 'e'))val rdd2=rdd.map(x=>(x,1)).mapValues(x=>x*20)var rdd4=rdd2.union(rdd2).union(rdd2)var rdd5=rdd4.reduceByKey((y1,y2)=>(y1+y2))println(rdd5.collect().mkString("\n"))

截图2

(14)groupBy命令(我感觉使用的不多,了解即可)

代码1

    val rdd = sc.parallelize(0 to 9)val rdd2=rdd.groupBy(x=>{if( x % 2==0) "even" else "odd" })println(rdd2.collect().mkString("\n"))

截图1

(15)groupByKey命令(我感觉使用的不多,了解即可)

代码1

    val rdd = sc.parallelize(List(('a',1),('b',2),('c',3)))val rdd1 = sc.parallelize(List(('a',4),('b',5),('c',6)))val rdd2=rdd.union(rdd1)println(rdd2.collect().mkString("\n"))

截图1

代码2

    val rdd = sc.parallelize(List(('a',1),('b',2),('c',3)))val rdd1 = sc.parallelize(List(('a',4),('b',5),('c',6)))val rdd2=rdd.union(rdd1).groupByKey()println(rdd2.collect().mkString("\n"))

截图2

(16)join命令

代码1

    val rdd1 = sc.parallelize(List(("K1", "V1"), ("K2", "V2"), ("K3", "V3")))val rdd2 = sc.parallelize(List(("K1", "V2"), ("K2", "V3"), ("K4", "V4")))var join1 = rdd1.join(rdd2)println(join1.collect().mkString("\n"))

截图1

代码2  (利用其他方法来实现和join类似的效果)

    val rdd1 = sc.parallelize(List(("K1", "V1"), ("K2", "V2"), ("K3", "V3")))val rdd2 = sc.parallelize(List(("K1", "V2"), ("K2", "V3"), ("K4", "V4")))var res2 = rdd1.union(rdd2).mapValues(x => (x, "V")).reduceByKey((y1, y2) => (y1._1, y2._1)).filter(x => x._2._2 != "V").sortBy(x => x._1)println(res2.collect().mkString("\n"))

截图2

(17)zip命令

代码1

    var rdd3=sc.makeRDD(1 to 5)var rdd4=sc.makeRDD(List('a','b','c','d','e'))var res3_4=rdd3.zip(rdd4)println(res3_4.collect().mkString("\n"))

截图1

代码2

    var rdd3 = sc.makeRDD(1 to 5)var rdd4 = sc.makeRDD(List('a', 'b', 'c', 'd', 'e'))var res4_3=rdd4.zip(rdd3)println(res4_3.collect().mkString("\n"))

截图2

(18)其他命令

3.总结一下

(1)第一点,也是重点

x._1表示元组的第一项(从1开始数这里,反正这样的写法是从1开始数的)

当然,x(0)是从0开始数的

count命令的返回值long类型,这一点要注意,经常需要使用toInt来转Int

(2)join命令的等价替换

这个其实主要还是为了方便自己更好理解这些命令

求点赞求收藏求关注

作者:nchu可乐百香果

指导者:nchu-YoungDragon

4.其他

(1)代码注释

package com.itheima

// 导入SparkSession和SaveMode等相关库
import org.apache.spark.sql.{SparkSession, SaveMode}

object task1 {
  def main(args: Array[String]): Unit = {
    // 创建SparkSession对象,这个对象是操作Spark的入口
    val spark = SparkSession
      .builder
      .appName("WordCount")  // 设置应用程序名称
      .master("local")  // 设置运行模式为local,即在本地运行,可以通过集群模式连接远程集群
//      .master("spark://192.168.88.101:7077")  // 这行代码可以用于连接到远程Spark集群,当前是注释掉的
      .getOrCreate()  // 获取SparkSession对象,如果没有则创建

    // 获取SparkContext对象,SparkContext是Spark应用的核心,用来创建RDD
    val sc = spark.sparkContext

    // 读取HDFS上的两个文本文件并创建RDD
    val rdd1 = sc.textFile("hdfs://node1:8020/input/A.txt")  // 读取A.txt文件
    val rdd2 = sc.textFile("hdfs://node1:8020/input/B.txt")  // 读取B.txt文件

//    // 本地文件读取方式(注释掉)
//    val rdd1 = sc.textFile("D:\\新建文件夹 (3)\\2024大三上学期文件夹\\黑马Redis笔记\\SparkRDD\\src\\main\\java\\com\\springbootdemo\\A.txt")
//    val rdd2 = sc.textFile("D:\\新建文件夹 (3)\\2024大三上学期文件夹\\黑马Redis笔记\\SparkRDD\\src\\main\\java\\com\\springbootdemo\\B.txt")

    // 合并两个RDD,并进行处理:
    // 1. 使用union合并两个RDD
    // 2. 使用map将每行文本按空格分割,取第一个和第二个元素作为元组
    // 3. 使用sortBy按元组的第一个元素排序
    // 4. 使用distinct去重
    val rdd3 = rdd1.union(rdd2).map(x => (x.split(" ")(0), x.split(" ")(1))).sortBy(_._1).distinct()

    // 将RDD转换为DataFrame,DataFrame是SparkSQL中用于表示结构化数据的核心数据结构
    val data = spark.createDataFrame(rdd3).toDF("value1", "value2")  // 设置DataFrame的列名为value1和value2

    // 配置数据库连接参数,假设目标数据库为MySQL
    // 设置数据库的连接URL,包含主机地址和端口号
    // val jdbcUrl = "jdbc:mysql://192.168.88.101:3306/spark"  // 使用远程MySQL服务器的URL(注释掉)
    val jdbcUrl = "jdbc:mysql://127.0.0.1:3306/spark"  // 使用本地MySQL服务器的URL
    val jdbcUser = "root"  // 数据库的用户名
    val jdbcPassword = "123456"  // 数据库的密码

    // 将DataFrame写入MySQL数据库
    data.write
      .format("jdbc")  // 使用JDBC格式进行数据写入
      .option("url", jdbcUrl)  // 配置JDBC连接URL
      .option("dbtable", "spark_task1")  // 指定目标数据库表名
      .option("user", jdbcUser)  // 配置数据库用户名
      .option("password", jdbcPassword)  // 配置数据库密码
      .mode(SaveMode.Overwrite)  // 写入模式设置为覆盖(Overwrite),会覆盖已有数据
      .save()  // 执行保存操作

    // 停止SparkSession,释放资源
    spark.stop()
  }
}

代码流程简述:

  1. 创建SparkSession:初始化Spark的核心环境,允许你使用SparkSQL等高级API。
  2. 读取数据:从HDFS或本地文件系统读取两个文本文件,创建RDD。
  3. 数据转换:对读取的RDD进行转换,进行数据的合并、分割、排序和去重操作。
  4. 转换为DataFrame:将RDD转换为DataFrame以便使用SQL等功能。
  5. 数据库配置:设置MySQL数据库连接的URL、用户名和密码。
  6. 将数据写入数据库:将处理后的DataFrame写入到指定的MySQL表中。
  7. 关闭SparkSession:释放资源,结束Spark应用。

(2)什么是SparkSession

`SparkSession` 是 Spark 2.0 引入的一个统一入口点,它简化了与 Spark 相关的所有操作,包括批处理、流处理、机器学习和图计算等。

在 Spark 1.x 中,用户使用 `SQLContext` 和 `HiveContext` 等不同的上下文来操作 Spark SQL 数据库或者使用 RDD API,而 `SparkSession` 将这些功能整合在一起,成为一个统一的入口,使得用户不需要区分具体的上下文。

### 主要功能和作用:

1. **创建 DataFrame 和 DataSet**:
   `SparkSession` 允许用户通过 `read` 接口创建 DataFrame 或者 DataSet,支持多种数据源如:CSV、JSON、Parquet、JDBC、HDFS 等。
   
2. **访问 Spark SQL**:
   通过 `SparkSession` 可以直接执行 SQL 查询,执行结果以 DataFrame 形式返回。

3. **Spark 应用的入口点**:
   `SparkSession` 提供了访问 `SparkContext`、`SQLContext`、`HiveContext` 等功能,因此它是操作 Spark 集群的主入口。

4. **管理 Spark 配置**:
   `SparkSession` 允许用户设置 Spark 配置参数,控制 Spark 作业的行为,比如内存大小、执行模式等。

5. **集成 Hive**:
   在 Spark 2.0 中,`SparkSession` 也提供了对 Hive 的支持,使得 Spark 可以无缝集成到 Hive 环境中,支持执行 HiveQL 查询。

### 创建 `SparkSession` 的基本步骤:
1. **初始化 SparkSession**:
   使用 `SparkSession.builder()` 创建一个 SparkSession 实例,并配置应用名称、运行模式等。

   ```scala
   val spark = SparkSession
     .builder()
     .appName("Example Application")
     .master("local[*]")  // 运行模式(local表示在本地运行,*表示使用所有CPU核心)
     .getOrCreate()  // 获取或创建 SparkSession
   ```

2. **通过 SparkSession 执行 SQL 操作**:
   ```scala
   val df = spark.read.json("path_to_json_file")
   df.createOrReplaceTempView("table_name")  // 创建临时视图
   val result = spark.sql("SELECT * FROM table_name")  // 执行SQL查询
   result.show()
   ```

3. **通过 SparkSession 访问 SparkContext**:
   `SparkSession` 提供了对 `SparkContext` 的访问,可以通过 `spark.sparkContext` 获取。
   ```scala
   val sc = spark.sparkContext  // 获取 SparkContext
   ```

### SparkSession 的重要属性和方法:
- `spark.read`:用于读取数据(如 CSV、JSON、Parquet 等)。
- `spark.sql()`:用于执行 SQL 查询。
- `spark.catalog`:用于管理表、视图等元数据。
- `spark.udf`:用于注册用户自定义函数(UDF)。
- `spark.version`:用于获取 Spark 版本。

### 示例:
```scala
val spark = SparkSession.builder()
  .appName("Spark Session Example")
  .master("local")
  .getOrCreate()

// 使用 SparkSession 读取数据
val df = spark.read.csv("path/to/data.csv")

// 执行 SQL 查询
df.createOrReplaceTempView("my_table")
val result = spark.sql("SELECT * FROM my_table WHERE column1 > 100")
result.show()

// 停止 SparkSession
spark.stop()
```

通过 `SparkSession`,Spark 提供了一个统一的接口来执行不同类型的操作,简化了 Spark 程序的编写和执行过程。

相关文章:

sparkRDD教程之基本命令

作者&#xff1a;nchu可乐百香果 指导者&#xff1a;nchu-YoungDragon 1.前期准备 &#xff08;1&#xff09;从迅雷网盘上面下载这个项目&#xff0c;并且把scala&#xff0c;maven和java环境配置好 网盘链接&#xff1a; 分享文件&#xff1a;SparkRDD.zip 链接&#xf…...

Linux:SystemV通信

目录 一、System V通信 二、共享内存 代码板块 总结 三、信号量 信号量理论 信号量接口 一、System V通信 System V IPC&#xff08;inter-process communication&#xff09;&#xff0c;是一种进程间通信方式。其实现的方法有共享内存、消息队列、信号量这三种机制。 …...

C#上位机通过CAN总线发送bin文件

让gpt生成一段代码用来把bin文件通过can总线发出去 c#代码还是比较强大的&#xff0c;各种功能基本都是一两行代码就实现了&#xff0c;这里记录一下对这个代码的理解和解读 主要代码如下&#xff0c;传入bin文件的地址即可将其从指定的can通道发送出去&#xff1a; public …...

CV 图像处理基础笔记大全(超全版哦~)!!!

一、图像的数字化表示 像素 数字图像由众多像素组成&#xff0c;是图像的基本构成单位。在灰度图像中&#xff0c;一个像素用一个数值表示其亮度&#xff0c;通常 8 位存储&#xff0c;取值范围 0 - 255&#xff0c;0 为纯黑&#xff0c;255 为纯白。例如&#xff0c;一幅简单的…...

2-Kbengine+Unity3D多人在线游戏DEMO源码架构分析

2-Kbengine+Unity3D多人在线游戏DEMO源码架构分析 目录 一、服务器端 1、编写并生成我们的服务器端和客户端通用的游戏协议 2、 认识Entity实体 3、 官方DEMO-kbengine_demos_assets分析 二、 客户端...

Vue.js组件开发-如何实现表头搜索

在Vue.js组件开发中&#xff0c;实现表头搜索通常涉及在表格组件的表头添加输入框&#xff0c;并让用户能够输入搜索关键字来过滤表格数据。 以下是一个使用Element UI的el-table组件实现表头搜索的示例&#xff1a; 一、准备阶段 ‌确保Element UI已安装‌&#xff1a; 确保…...

lerna使用指南

lerna版本 以下所有配置命令都是基于v8.1.9&#xff0c;lerna v5 v7版本差别较大&#xff0c;在使用时&#xff0c;注意自身的lerna版本。 lerna开启缓存及缓存配置 nx缓存是v5版本以后才有的&#xff0c;小于该版本的无法使用该功能。 初始化配置 缓存配置文件nx.json&am…...

spark,读取和写入同一张表问题

读取a表&#xff0c;写入a表 1.写入的是分区表&#xff0c;不报错 2.读取上来之后&#xff0c;创建为临时视图temp&#xff0c;然后先写入a表&#xff0c;再使用temp&#xff0c;就会报错 解决办法&#xff1a;可以先使用temp&#xff0c;再写入a表 3.写入的不是分区表&…...

iOS - TLS(线程本地存储)

从源码中&#xff0c;详细总结 TLS (Thread Local Storage) 的实现&#xff1a; 1. TLS 基本结构 // TLS 的基本结构 struct tls_data {pthread_key_t key; // 线程本地存储的键void (*destructor)(void *); // 清理函数 };// 自动释放池的 TLS class Autorelease…...

node.js项目依赖关系分析工具 Depazer 的使用

node.js项目依赖关系分析工具 Depazer 的使用 Depazer 是一个用于 分析和可视化 Node.js 项目依赖关系 的工具。它可以帮助开发者快速了解项目的依赖结构、模块关系&#xff0c;以及可能存在的问题&#xff0c;从而优化代码架构和依赖管理。 功能特点 依赖关系分析&#xff1…...

QT 如何禁止QComboBox鼠标滚轮

一般情况下&#xff0c;QComboBox会相应鼠标的滚轮事件&#xff0c;即当鼠标停靠在QComboBox上方时&#xff0c;滚动鼠标滚轮&#xff0c;QComboBox的选项会发生切换。但这或许并不是我们希望所出现的&#xff0c;尤其是当QComboBox嵌入在QScrollArea中时&#xff0c;用户只是想…...

理解CPU负载与使用率

目录 CPU使用率 CPU负载 CPU使用率 定义&#xff1a;就像看一个工人干活的时间占他上班时间的比例。比如工人上班8小时&#xff0c;实际干活6小时&#xff0c;干活时间占比就是68100%75%。对于CPU&#xff0c;单核的看它被占用的时间占总时间的比例&#xff0c;多核的就把每个…...

浅谈计算机网络01 | SDN数据平面

浅谈基本云架构 一、计算机网络数据平面的基础理论1.1 数据平面与控制平面的区分1.1.1 两者功能差异1.1.2 协同工作机制 1.2 数据平面在网络架构中的位置与角色1.2.1 与各网络层次的关系1.2.2 对网络整体性能的影响 二、数据平面的关键技术原理2.1 转发技术2.1.1 基于目的地转发…...

《Java开发手册》核心内容

文章目录 引言I 编程规约II 异常日志III 单元测试 :IV 安全规约 :V MySQL数据库:VI 工程结构 :VII 设计规约 :引言 手册的愿景是提升代码质量和开发效率,通过规范化的编码实践来减少错误和提高系统的稳定性。 I 编程规约 命名风格:规定了命名的一致性和规范性,避免使…...

采用海豚调度器+Doris开发数仓保姆级教程(满满是踩坑干货细节,持续更新)

目录 一、采用海豚调度器+Doris开发平替CDH Hdfs + Yarn + Hive + Oozie的理由。 1. 架构复杂性 2. 数据处理性能 3. 数据同步与更新 4. 资源利用率与成本 6. 生态系统与兼容性 7. 符合信创或国产化要求 二、ODS层接入数据 接入kafka实时数据 踩坑的问题细节 三、海…...

通过将模型权重的矩阵表示为低秩矩阵,可以减少需要调整的参数数量,通俗易懂的解释,不懂你爬网线打我

通过将模型权重矩阵表示为低秩矩阵&#xff0c;可以减少需要调整的参数数量&#xff0c;原因在于低秩矩阵的结构本身就比高秩矩阵更“紧凑”&#xff0c;即它们需要的独立参数更少。具体来说&#xff0c;低秩矩阵的结构可以通过减少模型的自由度&#xff08;独立参数的数量&…...

Java并发编程——线程池(基础,使用,拒绝策略,命名,提交方式,状态)

我是一个计算机专业研0的学生卡蒙Camel&#x1f42b;&#x1f42b;&#x1f42b;&#xff08;刚保研&#xff09; 记录每天学习过程&#xff08;主要学习Java、python、人工智能&#xff09;&#xff0c;总结知识点&#xff08;内容来自&#xff1a;自我总结网上借鉴&#xff0…...

DilateFormer: Multi-Scale Dilated Transformer for Visual Recognition 中的空洞自注意力机制

空洞自注意力机制 文章目录 摘要1. 模型解释1.1. 滑动窗口扩张注意力1.2. 多尺度扩张注意力 2. 代码3. 流程图3.1. MultiDilatelocalAttention3.2. DilateAttention3.3. MLP 摘要 本文针对DilateFormer中的空洞自注意力机制原理和代码进行详细介绍&#xff0c;最后通过流程图梳…...

二十三种设计模式-适配器模式

适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将不兼容的接口转换成客户端期望的接口&#xff0c;从而使原本因接口不匹配而不能一起工作的类可以协同工作。以下是关于适配器模式的详细介绍&#xff1a; 一、定义及作用 定义&am…...

复用类(2):代理、结合使用组合和继承

1 代理 第三种关系称为代理&#xff0c;这是继承与组合之间的中庸之道&#xff0c;因为我们将一个成员对象置于所要构造的类中&#xff08;就像组合&#xff09;&#xff0c;但与此同时我们在新类中暴露了该成员对象的所有方法&#xff08;就像继承&#xff09;。例如&#xff…...

浅谈云计算07 | 云安全机制

云计算安全机制 一、引言二、加密技术&#xff1a;数据的隐形护盾三、散列机制&#xff1a;数据完整性的忠诚卫士四、数字签名&#xff1a;数据来源与真伪的鉴定专家五、公钥基础设施&#xff08;PKI&#xff09;&#xff1a;信任的基石六、身份与访问管理&#xff08;IAM&…...

【机器学习】零售行业的智慧升级:机器学习驱动的精准营销与库存管理

我的个人主页 我的领域&#xff1a;人工智能篇&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;&#x1f44d;点赞 收藏❤ 在当今数字化浪潮汹涌澎湃的时代&#xff0c;零售行业正站在转型升级的十字路口。市场竞争的白热化使得企业必须另辟蹊径&#xff0…...

深入理解 Entity、VO、QO、DTO 的区别及其在 MVC 架构中的应用

文章背景 在现代软件开发中&#xff0c;我们经常会接触到各种数据结构的概念&#xff0c;比如 Entity、VO&#xff08;Value Object&#xff09;、QO&#xff08;Query Object&#xff09;、DTO&#xff08;Data Transfer Object&#xff09;等。这些概念尽管看似相似&#xff…...

vue集成高德地图API实现坐标拾取功能

安装与配置&#xff1a; 组件 | vue-amapDescriptionhttps://elemefe.github.io/vue-amap/#/zh-cn/introduction/install简介 | vuemap/vue-amap简介https://vue-amap.guyixi.cn/zh-cn/introduction/introduction.html ​​​​我的应用 | 高德控制台高德开放平台官网控…...

Spring Boot Actuator 详细介绍

Spring Boot Actuator 详细介绍 1. 简介 Spring Boot Actuator 是 Spring Boot 提供的一个用于监控和管理应用程序的强大功能模块。它可以帮助我们了解应用程序的运行状况、指标收集、环境信息、日志级别管理等。 2. 添加依赖 2.1 在 pom.xml 中添加以下依赖&#xff1a; …...

联通用户管理系统(一)

#联通用户管理系统&#xff08;一&#xff09; 1.新建项目 如果你是windows的话&#xff0c;界面应该是如下的&#xff1a; 2.创建app python manage.py startapp app01一般情况下&#xff1a;我们是在pycharm的终端中运行上述指令&#xff0c;但是pychrm中为我们提供了工具…...

go chan底层分析

go chan底层分析 底层源码hchanmakechan 方法 环形队列阻塞机制向管道写数据流程图源码 从管道读数据流程图源码 关闭通道 底层源码 hchan type hchan struct {qcount uint // 当前队列中剩余元素个数dataqsiz uint // 环形队列长度&#xff0c;即可以…...

idea上git log面板的使用

文章目录 各种颜色含义具体的文件的颜色标签颜色&#x1f3f7;️ 节点和路线 各种颜色含义 具体的文件的颜色 红色&#xff1a;表示还没有 git add 提交到暂存区绿色&#xff1a;表示已经 git add 过&#xff0c;但是从来没有 commit 过蓝色&#xff1a;表示文件有过改动 标…...

WOA-Transformer鲸鱼算法优化编码器时间序列预测(Matlab实现)

WOA-Transformer鲸鱼算法优化编码器时间序列预测&#xff08;Matlab实现&#xff09; 目录 WOA-Transformer鲸鱼算法优化编码器时间序列预测&#xff08;Matlab实现&#xff09;预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现WOA-Transformer鲸鱼算法优化编…...

dock 制作 python环境

报错 :Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) 解决方法 配置加速地址 vim /etc/docker/daemon.json 添加以下内容 { "registry-mirror…...