面试题集锦-java基础

java数据类型

数据类型
引用数据类型
基本数据类型
数值型
整数型 byte short int long
浮点型 float double
字符型 char
布尔型 boolean
接口
数组

下面这串代码打印的结果是什么?

public class Test {
    public static void main(String[] args) {
        System.out.println(Math.min(Double.MIN_VALUE, 0.0d));
    }
}

Double. MIN_VALUE 和 Double. MAX_VALUE 一样,都是正数,Double. MIN_VALUE 的值是
2^(-1074),直接打印 Double. MIN_VALUE 的话,输出结果为 4.9E-324。

因此这道题的正确答案是输出 0.0。

finally块一定会执行吗?

  • 在 try 块或者 catch 语句中执行 return 语句时,finally 语句会执行;
  • 在 try 块或者 catch 语句中执行 System.exit() 时,finally 语句不会执行。

面试题

JDK和JRE的区别

  1. JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。
  2. JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。
  1. 具体来说 JDK 其实包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,还包含了很多 Java 程序调试和分析的工具。
  2. 简单来说:如果你需要运行 Java 程序,只需安装 JRE 就可以了,如果你需要编写 Java 程序,需要安装
    JDK。

== 和 equals 的区别是什么?

1. ==号解读

对于基本类型和引用类型 == 的作用效果是不同的,如下所示:

  • 基本类型:比较的是值是否相同;
  • 引用类型:比较的是引用是否相同;

代码示例:

String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true

代码解读:因为 x 和 y 指向的是同一个引用(y位于字符串常量池中,和x共用一个引用地址),所以 == 也是 true,而 new String()方法则重写开辟了内存空间,所以 ==
结果为 false,而 equals 比较的一直是值,所以结果都为 true。

2. equals解读

  • equals 本质上就是 ==(因为equals方法是Object类中的方法),只不过 String 和 Integer 等重写了 equals 方法,把它变成了值比较。
  • 所以一般情况下 equals 比较的是值是否相等。
    代码示例:
/**
* Object类中的equals方法
*/
public boolean equals(Object obj){return (this == obj);}

/**
* String类中的重写的equals方法
* 
*/
publicbooleanequals(Object anObject){
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

两个对象的 hashCode() 相同,但是 equals() 也一定相同

  • hashCode是Object类的一个本地方法,默认返回的是当前对象的内存地址偏移量
  • 自定义对象基本都重写hashCode
    代码示例:
String str1 = "通话";
String str2 = "重地";
System. out. println(String. format("str1:%d | str2:%d",  str1. hashCode(),str2. hashCode()));
System. out. println(str1. equals(str2));

//执行的结果:
 //  str1:1179395 | str2:1179395
 //  false

final 在 Java 中有什么作用?

  • final 修饰的类叫最终类,该类不能被继承。
  • final 修饰的方法不能被重写。
  • final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。

Math.Round(3.45, 1)等于几

答案为 3.4

  • 有不少人误将Math.Round函数当作四舍五入函数在处理, 结果往往不正确, 实际上Math.Round采用的是国际通行的是 Banker 舍入法.
  • Banker’s rounding(银行家舍入)算法,即四舍六入五取偶。事实上这也是 IEEE 规定的舍入标准。因此所有符合 IEEE 标准的语言都应该是采用这一算法的. 这个算法可以概括为:

“四舍六入五考虑,五后非零就进一,五后皆零看奇偶,五前为偶应舍 去,五前为奇要进一。”

请看下面的例子:

   Math.Round(3.44, 1); //Returns 3.4.  四舍
   Math.Round(3.451, 1); //Returns 3.5  五后非零就进一
   Math.Round(3.45, 1); //Returns 3.4. 五后皆零看奇偶, 五前为偶应舍 去
   Math.Round(3.75, 1);  //Returns 3.8  五后皆零看奇偶,五前为奇要进一
   Math.Round(3.46, 1); //Returns 3.5. 六入

String 属于基础的数据类型吗?

  • String 不属于基础类型,而是引用数据类型
  • 基础类型有 8 种:byte、boolean、char、short、int、float、long、double,而 String 属于对象。

Java 中操作字符串都有哪些类?它们之间有什么区别?

  • 操作字符串的类有:String、StringBuffer、StringBuilder。
  • String 声明的是不可变的对象,每次操作都会生成新的 String 对象然后将指针指向新的 String 对象
  • StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。
  • StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。

String str="i"与 String str=new String(“i”)一样吗?

不一样,因为内存的分配方式不一样。String str="i"的方式,Java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中。

如何将字符串反转?

使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。

String 类的常用方法都有那些?

indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。

String不可变性

什么是不可变性

给已有字符串赋值,不是在原内存地址上修改,而是重新生成一个新对象、新内存地址。

为什么不可变(怎么做到不可变的)

  1. 内因
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
  1. String本质是一个char数组,使用final修改可以保证value不可变(只是引用地址不可变)
  2. value不可变只是引用地址不可变;value[]数组是内容可变的。value只是栈上的一个引用,数组的本体结构在堆中,用final修饰value只能说明value引用地址不可变[即不允许value执行堆区另一个内存地址],不能确保堆里面的value数组不可变。
 public static void main(String[] args) {
          final char[] value = {'q','w'};
          char[] other={'r','t'};
          
//          value=other;   //编译报错

   // 直接操作数组元素
          value[1]='u'; // 根据数组下标赋值
          Array.set(value,1 ,'p' );//或通过反射赋值
        System.out.println(value); // 输出结果为: qp
    }
  1. 保证不可变的主要原因是
    3.1 使用private修改value[]数组;不对外暴露
    3.2 所有String方法里面没有动value[]数组里面的内容,都是新创建对象
  1. 外因

使用final修改String类,保证不被继承,防止继承后破坏String的不可变特性

不可变的好处

安全

Hash中作为key,不可变性保证key的唯一性
多线程中使用安全。因为多线程中读不存在竟态,但是写会存在;不可变性保证不能被写,所有线程安全

常量池的基石

如果字符串可以被修改,常量池就没有存在的意义了

抽象类必须要有抽象方法吗?

不需要,抽象类不一定非要有抽象方法。

示例代码:

abstract classCat{
    publicstaticvoidsayHi(){
        System. out. println("hi~");
    }
}

上面代码,抽象类并没有抽象方法但完全可以正常运行。

普通类和抽象类有哪些区别?

普通类不能包含抽象方法,抽象类可以包含抽象方法。
抽象类不能直接实例化,普通类可以直接实例化。

接口和抽象类有什么区别?

实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
构造函数:抽象类可以有构造函数;接口不能有。
实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。

什么是反射?

反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。

什么是 Java 序列化?什么情况下需要序列化?

Java 序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。

以下情况需要使用 Java 序列化:

  • 想把的内存中的对象状态保存到一个文件中或者数据库中时候;
  • 想用套接字在网络上传送对象的时候;
  • 想通过RMI(远程方法调用)传输对象的时候。

动态代理是什么?有哪些应用?

动态代理是运行时动态生成代理类。

动态代理的应用有 spring aop、hibernate 数据查询、测试框架的后端 mock、rpc,Java注解对象获取等。

怎么实现动态代理?

JDK 原生动态代理和 cglib 动态代理。JDK 原生动态代理是基于接口实现的,而 cglib 是基于继承当前类的子类实现的。

为什么要使用克隆?

克隆的对象可能包含一些已经修改过的属性,而 new 出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠克隆方法了。

如何实现对象克隆?

实现 Cloneable 接口并重写 Object 类中的 clone() 方法。
实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

深拷贝和浅拷贝区别是什么?

浅克隆:当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。
深克隆:除了对象本身被复制外,对象所包含的所有成员变量也将复制。

throw 和 throws 的区别?

throw:是真实抛出一个异常。
throws:是声明可能会抛出一个异常。

final、finally、finalize 有什么区别?

  • final:是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变量,则表示此方法和此变量不能在被改变,只能使用。
  • finally:是 try{} catch{} finally{} 最后一部分,表示不论发生任何情况都会执行,finally 部分可以省略,但如果 finally 部分存在,则一定会执行 finally 里面的代码。
  • finalize: 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。

try-catch-finally 中哪个部分可以省略?

try-catch-finally 其中 catch 和 finally 都可以被省略,但是不能同时省略,也就是说有 try 的时候,必须后面跟一个 catch 或者 finally。

try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

finally 一定会执行,即使是 catch 中 return 了,catch 中的 return 会等 finally 中的代码执行完之后,才会执行。

常见的异常类有添加链接描述哪些?

NullPointerException 空指针异常
ClassNotFoundException 指定类不存在
NumberFormatException 字符串转换为数字异常
IndexOutOfBoundsException 数组下标越界异常
ClassCastException 数据类型转换异常
FileNotFoundException 文件未找到异常
NoSuchMethodException 方法不存在异常
IOException IO 异常
SocketException Socket 异常

Java为什么不支持多重继承

参考
多重继承的钻石问题(菱形问题)

类 B 和类 C 继承自类 A,且都重写了类 A 中的同一个方法,而类 D 同时继承了类 B 和类 C,那么此时类 D 会继承 B、C
的方法,那对于 B、C 重写的 A 中的方法,类 D 会继承哪一个呢?

看到这里,相信大家也明白了多重继承会导致这种有歧义的情况存在。
但是一个类可以实现多个接口。

Double和Integer的除法

当浮点数除以 0 的时候,结果为 Infinity 或者 NaN。

System.out.println(1.0 / 0.0); // Infinity
System.out.println(0.0 / 0.0); // NaN

Infinity 的中文意思是无穷大;
NaN 的中文意思是这不是一个数字(Not a Number)。

当整数除以 0 的时候(10 / 0),会抛出异常:

Exception in thread "main" java.lang.ArithmeticException: / by zero
 at com.itwanger.eleven.ArithmeticOperator.main(ArithmeticOperator.java:32)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值