无极低码 :https://wheart.cn
百万数据导出功能面临的问题
- 如果同步导数据,接口很容易超时。
- 如果把所有数据一次性装载到内存,很容易引起OOM。
- 数据量太大sql语句必定很慢。
- 相同商品编号的数据要放到一起。
- 如果走异步,如何通知用户导出结果?
- 如果excel文件太大,目标用户打不开怎么办?

1.异步处理
做一个MySQL百万数据级别的excel导出功能,如果走接口同步导出,该接口肯定会非常容易超时。
因此,我们在做系统设计的时候,第一选择应该是接口走异步处理。
说起异步处理,其实有很多种,比如:使用开启一个线程,或者使用线程池,或者使用job,或者使用mq等。
为了防止服务重启时数据的丢失问题,我们大多数情况下,会使用job或者mq来实现异步功能。
1.1 使用job
如果使用job的话,需要增加一张执行任务表,记录每次的导出任务。
用户点击全部导出按钮,会调用一个后端接口,该接口会向表中写入一条记录,该记录的状态为:待执行。
有个job,每隔一段时间(比如:5分钟),扫描一次执行任务表,查出所有状态是待执行的记录。
然后遍历这些记录,挨个执行。
需要注意的是:如果用job的话,要避免重复执行的情况。比如job每隔5分钟执行一次,但如果数据导出的功能所花费的时间超过了5分钟,在一个job周期内执行不完,就会被下一个job执行周期执行。
所以使用job时可能会出现重复执行的情况。
为了防止job重复执行的情况,该执行任务需要增加一个执行中的状态。
具体的状态变化如下:
- 执行任务被刚记录到执行任务表,是待执行状态。
- 当job第一次执行该执行任务时,该记录再数据库中的状态改为:执行中。
- 当job跑完了,该记录的状态变成:完成或失败。
这样导出数据的功能,在第一个job周期内执行不完,在第二次job执行时,查询待处理状态,并不会查询出执行中状态的数据,也就是说不会重复执行。
此外,使用job还有一个硬伤即:它不是立马执行的,有一定的延迟。
如果对时间不太敏感的业务场景,可以考虑使用该方案。
1.2 使用mq
用户点击全部导出按钮,会调用一个后端接口,该接口会向mq服务端,发送一条mq消息。
有个专门的mq消费者,消费该消息,然后就可以实现excel的数据导出了。
相较于job方案,使用mq方案的话,实时性更好一些。
对于mq消费者处理失败的情况,可以增加补偿机制,自动发起重试。
RocketMQ自带了失败重试功能,如果失败次数超过了一定的阀值,则会将该消息自动放入死信队列。
2.使用easyexcel
我们知道在Java中解析和生成Excel,比较有名的框架有Apache POI和jxl。
但它们都存在一个严重的问题就是:非常耗内存,POI有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。
百万级别的excel数据导出功能,如果使用传统的Apache POI框架去处理,可能会消耗很大的内存,容易引发OOM问题。
而easyexcel重写了POI对07版Excel的解析,之前一个3M的excel用POI sax解析,需要100M左右内存,如果改用easyexcel可以降低到几M,并且再大的Excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便。
需要在maven的pom.xml文件中引入easyexcel的jar包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.2</version>
</dependency>
读excel数据
@Test
public void simpleRead() {
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();
}
写excel数据
@Test
public void simpleWrite() {
String fileName = TestFileUtil.getPath() + "write" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
}
easyexcel能大大减少占用内存的主要原因是:在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
3.分页查询
百万级别的数据,从数据库一次性查询出来,是一件非常耗时的工作。
即使我们可以从数据库中一次性查询出所有数据,没出现连接超时问题,这么多的数据全部加载到应用服务的内存中,也有可能会导致应用服务出现OOM问题。
因此,我们从数据库中查询数据时,有必要使用分页查询。比如:每页5000条记录,分为200页查询。
public Page<User> searchUser(SearchModel searchModel) {
List<User> userList = userMapper.searchUser(searchModel);
Page<User> pageResponse = Page.create(userList, searchModel);
pageResponse.setTotal(userMapper.searchUserCount(searchModel));
return pageResponse;
}
每页大小pageSize和页码pageNo,是SearchModel类中的成员变量,在创建searchModel对象时,可以设置设置这两个参数。
然后在Mybatis的sql文件中,通过limit语句实现分页功能:
limit #{pageStart}, #{pageSize}
其中的pagetStart参数,是通过pageNo和pageSize动态计算出来的,比如:
pageStart = (pageNo - 1) * pageSize;
4.多个sheet
我们知道,excel对一个sheet存放的最大数据量,是有做限制的,一个sheet最多可以保存1048576行数据。否则在保存数据时会直接报错:
invalid row number (1048576) outside allowable range (0..1048575)
如果你想导出一百万以上的数据,excel的一个sheet肯定是存放不下的。
因此我们需要把数据保存到多个sheet中。
5.计算limit的起始位置
我之前说过,我们一般是通过limit语句来实现分页查询功能的:
limit #{pageStart}, #{pageSize}
其中的pagetStart参数,是通过pageNo和pageSize动态计算出来的,比如:
pageStart = (pageNo - 1) * pageSize;
如果只有一个sheet可以这么玩,但如果有多个sheet就会有问题。因此,我们需要重新计算limit的起始位置。
例如:
ExcelWriter excelWriter = EasyExcelFactory.write(out).build();
int totalPage = searchUserTotalPage(searchModel);
if(totalPage > 0) {
Page<User> page = Page.create(searchModel);
int sheet = (totalPage % maxSheetCount == 0) ? totalPage / maxSheetCount: (totalPage / maxSheetCount) + 1;
for(int i=0;i<sheet;i++) {
WriterSheet writeSheet = buildSheet(i,"sheet"+i);
int startPageNo = i*(maxSheetCount/pageSize)+1;
int endPageNo = (i+1)*(maxSheetCount/pageSize);
while(page.getPageNo()>=startPageNo && page.getPageNo()<=endPageNo) {
page = searchUser(searchModel);
if(CollectionUtils.isEmpty(page.getList())) {
break;
}
excelWriter.write(page.getList(),writeSheet);
page.setPageNo(page.getPageNo()+1);
}
}
}
复制代码
这样就能实现分页查询,将数据导出到不同的excel的sheet当中。
6.文件上传到OSS
由于现在我们导出excel数据的方案改成了异步,所以没法直接将excel文件,同步返回给用户。
因此我们需要先将excel文件存放到一个地方,当用户有需要时,可以访问到。
这时,我们可以直接将文件上传到OSS文件服务器上。
通过OSS提供的上传接口,将excel上传成功后,会返回文件名称和访问路径。
我们可以将excel名称和访问路径保存到表中,这样的话,后面就可以直接通过浏览器,访问远程excel文件了。
而如果将excel文件保存到应用服务器,可能会占用比较多的磁盘空间。
一般建议将应用服务器和文件服务器分开,应用服务器需要更多的内存资源或者CPU资源,而文件服务器需要更多的磁盘资源。
7.通过WebSocket推送通知
通过上面的功能已经导出了excel文件,并且上传到了OSS文件服务器上。
接下来的任务是要本次excel导出结果,成功还是失败,通知目标用户。
有种做法是在页面上提示:正在导出excel数据,请耐心等待。
然后用户可以主动刷新当前页面,获取本地导出excel的结果。
但这种用户交互功能,不太友好。
还有一种方式是通过webSocket建立长连接,进行实时通知推送。
如果你使用了SpringBoot框架,可以直接引入webSocket的相关jar包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
使用起来挺方便的。
我们可以加一张专门的通知表,记录通过webSocket推送的通知的标题、用户、附件地址、阅读状态、类型等信息。
能更好的追溯通知记录。
webSocket给客户端推送一个通知之后,用户的右上角的收件箱上,实时出现了一个小窗口,提示本次导出excel功能是成功还是失败,并且有文件下载链接。
当前通知的阅读状态是未读。
用户点击该窗口,可以看到通知的详细内容,然后通知状态变成已读。
8.总条数可配置
我们在做导百万级数据这个需求时,是给用户用的,也有可能是给运营同学用的。
其实我们应该站在实际用户的角度出发,去思考一下,这个需求是否合理。
用户拿到这个百万级别的excel文件,到底有什么用途,在他们的电脑上能否打开该excel文件,电脑是否会出现太大的卡顿了,导致文件使用不了。
如果该功能上线之后,真的发生发生这些情况,那么导出excel也没有啥意义了。
因此,非常有必要把记录的总条数,做成可配置的,可以根据用户的实际情况调整这个配置。
比如:用户发现excel中有50万的数据,可以正常访问和操作excel,这时候我们可以将总条数调整成500000,把多余的数据截取掉。
其实,在用户的操作界面,增加更多的查询条件,用户通过修改查询条件,多次导数据,可以实现将所有数据都导出的功能,这样可能更合理一些。
此外,分页查询时,每页的大小,也建议做成可配置的。
通过总条数和每页大小,可以动态调整记录数量和分页查询次数,有助于更好满足用户的需求。
无极低码 :https://wheart.cn
-
2024-08-15 22:52:35.0
GIS,等值面,绘图,插值算法
-
2024-08-15 08:40:56.0
GIS,等值面,绘图,插值算法
-
2024-03-10 21:50:52.0
编程,程序,java,教程,程序员,入门教程
-
2024-03-10 21:45:00.0
编程,程序,java,教程,程序员,入门教程
-
2024-03-10 21:41:35.0
编程,程序,java,教程,程序员,入门教程,Java集合
-
2024-02-21 14:32:13.0
卫星,风云,经纬度,webgis
-
2024-02-19 11:45:08.0
spring,java,springboot,后端框架,springmvc,springcloud
-
2024-02-17 14:47:05.0
java,分布式,redis,高并发
-
2023-07-16 15:39:13.0
Java,并发原理入门教程并发锁锁机制之Condition接口
-
2023-07-16 15:39:13.0
Java,并发原理入门教程并发锁多线程售票案例
-
2023-07-16 15:39:12.0
Java,并发原理入门教程并发锁读写锁ReentrantReadWriteLock
-
2023-07-16 15:39:11.0
Java,并发原理入门教程并发锁Unsafe类的使用
-
2023-07-16 15:39:11.0
Java,并发原理入门教程并发锁JAVA多线程锁介绍
-
2023-07-16 15:39:11.0
Java,并发原理入门教程并发锁并发锁之Lock接口
-
2023-07-16 15:39:11.0
Java,并发原理入门教程并发锁乐观锁与悲观锁
-
2023-07-16 15:39:11.0
Java,并发原理入门教程并发锁AQS原理
-
2023-07-16 15:39:11.0
Java,并发原理入门教程并发锁ReentrantLock使用
-
2023-07-16 15:39:11.0
Java,并发原理入门教程并发锁锁的可重入性验证
-
2023-07-16 15:39:10.0
Java,并发原理入门教程并发锁线程的状态详解
-
2023-07-16 15:39:10.0
Java,并发原理入门教程并发锁synchronized关键字
-
2023-07-16 15:39:10.0
Java,并发原理入门教程并发锁生产者与消费者案例
-
2023-07-16 15:39:10.0
Java,并发原理入门教程并发锁volatile关键字
-
2023-07-16 15:39:10.0
Java,并发原理入门教程并发锁CAS操作原理
-
2023-07-16 15:39:10.0
Java,并发原理入门教程并发锁Unsafe类方法介绍
-
2023-07-16 15:39:09.0
Java,并发原理入门教程并发锁多线程yield方法
-
2023-07-16 15:39:09.0
Java,并发原理入门教程并发锁线程上下文切换与死锁
-
2023-07-16 15:39:09.0
Java,并发原理入门教程并发锁守护线程与用户线程
-
2023-07-16 15:39:09.0
Java,并发原理入门教程并发锁ThreadLocal的使用
-
2023-07-16 15:39:09.0
Java,并发原理入门教程并发锁多线程的操作原则
-
2023-07-16 15:39:08.0
Java,并发原理入门教程多线程的安全与同步读写锁ReentrantReadWriteLock
-
2023-07-16 15:39:08.0
Java,并发原理入门教程多线程的安全与同步锁机制之Condition接口
-
2023-07-16 15:39:08.0
Java,并发原理入门教程多线程的安全与同步多线程售票案例
-
2023-07-16 15:39:08.0
Java,并发原理入门教程并发锁并发编程简介
-
2023-07-16 15:39:08.0
Java,并发原理入门教程并发锁操作系统的并发
-
2023-07-16 15:39:08.0
Java,并发原理入门教程并发锁Java,线程内存模型
-
2023-07-16 15:39:08.0
Java,并发原理入门教程并发锁Java,多线程的创建
-
2023-07-16 15:39:08.0
Java,并发原理入门教程并发锁多线程,join,方法
-
2023-07-16 15:39:07.0
Java,并发原理入门教程多线程的安全与同步AQS原理
-
2023-07-16 15:39:07.0
Java,并发原理入门教程多线程的安全与同步ReentrantLock使用
-
2023-07-16 15:39:07.0
Java,并发原理入门教程多线程的安全与同步锁的可重入性验证
-
2023-07-16 15:39:06.0
Java,并发原理入门教程多线程的安全与同步volatile关键字
-
2023-07-16 15:39:06.0
Java,并发原理入门教程多线程的安全与同步CAS操作原理
-
2023-07-16 15:39:06.0
Java,并发原理入门教程多线程的安全与同步Unsafe类方法介绍
-
2023-07-16 15:39:06.0
Java,并发原理入门教程多线程的安全与同步Unsafe类的使用
-
2023-07-16 15:39:06.0
Java,并发原理入门教程多线程的安全与同步JAVA多线程锁介绍
-
2023-07-16 15:39:06.0
Java,并发原理入门教程多线程的安全与同步并发锁之Lock接口
-
2023-07-16 15:39:06.0
Java,并发原理入门教程多线程的安全与同步乐观锁与悲观锁
-
2023-07-16 15:39:05.0
Java,并发原理入门教程多线程的安全与同步守护线程与用户线程
-
2023-07-16 15:39:05.0
Java,并发原理入门教程多线程的安全与同步ThreadLocal的使用
-
2023-07-16 15:39:05.0
Java,并发原理入门教程多线程的安全与同步多线程的操作原则
-
2023-07-16 15:39:05.0
Java,并发原理入门教程多线程的安全与同步线程的状态详解
-
2023-07-16 15:39:05.0
Java,并发原理入门教程多线程的安全与同步synchronized关键字
-
2023-07-16 15:39:05.0
Java,并发原理入门教程多线程的安全与同步生产者与消费者案例
-
2023-07-16 15:39:04.0
Java,并发原理入门教程多线程的安全与同步Java,线程内存模型
-
2023-07-16 15:39:04.0
Java,并发原理入门教程多线程的安全与同步Java,多线程的创建
-
2023-07-16 15:39:04.0
Java,并发原理入门教程多线程的安全与同步多线程,join,方法
-
2023-07-16 15:39:04.0
Java,并发原理入门教程多线程的安全与同步多线程yield方法
-
2023-07-16 15:39:04.0
Java,并发原理入门教程多线程的安全与同步线程上下文切换与死锁
-
2023-07-16 15:39:03.0
Java,并发原理入门教程并发编程基础锁机制之Condition接口
-
2023-07-16 15:39:03.0
Java,并发原理入门教程并发编程基础多线程售票案例
-
2023-07-16 15:39:03.0
Java,并发原理入门教程多线程的安全与同步并发编程简介
-
2023-07-16 15:39:03.0
Java,并发原理入门教程多线程的安全与同步操作系统的并发
-
2023-07-16 15:39:02.0
Java,并发原理入门教程并发编程基础乐观锁与悲观锁
-
2023-07-16 15:39:02.0
Java,并发原理入门教程并发编程基础AQS原理
-
2023-07-16 15:39:02.0
Java,并发原理入门教程并发编程基础ReentrantLock使用
-
2023-07-16 15:39:02.0
Java,并发原理入门教程并发编程基础锁的可重入性验证
-
2023-07-16 15:39:02.0
Java,并发原理入门教程并发编程基础读写锁ReentrantReadWriteLock
-
2023-07-16 15:39:01.0
Java,并发原理入门教程并发编程基础Unsafe类方法介绍
-
2023-07-16 15:39:01.0
Java,并发原理入门教程并发编程基础Unsafe类的使用
-
2023-07-16 15:39:01.0
Java,并发原理入门教程并发编程基础JAVA多线程锁介绍
-
2023-07-16 15:39:01.0
Java,并发原理入门教程并发编程基础并发锁之Lock接口
-
2023-07-16 15:39:00.0
Java,并发原理入门教程并发编程基础线程的状态详解
-
2023-07-16 15:39:00.0
Java,并发原理入门教程并发编程基础synchronized关键字
-
2023-07-16 15:39:00.0
Java,并发原理入门教程并发编程基础生产者与消费者案例
-
2023-07-16 15:39:00.0
Java,并发原理入门教程并发编程基础volatile关键字
-
2023-07-16 15:39:00.0
Java,并发原理入门教程并发编程基础CAS操作原理
-
2023-07-16 15:38:59.0
Java,并发原理入门教程并发编程基础守护线程与用户线程
-
2023-07-16 15:38:59.0
Java,并发原理入门教程并发编程基础ThreadLocal的使用
-
2023-07-16 15:38:59.0
Java,并发原理入门教程并发编程基础多线程的操作原则
-
2023-07-16 15:38:58.0
Java,并发原理入门教程并发编程基础Java,多线程的创建
-
2023-07-16 15:38:58.0
Java,并发原理入门教程并发编程基础多线程,join,方法
-
2023-07-16 15:38:58.0
Java,并发原理入门教程并发编程基础多线程yield方法
-
2023-07-16 15:38:58.0
Java,并发原理入门教程并发编程基础线程上下文切换与死锁
-
2023-07-16 15:38:57.0
Java,并发原理入门教程并发编程基础并发编程简介
-
2023-07-16 15:38:57.0
Java,并发原理入门教程并发编程基础操作系统的并发
-
2023-07-16 15:38:57.0
Java,并发原理入门教程并发编程基础Java,线程内存模型
-
2023-07-16 14:28:20.0
Java,入门教程实战函数式接口
-
2023-07-16 14:28:20.0
Java,入门教程实战方法引用
-
2023-07-16 14:28:20.0
Java,入门教程实战Java,流式操作
-
2023-07-16 14:28:20.0
Java,入门教程实战Optional,类
-
2023-07-16 14:28:20.0
Java,入门教程实战需求分析
-
2023-07-16 14:28:20.0
Java,入门教程实战数据库设计
-
2023-07-16 14:28:20.0
Java,入门教程实战业务实现,1
-
2023-07-16 14:28:20.0
Java,入门教程实战业务实现2
-
2023-07-16 14:28:19.0
Java,入门教程实战Java,输入输出流
-
2023-07-16 14:28:19.0
Java,入门教程实战Java,序列化与反序列化
-
2023-07-16 14:28:19.0
Java,入门教程实战Java,日期时间处理
-
2023-07-16 14:28:19.0
Java,入门教程实战Java,多线程
-
2023-07-16 14:28:19.0
Java,入门教程实战Java,数据库编程
-
2023-07-16 14:28:19.0
Java,入门教程实战Java,8,新特性
-
2023-07-16 14:28:19.0
Java,入门教程实战Lambda,表达式
-
2023-07-16 14:28:18.0
Java,入门教程实战Java,Scanner,类
-
2023-07-16 14:28:18.0
Java,入门教程实战Java,异常处理
-
2023-07-16 14:28:18.0
Java,入门教程实战Java,包装类
-
2023-07-16 14:28:18.0
Java,入门教程实战Java,枚举类
-
2023-07-16 14:28:18.0
Java,入门教程实战Java,集合
-
2023-07-16 14:28:18.0
Java,入门教程实战Java,泛型
-
2023-07-16 14:28:18.0
Java,入门教程实战Java,反射
-
2023-07-16 14:28:18.0
Java,入门教程实战Java,注解
-
2023-07-16 14:28:17.0
Java,入门教程实战Java,类和对象
-
2023-07-16 14:28:17.0
Java,入门教程实战Java,封装
-
2023-07-16 14:28:17.0
Java,入门教程实战Java,继承
-
2023-07-16 14:28:17.0
Java,入门教程实战Java,多态
-
2023-07-16 14:28:17.0
Java,入门教程实战Java,抽象类
-
2023-07-16 14:28:17.0
Java,入门教程实战Java,接口
-
2023-07-16 14:28:17.0
Java,入门教程实战Java,内部类
-
2023-07-16 14:28:17.0
Java,入门教程实战Java,包
-
2023-07-16 14:28:17.0
Java,入门教程实战Java,String,类
-
2023-07-16 14:28:17.0
Java,入门教程实战StringBuilder,类
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,集成开发环境,-,Eclipse
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,集成开发环境,-,IDEA
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,基础语法
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,变量
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,基本数据类型
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,运算符
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,表达式、语句和块
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,条件语句
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,循环语句
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,字符串
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,数组
-
2023-07-16 14:28:16.0
Java,入门教程实战Java,方法
-
2023-07-16 14:28:15.0
Java,入门教程Java,进阶函数式接口
-
2023-07-16 14:28:15.0
Java,入门教程Java,进阶方法引用
-
2023-07-16 14:28:15.0
Java,入门教程Java,进阶Java,流式操作
-
2023-07-16 14:28:15.0
Java,入门教程Java,进阶Optional,类
-
2023-07-16 14:28:15.0
Java,入门教程Java,进阶需求分析
-
2023-07-16 14:28:15.0
Java,入门教程Java,进阶数据库设计
-
2023-07-16 14:28:15.0
Java,入门教程Java,进阶业务实现,1
-
2023-07-16 14:28:15.0
Java,入门教程Java,进阶业务实现2
-
2023-07-16 14:28:15.0
Java,入门教程实战Java,简介
-
2023-07-16 14:28:15.0
Java,入门教程实战在,Windows,上安装,Java
-
2023-07-16 14:28:15.0
Java,入门教程实战在,MacOS,上安装,Java
-
2023-07-16 14:28:15.0
Java,入门教程实战在,Linux,上安装,Java
-
2023-07-16 14:28:15.0
Java,入门教程实战第一个,Java,程序
-
2023-07-16 14:28:14.0
Java,入门教程Java,进阶Java,反射
-
2023-07-16 14:28:14.0
Java,入门教程Java,进阶Java,注解
-
2023-07-16 14:28:14.0
Java,入门教程Java,进阶Java,输入输出流
-
2023-07-16 14:28:14.0
Java,入门教程Java,进阶Java,序列化与反序列化
-
2023-07-16 14:28:14.0
Java,入门教程Java,进阶Java,日期时间处理
-
2023-07-16 14:28:14.0
Java,入门教程Java,进阶Java,多线程
-
2023-07-16 14:28:14.0
Java,入门教程Java,进阶Java,数据库编程
-
2023-07-16 14:28:14.0
Java,入门教程Java,进阶Java,8,新特性
-
2023-07-16 14:28:14.0
Java,入门教程Java,进阶Lambda,表达式
-
2023-07-16 14:28:13.0
Java,入门教程Java,进阶Java,包
-
2023-07-16 14:28:13.0
Java,入门教程Java,进阶Java,String,类
-
2023-07-16 14:28:13.0
Java,入门教程Java,进阶StringBuilder,类
-
2023-07-16 14:28:13.0
Java,入门教程Java,进阶Java,Scanner,类
-
2023-07-16 14:28:13.0
Java,入门教程Java,进阶Java,异常处理
-
2023-07-16 14:28:13.0
Java,入门教程Java,进阶Java,包装类
-
2023-07-16 14:28:13.0
Java,入门教程Java,进阶Java,枚举类
-
2023-07-16 14:28:13.0
Java,入门教程Java,进阶Java,集合
-
2023-07-16 14:28:13.0
Java,入门教程Java,进阶Java,泛型
-
2023-07-16 14:28:12.0
Java,入门教程Java,进阶Java,继承
-
2023-07-16 14:28:12.0
Java,入门教程Java,进阶Java,多态
-
2023-07-16 14:28:12.0
Java,入门教程Java,进阶Java,抽象类
-
2023-07-16 14:28:12.0
Java,入门教程Java,进阶Java,接口
-
2023-07-16 14:28:12.0
Java,入门教程Java,进阶Java,内部类
-
2023-07-16 14:28:11.0
Java,入门教程Java,进阶Java,字符串
-
2023-07-16 14:28:11.0
Java,入门教程Java,进阶Java,数组
-
2023-07-16 14:28:11.0
Java,入门教程Java,进阶Java,方法
-
2023-07-16 14:28:11.0
Java,入门教程Java,进阶Java,类和对象
-
2023-07-16 14:28:11.0
Java,入门教程Java,进阶Java,封装
-
2023-07-16 14:28:10.0
Java,入门教程Java,进阶Java,运算符
-
2023-07-16 14:28:10.0
Java,入门教程Java,进阶Java,表达式、语句和块
-
2023-07-16 14:28:10.0
Java,入门教程Java,进阶Java,条件语句
-
2023-07-16 14:28:10.0
Java,入门教程Java,进阶Java,循环语句
-
2023-07-16 14:28:09.0
Java,入门教程Java,进阶Java,基础语法
-
2023-07-16 14:28:09.0
Java,入门教程Java,进阶Java,变量
-
2023-07-16 14:28:09.0
Java,入门教程Java,进阶Java,基本数据类型
-
2023-07-16 14:28:08.0
Java,入门教程Java,面向对象业务实现,1
-
2023-07-16 14:28:08.0
Java,入门教程Java,面向对象业务实现2
-
2023-07-16 14:28:08.0
Java,入门教程Java,进阶Java,简介
-
2023-07-16 14:28:08.0
Java,入门教程Java,进阶在,Windows,上安装,Java
-
2023-07-16 14:28:08.0
Java,入门教程Java,进阶在,MacOS,上安装,Java
-
2023-07-16 14:28:08.0
Java,入门教程Java,进阶在,Linux,上安装,Java
-
2023-07-16 14:28:08.0
Java,入门教程Java,进阶第一个,Java,程序
-
2023-07-16 14:28:08.0
Java,入门教程Java,进阶Java,集成开发环境,-,Eclipse
-
2023-07-16 14:28:08.0
Java,入门教程Java,进阶Java,集成开发环境,-,IDEA
-
2023-07-16 14:28:07.0
Java,入门教程Java,面向对象Java,流式操作
-
2023-07-16 14:28:07.0
Java,入门教程Java,面向对象Optional,类
-
2023-07-16 14:28:07.0
Java,入门教程Java,面向对象需求分析
-
2023-07-16 14:28:07.0
Java,入门教程Java,面向对象数据库设计
-
2023-07-16 14:28:06.0
Java,入门教程Java,面向对象Java,数据库编程
-
2023-07-16 14:28:06.0
Java,入门教程Java,面向对象Java,8,新特性
-
2023-07-16 14:28:06.0
Java,入门教程Java,面向对象Lambda,表达式
-
2023-07-16 14:28:06.0
Java,入门教程Java,面向对象函数式接口
-
2023-07-16 14:28:06.0
Java,入门教程Java,面向对象方法引用
-
2023-07-16 14:28:05.0
Java,入门教程Java,面向对象Java,输入输出流
-
2023-07-16 14:28:05.0
Java,入门教程Java,面向对象Java,序列化与反序列化
-
2023-07-16 14:28:05.0
Java,入门教程Java,面向对象Java,日期时间处理
-
2023-07-16 14:28:05.0
Java,入门教程Java,面向对象Java,多线程
-
2023-07-16 14:28:04.0
Java,入门教程Java,面向对象Java,集合
-
2023-07-16 14:28:04.0
Java,入门教程Java,面向对象Java,泛型
-
2023-07-16 14:28:04.0
Java,入门教程Java,面向对象Java,反射
-
2023-07-16 14:28:04.0
Java,入门教程Java,面向对象Java,注解
-
2023-07-16 14:28:03.0
Java,入门教程Java,面向对象Java,异常处理
-
2023-07-16 14:28:03.0
Java,入门教程Java,面向对象Java,包装类
-
2023-07-16 14:28:03.0
Java,入门教程Java,面向对象Java,枚举类
-
2023-07-16 14:28:02.0
Java,入门教程Java,面向对象Java,内部类
-
2023-07-16 14:28:02.0
Java,入门教程Java,面向对象Java,包
-
2023-07-16 14:28:02.0
Java,入门教程Java,面向对象Java,String,类
-
2023-07-16 14:28:02.0
Java,入门教程Java,面向对象StringBuilder,类
-
2023-07-16 14:28:02.0
Java,入门教程Java,面向对象Java,Scanner,类
-
2023-07-16 14:28:01.0
Java,入门教程Java,面向对象Java,封装
-
2023-07-16 14:28:01.0
Java,入门教程Java,面向对象Java,继承
-
2023-07-16 14:28:01.0
Java,入门教程Java,面向对象Java,多态
-
2023-07-16 14:28:01.0
Java,入门教程Java,面向对象Java,抽象类
-
2023-07-16 14:28:01.0
Java,入门教程Java,面向对象Java,接口
-
2023-07-16 14:28:00.0
Java,入门教程Java,面向对象Java,方法
-
2023-07-16 14:28:00.0
Java,入门教程Java,面向对象Java,类和对象
-
2023-07-16 14:27:59.0
Java,入门教程Java,面向对象Java,运算符
-
2023-07-16 14:27:59.0
Java,入门教程Java,面向对象Java,表达式、语句和块
-
2023-07-16 14:27:59.0
Java,入门教程Java,面向对象Java,条件语句
-
2023-07-16 14:27:59.0
Java,入门教程Java,面向对象Java,循环语句
-
2023-07-16 14:27:59.0
Java,入门教程Java,面向对象Java,字符串
-
2023-07-16 14:27:59.0
Java,入门教程Java,面向对象Java,数组
-
2023-07-16 14:27:58.0
Java,入门教程Java,面向对象Java,变量
-
2023-07-16 14:27:58.0
Java,入门教程Java,面向对象Java,基本数据类型
-
2023-07-16 14:27:57.0
Java,入门教程Java,面向对象Java,集成开发环境,-,Eclipse
-
2023-07-16 14:27:57.0
Java,入门教程Java,面向对象Java,集成开发环境,-,IDEA
-
2023-07-16 14:27:57.0
Java,入门教程Java,面向对象Java,基础语法
-
2023-07-16 14:27:56.0
Java,入门教程Java,基础业务实现,1
-
2023-07-16 14:27:56.0
Java,入门教程Java,基础业务实现2
-
2023-07-16 14:27:56.0
Java,入门教程Java,面向对象Java,简介
-
2023-07-16 14:27:56.0
Java,入门教程Java,面向对象在,Windows,上安装,Java
-
2023-07-16 14:27:56.0
Java,入门教程Java,面向对象在,MacOS,上安装,Java
-
2023-07-16 14:27:56.0
Java,入门教程Java,面向对象在,Linux,上安装,Java
-
2023-07-16 14:27:56.0
Java,入门教程Java,面向对象第一个,Java,程序
-
2023-07-16 14:27:55.0
Java,入门教程Java,基础方法引用
-
2023-07-16 14:27:55.0
Java,入门教程Java,基础Java,流式操作
-
2023-07-16 14:27:55.0
Java,入门教程Java,基础Optional,类
-
2023-07-16 14:27:55.0
Java,入门教程Java,基础需求分析
-
2023-07-16 14:27:55.0
Java,入门教程Java,基础数据库设计
-
2023-07-16 14:27:54.0
Java,入门教程Java,基础Java,多线程
-
2023-07-16 14:27:54.0
Java,入门教程Java,基础Java,数据库编程
-
2023-07-16 14:27:54.0
Java,入门教程Java,基础Java,8,新特性
-
2023-07-16 14:27:54.0
Java,入门教程Java,基础Lambda,表达式
-
2023-07-16 14:27:54.0
Java,入门教程Java,基础函数式接口
-
2023-07-16 14:27:53.0
Java,入门教程Java,基础Java,注解
-
2023-07-16 14:27:53.0
Java,入门教程Java,基础Java,输入输出流
-
2023-07-16 14:27:53.0
Java,入门教程Java,基础Java,序列化与反序列化
-
2023-07-16 14:27:53.0
Java,入门教程Java,基础Java,日期时间处理
-
2023-07-16 14:27:52.0
Java,入门教程Java,基础Java,集合
-
2023-07-16 14:27:52.0
Java,入门教程Java,基础Java,泛型
-
2023-07-16 14:27:52.0
Java,入门教程Java,基础Java,反射
-
2023-07-16 14:27:51.0
Java,入门教程Java,基础Java,String,类
-
2023-07-16 14:27:51.0
Java,入门教程Java,基础StringBuilder,类
-
2023-07-16 14:27:51.0
Java,入门教程Java,基础Java,Scanner,类
-
2023-07-16 14:27:51.0
Java,入门教程Java,基础Java,异常处理
-
2023-07-16 14:27:51.0
Java,入门教程Java,基础Java,包装类
-
2023-07-16 14:27:51.0
Java,入门教程Java,基础Java,枚举类
-
2023-07-16 14:27:50.0
Java,入门教程Java,基础Java,接口
-
2023-07-16 14:27:50.0
Java,入门教程Java,基础Java,内部类
-
2023-07-16 14:27:50.0
Java,入门教程Java,基础Java,包
-
2023-07-16 14:27:49.0
Java,入门教程Java,基础Java,方法
-
2023-07-16 14:27:49.0
Java,入门教程Java,基础Java,类和对象
-
2023-07-16 14:27:49.0
Java,入门教程Java,基础Java,封装
-
2023-07-16 14:27:49.0
Java,入门教程Java,基础Java,继承
-
2023-07-16 14:27:49.0
Java,入门教程Java,基础Java,多态
-
2023-07-16 14:27:49.0
Java,入门教程Java,基础Java,抽象类
-
2023-07-16 14:27:48.0
Java,入门教程Java,基础Java,条件语句
-
2023-07-16 14:27:48.0
Java,入门教程Java,基础Java,循环语句
-
2023-07-16 14:27:48.0
Java,入门教程Java,基础Java,字符串
-
2023-07-16 14:27:48.0
Java,入门教程Java,基础Java,数组
-
2023-07-16 14:27:47.0
Java,入门教程Java,基础Java,基本数据类型
-
2023-07-16 14:27:47.0
Java,入门教程Java,基础Java,运算符
-
2023-07-16 14:27:47.0
Java,入门教程Java,基础Java,表达式、语句和块
-
2023-07-16 14:27:46.0
Java,入门教程Java,基础第一个,Java,程序
-
2023-07-16 14:27:46.0
Java,入门教程Java,基础Java,集成开发环境,-,Eclipse
-
2023-07-16 14:27:46.0
Java,入门教程Java,基础Java,集成开发环境,-,IDEA
-
2023-07-16 14:27:46.0
Java,入门教程Java,基础Java,基础语法
-
2023-07-16 14:27:46.0
Java,入门教程Java,基础Java,变量
-
2023-07-16 14:27:45.0
Java,入门教程Java,简介与安装配置业务实现2
-
2023-07-16 14:27:45.0
Java,入门教程Java,基础Java,简介
-
2023-07-16 14:27:45.0
Java,入门教程Java,基础在,Windows,上安装,Java
-
2023-07-16 14:27:45.0
Java,入门教程Java,基础在,MacOS,上安装,Java
-
2023-07-16 14:27:45.0
Java,入门教程Java,基础在,Linux,上安装,Java
-
2023-07-16 14:27:44.0
Java,入门教程Java,简介与安装配置Optional,类
-
2023-07-16 14:27:44.0
Java,入门教程Java,简介与安装配置需求分析
-
2023-07-16 14:27:44.0
Java,入门教程Java,简介与安装配置数据库设计
-
2023-07-16 14:27:44.0
Java,入门教程Java,简介与安装配置业务实现,1
-
2023-07-16 14:27:43.0
Java,入门教程Java,简介与安装配置Lambda,表达式
-
2023-07-16 14:27:43.0
Java,入门教程Java,简介与安装配置函数式接口
-
2023-07-16 14:27:43.0
Java,入门教程Java,简介与安装配置方法引用
-
2023-07-16 14:27:43.0
Java,入门教程Java,简介与安装配置Java,流式操作
-
2023-07-16 14:27:42.0
Java,入门教程Java,简介与安装配置Java,数据库编程
-
2023-07-16 14:27:42.0
Java,入门教程Java,简介与安装配置Java,8,新特性
-
2023-07-16 14:27:41.0
Java,入门教程Java,简介与安装配置Java,注解
-
2023-07-16 14:27:41.0
Java,入门教程Java,简介与安装配置Java,输入输出流
-
2023-07-16 14:27:41.0
Java,入门教程Java,简介与安装配置Java,序列化与反序列化
-
2023-07-16 14:27:41.0
Java,入门教程Java,简介与安装配置Java,日期时间处理
-
2023-07-16 14:27:41.0
Java,入门教程Java,简介与安装配置Java,多线程
-
2023-07-16 14:27:40.0
Java,入门教程Java,简介与安装配置Java,集合
-
2023-07-16 14:27:40.0
Java,入门教程Java,简介与安装配置Java,泛型
-
2023-07-16 14:27:40.0
Java,入门教程Java,简介与安装配置Java,反射
-
2023-07-16 14:27:39.0
Java,入门教程Java,简介与安装配置Java,Scanner,类
-
2023-07-16 14:27:39.0
Java,入门教程Java,简介与安装配置Java,异常处理
-
2023-07-16 14:27:39.0
Java,入门教程Java,简介与安装配置Java,包装类
-
2023-07-16 14:27:39.0
Java,入门教程Java,简介与安装配置Java,枚举类
-
2023-07-16 14:27:38.0
Java,入门教程Java,简介与安装配置Java,内部类
-
2023-07-16 14:27:38.0
Java,入门教程Java,简介与安装配置Java,包
-
2023-07-16 14:27:38.0
Java,入门教程Java,简介与安装配置Java,String,类
-
2023-07-16 14:27:38.0
Java,入门教程Java,简介与安装配置StringBuilder,类
-
2023-07-16 14:27:37.0
Java,入门教程Java,简介与安装配置Java,继承
-
2023-07-16 14:27:37.0
Java,入门教程Java,简介与安装配置Java,多态
-
2023-07-16 14:27:37.0
Java,入门教程Java,简介与安装配置Java,抽象类
-
2023-07-16 14:27:37.0
Java,入门教程Java,简介与安装配置Java,接口
-
2023-07-16 14:27:36.0
Java,入门教程Java,简介与安装配置Java,数组
-
2023-07-16 14:27:36.0
Java,入门教程Java,简介与安装配置Java,方法
-
2023-07-16 14:27:36.0
Java,入门教程Java,简介与安装配置Java,类和对象
-
2023-07-16 14:27:36.0
Java,入门教程Java,简介与安装配置Java,封装
-
2023-07-16 14:27:35.0
Java,入门教程Java,简介与安装配置Java,条件语句
-
2023-07-16 14:27:35.0
Java,入门教程Java,简介与安装配置Java,循环语句
-
2023-07-16 14:27:35.0
Java,入门教程Java,简介与安装配置Java,字符串
-
2023-07-16 14:27:34.0
Java,入门教程Java,简介与安装配置Java,基本数据类型
-
2023-07-16 14:27:34.0
Java,入门教程Java,简介与安装配置Java,运算符
-
2023-07-16 14:27:34.0
Java,入门教程Java,简介与安装配置Java,表达式、语句和块
-
2023-07-16 14:27:33.0
Java,入门教程Java,简介与安装配置Java,集成开发环境,-,Eclipse
-
2023-07-16 14:27:33.0
Java,入门教程Java,简介与安装配置Java,集成开发环境,-,IDEA
-
2023-07-16 14:27:33.0
Java,入门教程Java,简介与安装配置Java,基础语法
-
2023-07-16 14:27:33.0
Java,入门教程Java,简介与安装配置Java,变量
-
2023-07-16 14:27:32.0
Java,入门教程Java,简介与安装配置在,Windows,上安装,Java
-
2023-07-16 14:27:32.0
Java,入门教程Java,简介与安装配置在,MacOS,上安装,Java
-
2023-07-16 14:27:32.0
Java,入门教程Java,简介与安装配置在,Linux,上安装,Java
-
2023-07-16 14:27:32.0
Java,入门教程Java,简介与安装配置第一个,Java,程序
-
2023-07-16 14:27:31.0
Java,入门教程Java,简介与安装配置Java,简介