Spark编程实验四:Spark Streaming编程

目录

一、目的与要求

二、实验内容

三、实验步骤

1、利用Spark Streaming对三种类型的基本数据源的数据进行处理

2、利用Spark Streaming对Kafka高级数据源的数据进行处理

3、完成DStream的两种有状态转换操作

4、把DStream的数据输出保存到文本文件或MySQL数据库中

四、结果分析与实验体会


一、目的与要求

1、通过实验掌握Spark Streaming的基本编程方法;
2、熟悉利用Spark Streaming处理来自不同数据源的数据。
3、熟悉DStream的各种转换操作。
4、熟悉把DStream的数据输出保存到文本文件或MySQL数据库中。

二、实验内容

1、参照教材示例,利用Spark Streaming对三种类型的基本数据源的数据进行处理。 
2、参照教材示例,完成kafka集群的配置,利用Spark Streaming对Kafka高级数据源的数据进行处理,注意topic为你的姓名全拼
3、参照教材示例,完成DStream的两种有状态转换操作。
4、参照教材示例,完成把DStream的数据输出保存到文本文件或MySQL数据库中。

三、实验步骤

1、利用Spark Streaming对三种类型的基本数据源的数据进行处理

(1)文件流

首先打开第一个终端作为数据流终端,创建一个logfile目录:

[root@bigdata zhc]# cd /home/zhc/mycode/sparkstreaming
[root@bigdata sparkstreaming]# mkdir logfile
[root@bigdata sparkstreaming]# cd logfile

然后打开第二个终端作为流计算终端,在“/logfile/”目录下面新建一个py程序:

[root@bigdata logfile]# vim FileStreaming.py

输入如下代码:

#/home/zhc/mycode/sparkstreaming/logfile/FileStreaming.pyfrom pyspark import SparkContext, SparkConf
from pyspark.streaming import StreamingContextconf = SparkConf()
conf.setAppName('TestDStream')
conf.setMaster('local[2]')
sc = SparkContext(conf = conf)
ssc = StreamingContext(sc, 10)
lines = ssc.textFileStream('file:///home/zhc/mycode/sparkstreaming/logfile')
words = lines.flatMap(lambda line: line.split(' '))
wordCounts = words.map(lambda x : (x,1)).reduceByKey(lambda a,b:a+b)
wordCounts.pprint()
ssc.start()
ssc.awaitTermination()

保存该文件并执行如下命令:

[root@bigdata logfile]# spark-submit FileStreaming.py 

然后我们进入数据流终端,在logfile目录下新建一个log2.txt文件,然后往里面输入一些英文语句后保存退出,再次切换到流计算终端,就可以看见打印出单词统计信息了。

(2)套接字流

1)使用套接字流作为数据源

继续在流计算端的sparkstreaming目录下创建一个socket目录,然后在该目录下创建一个NetworkWordCount.py程序:

[root@bigdata sparkstreaming]# mkdir socket
[root@bigdata sparkstreaming]# cd socket
[root@bigdata socket]# vim NetworkWordCount.py

输入如下代码:

#/home/zhc/mycode/sparkstreaming/socket/NetworkWordCount.pyfrom __future__ import print_function
import sys
from pyspark import SparkContext
from pyspark.streaming import StreamingContextif __name__ == "__main__":if len(sys.argv) != 3:print("Usage: NetworkWordCount.py <hostname> <port>", file=sys.stderr)exit(-1)sc = SparkContext(appName="PythonStreamingNetworkWordCount")ssc = StreamingContext(sc, 5)lines = ssc.socketTextStream(sys.argv[1], int(sys.argv[2]))counts = lines.flatMap(lambda line: line.split(" ")).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a+b)counts.pprint()ssc.start()ssc.awaitTermination()

再在数据流终端启动Socket服务器端:

[root@bigdata logfile]# nc -lk 9999

然后再进入流计算终端,执行如下代码启动流计算:

[root@bigdata socket]# spark-submit NetworkWordCount.py localhost 9999

然后在数据流终端内手动输入一行英文句子后回车,多输入几次,流计算终端就会不断执行词频统计并打印出信息。

2)使用Socket编程实现自定义数据源

下面我们再前进一步,把数据源头的产生方式修改一下,不要使用nc程序,而是采用自己编写的程序产生Socket数据源。在数据流终端执行以下命令,编写DataSourceSocket.py文件:

[root@bigdata logfile]# cd /home/zhc/mycode/sparkstreaming/socket
[root@bigdata socket]# vim DataSourceSocket.py

输入如下代码:

#/home/zhc/mycode/sparkstreaming/socket/DataSourceSocket.py
import socket
# 生成socket对象
server = socket.socket()
# 绑定ip和端口
server.bind(('localhost', 9999))
# 监听绑定的端口
server.listen(1)
while 1:# 为了方便识别,打印一个“我在等待”print("I'm waiting the connect...")# 这里用两个值接受,因为连接上之后使用的是客户端发来请求的这个实例# 所以下面的传输要使用conn实例操作conn,addr = server.accept()# 打印连接成功print("Connect success! Connection is from %s " % addr[0])# 打印正在发送数据print('Sending data...')conn.send('I love hadoop I love spark hadoop is good spark is fast'.encode())conn.close()print('Connection is broken.')

继续在数据流终端执行如下命令启动Socket服务端:

[root@bigdata socket]# spark-submit DataSourceSocket.py

再进入流计算终端,执行如下代码启动流计算:

[root@bigdata socket]# spark-submit NetworkWordCount.py localhost 9999

(3)RDD队列流

继续在sparkstreaming目录下新建rddqueue目录并在该目录下创建RDDQueueStream.py程序:

[root@bigdata sparkstreaming]# mkdir rddqueue
[root@bigdata sparkstreaming]# cd rddqueue
[root@bigdata rddqueue]# vim RDDQueueStream.py

输入如下代码:

#/home/zhc/mycode/sparkstreaming/rddqueue/RDDQueueStreaming.py
import time
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
if __name__ == "__main__":sc = SparkContext(appName="PythonStreamingQueueStream")ssc = StreamingContext(sc, 2)#创建一个队列,通过该队列可以把RDD推给一个RDD队列流rddQueue = []for i in range(5):rddQueue += [ssc.sparkContext.parallelize([j for j in range(1, 1001)], 10)]time.sleep(1)#创建一个RDD队列流inputStream = ssc.queueStream(rddQueue)mappedStream = inputStream.map(lambda x: (x % 10, 1))reducedStream = mappedStream.reduceByKey(lambda a, b: a + b)reducedStream.pprint()ssc.start()ssc.stop(stopSparkContext=True, stopGraceFully=True)

保存退出后,进入流计算终端再执行如下命令:

[root@bigdata rddqueue]# spark-submit RDDQueueStream.py

2、利用Spark Streaming对Kafka高级数据源的数据进行处理

此过程可以参照这篇博客的第四、五部分内容:

【数据采集与预处理】数据接入工具Kafka-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/Morse_Chen/article/details/135273370?spm=1001.2014.3001.5501

3、完成DStream的两种有状态转换操作

说明:上面的词频统计程序NetworkWordCount.py采取了无状态转换操作。

(1)滑动窗口转换操作

在socket目录下创建WindowedNetworkWordCount.py程序并输入如下代码:

#/home/zhc/mycode/sparkstreaming/socket/WindowedNetworkWordCount.py
from __future__ import print_function
import sys
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
if __name__ == "__main__":if len(sys.argv) != 3:print("Usage: WindowedNetworkWordCount.py <hostname> <port>", file=sys.stderr)exit(-1)sc = SparkContext(appName="PythonStreamingWindowedNetworkWordCount")ssc = StreamingContext(sc, 10)ssc.checkpoint("file:///home/zhc/mycode/sparkstreaming/socket/checkpoint")lines = ssc.socketTextStream(sys.argv[1], int(sys.argv[2]))counts = lines.flatMap(lambda line: line.split(" ")).map(lambda word: (word, 1)).reduceByKeyAndWindow(lambda x, y: x + y, lambda x, y: x - y, 30, 10)counts.pprint()ssc.start()ssc.awaitTermination()

然后在数据流终端执执行如下命令运行nc程序:

[root@bigdata sparkstreaming]# cd /home/zhc/mycode/sparkstreaming/socket
[root@bigdata socket]# nc -lk 9999

然后再在流计算终端运行WindowedNetworkWordCount.py代码:

[root@bigdata socket]# spark-submit WindowedNetworkWordCount.py localhost 9999

这时,可以查看流计算终端内显示的词频动态统计结果,可以看到,随着时间的流逝,词频统计结果会发生动态变化。 

(2)updateStateByKey操作

在“/home/zhc/mycode/sparkstreaming/”路径下新建目录“/stateful”,并在该目录下新建代码文件NetworkWordCountStateful.py。

[root@bigdata sparkstreaming]# mkdir stateful
[root@bigdata sparkstreaming]# cd stateful
[root@bigdata stateful]# vim NetworkWordCountStateful.py

输入如下代码: 

#/home/zhc/mycode/sparkstreaming/stateful/NetworkWordCountStateful.py
from __future__ import print_function
import sys
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
if __name__ == "__main__":if len(sys.argv) != 3:print("Usage: NetworkWordCountStateful.py <hostname> <port>", file=sys.stderr)exit(-1)sc = SparkContext(appName="PythonStreamingStatefulNetworkWordCount")ssc = StreamingContext(sc, 1)ssc.checkpoint("file:///home/zhc/mycode/sparkstreaming/stateful/")           # RDD with initial state (key, value) pairsinitialStateRDD = sc.parallelize([(u'hello', 1), (u'world', 1)]) def updateFunc(new_values, last_sum):return sum(new_values) + (last_sum or 0) lines = ssc.socketTextStream(sys.argv[1], int(sys.argv[2]))running_counts = lines.flatMap(lambda line: line.split(" ")).map(lambda word: (word, 1)).updateStateByKey(updateFunc, initialRDD=initialStateRDD) running_counts.pprint()ssc.start()ssc.awaitTermination()

在“数据源终端”,执行如下命令启动nc程序:

[root@bigdata stateful]# nc  -lk  9999

在“流计算终端”,执行如下命令提交运行程序:

[root@bigdata stateful]# spark-submit NetworkWordCountStateful.py localhost 9999

在数据源终端内手动输入一些单词并回车,再切换到流计算终端,可以看到已经输出了类似如下的词频统计信息: 

4、把DStream的数据输出保存到文本文件或MySQL数据库中

(1)把DStream输出到文本文件中

在stateful目录下新建NetworkWordCountStatefulText.py文件:

[root@bigdata stateful]# vim NetworkWordCountStatefulText.py

输入如下代码: 

#/home/zhc/mycode/sparkstreaming/stateful/NetworkWordCountStatefulText.py
from __future__ import print_function
import sys
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
if __name__ == "__main__":if len(sys.argv) != 3:print("Usage: NetworkWordCountStateful.py <hostname> <port>", file=sys.stderr)exit(-1)sc = SparkContext(appName="PythonStreamingStatefulNetworkWordCount")ssc = StreamingContext(sc, 1)ssc.checkpoint("file:///home/zhc/mycode/sparkstreaming/stateful/statefultext")# RDD with initial state (key, value) pairsinitialStateRDD = sc.parallelize([(u'hello', 1), (u'world', 1)])def updateFunc(new_values, last_sum):return sum(new_values) + (last_sum or 0)lines = ssc.socketTextStream(sys.argv[1], int(sys.argv[2]))running_counts = lines.flatMap(lambda line: line.split(" ")).map(lambda word: (word, 1)).updateStateByKey(updateFunc, initialRDD=initialStateRDD)running_counts.saveAsTextFiles("file:///home/zhc/mycode/sparkstreaming/stateful/statefultext/output")running_counts.pprint()ssc.start()ssc.awaitTermination()

在“数据源终端”,执行如下命令启动nc程序:

[root@bigdata stateful]# nc  -lk  9999

在“流计算终端”,执行如下命令提交运行程序:

[root@bigdata stateful]# spark-submit NetworkWordCountStatefulText.py localhost 9999

在数据源终端内手动输入一些单词并回车,再切换到流计算终端,可以看到已经输出了类似如下的词频统计信息:  

在“/home/zhc/mycode/sparkstreaming/stateful/statefultext”目录下便可查看到如下输出目录结果:

进入某个目录下,就可以看到类似part-00000的文件,里面包含了流计算过程的输出结果。

(2)把DStream写入到MySQL数据库中

首先启动MySQL数据库:

[root@bigdata stateful]# systemctl start mysqld.service
[root@bigdata stateful]# mysql -u root -p

然后创建spark数据库和wordcount表:

mysql> use spark;
mysql> create table wordcount (word char(20), count int(4));

然后再在终端安装python连接MySQL的模块:

[root@bigdata stateful]# pip3 install PyMySQL

在stateful目录并在该目录下创建NetworkWordCountStatefulDB.py文件: 

[root@bigdata stateful]# vim NetworkWordCountStatefulDB.py

输入如下代码: 

#/home/zhc/mycode/sparkstreaming/stateful/NetworkWordCountStatefulDB.py
from __future__ import print_function 
import sys 
import pymysql 
from pyspark import SparkContext
from pyspark.streaming import StreamingContext 
if __name__ == "__main__":if len(sys.argv) != 3:print("Usage: NetworkWordCountStateful <hostname> <port>", file=sys.stderr)exit(-1)sc = SparkContext(appName="PythonStreamingStatefulNetworkWordCount")ssc = StreamingContext(sc, 1)ssc.checkpoint("file:///home/zhc/mycode/sparkstreaming/stateful/statefuldb")  # RDD with initial state (key, value) pairsinitialStateRDD = sc.parallelize([(u'hello', 1), (u'world', 1)]) def updateFunc(new_values, last_sum):return sum(new_values) + (last_sum or 0) lines = ssc.socketTextStream(sys.argv[1], int(sys.argv[2]))running_counts = lines.flatMap(lambda line: line.split(" ")).map(lambda word: (word, 1)).updateStateByKey(updateFunc, initialRDD=initialStateRDD) running_counts.pprint() def dbfunc(records):db = pymysql.connect(host="localhost",user="root",password="MYsql123!",database="spark")cursor = db.cursor() def doinsert(p):sql = "insert into wordcount(word,count) values ('%s', '%s')" % (str(p[0]), str(p[1]))try:cursor.execute(sql)db.commit()except:db.rollback()for item in records:doinsert(item) def func(rdd):repartitionedRDD = rdd.repartition(3)repartitionedRDD.foreachPartition(dbfunc)running_counts.foreachRDD(func)ssc.start()ssc.awaitTermination()

在“数据源终端”,执行如下命令启动nc程序:

[root@bigdata stateful]# nc  -lk  9999

在“流计算终端”,执行如下命令提交运行程序:

[root@bigdata stateful]# spark-submit NetworkWordCountStatefulDB.py localhost 9999

在数据源终端内手动输入一些单词并回车,再切换到流计算终端,可以看到已经输出了类似如下的词频统计信息:

 

到MySQL终端便可以查看wordcount表中的内容:

mysql> select * from wordcount;

.......

四、结果分析与实验体会

        Spark Streaming是一个用于实时数据处理的流式计算框架,它基于 Apache Spark 平台,提供了高可靠性、高吞吐量和容错性强等特点。在进行 Spark Streaming 编程的实验中,掌握了Spark Streaming的基本编程方法;能够利用Spark Streaming处理来自不同数据源的数据以及DStream的各种转换操作;把DStream的数据输出保存到文本文件或MySQL数据库中。
        理解DStream:DStream 是 Spark Streaming 的核心概念,代表连续的数据流。在编程时,我们可以通过输入源(比如 Kafka、Flume、HDFS)创建一个 DStream 对象,并对其进行转换和操作。需要注意的是,DStream 是以时间片为单位组织数据的,因此在编写代码时要考虑时间窗口的大小和滑动间隔。
        适当设置批处理时间间隔:批处理时间间隔决定了 Spark Streaming 处理数据的粒度,过小的时间间隔可能导致频繁的任务调度和资源开销,而过大的时间间隔则可能造成数据处理延迟。因此,在实验中需要根据具体场景和需求来选择合适的时间间隔。
        使用合适的转换操作:Spark Streaming 提供了丰富的转换操作,如 map、flatMap、filter、reduceByKey 等,可以实现对数据流的转换和处理。在实验中,需要根据具体业务逻辑和需求选择合适的转换操作,并合理组合这些操作,以获取期望的结果。
        考虑容错性和数据丢失:Spark Streaming 具备很好的容错性,可以通过记录数据流的偏移量来保证数据不会丢失。在实验中,需要注意配置合适的容错机制,确保数据处理过程中的异常情况能够被恢复,并尽量避免数据丢失。
        优化性能和资源利用:对于大规模的实时数据处理任务,性能和资源利用是非常重要的。在实验中,可以通过调整并行度、合理设置缓存策略、使用广播变量等手段来提高性能和资源利用效率。
        总的来说,Spark Streaming 是一个功能强大且易用的流式计算框架,通过合理使用其提供的特性和操作,可以实现各种实时数据处理需求。在实验中,需要深入理解其原理和机制,并根据具体需求进行合理配置和优化,以获得良好的性能和结果。

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

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

相关文章

手摸手系列之SpringBoot+Vue2项目整合高德地图实现车辆实时定位功能

前言 最近在做一个物流内陆运输的项目&#xff0c;其中的一个关键功能是根据车辆的GPS数据在页面上实时显示车辆位置信息。由于我们已经获得了第三方提供的GPS数据&#xff0c;所以接下来的任务是将这些数据整合到我们的系统中&#xff0c;并利用高德地图API来展示车辆的实时位…

如何修复msvcp140_1.dll丢失问题,分享多种实测可靠的修复方法

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcp140_1.dll丢失”的错误。msvcp140_1.dll是Microsoft Visual C 2015 Redistributable的一个组件&#xff0c;它是运行某些程序所必需的动态链接库文件。动态链接库&#xff08;DLL&…

【Linux】Linux

Linux 文章目录 Linux1. 简介2. 目录结构3. vi/vim 的使用4. 网络配置4.1 配置网络ip地址4.2 配置主机名或ip映射4.3 远程登陆及上传下载 5. 系统管理5.1 service 服务管理&#xff08;CentOS 6 版本&#xff09;5.2 systemctl 服务管理&#xff08;CentOS 7 版本&#xff09;5…

Flask笔记

一&#xff1a;模板渲染 一般的话都序列化成字符串 二&#xff1a;项目拆分 2.1 项目拆分 app.py init.py views.py models.py 模型数据 2.2 蓝图 三&#xff1a;路由参数 3.1 String 重点 3.2 int 3.3 path 3.4 UUID 3.5 any 四&#xff1a;请求方式 五&#xff1a;Requ…

Docker单点部署Seata(2.0.0) + Nacos(v2.3.0) + Mysql(5.7)

文章目录 一、部署Nacos二、部署Mysql三、Seata准备工作1. 记住nacos、mysql、宿主机的ip2. 建立数据库3. Nacos远程配置文件 四、部署Seata五、初步检验Seata部署情况六、微服务使用Seata1.引入依赖2. application.yml配置 七、遇到的坑1. Nacos显示Seata服务的ip为容器内网ip…

听GPT 讲Rust源代码--src/tools(38)

File: rust/src/tools/clippy/clippy_dev/src/lib.rs rust/src/tools/clippy/clippy_dev/src/lib.rs文件是Clippy开发工具的入口文件&#xff0c;其作用是提供Clippy开发过程中所需的功能和工具。Clippy是一个Rust代码的静态分析工具&#xff0c;用于提供各种有用的代码规范、编…

ARCGIS PRO SDK 访问Geometry对象

一、Geometry常用对象 二、主要类 1、ReadOnlyPartCollection&#xff1a;Polyline 和 Polygon 使用的 ReadOnlySegmentCollection 部件的只读集合&#xff0c;属性成员&#xff1a;​ 名字描述Count获取 ICollection 中包含的元素数。TIEM获取位于指定索引处的元素。Spatial…

TimescaleDB安装部署

安装cmake 解压压缩包 tar xvf cmake-3.28.1-linux-x86_64.tar 将cmake 添加到profile中 vi ~/.bash_profile export PATH/home/postgres/app/cmake-3.28.1-linux-x86_64/bin:$PATH 保存&#xff0c;执行 source ~/.bash_profile 安装TimescaleDB 下载timescaledb安装包并解压…

【Matlab】基于遗传算法优化BP神经网络 (GA-BP)的数据时序预测

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88682033 一&#xff0c;概述 基于遗传算法优化BP神经网络 (GA-BP) 的数据时序预测是一种常用的机器学习方法&#xff0c;用于预测时间序列数据的趋势和未来值。 在使用这种方法之前&#xff0c;需要将时间序…

JVM工作原理与实战(二):字节码编辑器jclasslib

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、字节码编辑器jclasslib介绍和安装 1.介绍 2.安装 3.IntelliJ IDEA 插件安装 二、字节码编辑器jclasslib的使用 1.使用jclasslib bytecode viewer打开字节码文件 2.使用Intell…

Redis经典五大类型源码及底层实现(二)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

Screenshot-to-code开源项目mac上实践

github上的开源项目&#xff0c;看介绍可以将设计ui图片转换为 HTML 和 CSS 源码地址&#xff1a; GitCode - 开发者的代码家园 我的mac安装了2.7和3.11&#xff0c;就用3吧直接上代码 安装 pip3 install keras tensorflow pillow h5py jupyter 报错 ERROR: Could not in…

DFS BFS

用DFS和BFS分别实现 //这边给出DFS的模版 void dfs(int x,int y) {//判断是否到达终点&#xff08;只有给出结束点的时候需要&#xff09; if (x ex && y ey) {if (min_steps > step) {min_steps step;}return;}//给出移动方向int move[4][2] {{0, 1}, {0, -1}…

uniapp中uview组件库的丰富Upload 上传上午用法

目录 基础用法 #上传视频 #文件预览 #隐藏上传按钮 #限制上传数量 #自定义上传样式 API #Props #Methods #Slot #Events 基础用法 可以通过设置fileList参数(数组&#xff0c;元素为对象)&#xff0c;显示预置的图片。其中元素的url属性为图片路径 <template>…

音频播放软件Foobar2000 mac特点介绍

Foobar2000 mac是一款高度可定制的音频播放器&#xff0c;适用于Windows平台。它支持各种音频格式&#xff0c;包括MP3、FLAC、AAC、WMA等&#xff0c;同时也支持各种音频插件和效果器&#xff0c;可以提供更好的音质和用户体验。 Foobar2000 mac软件特点 1. 高度可定制&#…

69内网安全-域横向CobaltStrikeSPNRDP

这节课主要讲spn和rdp协议&#xff0c; 案例一域横向移动RDP传递-Mimikatz rdp是什么&#xff0c;rdp是一个远程的链接协议&#xff0c;在linux上面就是ssh协议&#xff0c; 我们在前期信息收集的时候&#xff0c;得到一些hash值和明文密码可以进行一些相关协议的链接的&am…

【Proteus仿真】【Arduino单片机】汽车尾灯控制设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用按键、LED模块等。 主要功能&#xff1a; 系统运行后&#xff0c;系统运行后&#xff0c;系统开始运行&#xff0c;K1键控制左转向灯&#x…

【UE 游戏模板】 游戏分类(RPG、RST等)

目录 0 引言1 游戏分类1.1 角色扮演游戏&#xff08;RPG&#xff09;1.2 第一人称射击游戏&#xff08;FPS&#xff09;1.3 即时策略游戏&#xff08;RTS&#xff09;1.4 VR游戏1.5 集换式卡牌游戏&#xff08;TCG&#xff09;1.5 塔防游戏&#xff08;Tower Defense Games&…

据报道,微软的下一代 Surface 笔记本电脑将是其首款真正的“人工智能 PC”

明年&#xff0c;微软计划推出 Surface Laptop 6和 Surface Pro 10&#xff0c;这两款设备将提供 Arm 和 Intel 两种处理器选项。不愿意透露姓名的不透露姓名人士透露&#xff0c;这些新设备将引入先进的人工智能功能&#xff0c;包括配备下一代神经处理单元 (NPU)。据悉&#…

Spring Data Redis对象缓存序列化问题

相信在项目中&#xff0c;你一定是经常使用 Redis &#xff0c;那么&#xff0c;你是怎么使用的呢&#xff1f;在使用时&#xff0c;有没有遇到同我一样&#xff0c;对象缓存序列化问题的呢&#xff1f;那么&#xff0c;你又是如何解决的呢&#xff1f; Redis 使用示例 添加依…