JavaSE进阶——玩转IO流

news2025/4/6 11:50:50

文章目录

  • 前言
  • 一、File类介绍
    • 1、概念引入
    • 2、实际应用
      • 2.1 操作文件
      • 2.2 操作文件夹
  • 二、IO流介绍
  • 三、字符流
    • 1、读文件
      • 1.1 一次读一个
      • 1.2 一次读多个,使用char数组去装
    • 2、写文件
      • 2.1 一次写一个
      • 2.2 一次写完,使用字符数组
    • 3、文件复制
      • 3.1 综合应用
      • 3.2 使用缓冲流提高效率
  • 四、字节流
    • 1、读文件
      • 1.1 一次读一个
      • 1.2 一次读多个,使用byte数组去装
    • 2、写文件
      • 2.1 一次写一个
      • 2.2 一次写多个,使用byte数组
    • 3、使用缓冲流完成文件复制
  • 五、缓冲流
  • 六、转换流
    • 1、读文件
    • 2、复制文件
  • 七、System流
    • 1、System.in
      • 1.1 从键盘录入
      • 1.2 Scanner
    • 2、System.out
    • 3、从键盘录入内容输出到文件中
  • 八、对象流
    • 1、写文件
      • 1.1 写String和基本数据类型
      • 1.2 写自定义对象
    • 2、读文件
    • 3、序列化&反序列化
      • 3.1 什么是序列化?反序列化又是什么?
      • 3.2 序列化是全部对象内容都序列化?
      • 3.3 认识serialVersionUID
  • 九、数据流

前言

📢 大家好,我是程序员Forlan,本篇内容主要分享IO流方面的知识,属于基础内容,一方面是新人必备知识,另一方面也方便自己和大家后续查找相关资料

一、File类介绍

1、概念引入

首先来介绍两个概念

  • 文件:为了便于数据的管理和检索,引入了文件,本质上都是字节组成,0和1,只不过有不同的形态(文本、图片、视频…)
  • 文件夹:为了便于对文件进行管理和使用,引入了文件夹,不同文件放到不同文件夹,分门别类

对于面向对象编程,我们操作的是对象,盘符上的文件/文件夹,需要封装为对象,我们才能进行操作,这个对象就是File,通过File类,我们可以获取文件/文件夹的各种信息,操作文件/文件夹

2、实际应用

2.1 操作文件

File f1 = new File("D:\\text.txt");
File f2 = new File("D:/text.txt");
/**
 * File.separator,本地文件系统的名称分隔符:在UNIX系统上,这个字段的值是'/';在Microsoft Windows系统上,它是'\\'
 * 建议使用这种
 */
File f3 = new File("d:" + File.separator + "text.txt");
if (f1.exists()) {
	// 如果文件存在,将文件删除操作
	f1.delete();
} else {
	// 如果文件不存在,就创建这个文件
	f1.createNewFile();
}
System.out.println("文件是否可读:" + f1.canRead());
System.out.println("文件是否可写:" + f1.canWrite());
System.out.println("文件的名字:" + f1.getName());
System.out.println("上级目录:" + f1.getParent());
System.out.println("是否是一个目录:" + f1.isDirectory());
System.out.println("是否是一个文件:" + f1.isFile());
System.out.println("是否隐藏:" + f1.isHidden());
System.out.println("文件的大小:" + f1.length());
System.out.println("是否存在:" + f1.exists());
System.out.println("绝对路径:" + f1.getAbsolutePath()); // 完整路径
System.out.println("相对路径:" + f1.getPath()); // 相对某个参照物的路径,在junit的测试方法中,相对路径指的就是相对模块,就是模块名之后的路径
System.out.println("toString:" + f1.toString()); // 相对路径
System.out.println(f1 == f2);//比较两个对象的地址
System.out.println(f1.equals(f2));//比较两个对象对应的文件的路径

2.2 操作文件夹

基本文件的命令,它也可以用,这里就不演示重复的了

File f = new File("D:\\forlan");
// 创建单层目录,前提:之前的目录已经存在,不然创建失败
f.mkdir();
// 创建多层目录
f.mkdirs();
// 删除:只会删除一层,前提:这层目录是空的,里面没有内容,如果有内容就不会被删除
f.delete();
// 获取当前文件夹下的文件或文件夹,不包括下一级
// File[] files = f.listFiles();
String[] list = f.list();
for (String s : list) {
	System.out.println(s);
}

二、IO流介绍

前面提到的FIle类,可以获取以及操作文件/文件夹表层信息,但拿不到里面的内容,这时候就出现了I/O流,用于处理设备之间的数据的传输,可以简单理解为一根“管”,连接不同东西进行传输

分类

  • 按照流的方向,分为:输入流、输出流
  • 按照处理数据的单位,分为:字节流、字符流
    注:字节流可以理解细管,字符流可以理解为粗管,传输大小不一样

所以按照不同的方向组合,就出现了4个基类:字节输入流、字节输出流、字符输入流、字节输出流
针对这4个抽象基类,又可以延伸出来不同类型的实现,具体如下图:

在这里插入图片描述

下面我们就针对不同的实现,来看看具体代码如何写

三、字符流

Windows的记事本默认保存的ANSI,也就是GBK,我们要转为UTF-8,它不支持,但我们可以使用转换流,这个后面会讲

1、读文件

1.1 一次读一个

// 读文件,先得到文件对象
File f = new File("D:\\text.txt");
// Windows的记事本默认保存的ANSI,也就是GBK,我们要转出UTF-8
try (FileReader fr = new FileReader(f);) {
	int n;
	// 如果到了文件的结尾处,那么读取的内容为-1
	while ((n = fr.read()) != -1) {
		System.out.print((char) n);
	}
} catch (IOException e) {
	e.printStackTrace();
}

1.2 一次读多个,使用char数组去装

// 读文件,先得到文件对象
File f = new File("D:\\text.txt");
try (FileReader fr = new FileReader(f);) {
	// 使用数组,一次性读10个
	char[] ch = new char[10];
	int len = fr.read(ch);
	// 如果到了文件的结尾处,那么读取的内容为-1
	while (len != -1) {
		System.out.print(new String(ch, 0, len));
		len = fr.read(ch);
	}
} catch (IOException e) {
	e.printStackTrace();
}

代码中的new String(ch, 0, len)可以写成new String(ch, 0, ch.length)?
答案肯定是不行的,会重复读取内容,比如最后len=2,实际上只需要展示2个字符,但还是展示了10个字符,8个是之前的字符

2、写文件

FileWriter说明:

  • 如果目标文件不存在,会自动创建文件
  • 如果目标文件存在:
    • new FileWriter(f),:对原文件覆盖
    • new FileWriter(f,true) : 在原文件末尾追加`

2.1 一次写一个

// 写的文件对象
File f = new File("D:\\text.txt");
try (FileWriter fw = new FileWriter(f, true);) {
	String content = "你好,程序员Forlan";
	for (int i = 0; i < content.length(); i++) {
		fw.write(content.charAt(i));
	}
} catch (IOException e) {
	e.printStackTrace();
}

2.2 一次写完,使用字符数组

// 写的文件对象
File f = new File("D:\\text.txt");
try (FileWriter fw = new FileWriter(f, true);) {
	String content = "你好,程序员Forlan";
	// 转为字符数据,一次性写完
	char[] chars = content.toCharArray();
	fw.write(chars);
} catch (IOException e) {
	e.printStackTrace();
}

3、文件复制

3.1 综合应用

// 源文件
File f1 = new File("D:\\text.txt");
// 目标文件
File f2 = new File("D:\\textCopy.txt");
try (FileReader fr = new FileReader(f1); FileWriter fw = new FileWriter(f2);) {
	char[] ch = new char[10];
	int len = fr.read(ch);
	while (len != -1) {
		fw.write(ch, 0, len);
		len = fr.read(ch);
	}
} catch (IOException e) {
	e.printStackTrace();
}

3.2 使用缓冲流提高效率

缓冲流:BufferedReader、BufferedWriter ,这个后面会讲到

// 源文件
File f1 = new File("D:\\text.txt");
// 目标文件
File f2 = new File("D:\\textCopy.txt");
try (FileReader fr = new FileReader(f1); FileWriter fw = new FileWriter(f2);
	 BufferedReader br = new BufferedReader(fr); BufferedWriter bw = new BufferedWriter(fw);) {
	char[] ch = new char[10];
	int len = br.read(ch);
	while (len != -1) {
		bw.write(ch, 0, len);
		len = br.read(ch);
	}
} catch (IOException e) {
	e.printStackTrace();
}

四、字节流

字节流,一般用来操作非文本文件,因为中文字符,不同编码,所占用的字节不同,文本文件,建议使用字符流操作
文本文件:txt、java、c…
非文本文件:jpg、mp3 、mp4…

1、读文件

1.1 一次读一个

File f = new File("D:\\forlan.png");
try (FileInputStream fis = new FileInputStream(f);) {
	int len = fis.read();
	// 如果到了文件的结尾处,那么读取的内容为-1
	while (len != -1) {
		System.out.print(len);
		len = fis.read();
	}
} catch (IOException e) {
	e.printStackTrace();
}

1.2 一次读多个,使用byte数组去装

File f = new File("D:\\forlan.png");
try (FileInputStream fis = new FileInputStream(f);) {
	byte[] bytes = new byte[1024];
	int len = fis.read(bytes);
	while (len != -1) {
		System.out.print(new String(bytes, 0, len));
		len = fis.read(bytes);
	}
} catch (IOException e) {
	e.printStackTrace();
}

2、写文件

非文本很难写完整,下面我们以复制的例子来演示写操作

2.1 一次写一个

File f1 = new File("D:\\forlan.png");
File f2 = new File("D:\\forlanCopy.png");
try (FileInputStream fis = new FileInputStream(f1); FileOutputStream fos = new FileOutputStream(f2);) {
	int len = fis.read();
	while (len != -1) {
		fos.write(len);
		len = fis.read();
	}
} catch (IOException e) {
	e.printStackTrace();
}

2.2 一次写多个,使用byte数组

File f1 = new File("D:\\forlan.png");
File f2 = new File("D:\\forlanCopy.png");
try (FileInputStream fis = new FileInputStream(f1); FileOutputStream fos = new FileOutputStream(f2);) {
	byte[] bytes = new byte[1024];
	int len = fis.read(bytes);
	while (len != -1) {
		fos.write(bytes, 0, len);
		len = fis.read(bytes);
	}
} catch (IOException e) {
	e.printStackTrace();
}

3、使用缓冲流完成文件复制

File f1 = new File("D:\\forlan.png");
File f2 = new File("D:\\forlanCopy.png");
try (FileInputStream fis = new FileInputStream(f1); FileOutputStream fos = new FileOutputStream(f2);
	 BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos);) {
	byte[] bytes = new byte[1024];
	int len = bis.read(bytes);
	while (len != -1) {
		bos.write(bytes, 0, len);
		len = bis.read(bytes);
	}
} catch (IOException e) {
	e.printStackTrace();
}

五、缓冲流

无论是字符流,还是字节流,为什么要用缓冲区?
假设有500b的文件,我们来看不同写法,具体是怎么操作的
一个个读写,要操作500次
利用byte[10],要操作50次
利用缓冲区,直接一次性全部读到缓冲区,底层会帮我们刷新缓冲区到磁盘
所以,很简单,缓冲区效率高

六、转换流

作用:将字节流和字符流进行转换,属于一个处理流
InputStreamReader :字节输入流 ——》字符的输入流
OutputStreamWriter :字符输出流 ——》字节的输出流

1、读文件

前面我们提到,我们读取的文件内容为乱码,使用转换流可以指定编码,正确展示

File f = new File("D:\\text.txt");
try (FileInputStream fis = new FileInputStream(f);
	 InputStreamReader isr = new InputStreamReader(fis);) {
	// 可以指定一个编码,不知道的话,默认是程序本身的编码utf-8
	// InputStreamReader isr = new InputStreamReader(fis,"utf-8");
	char[] ch = new char[10];
	int len = isr.read(ch);
	while (len != -1) {
		System.out.print(new String(ch, 0, len));
		len = isr.read(ch);
	}
} catch (IOException e) {
	e.printStackTrace();
}

2、复制文件

// 源文件
File f1 = new File("D:\\text.txt");
// 目标文件
File f2 = new File("D:\\textCopy.txt");
try (FileInputStream fis = new FileInputStream(f1); InputStreamReader isr = new InputStreamReader(fis, "utf-8");
	 FileOutputStream fos = new FileOutputStream(f2); OutputStreamWriter osw = new OutputStreamWriter(fos);) {
	char[] ch = new char[10];
	int len = isr.read(ch);
	while (len != -1) {
		osw.write(ch, 0, len);
		len = isr.read(ch);
	}
} catch (IOException e) {
	e.printStackTrace();
}

七、System流

System.in:标准输入流——》默认从键盘录入
System.out:标准输出流

1、System.in

1.1 从键盘录入

读到的东西,会被转为ascall码

InputStream in = System.in;
int n = in.read();

1.2 Scanner

扫描键盘

Scanner sc = new Scanner(System.in);
int num = sc.nextInt();

扫描文件

Scanner sc = new Scanner(new FileInputStream(new File("D:\\text.txt")));
while (sc.hasNext()) {
	System.out.print(sc.next());
}

2、System.out

// 写法1
PrintStream out = System.out;
out.print("程序员forlan");

// 写法2
System.out.println("程序员forlan");

3、从键盘录入内容输出到文件中

// 目标文件
File f = new File("D:\\text.txt");
// 属于字节流
InputStream in = System.in;
try (InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr);
	 FileWriter fw = new FileWriter(f); BufferedWriter bw = new BufferedWriter(fw);) {
	String s = br.readLine();
	while (!s.equals("quit")) {
		bw.write(s);
		bw.newLine();
		s = br.readLine();
	}
} catch (Exception e) {
	e.printStackTrace();
}

八、对象流

对象流:ObjectInputStream,ObjectInputStream
作用:用于存储和读取基本数据类型数据或对象的处理流
亮点:可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来

1、写文件

可以指定写入什么数据类型
在这里插入图片描述

1.1 写String和基本数据类型

File f = new File("D:\\text.txt");
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));) {
	oos.writeUTF("程序员forlan");
	oos.writeInt(100);
} catch (IOException e) {
	e.printStackTrace();
}

1.2 写自定义对象

1)自定义对象

public class Forlan implements Serializable {
	private String name;
	private int level;

	public Forlan(String name, int level) {
		this.name = name;
		this.level = level;
	}
}

2)写入文件

File f = new File("D:\\text.txt");
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));) {
	Forlan forlan = new Forlan("程序员Forlan", 100);
	oos.writeObject(forlan);
} catch (IOException e) {
	e.printStackTrace();
}

我们注意到一个细节,自定义对象实现了Serializable接口 ,不实现就会报错,如下:

java.io.NotSerializableException: cn.lw.io.Forlan
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at cn.lw.io.ObjectStream.writeObject(ObjectStream.java:31)
	at cn.lw.io.ObjectStream.main(ObjectStream.java:13)

2、读文件

我们写入什么内容,都可以把指定类型的数据读出来
在这里插入图片描述
具体代码

File f = new File("D:\\text.txt");
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));) {
	System.out.println(ois.readUTF());
} catch (Exception e) {
	e.printStackTrace();
}

3、序列化&反序列化

前面我们提到,自定义对象必须实现Serializable接口,否则,去写文件就会报错
这个接口里是空的,是一个标识接口,实现这个接口的类对象才能序列化

public interface Serializable {
}

3.1 什么是序列化?反序列化又是什么?

像ObjectOutputStream类,是把内存中的Java对象转换成二进制数据,然后就可以把数据保存在磁盘上,相反,ObjectInputStream类,是把磁盘上的二进制数据转换成Java对象进行操作

序列化:数据被转换成二进制数据的过程
反序列化:数据从二进制数据恢复成原样的过程

注:写文件的对象需要序列化,网络传输的对象也需要序列化(比如rpc请求)

3.2 序列化是全部对象内容都序列化?

1)被序列化的类,内部的所有属性,必须是可序列化的

基本数据类型、String都是可序列化的,但自定义对象需要实现Serializable

2)static,transient修饰的属性不可以被序列化

不可以被序列化,指的是属性内容不被保存或传输,反序列化出来的内容为空

3.3 认识serialVersionUID

凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态常量,serialVersionUID,用来表明类的不同版本间的兼容性
1)作用
对序列化对象进行版本控制,有关反序加化时会检测是否兼容
2)生成时机
没有显示声明的话,它的值是Java运行时环境根据类的内部细节自动生成的,若类的实例变量做了修改,serialVersionUID 可能发生变化,所以建议还是显式声明

简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常(InvalidCastException)

举个栗子:
原来Forlan类不加toString方法,进行序列化,也就是写文件

public class Forlan implements Serializable {
	private String name;
	private int level;

	public Forlan(String name, int level) {
		this.name = name;
		this.level = level;
	}

	// @Override
	// public String toString() {
	// 	return "Forlan{" +
	// 			"name='" + name + '\'' +
	// 			", level=" + level +
	// 			'}';
	// }
}

打开注释,再加上toString方法,进行反序列化会报错

java.io.InvalidClassException: cn.lw.io.Forlan; local class incompatible: stream classdesc serialVersionUID = 113793900596523614, local class serialVersionUID = -7076236456819894490
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1880)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1746)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2037)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1568)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:428)
	at cn.lw.io.ObjectStream.readObject(ObjectStream.java:20)
	at cn.lw.io.ObjectStream.main(ObjectStream.java:14)

解决,加serialVersionUID,因为值固定后,无论我们怎么改变类内容,都不会变,也就不会报错了,如果不加,serialVersionUID会隐式加,跟随类内部细节自动生成

IDEA中配置序列化版本号
在这里插入图片描述

九、数据流

数据流:用来操作基本数据类型和字符串的
DataInputStream:将文件中存储的基本数据类型和字符串 写入 内存的变量中
DataOutputStream: 将内存中的基本数据类型和字符串的变量 写出 文件中

写文件

File f = new File("D:\\text.txt");
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(f));) {
	dos.writeUTF("程序员Forlan");
	dos.writeBoolean(false);
	dos.writeInt(100);
} catch (Exception e) {
	e.printStackTrace();
}

读文件

File f = new File("D:\\text.txt");
try (DataInputStream dis = new DataInputStream(new FileInputStream(f));) {
	System.out.println(dis.readUTF());
	System.out.println(dis.readBoolean());
	System.out.println(dis.readInt());
} catch (Exception e) {
	e.printStackTrace();
}

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

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

相关文章

论文解读:ExamPle:用于预测植物小分泌肽的可解释的深度学习框架

ExamPle: explainable deep learning framework for the prediction of plant small secreted peptides 期刊&#xff1a;Bioinformatics 影响因子&#xff1a;6.931 中科院分区&#xff1a;小类数学与计算生物2区 出版日期&#xff1a;2023年3月10日 Github:https://gith…

Seata客户端的启动过程 学习记录

Seata客户端的启动过程 1.自动装配4个配置类 将在SpringBoot启动时往容器中添加4个类 1. 自动配置类 SeataAutoConfiguration SeataAutoConfiguration将会往容器中添加两个bean failureHandler 事务处理失败执行器globalTransactionScanner failureHandler failureHandle…

03 表达关系的术语

文章目录 表达关系的术语关联关联的语义表达(6点) 泛化细化(也称为实现)依赖例题 UML 基本关系的一般用法① 模型化简单依赖②模型化单继承③模型化结构关系例题 表达关系的术语 关联 定义&#xff1a;关联是类目之间的结构关系&#xff0c;描述了一组具有相同结构、相同语义…

【MySQL数据库一】MySQL数据库初体验

MySQL数据库初体验 1.数据库基本概念1.1 数据Data1.2 表1.3 数据库1.4 数据库管理系统1.5 数据库系统 2.数据库的发展3.主流的数据库介绍3.1 SQL Server&#xff08;微软公司产品&#xff09;3.2 Oracle &#xff08;甲骨文公司产品&#xff09;3.3 DB2&#xff08;IBM公司产品…

安卓高通机型的基带移植 修改 编译的相关 增加信号 支持5G等【二】

安卓高通机型的基带移植 修改 编译的相关 增加信号 支持5G等【一】 前面分享了这篇帖子&#xff0c;很多友友希望更新下新机型的基带替换方法。今天对其中做一些补充说明。由于安卓机型跨版本幅度较大。有的机型从出厂安卓8有可能官方目前已经更新到安卓12 13等等。所以任何的教…

每天五分钟机器学习:如何确定梯度下降中的学习率?

本文重点 学习率是梯度下降算法中的一个重要参数,它控制着每次迭代中参数的更新幅度,因此学习率的大小直接影响着算法的收敛速度和精度。在实际应用中,如何选择合适的学习率是一个非常重要的问题。 手动调整法 最简单的方法是手动调整学习率。我们可以根据经验或者试错的…

sealos 五年磨一剑——云操作系统正式发布

这是计划的一部分 这是一个宏伟的计划&#xff0c;漫长且有趣。。。 2018 年的一个晚上&#xff0c;我写下了 sealos 第一行代码&#xff0c;当时仓库命名 “kubeinit”&#xff0c;后一想格局太小&#xff0c;我不可能只做一个安装 kubernetes 的事&#xff0c;安装只是计划…

不知道测试什么?这些是你需要知道的软件测试类型和常识

有多少软件测试类型呢? 我们作为测试人员了解很多种不同的软件测试类型&#xff0c;例如功能测试(Functional Test)、非功能测试、自动测试、敏捷测试、以及它们的各种子类型. 尽管在我们的测试过程中会接触很多种测试类型, 或者听说过某些测试类型&#xff0c;但是很少人敢说…

小姐姐们,一起学数据分析

&#x1f496; 亲爱的女生们&#xff0c;听我说&#xff01;数据分析&#xff0c;给你的未来注入浪漫与激情&#xff01;&#x1f496; 嗨&#xff0c;小姐姐们&#x1f46d;&#xff0c; 我想和你们分享一个令人兴奋的话题——数据分析&#xff01;或许你们会觉…

Liunx系统重修

Liunx中以“树”结构的形式来管理文件和文件夹的&#xff01;

ISP下载原理分析

STM32的启动方式&#xff0c;系统存储器启动就是通过ISP下载 ISP简介 ISP下载是指可以通过串行外设&#xff0c;直接将程序下载Flash中&#xff0c;然后自动运行程序的启动方式。 ISP的时候需要用到bootloder(自举程序)&#xff0c;bootloader存储在STM32内部的自举ROM存储器…

webpack踩坑

因为电脑重新装了系统 所以很多环境都需要配置 1.首先去node.js官网下载了node&#xff0c;node下载后对应的npm版本也会自动下载好 2.想要成功跑通项目&#xff0c;还需要下载webpack 全局安装webpack npm -i webpack -Dnpm install webpack-cli -g但一直在报错 查看webpac…

基于Java毕业生就业信息统计系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

2023互联网Java高级工程师1080道面试题(附答案)分享

Java 面试八股文有必要背吗&#xff1f; 我的回答是&#xff1a;很有必要。你可以讨厌这种模式&#xff0c;但你一定要去背&#xff0c;因为不背你就进不了大厂。现如今&#xff0c;Java 面试的本质就是八股文&#xff0c;把八股文面试题背好&#xff0c;面试才有可能表现好。…

python字符串格式化控制数值经度

python字符串格式化通过占位符拼接演示了字符串格式化拼接的方法 但是大家应该有注意到 我们的 8.70 就变成了 8.700000 那么 我们就需要对浮点数 做一个经度控制 我们先编写如下代码 dom1 110; dom2 1234.1234567; print(dom1) print(dom2)运行结果如下 我们定义了一个整…

【RuoYi-Cloud-Plus】学习笔记 07 - Sentinel(二)Node ProcessorSlotChain 总览与知识整理

文章目录 前言参考目录版本说明学习笔记1、Sentinel 架构图2、Node2.1、入口节点 EntranceNode2.2、链路节点 DefaultNode2.3、簇点 ClusterNode2.4、统计节点 StatisticNode3、Slot Chain3.1、DefaultSlotChainBuilder3.1.1、Slot 排序的实现3.1.2、SPI 文件读取3.2、NodeSele…

Java并发工具之ThreadLocal

一、ThreadLocal 简介 1. ThreadLocal 是什么&#xff1f; ThreadLocal 字面意思是本地线程&#xff0c;其实更准确来说是线程局部变量&#xff0c;线程类 Thread 有个变量叫做 threadLocals&#xff0c;其类型就是ThreadLocal.ThreadLocalMap 类型&#xff0c;他其实不是一个…

回忆童年游戏,完美利用Python制作飞机大战(爷青回~)

名字&#xff1a;阿玥的小东东 学习&#xff1a;python、C/C 博客链接&#xff1a;阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 pygame包的安装 添加python环境变量 创建飞机大战窗口 飞机照片 将变量及函数抽取出来 添加多…

LeetCode:31. 下一个排列

31. 下一个排列 1&#xff09;题目2&#xff09;思路3&#xff09;代码4&#xff09;结果 1&#xff09;题目 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1…

Nacos负载均衡策略

文章目录 按权重分配流量负载均衡自定义负载均衡策略 按权重分配流量负载均衡 SpringCloud新版本&#xff08;2021.x.x&#xff09;中负载均衡器用LoadBalancer替代了Ribbon&#xff0c;默认只提供了2种负载均衡策略&#xff1a;RandomLoadBalancer 和 RoundRobinLoadBalancer。…