滚雪球学Java(74):深入理解JavaSE输入输出流:掌握数据流动的奥秘

在这里插入图片描述

  咦咦咦,各位小可爱,我是你们的好伙伴 bug菌,今天又来给大家手把手教学Java SE系列知识点啦,赶紧出来哇,别躲起来啊,听我讲干货记得点点赞,赞多了我就更有动力讲得更欢哦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~


🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8

文章目录

  • 前言
  • 摘要
  • 正文
    • 简介
    • 源代码解析
      • InputStream类
      • OutputStream类
      • BufferedInputStream类
      • BufferedOutputStream类
    • 应用场景案例
      • 文件复制
    • 优缺点讲解
      • 优点分析
      • 缺点分析
    • 类常用方法介绍
      • InputStream类
      • OutputStream类
      • BufferedInputStream类
      • BufferedOutputStream类
    • 测试用例
      • 测试代码
      • 测试代码分析
      • 测试结果
    • 小结
  • 全文总结
    • 附录源码
  • ☀️建议/推荐你
  • 📣关于我

前言

  首先,我们都知道输入输出流是Java SE开发中非常重要的一个组成部分,它们可以让程序与外部环境进行数据的交互,若无进行数据交换,则无法动态展示数据。借此,本文将深入探讨JavaSE中的输入输出流机制,并通过详细的源代码解析和实际应用场景案例,帮助大家全面理解JavaSE输入输出流的原理和用法,这对日常工作中的你或者即将步入职场的你都及其有帮助。

摘要

  JavaSE针对输入输出流,它提供了非常丰富的类和方法,供日常处理各种类型的数据流动。通过输入流,我们可以读取外部数据到程序中,拿到数据再进一步操作等;而对应输出流,我们可以将程序中的数据输出到外部环境。这里大家需要理解和灵活运用 Java之输入输出流,这也是身为Java开发人员(程序猿)必备的技能,毕竟我入社会也是从这些知识点学起的。

正文

简介

  首先,大家需要明确知道一点,JavaSE的输入输出流,它是属于面向字节的流,是基于抽象类InputStreamOutputStream以及相应的子类来实现的。数据流动的核心是字节流,而JavaSE中就提供了许多类和方法供大家可方便的操作字节流。下面我们将对JavaSE输入输出流的一些常用类进行源码解析及实战演示,以便于同学们加深理解。

源代码解析

InputStream类

  InputStream,首先它是一个抽象类,它定义了读取字节流的基本方法和属性,比如read()skip(long n)read(byte[] b, int off, int len)close()等,除了这些基本的读取方法外,InputStream还提供了一些其他方法,比如mark(int readlimit)reset()方法,允许在流中标记一个位置,并在需要时返回到该位置。它常用的子类有FileInputStreamByteArrayInputStream。其中,FileInputStream可以从文件中读取数据,而ByteArrayInputStream则可以从字节数组中读取数据。

源码部分截图,如下示意:

在这里插入图片描述
  需要注意的是,由于InputStream是一个抽象类,它是不能直接实例化,只能通过其子类来实现具体的输入流。

OutputStream类

  OutputStream,InputStream类一样,也是一个抽象类;它定义了写入字节流的基本方法。常用的子类有FileOutputStream和ByteArrayOutputStream,我们可以使用它的子类来读取和写入字节流。其中,FileOutputStream可以将数据写入到文件中,而ByteArrayOutputStream则可以将数据写入到字节数组中,这点我们在后面会直接演示给大家看,这里就不详细赘述了。

  对于OutputStream类,它的主要子类有,参考如下:

  • FileOutputStream:用于将数据写入文件。
  • ByteArrayOutputStream:用于将数据写入字节数组。
  • FilterOutputStream:用于添加过滤器功能,例如数据压缩或加密。
  • DataOutputStream:用于将基本数据类型写入输出流。
  • ObjectOutputStream:用于将对象写入输出流。

  接着,OutputStream类定义了以下常用方法,仅供参考:

  • write(int b):将一个字节写入输出流。
  • write(byte[] b):将一个字节数组写入输出流。
  • write(byte[] b, int off, int len):将一个指定长度的字节数组的一部分写入输出流。
  • flush():刷新输出流,确保所有缓冲的字节都被写入输出流。
  • close():关闭输出流,释放相关的资源。

BufferedInputStream类

  BufferedInputStream,它是InputStream类的装饰者类,它提供了带缓冲功能的读取方法,可以提高读取效率。BufferedInputStream内部维护了一个缓冲区,当需要读取数据时,先从缓冲区读取,如果缓冲区没有数据,则从底层流中读取新的数据。

BufferedOutputStream类

  BufferedOutputStream,它是OutputStream的装饰者类,它提供了带缓冲功能的写入方法,可以提高写入效率。BufferedOutputStream内部维护了一个缓冲区,当需要写入数据时,先将数据写入到缓冲区,当缓冲区满了或者需要刷新时,再将缓冲区的数据写入到底层流中。

应用场景案例

  接下来,我们就通过几个案例,由浅入深式的带着大家从理论过渡到实践中去,帮助大家更好的通过实践来理解理论知识点,“实践是检验真理的唯一标准!”毛爷爷曾言,接下来便开始实践部分。

文件复制

  首先,我们先通过使用输入输出流,实现一个文件的复制功能,这里大家可以先思考一下,不太能想到的也没关系,可以接着看下边的。

  实现思路大致步骤如下:首先我们可以使用FileInputStream类创建一个输入流,然后再使用FileOutputStream创建一个输出流,通过循环的方式依次读取输入流中的数据,并将其写入到输出流中,这样一个就可以实现文件的复制,是不是很简单呢?接着大家来参考下我写的代码。

package com.demo.javase.day74;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*** @Author bug菌* @Date 2023-12-27 16:51*/
public class FileCopy {public static void main(String[] args) {try {FileInputStream in = new FileInputStream("source.txt");FileOutputStream out = new FileOutputStream("target.txt");byte[] buffer = new byte[1024];int length;while ((length = in.read(buffer)) != -1) {out.write(buffer, 0, length);}in.close();out.close();System.out.println("文件复制成功!");} catch (IOException e) {e.printStackTrace();}}
}

代码详细分析:

  如上代码,它是一个文件复制的程序,实现功能就是将source.txt文件内容复制到target.txt文件中,具体实现思路如下,不太懂的同学这里要着重听:

  1. 首先是引入了java.io中的相关类,用于文件的输入和输出操作(这里大家肯定都能懂)。

  2. 其次,定义一个main函数,在main方法中,通过FileInputStream来创建一个输入流对象in,并将源文件"source.txt"作为参数传递给它。

  3. 同样地,再通过FileOutputStream来创建一个输出流对象out,并将目标文件"target.txt"作为参数传递过去。

  4. 创建一个字节数组buffer,用于存储读取到的文件数据。

  5. 依次循环,使用in.read(buffer)方法来读取文件中的内容,并将读取到的字节数保存在length变量中,是不是能懂。

  6. 然后呢,我们就要通过判断length的值,如果值不为-1,表示还有数据可以读取,没读取完,则使用out.write(buffer, 0, length)方法将读取到的数据继续写入目标文件即可。

  7. 然后这里循环继续,那什么时候循环结束呢?很简单,就是判断length的值等于-1时,即文件读取完,这里直接跳过循环。

  8. 最后,记得关闭输入流和输出流(如果不关呢?其实大家也需要知道,如下我单独给大家做个拓展。)。

拓展一下:

如果不关闭输入流和输出流,可能会导致以下问题:

  1. 资源泄漏:输入流和输出流占用系统资源,如果不关闭它们,将导致资源无法被释放和复用,最终可能导致系统性能下降或崩溃。

  2. 内存泄漏:输入流和输出流需要占用一定的内存空间,如果不关闭它们,可能会导致内存泄漏问题,即占用的内存空间无法被释放,导致内存溢出。

  3. 数据丢失:如果未关闭输出流,可能会导致数据未完全写入到磁盘或目标文件中,从而导致数据丢失。

  4. 数据损坏:如果未关闭输出流和输入流,可能会导致数据在传输过程中发生错误或被破坏,导致数据的完整性受到影响。

  5. 接着,我们给个文字提示,输出"文件复制成功!"。

  6. 最后,捕获可能抛出的IOException异常,并打印异常信息。

  以上,就是该程序代码实现文件复制功能的思路了,总的来说就是使用了字节数组作为中间存储器,从输入流读取数据,然后通过输出流写入数据到目标文件中,非常的简单。

优缺点讲解

优点分析

  • 输入输出流,它提供了灵活的访问外部数据的方式,可以读取和写入各种类型的数据。
  • 输入输出流,它可以处理大数据量,通过缓冲区的使用,可以提高读写效率。
  • 输入输出流的接口和方法简单易用,对于开发人员来说学习成本较低。

缺点分析

  • 使用输入输出流操作文件需要处理异常,繁琐而且容易出错(这点实际操作中确实)。
  • 输入输出流只能处理字节流,对于字符数据需要进行字符编码的转换。

类常用方法介绍

  接着,我给同学们梳理下InputStream、BufferedInputStream等类的常用方法介绍,方便大家对比及区分方法。

InputStream类

常用方法包括:

  • int read():读取一个字节的数据。
  • int read(byte[] buffer):读取一组字节的数据,并存储到指定的字节数组中。
  • void close():关闭输入流。
  • long skip(long n):跳过n个字节的数据,并返回实际跳过的字节数。如果已经到达流的末尾,则返回0。
  • int available():返回输入流中可以读取的字节数。

  如上这些方法,可以用来从输入流中读取数据,并处理流的末尾、跳过字节、获取可读字节数等操作,具体演示我们往下看。

OutputStream类

常用方法包括:

  • write(int b):将一个字节写入输出流。
  • write(byte[] b):将一个字节数组的所有字节写入输出流。
  • write(byte[] b, int off, int len):将字节数组的一部分字节写入输出流,从偏移量off开始,写入len个字节。
  • flush():刷新输出流,将缓冲区中的数据强制写入输出流。
  • close():关闭输出流,释放与之关联的系统资源。
  • flush()和close()方法都会自动调用write()方法将缓冲区中的数据写入输出流。

BufferedInputStream类

常用方法包括:

  • public int read() throws IOException:从输入流中读取一个字节,并返回读取的字节的整数表示。如果已到达流的末尾,则返回-1。

  • public int read(byte[] b, int off, int len) throws IOException:从输入流中读取最多len个字节到字节数组b的指定偏移量off处,返回实际读取的字节数。如果已到达流的末尾,则返回-1。

  • public long skip(long n) throws IOException:从输入流中跳过n个字节的数据,并返回实际跳过的字节数。

  • public int available() throws IOException:返回可以从输入流中读取的字节数。

  • public synchronized void mark(int readlimit):在当前位置设置一个标记点。

  • public synchronized void reset() throws IOException:将流重置到上次设置的标记点。

BufferedOutputStream类

  • void write(int b):写入一个字节的数据。
  • void write(byte[] buffer):写入一组字节的数据。
  • void flush():刷新输出流,将缓冲区的数据写入到底层流中。
  • void close():关闭输出流。

测试用例

  如下,到了大家最激动人心的阶段,实战环节,检验下大家理论基础到底学习及掌握的如何?所以,这里我给大家通过几个测试用例,尽可能的使用到它们的一些常规方法,运用到实际代码中去,以辅助大家理解。

测试代码

  这里我定义了一个MyInputStream类,具体测试代码如下,在阅读我写的代码的同时,可以思考下我写的内容有何目的性,运用到了那些常规知识点,代码如下:

package com.demo.javase.day74;import java.io.IOException;
import java.io.InputStream;/*** @Author bug菌* @Date 2023-12-27 16:48*/
public class MyInputStream extends InputStream {private byte[] data = {1, 2, 3, 4, 5};private int pos = 0;@Overridepublic int read() throws IOException {if (pos < data.length) {return data[pos++];} else {return -1;}}
}

不知道大家看懂了我写的这段测试代码没,其实很简单的,无非就是模拟读取数据流。接着我来给大家详细分析一下,这段代码的完整思路

代码分析:

  我先自定义了一个的InputStream类MyInputStream,继承自java.io.InputStream。该类重写了InputStream的read()方法,实现了从一个固定的byte数组data中读取数据的功能。

  在MyInputStream类中,定义了一个私有的byte数组data,用于存储数据。还定义了一个私有的整型变量pos,用于记录读取data中的位置。

  在重写的read()方法中,首先判断pos是否小于data的长度,如果是,表示还有数据可以读取,就返回data[pos]对应的字节,并将pos++。如果pos等于或大于data的长度,表示已经读取完所有数据,返回-1。

  总之,则这个MyInputStream类功能就是用于模拟读取数据流,在每次调用read()方法都可以读取data数组中的下一个字节,仅此而已,你们也可以拓展下。

  接着,我再定义一个MyOutputStream.java,大家可以先看,从代码中理解这段代码干了件什么事,具体实现代码如下:

package com.demo.javase.day74;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class MyOutputStream extends OutputStream {private ByteArrayOutputStream buffer = new ByteArrayOutputStream();@Overridepublic void write(int b) throws IOException {buffer.write(b);}public byte[] getData() {return buffer.toByteArray();}
}

代码分析:

  这里我给大家也解读下,理解这段代码实现了如何功能,大家请看:

  1. 首先,在 MyOutputStream类中有一个成员变量buffer,它是一个ByteArrayOutputStream类型的对象。
  2. ByteArrayOutputStream类是一个在内存中创建字节数组缓冲区的输出流,可以将数据写入到内存中的字节数组中。
  3. MyOutputStream类重写了write方法,该方法将传入的字节写入到buffer中。
  4. getData方法返回buffer的字节数组表示形式。

  总之,这段代码定义了一个自定义的输出流类MyOutputStream,它可以将数据写入到内存中的字节数组中,并可以获取该字节数组的数据,你们学废了么。

测试3

最后,再次给大家演示下,测试输入流和输出流类的实际操作。

package com.demo.javase.day74;import java.io.IOException;/*** @Author bug菌* @Date 2023-12-27 16:49*/
public class Test {public static void main(String[] args) {try {MyInputStream in = new MyInputStream();MyOutputStream out = new MyOutputStream();int b;while ((b = in.read()) != -1) {out.write(b);}in.close();out.close();byte[] data = out.getData();for (byte d : data) {System.out.print(d + " ");}} catch (IOException e) {e.printStackTrace();}}
}

测试代码分析

  根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。

  这段代码主要是测试自定义的输入流和输出流类。在主方法中,首先创建一个MyInputStream对象和一个MyOutputStream对象。然后通过循环,从输入流中读取字节,并将其写入到输出流中。在读取和写入的过程中,如果读取的字节等于-1,即表示输入流已经读取完毕,循环结束。接着调用输入流和输出流的close()方法关闭流。

  然后,通过调用输出流的getData()方法获取输出流中的数据,并将数据以字节数组的形式存储在data数组中。最后,通过遍历data数组,将每个字节打印输出。

  需要注意的是,在上述代码中使用了try-catch块来捕获IOException异常。如果在读写过程中发生异常,将会打印异常信息。

测试结果

  根据如上的测试用例,作者在本地进行测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加其他的测试数据或测试方法,以便于进行熟练学习以此加深知识点的理解。

在这里插入图片描述

小结

  在此,给大家做个小结,本文着重演示了并深入理解JavaSE输入输出流的原理和用法,通过源代码解析和实际应用案例的介绍,可以帮助大家更好地掌握输入输出流的知识。输入输出流在Java开发中非常重要,对于处理外部数据流动具有重要作用。

全文总结

  总而言之,JavaSE输入输出流作为Java开发中不可或缺的部分,通过对InputStream、OutputStream、BufferedInputStream和BufferedOutputStream等类的源代码解析,我们可以了解了它们的基本原理和用法。通过如上的应用场景案例讲解,我们能够更加清楚输入输出流在实际开发中的应用价值。掌握输入输出流的知识,对于Java开发人员来说是非常重要的,所以说,大家听我讲,一定可以轻松掌握。

  … …

  好啦,这期的内容就基本接近尾声啦,若你想学习更多,你可以看看专栏的导读篇《「滚雪球学Java」教程导航帖》,本专栏致力打造最硬核 Java 零基础系列学习内容,🚀打造全网精品硬核专栏,带你直线超车;欢迎大家订阅持续学习。功不唐捐,久久为功!

「赠人玫瑰,手留余香」,咱们下期拜拜~~

附录源码

  如上涉及所有源码均已上传同步在「Gitee」,提供给同学们一对一参考学习,辅助你更迅速的掌握。

☀️建议/推荐你

  无论你是计算机专业的学生,还是对编程感兴趣的跨专业小白,都建议直接入手「滚雪球学Java」专栏;该专栏不仅免费,bug菌还郑重承诺,只要你学习此专栏,均能入门并理解Java SE,以全网最快速掌握Java语言,每章节源码均同步「Gitee」,你真值得拥有;学习就像滚雪球一样,越滚越大,带你指数级提升。

  码字不易,如果这篇文章对你有所帮助,帮忙给bugj菌来个一键三连(关注、点赞、收藏) ,您的支持就是我坚持写作分享知识点传播技术的最大动力。

  同时也推荐大家关注我的硬核公众号:「猿圈奇妙屋」 ;以第一手学习bug菌的首发干货,不仅能学习更多技术硬货,还可白嫖最新BAT大厂面试真题、4000G Pdf技术书籍、万份简历/PPT模板、技术文章Markdown文档等海量资料,你想要的我都有!

📣关于我

我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 20w+;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。


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

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

相关文章

nginx学习记录-动静分离

1. 动静分离原理 我们在访问网站资源的时候&#xff0c;通常会将资源分成两种&#xff0c;一种是静态资源&#xff08;前端的固定界面&#xff0c;比如图片&#xff0c;html页面等&#xff09;&#xff0c;这些资源无需后台程序处理&#xff1b;另一种是动态资源&#xff0c;这…

分布式调度器

xxl-job介绍 xxl-job 是一个轻量级分布式任务调度框架&#xff0c;支持动态添加、修改、删除定时任务&#xff0c;支持海量任务分片执行&#xff0c;支持任务执行日志在线查看和分页查询&#xff0c;同时支持任务失败告警和重试机制&#xff0c;支持分布式部署和高可用。xxl-j…

阿里云、腾讯云、华为云优惠券领取入口整理汇总

阿里云、腾讯云、华为云作为国内领先的云服务提供商&#xff0c;一直以其稳定、高效、安全的服务赢得了广大用户的青睐。为了回馈用户&#xff0c;这些云平台经常会推出各种优惠活动&#xff0c;其中最为常见的便是优惠券。本文将为大家整理汇总阿里云、腾讯云、华为云优惠券的…

linux-centos虚拟机设置固定ip

环境准备 虚拟机版本&#xff1a;centos7 安装环境&#xff1a;vmware17 1、设置网络连接 虚拟机-设置-网络适配器-NAT模式 2、查看子网信息 编辑-虚拟网络编辑器-NAT模式-NAT设置 查看子网ip和网关ip 下一步要用 3、修改配置文件 vim /etc/sysconfig/network-scripts…

构建数据平台架构指导原则与平台核心组件说明

文章目录 前言什么是数据架构&#xff1f;数据架构如何帮助构建数据平台&#xff1f;数据平台核心组件数据源系统数据加载数据存储数据处理和转换提供使用数据的方式公共服务 前言 湖仓一体是最近几年非常流行的现代大数据架构&#xff0c;目前它已经成为设计数据平台架构的首…

Flask框架初探-如何在本机发布一个web服务并通过requests访问自己发布的服务-简易入门版

Flask框架初探 在接触到网络框架之前我其实一直对一个事情有疑惑&#xff0c;跨语言的API在需要传参的情况下究竟应该如何调用&#xff0c;之前做过的项目里&#xff0c;我用python做了一个代码使用一个算法得到一个结果之后我应该怎么给到做前端的同学或者同事&#xff0c;之前…

基于springboot 的医院信管系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven…

SpringBoot新增菜品模块开发(事务管理+批量插入+主键回填)

需求分析与设计 一&#xff1a;产品原型 后台系统中可以管理菜品信息&#xff0c;通过 新增功能来添加一个新的菜品&#xff0c;在添加菜品时需要选择当前菜品所属的菜品分类&#xff0c;并且需要上传菜品图片。 新增菜品原型&#xff1a; 当填写完表单信息, 点击"保存…

【数据分析】AHP层次分析法

博主总结&#xff1a;根据每个方案x各准则因素权重累加结果 对比来选择目标。数据主观性强 简介 AHP层次分析法是一种解决多目标复杂问题的定性和定量相结合进行计算决策权重的研究方法。该方法将定量分析与定性分析结合起来&#xff0c;用决策者的经验判断各衡量目标之间能…

【数字人】AIGC技术引领数字人革命:从制作到应用到全景解析

AIGC技术引领虚拟数字人革命&#xff1a;从制作到应用的全景解析 一、AIGC技术为虚拟数字人注入智能灵魂二、AIGC型虚拟人制作流程实例分析1、采集数据2、建模3、内容生成 三、AIGC在虚拟数字人应用中的案例分析四、总结与展望 在科技的浪潮中&#xff0c;AIGC&#xff08;人工…

Ubuntu:VSCode中编译运行C++代码

版本&#xff1a;Ubuntu22.04.1 LTS 目录 1 安装VSCode并汉化 2 检查Ubuntu是否已经安装了 GCC 3 在VScode中安装C/C扩展 4 在VSCode中进行C/C配置 1 安装VSCode并汉化 安装VSCode&#xff08;参考之前博客Ubuntu&#xff1a;安装VSCode_ubuntu vscode-CSDN博客&#xff…

Linux sort/uniq/wc

文章目录 1. sort 排序将线程ID从大到小排序 2.uniq 临近去重3.wc word cnt 统计 1. sort 排序 将线程ID从大到小排序 grep -v是反向筛选&#xff0c;利用USER&#xff0c;排除掉首行 awk是打印第1 2列 sort -n是代码以数值大小做排序&#xff0c;不加的话会以字符排序。 -k是…

Gitee和Git学习笔记

Gitee和Git指令 Gitee提交代码方法1 先将仓库clone到本地&#xff0c;修改后再push到 Gitee 的仓库方法2 本地初始化一个仓库&#xff0c;设置远程仓库地址后再做push 切换分支下载代码通过git clone克隆仓库通过下载 ZIP 的方式下载代码 Git提交指令 解决本地库同时关联GitHub…

(C语言入门)复合类型、内存管理

目录 复合类型&#xff08;自定义类型&#xff09; 概述&#xff1a; 结构体变量的定义和初始化&#xff1a; 结构体成员的使用&#xff1a; 结构体做函数参数&#xff1a; 结构体值传参&#xff1a; 结构体地址传参&#xff1a; 共用体&#xff08;联合体&#xff09;&…

测试人员如何做好工作量评估和风险把控?

今天想聊一聊关于测试工作量评估及需求进度把控的内容。 我个人觉得有时候评估测试工作量其实也挺难的&#xff0c;比如有的需求没有需求文档&#xff0c;只能靠自己对需求的理解去大概评估&#xff0c;有可能评估的工作量比实际需要的工作量会少点&#xff0c;对于每周进行迭…

【Index to Lectures or Courses】

文章目录 1 Speech / Course2 Material3 Basic knowledge and tools4 职位缩写你知道几个? 1 Speech / Course 《中国文化文概论》&#xff08;武汉大学&#xff09;【Paper material】【阅读笔记】【Reading Notes】&#xff08;1&#xff09;【Reading Notes】&#xff08;…

Mybatis-plus中的分页操作

Mybatis-plus中的分页操作 1.导入Mybatis-plus依赖2.创建mybatis配置类3.参数 1.导入Mybatis-plus依赖 因为是一个springboot项目&#xff0c;其中的pom.xml文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns&q…

用于时空交通数据插补的多注意张量完成网络

用于时空交通数据插补的多注意张量完成网络 摘要:道路传感器在物联网(IoT)中的广泛部署可以实现细粒度的数据集成,这是数据驱动应用程序的基本需求。 由于网络通信不稳定、传感器故障等,不可避免地丢失和实质性异常的传感数据是不可避免的。最近的张量补全研究通过精确捕获…

提高 RAG 应用准确度,时下流行的 Reranker 了解一下?

检索增强生成&#xff08;RAG&#xff09;是一种新兴的 AI 技术栈&#xff0c;通过为大型语言模型&#xff08;LLM&#xff09;提供额外的“最新知识”来增强其能力。 基本的 RAG 应用包括四个关键技术组成部分&#xff1a; Embedding 模型&#xff1a;用于将外部文档和用户查询…

DDoS攻击类型与应对措施详解

攻击与防御简介 SYN Flood攻击 原理&#xff1a; SYN Flood攻击利用的是TCP协议的三次握手机制。在正常的TCP连接建立过程中&#xff0c;客户端发送一个SYN&#xff08;同步序列编号&#xff09;报文给服务器&#xff0c;服务器回应一个SYN-ACK&#xff08;同步和确认&#xf…