当前位置: 首页 > news >正文

EasyExcel多线程批量导出数据,动态表头,静态资源访问

1.导入依赖

        <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency>

2.建立实体

@Data
public class ActResultLogVO implements Serializable {private static final long serialVersionUID = 1L;@ExcelProperty(value = "onlineseqid",index = 0)private String onlineseqid;@ExcelProperty(value = "businessid",index = 1)private String businessid;@ExcelProperty(value = "becifno",index = 2)private String becifno;@ExcelProperty(value = "ivisresult",index = 3)private String ivisresult;@ExcelProperty(value = "createdby",index = 4)private String createdby;@ExcelProperty(value = "createddate",index = 5)private LocalDate createddate;@ExcelProperty(value = "updateby",index = 6)private String updateby;@ExcelProperty(value = "updateddate",index = 7)private LocalDate updateddate;@ExcelProperty(value = "risklevel",index = 8)private String risklevel;/*** 分页开始数量*/private Integer start;/***  分页 size*/private Integer size;
}

3.多线程异步导出

	@Async@Transactionalpublic  void exportExcel(String filePath) {//filePath 文件路径ExcelWriter writer = EasyExcel.write(filePath, ActResultLogVO.class).build();// 根据数据读写速度来调整,一般来说读的逻辑复杂,比较慢,如果读比写快,这里设为1int N = 2;// 大小设置为2就可以,作为缓冲BlockingQueue<List<ActResultLogVO>> queue = new ArrayBlockingQueue<>(2);AtomicInteger start = new AtomicInteger(0);AtomicInteger num = new AtomicInteger(0);AtomicInteger sheet = new AtomicInteger(1);// 分页大小可以适当调整int pageSize = 100000;//开启多个线程分页查数据for (int i = 0; i < N; i++) {executorService.submit(() -> {while (true) {//自增int startNum= start.getAndAdd(pageSize);try {long l = System.currentTimeMillis();logger.info("[多线程,分页查询] 线程:{},开始执行查询:startNum :{},时间:{}",Thread.currentThread().getName(),startNum,l);List<ActResultLogVO> list = selectActResultLogVOPage(startNum, pageSize);logger.info("[多线程,分页查询] 线程:{},执行查询完成 startNum :{} 用时:{}",Thread.currentThread().getName(),startNum,System.currentTimeMillis()-l);if (CollectionUtils.isEmpty(list)) {//读到没数据也要放入空集合queue.put(Collections.EMPTY_LIST);break;}queue.put(list);} catch (Exception e) {//异常情况也要放入空集合,防止写线程无法退出循环try {queue.put(Collections.EMPTY_LIST);} catch (InterruptedException ex) {throw new RuntimeException(ex);}throw new RuntimeException(e);}}});}Future<?> submit = executorService.submit(() -> {int count = 0;while (true) {List<ActResultLogVO> list = null;try {list = queue.take();} catch (InterruptedException e) {Thread.interrupted();}if (CollectionUtils.isEmpty(list)) {count++;// 当获取到两次空集合时,说明已经读完if (count == N) {break;}continue;}if(num.get()>=500000){sheet.getAndAdd(1);num.getAndSet(0);}num.getAndAdd(list.size());long l = System.currentTimeMillis();logger.info("[多线程,写入Excel] 线程:{},开始执行写入:sheet :{},num:{}时间:{}",Thread.currentThread().getName(),sheet.get(),num.get(),l);writer.write(list, EasyExcel.writerSheet("Sheet"+sheet).build());logger.info("[多线程,写入Excel] 线程:{},开始执行写入结束:sheet :{},num:{},时间:{}",Thread.currentThread().getName(),sheet.get(),num.get(),System.currentTimeMillis()-l);}writer.finish();});try {// 阻塞等待完成,异步处理也可以去掉这段代码submit.get();} catch (Exception e) {}}

4.动态表头

 	 @Autowired@Qualifier("excelThreadPool")private ExecutorService executorService;@Async@Transactionalpublic void exportExcel(String filePath,LinkedHashMap<String, DynamicExcelData> nameMap) {// 指定写入的文件ExcelWriter writer = EasyExcel.write(filePath).head(ExcelUtils.getHead(nameMap)).build();// 根据数据读写速度来调整,一般来说读的逻辑复杂,比较慢,如果读比写快,这里设为1int N = 2;// 大小设置为2就可以,作为缓冲BlockingQueue<List<Map<String,Object>>> queue = new ArrayBlockingQueue<>(2);AtomicInteger num = new AtomicInteger(0);AtomicInteger sheet = new AtomicInteger(1);// 分页大小可以适当调整int pageSize = ExcelConstants.SELECT_TO_DB_ROWS_MYBATIS;//开启多个线程分页查数据getData(lvnengAllCardBillVo,queue,pageSize);Future<?> submit = executorService.submit(() -> {int count = 0;while (true) {List<Map<String,Object>> list = null;try {list = queue.take();} catch (InterruptedException e) {Thread.interrupted();}if (CollectionUtils.isEmpty(list)) {count++;// 当获取到两次空集合时,说明已经读完if (count == N) {break;}continue;}if(num.get()>=600000){sheet.getAndAdd(1);num.getAndSet(0);}num.getAndAdd(list.size());List<List<String>> dataList = ExcelUtils.getDataList(nameMap, list);writer.write(dataList, EasyExcel.writerSheet("Sheet"+sheet).build());}writer.finish();});try {// 阻塞等待完成,异步处理也可以去掉这段代码submit.get();} catch (Exception e) {}}
public void getData(ActResultLogVO actResultLogVO,BlockingQueue<List<Map<String,Object>>> queue,int pageSize) {// 根据数据读写速度来调整,一般来说读的逻辑复杂,比较慢,如果读比写快,这里设为1int N = 2;AtomicInteger start = new AtomicInteger(0);for (int i = 0; i < N; i++) {executorService.submit(() -> {while (true) {//自增int startNum = start.getAndAdd(pageSize);List<Map<String, Object>> list = new ArrayList<>();try {ActResultLogVO actResultLogVO1 = DeepCopyUtil.deepCopy(actResultLogVO);actResultLogVO1.setStart(startNum);List<Map<String, Object>> list = selectactResultLogVOPage(actResultLogVO1);if (CollectionUtils.isEmpty(list)) {//读到没数据也要放入空集合queue.put(Collections.EMPTY_LIST);break;}queue.put(list);} catch (Exception e) {//异常情况也要放入空集合,防止写线程无法退出循环try {queue.put(Collections.EMPTY_LIST);} catch (InterruptedException ex) {throw new RuntimeException(ex);}throw new RuntimeException(e);}}});}logger.info("查询数据完成");}
@Configuration
public class ThreadPoolConfig {@Bean("excelThreadPool")public  ExecutorService buildExcelThreadPool() {int cpuNum = Runtime.getRuntime().availableProcessors();BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(1000);ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("excel-pool-%d").build();return new ThreadPoolExecutor(10 * cpuNum, 30 * cpuNum,1, TimeUnit.MINUTES, workQueue, threadFactory);}
}
public class ExcelConstants {public static final Integer PER_SHEET_ROW_COUNT = 100*10000;public static final Integer PER_WRITE_ROW_COUNT = 20*10000;public static final Integer SHEET_WRITE_ROW_COUNT = 50*10000;public static final Integer SELECT_TO_DB_ROWS = 10*10000;public static final Integer SELECT_TO_DB_ROWS_MYBATIS = 5*10000;
}
@Data
public class DynamicExcelData {//列名private String name;//默认值private String defaultValue;public DynamicExcelData(String name, String defaultValue) {this.name = name;this.defaultValue = defaultValue;}
}

5,用到的util

5.1 EasyUtils

public class ExcelUtils {public static void dynamicExportByURL(String filePath,LinkedHashMap<String, DynamicExcelData> nameMap,List<Map<String, Object>> list,String sheetName) throws IOException {//首先判断是否有数据,没有就返回if(CollUtil.isEmpty(list)){return;}//这里的map使用LinkedHashMap,实现字段的顺序功能if(nameMap==null){throw new RuntimeException("请填写好映射表数据");}File file = getFile(filePath);dynamicExportByURL(file,nameMap,list,sheetName);}public static void dynamicExport(HttpServletResponse response,LinkedHashMap<String, DynamicExcelData> nameMap,List<Map<String, Object>> list,String sheetName) throws IOException {//首先判断是否有数据,没有就返回if(CollUtil.isEmpty(list)){return;}//这里的map使用LinkedHashMap,实现字段的顺序功能if(nameMap==null){throw new RuntimeException("请填写好映射表数据");}response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");//使用EasyExcel write进行写出EasyExcel.write(response.getOutputStream()).head(getHead(nameMap)).sheet(sheetName).doWrite(getDataList(nameMap,list));}public static ArrayList<List<String>> getHead(LinkedHashMap<String, DynamicExcelData> nameMap) {//获取表头ArrayList<List<String>> head = new ArrayList<>();for (Map.Entry<String, DynamicExcelData> titleMap : nameMap.entrySet()) {DynamicExcelData data = titleMap.getValue();head.add(Collections.singletonList(data.getName()));}return head;}public static List<List<String>> getDataList(LinkedHashMap<String, DynamicExcelData> nameMap, List<Map<String, Object>> list) {//先初始化一下传入int size = list.size();List<List<String>> dataList = new ArrayList<>();for (int i = 0; i < size; i++) {dataList.add(new ArrayList<>());}//数据重组for (int i = 0; i < list.size(); i++) {Map<String, Object> map = list.get(i);List<String> columns = dataList.get(i);for (Map.Entry<String, DynamicExcelData> sortNameEntry : nameMap.entrySet()) {String key = sortNameEntry.getKey();Object value = map.get(key);columns.add(value != null ? String.valueOf(value) : sortNameEntry.getValue().getDefaultValue());}}return dataList;}public static File getFile(String filePath) throws IOException {File file = new File(filePath);if (!file.exists()) {file.createNewFile();}return file;}public static void dynamicExportByURL(File file,LinkedHashMap<String, DynamicExcelData> nameMap,  List date,String sheetName) {long startTime = 0;ExcelWriter excelWriter = null;try {startTime = System.currentTimeMillis();// 获取 sheet 的个数int sheetNum = getSheetNum(date.size());// 获取每个sheet 写入的次数int writeNumPerSheet = getWriteNumPerSheet();// 最后一个 sheet 写入的数量int writeNumLastSheet = date.size() - (sheetNum - 1) * ExcelConstants.PER_SHEET_ROW_COUNT;// 最后一个 sheet 写入的次数int writeNumPerLastSheet = writeNumLastSheet % ExcelConstants.PER_WRITE_ROW_COUNT == 0 ? writeNumLastSheet / ExcelConstants.PER_WRITE_ROW_COUNT : writeNumLastSheet / ExcelConstants.PER_WRITE_ROW_COUNT + 1;// 指定写入的文件excelWriter = EasyExcel.write(file).head(getHead(nameMap)).build();for (int i = 0; i < sheetNum; i++) {String sheet = sheetName + i;WriteSheet writeSheet = EasyExcel.writerSheet(i, sheet).build();int writeNum = i == sheetNum - 1 ? writeNumPerLastSheet : writeNumPerSheet; // 每个sheet 写入的次数int endEndNum = i == sheetNum - 1 ? date.size() : (i + 1) * ExcelConstants.PER_SHEET_ROW_COUNT; // 每个sheet 最后一次写入的最后行数for (int j = 0; j < writeNum; j++) {long l = System.currentTimeMillis();int startNum = i * ExcelConstants.PER_SHEET_ROW_COUNT + j * ExcelConstants.PER_WRITE_ROW_COUNT;int endNum = j == writeNum - 1 ? endEndNum : i * ExcelConstants.PER_SHEET_ROW_COUNT + (j + 1) * ExcelConstants.PER_WRITE_ROW_COUNT;excelWriter.write(getDataList(nameMap,date.subList(startNum, endNum)), writeSheet);}}} catch (Exception e) {} finally {// 需要放入 finally 中if (excelWriter != null) {excelWriter.finish();}}}public static void writeExcel(String filePath, Class clazz, List date,String sheetName) throws Exception{File file = getFile(filePath);long startTime = System.currentTimeMillis();// 获取 sheet 的个数int sheetNum = getSheetNum(date.size());// 获取每个sheet 写入的次数int writeNumPerSheet = getWriteNumPerSheet();// 最后一个 sheet 写入的数量int writeNumLastSheet = date.size() - (sheetNum - 1) * ExcelConstants.PER_SHEET_ROW_COUNT;// 最后一个 sheet 写入的次数int writeNumPerLastSheet = writeNumLastSheet % ExcelConstants.PER_WRITE_ROW_COUNT == 0 ? writeNumLastSheet / ExcelConstants.PER_WRITE_ROW_COUNT : writeNumLastSheet / ExcelConstants.PER_WRITE_ROW_COUNT + 1;// 指定写入的文件ExcelWriter excelWriter = EasyExcel.write(file, clazz).build();for (int i = 0; i < sheetNum; i++) {String sheet = sheetName + i;WriteSheet writeSheet = EasyExcel.writerSheet(i, sheet).build();int writeNum = i == sheetNum - 1 ? writeNumPerLastSheet : writeNumPerSheet; // 每个sheet 写入的次数int endEndNum = i == sheetNum - 1 ? date.size() : (i + 1) * ExcelConstants.PER_SHEET_ROW_COUNT; // 每个sheet 最后一次写入的最后行数for (int j = 0; j < writeNum; j++) {long l = System.currentTimeMillis();int startNum = i * ExcelConstants.PER_SHEET_ROW_COUNT + j * ExcelConstants.PER_WRITE_ROW_COUNT;int endNum = j == writeNum - 1 ? endEndNum : i * ExcelConstants.PER_SHEET_ROW_COUNT + (j + 1) * ExcelConstants.PER_WRITE_ROW_COUNT;excelWriter.write(date.subList(startNum, endNum), writeSheet);}}// 需要放入 finally 中if (excelWriter != null) {excelWriter.finish();}}public static int getSheetNum(int dateSize){return dateSize % ExcelConstants.PER_SHEET_ROW_COUNT == 0 ? (dateSize / ExcelConstants.PER_SHEET_ROW_COUNT) : (dateSize / ExcelConstants.PER_SHEET_ROW_COUNT + 1);}public static int getWriteNumPerSheet(){return ExcelConstants.PER_SHEET_ROW_COUNT % ExcelConstants.PER_WRITE_ROW_COUNT == 0 ? (ExcelConstants.PER_SHEET_ROW_COUNT / ExcelConstants.PER_WRITE_ROW_COUNT) : (ExcelConstants.PER_SHEET_ROW_COUNT / ExcelConstants.PER_WRITE_ROW_COUNT + 1);}public static  List<String> objectToList(Object obj){ArrayList<String> list = new ArrayList<>();//获取obj类中的所有字段Field[] fields = obj.getClass().getDeclaredFields();//遍历所有属性for (Field field : fields) {try {field.setAccessible(true);list.add(field.get(obj).toString());} catch (IllegalAccessException e) {throw new RuntimeException(e);}}return list;}public static Map<String,Object> objectToMap(Object obj){HashMap<String, Object> map = new HashMap<>();//获取obj类中的所有字段Field[] fields = obj.getClass().getDeclaredFields();//遍历所有属性for (Field field : fields) {try {field.setAccessible(true);map.put(field.getName(),field.get(obj));} catch (IllegalAccessException e) {throw new RuntimeException(e);}}return map;}/*** 通过反射方式将头部作为公共部分进行设置*/public static List<List<String>> setTitles(Class clazz) {List<List<String>> titles = new ArrayList<List<String>>();for (Field declaredField : clazz.getDeclaredFields()) {ExcelProperty annotation = declaredField.getAnnotation(ExcelProperty.class);if (null != annotation) {titles.add(Arrays.asList(annotation.value()));}}return titles;}
}

5.2 深拷贝

public class DeepCopyUtil {public static <T extends Serializable> T deepCopy(T object) {try {ByteArrayOutputStream outputStream = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);objectOutputStream.writeObject(object);ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);return (T) objectInputStream.readObject();} catch (IOException | ClassNotFoundException e) {throw new RuntimeException(e);}}
}

配置静态资源访问

@Configuration
public class MyStaticConfig extends WebMvcConfigurationSupport {@Value("${download.url}")private String fileDir;@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/uploads/**").addResourceLocations("classpath:/META-INF/resources/", "classpath:/resources/","classpath:/static/", "classpath:/public/","file:"+fileDir);}
}

相关文章:

EasyExcel多线程批量导出数据,动态表头,静态资源访问

1.导入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency>2.建立实体 Data public class ActResultLogVO implements Serializable {private static…...

树莓派界面改成中文

安装完树莓派系统(Raspberry Pi OS with Desktop)&#xff0c;第一次启动时&#xff0c;时会有如下面二个图所示&#xff0c;让你选择区域时区和语言。 树莓派默认的语言为英文&#xff0c;如果你在安装时没有选择的话&#xff0c;默认的区域为英国&#xff0c;语言为英国英文&…...

软件工程期末复习

● 用例&#xff1a;借书 ●参与者&#xff1a;管理员,借阅者 ●操作流&#xff1a; ① 管理员进入图书借阅界面&#xff0c;用例开始。 ② 系统要求输入借阅者的借书证编码。 ③系统检验借书证编码,如果正确,则显示借阅者的信息。 A1&#xff1a;借书证编码有错。 A2: 如果该借…...

【linux】select实现定时器

/*秒级定时器*/ void seconds_sleep(unsigned long seconds) {if(seconds 0) return;struct timeval tv;tv.tv_secseconds;tv.tv_usec0;int err;do{errselect(0,NULL,NULL,NULL,&tv);}while(err<0 && errnoEINTR); }/*毫秒定时器*/void milliseconds_slee…...

Android 13 - Media框架(28)- MediaCodec(三)

上一节我们了解到 ACodec 执行完 start 流程后&#xff0c;会把所有的 input buffer 都提交给 MediaCodec 层&#xff0c;MediaCodec 是如何处理传上来的 buffer 呢&#xff1f;这一节我们就来了解一下这部分内容。 1、ACodecBufferChannel::fillThisBuffer ACodec 通过调用 A…...

Azure 学习总结

文章目录 1. Azure Function1.1 Azure Function 概念1.2 Azure Function 实现原理1.3 Azure Function 本地调试1.4 Azure Function 云部署 2. Azure API Managment 概念 以及使用2.1 Azure API 概念2.2 Azure API 基本使用 3. Service Bus 应用场景及相关特性3.1 Service Bus 基…...

数据库是否可以直接作为数据仓库的数据源

在数据仓库使用数据时&#xff0c;我们是否可以直接将数据库作为数据源&#xff1f;如果使用了&#xff0c;会存在哪些问题&#xff1f; 数据库中存储的是业务数据&#xff0c;存储方式是行式存储&#xff1b;而数据仓库中数据是以列式存储的&#xff1b;如果数据仓库要想使用…...

IntelliJ IDE 插件开发 | (四)开发一个时间管理大师插件

系列文章 IntelliJ IDE 插件开发 |&#xff08;一&#xff09;快速入门IntelliJ IDE 插件开发 |&#xff08;二&#xff09;UI 界面与数据持久化IntelliJ IDE 插件开发 |&#xff08;三&#xff09;消息通知与事件监听IntelliJ IDE 插件开发 |&#xff08;四&#xff09;开发一…...

【ChatGPT 默认强化学习策略】PPO 近端策略优化算法

PPO 近端策略优化算法 PPO 概率比率裁剪 演员-评论家算法演员-评论家算法&#xff1a;多智能体强化学习核心框架概率比率裁剪&#xff1a;逐步进行变化的方法PPO 目标函数的设计重要性采样KL散度 PPO 概率比率裁剪 演员-评论家算法 论文链接&#xff1a;https://arxiv.org…...

【银行测试】金融银行-理财项目面试/分析总结(二)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 银行理财相关的项…...

张江智荟毁约offer

毕业8年后&#xff0c;找工作被国企歧视学历&#xff01;已经收到了offer&#xff0c;在入职前一周被通知要撤回offer&#xff0c;拒绝录用&#xff0c;理由居然是他们只要本科211以上的人 这是我今天&#xff08;2023-12-26&#xff09;亲身经历的事&#xff0c;听说过面试前…...

ubuntu 系统终端颜色设置

1 开启终端颜色 # 第一步&#xff1a; 在 ~/.bashrc 中设置 force_color_promptyes# 第二步&#xff1a; 执行 source ~/.bashrc2 对于精减的 .bashrc 在 ~/.bashrc 中添加以下内容&#xff0c;再执行 source ~/.bashrc &#xff1a; # uncomment for a colored prompt, if…...

【Vue】class与style绑定

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…...

大厂前端面试题总结(百度、字节跳动、腾讯、小米.....),附上热乎面试经验!

先简单介绍下自己&#xff0c;我“平平无奇小天才”一枚&#xff0c;毕业于南方普通985普通学生&#xff0c;有幸去百度、字节面试&#xff0c;感觉大公司就是不一样&#xff0c;印象最深的是字节&#xff0c;所以有必要总结一下面试经验&#xff0c;以及面试中遇到的一些问题&…...

EXPLORING DIFFUSION MODELS FOR UNSUPERVISED VIDEO ANOMALY DETECTION 论文阅读

EXPLORING DIFFUSION MODELS FOR UNSUPERVISED VIDEO ANOMALY DETECTION 论文阅读 ABSTRACT1. INTRODUCTION2. RELATEDWORK3. METHOD4. EXPERIMENTAL ANALYSIS AND RESULTS4.1. Comparisons with State-Of-The-Art (SOTA)4.2. Diffusion Model Analysis4.3. Qualitative Result…...

当 ML 遇到 DevOps:如何理解 MLOps

近年来&#xff0c;人工智能 &#xff08;AI&#xff09; 和机器学习 &#xff08;ML&#xff09; 已经席卷全球&#xff0c;几乎成为任何行业的重要组成部分&#xff0c;从零售和娱乐到医疗保健和银行业。这些技术能够通过分析大量数据实现运营自动化、降低成本和促进决策&…...

vue+element+springboot实现多张图片上传

1.需求说明 2.实现思路 3.el-upload组件主要属性说明 4.前端传递MultipartFile数组与服务端接收说明 5.完整代码 1.需求说明 动态模块新增添加动态功能,支持多张图片上传.实现过程中对el-upload组件不是很熟悉,踩了很多坑,当然也参考过别的文章,发现处理很…...

react使用useState更新数组失败

失败案例&#xff1a; const [addBox, setAddBox] useState([])const itemAdd (item) >{addBox.push(item);setAddBox(addBox)console.log(addBox,点击添加按钮)} 原因&#xff1a;react的useState hook监听的是浅监听 在 React 中&#xff0c;使用 useState Hook 来更新…...

《LIO-SAM阅读笔记》3.后端优化

前言&#xff1a; LIO-SAM后端优化部分写在了mapOptimization.cpp文件中&#xff0c;本部分主要进行了激光帧的scan-to-map匹配&#xff0c;回环检测以及关键帧的因子图优化。本部分主要有两个环节同步进行&#xff0c;一个单独开辟了回环检测线程&#xff0c;另外一个是lidar…...

mac下jd-gui提示没有找到合适的jdk版本

mac下jd-gui提示jdk有问题 背景解决看一下是不是真有问题了方法一&#xff1a;修改启动脚本方法二&#xff1a;设置launchd环境变量 扩展动态切jdk脚本(.bash_profile) 背景 配置了动态jdk后&#xff0c;再次使用JD-GUI提示没有找到合适的jdk版本。 解决 看一下是不是真有问题…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

深度解析云存储:概念、架构与应用实践

在数据爆炸式增长的时代&#xff0c;传统本地存储因容量限制、管理复杂等问题&#xff0c;已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性&#xff0c;成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理&#xff0c;云存储正重塑数据存储与…...

Git 命令全流程总结

以下是从初始化到版本控制、查看记录、撤回操作的 Git 命令全流程总结&#xff0c;按操作场景分类整理&#xff1a; 一、初始化与基础操作 操作命令初始化仓库git init添加所有文件到暂存区git add .提交到本地仓库git commit -m "提交描述"首次提交需配置身份git c…...