Java面试——基础篇
目录
1、java语言有哪些优点和缺点?
2、JVM 、 JDK 和 JRE的关系
3、为什么说 Java 语言“编译与解释并存”?
4、Java和c++的区别
5、基本数据类型
5.1、java的8种基本数据类型:
5.2、基本类型和包装类型的区别:
5.3、包装类型的缓存机制:
5.4、自动装箱和自动拆箱:
5.5、浮点数运算的精度丢失问题及解决办法:
6、变量
6.1、成员变量与局部变量的区别?
6.2、静态变量有什么作用?
6.3、字符型常量和字符串常量的区别?
7、方法
7.1、静态方法和实例方法的区别:
7.2、静态方法为什么不能调用非静态成员?
7.3、重载和重写的区别:
8、面向对象基础
8.1、面向对象和面向过程的区别:
8.2、创建一个对象用什么运算符?对象实体与对象引用有何不同?
8.3、对象的相等和引用相等的区别:
8.4、构造函数是什么?能否被override?类没有声明构造方法,程序还能正确执行吗?
8.5、面向对象三大特征
8.6、接口和抽象类有什么共同点和区别?
8.7、深拷贝和浅拷贝的区别?什么是引用拷贝?
9、Object类
9.1、Object 类的常见方法有哪些?
9.2、== 和 equals() 的区别:
9.3、为什么重写 equals() 时必须重写 hashCode() 方法?
10、String类
10.1、String 为什么是不可变的?
10.2、String、StringBuffer、StringBuilder 的区别:
10.3、String s1 = new String("abc");这句话创建了几个字符串对象?
10.4、String#intern 方法有什么作用?
10.5、String 类型的变量和常量做“+”运算时发生了什么?
11、异常
11.1、Exception 和 Error 的区别:
11.2、Checked Exception 和 Unchecked Exception的区别:
11.3、Throwable 类常用方法有哪些?
11.4、try-catch-finally 如何使用?
11.5、finally 中的代码一定会执行吗?
11.6、如何使用 try-with-resources 代替try-catch-finally?
12、泛型的使用方式有哪几种?
13、反射
13.1、反射的使用:
13.2、反射的应用场景:
14、注解的解析方法有哪几种?
15、什么是序列化?什么是反序列化?
16、I/O流
字节缓冲流:
Java 中 3 种常见 IO 模型:
1、java语言有哪些优点和缺点?
优点:
- 面向对象(封装,继承,多态)
- 平台无关性( Java 虚拟机实现平台无关性)
- 支持多线程
- 具备异常处理和自动内存管理机制
- 支持网络编程并且很方便
- 编译与解释并存
缺点:
- 使用大量的内存:垃圾回收机制需要占用大量内存,可能导致程序的运行速度相对较慢。
- 不支持底层操作:Java使用虚拟机来实现,无法和操作系统的底层打交道了。
- 启动时间慢:由于Java程序需要先启动虚拟机,再执行程序,启动时间相对较慢。
2、JVM 、 JDK 和 JRE的关系
- JDK(Java Development Kit):是 Java 开发工具包,是整个 Java 的核心,它包含了JRE,同时还包含了 javac(编译 java 源码的编译器)、jconsole(基于 JMX 的可视化监控⼯具)、javap(反编译工具)等等。
- JRE( Java Runtime Environment):是 Java 的运行环境,包含 JVM 及 Java 核心类库。
- JVM(Java Virtual Machine):Java 虚拟机,是整个 Java 实现跨平台的最核心的部分。所有 Java 程序会首先被编译为 .class 的类文件,这种类文件可以在虚拟机上执行。
3、为什么说 Java 语言“编译与解释并存”?
高级编程语言按照程序的执行方式分为两种:
- 编译型语言:通过编译器将源代码一次性翻译成可被该平台执行的机器码。一般编译语言的执行速度比较快,开发效率比较低。常见的编译性语言有 C、C++、Go、Rust 等等。
- 解释型语言:通过解释器一句一句的将代码解释(interpret)为机器代码后再执行。一般开发效率比较快,执行速度比较慢。常见的解释性语言有 Python、JavaScript、PHP 等等。
Java 语言既具有编译型语言的特征,又有解释型语言的特征。因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(.class
文件),这种字节码必须由 Java 解释器来解释执行。
4、Java和c++的区别
- Java 不提供指针直接访问内存,程序内存更加安全。
- Java 的类单继承的,C++ 支持多重继承;虽然 Java 类不支持多继承,但接口支持多继承。
- Java 有自动内存管理垃圾回收机制(GC),不需要程序员手动释放无用内存。
- C++支持方法重载和操作符重载,但是 Java 只支持方法重载(操作符重载增加了复杂性,这与 Java 最初的设计思想不符)。
- ……
5、基本数据类型
5.1、java的8种基本数据类型:
5.2、基本类型和包装类型的区别:
- 用途:基本类型一般用来定义一些局部变量和常量,在其他地方比如方法参数、对象属性中一般使用包装类型,并且包装类型可用于泛型,而基本类型不可以。
- 存储方式:基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中,基本数据类型的成员变量存放在 Java 虚拟机的堆中。包装类型属于对象类型,放在堆中。
-
占用空间:相比于包装类型, 基本数据类型占用的空间比较小。
-
比较方式:对于基本数据类型来说,
==
比较的是值。对于包装数据类型来说,==
比较的是对象的内存地址。整型包装类对象之间值的比较,需要使用equals()
方法。
对于不同类型变量的存储问题,有两条黄金法则:
- 引用类型总是被分配到“堆”上。不论是成员变量还是局部
- 基础类型总是分配到它声明的地方:成员变量在堆内存里,局部变量在栈内存里。
public class Test {// 成员变量,存放在堆中int a = 10;// 被 static 修饰,也存放在堆中,但属于类,不属于对象// JDK1.7 静态变量从永久代移动了 Java 堆中static int b = 20;public void method() {// 局部变量,存放在栈中int c = 30;static int d = 40; // 编译错误,不能在方法中使用 static 修饰局部变量}
}
5.3、包装类型的缓存机制:
Byte
,Short
,Integer
,Long
这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character
创建了数值在 [0,127] 范围的缓存数据,Boolean
直接返回 True
或 False,
两种浮点数类型的包装类 Float
,Double
没有实现缓存机制。
看如下代码:
Integer i1 = 40;
Integer i2 = new Integer(40);
System.out.println(i1==i2);
上述代码应输出false。首先第一行代码会发生自动装箱,因此变量i1使用的是缓存中的对象,而i2会新new一个对象出来,故两者不相等。
如果想比较包装类对象之间值,需要使用equals。
5.4、自动装箱和自动拆箱:
- 自动装箱:将基本类型用它们对应的引用类型包装起来;
- 自动拆箱:将包装类型转换为基本数据类型;
装箱其实就是调用了 包装类的valueOf()
方法,拆箱其实就是调用了 xxxValue()
方法。
因此,
Integer i = 10
等价于Integer i = Integer.valueOf(10)
int n = i
等价于int n = i.intValue()
;
5.5、浮点数运算的精度丢失问题及解决办法:
由于底层保存浮点数的机制,会出现小数的精度发生损失的情况,可以使用 BigDecimal
对浮点数的运算,不会造成精度丢失。如:
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");BigDecimal x = a.subtract(b);
BigDecimal y = b.subtract(c);System.out.println(x); /* 0.1 */
System.out.println(y); /* 0.1 */
System.out.println(Objects.equals(x, y)); /* true */
6、变量
6.1、成员变量与局部变量的区别?
- 语法形式:
- 成员变量属于类,而局部变量是方法中定义的变量或参数;
- 成员变量可以被
public
,private
,static
等修饰符所修饰,而局部变量不能被访问控制修饰符及static
所修饰; - 成员变量和局部变量都能被
final
所修饰。
- 存储方式:
- 如果成员变量是使用
static
修饰的,那么这个成员变量是属于类的,如果没有使用static
修饰,这个成员变量是属于类实例的。 - 而对象存在于堆内存,局部变量则存在于栈内存。
- 如果成员变量是使用
6.2、静态变量有什么作用?
静态变量也就是被 static
关键字修饰的变量。它可以被类的所有实例共享,无论一个类创建了多少个对象,它们都共享同一份静态变量。也就是说,静态变量只会被分配一次内存,即使创建了多个对象,这样可以节省内存。
通常情况下,静态变量会被 final
关键字修饰成为常量。
6.3、字符型常量和字符串常量的区别?
- 形式 : 字符常量是单引号引起的一个字符,字符串常量是双引号引起的 0 个或若干个字符。
- 含义 : 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)。
- 占内存大小:字符常量占 2 个字节; 字符串常量占若干个字节。
7、方法
7.1、静态方法和实例方法的区别:
- 调用方式:在外部调用静态方法时,可以使用
类名.方法名
的方式,也可以使用对象.方法名
的方式,而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象 。 - 访问限制:静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),不允许访问实例成员(即实例成员变量和实例方法),而实例方法不存在这个限制。
7.2、静态方法为什么不能调用非静态成员?
- 静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,需要通过类的实例对象去访问。
- 在类的非静态成员不存在的时候静态方法就已经存在了,此时调用在内存中还不存在的非静态成员,属于非法操作。
7.3、重载和重写的区别:
- 重载:同一个类中多个同名方法根据不同的传参来执行不同的逻辑处理。
- 重写:子类对父类方法的重新改造,外部样子不能改变,内部实现逻辑可以改变。
8、面向对象基础
8.1、面向对象和面向过程的区别:
- 面向过程:把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。
- 面向对象:是一种“万物皆对象”的编程思想,任何物体都可以归为一类事物,而每一个个体都是一类事物的实例,通过调用对象的方法来解决问题。
8.2、创建一个对象用什么运算符?对象实体与对象引用有何不同?
用new 运算符,new 创建对象实例,对象实例在堆内存中;对象引用指向对象实例,存放在栈内存中。
- 一个对象引用可以指向 0 个或 1 个对象(一根绳子可以不系气球,也可以系一个气球);
- 一个对象可以有 n 个引用指向它(可以用 n 条绳子系住一个气球)。
8.3、对象的相等和引用相等的区别:
- 对象相等一般比较的是内存中存放的内容是否相等。
- 引用相等一般比较的是指向的内存地址是否相等。
例如:
String str1 = "hello";
String str2 = new String("hello");
String str3 = "hello";
// 使用 == 比较字符串的引用相等
System.out.println(str1 == str2);
System.out.println(str1 == str3);
// 使用 equals 方法比较字符串的相等
System.out.println(str1.equals(str2));
System.out.println(str1.equals(str3));
上述代码执行结果为:
结果分析:由于==比较的是引用相等,str2字符串会重新new一个string对象,因此引用和str1不同;str3会优先去字符串常量池寻找有无“hello”这个字符串,有的话就直接引用它,所以str3和str1引用相等。而最后两个比较的是字符串内容是否相等,故str1、str2、str3都相等。
8.4、构造函数是什么?能否被override?类没有声明构造方法,程序还能正确执行吗?
构造方法是一种特殊的方法,主要作用是完成对象的初始化工作。构造函数可以被重载(overload),但不能被重写(override)。
当一个类没有声明构造方法,程序也是可以正常执行的。 当没有显式声明构造方式时,类会默认声明一个无参构造函数。但如果我们自己添加了类的构造方法(无论是否有参),Java 就不会添加默认的无参构造方法了。
8.5、面向对象三大特征
- 封装:把数据和操作数据的方法封装起来,对数据的访问只能通过已定义的接口。
- 可以类比平常生活的开车,汽车的底层结构被封装起来,我们无需关心底层,只需要会踩油门、转动方向盘开车即可。
- 继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类,得到继承信息的被称为子类。
- 父类中的私有属性和方法子类是无法访问,只是拥有。
- 多态:一个对象具有多种状态,具体表现为父类的引用指向子类的实例。
- 多态存在的3个必要条件: 要有继承关系 、要有方法的重写、父类引用指向子类对象。
8.6、接口和抽象类有什么共同点和区别?
抽象类和普通类类似,只是无法实例化,存在的意义就是让其他类继承的。抽象类可以包含抽象方法和非抽象方法,其中抽象方法没有具体的实现,而非抽象方法有具体的实现代码。接口是一种定义了一组方法签名的集合,这些方法默认都是公共的抽象方法,不包含具体的实现代码,比抽象类更加抽象。
共同点:
- 都不能被实例化。(存在的意义就是被继承或实现)
- 都包含抽象方法。(抽象类也可以没有抽象方法,只要有abstract关键字修饰,但是没意义)
不同点:
- 用途:
- 接口主要用于限制类的行为,实现了某个接口就具有了对应的行为。
- 抽象类主要用于代码复用。
- 抽象类中可以定义构造函数,接口不能定义构造函数;
- 一个类只能继承一个类,但是可以实现多个接口。
8.7、深拷贝和浅拷贝的区别?什么是引用拷贝?
- 浅拷贝:只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
- 深拷贝:会创造一个一模一样的对象,新旧对象不共享内存,修改新对象不会影响到原对象。
9、Object类
9.1、Object 类的常见方法有哪些?
Object 类是一个特殊的类,是所有类的父类。它主要提供了以下 11 个方法:
/*** native 方法,用于返回当前运行时对象的 Class 对象,使用了 final 关键字修饰,故不允许子类重写。*/
public final native Class<?> getClass()
/*** native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的HashMap。*/
public native int hashCode()
/*** 用于比较 2 个对象的内存地址是否相等,String 类对该方法进行了重写以用于比较字符串的值是否相等。*/
public boolean equals(Object obj)
/*** native 方法,用于创建并返回当前对象的一份拷贝。*/
protected native Object clone() throws CloneNotSupportedException
/*** 返回类的名字实例的哈希码的 16 进制的字符串。建议 Object 所有的子类都重写这个方法。*/
public String toString()
/*** native 方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。*/
public final native void notify()
/*** native 方法,并且不能重写。跟 notify 一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。*/
public final native void notifyAll()
/*** native方法,并且不能重写。暂停线程的执行。注意:sleep 方法没有释放锁,而 wait 方法释放了锁 ,timeout 是等待时间。*/
public final native void wait(long timeout) throws InterruptedException
/*** 多了 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒。。*/
public final void wait(long timeout, int nanos) throws InterruptedException
/*** 跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念*/
public final void wait() throws InterruptedException
/*** 实例被垃圾回收器回收的时候触发的操作*/
protected void finalize() throws Throwable { }
9.2、== 和 equals() 的区别:
- “==”:由于 Java 只有值传递,所以,对于 == 来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量存的值是对象的地址。因此 == 对于基本数据类型来说比较的是值,对于引用数据类型来说比较的是内存地址。
- equals():如果类没有重写equals方法,等价于“==”的效果;如果重写了,则比较的是对象的属性是否相等。
9.3、为什么重写 equals() 时必须重写 hashCode() 方法?
如果不同时重写的话,可能会出现以下情况:set集合中出现两个相同的对象,即无法去重。
原因:set集合在进行去重操作时,会先判断两个对象的hashcode是否相等,如果不重写hashcode()方法,就会调用object中的hashcode()方法,返回的是对象内存地址的哈希码,这就意味着两个内容相同的对象,其哈希码会由于内存地址的不同而不同。 两个内容相同的对象哈希码不同,则默认这两个对象不同,都会插入到set集合中,导致set集合有重复对象。
10、String类
10.1、String 为什么是不可变的?
- 字符串常量池:
- Java内存中存在一个字符串常量池,是存储字符串对象的特殊内存区域。当创建一个字符串时,如果该字符串已经存在于字符串常量池中,那么就会直接返回这个字符串的引用;如果不存在,则会将该字符串添加到字符串常量池中,并返回新创建的字符串的引用。由于字符串常量池的存在,多个字符串可以共享同一个实例,这样可以节省内存空间。而如果 String 是可变的,那么在修改字符串时,会导致其他使用相同字符串的地方出问题。
- 安全性:
- 由于String不可变,因此其在多线程环境下是安全的。
- 缓存哈希值:
- String 类重写了 hashCode()方法,并且在第一次调用时计算并缓存了字符串的哈希值。由于 String 是不可变的,所以可以保证哈希值的唯一性和一致性。
10.2、String、StringBuffer、StringBuilder 的区别:
- 可变性:
- String 用于表示字符串,属于不可变类。所以每次对String进行修改都会创建一个新的String对象,导致频繁的内存分配和回收,影响性能。
- Java提供了StringBuffer 和 StringBuilder两个可变的字符串,用于高效地进行字符串的操作。
- 原理:
- String 内部使用字符数组来保存字符串内容,并且该数组是 final 修饰的,当对 String 进行修改时,会创建一个新的 String 对象;
- StringBuffer 内部也使用字符数组来保存字符串内容,但是该数组没有被 final 修饰,当对 StringBuffer 进行修改时,直接在原有的字符数组上进行操作,不会创建新的对象。
- StringBuilder 的实现原理与 StringBuffer 相同,唯一的区别是 StringBuilder 不是线程安全的,而 StringBuffer 是线程安全的。
10.3、String s1 = new String("abc");这句话创建了几个字符串对象?
分情况:
- 如果字符串常量池无该对象:那么会堆中创建两个字符串对象,一个存在字符串常量池中。
- 如果字符串常量池有该对象:那么只会在堆中创建一个字符串对象。
10.4、String#intern 方法有什么作用?
intern 是一个 native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中,可以简单分为两种情况:
- 如果字符串常量池中保存了对应的字符串对象的引用,就直接返回该引用。
- 如果字符串常量池中没有保存了对应的字符串对象的引用,那就在常量池中创建一个指向该字符串对象的引用并返回。
10.5、String 类型的变量和常量做“+”运算时发生了什么?
当字符串不加 final
关键字拼接时:
String str1 = "str";
String str2 = "ing";
String str3 = "str" + "ing";
String str4 = str1 + str2;
String str5 = "string";
System.out.println(str3 == str4);//false
System.out.println(str3 == str5);//true
System.out.println(str4 == str5);//false
执行结果分析:首先明确一点:
对于编译期可以确定值的字符串,也就是常量字符串 ,jvm 会将其存入字符串常量池。并且,字符串常量拼接得到的字符串常量在编译阶段就已经被存放字符串常量池,这个得益于编译器的优化。
因此,上述代码中,除了str4的其余字符串都已经存入到字符串常量池中;而str4涉及到两个字符串的拼接,底层会在堆中创建一个新的对象,所以str4和其他字符串的比较都为false。
不过,当字符串使用 final
关键字声明之后,可以让编译器当做常量来处理:
final String str1 = "str";
final String str2 = "ing";
// 下面两个表达式其实是等价的
String c = "str" + "ing";// 常量池中的对象
String d = str1 + str2; // 常量池中的对象
System.out.println(c == d);// true
11、异常
Java 异常类层次结构图概览:
11.1、Exception 和 Error 的区别:
- Exception:程序本身可以处理的异常,可以通过catch来获取,Exception又可以细分为受检查异常和不受检查异常。
- Error:属于程序无法处理的错误。
11.2、Checked Exception 和 Unchecked Exception的区别:
- Checked Exception:即受检查异常,Java 代码在编译过程中,如果受检查异常没有被
catch
或者throws
关键字处理的话,就没办法通过编译。除了RuntimeException
及其子类以外,其他的Exception
类及其子类都属于受检查异常 。常见的受检查异常有:IO 相关的异常、ClassNotFoundException
、SQLException
...。 - Unchecked Exception:即不受检查异常,Java 代码在编译过程中 ,我们即使不处理不受检查异常也可以正常通过编译。
RuntimeException
及其子类统称为不受检查异常,常见的有:NullPointerException
(空指针错误)ArrayIndexOutOfBoundsException
(数组越界错误)ClassCastException
(类型转换错误)IllegalArgumentException
(参数错误比如方法入参类型错误)NumberFormatException
(字符串转换为数字格式错误)ArithmeticException
(算术错误)SecurityException
(安全错误比如权限不够)UnsupportedOperationException
(不支持的操作错误比如重复创建同一用户)
11.3、Throwable 类常用方法有哪些?
String getMessage()
: 返回异常发生时的简要描述String toString()
: 返回异常发生时的详细信息String getLocalizedMessage()
: 返回异常对象的本地化信息。使用Throwable
的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与getMessage()
返回的结果相同void printStackTrace()
: 在控制台上打印Throwable
对象封装的异常信息
11.4、try-catch-finally 如何使用?
- try块:用于捕获异常。其后可接零个或多个
catch
块,如果没有catch
块,则必须跟一个finally
块。 - catch块:用于处理 try 捕获到的异常。
- finally 块:无论是否捕获或处理异常,
finally
块里的语句都会被执行。当在try
块或catch
块中遇到return
语句时,finally
语句块将在方法返回之前被执行。
11.5、finally 中的代码一定会执行吗?
不一定,在某些情况下,finally 中的代码不会被执行,如:
- 在执行finally的代码之前虚拟机被终止了。
- 程序所在的线程死亡。
- 关闭CPU。
11.6、如何使用 try-with-resources 代替try-catch-finally?
try-with-resources 是 Java 7 引入的一种语法结构,用于自动关闭实现了 AutoCloseable
接口的资源。它可以代替传统的 try-catch-finally 结构来处理资源的释放。
优点:
- 简化了代码结构:不再需要显式地编写 finally 块来关闭资源。
- 自动确保资源的正确关闭:无论是否发生异常,都会自动调用资源的
close()
方法进行关闭。 - 支持多个资源同时关闭:可以在 try 后面的括号内声明多个资源,并按照声明顺序逆序关闭。
12、泛型的使用方式有哪几种?
使用泛型,可以增加代码的灵活性和安全性,使得代码更加通用和易于维护。
- 泛型类:定义一个类时,可以在类名后面加上尖括号<>,并在其中指定类型参数。
- 泛型接口:与泛型类类似,可以在接口名后面加上尖括号<>,并在其中指定类型参数。然后在实现该接口时,需要指定具体的类型。
- 泛型方法:即在方法返回值前面加上尖括号<>,并在其中指定类型参数。
13、反射
13.1、反射的使用:
反射是java语言的一个特性,它允程序在运行时动态获取和调用类的属性和方法。
要使用反射,需要先获取类的class对象(字节码对象),有三种方式:
- Class.forName("全类名");
- 类名.class;
- 类实例对象.getClass();
接下来就可以通过具体的API调用获取到详细的属性或者方法:
- 获取构造函数:getConstructors()等方法。
- 获取类成员变量:getFields()等方法。
- 获取类成员方法:getMethods()等方法。
13.2、反射的应用场景:
Spring 框架的 IOC(动态加载管理 Bean)、加载数据库驱动:
Class.forName("com.mysql.cj.jdbc.Driver");
、IDEA的方法提醒都需要用到反射机制。
14、注解的解析方法有哪几种?
注解只有被解析之后才会生效,常见的解析方法有两种:
- 编译期直接扫描:编译器在编译 Java 代码的时候扫描对应的注解并处理,比如某个方法使用
@Override
注解,编译器在编译的时候就会检测当前的方法是否重写了父类对应的方法。 - 运行期通过反射处理:像框架中自带的注解(比如 Spring 框架的
@Value
、@Component
)都是通过反射来进行处理的。
15、什么是序列化?什么是反序列化?
如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。
简单来说:
- 序列化:将数据结构或对象转换成二进制字节流的过程。
- 反序列化:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程。
序列化协议对应于OSI 七层协议模型中表示层。
对于不想进行序列化的变量,使用 transient
关键字修饰。
transient
只能修饰变量,不能修饰类和方法。static
变量不属于任何对象(Object),所以无论有无transient
修饰,均不会被序列化。
16、I/O流
I/O即Input/Output,数据输入到计算机内存的过程即输入,反之输出到外部存储(比如数据库,文件,远程主机)的过程即输出。数据传输过程类似于水流,因此称为 IO 流。IO 流在 Java 中分为输入流和输出流,而根据数据的处理方式又分为字节流和字符流。
Java I/O流中有四个抽象类基类,其架构如下图:
字节流适合传输所有类型的文件,如音频、视频、图片、文本文件的复制转移等。字符流只适合传输纯文本文件,如txt、java文件等。
字节缓冲流:
字节流在调用 write(int b)
和 read()
方法的时候,一次只能读取一个字节。由于字节缓冲流内部有缓冲区(字节数组),因此,字节缓冲流会先将读取到的字节存放在缓存区,大幅减少 IO 次数,提高读取效率。
Java 中 3 种常见 IO 模型:
-
BIO (Blocking I/O):同步阻塞 IO 模型中,应用程序发起 read 调用后,会一直阻塞,直到内核把数据拷贝到用户空间。在高并发场景下效率较低。
-
NIO (Non-blocking I/O):同步非阻塞 IO 模型,应用程序会一直发起 read 调用,等待数据从内核空间拷贝到用户空间的这段时间里,线程依然是阻塞的,直到在内核把数据拷贝到用户空间。通过轮询操作,避免了一直阻塞,但是不断发起调用消耗大量cpu资源。
-
AIO (Asynchronous I/O):异步 IO 模型,应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。
相关文章:
Java面试——基础篇
目录 1、java语言有哪些优点和缺点? 2、JVM 、 JDK 和 JRE的关系 3、为什么说 Java 语言“编译与解释并存”? 4、Java和c的区别 5、基本数据类型 5.1、java的8种基本数据类型: 5.2、基本类型和包装类型的区别: 5.3、包装类型的缓存机…...
C++——结构体
1,结构体基本概念 结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。像int(整型),浮点型,bool型,字符串型等都是属于系统内置的数据类型。而今天要学习的结构体则是属于我们自定义…...
C++技术要点总结, 面试必备, 收藏起来慢慢看
目录 1. 语言对比 1.1 C 11 新特性 2.2 C 和 C 的区别 2.3 Python 和 C 的区别 2. 编译内存相关 2.1. C 程序编译过程 2.2. C 内存管理 2.3. 栈和堆的区别 2.4. 变量的区别 2.5. 全局变量定义在头文件中有什么问题? 2.6. 内存对齐 2.7. 什么是内存泄露 …...
VR数字展厅,平面静态跨越到3D立体化时代
近些年,VR的概念被越来越多的人提起,较为常见的形式就是VR数字展厅。VR数字展厅的出现,让各地以及各行业的展厅展馆的呈现和宣传都发生了很大的改变和革新,同时也意味着展览传播的方式不再局限于原来的图文、视频,而是…...
Linux中LVM实验
LVM实验: 1、分区 -L是大小的意思-n名称的意思 从vg0(卷组)分出来 2、格式化LV逻辑卷 LVM扩容 如果icdir空间不够了, 扩展空间lvextend -L 5G /dev/vg0/lv1 /dev/vg0/lv1(pp,vg,lv) 刷新文件系统xfs_growfs /lvdir VG扩容 …...
外包干了一个月,技术退步明显。。。。。
先说一下自己的情况,本科生,19年通过校招进入南京某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...
gitlab.rb主要配置
根据是否docker安装,进入挂载目录或安装目录 修改此文件,我一般是在可视化窗口中修改,有时候也在命令行手敲 将下面的配置复制到该文件中 external_url http://192.168.100.50 # nginx[listen_port] = 8000 (docker安装的这一行不需要,因为端口映射导致此处修改会导致访问…...
网络协议基础
tcp/ip协议簇 TCP/IP协议族 网络接口层(没有特定的协议) 物理层 数据链路层 网络层: IP (v4/v6) ARP(地址解析协议) RARP . ICMP (Internet控制报文协议) IGMP 传输层: TCP (传输控制协议) UDP (用户数据报协议) 应用层: 都是基于传输层协议的端口,总共端口0~65535 …...
Mac使用adb调试安卓手机
0x00 背景 最近windows电脑休息,用mac办公比较多,手机用时间长了,不太灵光,准备修理一番。于是要用mac调试下android手机。配置略显麻烦,网上的步骤多参差不齐。估计是入门步骤,大佬们也懒得写的太细。于是…...
Web 开发 1: Flask 框架介绍和使用
在 Web 开发中,Flask 是一个流行且灵活的 Python Web 框架,用于构建 Web 应用程序。它简洁而易于上手,适用于小型到中型的项目。在本篇博客中,我将为你介绍 Flask 框架的基础知识和常用技巧,帮助你更好地掌握 Web 开发…...
Centos7.6之禅道开源版17.6.1安装记录
Centos7.6之禅道开源版17.6.1安装记录 文章目录 Centos7.6之禅道开源版17.6.1安装记录1. 下载2. 安装3. 登录4. 连接数据库1. 本地连接2. 远程连接1. 开启远程访问用户2. 更改mysql绑定的主机3. 重启Apache与MySQL服务 4. 常用命令1. Apache和Mysql常用命令2. 其他 1. 下载 官网…...
有趣的代码(简单)
1.代码1 #include<stdio.h> #include<string.h> #include<windows.h> #define _CRT_SECURE_NO_WARNINGS 1 void love() {system("color 4");printf(" **** ***************** ** …...
Java和Redis实现一个简单的热搜功能
1. 前言 我们有一个简单的需求: 搜索栏展示当前登陆的个人用户的搜索历史记录,删除个人历史记录。用户在搜索栏输入某字符,则将该字符记录下来 以zset格式存储的redis中,记录该字符被搜索的个数以及当前的时间戳 (用…...
超越传统,想修哪里就修哪里,SUPIR如何通过文本提示实现智能图像修复
项目简介 通过参数增加使得模型不仅能够修复图像中的错误或损坏,还能根据文本提示进行智能修复。例如根据描述来改变图像中的特定细节。这样的处理方式提升了图像修复的质量和智能度,使得模型能够更准确、更灵活地恢复和改进图像。 SUPIR的主要功能图像…...
《如何画好架构图》学习笔记
看了一堂《如何画好架构图》的公开课,结合网上的资料与经验做一些思考总结。文中的例子和图片大多是从课程中摘录的。 1. 4R架构定义 4R架构定义其实是软件架构定义经过归纳提炼后的简称。 软件架构定义:软件架构是指软件系统的顶层(Rank&am…...
redis整合
一.redis的发布订阅 什么 是发布和订阅 Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。 Redis 客户端可以订阅任意数量的频道。 1、Redis的发布和订阅 客户端订阅频道发布的消息 频道发布消息 订阅者就可以…...
开循环低温样品架节约液氦操作技巧
开循环低温样品架以降温快、无轰动源、重量轻、装置便利等特色遭到大多数客户的喜爱。但是制冷剂消耗量引起的运用本钱是客户在运用过程中zhong点重视的问题,特别是随着全球液氦价格继续飙升,开循环样品架的运用本钱也在逐渐添加,如何节约液氦…...
年薪30W+,待遇翻倍,我的经历值得每个测试人借鉴
从自考大专到出走公司,从半年无业露宿深圳北站,从8k…到11.5k…再到20k,我的经历值得每个测试人借鉴 或许学历并没有那么重要 12年高考之后,在朋友的介绍下(骗了过去),没有好好的读大学&#x…...
DEB方式安装elastic search7以及使用
参考:https://www.cnblogs.com/anech/p/15957607.html 1、安装elastic search7 #手动下载安装 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.1-amd64.deb wget https://artifacts.elastic.co/downloads/elasticsearch/elastics…...
[Tomcat] [最全] 目录和文件详解
打开tomcat的解压之后的目录可以看到如下的目录结构: Bin bin目录主要是用来存放tomcat的命令,主要有两大类,一类是以.sh结尾的(linux命令),另一类是以.bat结尾的(windows命令)。 …...
微信小程序元素/文字在横向和纵向实现居中对齐、两端对齐、左右对齐、上下对齐
元素对齐往往是新学者的一大困惑点,在此总结常用的各种元素和文字对齐方式以供参考: 初始显示 .wxml <view style"width: 100%;height: 500rpx; background-color: lightgray;"><view style"width: 200rpx;height:100rpx;bac…...
兼容树莓派扩展模块,专注工业产品开发的瑞米派强势来袭
近日,米尔电子和瑞萨电子共同定义和开发了瑞萨第一款MPU生态开发板——瑞米派(Remi Pi)正式上市了!在各种Pi板卡琳琅满目的当下,Remi Pi是一款与众不同的开发板,他兼顾了严肃产品开发和爱好者创意实现两种需…...
云原生 - 微信小程序 COS 对象存储图片缓存强制更新解决方案
问题描述 遇到一个这样的情况:在微信小程序里图片缓存十分麻烦,网上很多说在腾讯云里的 COS 存储对象服务里设置对应的图片缓存(Header 头 Cache-Contorl),说实话真不好用,一会儿生效,一会儿没…...
设计公司设计ppt的优势—南京梵构广告
在这个时代的发展下,PPT软件越来越好用,投影仪越来越便宜,直接导致许多商界人士不再撰写文件了。他们只是在编写演示文稿,这些文稿只是些没有细节、缺乏支持的概要。许多人不喜欢撰写详尽文件所付出的脑力劳动。 视觉效果 一个好…...
gitlab设置/修改克隆clone地址端口
最近由于公司要停测试库云服务器? 什么?要停测试库服务器??? 是的! 你没听错。 真是醉了,多大的集团,为了省钱,也真是拼了, 作为开发人员,没有测试服务器,犹如断臂之人。 所以,在之前搭建环境的时候都没有写文档,今天算是弥补上,以后都可以作为参考了, …...
Jellyfin影音服务本地部署并结合内网穿透实现公网访问本地资源
文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及,各种各样的使用需求也被开发出来&…...
笨蛋学设计模式行为型模式-责任链模式【18】
行为型模式-责任链模式 8.5责任链模式:arrow_up::arrow_up::arrow_up:8.5.1概念8.5.2场景8.5.3优势 / 劣势8.5.4责任链模式可分为8.5.5责任链模式8.5.6实战8.5.6.1题目描述8.5.6.2输入描述8.5.6.3输出描述8.5.6.4代码 8.5.7总结 8.5责任链模式⬆️⬆️⬆️ 8.5.1概念 责任…...
【.NET Core】深入理解任务并行库 (TPL)
【.NET Core】深入理解任务并行库 (TPL) 文章目录 【.NET Core】深入理解任务并行库 (TPL)一、概述二、数据并行(任务并行库)三、Parallel.For 循环示例四、Parallel.ForEach 循环示例五、处理并行循环中的异常六、数据并行总结6.1 不要假定并行的速度始…...
win10安装redis并配置加自启动(采用官方推荐unix子系统)
记录,为啥有msi安装包,还这么麻烦的用linux版本redis的安装方式,是因为从github上下载别人制作的msi报毒,还不止一处,这种链接数据库的东西,用别人加工过的,都报毒了还用就是傻逼了。 所以采用…...
【大数据面试题】HBase面试题附答案
目录 1.介绍下HBase 2.HBase优缺点 3.介绍下的HBase的架构 4.HBase的读写缓存 5.在删除HBase中的一个数据的时候,它是立马就把数据删除掉了吗? 6.HBase中的二级索引 7.HBase的RegionServer宕机以后怎么恢复的? 8.HBase的一个region由哪些东西组成? 9.…...
如何做好平台推广/杭州seo中心
今天都不好意思写这篇日记,今天有多个题交了很多次都没AC,还有今天下午的训练最后两个题那么简单的两个dfs没做上来也是讽刺,伤心啊伤心,还是强调昨天的一点,在平时练习比赛中遇到多次没做对的题,一定过会再…...
西安行业网站制作/谷歌网站优化推广
游览器中打开status.jsp文件start.jsp-------- <% session.removeAttribute("task");%>//为了使每次开始都新建一个bean对象 <jsp:useBean id "task" scope "session" class "test.barBean.TaskBean"/> <%task.setR…...
司法局网站建设/a5站长网
转自:http://blog.itpub.net/4227/viewspace-536379/ 在10g以前,Oracle的全局索引分区方法只有一种,即范围分区。 SQL> CREATE TABLE T_PART_INDEX (ID NUMBER, NAME VARCHAR2(30), CREATE_DATE DATE); 表已创建。 SQL> INSERT INTO…...
常州做网站公司排名/微博搜索引擎优化
原文地址为: ASP.NET Web API系列教程(目录)注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API。这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术。目前&…...
汽车网站制作/今日头条新闻最全新消息
在上一篇文章中,我们分析了Android系统进程间通信机制Binder中的Server在启动过程使用Service Manager的addService接口把自己添加到Service Manager守护过程中接受管理。在这一篇文章中,我们将深入到Binder驱动程序源代码去分析Client是如何通过Service…...
怎么样再自己的网站做二级域名/推广宣传文案
技术创新正在变革医疗与健康产业,雷锋网持续关注医疗领域出现的软硬件创新,包括设备、数据,抑或对他们的创新运用。目前我们在招募医疗健康领域作者,负责采写报道医疗科技领域的企业与牛人。简历投递至zhangchileiphone.com&#…...