使用多线程快速向Excel中快速插入一万条数据案例
当有大量数据需要存入Excel时,使用传统的单线程完成会有以下这些弊端:
- 导入速度慢:单线程一次只能处理一个任务,在导入大量数据时,需要逐个将数据写入 Excel。这意味着 CPU 在大部分时间里只能处理一个数据块,其他时间可能处于闲置状态,无法充分利用多核处理器的优势,导致导入过程耗时较长。
- 界面卡顿:如果在图形界面应用程序中使用单线程进行 Excel 导入,在导入过程中,主线程会被阻塞,导致界面无法响应用户的操作,如点击按钮、滚动窗口等,给用户造成程序 “卡死” 的感觉,严重影响用户体验。
- 资源利用率低:单线程无法同时利用 CPU 的多个核心,也不能在 I/O 操作等待时让其他任务占用 CPU,使得系统资源(如 CPU、内存等)不能得到充分利用,系统整体性能无法得到有效发挥。
下面我们一起使用多线程来优化代码,生成的Excel存将放在项目目录下(也可以自定义目录):
package com.example.demo.demo_insert_excel;import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;/*** 该类用于演示如何使用多线程向 Excel 文件中插入 1 万条数据。* 它通过将任务分配给多个线程来提高数据插入的效率,并使用日志记录执行过程。*/
public class MultiThreadExcelInsert {// 定义要插入到 Excel 中的总行数private static final int ROW_COUNT = 10000;// 定义使用的线程数量private static final int THREAD_COUNT = 4;// 定义生成的 Excel 文件的名称private static final String FILE_NAME = "output.xlsx";// 获取当前类的日志记录器,用于记录程序执行过程中的信息private static final Logger LOGGER = Logger.getLogger(MultiThreadExcelInsert.class.getName());/*** 程序的入口点,负责初始化工作簿、分配任务给线程池,并处理文件写入和资源关闭。** @param args 命令行参数(在本程序中未使用)*/public static void main(String[] args) {// 记录程序开始执行的时间,用于后续计算总耗时long startTime = System.currentTimeMillis();// 创建一个新的 XSSF 工作簿(即 .xlsx 格式的 Excel 文件)Workbook workbook = new XSSFWorkbook();// 在工作簿中创建一个名为 "Data" 的工作表Sheet sheet = workbook.createSheet("Data");// 创建一个固定大小的线程池,线程数量为 THREAD_COUNTExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);// 计算每个线程需要处理的行数int batchSize = ROW_COUNT / THREAD_COUNT;// 用于存储每个任务的 Future 对象,以便后续等待任务完成Future<?>[] futures = new Future[THREAD_COUNT];// 为每个线程分配任务for (int i = 0; i < THREAD_COUNT; i++) {// 计算当前线程处理的起始行int startRow = i * batchSize;// 计算当前线程处理的结束行int endRow = (i == THREAD_COUNT - 1) ? ROW_COUNT : (i + 1) * batchSize;// 创建一个插入任务实例InsertTask task = new InsertTask(sheet, startRow, endRow, i);// 提交任务到线程池,并获取该任务的 Future 对象futures[i] = executor.submit(task);// 记录线程任务提交信息LOGGER.info("线程 " + i + " 已提交任务,处理行范围:" + startRow + " - " + endRow);}// 等待所有任务完成for (Future<?> future : futures) {try {// 阻塞当前线程,直到任务完成future.get();} catch (InterruptedException | ExecutionException e) {// 若任务执行过程中出现异常,中断当前线程并记录错误信息Thread.currentThread().interrupt();LOGGER.log(Level.SEVERE, "任务执行出错", e);}}// 关闭线程池,不再接受新的任务executor.shutdown();// 使用 try-with-resources 语句确保文件输出流在使用后正确关闭try (FileOutputStream fileOut = new FileOutputStream(FILE_NAME)) {// 将工作簿的内容写入到指定的文件中workbook.write(fileOut);} catch (IOException e) {// 若写入文件过程中出现异常,记录错误信息LOGGER.log(Level.SEVERE, "写入文件出错", e);} finally {try {// 关闭工作簿workbook.close();} catch (IOException e) {// 若关闭工作簿时出现异常,记录错误信息LOGGER.log(Level.SEVERE, "关闭工作簿出错", e);}}// 记录程序结束执行的时间long endTime = System.currentTimeMillis();// 记录数据插入成功的信息LOGGER.info("数据已成功插入到 " + FILE_NAME);// 记录数据插入的总耗时LOGGER.info("插入数据总共耗时: " + (endTime - startTime) + " 毫秒");}/*** 插入任务类,实现了 Runnable 接口,用于在单独的线程中执行数据插入操作。*/static class InsertTask implements Runnable {// 要操作的工作表private final Sheet sheet;// 当前任务处理的起始行private final int startRow;// 当前任务处理的结束行private final int endRow;// 当前线程的 IDprivate final int threadId;// 获取当前类的日志记录器,用于记录任务执行过程中的信息private static final Logger TASK_LOGGER = Logger.getLogger(InsertTask.class.getName());/*** 构造函数,用于初始化插入任务的相关信息。** @param sheet 要操作的工作表* @param startRow 任务处理的起始行* @param endRow 任务处理的结束行* @param threadId 当前线程的 ID*/public InsertTask(Sheet sheet, int startRow, int endRow, int threadId) {this.sheet = sheet;this.startRow = startRow;this.endRow = endRow;this.threadId = threadId;}/*** 线程执行的具体任务,负责在指定的行范围内插入数据。*/@Overridepublic void run() {// 记录线程开始执行任务的信息TASK_LOGGER.info("线程 " + threadId + " 开始执行任务,处理行范围:" + startRow + " - " + endRow);// 遍历当前任务需要处理的行for (int rowIndex = startRow; rowIndex < endRow; rowIndex++) {// 使用 synchronized 块确保同一时间只有一个线程可以访问 sheetsynchronized (sheet) {// 在工作表中创建一行Row row = sheet.createRow(rowIndex);// 遍历每一行的列for (int colIndex = 0; colIndex < 4; colIndex++) {// 在当前行中创建一个单元格Cell cell = row.createCell(colIndex);// 为单元格设置值,格式为 "数据" + 行索引 + "_" + 列索引cell.setCellValue("数据" + rowIndex + "_" + colIndex);}}// 每处理 100 行记录一次当前处理进度if (rowIndex % 100 == 0) {TASK_LOGGER.info("线程 " + threadId + " 已处理到行:" + rowIndex);}}// 记录线程完成任务的信息TASK_LOGGER.info("线程 " + threadId + " 完成任务,处理行范围:" + startRow + " - " + endRow);}}
}
最终结果:
优点
1. 提高导入速度
在多核处理器的环境下,多线程能够充分利用 CPU 的多个核心,让多个线程同时进行数据处理和写入操作。相比于单线程按顺序依次写入数据,多线程可以并行处理多个数据块,显著减少了整体的导入时间。例如,在导入大量数据时,单线程可能需要几分钟甚至更长时间,而多线程可以将时间缩短至几十秒。
2. 提升系统资源利用率
多线程可以让 CPU、内存等系统资源得到更充分的利用。当一个线程在进行 I/O 操作(如将数据写入 Excel 文件)时,CPU 可能处于空闲状态,此时其他线程可以继续执行数据处理任务,避免了资源的闲置浪费,提高了系统的整体性能。
3. 增强用户体验
对于需要处理大量数据导入的应用程序,使用多线程可以避免主线程被长时间阻塞,从而保证界面的响应性。用户在导入数据的过程中仍然可以进行其他操作,不会感觉到程序卡顿,提升了用户体验。
缺点
1. 线程安全问题
在多线程环境下,多个线程可能会同时访问和修改共享资源(如 Excel 文件的工作表、单元格等),这就容易引发线程安全问题。例如,两个线程同时尝试在同一单元格写入数据,可能会导致数据覆盖或文件损坏。为了保证线程安全,需要使用同步机制(如
synchronized
关键字、Lock
接口等),但这会增加代码的复杂度和性能开销。2. 调试和维护困难
多线程程序的执行流程比单线程程序更加复杂,线程之间的交互和调度难以预测。当出现问题时,调试和定位问题会变得非常困难,因为错误可能是由于线程之间的竞争条件、死锁等原因引起的,这些问题很难通过简单的日志和调试工具来排查。此外,多线程代码的维护也更加困难,因为需要考虑线程安全和并发控制等因素。
3. 资源竞争和性能开销
虽然多线程可以提高系统资源的利用率,但如果线程数量过多,会导致资源竞争加剧。例如,多个线程同时访问磁盘、内存等资源,可能会导致资源瓶颈,反而降低了系统的性能。此外,线程的创建、销毁和切换都需要消耗一定的系统资源,过多的线程会增加系统的负担,导致性能下降。
4. 兼容性问题
不同的 Excel 操作库对多线程的支持程度可能不同,某些库可能没有很好地处理多线程环境下的并发问题,导致在使用多线程进行数据导入时出现兼容性问题。此外,不同版本的 Excel 软件对多线程操作的稳定性也可能存在差异。
相关文章:
使用多线程快速向Excel中快速插入一万条数据案例
当有大量数据需要存入Excel时,使用传统的单线程完成会有以下这些弊端: 导入速度慢:单线程一次只能处理一个任务,在导入大量数据时,需要逐个将数据写入 Excel。这意味着 CPU 在大部分时间里只能处理一个数据块ÿ…...
RestRequest ,newtonsoft解析
var request new RestRequest(Method.GET); IRestResponse response client.Execute(request); Console.WriteLine(response.Content); //保存token Newtonsoft.Json.Linq.JObject obj3 Newtonsoft.Json.Linq.JObject.Pars…...
vs2022解决 此项目需要MFC库。从visual studio安装程序(单个组件选项卡)为正在使用的任何工具和体系结构安装他们问题
使用visual studio 2022创建MFC 单文档的项目,编译器报错: 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误 MSB8041 此项目需要 MFC 库。从 Visual Studio 安装程序(单个组件选项卡)为正在使用的任何工具集和体系结构安装它们。 osgEarthMFC…...
面试算法高频08-动态规划-03
练习题 题目描述 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每…...
uniapp做app,使用v-for遍历渲染第二层的时候,打包到手机上渲染不出第二层的数据
1.打包apk要严格注意一点,在data中定义的时候要把第二层定义上, pointspower: [{ jcdbh: 1, cgqbhs:[] }] 不然会出现未定义的情况,直接把二层结构定义上,有利无害 2.渲染…...
Uniapp(vue):生命周期
目录 一、Vue生命周期二、Uniapp中页面的生命周期三、执行顺序比较一、Vue生命周期 setup():是在beforeCreate和created之前运行的,所以可以用setup代替这两个钩子函数。onBeforeMount():已经完成了模板的编译,但是组件还未挂载到DOM上的函数。onMounted():组件挂载到DOM完…...
Git技巧:Git Hook,自动触发,含实战分享
Git技巧:Git Hook,自动触发,含实战分享 最近项目需要1个git合入时触发脚本的功能,使用Git Hook功能实现,总结如下: Git项目在路径:repo\.git\hooks下有很多文件,这些文件就是本地钩…...
DeepSeek创始人梁文峰是个什么样的人?
梁文峰是一位在人工智能领域具有深远影响力的企业家和技术创新者,他的个人经历和成就展现了他作为一位技术天才、创新领袖以及社会责任感强的企业家的多重身份。 从学术背景来看,梁文峰出生于广东湛江吴川,17岁时以高考状元的身份考入浙江大…...
【知识科普】今天聊聊CDN
CDN 技术详解:从原理到配置实践 CDN 技术详解:从原理到配置实践一、CDN 核心定义二、工作原理深度解析1. 请求路由机制2. 缓存分层架构3. 内容更新流程 三、核心功能组件1. 基础设施层2. 软件系统 四、典型配置流程(以Cloudflare为例…...
Axure疑难杂症:利用中继器制作三级下拉菜单(逻辑判断进阶)
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:三级下拉菜单 主要内容:条件筛选时的逻辑判断思维,中继器使用 应用场景:复合条件下的下拉列表制作 案例展…...
C语言----操作符详解(万字详解)
目录 1. 操作符的分类 2. 二进制和进制转换 3. 原码 反码 补码 4. 移位操作符 4.1 左移操作符 >> 4.2 右移操作符 >> 5. 位操作符 5.1 按位与 & 5.2 按位或 | 5.3 按位异或 ^ 5.4 按位取反 ~ 练习 整数存储在内存中二进制中1的个数 练习 二进制位…...
docker本地部署ClipCascade,实现跨设备剪贴板同步
1、什么是 ClipCascade ? ClipCascade 是一款开源的轻量级工具,可以自动同步您的剪贴板在多个设备之间,无需按键。它确保设备之间无缝的剪贴板共享,并以端对端加密优先保护隐私。无论您是在不同工作站之间切换,还是仅…...
Android Compose vs 传统View系统:全面对比与选型指南
Android Compose vs 传统View系统:全面对比与选型指南 一、引言 随着Android Jetpack Compose的正式发布,Android开发迎来了全新的声明式UI框架。本文将全面对比Compose与传统View系统的差异,帮助开发者做出合理的技术选型。 二、核心架构…...
CVE-2024-3431 EyouCMS 反序列化漏洞研究分析
易优内容管理系统(EyouCms) 隶属于海口快推科技有限公司,专注中小型企业信息传播解决方案,利用网络传递信息在一定程度上提高了办事的效率,提高企业的竞争力。EyouCms 是一个自由和开放源码的内容管理系统,它是一个可以独立使用的…...
C# wpf
学习网址:控件的父类们 - WPF中文网 - 从小白到大佬 控件的父类: 由此我们可以得出结论,控件的父类们(准确的说,应该叫父类的父类的父类),至少有如下几个类型: DispatcherObjectDependencyObjectVisualU…...
十一、引用与拷贝函数(References the Copy-Constructor)
十一、引用与拷贝函数(References & the Copy-Constructor) 11.1 指针回顾(Review of pointers) 指针可以保存一个地址。 当你定义一个指针时,必须指定它所指向变量的类型,并且应该初始化它。 示例&a…...
数据结构之顺序表
目录 1.线性表 1.1 线性表的定义:零个或多个数据元素的有限序列。 1.2深度解析 1.3 线性表的抽象数据类型 2.顺序表 2.1 顺序表的定义和存储方式 2.2静态顺序表 2.2.1 静态顺序表的使用 2.2.3 为什么我们要使用typedef呢? 2.2.4 为什么我们要使…...
【计算机视觉】三种图像质量评价指标详解:PSNR、SSIM与SAM
图像质量评价指标详解:PSNR、SSIM与SAM 文章目录 图像质量评价指标详解:PSNR、SSIM与SAM1. 峰值信噪比(PSNR)1.1 数学定义1.2 特点与局限性 2. 结构相似性指数(SSIM)2.1 数学定义2.2 特点与应用 3. 光谱角度映射器(SAM)3.1 数学定义3.2 特点与应用 4. Py…...
轻舟系列FPGA加速卡:大模型分布式训练中的高效协同者
在超大规模模型(如千亿级参数)的分布式训练中,计算、存储与通信的协同优化是突破性能瓶颈的关键。绿算技术公司的轻舟系列FPGA加速卡凭借其低延迟、高能效和可编程特性,能够成为分布式训练架构中的异构加速节点。其在训练集群中的…...
C++20 小语法
这个提案允许在static_assert和if constexpr中从整形转换为布尔类型。 以下表格就可以表示所有内容。 对于严格的C 编译器来说,以前在这种情境下int无法向下转换为bool,需要手动强制转换, C23 这一情况得到了改善。 对于严格的C编译器来说&a…...
LM393比较器的比较翻转电压不对
问个问题,用的LM393比较器,3.3V供电,比较器输出上拉到3.3V, V给的基准2.8V,V-电压从1V升到2.3V,比较器就输出0V了,按理论超过2.8V才翻转到0V的 根据问题描述和电路分析,比较器LM393…...
解决 shadui组件库Popover 点击后会消失
react用了shadui组件库 <Popover><PopoverTrigger><div className"text-operation-item" onClick{props.callback}><img src{props.imgSrc} width{20} height{20} /></div></PopoverTrigger><PopoverContent className"…...
国联股份卫多多与北京慧闻科技(集团)签署战略合作协议
4月27日,北京慧闻科技(集团)有限公司(以下简称“慧闻科技”)销售总监王兴卓一行到访国联股份卫多多,同卫多多/纸多多副总裁、产发部总经理段任飞,卫多多机器人产业链总经理桂林展开深入交流&…...
从数据到决策:如何使用Python进行自动驾驶数据分析
从数据到决策:如何使用Python进行自动驾驶数据分析 大家好,我是Echo_Wish,今天来和大家聊一聊在自动驾驶领域中,如何通过Python进行数据分析。随着自动驾驶技术的不断发展,数据分析在这一领域的作用越来越重要。从传感器数据的处理到模型的训练和优化,Python在自动驾驶数…...
IIS服务器提示ERR_HTTP2 PROTOCOL ERROR解决方案
今天我的淘宝店来了一个客户,说小程序苹果访问没问题,安卓系统访问出现ERR HTTP2 PROTOCAL ERROR的错误见下图 方法供大家闭坑步骤:通过注册表修改(高级) 打开注册表编辑器 (regedit) 导航到: HKEY_LOCAL_MACHINE\SYSTEM\Current…...
Django的异步任务队列管理_Celery
1 基本原理 Celery 是一个异步任务队列,能够将耗时操作(如发邮件、处理图片、网络爬虫等)从 Django 主线程中分离出来,由后台的 worker 处理,避免阻塞请求。Celery 作为独立运行的后台进程(Worker…...
Ubuntu18.04安装IntelliJ IDEA2025步骤
1.下载linux版本的idea 复制下面链接到虚拟机浏览器 下载 IntelliJ IDEA 下载好后,你的文件里会多一个文件,如下图 2.解压并运行Idea 2.1在/usr/local/路径下新建安装目录IDEA: 打开终端输入以下命令: sudo mkdir -p /usr/loc…...
LLM - Large Language Model
回顾2024:与LLM又相伴一年的经历与思考 - 知乎万字长文入门大语言模型(LLM) - 知乎“大模型本质就是两个文件!”特斯拉前AI总监爆火LLM科普,时长1小时,面向普通大众 - 知乎大模型本质及趋势剖析,…...
解决Ubuntu20.04重启出现显卡驱动异常的问题(操作记录)
一、问题情况 电脑异常断电,重启后,显示界面异常,显卡驱动已丢失。 二、操作流程 1、查看安装显卡驱动 ls /usr/src | grep nvidia 记住该驱动,我的是nvidia-550.127.05 2、安装dkms(如果没有) sudo …...
23.开关电源干扰控制的EMC改善措施
开关电源干扰控制的EMC改善措施 1. 开关电源的EMI干扰机理2. 钳位抑制EMI3. 阻容吸收抑制EMI4. 波形整形抑制EMI 1. 开关电源的EMI干扰机理 2. 钳位抑制EMI 只能抑制Ts阶段。 3. 阻容吸收抑制EMI 4. 波形整形抑制EMI...
新能源汽车声纹监测技术的发展趋势是什么?
新能源汽车声纹监测技术有以下发展趋势: 智能化与自动化程度不断提高 故障自动诊断与预警:未来声纹监测系统将能够更加准确地自动识别和分析新能源汽车各部件的声纹特征变化,不仅能检测出故障,还能对故障的发展趋势进行预测&…...
如何获取按关键字搜索京东商品详情(代码示例)
在电商领域,获取京东商品的详细信息对于市场分析、选品上架、库存管理和价格策略制定等方面至关重要。京东作为国内知名的电商平台,提供了丰富的商品资源。通过 Python 爬虫技术,我们可以高效地获取京东商品的详细信息,包括商品名…...
C#中构造器及属性的加载顺序
一.基本原则: 先加载静态构造函数和静态字段,后加载普通构造函数和普通字段;先加载基类再加载子类; 二.具体的加载顺序: 父类静态字段--->父类静态构造函数--->子类静态字段--->子类静态构造函数--->父类实例字段---> 父类实例构造函数--->子类实例字段-…...
vue项目中如何使用markdown编辑器
在开发中,编辑markdown和回显markdown都是常见的需求。在vue(2.x和3.x都可以)中可以使用mavon-editor这个第三方依赖包。示例很简单易懂。 安装 npm install mavon-editor 注册 在main.js中注册这个组件 import Vue from vue import mavonEditor from mavon-editor impor…...
Python爬虫(9)Python数据存储实战:基于pymysql的MySQL数据库操作详解
目录 一、背景与核心价值二、pymysql核心操作详解2.1 环境准备2.2 数据库连接与基础操作2.3 事务处理与错误回滚2.4 高级功能:批量插入与性能优化 三、pymysql进阶技巧3.1 连接池管理(推荐使用DBUtils)3.2 SQL注入防御3.3 与ORM框架对比 四、…...
WPF之Button控件详解
文章目录 1. 引言2. Button控件基础Button类定义 3. Button控件的核心属性3.1 Content属性3.2 IsDefault属性3.3 IsCancel属性3.4 其他常用属性 4. 按钮样式与模板自定义4.1 简单样式设置4.2 使用Style对象4.3 触发器使用4.4 使用ControlTemplate完全自定义4.5 按钮视觉状态 5.…...
如何查看电脑电池使用情况
第一步打开cmd: 在键盘上按下winr 或者在搜索框中输入cmd 点击命令提示符 进入命令框 第二步输入命令: powercfg/batteryreport 出现如下情况 第三部找到对应电池报告进行查看: 在对应路径下找到电池报告 点击battery-report.html 到此…...
软考-软件设计师中级备考 6、数据结构 图
1. 有向图 有向图是由顶点集合 V 和有向边集合 E 组成的图结构。在有向图中,边是有方向的,即从一个顶点指向另一个顶点,通常用有序对 (u, v) 表示,其中 u 是边的起始顶点,v 是边的终止顶点。例如,在一个表…...
Label Studio 软件介绍及安装使用说明
背景说明 在做AI项目建模的时候,往往需要数据标注工作,比较常用的数据标注软件是Labeling或者Labelme,这两个都是离线的单独标注软件,使用起来是比较方便的,也是入门级学者比较适合的软件,然而有时候我们数据标注的数据…...
Azure 数字孪生是什么?
“Azure 数字孪生”是一项平台即服务 (PaaS) 产品/服务,它能够创建基于整个环境的数字模型的孪生图,这些图可能是建筑物、工厂、农场、能源网络、铁路、体育场馆,甚至整个城市。 这些数字模型可用于获取洞察力,以推动产品改进、运…...
界面控件DevExpress WPF v25.1预览 - AI功能增强(语义搜索)
DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...
【神经网络与深度学习】五折交叉验证(5-Fold Cross-Validation)
引言 五折交叉验证(5-Fold Cross-Validation)是一种广泛应用于机器学习模型性能评估的技术,通过多次实验确保模型的评估结果更加稳定、可靠,同时最大限度地利用有限的数据资源。它将数据分成若干子集,交替作为训练集和…...
Linux权限概念讲解
1. 用户类型 1.1 用户分类 在Linux里面用户分为两类,一种是超级用户(root),一种是普通用户。 超级用户只有一个,而普通用户可以有很多个。 如果我们在root用户状态下想要变成普通用户,我们可以使用命令…...
网络安全零基础培训 L1-8 PHP基础语法
文章目录 1 认识PHP1.1 PHP简介1.2 主要的特点1.3 跨平台性1.4 与数据库的良好集成1.5 开源和社区支持1.6 应用场景1.6.1 网站开发1.6.2 内容的管理程序1.6.3 Web应用程序开发1.6.4 为什么学习了解PHP 2 PHP的基础语法2.1 创建第一个PHP程序2.2 如何写注释2.3 PHP的变量2.4 PHP…...
鸿蒙 长列表加载性能优化
长列表加载性能优化 针对长列表加载这一场景,对列表渲染时间、页面滑动帧率、应用内存占用等方面带来优化,提升性能和用户体验的手段有如下 4 种: 懒加载:提供列表数据按需加载能力,解决一次性加载长列表数据耗时长、…...
第十二届蓝桥杯 2021 C/C++组 卡片
目录 题目: 题目描述: 题目链接: 思路: 思路详解: 代码: 代码详解: 题目: 题目描述: 题目链接: 卡片 - 蓝桥云课 思路: 思路详解&#…...
vscode 使用gitcode团队管理项目
1、下载安装vscode https://code.visualstudio.com/Download 2、安装git 3、在vscode中安装GitLens插件 4、打开终端 点击会显示当前更改的项目 5、提交更改的文件,会提示输入用户名、密码,这里的密码即是令牌,令牌在第一次创建的时候显…...
uniapp+vue3+ts 使用canvas实现安卓端、ios端及微信小程序端二维码生成及下载
加粗样式uniapp多端生成带二维码海报并保存至相册的实现 在微信小程序开发中,我们常常会遇到生成带有二维码的海报并保存到手机相册的需求,比如分享活动海报、产品宣传海报等。今天就来和大家分享一下如何通过代码实现这一功能。 准备工作 在开始之前&am…...
vue mixin混入与hook
mixin混入是 选项式 API,在vue3-Composition API <script setup> 中无法直接使用,需通过 setup() 函数转换 vue2、vue3选项式API: // mixins/mixin.js export const mixin {methods: {courseType(courseLevel) {const levelMap {1: 初级,…...
《Masked Autoencoders Are Scalable Vision Learners》---CV版的BERT
目录 一、与之前阅读文章的关系? 二、标题:带掩码的自auto编码器是一个可拓展的视觉学习器 三、摘要 四、核心图 五、结果图 六、不同mask比例对比图 七、“Introduction” (He 等, 2021, p. 1) 引言 八、“Related Work” (He 等, 2021, p. 3)相…...