一、Java基础
1、面向对象的三个基本特征?
封装、继承和多态。
封装 | 继承 | 多态 | |
---|---|---|---|
定义 | 将数据(属性)和操作数据的方法(方法或函数)封装在一个单元中,即类。类是封装的基本单元,它定义了数据的结构和数据的操作。 | 允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。子类可以使用父类已定义的属性和方法,同时可以在其上进行扩展或修改。 | 允许不同类的对象对相同的消息做出不同的响应。这意味着不同的对象可以具有相同的方法名称,但可以根据其具体类型来执行不同的操作。 |
好处 | 有助于隐藏对象的内部实现细节,只暴露必要的接口,提高了代码的可维护性和安全性。 | 促进了代码的重用,减少了重复编写相似功能的代码。 | 增加了代码的灵活性和可扩展性,使得可以编写通用的代码,适用于多种不同类型的对象。 |
作用 | 可以控制数据的访问和修改。 | 建立类之间的层次结构,形成父子关系 | 允许通过基类或接口引用对象,然后在运行时选择执行哪个类的方法。 |
2、编译型语言和解释型语言区别:
编译型语言 | 解释型语言 | |
---|---|---|
定义 | 运行前需要编译成机器码,生成可执行文件(可以直接在计算机上运行,windows,常使用.exe 作为可执行文件的扩展名) |
不需要预编译成可执行文件,需要逐行编译成机器码执行 |
执行速度 | 执行速度通常较快。每次运行程序时,不需要重新翻译代码。 | 执行速度通常较慢,每次运行程序都需要解释器将源代码转化为机器码。 |
举例 | C、C++、Java | Python、JavaScript |
3、访问修饰符public、protected、private区别:
不同包 | 同包 | 同子类 | 同类 | |
---|---|---|---|---|
public | ✓ | ✓ | ✓ | ✓ |
protected | ✓ | ✓ | ✓ | |
default | ✓ | ✓ | ||
private | ✓ |
4、Integer运行原理
Integer
类是一个包装类,用于封装基本数据类型 int
的值。若其值在范围[-128, 127]内,那么它将引用缓存中的现有对象,而不会创建新的对象。若其值超出了范围[-128, 127],那么它将创建一个新的 Integer
对象,而不会引用缓存中的对象。
基础考察,指出下题的输出结果
public static void main(String[] args) {
Integer a = 128, b = 128, c = 127, d = 127;
System.out.println(a == b);
System.out.println(c == d);
}
答案是:false,true。
执行 Integer a = 128,相当于执行:Integer a = Integer.valueOf(128),基本类型自动转换为包装类的过程称为自动装箱(autoboxing)。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
在 Integer 中引入了 IntegerCache 来缓存一定范围的值,IntegerCache 默认情况下范围为:-128~127。
本题中的 127 命中了 IntegerCache,所以 c 和 d 是相同对象,而 128 则没有命中,所以 a 和 b 是不同对象。
但是这个缓存范围时可以修改的,可能有些人不知道。可以通过JVM启动参数:-XX:AutoBoxCacheMax= 来修改上限值,如下图所示:
5、用最有效率的方法计算2乘以8?
2 << 3。
进阶:通常情况下,可以认为位运算是性能最高的。但是,其实编译器现在已经“非常聪明了”,很多指令编译器都能自己做优化。所以在实际实用中,我们无需特意去追求实用位运算,这样不仅会导致代码可读性很差,而且某些自作聪明的优化反而会误导编译器,使得编译器无法进行更好的优化。
6、&和&&的区别?
-
&&(逻辑与):逻辑与运算符。当运算符左右两边的表达式都为 true,才返回 true。同时具有短路性(如果第一个表达式为 false,不会判断第二个表达式是否出错,值为多少,则直接返回 false)。
-
&(按位与):逻辑与运算符、按位与运算符,和 && 的区别是不具有短路性。
通常,在处理布尔条件时,推荐使用 &&
,因为它具有短路行为,可以提高效率和避免不必要的计算。
7、String 是 Java 基本数据类型吗?
答:不是。Java 中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type),剩下的都是引用类型(reference type)。
8、String 类可以继承吗?
不行。String 类使用 final 修饰,无法被继承。
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1 == s2); // true,因为它们都引用相同的字符串常量池中的对象
System.out.println(s1 == s3); // false,因为s3是一个新的对象
System.out.println(s1.equals(s3)); // true,因为内容相同
9、String和StringBuilder、StringBuffer的区别?
String | StringBuilder | StringBuffer | |
---|---|---|---|
不可变性 | ✓ | ||
线程安全 | ✓ | ✓ | |
适合频繁的字符串操作 | ✓ | ✓ |
不可变性:一旦创建了一个 String
对象,它的内容不能被修改。任何对字符串的操作都会返回一个新的字符串对象,而不会更改原始字符串。
StringBuffer:方法都进行了同步处理,StringBuffer
适用于多线程环境中需要频繁修改字符串内容的情况,因为它的操作是线程安全的,但性能可能较差。
StringBuilder: 适用于单线程环境中需要频繁修改字符串内容的情况,因为它的操作是非线程安全的,但性能较好。
10、String s = new String(“xyz”) 创建了几个字符串对象?
一个或两个。如果字符串常量池中已经有“xyz”,则只创建一个存放在堆空间的对象,用来存放字符串常量池中”xyz“的引用。如果没有,还会在字符串常量池中创建一个”xyz“。
注:字符串常量池中只放字符串的引用,实际值还在堆空间的一个(不能更改的)字符数组中。
11、String s = “xyz” 和 String s = new String(“xyz”) 区别?
两个语句都会先去字符串常量池中检查是否已经存在 “xyz”,如果有则直接使用,如果没有则会在常量池中创建 “xyz” 对象。
此外:String s = new String(“xyz”) 还会在堆空间里创建一个指向字符串常量池 “xyz” 的对象实例。
12、== 和 equals 的区别是什么?
==:运算符,用于比较基础类型变量和引用类型变量。对于基础类型变量,比较的变量保存的值是否相同,类型不一定要相同。
short s1 = 1; long l1 = 1;
// 结果:true。类型不同,但是值相同
System.out.println(s1 == l1);
对于引用类型变量,比较的是两个对象的地址是否相同。
Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
// 结果:false。通过new创建,在内存中指向两个不同的对象
System</