基于矩阵分解算法的智能Steam游戏AI推荐系统——深度学习算法应用(含python、ipynb工程源码)+数据集(三)

2023-09-21 22:57:37


在这里插入图片描述

前言

本项目采用了矩阵分解算法,用于对玩家已游玩的数据进行深入分析。它的目标是从众多游戏中筛选出最适合该玩家的游戏,以实现一种相对精准的游戏推荐系统。

首先,项目会收集并分析玩家已经玩过的游戏数据,包括游戏名称、游戏时长、游戏评分等信息。这些数据构成了一个大型的用户-游戏交互矩阵,其中每一行代表一个玩家,每一列代表一个游戏,矩阵中的值表示玩家与游戏之间的交互情况。

接下来,项目运用矩阵分解算法,将用户-游戏这稀疏矩阵用两个小矩阵——特征-游戏矩阵和用户-特征矩阵,进行近似替代。这个分解过程会将玩家和游戏映射到一个潜在的特征空间,从而能够推断出玩家与游戏之间的潜在关系。

一旦模型训练完成,系统可以根据玩家的游戏历史,预测他们可能喜欢的游戏。这种预测是基于玩家与其他玩家的相似性以及游戏与其他游戏的相似性来实现的。因此,系统可以为每个玩家提供个性化的游戏推荐,考虑到他们的游戏偏好和历史行为。

总的来说,本项目的目标是通过矩阵分解和潜在因子模型,提供一种更为精准的游戏推荐系统。这种个性化推荐可以提高玩家的游戏体验,同时也有助于游戏平台提供更好的游戏推广和增加用户黏性。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。

在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

运行环境

本部分包括 Python 环境、TensorFlow环境、 PyQt5环境。

详见博客:https://blog.csdn.net/qq_31136513/article/details/133148686#_38

模块实现

本项目包括4个模块:数据预处理、模型构建、模型训练及保存、模型测试,下面分别给出各模块的功能介绍及相关代码。

1. 数据预处理

数据集来源于Kaggle,链接地址为https://www.kaggle.com/tamber/steam-video-games,此数据集包含了用户的ID、游戏名称、是否购买或游玩、游戏时长,其中:共包含12393名用户,涉及游戏数量5155款。将数据集置于Jupyter工作路径下的steam-video-games文件夹中。

详见博客:https://blog.csdn.net/qq_31136513/article/details/133148686#1__97

2. 模型构建

数据加载进模型之后,需要定义模型结构,并优化损失函数。

1)定义模型结构

使用矩阵分解算法,将用户-游戏这稀疏矩阵用两个小矩阵——特征-游戏矩阵和用户-特征矩阵,进行近似替代。

详见博客:https://blog.csdn.net/qq_31136513/article/details/133151049#1_54

2)优化损失函数

L2范数常用于矩阵分解算法的损失函数中。因此,本项目的损失函数也引入了L2范数以避免过拟合现象。使用Adagrad优化器优化模型参数。

详见博客:https://blog.csdn.net/qq_31136513/article/details/133151049#2_91

3. 模型训练及保存

由于本项目使用的数据集中,将游戏的DLC (Downloadable Content,后续可下载内容)单独作为另一款游戏列举,因此,在计算准确率时,DLC和游戏本体判定为同一款游戏,同系列的游戏也可以判定为同一款。

详见博客:https://blog.csdn.net/qq_31136513/article/details/133151049#3__105

1)模型训练

详见博客:https://blog.csdn.net/qq_31136513/article/details/133151049#1_148

2)模型保存

为方便使用模型,需要将训练得到的结果使用Joblib进行保存。

详见博客:https://blog.csdn.net/qq_31136513/article/details/133151049#2_187

4. 模型应用

一是制作页面的布局,获取并检查输入的数据;二是将获取的数据-与之前保存的模型进行匹配达到应用效果。

1)制作页面

相关操作如下:

(1)使用代码绘制页面的基础布局,创建Recommandation类。

class Recommandation(QWidget):
#初始化
    def __init__(self):
        super().__init__()
        self.initUI()
#初始化布局
    def initUI(self):
        #设置界面的初始位置和大小
        self.setGeometry(600,200,450,550)
        #窗口名
        self.setWindowTitle('steam游戏推荐')
        #设置组件,以下为标签
        self.lb1 = QLabel('请输入游戏名:',self)
        #这是所在位置
        self.lb1.move(20,20)
        self.lb2 = QLabel('请输入游戏名:',self)
        self.lb2.move(20,80)
        self.lb3 = QLabel('请输入游戏名:',self)
        self.lb3.move(20,140)
        self.lb4 = QLabel('请输入游戏名:',self)
        self.lb4.move(20,200)
        self.lb5 = QLabel('请输入游戏名:',self)
        self.lb5.move(20,260)
        #以下为下拉输入框的创建
        self.combobox1 = QComboBox(self, minimumWidth=200)
        self.combobox1.move(100,20)
        self.combobox1.setEditable(True)
        self.combobox2 = QComboBox(self, minimumWidth=200)
        self.combobox2.move(100,80)
        self.combobox2.setEditable(True)
        self.combobox3 = QComboBox(self, minimumWidth=200)
        self.combobox3.move(100,140)
        self.combobox3.setEditable(True)
        self.combobox4 = QComboBox(self, minimumWidth=200)
        self.combobox4.move(100,200)
        self.combobox4.setEditable(True)
        self.combobox5 = QComboBox(self, minimumWidth=200)
        self.combobox5.move(100,260)
        self.combobox5.setEditable(True)
        #以下为输入的按键设置
        self.bt1 = QPushButton('请输入游戏时间',self)
        self.bt1.move(330,20)
        self.bt2 = QPushButton('请输入游戏时间',self)
        self.bt2.move(330,80)
        self.bt3 = QPushButton('请输入游戏时间',self)
        self.bt3.move(330,140)
        self.bt4 = QPushButton('请输入游戏时间',self)
        self.bt4.move(330,200)
        self.bt5 = QPushButton('请输入游戏时间',self)
        self.bt5.move(330,260)
        #推荐按钮
        self.bt=QPushButton('推荐开始',self)
        self.bt.move(20,400)
        #初始化下拉输入框
        self.init_combobox()
        #连接按键与槽
        self.bt1.clicked.connect(self.timeDialog)
        self.bt2.clicked.connect(self.timeDialog)
        self.bt3.clicked.connect(self.timeDialog)
        self.bt4.clicked.connect(self.timeDialog)
        self.bt5.clicked.connect(self.timeDialog)
        #连接推荐
        self.bt.clicked.connect(self.recommand) 

connect()是Qt特有的信号与槽机制,槽接收到信号进行处理。在这里使用了clicked 作为信号,单击按键会发出信号。

(2)初始化下拉输入框,将gamelist输入进下拉框的菜单,以及添加自动补全机能。

#初始化下拉输入框
def init_combobox(self):
    #增加选项元素
    for i in range(len(gamelist)):
        self.combobox1.addItem(gamelist[i])
        self.combobox2.addItem(gamelist[i])
        self.combobox3.addItem(gamelist[i])
        self.combobox4.addItem(gamelist[i])
        self.combobox5.addItem(gamelist[i])
    self.combobox1.setCurrentIndex(-1)
    self.combobox2.setCurrentIndex(-1)
    self.combobox3.setCurrentIndex(-1)
    self.combobox4.setCurrentIndex(-1)
    self.combobox5.setCurrentIndex(-1)
    #增加自动补全
    self.completer = QCompleter(gamelist)
    #补全方式
    self.completer.setFilterMode(Qt.MatchStartsWith)
    self.completer.setCompletionMode(QCompleter.PopupCompletion)
    self.combobox1.setCompleter(self.completer)
    self.combobox2.setCompleter(self.completer)
    self.combobox3.setCompleter(self.completer)
    self.combobox4.setCompleter(self.completer)
    self.combobox5.setCompleter(self.completer)

(3)设置槽,同时存储数据

相关操作如下:

    def timeDialog(self):
#获取信号
        sender = self.sender()
        if sender == self.bt1:
                #获取下拉输入框1输入的游戏名
                gamename = self.combobox1.currentText()
                #通过字典game2idx查询获得的游戏名所对应的序列号
                gameid = game2idx.get(gamename)
                #没有序列号的情况,可以理解为未输入正确的游戏名,或者输入为空
                if gameid == None:
                    #这种情况下生成一个MessageBox报错
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
                  #输入正确的情况,将游戏名字、ID,分别记录到一个字典里,方便保存与更改
                    gamedict[1] = gamename
                    idxdict[1] = gameid
                    #弹出一个文本输入框,要求输入对应游戏时长
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    #如果输入正确,将时长记录到一个字典中,方便保存与更改
                    if ok:
                        timedict[1] = text
        elif sender == self.bt2:
                gamename = self.combobox2.currentText()
                gameid = game2idx.get(gamename)
                if gameid == None:
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
                    gamedict[2] = gamename
                    idxdict[2] = gameid
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    if ok:
                        timedict[2] = text
        elif sender == self.bt3:
                gamename = self.combobox3.currentText()
                gameid = game2idx.get(gamename)
                if gameid == None:
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
                    gamedict[3] = gamename
                    idxdict[3] = gameid
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    if ok:
                        timedict[3] = text
        elif sender == self.bt4:
                gamename = self.combobox4.currentText()
                gameid = game2idx.get(gamename)
                if gameid == None:
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
                    gamedict[4] = gamename
                    idxdict[4] = gameid
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    if ok:
                        timedict[4] = text
        elif sender == self.bt5:
                gamename = self.combobox5.currentText()
                gameid = game2idx.get(gamename)
                if gameid == None:
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
                    gamedict[5] = gamename
                    idxdict[5] = gameid
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    if ok:
                        timedict[5] = text 

(4) 验证数据是否输入完毕,以及准备调用模型

   def recommand(self):
        #验证是否存在没有写入的数据
        c = 0
        for i in range(1,6):
            if gamedict[i] == "NULL":
                c+=1
            if idxdict[i] == "NULL":
                c+=1
            if timedict[i] == "NULL":
                c+=1
        #全部写完的情况
        if c == 0:
            #将字典转化为列表
            usertime = list(timedict.values())
            useridx = list(idxdict.values())
            #调用模型
            allrecidx = UserSimilarity(useridx,usertime)
            #降序排列数据
            rr = np.argsort(-allrecidx)
            #获取排行前五的游戏ID
            top_k = rr[:5]
            #将ID对应的游戏名字输入数组
            for i in top_k:
                recgame.append(idx2game[i])
            #将数组转化为字符串并输出
            reclist = ','.join(recgame)
            reply = QMessageBox.information(self,'推荐的游戏','给您推荐的游戏是'+reclist, QMessageBox.Close)
        #存在没有写完的数据,要求重新写入
        else:
            reply = QMessageBox.information(self,'Error','请输入全部数据!', QMessageBox.Close)

2)模型导入及调用

相关操作如下:

(1)加载当前文件夹下的Save_data模型

game2idx = joblib.load('./Save_data/game2idx.pkl')
idx2game = joblib.load('./Save_data/idx2game.pkl')
rec = joblib.load('./Save_data/rec.pkl')
hours = joblib.load('./Save_data/hours.pkl')
buy = joblib.load('./Save_data/buy.pkl')
users = joblib.load('./Save_data/buyers.pkl')

(2)创建一个用户相似度函数,用于刻画Qt里收集到的数据与训练出的用户相似度最高的数据作为输出

def UserSimilarity(games, game_hours):
    similarity = np.zeros(len(users)) # 用户相似度矩阵
    for i in range(len(users)):
        #计算用户输入的游戏与数据集中每个用户购买游戏的重合度
        coincidence = 0 #重合度,每重合一个游戏加1
        positions = [] #重合游戏在games中的位置
        #获取数据集中的第i个玩家与用户输入的重合情况
        for ii in range(len(games)):
            if games[ii] in np.where(buy[users[i], :] == 1)[0]:
                coincidence += 1
                positions.append(ii)
        #如果没有重合,则相似度为0,跳过
        if coincidence == 0:
            continue
        simi = []
        #将重合的游戏,根据时长和相同游戏的时长差取绝对值,根据e^-x计算出相似度
        for position in positions:
            game = games[position]
            hour = abs(game_hours[position] - hours[users[i], game])
            simi.append(math.exp(-hour))
        #对所有相似度取均值,得到用户与数据集中第i个玩家的相似度similarity[i]
        similarity[i] = sum(simi) / coincidence
    #相似度与玩家—游戏矩阵每一行相乘
    for i in range(len(users)):
        user = users[i]
        rec[user] = rec[user] * similarity[i]
      new_rec = np.zeros(len(rec[0])) # 1*n_games矩阵
    #将玩家—游戏矩阵按列相加,得到用户对每个游戏的喜好程度,即new_rec矩阵
    for i in range(len(new_rec)):
        for user in users:
            new_rec[i] += rec[user][int(i)]
    return new_rec

3)模型应用代码

相关代码如下:

import joblib
import numpy as np
import pandas as pd
import math
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
#读取数据
game2idx = joblib.load('./Save_data/game2idx.pkl')
idx2game = joblib.load('./Save_data/idx2game.pkl')
rec = joblib.load('./Save_data/rec.pkl')
hours = joblib.load('./Save_data/hours.pkl')
buy = joblib.load('./Save_data/buy.pkl')
users = joblib.load('./Save_data/buyers.pkl')
#游戏名称列表
gamelist = list(game2idx)
#游戏数
n_game = len(gamelist)
#传入字典
gamedict = {1:"NULL",2:"NULL",3:"NULL",4:"NULL",5:"NULL"}
timedict = {1:"NULL",2:"NULL",3:"NULL",4:"NULL",5:"NULL"}
idxdict = {1:"NULL",2:"NULL",3:"NULL",4:"NULL",5:"NULL"}
#下面两个是要传递的
usertime=[]
useridx=[]
#下面是返回的推荐游戏
recgame=[]
#相似度推荐
def UserSimilarity(games, game_hours):
    similarity = np.zeros(len(users)) #用户相似度矩阵
    for i in range(len(users)):
        #计算用户输入的游戏与数据集中每个用户购买游戏的重合度
        coincidence = 0 #重合度
        positions = [] #重合游戏在games中的位置
        for ii in range(len(games)):
            if games[ii] in np.where(buy[users[i], :] == 1)[0]:
                coincidence += 1
                positions.append(ii)
        if coincidence == 0:
            continue
        simi = []
        for position in positions:
            game = games[position]
            hour = abs(game_hours[position] - hours[users[i], game])
            simi.append(math.exp(-hour))
        similarity[i] = sum(simi) / coincidence
    #相似度与玩家—游戏矩阵每一行相乘
    for i in range(len(users)):
        user = users[i]
        rec[user] = rec[user] * similarity[i]
        new_rec = np.zeros(len(rec[0])) #1*n_games矩阵
    for i in range(len(new_rec)):
        for user in users:
            new_rec[i] += rec[user][int(i)]
    return new_rec
class Recommandation(QWidget):
    #初始化
    def __init__(self):
        super().__init__()
        self.initUI()
    #初始化布局
    def initUI(self):
        #设置界面的初始位置和大小
        self.setGeometry(600,200,450,550)
        #窗口名
        self.setWindowTitle('steam游戏推荐')
        #设置组件,以下为标签
        self.lb1 = QLabel('请输入游戏名:',self)
        #这是所在位置
        self.lb1.move(20,20)
        self.lb2 = QLabel('请输入游戏名:',self)
        self.lb2.move(20,80)
        self.lb3 = QLabel('请输入游戏名:',self)
        self.lb3.move(20,140)
        self.lb4 = QLabel('请输入游戏名:',self)
        self.lb4.move(20,200)
        self.lb5 = QLabel('请输入游戏名:',self)
        self.lb5.move(20,260)
        #以下为下拉输入框的创建
        self.combobox1 = QComboBox(self, minimumWidth=200)
        self.combobox1.move(100,20)
        self.combobox1.setEditable(True)
        self.combobox2 = QComboBox(self, minimumWidth=200)
        self.combobox2.move(100,80)
        self.combobox2.setEditable(True)
        self.combobox3 = QComboBox(self, minimumWidth=200)
        self.combobox3.move(100,140)
        self.combobox3.setEditable(True)
        self.combobox4 = QComboBox(self, minimumWidth=200)
        self.combobox4.move(100,200)
        self.combobox4.setEditable(True)
         self.combobox5 = QComboBox(self, minimumWidth=200)
        self.combobox5.move(100,260)
        self.combobox5.setEditable(True)
        #以下为输入的按键设置
        self.bt1 = QPushButton('请输入游戏时间',self)
        self.bt1.move(330,20)
        self.bt2 = QPushButton('请输入游戏时间',self)
        self.bt2.move(330,80)
        self.bt3 = QPushButton('请输入游戏时间',self)
        self.bt3.move(330,140)
        self.bt4 = QPushButton('请输入游戏时间',self)
        self.bt4.move(330,200)
        self.bt5 = QPushButton('请输入游戏时间',self)
        self.bt5.move(330,260)
        #推荐按钮
        self.bt=QPushButton('推荐开始',self)
        self.bt.move(20,400)
        #初始化下拉输入框
        self.init_combobox()
        #连接按键与槽
        self.bt1.clicked.connect(self.timeDialog)
        self.bt2.clicked.connect(self.timeDialog)
        self.bt3.clicked.connect(self.timeDialog)
        self.bt4.clicked.connect(self.timeDialog)
        self.bt5.clicked.connect(self.timeDialog)
        #连接推荐
        self.bt.clicked.connect(self.recommand)
        #初始化下拉输入框   
    def init_combobox(self):
        #增加选项元素
        for i in range(len(gamelist)):
            self.combobox1.addItem(gamelist[i])
            self.combobox2.addItem(gamelist[i])
            self.combobox3.addItem(gamelist[i])
            self.combobox4.addItem(gamelist[i])
            self.combobox5.addItem(gamelist[i])
        self.combobox1.setCurrentIndex(-1)
        self.combobox2.setCurrentIndex(-1)
        self.combobox3.setCurrentIndex(-1)
        self.combobox4.setCurrentIndex(-1)
        self.combobox5.setCurrentIndex(-1)
        #增加自动补全
        self.completer = QCompleter(gamelist)
        #补全方式
        self.completer.setFilterMode(Qt.MatchStartsWith)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.combobox1.setCompleter(self.completer)
        self.combobox2.setCompleter(self.completer)
        self.combobox3.setCompleter(self.completer)
        self.combobox4.setCompleter(self.completer)
        self.combobox5.setCompleter(self.completer)
        def timeDialog(self):
        #获取信号
        sender = self.sender()
        if sender == self.bt1:
                #获取下拉输入框1输入的游戏名
                gamename = self.combobox1.currentText()
                #通过字典game2idx查询获得的游戏名所对应的序列号
                gameid = game2idx.get(gamename)
                #没有序列号的情况,可以理解为未输入正确的游戏名,或者输入为空
                if gameid == None:
                    #这种情况下生成一个MessageBox报错
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
             #输入正确的情况,将游戏名字、ID,分别记录到一个字典里,方便保存与更改
                    gamedict[1] = gamename
                    idxdict[1] = gameid
                    #弹出一个文本输入框,要求输入对应的游戏时长
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    #如果输入正确,将时长记录到一个字典中,方便保存与更改
                    if ok:
                        timedict[1] = text
        elif sender == self.bt2:
                gamename = self.combobox2.currentText()
                gameid = game2idx.get(gamename)
                if gameid == None:
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
                    gamedict[2] = gamename
                    idxdict[2] = gameid
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    if ok:
                        timedict[2] = text
        elif sender == self.bt3:
                gamename = self.combobox3.currentText()
                gameid = game2idx.get(gamename)
                if gameid == None:
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
                    gamedict[3] = gamename
                    idxdict[3] = gameid
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    if ok:
                        timedict[3] = text
        elif sender == self.bt4:
                gamename = self.combobox4.currentText()
                gameid = game2idx.get(gamename)
                if gameid == None:
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
                    gamedict[4] = gamename
                    idxdict[4] = gameid
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    if ok:
                        timedict[4] = text
        elif sender == self.bt5:
                gamename = self.combobox5.currentText()
                gameid = game2idx.get(gamename)
                if gameid == None:
                    reply = QMessageBox.information(self,'Error','请输入正确的游戏名!', QMessageBox.Close)
                else:
                    gamedict[5] = gamename
                    idxdict[5] = gameid
                    text, ok = QInputDialog.getDouble(self, '游戏时间', '请输入游戏时间:', min = 0.1)
                    if ok:
                        timedict[5] = text
               def recommand(self):
        #验证是否存在没有写入的数据
        c = 0
        for i in range(1,6):
            if gamedict[i] == "NULL":
                c+=1
            if idxdict[i] == "NULL":
                c+=1
            if timedict[i] == "NULL":
                c+=1
        #全部写完的情况
        if c == 0:
            #将字典转化为列表
            usertime = list(timedict.values())
            useridx = list(idxdict.values())
            #调用模型
            allrecidx = UserSimilarity(useridx,usertime)
            #降序排列数据
            rr = np.argsort(-allrecidx)
            #获取排行前五的游戏ID
            top_k = rr[:5]
            #将ID对应的游戏名字输入数组
            for i in top_k:
                recgame.append(idx2game[i])
            #将数组转化为字符串并输出
            reclist = ','.join(recgame)
            reply = QMessageBox.information(self,'推荐的游戏','给您推荐的游戏是'+reclist, QMessageBox.Close)
        #存在没有写完的数据,要求重新写入
        else:
            reply = QMessageBox.information(self,'Error','请输入全部数据!', QMessageBox.Close)
#主函数
if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Recommandation()
    w.show()
    sys.exit(app.exec_())

相关其它博客

基于矩阵分解算法的智能Steam游戏AI推荐系统——深度学习算法应用(含python、ipynb工程源码)+数据集(一)

基于矩阵分解算法的智能Steam游戏AI推荐系统——深度学习算法应用(含python、ipynb工程源码)+数据集(二)

基于矩阵分解算法的智能Steam游戏AI推荐系统——深度学习算法应用(含python、ipynb工程源码)+数据集(四)

工程源代码下载

详见本人博客资源下载页


其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

更多推荐

Java中的隐式转换和强制转换底层是怎么做的?

目录1.回顾数值型基本数据类型共有哪些?2.什么时候进行隐式类型转换?3.数据类型的隐式转换规则4.特殊隐式转换规则需牢记5.隐式转换小练习5.1byte与byte如何转?5.2int,long,double的转换5.3byte,short,long的转换6.强制转换如何转换?7.强制转换有哪些问题?1.回顾数值型基本

Windows如何删除“$WINDOWS.~BT“文件夹,解决权限不足无法删除

$WINDOWS.~BT是干嘛的$Windows.BT是升级或者安装Windows操作系统中间过程中产生的临时文件夹,一般用于保存下载后的升级文件,或者安装过程中复制文件时产生的。用于保存Windows安装记录,包括配置资料,错误报告等,如果安装失败便可反馈给微软公司,帮助用户解决安装过程中出现的问题。如果系统可正常运

GaussDB数据库SQL系列-表连接(JOIN)

目录一、前言二、GaussDBJOIN1、LEFTJOIN2、LEFTJOINEXCLUDINGINNERJOIN3、RIGHTJOIN4、LEFTJOINEXCLUDINGINNERJOIN5、INNERJOIN6、FULLOUTERJOIN7、FULLOUTERJOINEXCLUDINGINNERJOIN三、Gau

Intel汇编在VS下开发的环境配置

1.创建一个C/C++的空项目2.创建汇编源码文件,就是C++文件改后缀为asm3.在生成依赖项一栏中选择自定义4.选择masm5.在源文件上右击选择属性6.这么设置一下7.为了让代码看的更舒服一些,添加一些高亮插件8.安装AsmHighligher和AsmDude插件(非必须),其中前者主要是高亮配色(个人很喜欢这个

Android存储权限完美适配(Android11及以上适配)

一、Bug简述一个很普通的需求,需要下载图片到本地,我的三个测试机(荣耀Android10,红米11和小米Android13都没有问题)。然后,主角登场了,测试的三星Android13死活拉不起存储权限弹窗。想了下,三星的系统可能和小米的系统做了些区别。于是就是看了下存储权限的版本更迭,却是发现了些骚东西。二、原因很早

Java Script

初识JavaScriptJavaScript是什么?JavaScript(简称JS)是世界上最流行的编程语言之一是一个脚本语言,通过解释器运行主要在客户端(浏览器)上运行,现在也可以基于node.js在服务器端运行JavaScript最初只是为了完成简单的表单验证(验证数据合法性),结果后来不小心就火了.当前JavaS

Android 显示surfaceFlinger vsync 获取

文章目录vsync的概念vsync应用层获取的方式vsync信号传递vsync的概念vsync简单理解就是一帧图像在显示设备这边显示完成之后(图像从左上角扫描到了右下角了)发送的第一个硬件vsync信号,显示设备重新回到左上角开始显示的时候会在发第二个vsync信号。在发送第一个vsync信号出来的时候,上层要开始准备

IP归属地在金融行业的应用场景

IP归属地查询在各大行业当中的利用率可以说非常的高了,提供了各种的保障,比如安全保障、数据保障、性能保障等等。今天我就来详细说一说IP归属地在金融行业的应用场景有哪些?用途一:通过解析用户IP地址所处的区县位置与表单填写位置或者GPS位置进行交叉验证,判断位置是否一致;用途二:识别来自高危地区的IP地址,如缅甸、老挝;

【面试题】—— 笔试题(4题)

文章目录1.分割集合第一种方式:自己实现分割方法第二种方式:使用第三方依赖2.链表计算3.字符串计算4.找到相加为0的数字1.分割集合题目:编写一个Java函数,实现批量获取数据的功能(BService.get(Listids))。具体要求如下:1)提供一个函数BService.get(Listids),支持最多传入1

使用Jmeter+ant进行接口自动化测试(数据驱动)

最近在做接口测试,因为公司有使用jmeter做接口测试的相关培训资料,所以还是先选择使用jmeter来批量管理接口,进行自动化测试。话不多说,进入正题:1.使用csv文件保存接口测试用例,方便后期对接口进行维护(先新建txt文件,然后文件扩展名改为.csv,不要新建xls再改为csv,不然会出现读取不到文件的情况)注意

【C语言学习笔记---指针进阶02】

C语言程序设计笔记---017C语言进阶之回调函数1、函数指针数组2、回调函数3、回调函数的应用---qsort库函数4、模拟qsort函数5、结语C语言进阶之回调函数前言:通过C语言进阶前篇的指针进阶01的知识,继续学习。这篇引用一个简易计算器的程序进行深入学习指针进阶的知识。/知识点汇总/1、函数指针数组比如:指针

热文推荐