Java基础面试题学习笔记

96 阅读5分钟

前言

主要用于记录准备面试阶段遇到的Java基础面试题

正文

1、自动装箱

判断程序输出结果

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) 查看Integer.valueOf源码

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来缓存值,默认的范围为:-128 ~ 127 修改默认缓存范围: JVM启动参数:-XX:AutoBoxCacheMax=

2、&和&&的区别

&&: 逻辑与运算符。当运算符左右两边的表达式都为 true,才返回 true。同时具有短路性,如果第一个表达式为 false,则直接返回 false &: 逻辑与运算符、按位与运算符

按位与运算符: 用于二进制的计算,只有对应的两个二进位均为1时,结果位才为1 ,否则为0 &在用于逻辑与时,和&&的区别是不具有短路性。所在通常使用逻辑与运算符都会使用 &&,而 & 更多的适用于位运算。

3、数据类型

基本数据类型: byte、short、int、long、float、double、char、boolean

类型概述范围默认值作用例子
byte8位、有符号,以二进制补码表示的整数-2^7 ~ (2^7-1),即 -128 ~ 1270byte类型用在大型数组中节约空间,主要代替整数,因为byte变量占用的空间只有int的四分之一;例子:byte a=-2
short16位,有符号,以二进制补码表示的整数-2^15 ~ 2^15-1, 即 -32768 ~ 327670short占用空间是int的二分之一例子:short s=-20000
int32位、有符号,以二进制补码表示的整数-2^31 ~ 2^31-10一般整数型默认为int类型;例子:int=-200000
long64位、有符号,以二进制补码表示的整数-2^63 ~ 2^63-10L主要使用在需要比较大整数的系统上例子:long a=10000L
float32位、单精度,浮点数浮点数不能用于表示精确的值0.0f在存储大型浮点数组的时候可以节省内存空间例子:float f1=0.3f
double64位、双精度,浮点数double也不能表示精确的值0.0d浮点数的默认类型为double类型例子:double d1=12.3
boolean表示一位的信息取值:true/falsefalse只作为一种标志类记录 true/false 情况例子:boolean one=true
char是一个单一的16位Unicode字符\u0000(即0)~\uffff(65,535)'\u0000'char可以存储任何字符例子:char letter='A'

引用数据类型:

  • 引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时候被指定为一个特定的类型,声明之后不能改变。
  • 引用数据类型包括:类(对象)、接口、数组。
  • 所有引用类型默认值都是null.
  • 一个引用变量可以用于引用任何与之兼容的类型。

基本数据类型:数据存储在栈上 引用数据类型:数据存储在堆上,栈上只存储引用地址

4、String和StringBuilder、StringBuffer

String: String的值被创建后不能修改,任何对String的修改都会引起新的String对象的生成 StringBuilder: 值可以改变,线程安全(synchronized) StringBuffer: 值可以改变,线程不安全,性能更高

5、==和equals

==: 运算符,用于比较基础类型变量和引用类型变量 对于基础类型变量,比较的变量保存的值是否相同,类型不一定要相同。

short s1 = 1; long l1 = 1;
System.out.println(s1 == l1);
// true,类型不同,但是值相同

对于引用类型变量,比较的是两个变量的地址是否相同。

Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
System.out.println(i1 == i2);
// false,通过new创建,在内存中指向两个不同的对象

equals: Object 类中定义的方法,通常用于比较两个对象的值是否相等。 equals 在 Object 方法中其实等同于 ==,但是在实际的使用中,equals 通常被重写用于比较两个对象的值是否相同。

Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
System.out.println(i1.equals(i2));
// true,两个不同的对象,但是具有相同的值
 
// Integer的equals重写方法
public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        // 比较对象中保存的值是否相同
        return value == ((Integer)obj).intValue();
    }
    return false;
}

6、equals()和hashCode()

  • 若重写了equals(Object obj)方法,则有必要重写hashCode()方法。

  • 若两个对象equals(Object obj)返回true,则hashCode()有必要也返回相同的int数。

  • 若两个对象equals(Object obj)返回false,则hashCode()不一定返回不同的int数。

  • 若两个对象hashCode()返回相同int数,则equals(Object obj)不一定返回true。

  • 若两个对象hashCode()返回不同int数,则equals(Object obj)一定返回false。

  • 同一对象在执行期间若已经存储在集合中,则不能修改影响hashCode值的相关信息,否则会导致内存泄露问题。

7、JDK和JRE和JVM

  • JDK: Java Development Kit(Java开发工具包)
  • JRE: Java Runtime Environment(Java运行环境)
  • JVM: Java Virtual Machine(Java虚拟机)

image.png

JDK = JRE + Java开发工具(javac.exe,java.exe,javadoc.exe)

JRE = JVM + Java核心类库

8、初始化顺序

public class InitialTest {
    public static void main(String[] args) {
        A ab = new B();
        ab = new B();
    }
}
class A {
    static { // 父类静态代码块
        System.out.print("A");
    }
    public A() { // 父类构造器
        System.out.print("a");
    }
}
class B extends A {
    static { // 子类静态代码块
        System.out.print("B");
    }
    public B() { // 子类构造器
        System.out.print("b");
    }
}

执行结果:ABabab

  • 静态变量/静态代码块只会初始化(执行)一次
  • 当有父类时,完整的初始化顺序为:父类静态变量(静态代码块)->子类静态变量(静态代码块)->父类非静态变量(非静态代码块)->父类构造器 ->子类非静态变量(非静态代码块)->子类构造器

9、try、catch、finally

  • 运行顺序
public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }
    public static int test1() {
        int i = 0;
        try {
            i = 2;
            return i;
        } finally {
            i = 3;
        }
    }
}

执行结果:2 在进入finally之前,jvm会将i的值暂存

10、多线程实现方式

  • 继承Thread类

  • 实现Runnable接口

  • 实现Callable接口