QTableWidget 中insertRow(0)(头插)和 insertRow(rowCount())(尾插)的性能差异
一、目的
在 Qt 的 QTableWidget
中,insertRow(0)
(头插)和 insertRow(rowCount())
(尾插)在性能上存在显著差异。
二、QAbstractItemModel:: insertRows 原文解释
QAbstractItemModel Class | Qt Core 5.15.18
AI 解释
QAbstractItemModel:: insertRows
是 Qt 模型/视图框架中用于在模型中插入行的一个虚函数。以下是对该函数的详细解释,包括其功能、参数、返回值以及如何正确实现自定义模型中的插入操作。
函数声明
[virtual] bool QAbstractItemModel::insertRows(int row, int count, const QModelIndex &parent = QModelIndex())
功能概述
insertRows
函数用于在模型中指定位置插入一行或多行数据。具体来说,它会在给定的 row
位置之前插入 count
行新数据。这些新行将成为由 parent
模型索引表示的父项的子项。
参数说明
-
int row
指定插入行的位置。如果row
为0
,新行将被插入到父项的最前面;如果row
等于rowCount(parent)
,新行将被追加到父项的最后面。 -
int count
要插入的行数。可以一次性插入多行数据。 -
const QModelIndex &parent = QModelIndex()
表示插入行的父索引。如果parent
是无效索引(默认值),则插入的行将成为顶级行(即没有父项)。否则,新行将作为parent
所表示的父项的子项插入。
返回值
-
bool
返回true
表示插入操作成功;返回false
表示插入操作失败。
注意事项
- 基类实现
QAbstractItemModel
的基类实现是空的,直接调用会返回false
。因此,如果你的自定义模型需要支持插入行的操作,必须重写(reimplement)此函数。 - 通知机制
在实际插入数据之前和之后,必须调用beginInsertRows
和endInsertRows
函数。这两个函数用于通知视图和其他相关组件模型数据的变化,以确保界面能够正确更新。 - 实现逻辑
当重写insertRows
时,除了调用beginInsertRows
和endInsertRows
来通知变化外,还需要在内部数据结构中实际插入新的数据行。
示例代码
以下是一个简单的自定义模型中重写 insertRows
的示例:
#include <QAbstractItemModel>
#include <QModelIndex>
#include <QVariant>
#include <QList>class MyModel : public QAbstractItemModel {Q_OBJECTpublic:// 构造函数和其他必要的成员函数...// 重写 insertRows 函数bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override {// 开始插入操作的通知beginInsertRows(parent, row, row + count - 1);// 在内部数据结构中插入新行if (!parent.isValid()) {// 插入顶级行for (int i = 0; i < count; ++i) {m_data.insert(row, QVariant()); // 假设 m_data 是 QList<QVariant>}} else {// 插入子行(假设父项有子项列表)MyItem *parentItem = static_cast<MyItem*>(parent.internalPointer());if (parentItem) {parentItem->appendChildItems(count); // 假设有相应的方法添加子项}}// 结束插入操作的通知endInsertRows();return true; // 插入成功}// 其他必要的虚函数实现...private:QList<QVariant> m_data; // 示例数据结构,实际应用中可能更复杂
};
详细解释
-
调用
beginInsertRows
beginInsertRows(parent, row, row + count - 1);
这个函数通知所有连接到模型的视图,即将在
parent
父索引下的row
到row + count - 1
位置插入新行。这使视图能够预先调整其布局和缓冲区,以适应即将到来的数据变化。 -
修改内部数据结构
根据parent
是否有效,决定是插入顶级行还是子行:- 顶级行:直接在
m_data
列表的指定位置插入新数据。 - 子行:通过
parent
获取对应的父项对象,并调用相应的方法在父项下插入新的子项。
- 顶级行:直接在
-
调用
endInsertRows
endInsertRows();
这个函数通知视图插入操作已完成,视图可以更新显示新的数据行。
-
返回值
返回true
表示插入操作成功。如果插入过程中出现错误,可以返回false
,但通常需要提供适当的错误处理机制。
使用场景
- 动态添加数据:当用户通过界面按钮或其他方式请求添加新行时,模型通过
insertRows
插入新数据。 - 批量插入:一次性插入多行数据,提高效率。
- 层级结构:在树形结构模型中,为特定父项插入子行。
性能考虑
- 通知开销:频繁调用
beginInsertRows
和endInsertRows
可能导致性能下降。因此,应尽量批量插入数据,而不是逐行插入。 - 数据结构的效率:确保内部数据结构支持高效的插入操作。例如,使用链表可以快速在头部插入,而动态数组在尾部插入更高效。
总结
QAbstractItemModel::insertRows
是实现自定义模型时用于插入新行的关键函数。通过正确重写此函数,并结合 beginInsertRows
和 endInsertRows
的通知机制,可以确保模型数据的动态变化能够正确反映在关联的视图上,同时保持良好的性能和用户体验。
三、QTableWidget::insertRow(int row) 源码
路径
- Qt\5.15.2\Src\qtbase\src\widgets\itemviews\qtablewidget. cpp
- Qt\5.15.2\Src\qtbase\src\widgets\itemviews\qtablewidget_p.h
代码解析
void QTableWidget::insertRow(int row)
{Q_D(QTableWidget);d->tableModel()->insertRows(row);
}bool QTableModel::insertRows(int row, int count, const QModelIndex &)
{if (count < 1 || row < 0 || row > verticalHeaderItems.count())return false;beginInsertRows(QModelIndex(), row, row + count - 1);int rc = verticalHeaderItems.count();int cc = horizontalHeaderItems.count();verticalHeaderItems.insert(row, count, 0);if (rc == 0)tableItems.resize(cc * count);elsetableItems.insert(tableIndex(row, 0), cc * count, 0);endInsertRows();return true;
}class QTableModel : public QAbstractTableModel
{Q_OBJECTfriend class QTableWidget;.....
private:const QTableWidgetItem *prototype;QVector<QTableWidgetItem*> tableItems;QVector<QTableWidgetItem*> verticalHeaderItems;QVector<QTableWidgetItem*> horizontalHeaderItems;// A cache must be mutable if get-functions should have const modifiersmutable QModelIndexList cachedIndexes; };
从这段代码可以看出,QTableWidget
的插入行操作实际上是通过其内部的 QTableModel
来实现的,具体步骤包括:
- 插入表头项:
verticalHeaderItems.insert(row, count, 0);
- 插入表格数据项:
- 如果当前表格没有行 (
rc == 0
),则直接调整tableItems
的大小。 - 否则,在指定位置插入新的数据项,
tableItems.insert(tableIndex(row, 0), cc * count, 0);
- 如果当前表格没有行 (
性能差异分析
1. 性能差异的核心原因
头插 (insertRow(0)
)
- 表头项操作:
verticalHeaderItems.insert(row, count, 0)
在QVector
头部插入元素,需要将后续所有元素向后移动,时间复杂度为 O (n)(n 为当前行数)。 - 表格数据操作:
tableItems.insert(tableIndex(row, 0), cc * count, 0)
在数据数组头部插入新元素,同样需要移动后续所有数据,时间复杂度为 O (n * m)(m 为列数)。 - 视图更新:
触发beginInsertRows
和endInsertRows
,通知视图重新计算所有行的位置,导致界面重绘开销较大。
尾插 (insertRow(rowCount())
)
- 表头项操作:
在QVector
尾部追加元素,时间复杂度为 O (1)(假设预分配了足够内存)。 - 表格数据操作:
- 若表格为空,通过
tableItems.resize(cc * count)
初始化内存(O (1))。 - 若表格非空,直接追加到
QVector
末尾(O (1))。
- 若表格为空,通过
- 视图更新:
视图仅需扩展显示区域,渲染开销更低。
2. 插入操作的时间复杂度
- 尾插 (
insertRow(rowCount())
):- 表头项插入:在
QVector
的末尾插入元素,时间复杂度为 O(1)。 - 表项数据插入:如果表格为空,仅需调整大小;否则,由于是在末尾插入,
QVector::insert
在有预留空间的情况下也是 O(1)。但如果有重新分配内存的需求,可能会涉及到 O(n) 的复制操作,但这种情况在尾部插入时较少发生。
- 表头项插入:在
- 头插 (
insertRow(0)
):- 表头项插入:在
QVector
的开头插入元素,需要移动所有现有元素,时间复杂度为 O(n)。 - 表项数据插入:同样,在开头插入需要移动所有现有的数据项,时间复杂度为 O(n)。如果表格较大,这种移动操作的开销会显著增加。
- 表头项插入:在
3. 实际性能影响
- 数据量较小:
- 当表格中的行数较少(例如几十行)时,头插和尾插的性能差异可能不明显,用户几乎感觉不到延迟。
- 数据量较大:
- 当表格包含数千行甚至更多行时,头插操作由于需要频繁移动大量元素,会导致明显的性能下降,甚至可能造成界面卡顿或响应延迟。
- 尾插操作由于主要在末尾添加元素,性能相对稳定,几乎不受插入次数的影响。
4. 内存与缓存的影响
- 内存重新分配:
QVector
在插入元素时,如果当前容量不足以容纳新元素,会进行内存重新分配和元素复制。头插操作由于频繁移动元素,可能更频繁地触发内存重新分配,增加开销。
- 缓存局部性:
- 尾插操作更有利于 CPU 缓存的利用,因为新元素通常被添加到内存的连续区域。而头插操作打乱了数据的连续性,导致缓存命中率降低,进一步影响性能。
5. 实际性能对比
操作类型 | 时间复杂度 | 内存移动次数 | 适用场景 | 性能影响 |
---|---|---|---|---|
头插 | O(n) | 高(n 次移动) | 按倒序插入少量数据 | 高(避免频繁使用) |
尾插 | O(1) | 低(尾部追加) | 常规数据追加、大规模插入 | 低(推荐优先使用) |
- 小数据量场景(如数十行):两者差异可忽略。
- 大数据量场景(如数万行): - 头插单行耗时可能是尾插的 10 倍以上(因需移动全部数据)。 - 尾插性能稳定,适合高频插入操作。
四、 示例测试
以下是一个使用 QElapsedTimer
和 QTableWidget
测试 insertRow(0)
(头插)和 insertRow(rowCount())
(尾插)性能差异的完整示例代码。代码通过批量插入数据并测量时间,直观展示两者的性能差距:
#include <QApplication>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QElapsedTimer>
#include <QTimer>
#include <QDebug>// 测试函数:插入指定行数到表格的头部或尾部
void testInsertPerformance(QTableWidget* table, int rowCount, const QString& testName) {table->clearContents();table->setRowCount(0);// 禁用视图更新以提高测试准确性table->setUpdatesEnabled(false);QElapsedTimer timer;timer.start();for (int i = 0; i < rowCount; ++i) {int row = (testName == "Head Insert") ? 0 : table->rowCount();table->insertRow(row);table->setItem(row, 0, new QTableWidgetItem(QString("Name %1").arg(i)));table->setItem(row, 1, new QTableWidgetItem(QString::number(i)));table->setItem(row, 2, new QTableWidgetItem(QString("City %1").arg(i % 10)));}auto elapsed_ms = timer.elapsed();table->setUpdatesEnabled(true); // 恢复视图更新qDebug() << testName << "Performance:";qDebug() << " Time elapsed:" << elapsed_ms << "ms";qDebug() << " Time elapsed:" << elapsed_ms << "ms";qDebug() << " Memory used:" << table->sizeHint().height() * sizeof(QTableWidgetItem*) / 1024.<< "KB";qDebug() << " Memory used:" << table->sizeHint().width() * sizeof(QTableWidgetItem*) / 1024.<< "KB";
}int main(int argc, char* argv[]) {QApplication a(argc, argv);// 创建测试表格(3列)QTableWidget table;table.setColumnCount(3);table.setHorizontalHeaderLabels({ "Name", "Age", "City" });table.resize(600, 400);table.show();
#if 1// 测试头插性能(插入100000行)testInsertPerformance(&table, 100000, "Head Insert");// 等待用户操作后测试尾插性能QTimer::singleShot(2000, [&]() {testInsertPerformance(&table, 100000, "Tail Insert");});
#else//测试尾插性能testInsertPerformance(&table, 100000, "Tail Insert");// 等待用户操作后测试头插性能QTimer::singleShot(2000, [&]() {testInsertPerformance(&table, 100000, "Head Insert");});
#endifreturn a.exec();
}
代码解析与测试结果
1. 核心逻辑
- 禁用视图更新:通过
setUpdatesEnabled(false)
暂停界面刷新,避免渲染开销干扰时间测量。 - 批量插入数据:循环插入指定行数,每行包含姓名、年龄、城市三列数据。
- 时间测量:使用
QElapsedTimer
记录插入操作的耗时。 - 内存估算:通过
sizeHint().height()
估算表格占用的内存(粗略计算)。
2. 测试结果示例
操作类型 | 插入行数 | 耗时(ms) | 内存占用(KB) | |
---|---|---|---|---|
头插 | 100,000 | 9,224 | 1.5 | |
尾插 | 100,000 | 2509 | 1.5 | |
注:实际结果可能因硬件和 Qt 版本略有差异,但头插耗时通常比尾插高 。
性能差异原因
-
头插 (
insertRow(0)
):- 数据移动:
QVector
在头部插入元素需移动后续所有元素,时间复杂度为 O(n)。 - 内存重新分配:频繁插入导致内存多次重新分配,增加开销。
- 数据移动:
-
尾插 (
insertRow(rowCount())
):- 尾部追加:
QVector
在尾部插入元素时间复杂度为 O(1)(预分配内存时)。 - 内存连续性:数据连续存储,缓存命中率高。
- 尾部追加:
优化建议
- 预分配内存:若已知数据量,提前调用
table->setRowCount(rowCount)
预分配内存。 - 改用自定义模型:对超大数据集,使用
QAbstractTableModel
替代QTableWidget
,通过虚拟化技术减少内存占用。
五、 优化建议
基于上述分析,以下是一些优化建议:
-
优先使用尾插:
- 如果业务逻辑允许,尽量使用
insertRow(rowCount())
进行尾插操作,以获得更好的性能表现。
- 如果业务逻辑允许,尽量使用
-
批量插入:
- 如果需要插入多行,尽量一次性批量插入,而不是逐行插入。例如,先收集所有需要插入的数据,然后调用一次
setRowCount
。
// 示例:批量插入多行 tableWidget->setRowCount(10000); for (int i = 0; i < 10000; ++i) {// 填充数据 }
- 如果需要插入多行,尽量一次性批量插入,而不是逐行插入。例如,先收集所有需要插入的数据,然后调用一次
-
使用模型/视图架构:
- 如果需要频繁进行插入、删除等操作,考虑直接使用
QAbstractTableModel
或其子类QStandardItemModel
,而不是QTableWidget
。QAbstractTableModel
提供了更高的灵活性和性能优化空间,尤其是在处理大规模数据时。 - 对于超大数据集,推荐使用
QTableView
+ 自定义QAbstractTableModel
/QStandardItemModel
,通过虚拟化技术减少内存和渲染开销。例如:
class CustomTableModel : public QAbstractTableModel {// 实现 data()、rowCount()、columnCount() 等虚函数 }; QTableView *tableView = new QTableView; tableView->setModel(new CustomTableModel); // 或者 tableView->setModel(new QStandardItemModel);
- 如果需要频繁进行插入、删除等操作,考虑直接使用
-
延迟更新:
- 若必须头插,可先禁用视图更新(
setUpdatesEnabled(false)
),插入多行后再统一刷新界面:
tableWidget->setUpdatesEnabled(false); for (int i = 0; i < 100; ++i) {tableWidget->insertRow(0); // 批量头插 } tableWidget->setUpdatesEnabled(true);
- 在进行大量插入操作前,可以暂时禁用视图的更新,操作完成后再恢复。这可以通过
setUpdatesEnabled(false)
和setUpdatesEnabled(true)
实现,但需要注意处理好数据的一致性。
tableWidget->setUpdatesEnabled(false); // 执行批量插入操作 tableWidget->setUpdatesEnabled(true);
- 若必须头插,可先禁用视图更新(
-
懒加载技术:
- 仅在可见区域加载数据,结合滚动事件动态插入行(参考 QT 懒加载技术 的
UpdateAlarmList
实现):
void AlarmCenter::wheelEvent(QWheelEvent *event) {// 根据滚动条位置动态加载数据int visibleRows = tableViewHeight / rowHeight;int startRow = currentRow - visibleRows / 2;UpdateAlarmList(startRow, visibleRows); }
- 仅在可见区域加载数据,结合滚动事件动态插入行(参考 QT 懒加载技术 的
-
性能对比总结:
指标 | 头插 | 尾插 |
---|---|---|
时间复杂度 | O (n)(数据移动) | O (1)(尾部追加) |
内存操作 | 高(频繁重新分配和复制) | 低(预分配或追加) |
界面渲染 | 高(全表重绘) | 低(仅扩展区域) |
适用场景 | 倒序插入少量数据 | 常规追加、大规模插入 |
总结
- 头插 (
insertRow(0)
):- 性能较低,尤其是在数据量较大时,由于需要在开头插入元素,导致所有现有元素需要移动,时间复杂度为 O(n)。
- 尾插 (
insertRow(rowCount())
):- 性能较高,在末尾插入元素通常为 O(1),即使有内存重新分配,也相对高效。
因此,在使用 QTableWidget::insertRow
时,尾插性能远优于头插,应优先考虑尾插操作,以获得更好的性能表现。如果业务逻辑确实需要频繁进行头插操作,建议重新评估设计,或者考虑使用更适合频繁插入删除操作的模型/视图架构(如 QAbstractTableModel
)配合自定义的数据结构优化性能。
相关文章:
QTableWidget 中insertRow(0)(头插)和 insertRow(rowCount())(尾插)的性能差异
一、目的 在 Qt 的 QTableWidget 中,insertRow(0) (头插)和 insertRow(rowCount())(尾插)在性能上存在显著差异。 二、QAbstractItemModel:: insertRows 原文解释 QAbstractItemModel Class | Qt Core 5.15.18 AI 解…...
使用MFC ActiveX开发KingScada控件(OCX)
最近有个需求,要在KingScada上面开发一个控件。 原来是用的WinCC,WinCC本身是支持调用.net控件,就是winform控件的,winform控件开发简单,相对功能也更丰富。奈何WinCC不是国产的。 话说KingScada,国产组态软…...
大模型学习二:DeepSeek R1+蒸馏模型组本地部署与调用
一、说明 DeepSeek R1蒸馏模型组是基于DeepSeek-R1模型体系,通过知识蒸馏技术优化形成的系列模型,旨在平衡性能与效率。 1、技术路径与核心能力 基础架构与训练方法 DeepSeek-R1-Zero:通过强化学习(RL)训练&…...
通过 Markdown 改进 RAG 文档处理
通过 Markdown 改进 RAG 文档处理 作者:Tableau 原文地址:https://zhuanlan.zhihu.com/p/29139791931 通过 Markdown 改进 RAG 文档处理https://mp.weixin.qq.com/s/LOBOKNA71dANXHuwxe7yxw 如何将 PDF 转换为 Markdown 以获得更好的 LLM RAG 结果 Mar…...
Java学习总结-IO流
什么IO流? 以内存为主体。input:磁盘向内存输入内容。output:内存向磁盘输入内容。 IO流的分类:...
python发送qq邮件
1.发送邮件的前提是你的qq邮箱设置能够用程序访问 这个服务点打开 就在 设置->账号 中 可以找到 # 导入 smtplib 库,用于实现 SMTP 协议,可实现邮件的发送功能 import smtplib # 从 email.mime.multipart 模块导入 MIMEMultipart 类,用…...
使用Deployment运行无状态应用
使用Deployment运行无状态应用 文章目录 使用Deployment运行无状态应用[toc]一、工作负载资源与控制器二、ReplicationController、ReplicaSet和Deployment1. ReplicationController(已淘汰)2. ReplicaSet(ReplicationController 的增强版&am…...
QT Quick(C++)跨平台应用程序项目实战教程 6 — 弹出框
目录 1. Popup组件介绍 2. 使用 上一章内容完成了音乐播放器程序的基本界面框架设计。本小节完成一个简单的功能。单击该播放器顶部菜单栏的“关于”按钮,弹出该程序的相关版本信息。我们将使用Qt Quick的Popup组件来实现。 1. Popup组件介绍 Qt 中的 Popup 组件…...
Design Compiler:库特征分析(ALIB)
相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 简介 在使用Design Compiler时,可以对目标逻辑库进行特征分析,并创建一个称为ALIB的伪库(可以被认为是缓存)&…...
2025高频面试设计模型总结篇
文章目录 设计模型概念单例模式工厂模式策略模式责任链模式 设计模型概念 设计模式是前人总结的软件设计经验和解决问题的最佳方案,它们为我们提供了一套可复用、易维护、可扩展的设计思路。 (1)定义: 设计模式是一套经过验证的…...
41. 评论日记
越复杂的结构越脆弱,你不能因为有智驾有只能,你就全交给它了,手机永久了还发热呢,你全交给它那你要死了也怪不了谁。 这年头的手机基本都有防水,但是你天天拿着这个在泳池里玩,哪天炸了我都只能说炸的响炸的…...
Python第七章09:自定义python包.py
# 自定义python包# 从物理上看,包就是一个文件夹,在该文件夹下包含了一个_init_.py文件,该文件夹可用于包含多个模块文件 # 从逻辑上看,包的本质依然是模块 # _init_.py 标识python包,没有就是普通文件夹࿰…...
基于大模型预测升主动脉瘤的多维度诊疗研究报告
目录 一、引言 1.1 研究背景 1.2 研究目的与意义 二、升主动脉瘤概述 2.1 定义与分类 2.2 发病原因与机制 2.3 流行病学现状 三、大模型技术原理及应用现状 3.1 大模型基本原理 3.2 在医疗领域的应用进展 3.3 针对升主动脉瘤预测的独特价值 四、术前大模型预测方案…...
Lua中table函数使用详解
目录 1. table.concat(list [, sep [, i [, j]]])2. table.insert(list, [pos,] value)3. table.move(src, a, b, dest [, dest_pos]) (Lua 5.3)4. table.pack(...) (Lua 5.2)5. table.remove(list [, pos])6. table.sort(list [, comp])7. table.unpack(list [, i [, j]])总结…...
如何在Windows上找到Python安装路径?两种方法快速定位
原文:如何在Windows上找到Python安装路径?两种方法快速定位 | w3cschool笔记 在 Windows 系统上找到 Python 的安装路径对于设置环境变量或排查问题非常重要。本文将介绍两种方法,帮助你找到 Python 的安装路径:一种是通过命令提…...
图形库 EasyX - EasyX 初识(EasyX 概述、EasyX 下载与安装、打开一个窗口、打开一个彩色窗口、绘制简易图形、输出文字)
一、EasyX 概述 EasyX 是一款专为 C 开发者设计的轻量级图形库,主要面向 Windows 平台,它有如下特点 EasyX 的 API 设计简洁直观,易学易用,绘图效果所见即所得 二、EasyX 下载与安装 1、EasyX 下载 官方网址:https…...
《深度探秘:SQL助力经典Apriori算法实现》
在数据的广袤世界里,隐藏着无数有价值的信息,等待着我们去挖掘和发现。关联规则挖掘算法,作为数据挖掘领域的关键技术,能够从海量数据中找出事物之间潜在的关联关系,为商业决策、学术研究等诸多领域提供有力支撑。其中…...
AVR128单片机红外遥控8*8LED点阵屏显示
1)将接收到的红外解码信号用LCD液晶显示屏显示。 2)将接收到的5种红外解码信号分别控制88的液晶点阵屏MATRIX-88-GREEN (颜色可以自定)进行不同的显示:整行从上到下、从下到上轮流显示;整列从左到右、从右到左轮流显示;…...
前端Uniapp接入UviewPlus详细教程!!!
相信大家在引入UviewPlusUI时遇到很头疼的问题,那就是明明自己是按照官网教程一步一步的走,为什么到处都是bug呢?今天我一定要把这个让人头疼的问题解决了! 1.查看插件市场 重点: 我们打开Dcloud插件市场搜素uviewPl…...
【c++深入系列】:类与对象详解(中)
🔥 本文专栏:c 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 不是因为看到希望才坚持,而是坚持了才能看到希望 那么上一篇博客我讲解了什么是类和对象以及类和对象是怎么定义的࿰…...
【Linux】远程登录时,使用图形界面报错:MoTTY X11 proxy: Unsupported authorisation protocol
1、问题描述 使用 MobaXterm 远程登录Ubuntu后,使用sudo权限运行图形界面程序报错: MoTTY X11 proxy: Unsupported authorisation protocol (gpartedbin:10518): Gtk-WARNING **: 22:01:34.377: cannot open display: localhost:10.02、查看SSH配置 修改 SSH 服务端配置,…...
作用域与上下文:JavaScript魔法森林探秘
在JavaScript的魔法森林里,作用域和上下文是两位神秘的守护者,它们掌控着代码的逻辑流向和变量的生杀大权。今天,就让我们一起踏入这片神奇的土地,揭开全局作用域、函数作用域和闭包的神秘面纱,看它们如何影响我们的代…...
虚拟电商-话费充值业务(五)充值成功逻辑和网络异常重试逻辑
一、网络异常重试逻辑编写 如果在对接供应商的过程中出现了网络异常,我们需要做一个补偿机制,在任务类型枚举类:TaskTypeEnum中有一种业务状态码是针对远程调用失败的 步骤一:在对接供应商的方法:SupplierServiceImp…...
42.评论日记
怎么看待算命? 我能算到你今晚睡觉前会上一次厕所。 你可以选择相信我算的内容,也可以不信。 你也可以有感觉要上厕所的时候不去拉兜里。 也可以选择相信,早早的拿好纸做准备。 你今晚可能不止上一次,也可能今晚没吃没喝早早…...
MTK-GMS版本国内WIFI受限问题
MTK-GMS版本国内WIFI受限问题解决 文章目录 问题参考资料解决方案方案一 修改配置坑点 方案二 直接修改属性 问题 最近负责ROOM 产品,出现WIFI受限显示,但是网络是通畅的。 GMS 版本,在国外或者国内翻墙网络不会出现WIFI受限显示问题&#…...
C# System.Text.Json 中 JsonConverter 使用详解
总目录 前言 在 C# 开发中,System.Text.Json 是一个高性能的 JSON 处理库,广泛用于序列化和反序列化对象。当默认的序列化行为无法满足需求时,JsonConverter 提供了强大的自定义能力。本文将详细讲解 JsonConverter 的使用方法,帮…...
Leetcode 857 -- 贪心 | 数学
题目描述 雇佣 K 名工人的最低成本 思路 参考官方题解和这里。 代码1(正确) class Solution { public:double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int k) {int n wage.size();double res 0, totalq …...
基于 SpringBoot 的社区维修平台
收藏关注不迷路!! 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,还有大家在毕设选题(免费咨询指导选题),项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多…...
maven项目添加第三方JAR包
项目开发过程中,不可避免的需要用到一些maven库(公共库、司库等)中没有的冷门jar包依赖,这时,可以将这些第三方JAR包安装到本地maven仓库中,实现项目依赖的一致性。具体步骤如下: 1、下载jar包 …...
C#:接口(interface)
目录 接口的核心是什么? 1. 什么是接口(Interface),为什么要用它? 2. 如何定义和使用接口? 3.什么是引用接口? 如何“引用接口”? “引用接口”的关键点 4. 接口与抽象类的区…...
c#和c++脚本解释器科学运算
说明: 我希望用c#和c写一个脚本解释器,用于科学运算 效果图: step1: c# C:\Users\wangrusheng\RiderProjects\WinFormsApp3\WinFormsApp3\Form1.cs using System; using System.Collections.Generic; using System.Data; using System.Tex…...
2025年嵌入式大厂春招高频面试真题及解析
以下是 2025 年嵌入式大厂春招高频面试真题及解析,结合真题分类和核心知识点整理: 一、C/C++编程基础 1.1 指针与内存 野指针的成因及避免方法(未初始化、释放后未置空) malloc与calloc的区别(后者自动初始化为0) 指针与数组的区别(内存分配方…...
【C++】nlohmann::json 配置加载技术实践:从基础到高级应用
一、nlohmann::json 库概况与核心特性 nlohmann::json 是 C 社区最受欢迎的 JSON 库之一,其设计理念简洁即美,通过单头文件实现完整的 JSON 解析、序列化和操作功能。 1.1 基本特性 nlohmann::json是一个现代C编写的开源JSON库,采用MIT协议…...
ngx_regex_init
定义在 src\core\ngx_regex.c void ngx_regex_init(void) { #if !(NGX_PCRE2)pcre_malloc ngx_regex_malloc;pcre_free ngx_regex_free; #endif } NGX_PCRE21 #if !(NGX_PCRE2) 就为假 条件不成立 ngx_regex_init 函数就成了空实现 NGX_PCRE2 被定义,则表示 Ngin…...
【前端扫盲】postman介绍及使用
Postman 是一款专为 API 开发与测试设计的 全流程协作工具,程序员可通过它高效完成接口调试、自动化测试、文档管理等工作。以下是针对程序员的核心功能介绍和应用场景说明: 一、核心功能亮点 接口请求构建与调试 支持所有 HTTP 方法(GET/POS…...
Lua中os模块函数使用详解
目录 os.clock()os.date([format [, time]])os.difftime(t2, t1)os.execute(command)os.exit([code [, close]])os.getenv(varname)os.remove(filename)os.rename(oldname, newname)os.setlocale(locale [, category])os.time([table])os.tmpname()总结 以下是 Lua 中 os 模块的…...
量子计算与经典计算的拉锯战:一场关于计算未来的辩论
在计算科学领域,一场关于未来的激烈辩论正在上演。2025年3月,D-Wave量子公司的研究人员在《Science》杂志上发表了一项突破性成果,声称他们的量子退火处理器在几分钟内解决了一个经典超级计算机需要数百万年才能完成的复杂现实问题。这一声明…...
MySQL 基础入门
写在前面 关于MySQL的下载安装和其图形化软件Navicat的下载安装,网上已经有了很多的教程,这里就不再赘述了,本文主要是介绍了关于MySQL数据库的基础知识。 MySQL数据库 MySQL数据库基础 MySQL数据库概念 MySQL 数据库: 是一个关系型数据库管理系统 。 支持SQL语…...
GPT模型搭建
GPT模型搭建 1. 章节介绍 本章节聚焦于从0搭建GPT模型,通过事先准备的基础代码,引导学习者逐步构建模型。旨在让程序员、软件架构师和工程师等掌握GPT模型搭建的核心流程,理解其关键组件与技术细节,为实际应用和面试做好准备。 …...
BUUCTF-web刷题篇(8)
17.EasyCalcS 查看源码,发现有段代码有php文件,即calc.php 经过代码审计之后应该要访问calc.php文件,打开后: <?php error_reporting(0); if(!isset($_GET[num])){show_source(__FILE__); }else{$str $_GET[num];$blackli…...
AI SEO内容优化指南:如何打造AI平台青睐的高质量内容
AI SEO内容优化指南:如何打造AI平台青睐的高质量内容 在生成式AI平台(如DeepSeek、Kimi、豆包、腾讯元宝等)主导的搜索新时代,内容优化已成为企业抢占流量入口的核心策略。本文将从内容创作、分发到效果维护全链路,解…...
无需预对齐即可消除批次效应,东京大学团队开发深度学习框架STAIG,揭示肿瘤微环境中的详细基因信息
生物组织是由多种类型细胞构成的复杂网络,这些细胞通过特定的空间配置执行重要功能。近年来,10x Visium、Slide-seq、Stereo-seq 和 STARmap 等空间转录组学 (ST) 技术的进步,使得生物学家们能够在空间结构内绘制基因数据,从而各类…...
B2B2C多用户商城系统:打造新零售电商生态的创新解决方案
在当今数字化时代,电商行业正以前所未有的速度蓬勃发展,而新零售作为电商与传统零售的深度融合,正逐渐成为市场的新宠。为了满足这一变革带来的多元化需求,B2B2C多用户商城系统应运而生,为商家和消费者搭建了一个高效、…...
走向多模态AI之路(二):多模态 AI 如何工作?
目录 前言一、跨模态对齐(Cross-modal Alignment):AI 如何理解不同模态的关系二、多模态融合(Multimodal Fusion):AI 如何整合不同模态的信息三、多模态生成(Multimodal Generation)…...
MCP 实战:实现server端,并在cline调用
本文动手实现一个简单的MCP服务端的编写,并通过MCP Server 实现成绩查询的调用。 一、配置环境 安装mcp和uv, mcp要求python版本 Python >3.10; pip install mcppip install uv 二、编写并启用服务端 # get_score.py from mcp.server.fastmcp import…...
C#游戏开发【第18天】 | 深入理解队列(Queue)与栈(Stack):从基础到任务队列实战
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...
2.5路径问题专题:LeetCode 64. 最小路径和
动态规划解决最小路径和问题 1. 题目链接 LeetCode 64. 最小路径和 2. 题目描述 给定一个包含非负整数的 m x n 网格 grid,从网格的左上角出发,每次只能向右或向下移动一步,最终到达右下角。要求找到一条路径,使得路径上的数字…...
办公设备管理系统(springboot+ssm+jsp+maven)
基于springboot的办公设备管理系统(springbootssmjspmaven) 系统功能主要有: 欢迎页账号管理 管理员账号管理系统账号添加密码修改 普通管理员管理 用户管理用户添加用户查询 资产类型管理资产信息管理资产档案管理资产报表...
蓝桥杯2024JavaB组的一道真题的解析
文章目录 1.问题描述2.问题描述3.思路分析4.代码分析 1.问题描述 这个是我很久之前写的一个题目,当时研究了这个题目好久,发布了一篇题解,后来很多人点赞,我都没有意识到这个问题的严重性,我甚至都在怀疑自己…...
数据库--SQL
SQL:Structured Query Language,结构化查询语言 SQL是用于管理关系型数据库并对其中的数据进行一系列操作(包括数据插入、查询、修改删除)的一种语言 分类:数据定义语言DDL、数据操纵语言DML、数据控制语言DCL、事务处…...