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()
}
}
代码流程简述:
- 创建SparkSession:初始化Spark的核心环境,允许你使用SparkSQL等高级API。
- 读取数据:从HDFS或本地文件系统读取两个文本文件,创建RDD。
- 数据转换:对读取的RDD进行转换,进行数据的合并、分割、排序和去重操作。
- 转换为DataFrame:将RDD转换为DataFrame以便使用SQL等功能。
- 数据库配置:设置MySQL数据库连接的URL、用户名和密码。
- 将数据写入数据库:将处理后的DataFrame写入到指定的MySQL表中。
- 关闭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教程之基本命令
作者:nchu可乐百香果 指导者:nchu-YoungDragon 1.前期准备 (1)从迅雷网盘上面下载这个项目,并且把scala,maven和java环境配置好 网盘链接: 分享文件:SparkRDD.zip 链接…...

Linux:SystemV通信
目录 一、System V通信 二、共享内存 代码板块 总结 三、信号量 信号量理论 信号量接口 一、System V通信 System V IPC(inter-process communication),是一种进程间通信方式。其实现的方法有共享内存、消息队列、信号量这三种机制。 …...
C#上位机通过CAN总线发送bin文件
让gpt生成一段代码用来把bin文件通过can总线发出去 c#代码还是比较强大的,各种功能基本都是一两行代码就实现了,这里记录一下对这个代码的理解和解读 主要代码如下,传入bin文件的地址即可将其从指定的can通道发送出去: public …...

CV 图像处理基础笔记大全(超全版哦~)!!!
一、图像的数字化表示 像素 数字图像由众多像素组成,是图像的基本构成单位。在灰度图像中,一个像素用一个数值表示其亮度,通常 8 位存储,取值范围 0 - 255,0 为纯黑,255 为纯白。例如,一幅简单的…...
2-Kbengine+Unity3D多人在线游戏DEMO源码架构分析
2-Kbengine+Unity3D多人在线游戏DEMO源码架构分析 目录 一、服务器端 1、编写并生成我们的服务器端和客户端通用的游戏协议 2、 认识Entity实体 3、 官方DEMO-kbengine_demos_assets分析 二、 客户端...
Vue.js组件开发-如何实现表头搜索
在Vue.js组件开发中,实现表头搜索通常涉及在表格组件的表头添加输入框,并让用户能够输入搜索关键字来过滤表格数据。 以下是一个使用Element UI的el-table组件实现表头搜索的示例: 一、准备阶段 确保Element UI已安装: 确保…...

lerna使用指南
lerna版本 以下所有配置命令都是基于v8.1.9,lerna v5 v7版本差别较大,在使用时,注意自身的lerna版本。 lerna开启缓存及缓存配置 nx缓存是v5版本以后才有的,小于该版本的无法使用该功能。 初始化配置 缓存配置文件nx.json&am…...
spark,读取和写入同一张表问题
读取a表,写入a表 1.写入的是分区表,不报错 2.读取上来之后,创建为临时视图temp,然后先写入a表,再使用temp,就会报错 解决办法:可以先使用temp,再写入a表 3.写入的不是分区表&…...
iOS - TLS(线程本地存储)
从源码中,详细总结 TLS (Thread Local Storage) 的实现: 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 项目依赖关系 的工具。它可以帮助开发者快速了解项目的依赖结构、模块关系,以及可能存在的问题,从而优化代码架构和依赖管理。 功能特点 依赖关系分析࿱…...
QT 如何禁止QComboBox鼠标滚轮
一般情况下,QComboBox会相应鼠标的滚轮事件,即当鼠标停靠在QComboBox上方时,滚动鼠标滚轮,QComboBox的选项会发生切换。但这或许并不是我们希望所出现的,尤其是当QComboBox嵌入在QScrollArea中时,用户只是想…...
理解CPU负载与使用率
目录 CPU使用率 CPU负载 CPU使用率 定义:就像看一个工人干活的时间占他上班时间的比例。比如工人上班8小时,实际干活6小时,干活时间占比就是68100%75%。对于CPU,单核的看它被占用的时间占总时间的比例,多核的就把每个…...
浅谈计算机网络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实时数据 踩坑的问题细节 三、海…...
通过将模型权重的矩阵表示为低秩矩阵,可以减少需要调整的参数数量,通俗易懂的解释,不懂你爬网线打我
通过将模型权重矩阵表示为低秩矩阵,可以减少需要调整的参数数量,原因在于低秩矩阵的结构本身就比高秩矩阵更“紧凑”,即它们需要的独立参数更少。具体来说,低秩矩阵的结构可以通过减少模型的自由度(独立参数的数量&…...

Java并发编程——线程池(基础,使用,拒绝策略,命名,提交方式,状态)
我是一个计算机专业研0的学生卡蒙Camel🐫🐫🐫(刚保研) 记录每天学习过程(主要学习Java、python、人工智能),总结知识点(内容来自:自我总结网上借鉴࿰…...

DilateFormer: Multi-Scale Dilated Transformer for Visual Recognition 中的空洞自注意力机制
空洞自注意力机制 文章目录 摘要1. 模型解释1.1. 滑动窗口扩张注意力1.2. 多尺度扩张注意力 2. 代码3. 流程图3.1. MultiDilatelocalAttention3.2. DilateAttention3.3. MLP 摘要 本文针对DilateFormer中的空洞自注意力机制原理和代码进行详细介绍,最后通过流程图梳…...
二十三种设计模式-适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将不兼容的接口转换成客户端期望的接口,从而使原本因接口不匹配而不能一起工作的类可以协同工作。以下是关于适配器模式的详细介绍: 一、定义及作用 定义&am…...
复用类(2):代理、结合使用组合和继承
1 代理 第三种关系称为代理,这是继承与组合之间的中庸之道,因为我们将一个成员对象置于所要构造的类中(就像组合),但与此同时我们在新类中暴露了该成员对象的所有方法(就像继承)。例如ÿ…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...