spark的学习-06

news2024/11/23 5:11:52

SparkSQL读写数据的方式

1)输入Source

方式一:给定读取数据源的类型和地址

spark.read.format("json").load(path)
spark.read.format("csv").load(path)
spark.read.format("parquet").load(path)

方式二:直接调用对应数据源类型的方法

spark.read.json(path)
spark.read.csv(path)
spark.read.parquet(path)

特殊参数:option,用于指定读取时的一些配置选项

spark.read.format("csv").option("sep", "\t").load(path)

jdbcDF = spark.read \
    .format("jdbc") \
    .option("url", "jdbc:postgresql:dbserver") \
    .option("dbtable", "schema.tablename") \
    .option("user", "username") \
    .option("password", "password") \
    .load()

1、普通的文件读取方式:

import os

from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession

if __name__ == '__main__':
    os.environ['JAVA_HOME'] = 'C:/Program Files/Java/jdk1.8.0_131'
    # 配置Hadoop的路径,就是前面解压的那个路径
    os.environ['HADOOP_HOME'] = r'D:\BigDate\05-Hadoop\software\hadoop-3.3.1'
    # 配置base环境Python解析器的路径
    os.environ['PYSPARK_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'  # 配置base环境Python解析器的路径
    os.environ['PYSPARK_DRIVER_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'

    # 创建spark对象
    spark = SparkSession.builder.master("local[2]").appName("第一次构建SparkSession").config(
        "spark.sql.shuffle.partitions", 2).getOrCreate()

    deptDf = spark.read.csv("../../datas/zuoye/dept.csv").toDF("deptno","dept_name","dept_address")

    empDf = spark.read.format("csv").option("sep","\t").load("../../datas/zuoye/emp.tsv").toDF("empno","ename","salary","comm","deptno")

    deptDf.createOrReplaceTempView("dept")
    empDf.createOrReplaceTempView("emp")

    # spark.sql("""
    #     select * from dept
    # """).show()
    #
    # spark.sql("""
    #         select * from emp
    #     """).show()
    # 需求:查询统计每个部门薪资最高的前两名员工的信息以及员工所在的部门名称。
    spark.sql("""
        with t as (
             select e.*,d.dept_name,dense_rank() over(partition by e.deptno order by cast(salary as int) desc) paixu from emp e join dept d on d.deptno = e.deptno
        ) select * from t where paixu <= 2
    """).show()

    spark.stop()

2、通过jdbc读取数据库数据

注意:使用jdbd读取之前,需要先将mysql5或者8 的驱动放在

import os

from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession

if __name__ == '__main__':
    os.environ['JAVA_HOME'] = 'C:/Program Files/Java/jdk1.8.0_131'
    # 配置Hadoop的路径,就是前面解压的那个路径
    os.environ['HADOOP_HOME'] = r'D:\BigDate\05-Hadoop\software\hadoop-3.3.1'
    # 配置base环境Python解析器的路径
    os.environ['PYSPARK_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'  # 配置base环境Python解析器的路径
    os.environ['PYSPARK_DRIVER_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'
        # 得到sparkSession对象
        spark = SparkSession.builder.master("local[2]").appName("").config("spark.sql.shuffle.partitions", 2).getOrCreate()
        # 处理逻辑
        # 读取json 数据
        df1 = spark.read.format("json").load("../../datas/sql/person.json")
        df1.show()
        # 另一种写法,推荐使用这一种
        df2 = spark.read.json("../../datas/sql/person.json")
        df2.show()
        df3 = spark.read.csv("../../datas/dept.csv")
        df4 = spark.read.format("csv").load("../../datas/dept.csv")

        # 读取分隔符为别的分隔符的文件
        user_schema = StructType([
                StructField(name="emp_id", dataType=StringType(), nullable=False),
                StructField(name="emp_name", dataType=StringType(), nullable=True),
                StructField(name="salary", dataType=DoubleType(), nullable=True),
                StructField(name="comm", dataType=DoubleType(), nullable=True),
                StructField(name="dept_id", dataType=LongType(), nullable=True)
        ])
        # 使用csv 读取了一个 \t 为分隔符的文件,读取的数据字段名很随意,所以可以自定义
        df5 = spark.read.format("csv").option("sep","\t").load("../../datas/emp.tsv",schema=user_schema)
        df5.show()

        # 昨天的作业是否也可以有另一个写法
        movie_schema = StructType([
                StructField(name="movie_id", dataType=LongType(), nullable=False),
                StructField(name="movie_name", dataType=StringType(), nullable=True),
                StructField(name="movie_type", dataType=StringType(), nullable=True)
        ])
        movieDF = spark.read.format("csv").option("sep","::").load("../../datas/zuoye/movies.dat",schema=movie_schema)
        movieDF.show()

        spark.read.load(
                path="../../datas/zuoye/movies.dat",
                format="csv",
                sep="::",
                schema=movie_schema
        ).show()
        dict = {"user":"root","password":"root"}
        jdbcDf = spark.read.jdbc(url="jdbc:mysql://localhost:3306/spark",table="emp",properties=dict)
        jdbcDf.show()
        # jdbc的另一种写法
        jdbcDf2 = spark.read.format("jdbc") \
                .option("driver", "com.mysql.cj.jdbc.Driver") \
                .option("url", "jdbc:mysql://localhost:3306/spark") \
                .option("dbtable", "spark.dept") \
                .option("user", "root") \
                .option("password", "root").load()
        jdbcDf2.show()

        # 读取hive表中的数据

        # 关闭
        spark.stop()

3、读取集群中hive表中的数据

import os

from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession

if __name__ == '__main__':
    os.environ['JAVA_HOME'] = 'C:/Program Files/Java/jdk1.8.0_131'
    # 配置Hadoop的路径,就是前面解压的那个路径
    os.environ['HADOOP_HOME'] = r'D:\BigDate\05-Hadoop\software\hadoop-3.3.1'
    # 配置base环境Python解析器的路径
    os.environ['PYSPARK_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'  # 配置base环境Python解析器的路径
    os.environ['PYSPARK_DRIVER_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'

    # 创建spark对象
    spark = SparkSession \
        .builder \
        .appName("测试spark链接") \
        .master("local[2]") \
        .config("spark.sql.warehouse.dir", 'hdfs://bigdata01:9820/user/hive/warehouse') \
        .config('hive.metastore.uris', 'thrift://bigdata01:9083') \
        .config("spark.sql.shuffle.partitions", 2) \
        .enableHiveSupport() \
        .getOrCreate()

    spark.sql("select * from homework.game").show()

    spark.stop()

2)输出Sink

方式一:给定输出数据源的类型和地址

df.write.format("json").save(path)
df.write.format("csv").save(path)
df.write.format("parquet").save(path)

方式二:直接调用对应数据源类型的方法

df.write.json(path)
df.write.csv(path)
df.write.parquet(path)

特殊参数:option,用于指定输出时的一些配置选项

df.write \
.format("jdbc") \
.option("url", "jdbc:postgresql:dbserver") \
.option("dbtable", "schema.tablename") \
.option("user", "username") \
.option("password", "password") \
.save()

append: 追加模式,当数据存在时,继续追加

overwrite: 覆写模式,当数据存在时,覆写以前数据,存储当前最新数据;

error/errorifexists: 如果目标存在就报错,默认的模式

ignore: 忽略,数据存在时不做任何操作

df.write.mode(saveMode="append").format("csv").save(path)

保存为普通格式:

import os

from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession

if __name__ == '__main__':
    os.environ['JAVA_HOME'] = 'C:/Program Files/Java/jdk1.8.0_131'
    # 配置Hadoop的路径,就是前面解压的那个路径
    os.environ['HADOOP_HOME'] = r'D:\BigDate\05-Hadoop\software\hadoop-3.3.1'
    # 配置base环境Python解析器的路径
    os.environ['PYSPARK_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'  # 配置base环境Python解析器的路径
    os.environ['PYSPARK_DRIVER_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'

    # 创建spark对象
    spark = SparkSession.builder.master("local[2]").appName("第一次构建SparkSession").config(
        "spark.sql.shuffle.partitions", 2).getOrCreate()

    df = spark.read.json("../../datas/person.json")

    df.createOrReplaceTempView("person")

    rsDf = spark.sql("""
        select name,age from person where age = (select max(age) from person)
    """)

    rsDf.write.csv("hdfs://bigdata01:9820/result")

    spark.stop()

如果你的hdfs没有关闭安全模式的话,会报一个错误,使用下面命令关闭安全模式即可

Hdfs 关闭安全模式
hdfs dfsadmin -safemode leave

保存到本地数据库:

import os

from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession

if __name__ == '__main__':
    os.environ['JAVA_HOME'] = 'C:/Program Files/Java/jdk1.8.0_131'
    # 配置Hadoop的路径,就是前面解压的那个路径
    os.environ['HADOOP_HOME'] = r'D:\BigDate\05-Hadoop\software\hadoop-3.3.1'
    # 配置base环境Python解析器的路径
    os.environ['PYSPARK_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'  # 配置base环境Python解析器的路径
    os.environ['PYSPARK_DRIVER_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'

    # 创建spark对象
    spark = SparkSession.builder.master("local[2]").appName("第一次构建SparkSession").config(
        "spark.sql.shuffle.partitions", 2).getOrCreate()

    df = spark.read.format("csv").option("sep","\t").load("../../datas/zuoye/emp.tsv") \
          .toDF("id","name","sal","comm","deptno")

    # 本地数据库jdbc连接
    df.write.format("jdbc") \
        .option("driver","com.mysql.cj.jdbc.Driver") \
        .option("url","jdbc:mysql://localhost:3306/homework") \
        .option("dbtable","emp1") \
        .option("user","root") \
        .option("password","123456") \
        .save(mode="overwrite")


    spark.stop()

保存到集群的hive中:

这里的spark环境是yarn,执行代码之前,需要先打开hdfs、yarn、hive(metastore和hiveserver2)

注意:如果没有使用schema,直接用toDf导入的时候,也可以导入成功,但是表中的字段类型就全都是String类型的,使用schema导入的时候可以指定字段的数据类型

import os

from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession
from pyspark.sql.types import StringType, StructType, StructField, IntegerType

if __name__ == '__main__':
    os.environ['JAVA_HOME'] = 'C:/Program Files/Java/jdk1.8.0_131'
    # 配置Hadoop的路径,就是前面解压的那个路径
    os.environ['HADOOP_HOME'] = r'D:\BigDate\05-Hadoop\software\hadoop-3.3.1'
    # 配置base环境Python解析器的路径
    os.environ['PYSPARK_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'  # 配置base环境Python解析器的路径
    os.environ['PYSPARK_DRIVER_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'

    # 创建spark对象
    spark = SparkSession \
        .builder \
        .appName("测试本地连接hive") \
        .master("local[2]") \
        .config("spark.sql.warehouse.dir", 'hdfs://bigdata01:9820/user/hive/warehouse') \
        .config('hive.metastore.uris', 'thrift://bigdata01:9083') \  #9083 metastore的端口号
        .config("spark.sql.shuffle.partitions", 2) \
        .enableHiveSupport() \
        .getOrCreate()

    # 如果没有这样指定表头的数据类型,导入hive中的数据类型全都是String 类型的
    # 指定了之后,表头的数据类型就是指定的了
    dept_schema = StructType([
        StructField(name="id", dataType=IntegerType(), nullable=False),
        StructField(name="name", dataType=StringType(), nullable=True),
        StructField(name="address", dataType=StringType(), nullable=True),
    ])

    df = spark.read.format("csv").load("../../datas/zuoye/dept.csv",schema=dept_schema)

    df.show()

    df.write.saveAsTable("homework.dept1")

    spark.stop()
连接DataGrip

通过DataGrip连接 spark(读取的是hive中的数据)

/opt/installs/spark/sbin/start-thriftserver.sh --hiveconf hive.server2.thrift.port=10001 --hiveconf hive.server2.thrift.bind.host=bigdata01 --master yarn --conf spark.sql.shuffle.partitions=2

一个综合案例:

1-统计查询每个省份的总销售额【订单金额要小于1万】:省份、订单金额

2-统计查询销售额最高的前3个省份中,统计各省份单日销售额超过1000的各省份的店铺个数

  • 只对销售额最高的前3个省份做统计:将这三个省份的数据过滤出来

  • 统计每个省份每个店铺每天的销售额超过1000的店铺个数

  • 省份、店铺id【去重】、销售额、天

3-统计查询销售额最高的前3个省份中,每个省份的平均订单金额

  • 只对销售额最高的前3个省份做统计:将这三个省份的数据过滤出来

  • 按照省份分组,求订单金额平均值

4-统计查询销售额最高的前3个省份中,每个省份的每种支付类型的占比

  • 只对销售额最高的前3个省份做统计:将这三个省份的数据过滤出来

  • 支付类型:微信、刷卡、支付宝、现金

  • 支付类型的占比 = 类型支付个数 / 总个数

  • 分组:每个省份每种类型支付的个数 / 每个省份总支付个数

  • 省份、支付类型

读取数据变成DataFrame,并对不合法的数据进行清洗【过滤、转换】

  • 订单金额超过10000的订单不参与统计

  • storeProvince不为空:None, 也不为 ‘null’值

  • 只保留需要用到的字段,将字段名称转换成Python规范:a_b_c

  • 并对时间戳进行转换成日期,获取天

  • 对订单金额转换为decimal类型

import os

from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession

if __name__ == '__main__':
    os.environ['JAVA_HOME'] = 'C:/Program Files/Java/jdk1.8.0_131'
    # 配置Hadoop的路径,就是前面解压的那个路径
    os.environ['HADOOP_HOME'] = r'D:\BigDate\05-Hadoop\software\hadoop-3.3.1'
    # 配置base环境Python解析器的路径
    os.environ['PYSPARK_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'  # 配置base环境Python解析器的路径
    os.environ['PYSPARK_DRIVER_PYTHON'] = 'C:/ProgramData/Miniconda3/python.exe'

    # 创建spark对象
    spark = SparkSession.builder.master("local[2]").appName("第一次构建SparkSession").config(
        "spark.sql.shuffle.partitions", 2).getOrCreate()

    df = spark.read.json("../../datas/function/retail.json")
    df.createOrReplaceTempView("orders")

    # spark.sql("""
    #     select * from orders
    # """).show()

    '''
            - 核心字段
        - "storeProvince":订单所在的省份信息,例如:湖南省
        - "storeID":订单所产生的店铺ID,例如:4064
        - "receivable":订单收款金额:例如:22.5
        - "payType":订单支付方式,例如:alipay
        - "dateTS":订单产生时间,例如:1563758583000
    '''
    #数据清洗
    clearDf = spark.sql("""
        select 
        storeProvince store_province,
        storeID store_id,
        cast(receivable as decimal(10,2)) receivable,
        payType pay_type,
        from_unixtime(dateTS/1000,"yyyy-MM-dd") date_tS
        from orders where receivable < 10000 and storeProvince is not null and storeProvince != 'null'
    """)
    clearDf.createOrReplaceTempView("clear_orders")

    # 1-统计查询每个省份的总销售额【订单金额要小于1万】:省份、订单金额
    df1 = spark.sql("""
        select store_province,sum(receivable) total_money from clear_orders group by store_province
    """)
    df1.createOrReplaceTempView("province_total_money")

    # 统计查询销售额最高的前3个省份中,统计各省份单日销售额超过1000的各省份的店铺个数

    # 只对销售额最高的前3个省份做统计:将这三个省份的数据过滤出来
    qiansanDf = spark.sql("""
        select * from clear_orders where store_province in (
               select store_province from province_total_money order by total_money desc limit 3
        )
    """)
    qiansanDf.createOrReplaceTempView("qs_province")

    # 统计每个省份每个店铺每天的销售额超过1000的店铺个数
    # spark.sql("""
    #     select store_province,count(distinct store_id) from qs_province group by store_province having sum(receivable) > 1000
    # """).show()

    spark.sql("""
           with t as(
              select date_ts,store_id,store_province from qs_province group by date_ts,store_id,store_province having sum(receivable) > 1000
           )
           select store_province,count(distinct store_id) store_num from t group by store_province
        """).show()

    qiansanDf.createOrReplaceTempView("qs_details")

    # 统计查询销售额最高的前3个省份中,统计各省份单日销售额超过1000的各省份的店铺个数
    spark.sql("""
         with t as(
            select date_ts,store_id,store_province from qs_details group by date_ts,store_id,store_province having sum(receivable) > 1000
         )
         select store_province,count(distinct store_id) store_num from t group by store_province
      """).show()

    # 每个省份的平均订单金额
    spark.sql("""
        select store_province,round(avg(receivable),2) avg_receivable from qs_details group by store_province
      """).show()

    # 每个省份的每种支付类型的占比
    spark.sql("""
         with t as(
           select store_province,pay_type,count(1) total_order from  qs_details group by store_province,pay_type
         )
         select store_province,pay_type,round(total_order/(sum(total_order) over(partition by store_province )),2) rate from t 
      """).show()


    spark.stop()

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

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

相关文章

ODOO学习笔记(5):ODOO开发规范

一、代码结构与布局 模块结构&#xff1a; 每个ODOO模块应具有清晰的结构&#xff0c;通常包含以下目录和文件&#xff1a; models&#xff1a;存放业务逻辑相关的模型类定义&#xff0c;如定义数据库表结构、业务规则等。views&#xff1a;用于放置各种视图文件&#xff0c;包…

【性能测试】linux服务器性能监控常用命令

CPU 性能监控指令 top 命令 基本功能&#xff1a;top 命令是 Linux 系统中最常用的性能监控工具之一。它可以实时显示系统中各个进程的资源占用情况&#xff0c;包括 CPU 使用率、内存使用量、进程状态等信息。在性能测试监控服务器性能时&#xff0c;通过 top 命令可以快速查…

ROS2humble版本使用colcon构建包

colcon与与catkin相比&#xff0c;没有 devel 目录。 创建工作空间 首先&#xff0c;创建一个目录 ( ros2_example_ws ) 来包含我们的工作区: mkdir -p ~/ros2_example_ws/src cd ~/ros2_example_ws 此时&#xff0c;工作区包含一个空目录 src : . └── src1 directory, …

VUE使用TS开发打包时发现校验问题无法打包

解决办法&#xff1a; 找到 tsconfig.app.json 这个文件&#xff0c;把他的include改为一个实际存在的空文件即可

vscode+EIDE开发环境搭建

嵌入式知识框架目录篇章&#xff1a;返回请点我 热门优质文章 文章标题等级&#xff1a;低中高推荐指数5√最佳vscode安装配置使用调试【保姆级教程】中√√√[VSCODE]基于EIDE插件搭建vscode下的STM32单片机开发环境中√√√官方安装高√√√√VScode利用EIDE和cortex-debug…

kafka面试题解答(四)

5、消费者组和分区数之间的关系是怎样的&#xff1f; 消费者组数小于等于分区数&#xff0c;消费者组内每个消费者负责消费不同分区的数据&#xff0c;一个分区只能由一个组内消费者消费。 6、kafka如何知道哪个消费者消费哪个分区&#xff1f; 生产者把数据发送给各个分区&…

C#入门 020 事件(类型成员)

初步了解事件 定义:单词Event&#xff0c;译为“事件” 《牛津词典》中的解释是“a thing that happens, especially something important通顺的解释就是“能够发生的什么事情” 角色:使对象或类具备通知能力的成员 事件(event)是一种使对象或类能够提供通知的成员对象O拥有…

单链表算法题(数据结构)

1. 反转链表 https://leetcode.cn/problems/reverse-linked-list/description/ 题目&#xff1a; 看到这个题目的时候我们怎么去想呢&#xff1f;如果我们反应快的话&#xff0c;应该可以想到我们可以从1遍历到5然后依次头插&#xff0c;但是其实我们还有更好的办法&#xff…

Python 如何通过 cron 或 schedule 实现爬虫的自动定时运行

Python 如何通过 cron 或 schedule 实现爬虫的自动定时运行 自动定时运行爬虫是很多数据采集项目的基本需求。例如&#xff0c;每天采集一次新闻数据&#xff0c;或每小时更新股票行情数据等。通过 Python 实现定时任务&#xff0c;可以保证数据采集的高效和持续性。本文将带大…

初学mongoDB

MongoDB 是一个开源的 NoSQL 数据库&#xff0c;由 C 语言编写。它与传统的关系型数据库不同&#xff0c;MongoDB 使用的是一种基于文档的存储模型&#xff0c;不需要定义固定的表结构&#xff0c;可以灵活地存储和管理大量的非结构化数据。下面是 MongoDB 的一些核心特性&…

Ubuntu 的 ROS 操作系统turtlebot3环境搭建

引言 本文介绍如何在Ubuntu系统中为TurtleBot3配置ROS环境&#xff0c;包括安装和配置ROS Noetic的步骤&#xff0c;为PC端控制TurtleBot3提供操作指南。 安装和配置的过程分为PC设置、系统安装、依赖安装等部分&#xff0c;并在最后进行网络配置&#xff0c;确保PC端能够顺利…

图像增强的100种方法

文章目录 什么是图像增强 &#xff1f;一、亮度和对比度调整1.1、线性方法1.1.1、灰度反转&#xff08;Gray Inversion&#xff09;1.1.2、对比度拉伸&#xff08;Contrast Stretching&#xff09;1.1.3、对比度和亮度增强&#xff08;Contrast and Brightness&#xff09; 1.2…

Android Kotlin Flow 冷流 热流

在 Android 开发中&#xff0c;Flow 是 Kotlin 协程库的一部分&#xff0c;用于处理异步数据流的一个组件。本质上&#xff0c;Flow 是一个能够异步生产多个值的数据流&#xff0c;与 suspend 函数返回单个值的模式相对应。Flow 更类似于 RxJava 中的 Observable&#xff0c;但…

Web服务器nginx实验2修改端口、默认目录、默认文件访问web页面

修改默认目录、默认文件&#xff1a; 创建配置文件&#xff1a; 里面写&#xff1a;&#xff08;访问的位置是/haha目录里面的haha.html&#xff09; 把haha里面的index.html改名为haha.html&#xff1a; 重启服务&#xff1a; 关闭防火墙、改宽松模式&#xff1a; 用Windows访…

Maven最佳实践

文章目录 1.摘要 本文主要介绍Maven使用&#xff0c;作为Maven使用手册来记录。 2.介绍 Maven是项目管理工具&#xff0c;将项目开发和管理过程抽象成一个项目对象模型&#xff0c;使用pom.xml 文件进行依赖管理和项目构建。 Maven 中pom.xml 是根据坐标信息来定位资源的位置&a…

el-table 纵向垂直表头处理

项目中表格展示会遇到需要纵向垂直表头情况&#xff0c;下面&#xff0c;我们基于el-table组件来实现这种表格。 以下是这次需要用到的数据表格&#xff0c;已知左侧违章名称是固定的&#xff0c;而月份是不固定的&#xff0c;在后端返回数据格式已确定的情况下&#xff0c;需…

Android OpenGL ES详解——纹理:纹理过滤GL_NEAREST和GL_LINEAR的区别

目录 一、概念 1、纹理过滤 2、邻近过滤 3、线性过滤 二、邻近过滤和线性过滤的区别 三、源码下载 一、概念 1、纹理过滤 当纹理被应用到三维物体上时&#xff0c;随着物体表面的形状和相机视角的变化&#xff0c;会导致纹理在渲染过程中出现一些问题&#xff0c;如锯齿…

超市11-12月生鲜重点商品配置

11月份&#xff1a;应季商品很多,特别是与季节相对应的蔬菜大量上市。宜推荐对预防感冒等相应的特殊食谱,推荐对于常外出的人方便又省事、省时的食谱&#xff0c;推荐多种花样的火锅&#xff0c;推荐便于保存的应季食品原料。 生活特性&#xff1a;大众食谱宜以炖菜、红焖、火锅…

c++设计模式demo

模式设计原则 依赖倒置原则 ⾼层模块不应该依赖低层模块&#xff0c;⼆者都应该依赖抽象 &#xff1b; 抽象不应该依赖具体实现&#xff0c;具体实现应该依赖于抽象&#xff1b; ⾃动驾驶系统公司是⾼层&#xff0c;汽⻋⽣产⼚商为低层&#xff0c;它们不应该互相依赖&#x…

【网络面试篇】其他面试题——Cookie、Session、DNS、CDN、SSL/TLS、加密概念

目录 一、HTTP 相关问题 1. Cookie 和 Session 是什么&#xff1f; &#xff08;1&#xff09;Cookie &#xff08;2&#xff09;Session 2. Cookie 的工作原理&#xff1f; 3. Session 的工作原理&#xff1f; 4. Cookie 和 Session 有什么区别&#xff1f; 二、其他问…