基于大数据+Hadoop的豆瓣电子图书推荐系统设计和实现

博主介绍全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作

主要内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。

🍅文末获取源码联系🍅

👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟

2022-2024年最全的计算机软件毕业设计选题大全:1000个热门选题推荐✅

Java项目精品实战案例《100套》

Java微信小程序项目实战《100套》

感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人

 

一、前言介绍:

       随着信息技术的飞速发展,特别是互联网和移动通信技术的普及,数字化阅读逐渐成为人们获取知识和信息的重要方式。在这样的背景下,电子图书以其便捷性和丰富性受到了广泛欢迎。随着电子图书市场的不断扩大,书籍的种类和数量也在急剧增加,这为用户挑选书籍带来了挑战。为了解决信息过载的问题,个性化推荐系统应运而生,并逐渐成为在线阅读平台不可或缺的一部分。基于用户历史行为数据进行推荐的协同过滤算法尤为流行。处理庞大的用户群体和海量的图书数据需要强大的计算能力,传统的单机计算模式已无法满足需求。Hadoop作为一个开源的分布式计算平台,以其高容错性、高扩展性和对大数据处理的优秀能力,成为大数据分析的首选工具。因此,利用Hadoop来构建电子图书推荐系统,不仅可以有效处理和分析大规模数据集,提升推荐质量,还能保证系统的可扩展性和稳定性。

      基于Hadoop的豆瓣电子图书推荐系统的研究与实现能够为用户提供更加精准和个性化的阅读推荐,从而优化用户体验,提高用户满意度和平台黏性。通过分析用户的历史阅读行为和偏好,系统可以发现用户的阅读模式,进而推荐更符合个人兴趣的书籍,帮助用户节省筛选时间,增强阅读效率。对于电子图书平台来说,一个高效的推荐系统可以促进更多优质内容的分发,增加用户流量和书籍销量,从而带动平台的经济效益。该系统的建立还有助于推动数据挖掘和机器学习技术在实际应用中的发展,为相关领域提供宝贵的实践经验和研究成果。最后,随着数据处理技术的不断进步,该研究还可以为未来电子图书推荐系统的改进提供理论基础和技术支持,具有长远的研究和应用价值。

二、功能设计:

系统的功能设计是整个系统的运行基础,是一个把设计需求替换成以计算机系统的形式表示出来。通过对豆瓣电子图书推荐系统的调查、分析和研究,得出了该系统的总体规划,这是开发设计系统的初步核心。如下图所示:

爬虫数据集展示:

三、功能实现:

当人们打开系统的网址后,首先看到的就是首页界面。在这里,人们能够看到系统的导航条,通过导航条导航进入各功能展示页面进行操作。系统首页界面如图5-1所示:

在注册流程中,用户在Vue前端填写必要信息(如用户名、密码等)并提交。前端将这些信息通过HTTP请求发送到Java后端。后端处理这些信息,检查用户名是否唯一,并将新用户数据存入MySQL数据库。完成后,后端向前端发送注册成功的确认,前端随后通知用户完成注册。这个过程实现了新用户的数据收集、验证和存储。注册页面如图5-2所示:

图5-2注册详细页面

豆瓣高分:在豆瓣高分页面的输入栏中输入书名、作者、出版社和标签进行查询,可以查看到豆瓣高分详细信息,并进行评论或收藏操作;豆瓣高分页面如图5-3所示:

图5-3豆瓣高分详细页面

个人中心:在个人中心页面可以对个人中心、修改密码、我的发布、我的收藏等进行详细操作;如图5-4所示:

在登录流程中,用户首先在Vue前端界面输入用户名和密码。这些信息通过HTTP请求发送到Java后端。后端接收请求,通过与MySQL数据库交互验证用户凭证。如果认证成功,后端会返回给前端,允许用户访问系统。这个过程涵盖了从用户输入到系统验证和响应的全过程。如图5-5所示。 

用户管理功能在视图层(view层)进行交互,比如点击“查询、添加或删除”按钮或填写用户信息表单。这些用户表单动作被视图层捕获并作为请求发送给相应的控制器层(controller层)。控制器接收到这些请求后,调用服务层(service层)以执行相关的业务逻辑,例如验证输入数据的有效性和与数据库的交互。服务层处理完这些逻辑后,进一步与数据访问对象层(DAO层)交互,后者负责具体的数据操作如查看、修改或删除用户信息,并将操作结果返回给控制器。最终,控制器根据这些结果更新视图层,以便用户功能可以看到最新的信息或相应的操作反馈。如图5-7所示:

图5-7用户管理界面

豆瓣高分管理功能在视图层(view层)进行交互,比如点击“查询、添加、删除或爬取数据”按钮或填写豆瓣高分信息表单。这些豆瓣高分表单动作被视图层捕获并作为请求发送给相应的控制器层(controller层)。控制器接收到这些请求后,调用服务层(service层)以执行相关的业务逻辑,例如验证输入数据的有效性和与数据库的交互。服务层处理完这些逻辑后,进一步与数据访问对象层(DAO层)交互,后者负责具体的数据操作如查看、修改、查看评论或删除豆瓣高分信息,并将操作结果返回给控制器。最终,控制器根据这些结果更新视图层,以便豆瓣高分功能可以看到最新的信息或相应的操作反馈。如图5-8所示:

图5-8豆瓣高分管理界面

管理员进行爬取数据后,点击主页面右上角的看板,可以查看到系统简介、书名、作者统计、价格统计、出版社、评分统计、豆瓣高分总数、豆瓣高分信息等实时的分析图进行可视化管理;如图5-9所示:

图5-9看板界面

四、库表设计:

表4-11豆瓣高分

字段名称

类型

长度

字段说明

主键

默认值

id

bigint

主键

主键

addtime

timestamp

创建时间

bookname

varchar

200

书名

author

varchar

200

作者

cover

longtext

4294967295

封面

laiyuan

varchar

200

来源

wordcount

int

字数

salesprice

double

价格

chuban

varchar

200

出版社

tags

varchar

200

标签

mulu

longtext

4294967295

章节目录

rating

double

评分

thumbsupnum

int

0

crazilynum

int

0

clicktime

datetime

最近点击时间

clicknum

int

点击次数

0

discussnum

int

评论数

0

storeupnum

int

收藏数

0

五、关键代码:

# # -*- coding: utf-8 -*-

# 数据爬取文件

import scrapy
import pymysql
import pymssql
from ..items import DianzitushuItem
import time
from datetime import datetime,timedelta
import datetime as formattime
import re
import random
import platform
import json
import os
import urllib
from urllib.parse import urlparse
import requests
import emoji
import numpy as np
import pandas as pd
from sqlalchemy import create_engine
from selenium.webdriver import ChromeOptions, ActionChains
from scrapy.http import TextResponse
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
# 电子图书
class DianzitushuSpider(scrapy.Spider):
    name = 'dianzitushuSpider'
    spiderUrl = 'https://read.douban.com/j/kind/'
    start_urls = spiderUrl.split(";")
    protocol = ''
    hostname = ''
    realtime = False


    def __init__(self,realtime=False,*args, **kwargs):
        super().__init__(*args, **kwargs)
        self.realtime = realtime=='true'

    def start_requests(self):

        plat = platform.system().lower()
        if not self.realtime and (plat == 'linux' or plat == 'windows'):
            connect = self.db_connect()
            cursor = connect.cursor()
            if self.table_exists(cursor, '0n4b129m_dianzitushu') == 1:
                cursor.close()
                connect.close()
                self.temp_data()
                return
        pageNum = 1 + 1

        for url in self.start_urls:
            if '{}' in url:
                for page in range(1, pageNum):

                    next_link = url.format(page)
                    yield scrapy.Request(
                        url=next_link,
                        callback=self.parse
                    )
            else:
                yield scrapy.Request(
                    url=url,
                    callback=self.parse
                )

    # 列表解析
    def parse(self, response):
        _url = urlparse(self.spiderUrl)
        self.protocol = _url.scheme
        self.hostname = _url.netloc
        plat = platform.system().lower()
        if not self.realtime and (plat == 'linux' or plat == 'windows'):
            connect = self.db_connect()
            cursor = connect.cursor()
            if self.table_exists(cursor, '0n4b129m_dianzitushu') == 1:
                cursor.close()
                connect.close()
                self.temp_data()
                return
        data = json.loads(response.body)
        try:
            list = data["list"]
        except:
            pass
        for item in list:
            fields = DianzitushuItem()


            try:
                fields["title"] = emoji.demojize(self.remove_html(str( item["title"] )))

            except:
                pass
            try:
                fields["picture"] = emoji.demojize(self.remove_html(str( item["cover"] )))

            except:
                pass
            try:
                fields["salesprice"] = float( item["salesPrice"]/100)
            except:
                pass
            try:
                fields["wordcount"] = int( item["wordCount"])
            except:
                pass
            try:
                fields["author"] = emoji.demojize(self.remove_html(str(','.join(str(i['name']) for i in  item["author"]) )))

            except:
                pass
            try:
                fields["biaoqian"] = emoji.demojize(self.remove_html(str( item.get("biaoqian", "小说") )))

            except:
                pass
            try:
                fields["detailurl"] = emoji.demojize(self.remove_html(str('https://read.douban.com'+ item["url"] )))

            except:
                pass
            detailUrlRule = item["url"]

            if '["url"]'.startswith('http'):
                if '{0}' in '["url"]':
                    detailQueryCondition = []
                    detailUrlRule = '["url"]'
                    i = 0
                    while i < len(detailQueryCondition):
                        detailUrlRule = detailUrlRule.replace('{' + str(i) + '}', str(detailQueryCondition[i]))
                        i += 1
            else:
                detailUrlRule =item["url"]

            detailUrlRule ='https://read.douban.com'+ detailUrlRule

            if detailUrlRule.startswith('http') or self.hostname in detailUrlRule:
                pass
            else:
                detailUrlRule = self.protocol + '://' + self.hostname + detailUrlRule
                fields["laiyuan"] = detailUrlRule
            yield scrapy.Request(url=detailUrlRule, meta={'fields': fields}, callback=self.detail_parse)

    # 详情解析
    def detail_parse(self, response):
        fields = response.meta['fields']
        try:
            if '(.*?)' in '''span[itemprop="genre"]::text''':
                fields["genre"] = str( re.findall(r'''span[itemprop="genre"]::text''', response.text, re.S)[0].strip())

            else:
                if 'genre' != 'xiangqing' and 'genre' != 'detail' and 'genre' != 'pinglun' and 'genre' != 'zuofa':
                    fields["genre"] = str( self.remove_html(response.css('''span[itemprop="genre"]::text''').extract_first()))

                else:
                    try:
                        fields["genre"] = str( emoji.demojize(response.css('''span[itemprop="genre"]::text''').extract_first()))

                    except:
                        pass
        except:
            pass
        try:
            fields["chubanshe"] = str( response.xpath('''//span[text()="出版社"]/../span[@class="labeled-text"]/span[1]/text()''').extract()[0].strip())

        except:
            pass
        try:
            fields["cbsj"] = str( response.xpath('''//span[text()="出版社"]/../span[@class="labeled-text"]/span[2]/text()''').extract()[0].strip())

        except:
            pass
        try:
            if '(.*?)' in '''a[itemprop="provider"]::text''':
                fields["provider"] = str( re.findall(r'''a[itemprop="provider"]::text''', response.text, re.S)[0].strip())

            else:
                if 'provider' != 'xiangqing' and 'provider' != 'detail' and 'provider' != 'pinglun' and 'provider' != 'zuofa':
                    fields["provider"] = str( self.remove_html(response.css('''a[itemprop="provider"]::text''').extract_first()))

                else:
                    try:
                        fields["provider"] = str( emoji.demojize(response.css('''a[itemprop="provider"]::text''').extract_first()))

                    except:
                        pass
        except:
            pass
        try:
            if '(.*?)' in '''span.score::text''':
                fields["score"] = float( re.findall(r'''span.score::text''', response.text, re.S)[0].strip())
            else:
                if 'score' != 'xiangqing' and 'score' != 'detail' and 'score' != 'pinglun' and 'score' != 'zuofa':
                    fields["score"] = float( self.remove_html(response.css('''span.score::text''').extract_first()))
                else:
                    try:
                        fields["score"] = float( emoji.demojize(response.css('''span.score::text''').extract_first()))
                    except:
                        pass
        except:
            pass
        try:
            if '(.*?)' in '''span.amount::text''':
                fields["pingjiashu"] = int( re.findall(r'''span.amount::text''', response.text, re.S)[0].strip().replace('评价',''))
            else:
                if 'pingjiashu' != 'xiangqing' and 'pingjiashu' != 'detail' and 'pingjiashu' != 'pinglun' and 'pingjiashu' != 'zuofa':
                    fields["pingjiashu"] = int( self.remove_html(response.css('''span.amount::text''').extract_first()).replace('评价',''))
                else:
                    try:
                        fields["pingjiashu"] = int( emoji.demojize(response.css('''span.amount::text''').extract_first()).replace('评价',''))
                    except:
                        pass
        except:
            pass
        return fields

    # 数据清洗
    def pandas_filter(self):
        engine = create_engine('mysql+pymysql://root:123456@localhost/spider0n4b129m?charset=UTF8MB4')
        df = pd.read_sql('select * from dianzitushu limit 50', con = engine)

        # 重复数据过滤
        df.duplicated()
        df.drop_duplicates()

        #空数据过滤
        df.isnull()
        df.dropna()

        # 填充空数据
        df.fillna(value = '暂无')

        # 异常值过滤

        # 滤出 大于800 和 小于 100 的
        a = np.random.randint(0, 1000, size = 200)
        cond = (a<=800) & (a>=100)
        a[cond]

        # 过滤正态分布的异常值
        b = np.random.randn(100000)
        # 3σ过滤异常值,σ即是标准差
        cond = np.abs(b) > 3 * 1
        b[cond]

        # 正态分布数据
        df2 = pd.DataFrame(data = np.random.randn(10000,3))
        # 3σ过滤异常值,σ即是标准差
        cond = (df2 > 3*df2.std()).any(axis = 1)
        # 不满⾜条件的⾏索引
        index = df2[cond].index
        # 根据⾏索引,进⾏数据删除
        df2.drop(labels=index,axis = 0)

    # 去除多余html标签
    def remove_html(self, html):
        if html == None:
            return ''
        pattern = re.compile(r'<[^>]+>', re.S)
        return pattern.sub('', html).strip()

    # 数据库连接
    def db_connect(self):
        type = self.settings.get('TYPE', 'mysql')
        host = self.settings.get('HOST', 'localhost')
        port = int(self.settings.get('PORT', 3306))
        user = self.settings.get('USER', 'root')
        password = self.settings.get('PASSWORD', '123456')

        try:
            database = self.databaseName
        except:
            database = self.settings.get('DATABASE', '')

        if type == 'mysql':
            connect = pymysql.connect(host=host, port=port, db=database, user=user, passwd=password, charset='utf8')
        else:
            connect = pymssql.connect(host=host, user=user, password=password, database=database)
        return connect

    # 断表是否存在
    def table_exists(self, cursor, table_name):
        cursor.execute("show tables;")
        tables = [cursor.fetchall()]
        table_list = re.findall('(\'.*?\')',str(tables))
        table_list = [re.sub("'",'',each) for each in table_list]

        if table_name in table_list:
            return 1
        else:
            return 0

    # 数据缓存源
    def temp_data(self):

        connect = self.db_connect()
        cursor = connect.cursor()
        sql = '''
            insert into `dianzitushu`(
                id
                ,title
                ,picture
                ,salesprice
                ,wordcount
                ,author
                ,biaoqian
                ,detailurl
                ,genre
                ,chubanshe
                ,cbsj
                ,provider
                ,score
                ,pingjiashu
            )
            select
                id
                ,title
                ,picture
                ,salesprice
                ,wordcount
                ,author
                ,biaoqian
                ,detailurl
                ,genre
                ,chubanshe
                ,cbsj
                ,provider
                ,score
                ,pingjiashu
            from `0n4b129m_dianzitushu`
            where(not exists (select
                id
                ,title
                ,picture
                ,salesprice
                ,wordcount
                ,author
                ,biaoqian
                ,detailurl
                ,genre
                ,chubanshe
                ,cbsj
                ,provider
                ,score
                ,pingjiashu
            from `dianzitushu` where
                `dianzitushu`.id=`0n4b129m_dianzitushu`.id
            ))
            order by rand()
            limit 50;
        '''

        cursor.execute(sql)
        connect.commit()
        connect.close()

六、论文参考:

 

七、其他案例: 

 

八、推荐项目:

基于微信小程序+Springboot线上租房平台设计和实现-三端

2022-2024年最全的计算机软件毕业设计选题大全

基于Java+SpringBoot+Vue前后端分离手机销售商城系统设计和实现

基于Java+SpringBoot+Vue前后端分离仓库管理系统设计实现

基于SpringBoot+uniapp微信小程序校园点餐平台详细设计和实现

基于Java+SpringBoot+Vue+echarts健身房管理系统设计和实现

基于JavaSpringBoot+Vue+uniapp微信小程序实现鲜花商城购物系统

基于Java+SpringBoot+Vue前后端分离摄影分享网站平台系统 

基于Java+SpringBoot+Vue前后端分离餐厅点餐管理系统设计和实现

基于Python热门旅游景点数据分析系统设计与实现

九、源码获取:

 大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻

 精彩专栏推荐订阅下方专栏👇🏻

2022-2024年最全的计算机软件毕业设计选题大全:1000个热门选题推荐✅

Java项目精品实战案例《100套》

Java微信小程序项目实战《100套》

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux学习:多媒体开发库SDL+视频、音频、事件子系统+处理yuv视频源

目录 编译和移植 视频子系统 视频子系统产生图像的步骤 api 初始化 SDL 的相关子系统 使用指定的宽、高和色深来创建一个视窗 surface 使用 fmt 指定的格式创建一个像素点​编辑 将 dst 上的矩形 dstrect 填充为单色 color​编辑 将 src 快速叠加到 dst 上​编辑 更新…

sqli-labs 第十七关

目录 找注入点&#xff1a; 源码分析&#xff1a; 测试&#xff1a; 奇怪现象&#xff1a; &#xff08;1&#xff09;&#xff1a;当我们输入的密码为字符进行注入时。 &#xff08;2&#xff09;&#xff1a;当我们输入的密码为整数时。 产生原因&#xff1a; 解决方法…

Docker:docker在项目中常用的一些命令

简介   Docker 是一个开源的容器化平台&#xff0c;它允许开发者将应用程序及其依赖项打包到一个可移植的容器中&#xff0c;并发布到任何安装了 Docker 引擎的机器上。这些容器是轻量级的&#xff0c;包含了应用程序运行所需的所有东西&#xff0c;如代码、系统库、系统工具…

SpringBoot集成Redis环境搭建及配置详解

前言 Redis作为当前最火的NoSQL数据库&#xff0c;支持很多语言客户端操作Redis。 而SpringBoot作为java当前最火的开发框架&#xff0c;提供了Spring-data-redis框架实现对Redis的各种操作。 在springboot1.5.x版本的默认的Redis客户端都是Jedis实现的&#xff0c;springboot…

大模型时代下两种few shot高效文本分类方法

介绍近年(2022、2024)大语言模型盛行下的两篇文本分类相关的论文&#xff0c;适用场景为few shot。两种方法分别是setfit和fastfit&#xff0c;都提供了python的包使用方便。 论文1&#xff1a;Efficient Few-Shot Learning Without Prompts 题目&#xff1a;无需提示的高效少…

浪潮信息企业级存储逆势增长 市场份额位列中国前二

2023年&#xff0c;中国企业级存储市场竞争激烈&#xff0c;在挑战重重之下&#xff0c;浪潮信息仍然实现逆势增长&#xff0c;销售额增幅达4.7%&#xff0c;市场份额相比2022年扩大0.6%&#xff0c;位列中国前二。另外&#xff0c;在高端和全闪存阵列细分市场&#xff0c;浪潮…

Vue3实战Easy云盘(三):文件删除+文件移动+目录导航+上传优化/文件过滤/搜索

一、文件删除 &#xff08;1&#xff09;选中了之后才可以删除&#xff0c;没有选中时就显示暗调删除按钮 &#xff08;2&#xff09;实现选中高亮功能 &#xff08;3&#xff09;单个删除 &#xff08;4&#xff09;批量删除 Main.vue中 <!-- 按钮3 --><!-- 如果sel…

鸿蒙内核源码分析(用户态锁篇) | 如何使用快锁Futex(上)

快锁上下篇 鸿蒙内核实现了Futex&#xff0c;系列篇将用两篇来介绍快锁&#xff0c;主要两个原因: 网上介绍Futex的文章很少&#xff0c;全面深入内核介绍的就更少&#xff0c;所以来一次详细整理和挖透。涉及用户态和内核态打配合&#xff0c;共同作用&#xff0c;既要说用户…

【Linux】文件描述符和重定向

目录 一、回顾C文件 二、系统文件I/O 2.1 系统调用 open 2.2 标志位传参 2.3 系统调用 write 2.4 文件描述符fd 2.5 struct file 2.6 fd的分配规则 2.7 重定向 2.7.1 基本原理&#xff1a; 2.7.2 系统调用 dup2 2.8 标准错误 一、回顾C文件 文件 内容 属性 对…

3分钟,学会一个 Lambda 小知识之【流API】

之前给大家介绍的 Lambda 小知识还记得吗&#xff1f;今天再来给大家介绍&#xff0c; 流API 的相关知识要点。 流API Stream是Java8中处理集合的关键抽象概念&#xff0c;它可以指定你对集合的&#xff0c;可以执行查找、过滤和映射等数据操作。 Stream 使用一种类似用 SQ…

资料如何打印更省钱

在日常工作和学习中&#xff0c;我们经常需要打印各种资料。然而&#xff0c;随着打印成本的不断提高&#xff0c;如何更省钱地打印资料成为了大家关注的焦点。今天&#xff0c;就为大家分享一些资料打印的省钱技巧&#xff0c;并推荐一个省钱又省心的打印平台。 首先&#xff…

冥想的时候怎么专注自己

冥想的时候怎么专注自己&#xff1f;我国传统的打坐养生功法&#xff0c;实际最早可追溯到五千年前的黄帝时代。   每天投资两个半小时的打坐&#xff0c;有上千年之久的功效。因为当你们打坐进入永恒时&#xff0c;时间停止了。这不只是两个半小时&#xff0c;而是百千万亿年…

深入探讨黑盒测试:等价类划分与边界值分析

文章目录 概要黑盒测试等价类划分边界值分析 设计测试用例小结 概要 在软件开发领域&#xff0c;测试是确保产品质量的关键步骤之一。而黑盒测试方法作为其中的一种&#xff0c;通过关注输入与输出之间的关系&#xff0c;而不考虑内部实现的细节&#xff0c;被广泛应用于各种软…

使用git系统来更新FreeBSD ports源码

FreeBSD跟其它系统相比一大特色就是ports系统。 The Ports Collection is a set of Makefiles, patches, and description files. Each set of these files is used to compile and install an individual application on FreeBSD, and is called a port. By default, the Po…

5 款免费好用的精品软件推荐!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 1.系统优化软件 - Wise Care 365 Wise Care 365 -全球最快的系统优化软件&#xff01;精简系统、管理启动项、清理和优化注册表、清理个人隐私…

基于51单片机的冰箱控制系统设计( proteus仿真+程序+设计报告+原理图+讲解视频)

基于51单片机冰箱控制系统设计( proteus仿真程序设计报告原理图讲解视频&#xff09; 基于51单片机冰箱控制系统设计 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单&&下载链接资料下载链接&#xff1a; …

Debian mariadb 10.11 XXXX message from server: “Too many connections“

问题表现 报错信息&#xff1a;Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections" 处理步骤 1、尝试能不能通过终端登录&…

从头理解transformer,注意力机制(下)

交叉注意力 交叉注意力里面q和KV生成的数据不一样 自注意力机制就是闷头自学 解码器里面的每一层都会拿着编码器结果进行参考&#xff0c;然后比较相互之间的差异。每做一次注意力计算都需要校准一次 编码器和解码器是可以并行进行训练的 训练过程 好久不见输入到编码器&…

SpringBoot中@Value注入失败

首先&#xff0c;不支持static的 解决&#xff1a;使用setter方法进行属性的赋值,并且setter方法不能有static 生成set/get方法就可以了&#xff0c;然后Value 放在set上

《系统架构设计师教程(第2版)》第10章-软件架构的演化和维护-07-软件架构维护

文章目录 1. 软件架构知识管理1.1 概念1.2 架构知识的获取1.3 作用1.4 架构知识管理的现状 2 软件架构修改管理3 软件架构版本管理4. 示例4.1 背景4.2 数据获取4.3 数据计算4.4 结果分析4.4.1 圈复杂度 (CCN)4.4.2 扇入扇出度 (FFC)4.4.3 模块间耦合度 (CBO)4.4.4 模块的响应 (…