Python轻量级Web框架Flask(14)—— 自己做Flask项目总结

news2024/12/24 9:01:57

0、前言:

  • 本文意在记录自己在做毕业Flask项目开发时遇到的一些问题,并将问题解决方案记录下来,可做日后查询
  • 本文也会记录自己做FLask项目时实现的一些功能,作为开发工作的进程记录
  • 注意:用Flask开发的前提是已经设计好前端页面和后端数据库表的情况下,通过Flask进行前后端联合调试

1、项目路径问题:

  • 问题描述:在之前写好的html模板中调用了一些css样式,之前css和html在一个文件夹中直接调用就好了,但是在flask中,需要重新放在不同文件夹中,就需要用相对路径来调用了,项目开发最好都是写相对路径,方便别人在跑你代码的时候,不论别人把你项目放在哪个地方,都可以顺畅跑起路来。如下图,在“系统首页”代码中要访问“全局样式”,就需要写路径,方式有绝对路径和相对路径两种。
    在这里插入图片描述
  • 绝对路径:C:\Users\11252\Desktop\个性化交互式在线学习系统\App\static\css\全局样式.css
  • 相对路径:…/…/…/static/css/全局样式.css
  • 总结:相对路径中,一层 “ …/ ” 就意味着往外面走一层,直到走到包含你要引用的文件那一层,再写路径往下找。

2、css样式失效:

  • 解决方法:通过内联样式修改html代码,如下所示就是内联样式的写法。
<!-- 使用内联样式定义一个带有背景色和边框的div -->  
<div style="background-color: lightblue; border: 1px solid black; padding: 10px;">  
    这是一个使用内联样式定义的div,它有背景色、边框和内边距。  
</div> 

3、登陆页面登陆验证:

  • 实现逻辑:如果视图函数收到的是从服务器向前端请求数据的request请求,也就是GET请求,那么就通过rend_template返回网页模板,如果视图函数再次收到网页发送数据的request请求,也就是POST请求,那么就可以通过request拿到网页提交过来的表单数据(这里要注意,网页提交数据的请求是通过form表单中action属性连接到视图函数的,其中method属性要设置为post,autocompete属性设置为off就避免了自动填充内容)。通过request拿到前端页面提交的数据之后,再通过数据表查询的filter_by方法去用户表中核对账号和密码即可,核对上就表示登录成功,借助response变量重定向到首页,然后把cookie保存到response中,再返回即可。
  • 视图函数
# 登录页面
@blue.route('/user/login/', methods=['GET','POST'])
def user_login():
    if request.method == 'GET':
        return render_template('/user_0/登录页面.html')
    elif request.method == 'POST':
        user_account = request.form.get('user_account')
        user_password = request.form.get('user_password')
        # print(user_account,user_password)
        user = User.query.filter_by(user_account=user_account, user_password=user_password).first()
        if user:
            # 登录成功,将cookie保存到要返回给前端页面的响因中
            response = redirect('/user/index/')
            response.set_cookie('user_id', str(user.user_id), max_age=3*24*3600) # 设置cookie名,cookie值,cookie的有效期(秒作为单位)
            print(f'登录用户账号;{user.user_account}')
            return response
        else:
            return '输入户账号或密码错误!'
    else:
        return 'login failed'
  • 前端代码
<form action="/user/login/" method="post" autocomplete="off">
                <div>
                    <img src="../../../static/img/账户.png" alt="">
                    <input name="user_account" type="text" class="in" placeholder="请输入账号">
                </div>
                <div>
                    <img src="../../../static/img/密码.png" alt="">
                    <input name="user_password" type="password" class="in" placeholder="请输入密码">
                </div>
                <div class="b1">
                    <button type="submit">登录</button>
                </div>
                <div class="b2">
                    <a href="" style="width:300px; height: 50px;
                    font-size: 18px; color: #fff; border: none;">注册</a>
                </div>
            </form>
  • 效果图
    在这里插入图片描述
  • 总结:如果项目中登陆其他页面需要做登录验证,那么在开发这个项目的时候,应该先做登录功能,然后在登录成功后保存登录对象的cookie,然后再做退出登录功能删除cookie,然后其他页面需要登录验证的时候,只需要获取cookie即可,如果拿到cookie就说明该用户登录成功过,但是要注意cookie的值设置时必须是用户数据表的唯一字段,后续在做完登录验证后,在视图函数中还可以通过cookie去查询对应用户在用户数据表中的信息;从逻辑上来讲,系统启动后默认路径进入的应该是登陆页面。

4、在项目编辑过程中如何发现数据库缺少字段处理方式:

  • 1、在对应models文件中给对应数据表添加字段
  • 2、在终端该项目路径下执行:flask db migrate;flask db upgrade
  • 说明:这种修改方式会保存数据表中原有的数据的同时,给数据表添加字段

5、数据库外键查询报错问题

  • 我的理解:在models文件中只要把数据库外键和外键关联关系写对,如下所示:
# models文件中的内容

# 课程表
class Course(db.Model):
    # 表名
    __tablename__ = 'tb_course'
    # 字段
    course_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    course_name = db.Column(db.String(20), default='课程名')
    course_introduction = db.Column(db.Text(), default='课程介绍')
    # 与外键反向关联
    course_resources = db.relationship('Course_resources', backref='course', lazy='dynamic')

# 课程资源表
class Course_resources(db.Model):
    # 表名
    __tablename__ = 'db_c_resources'
    # 字段
    video_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    video_name = db.Column(db.String(30), default='视频名称')
    show_url = db.Column(db.String(100), default='封面链接')
    # 外键
    course_id = db.Column(db.Integer, db.ForeignKey(Course.course_id))

然后在视图函数中调用即可,如下面代码中,我想通过 课程表 去查与他关联的 课程资源表 ,结果就会出现报错,

# views文件中的内容

# 系统首页面
@blue.route('/user/index/')
def user_index():
    # 获取cookie,得到登录的用户
    user_id = request.cookies.get('user_id', None)
    if user_id:
        # 登陆过,查询用户信息,返回
        user = User.query.get(user_id)
        # 在课程表中查询信息
        course = Course.query.all()
        # 在资源表中查询信息(出错的地方!)
        print(f'{course[0].course_resources.show_url}')
        return render_template('/user_0/系统首页.html',
                               user = user,
                               hot_course = hot_course,
                               recommend_course = recommend_course)
    else:
        return redirect('/user/login/')

报错信息如下:
在这里插入图片描述
通过查询后得知:course_resources是数据表中的一个关系属性,它返回的是一个AppenderQuery对象,在SQLAIchemy中,当访问一个模型关系属性时,得到的是一个查询对象而不是结果集,需要进一步从查询对象当中执行查询来获取实际的资源对象,因此可以在course[0].course_resources后面使用 .all() 或 .first() 方法来获取所有资源或第一个资源。


6、在网页通过链接跳转传参

  • 本质上讲该问题就是在网页实现调用视图函数并传递参数给视图函数
    在这里插入图片描述

7、在jinja2模板语言中如何调用一个自增长的变量

  • 在jinja2的for循环当中有一个属性就是index,它会随着循环每次都增加1。
    在这里插入图片描述

8、如何导出一个项目的python环境,方便他人复现你的项目


9、★★★★★如何将训练好的机器学习或者深度学习模型嵌入Flask项目中实现调用。

9.1、模型部分调试记录

  • 1、首先把模型跑通,该模型是一个二分类模型,主要用于通过32个用户行为特征来预测用户学习风格属于二分类当中的哪一个。
# 1、构造模型
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense
from tensorflow.keras.callbacks import LearningRateScheduler

model = Sequential([
    Embedding(input_dim=900, output_dim=64, input_length=32),
    LSTM(units=128, return_sequences=True),
    LSTM(units=64),
    Dense(units=2, activation='softmax')
])


def lr_schedule(epoch):
    initial_lr = 0.001  # 初始学习率
    decay_factor = 0.5  # 学习率衰减因子
    decay_epochs = 5    # 学习率衰减的周期数
    new_lr = initial_lr * (decay_factor ** (epoch // decay_epochs))
    return new_lr

# 定义学习率回调
lr_scheduler = LearningRateScheduler(lr_schedule)
# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 打印模型概况
model.summary()

在这里插入图片描述

  • 2、通过数据预处理,把需要训练的数据第1类和第2类都划分为7:1.5:1.5,其中7成是训练数据,1.5成分别是测试数据和验证数据,然后再将这两部分7成部分打乱,1.5部分打乱,然后拼接在一起。最终保证总体训练集占比为7成,总体测试集和验证集占比分别是1.5成。
    在这里插入图片描述

  • 3、导入预处好的数据,划分好训练集、预测集、验证集

train_data = data.iloc[0:631,1:34]
val_data = data.iloc[631:768,1:34]
test_data = data.iloc[768:900,1:34]

# 划分数据集
X_train = train_data.iloc[:,0:32]
y_train = train_data.iloc[:,32]-1 # 后面进行one-hot 
X_val = val_data.iloc[:,0:32]
y_val= val_data.iloc[:,32]-1 # 后面进行one-hot 
X_test = test_data.iloc[:,0:32]
y_test = test_data.iloc[:,32]-1 # 后面进行one-hot 
  • 4、数据训练
# 假设你已经准备好了 train_data 和 train_labels 数据

# 进行标签的 one-hot 编码
from tensorflow.keras.utils import to_categorical
y_train_encoded = to_categorical(y_train, num_classes=2)
y_val_encoded = to_categorical(y_val, num_classes=2)
# 训练模型
batch_size = 12
epochs = 100

history = model.fit(X_train, y_train_encoded, batch_size=batch_size, epochs=epochs, validation_data=(X_val, y_val_encoded), callbacks=[lr_scheduler])
# history = model.fit(train_data, y_train_encoded, batch_size=batch_size, epochs=epochs, callbacks=[lr_scheduler])
# 注意:代码中的 history 中会保存训练过程的数据,后面要生成准确率变化图,损失率变化图,都得通过 history 获取。
  • 5、生成分类报告:查看模型分类能力如何
# 生成分类报告
from sklearn.metrics import classification_report

y_test_one_hot = to_categorical(y_test, num_classes=2)
# 在测试数据上进行预测
y_pred = model.predict(X_test)

# 将模型的预测结果转换为类别标签
y_pred_labels = tf.argmax(y_pred, axis=1)
y_test_labels = tf.argmax(y_test_one_hot, axis=1)  # tf.argmax 来计算 y_pred 中每行的最大值所在的列索引


# 生成分类报告
report = classification_report(y_test_labels, y_pred_labels)
print(report)

在这里插入图片描述

  • 6、保存模型:在这里遇到过保存路径直接写相对路径,就会报错的问题,最后通过导入os模块,解决了这个问题。
# 保存模型
import os

# 定义保存路径,确保路径存在
save_dir = './save_model'
if not os.path.exists(save_dir):
    os.makedirs(save_dir)

# 使用绝对路径,保存为 .keras 文件
model_save_path = os.path.abspath(os.path.join(save_dir, 'shijian_model.keras'))

# 保存模型
model.save(model_save_path)
  • 7、★加载模型
# 加载模型
loaded_model = tf.keras.models.load_model(model_save_path)
# 生成满足模型要求的数据(一组32列的二维数据,数据内容是从0-899随机的整数)
new_data = np.random.randint(900, size=[1,32])
# 用加载模型测试
result = loaded_model.predict(new_data)
print(result) # [[0.15184742 0.8481526 ]]
# 判断并生成最终结果
# 判断最后的值
if result[0][0] > result[0][1]:
    print('类型1')
else:
    print('类型2')
# 类型2
  • 补充:最后得到的模型可以用来做预测、可以用带标签的数据来评估模型、还可以继续输入训练数据来训练模型,训练好之后,还可以保存模型进入下一个迭代循环周期。
# 1、进行预测的代码示例
predictions = loaded_model.predict(new_data)

# 2、进行评估的代码示例
# 示例测试数据和标签
test_data = np.random.randint(900, size=(20, 32))  # 20个测试样本,每个样本长度为32
test_labels = np.random.randint(2, size=(20, 2))  # 20个测试样本对应的标签,假设是one-hot编码
# 评估模型
loss, accuracy = loaded_model.evaluate(test_data, test_labels)
# 打印评估结果
print(f'Loss: {loss}, Accuracy: {accuracy}')

# 3、用保存的代码继续训练的方法
import tensorflow as tf
import numpy as np
# 假设你有训练数据和标签
train_data = np.random.random((100, 32))  # 示例训练数据,假设形状为 (100, 32)
train_labels = np.random.randint(2, size=(100, 2))  # 示例训练标签,假设形状为 (100, 2)
# 加载已保存的模型
loaded_model = tf.keras.models.load_model('my_model.h5')
# 编译模型(如果需要)
loaded_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 继续训练模型
loaded_model.fit(train_data, train_labels, epochs=5)

9.2、项目中导入模型部分调试记录

  • 1、首先项目当中要调用模型的话,环境配置当中要有tensorflow库,而且一定要注意,通过下面代码查看下你训练模型时用到的tensorflow版本
import tensorflow as tf
print(tf.__version__)

我刚开始没有注意到这一点,就直接通过pycharm终端通过:pip install tensorflow ,给项目安装了一个tensorflow,结果,我安装的这个tensorflow是2.16.1的版本,然后,在视图函数中调用模型的时候,老是报错,我检查了我写的路径没有问题,折磨了我一下午,查看了我训练模型的tensorflow版本是2.14.0的,当我通过:pip uninstall tensorflow 从项目中卸载了2.16.1的版本,然后通过:pip install tensorflow==2.14.0 下载了与训练模型一致的版本后,问题迎刃而解。

  • 2、以下是对应的视图函数:
# 学习风格分类任务(写在这里可以作为参考,这个视图函数并不会被调用,这个功能写在了用户页面视图函数当中)
@blue.route('/user/classify/<int:user_id>')
def classify_model(user_id):
    print(tf.__version__)
    # 通过id获取到用户行为列表
    user = User.query.get(user_id)
    user_action = User_action.query.get(user_id)

    # 将用户行为列表转换为列表,作为学习风格分类模型的输入
    user_ac_list = []
    for i in range(32):
        ac = str(f'act{i+1}')
        # 如果直接写user_action.ac,程序不能把ac识别为上面的ac,因此要用到getattr函数,它可以基于字符串变量访问对象属性
        ac_value = getattr(user_action, ac)
        user_ac_list.append(ac_value)
    # print(user_ac_list)
    
    # 将输入数据格式调整为可以被模型识别的二维数据
    ac_array = np.array(user_ac_list)
    ac_array = ac_array.reshape((1,32))

    # 获取当前文件所在的目录
    base_dir = os.path.dirname(os.path.abspath(__file__))

    # 拼接模型文件的相对路径
    shijianmodel_save_path = os.path.join(base_dir,  'static', 'project_model', 'shijian_model.keras')
    jihuamodel_save_path = os.path.join(base_dir,  'static', 'project_model', 'jihua_model.keras')
    luojimodel_save_path = os.path.join(base_dir,  'static', 'project_model', 'luoji_model.keras')
    ganguanmodel_save_path = os.path.join(base_dir,  'static', 'project_model', 'ganguan_model.keras')

    # 加载保存的模型
    shijian_model = load_model(shijianmodel_save_path)
    jihua_model = load_model(jihuamodel_save_path)
    luoji_model = load_model(luojimodel_save_path)
    ganguan_model = load_model(ganguanmodel_save_path)

    # 通过模型结果判断学习风格
    shijian_result = shijian_model.predict(ac_array)
    jihua_result = jihua_model.predict(ac_array)
    luoji_result = luoji_model.predict(ac_array)
    ganguan_result = ganguan_model.predict(ac_array)

    print(shijian_result)
    user_style = ""
    if shijian_result[0][0] > shijian_result[0][1]:
        user_style += 'I' # 主动型
    else:
        user_style += 'R' # 反应型  

    if jihua_result[0][0] > jihua_result[0][1]:
        user_style += 'D' # 细节型
    else:
        user_style += 'O' # 全局型

    if luoji_result[0][0] > luoji_result[0][1]:
        user_style += 'R' # 理性型
    else:
        user_style += 'P' # 感性型

    if ganguan_result[0][0] > ganguan_result[0][1]:
        user_style += 'V' # 视觉型
    else:
        user_style += 'H' # 听觉型

    # 将结果存放到用户数据表
    user.user_style = user_style
    try:
        db.session.commit()
    except Exception as e:
        print(e)
        db.session.rollback()

    return redirect('/user/home/')

把模型嵌入到项目中的思路就是,在静态文件夹中新建一个project_model来存放训练好保存起来的模型,然后下载模型对应的第三方库,之后,按照正确路径加载模型,构建符合模型输入要求的输入数据,然后通过模型预测结果即可,从上面视图函数中看出,最后我还把模型预测结果通过修改数据表的方式,存放到了用户数据表当中。


总结:Flask就是一个带有组装规则的骨架,前端就是皮肤,后端就是内脏,通过Flask就能够把皮肤和内脏有效组合起来,而视图函数就是神经和血液,它能够帮助皮肤和内脏进行交互。读了三年研,最后也就是把自己麻麻赖赖一堆研究成果,想办法找个说法,组合起来,这个项目的完结,标志着我自己对自己能力的认可,我能够把自己想做的东西,通过代码实现出来,所以,从我的良心出发,我认为我达到了一个专硕的毕业标准,从初心而言,技术永远都是我的梦想,不论20岁,30岁,亦或是50岁。

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

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

相关文章

202009青少年软件编程(Python)等级考试试卷(三级)

第 1 题 【单选题】 通过算式123122021120可将二进制1101 转为十进制,下列进制转换结果正确的是?( ) A :0b10转为十进制,结果是2 B :0d10转为十进制,结果是8 C :0x10转为十进制,结果是10 D :0o10转为十进制,结果是16 正确答案:A 试题解析: 第 2 题 【单选题】 语句flo…

svn如何远程访问?

svn&#xff08;Subversion&#xff09;是一种版本控制系统&#xff0c;广泛应用于软件开发领域。它能够追踪文件和目录的变化&#xff0c;记录每个版本的修改内容&#xff0c;并允许多人协同开发。svn的远程访问功能允许开发人员可以在不同的地点访问和管理代码&#xff0c;提…

ES6之正则扩展

正则表达式扩展 u修饰符&#xff08;Unicode模式&#xff09;y修饰符&#xff08;Sticky或粘连模式&#xff09;s修饰符&#xff08;dotAll模式&#xff09;Unicode属性转义正则实例的flags属性字符串方法与正则表达式的整合 javascript的常用的正则表达式 验证数字邮箱验证手机…

华为OD机试 - CPU算力分配(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…

string的模拟全实现

文章目录 &#x1f4dd;前言&#x1f320; string的基本要素&#x1f309;构造函数和析构函数&#x1f320;string()&#x1f309;string(const char* str ""); &#x1f320;~string()&#x1f309;深拷贝string(const string& s); &#x1f320;三个成员函数的…

外网ip地址怎么获取?快解析

大家都清楚互联网是通过ip地址通信的&#xff0c;ip地址又分内网ip和外网ip。内网ip只能在内网使用&#xff1b;而外网ip作为电脑唯一标识&#xff0c;可在公网使用。那么外网ip地址怎么获取呢&#xff1f; 外网ip是网络运营商分配给用户的。目前最常见的两种上网方式一个是拉…

金航标kinghelm萨科微slkor公司发展和品牌传播

为了金航标kinghelm萨科微slkor公司发展和品牌传播&#xff0c;推出了”金航标每日芯闻“与“萨科微每日芯闻“栏目&#xff0c;影响力非常好。这一构想并非一时的灵光乍现&#xff0c;而是经过深思熟虑和充分调研的结果。制定该栏目的模板时候时&#xff0c;就明确了要求语音版…

【nfs服务部署服务端和客户端搭建】

原理 NFS&#xff08;Network File System&#xff09;是文件服务器之一。它的功能是可以通过网络&#xff0c;让不同的机器、不同的操作系统可以彼此共享数据文件。 NFS服务器可以让服务端的共享目录挂载到本地端的文件系统中&#xff0c;其他服务器如果想访问共享目录&#…

windows 安装 Conda

1 Conda简介 Conda 是一个开源的软件包管理系统和环境管理系统&#xff0c;用于安装多个版本的软件包及其依赖关系&#xff0c;并在它们之间轻松切换。Conda 是为 Python 程序创建的&#xff0c;适用于 Linux&#xff0c;OS X 和Windows&#xff0c;也可以打包和分发其他软…

键盘和鼠标的隐形观察者:用Python的pynput库记录每一个动作

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 揭秘pynput&#xff1a;监控神器还是隐私威胁&#xff1f; 在数字时代&#xff0c;的每一次键盘敲击和鼠标点击都可能泄露信息。但如果能够控制这一过程&#xff0c;又将如何利用这些数据呢&#xff1f;Python的pyn…

“Linux”目录结构and配置网络

了解完命令格式和vi、vim编辑器后&#xff0c;我们来认识一下目录的结构&#xff1a; 一、目录 &#xff08;1&#xff09;目录的特点 windows特点&#xff1a; Windows中有C、D、E盘&#xff0c;每个都是一个根系统 Linux特点&#xff1a; linux中只有一个根&#xff08;单…

【opencv】opencv透视变换和ocr识别实验

实验环境&#xff1a;anaconda、jupyter notebook 实验用到的包opencv、numpy、matplotlib、tesseract 一、opencv透视变换 原图 图片是我拍的耳机说明书&#xff0c;哈哈哈哈&#xff0c;你也可以使用自己拍的照片&#xff0c;最好是英文内容&#xff0c;tesseract默认识别英…

C++|多态性与虚函数(2)|虚析构函数|重载函数|纯虚函数|抽象类

前言 看这篇之前&#xff0c;可以先看多态性与虚函数&#xff08;1&#xff09;⬇️ C|多态性与虚函数&#xff08;1&#xff09;功能绑定|向上转换类型|虚函数-CSDN博客https://blog.csdn.net/weixin_74197067/article/details/138861418?spm1001.2014.3001.5501这篇文章会…

Kasawaki川崎机器人故障维修

在当今的自动化工业领域&#xff0c;川崎工业机器人以其卓越的性能和可靠的工作效率赢得了广泛的赞誉。作为机器人的核心组成部分&#xff0c;伺服电机的作用至关重要。然而&#xff0c;就像所有机械设备一样&#xff0c;也可能会遭遇电机磨损或故障&#xff0c;需要适时的川崎…

二叉树——初解

二叉树 树树的概念树的性质 二叉树二叉树的概念二叉树的性质二叉树的实现方式数组构建左孩子右兄弟法构建指针构建 树 树的概念 在计算机科学中&#xff0c;树&#xff08;Tree&#xff09;是一种重要的非线性数据结构&#xff0c;它由若干节点&#xff08;Node&#xff09;组…

iPhone15销量不佳,新产品没希望,苹果开始寻找库克接班人

美国媒体开始谈论谁将成为苹果的新CEO&#xff0c;这意味着苹果董事会开始为库克寻找接班人了&#xff0c;导致如此结果&#xff0c;可能在于iPhone15的表现实在太差了&#xff0c;而库克力推的vision Pro等新产品又没有为苹果打开局面所致。 如今的苹果倒是与1980年代乔布斯离…

壹资源知识付费系统源码-小程序端+pc端

最新整理优化&#xff0c;含微信小程序和pc网页。内置几款主题&#xff0c;并且可以自己更改主题样式&#xff0c;各区块颜色&#xff0c;文字按钮等。 适用于知识付费类资源类行业。如&#xff1a;项目类&#xff0c;小吃技术类&#xff0c;图书类&#xff0c;考研资料类&…

Nodejs 第七十一章(libuv)

libuv 在Node.js中&#xff0c;libuv是作为其事件循环和异步I/O的核心组件而存在的。Node.js是构建在libuv之上的&#xff0c;它利用libuv来处理底层的异步操作&#xff0c;如文件I/O、网络通信和定时器等。 libuv在Node.js中扮演了以下几个重要角色&#xff1a; 事件循环&a…

同为科技详解智能PDU所应用的通信协议与接口

现如今&#xff0c;信息服务、AI人工智能的飞速发展与增长&#xff0c;全球正经历信息数据的爆炸。不仅数据量以惊人的速度增长&#xff0c;而且全球社会各行业对数据的依赖的程度也在日益增加。这些趋势使数据中心在全球都享有关键基础架构的地位。假设某个数据中心发生严重的…