Spark Core--加强

news2024/11/16 4:31:01

RDD的持久化

在这里插入图片描述

RDD缓存

当RDD被重复使用,或者计算该RDD比较容易出错,而且需要消耗比较多的资源和时间的时候,我们就可以将该RDD缓存起来。

主要作用: 提升Spark程序的计算效率
注意事项: RDD的缓存可以存储在内存或者是磁盘上,甚至可以存储在Executor进程的堆外内存中。主要是放在内存中,因此缓存的数据是不太稳定可靠。

由于是临时存储,可能会存在丢失,所以缓存操作,并不会将RDD之间的依赖关系给截断掉(丢失掉),因为当缓存
失效后,可以全部重新计算
缓存的API都是Lazy惰性的,如果需要触发缓存操作,推荐调用count算子,因为运行效率高

设置缓存的API: 
	rdd.cache(): 将RDD的数据缓存储内存中
	rdd.persist(缓存的级别/位置): 将RDD的数据存储在指定位置

手动清理缓存API:
	rdd.unpersist()
默认情况下,当整个Spark应用程序执行完成后,缓存数据会自动失效,会被自动删除

缓存的级别/位置:
    DISK_ONLY: 只存储在磁盘
    DISK_ONLY_2: 只存储在磁盘,并且有2个副本
    DISK_ONLY_3: 只存储在磁盘,并且有3个副本
    MEMORY_ONLY: 只存储在内存中
    MEMORY_ONLY_2: 只存储在内存中,并且有2个副本
    MEMORY_AND_DISK: 存储在内存和磁盘中,先放在内存,再放在磁盘
    MEMORY_AND_DISK_2: 存储在内存和磁盘中,先放在内存,再放在磁盘,并且有2个副本
    OFF_HEAP: Executor进程的堆外内存
    
工作中最常用的是: MEMORY_AND_DISK和MEMORY_AND_DISK_2。优先推荐使用MEMORY_AND_DISK

演示缓存的使用操作:

import time

from pyspark import SparkConf, SparkContext, StorageLevel
import os
import jieba

# 绑定指定的Python解释器
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'

# 需要过滤的关键词黑名单
keyword_black_list = ['+','.','的','com']

# ctrl+alt+M将代码封装成函数/方法
# 3.2- 需求一:统计每个关键词出现了多少次。先提取需要操作的字段并且分词,这一步类似WordCount中的对每行进行切分处理,再仿照WordCount实现。
def top10_keyword():
    keyword_rdd = etl_rdd.flatMap(lambda line_tup: list(jieba.cut(line_tup[2])))
    # print(keyword_rdd.take(10))

    # 数据结构转变。将单词变成元组
    # keyword_map_rdd = keyword_rdd.filter(lambda word:word!='+' or word!='.').map(lambda word:(word,1))
    keyword_map_rdd = keyword_rdd.filter(lambda word: word not in keyword_black_list).map(lambda word: (word, 1))

    # 分组聚合操作
    keyword_result_rdd = keyword_map_rdd.reduceByKey(lambda agg, curr: agg + curr)
    # print(keyword_result_rdd.take(100))

    # 对结果中关键词的次数降序排序,取TOP10
    keyword_result = keyword_result_rdd.top(10, key=lambda tup: tup[1])
    print(keyword_result)


# 3.3- 需求二:统计每个用户每个搜索内容点击的次数
def content():
    # 从原始的6个字段中,提取出2个字段,得到 (用户,搜索内容)
    new_tup_tmp_rdd = etl_rdd.map(lambda tup: (tup[1], tup[2]))

    # 数据格式转换
    """
            输入:(张三,鸡你太美) -> hello
            输出:((张三,鸡你太美),1) -> (hello,1)
        """
    new_tup_rdd = new_tup_tmp_rdd.map(lambda tup: (tup, 1))
    # new_tup_rdd = new_tup_tmp_rdd.map(lambda tup:(tup[0],tup[1],1))

    # 分组聚合
    content_result = new_tup_rdd.reduceByKey(lambda agg, curr: agg + curr)
    print(content_result.take(10))


if __name__ == '__main__':

    # 1- 创建SparkContext
    conf = SparkConf().setAppName('sogou_demo').setMaster('local[*]')
    sc = SparkContext(conf=conf)

    # 2- 数据输入
    init_rdd = sc.textFile('file:///export/data/spark_core/data/SogouQ.sample')

    print("ETL处理前数据条数:",init_rdd.count())

    # 3- 数据处理
    # 3.1- ETL:数据的清洗、转换、加载
    """
        split():默认按照空白字符进行切分。例如:空格、制表符、回车换行符等
        
        map和flatMap的主要区别:flatMap对每一个元素处理以后,会将结果打平/压扁到一个更大的容器当中。
    """
    map_rdd = init_rdd.map(lambda line:line.split())
    # print("调用map算子后的内容:",map_rdd.take(10))

    # flatmap_rdd = init_rdd.flatMap(lambda line: line.split())
    # print("调用flatMap算子后的内容:",flatmap_rdd.take(10))

    # 过滤掉每行中没有6个字段的数据
    filter_rdd = map_rdd.filter(lambda line_list: len(line_list)==6)


    # 数据结构转换(为了演示而演示)
    etl_rdd = filter_rdd.map(lambda line_list:(
        line_list[0],
        line_list[1],
        line_list[2][1:-1], # 省略前后的中括号
        line_list[3],
        line_list[4],
        line_list[5]
    ))

    # 设置缓存。并且调用count算子触发操作
    # etl_rdd.cache().count()
    etl_rdd.persist(storageLevel=StorageLevel.MEMORY_AND_DISK).count()

    print("ETL处理后数据条数:", etl_rdd.count())

    # 3.2- 需求一:统计每个关键词出现了多少次
    # top10_keyword()

    # 3.3- 需求二:统计每个用户每个搜索内容点击的次数
    content()
    time.sleep(20)

    # 手动清理缓存。你对哪个RDD设置了缓存,那么你就对那个RDD清理缓存。也需要调用count算子触发。
    etl_rdd.unpersist().count()
    time.sleep(100)
    # 5- 释放资源
    sc.stop()

无缓存的DAG流程图显示:
在这里插入图片描述
有缓存的DAG流程图显示:
在这里插入图片描述
在这里插入图片描述

RDD的checkpoint检查点

RDD缓存主要是将数据存储在内存中,是临时存储,不太稳定,它主要是用来提升程序运行效率的。RDD的checkpoint(检查点)主要是将数据存储在HDFS上,是持久化存储。而HDFS存储数据有3副本的机制,让数据更加安全可靠。

checkpoint认为使用磁盘或者HDFS存储数据之后,数据非常的安全可靠,因此checkpoint会将RDD间的依赖关系给删除/丢弃掉。因此如果checkpoint的数据真的出现了问题,是无法在从头开始计算。

checkpoint主要作用: 提高程序的容错性
注意事项: checkpoint可以将数据存储在磁盘或者HDFS上,主要是将数据存储在HDFS上。

相关API:
sc.setCheckpointDir(存储路径): 设置checkpoint数据存放路径
rdd.checkpoint(): 对指定RDD启用checkpoint
rdd.count(): 触发checkpoint

代码演示:

import time

from pyspark import SparkConf, SparkContext, StorageLevel
import os
import jieba

# 绑定指定的Python解释器
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'

# 需要过滤的关键词黑名单
keyword_black_list = ['+','.','的','com']

# ctrl+alt+M将代码封装成函数/方法
# 3.2- 需求一:统计每个关键词出现了多少次。先提取需要操作的字段并且分词,这一步类似WordCount中的对每行进行切分处理,再仿照WordCount实现。
def top10_keyword():
    keyword_rdd = etl_rdd.flatMap(lambda line_tup: list(jieba.cut(line_tup[2])))
    # print(keyword_rdd.take(10))

    # 数据结构转变。将单词变成元组
    # keyword_map_rdd = keyword_rdd.filter(lambda word:word!='+' or word!='.').map(lambda word:(word,1))
    keyword_map_rdd = keyword_rdd.filter(lambda word: word not in keyword_black_list).map(lambda word: (word, 1))

    # 分组聚合操作
    keyword_result_rdd = keyword_map_rdd.reduceByKey(lambda agg, curr: agg + curr)
    # print(keyword_result_rdd.take(100))

    # 对结果中关键词的次数降序排序,取TOP10
    keyword_result = keyword_result_rdd.top(10, key=lambda tup: tup[1])
    print(keyword_result)


# 3.3- 需求二:统计每个用户每个搜索内容点击的次数
def content():
    # 从原始的6个字段中,提取出2个字段,得到 (用户,搜索内容)
    new_tup_tmp_rdd = etl_rdd.map(lambda tup: (tup[1], tup[2]))

    # 数据格式转换
    """
            输入:(张三,鸡你太美) -> hello
            输出:((张三,鸡你太美),1) -> (hello,1)
        """
    new_tup_rdd = new_tup_tmp_rdd.map(lambda tup: (tup, 1))
    # new_tup_rdd = new_tup_tmp_rdd.map(lambda tup:(tup[0],tup[1],1))

    # 分组聚合
    content_result = new_tup_rdd.reduceByKey(lambda agg, curr: agg + curr)
    print(content_result.take(10))


if __name__ == '__main__':

    # 1- 创建SparkContext
    conf = SparkConf().setAppName('sogou_demo').setMaster('local[*]')
    sc = SparkContext(conf=conf)

    # 设置checkpoint路径
    sc.setCheckpointDir("hdfs://node1:8020/chk")

    # 2- 数据输入
    init_rdd = sc.textFile('file:///export/data/spark_core/data/SogouQ.sample')

    print("ETL处理前数据条数:",init_rdd.count())

    # 3- 数据处理
    # 3.1- ETL:数据的清洗、转换、加载
    """
        split():默认按照空白字符进行切分。例如:空格、制表符、回车换行符等
        
        map和flatMap的主要区别:flatMap对每一个元素处理以后,会将结果打平/压扁到一个更大的容器当中。
    """
    map_rdd = init_rdd.map(lambda line:line.split())
    # print("调用map算子后的内容:",map_rdd.take(10))

    # flatmap_rdd = init_rdd.flatMap(lambda line: line.split())
    # print("调用flatMap算子后的内容:",flatmap_rdd.take(10))

    # 过滤掉每行中没有6个字段的数据
    filter_rdd = map_rdd.filter(lambda line_list: len(line_list)==6)


    # 数据结构转换(为了演示而演示)
    etl_rdd = filter_rdd.map(lambda line_list:(
        line_list[0],
        line_list[1],
        line_list[2][1:-1], # 省略前后的中括号
        line_list[3],
        line_list[4],
        line_list[5]
    ))

    # 对指定RDD启用checkpoint
    etl_rdd.checkpoint()
    # 调用count算子,触发checkpoint操作
    etl_rdd.count()
    print("ETL处理后数据条数:", etl_rdd.count())

    # 3.2- 需求一:统计每个关键词出现了多少次
    # top10_keyword()

    # 3.3- 需求二:统计每个用户每个搜索内容点击的次数
    content()
    time.sleep(1000)
    # 5- 释放资源
    sc.stop()

没有设置检查点正常的DAG执行流图:
在这里插入图片描述
设置检查点后:

在这里插入图片描述

缓存和checkpoint的区别

1- 数据存储位置不同
缓存: 存储在内存或者磁盘 或者 堆外内存中
checkpoint检查点: 可以将数据存储在磁盘或者HDFS上, 在集群模式下, 仅能保存到HDFS上

2- 数据生命周期:
缓存: 当程序执行完成后, 或者手动调用unpersist 缓存都会被删除
checkpoint检查点: 即使程序退出后, checkpoint检查点的数据依然是存在的, 不会删除, 需要手动删除

3- 血缘关系:
缓存: 不会截断RDD之间的血缘关系, 因为缓存数据有可能是失效, 当失效后, 需要重新回溯计算操作
checkpoint检查点: 会截断掉依赖关系, 因为checkpoint将数据保存到更加安全可靠的位置, 不会发生数据丢失的问题, 当执行失败的时候, 也不需要重新回溯执行

4- 主要作用不同
缓存: 提高Spark程序的运行效率
checkpoint检查点: 提高Spark程序的容错性

思考:既然持久化的方案有两种,那么在生产环境中应该使用哪种方案呢?

在同一个项目中,推荐缓存和checkpoint(检查点)同时配合使用。

使用顺序如下: 在代码中先设置缓存,再设置checkpoint检查点,然后再一同使用Action算子触发,推荐使用count算子。因为这个顺序,只会有一次IO写的过程。

实际过程如下: 程序会优先从缓存中读取数据,如果发现缓存中没有数据。再从checkpoint中读取数据,并且接着将读取到的数据重新在内存中放置一份,后续还是优先从缓存中读取

在这里插入图片描述
测试:

import time

from pyspark import SparkConf, SparkContext, StorageLevel
import os
import jieba

# 绑定指定的Python解释器
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'

# 需要过滤的关键词黑名单
keyword_black_list = ['+','.','的','com']

# ctrl+alt+M将代码封装成函数/方法
# 3.2- 需求一:统计每个关键词出现了多少次。先提取需要操作的字段并且分词,这一步类似WordCount中的对每行进行切分处理,再仿照WordCount实现。
def top10_keyword():
    keyword_rdd = etl_rdd.flatMap(lambda line_tup: list(jieba.cut(line_tup[2])))
    # print(keyword_rdd.take(10))

    # 数据结构转变。将单词变成元组
    # keyword_map_rdd = keyword_rdd.filter(lambda word:word!='+' or word!='.').map(lambda word:(word,1))
    keyword_map_rdd = keyword_rdd.filter(lambda word: word not in keyword_black_list).map(lambda word: (word, 1))

    # 分组聚合操作
    keyword_result_rdd = keyword_map_rdd.reduceByKey(lambda agg, curr: agg + curr)
    # print(keyword_result_rdd.take(100))

    # 对结果中关键词的次数降序排序,取TOP10
    keyword_result = keyword_result_rdd.top(10, key=lambda tup: tup[1])
    print(keyword_result)


# 3.3- 需求二:统计每个用户每个搜索内容点击的次数
def content():
    # 从原始的6个字段中,提取出2个字段,得到 (用户,搜索内容)
    new_tup_tmp_rdd = etl_rdd.map(lambda tup: (tup[1], tup[2]))

    # 数据格式转换
    """
            输入:(张三,鸡你太美) -> hello
            输出:((张三,鸡你太美),1) -> (hello,1)
        """
    new_tup_rdd = new_tup_tmp_rdd.map(lambda tup: (tup, 1))
    # new_tup_rdd = new_tup_tmp_rdd.map(lambda tup:(tup[0],tup[1],1))

    # 分组聚合
    content_result = new_tup_rdd.reduceByKey(lambda agg, curr: agg + curr)
    print(content_result.take(10))


if __name__ == '__main__':

    # 1- 创建SparkContext
    conf = SparkConf().setAppName('sogou_demo').setMaster('local[*]')
    sc = SparkContext(conf=conf)

    # 设置checkpoint路径
    sc.setCheckpointDir("hdfs://node1:8020/chk")

    # 2- 数据输入
    init_rdd = sc.textFile('file:///export/data/spark_core/data/SogouQ.sample')

    print("ETL处理前数据条数:",init_rdd.count())

    # 3- 数据处理
    # 3.1- ETL:数据的清洗、转换、加载
    """
        split():默认按照空白字符进行切分。例如:空格、制表符、回车换行符等
        
        map和flatMap的主要区别:flatMap对每一个元素处理以后,会将结果打平/压扁到一个更大的容器当中。
    """
    map_rdd = init_rdd.map(lambda line:line.split())
    # print("调用map算子后的内容:",map_rdd.take(10))

    # flatmap_rdd = init_rdd.flatMap(lambda line: line.split())
    # print("调用flatMap算子后的内容:",flatmap_rdd.take(10))

    # 过滤掉每行中没有6个字段的数据
    filter_rdd = map_rdd.filter(lambda line_list: len(line_list)==6)

    # 数据结构转换(为了演示而演示)
    etl_rdd = filter_rdd.map(lambda line_list:(
        line_list[0],
        line_list[1],
        line_list[2][1:-1], # 省略前后的中括号
        line_list[3],
        line_list[4],
        line_list[5]
    ))

    # 先缓存
etl_rdd.persist(storageLevel=StorageLevel.MEMORY_AND_DISK)
    # 再checkpoint
    etl_rdd.checkpoint()
    # 最后调用count算子,一同触发
    etl_rdd.count()
    
    print("ETL处理后数据条数:", etl_rdd.count())

    # 3.2- 需求一:统计每个关键词出现了多少次
    # top10_keyword()
    # 3.3- 需求二:统计每个用户每个搜索内容点击的次数
    content()
    time.sleep(1000)
    # 5- 释放资源
    sc.stop()

DAG有向无环图:
在这里插入图片描述

Spark内核调度

RDD的依赖

RDD依赖:一个RDD的形成可能是由一个或者多个RDD得到的,此时这个RDD和之前的RDD之间产生依赖关系。

在Spark中,RDD之间的依赖关系,主要有二种类型:

  • 窄依赖
作用: 能够让Spark程序并行计算。也就是一个分区数据计算出现问题以后,其他的分区计算不受到任何影响

特点: 父RDD的分区和子RDD的分区关系是一对一的关系。
也就是父RDD分区的数据会整个被下游子RDD的分区接收

在这里插入图片描述

  • 宽依赖
作用: 划分Stage的重要依据。宽依赖也叫做Shuffle依赖
特点: 父RDD的分区和子RDD的分区关系是一对多的关系。也就是父RDD的分区数据会被分成多份给到下游子RDD的多个分区所接收。

注意: 如果有宽依赖,shuffle下游的其他操作,必须等待shuffle执行完成以后才能够继续执行。为了避免数据不完整

在这里插入图片描述

在实际使用中,不需要纠结哪些算子会存在shuffle,以需求为目标**。虽然shuffle的存在会影响一定的效率, 但是以完成任务为准则,**该用那个算子,就使用那个算子即可,不要过分纠结。	

算子中一般以ByKey结尾的会发生shuffle;另外是重分区算子会发生shuffle

DAG和Stage

DAG:有向无环图,主要描述一段执行任务,从开始一直往下走,不允许出现回调操作

Spark应用程序中,遇到一个Action算子,就会触发形成一个Job任务的产生。

对于每一个Job的任务,都会产生一个DAG执行流程图,那么这个流程图是如何形成的呢?

层级关系:
1- 一个Spark应用程序 -> 遇到一个Action算子,就会触发形成一个Job任务
2- 一个Job任务只有一个DAG有向无环图
3- 一个DAG有向无环图 -> 有多个Stage
4- 一个Stage -> 有多个Task线程
5- 一个RDD -> 有多个分区
6- 一个分区会被一个Task线程所处理

DAG执行流程图形成和Stage划分:
在这里插入图片描述

1- Spark应用程序遇到Action算子后,就会触发一个Job任务的产生。Job任务会将它所依赖的所有算子全部加载进来,形成一个Stage

2- 接着从Action算子从后往前进行回溯,遇到窄依赖就将算子放在同一个Stage当中;如果遇到宽依赖,就划分形成新的Stage。最后一直回溯完成

细化剖析Stage内部的流程:
在这里插入图片描述
默认并行度的值确认:

因为是使用textFile读取HDFS上的文件,因此RDD分区数=max(文件的block块的数量, defaultMinPartition)。继续需要知道defaultMinPartition的值是多少。

defaultMinPartition=min(spark.default.parallelism,2)取最小值。最终我们确认spark.default.parallelism的参数值就能够最终确认RDD的分区数有多少个

spark.default.parallelism参数值确认过程如下:
1- 如果有父RDD,就取父RDD的最大分区数
2- 如果没有父RDD,根据集群模式进行取值:
   2.1- 本地模式:机器的最大CPU核数
   2.2- (了解)Mesos:默认是8
   2.3- 其他模式:所有执行节点上的核总数或2,以较大者为准

Spark Shuffle

Spark中shuffle的发展历程:

1- 在1.1版本以前,Spark采用Hash shuffle (优化前 和 优化后)

2- 在1.1版本的时候,Spark推出了Sort Shuffle

3- 在1.5版本的时候,Spark引入钨丝计划(优化为主)

4- 在1.6版本的时候,将钨丝计划合并到sortShuffle中

5- 在2.0版本的时候,将Hash Shuffle移除,将Hash shuffle方案移植到Sort Shuffle

在这里插入图片描述

  • 在优化前的Hash shuffle:
    在这里插入图片描述
存在的问题:
	上游(map端)的每个Task会产生与下游Task个数相等的小文件个数。这种情况会导致上游有非常多的小文件。另外,下游(reduce端)来拉取文件的时候,会有大量的网络IO和磁盘IO过程,因为要打开和读取多个小文件。
  • 经过优化后的Hash shuffle
    在这里插入图片描述
变成了由每个Executor进程产生与下游Task个数相等的小文件数。这样可以大量减小小文件的产生,以及降低下游拉取文件时候的网络IO和磁盘IO过程
  • Sort shuffle:
    在这里插入图片描述
Sort Shuffle分成了两种: 普通机制和bypass机制。具体使用哪种,由Spark底层决定。

普通机制的运行过程: 每个上游Task线程处理数据,数据处理完以后,先放在内存中。接着对内存中的数据进行分区、排序。将内存中的数据溢写到磁盘,形成一个个的小文件。溢写完成以后,会将多个小文件合并成一个大的磁盘文件。并且针对每个大的磁盘文件,会提供一个索引文件。接着是下游Task根据索引文件来读取相应的数据。

bypass机制: 就是在普通机制的基础上,省略了排序的过程

bypass机制的触发条件是:
1- 上游RDD的分区数量最多不能超过200个
2- 上游不能对数据进行提前聚合操作(因为提前聚合,需要先进行分组操作,而分组的操作实际上是有排序的操作)

Job调度流程

主要是讨论:在Driver内部,是如何调度任务
在这里插入图片描述
1- Driver进程启动后,底层PY4J创建SparkContext顶级对象。在创建该对象的过程中,还会创建另外两个对象,分别是: DAGScheduler和TaskScheduler
DAGScheduler: DAG调度器。将Job任务形成DAG有向无环图和划分Stage的阶段
TaskScheduler: Task调度器。将Task线程分配给到具体的Executor执行

2- 一个Spark程序遇到一个Action算子就会触发产生一个Job任务。SparkContext将Job任务给到DAG调度器,拿到Job任务后,会将Job任务形成DAG有向无环图和划分Stage的阶段。并且会确定每个Stage阶段有多少个Task线程,会将众多的Task线程放到TaskSet的集合中。DAG调度器将TaskSet集合给到Task调度器

3- Task调度器拿到TaskSet集合以后,将Task分配给到给到具体的Executor执行。底层是基于SchedulerBackend调度队列来实现的。

4- Executor开始执行任务。并且Driver会监控各个Executor的执行状态,直到所有的Executor执行完成,就认为任务运行结束

5- 后续过程和之前一样

Spark RDD 并行度

整个Spark应用中,影响并行度的因素有以下两个原因:

  • 1- 资源的并行度: Executor数量 和 CPU核心数 以及 内存的大小
  • 2- 数据的并行度: Task的线程数 和 分区数量
一般将Task线程数设置为CPU核数的2-3倍。另外每个线程分配3-5GB的内存资源。

如何设置并行度:
在这里插入图片描述

说明: spark.default.parallelism该参数是SparkCore中的参数。该参数只会影响shuffle以后的分区数量。
另外该参数对parallelize并行化本地集合创建的RDD不起作用。

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

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

相关文章

为布偶猫精心挑选的三款主食冻干,K9、sc、希喂深度解析对比

喂养布偶猫的小技巧:如何满足其食肉天性同时呵护其肠胃?主食冻干是答案!它不仅符合猫咪天然的饮食结构,还采用新鲜生肉为原料。搭配其他营养元素,既美味又营养,还能增强抵抗力。我们将为您测评市场上热门的…

ubuntu 20.04下 Tesla P100加速卡使用

1.系统环境:系统ubuntu 20.04, python 3.8 2.查看cuDNN/CUDA与tensorflow的版本关系如下: Build from source | TensorFlow 从上图可以看出,python3.8 对应的tensorflow/cuDNN/CUDA版本。 3.安装tensorflow #pip3 install tensorflow 新版…

C++其他语法总结

目录 《C基础语法总结》《C面向对象语法总结(一)》《C面向对象语法总结(二)》《C面向对象语法总结(三)》 一、运算符重载 运算符重载可以为运算符增加一些新的功能全局函数、成员函数都支持运算符重载常用的运算符重载示例 class Point {…

Python私有变量的定义与访问

class Student():def __init__(self, name, age):self.name nameself.age ageself.__score 0def marking(self, score):if score < 0:return 分数不能为0self.__score scoreprint(self.name 同学本次得分是: str(self.__score)) def __talk(self): # 私有的类可通过在…

qss设置某一个widget下的Checkbox的样式

#ObjectName 控件名称{属性&#xff1a;值&#xff1b;属性1&#xff1a;值1} 如下&#xff1a; 效果&#xff1a;

【大数据】分布式协调系统 Zookeeper

分布式协调系统 Zookeeper 1.Zookeeper 的特点2.Zookeeper 的数据结构3.Zookeeper 的应用场景3.1 统一命名服务3.2 统一配置管理3.3 统一集群管理3.4 服务器动态上下线3.5 软负载均衡 Zookeeper 是 Apache 开源的一个顶级项目&#xff0c;目的是为分布式应用提供协调服务&#…

910b上跑Chatglm3-6b进行流式输出【pytorch框架】

文章目录 准备阶段避坑阶段添加代码结果展示 准备阶段 配套软件包Ascend-cann-toolkit和Ascend-cann-nnae适配昇腾的Pytorch适配昇腾的Torchvision Adapter下载ChatGLM3代码下载chatglm3-6b模型&#xff0c;或在modelscope里下载 避坑阶段 每个人的服务器都不一样&#xff0…

01-连接池项目背景:C++的数据库操作

从0开始学习C与数据库的联动 1.原始方式-使用MySQL Connector/C 提供的API查询 1.1 数据库预操作 我的本地电脑上有mysql数据库&#xff0c;里面预先创建了一个database名叫chat&#xff0c;用户名root&#xff0c;密码password。 1.2 Visual Studio预操作 在Windows上使用…

分析一个项目(微信小程序篇)一

分析一个项目讲究的是如何进行对项目的解析分解&#xff0c;进一步了解项目的整体结构&#xff0c;熟悉项目的结构&#xff0c;能够知道每个组件所处在哪个位置&#xff0c;发挥什么作用。 本次所介绍的是微信小程序项目&#xff08;甑选商场&#xff09;&#xff1a; 其首页…

深度解析HubSpot数据分析:洞察未来商业趋势

在当今数字化的商业环境中&#xff0c;数据是推动决策和业务增长的关键。作为业内领先的CRM平台&#xff0c;HubSpot不仅为企业提供了高效的客户关系管理工具&#xff0c;同时也成为了数据分析的利器。 1. HubSpot数据分析的核心价值 1.1 洞察客户行为和趋势 HubSpot数据分析…

【SkyWant.[2304]】路由器操作系统,移动【Netkeeper】使用教程校园网

目录 步骤一&#xff1a;正确连接网线&#xff0c;插电开机正确连接网线&#xff1a; 认识系统灯&#xff1a; 插电开机&#xff1a; 步骤二&#xff1a;开机之后&#xff0c;系统的基本设置 1.进入设置界面&#xff1a; 2.设置辅助热点wifi&#xff1a; 3.设置日常…

domain adapation

假设测试资料和训练资料分布不一样&#xff0c; 训练为黑白数字&#xff0c;测试为彩色数字时&#xff0c;识别率很低 称之为 Domain shift Domain adaptation : 可以看做 transfer 的一种 输出分布也有可能不一样 target domain 有部分数据&#xff0c;但是无标签 分布也不…

css中的变量和辅助函数

变量 --name 两个破折号加变量名称&#xff08;可以在当前的选择器内定义&#xff09;var(--*) 命名规则 body {--深蓝: #369;background-color: var(--深蓝); } 变量值只能做用属性值&#xff0c;不能用做属性名。变量命名不能包含 $,[,^,(,% 等字符 普通字符局限在只要是数…

如何快速编写高效的测试用例? -5个建议让你的测试更准确、更全面

逛知乎的时候&#xff0c;经常看到无论是刚入职场的新人&#xff0c;还是工作了一段时间的老人&#xff0c;都会对编写测试用例感到困扰&#xff1f;例如&#xff1a; 固然&#xff0c;编写一份好的测试用例需要&#xff1a;充分的需求分析能力理论及经验加持。 但这并不意味着…

【每日论文阅读】Do Perceptually Aligned Gradients Imply Robustness?

近似人眼梯度 https://icml.cc/virtual/2023/oral/25482 对抗性鲁棒分类器具有非鲁棒模型所没有的特征——感知对齐梯度&#xff08;PAG&#xff09;。它们相对于输入的梯度与人类的感知非常一致。一些研究已将 PAG 确定为稳健训练的副产品&#xff0c;但没有一篇研究将其视为…

windows同时安装mysql5.0和8.0步骤(完美测试)

mysql5.0和mysql8.0配置如下 1.把如下配置复制下替换到my.ini中 mysql5.0配置如下 [mysqld] # 设置3306端口 port3306 # 设置mysql的安装目录 basedirF:\mysql-5.7.38 # 设置mysql数据库的数据的存放目录 datadirF:\mysql-5.7.38\data # 允许最大连接数 max_connections200 #…

串口乱码原因

开发板上外部时钟的晶振与代码中的外部时钟的晶振不一致&#xff0c;使用cubemx配置时钟时要格外注意&#xff0c;选好芯片之后再看外部晶振是啥&#xff0c;不然随便设置可能乱码 重写fputc函数之后&#xff0c;需要自己手动勾选下面选项

【Linux系统编程二十七】:线程的互斥与同步(互斥锁的使用与应用)

【Linux系统编程二十七】&#xff1a;线程的互斥与同步(互斥锁的使用与应用&#xff09; 一.问题:数据不一致(混乱/不安全)1.多线程并发计算不安全2.将数据加载到寄存器的本质 二.解决方法--互斥锁三.互斥锁的概念与接口1.定义锁2.加锁/解锁 四.互斥锁实现原理与应用1.原理&…

AArch64 Exception Model学习

提示 该博客主要为个人学习&#xff0c;通过阅读官网手册整理而来&#xff08;个人觉得阅读官网的英文文档非常有助于理解各个IP特性&#xff09;。若有不对之处请参考参考文档&#xff0c;以官网文档为准。 1 Privilege and Exception Levels 1.1 为什么要划分权限&#xf…

swaggerUI不好用,试试这个openapiUI?

title: swaggerUI不好用&#xff0c;试试这个openapiUI? date: 2024-01-08 categories: [tool] tags: [openapi,工具] description: 基于swaggger2, openapi3规范的UI文档 1.背景 由于长期使用 swaggerUI 工具&#xff0c;它的轻量风格个人觉得还是不错的&#xff0c;但是它…