Java面试题(1) – 语言基础

Java面试题(1) – 语言基础

1 一个字符占多少个字节,int、long、double占多少字节?

字符(char)是Java中的基本数据类型,由2个字节组成,范围从0开始,到2^16-1。int占4个字节,long占8个字节,double占8个字节。

2 Java中的异常有哪几类,分别怎么使用?

Java中的异常分成Error和Exception两类。

Error和Exception的关系:

  • 继承结构:Error和Exception都是继承于Throwable,RuntimeException继承自Exception。
  • Error和RuntimeException及其子类称为未检查异常(Unchecked exception),其它异常成为受检查异常(Checked Exception)。

Error和Exception的区别:

  • Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。如java.lang.StackOverFlowError和Java.lang.OutOfMemoryError。对于这类错误,Java编译器不去检查他们。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。
  • Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

Exception又分为运行时异常(Runtime Exception)和受检查的异常(Checked Exception ):

  • RuntimeException:其特点是Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try……catch捕获,也没有用throws抛出,还是会编译通过,如除数为零的ArithmeticException、错误的类型转换、数组越界访问和试图访问空指针等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。
  • 受检查的异常(IOException等):这类异常如果没有try catch也没有throws抛出,编译是通不过的。这类异常一般是外部错误,例如文件找不到、试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。

3 ==和equals的区别?

在JAVA中,==与equals都有比较判断对象是否相等的作用,但具体用法却并不相同。

==是运算符号,而equals则属于方法。

当==两边的对象属于基本类型时,==的作用仅是比较对象的值是否相等,如果相等返回true,否则返回false;当两边的对象属于引用数据类型时,==的作用是判断对象的内存地址是否一致,如果同时指向同一地址,则返回true,否则返回false.

equals两边对象只能属于引用数据类型,因为equals是方法,所以它是如何具体判断对象是否相等是根据程序而定的,equals是属于 object类,默认是判断内存地址是否相同,但在object的子类中可以重写equals方法,如在String类中只是比较对象内容是否一致,一致 则返回true,否则返回false

4 hashCode方法的作用?

  • HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode经常用于确定对象的存储地址。
  • 如果两个对象相同, equals方法一定返回true,并且这两个对象的HashCode一定相同;
  • 两个对象的HashCode相同,并不一定表示两个对象就相同,即equals()不一定为true,只能够说明这两个对象在一个散列存储结构中。
  • 如果对象的equals方法被重写,那么对象的HashCode也尽量重写。

5 创建一个类的实例都有哪些方法?

创建对象的方法有四种:

  • 使用new关键字

    Something somethingNew = new Something();
  • 反射机制
    利用java.lang.Class类的newInstance方法,则可根据Class对象的实例,建立该Class所表示的类的对象实例。

somethingNew.getClass().newInstance().
  • 实现Cloneable接口

    User user1 = new User(1,"dan");
    User user2 = null;
    user2 = (User) user1.clone();
  • 序列化和反序列化
    序列化:将对象转化为可保持或传输的格式过程,被序列化的对象必须实现序列化接口即implement serialiable
    反序列化:将流转化为对象的过程

6 final、finally、finalize的区别?

区别:

  • final用于声明属性、方法和类,分别表示属性不可变,方法不可覆盖,类不可以继承。
  • finally是异常处理语句结构的一部分,表示无论是否发生异常总是要执行。
  • finalize是Object类中的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收。

详解:

  • final
    如果一个类被声明为 final,意味着它不能再派生出新的子类,即不能被继承,因此它和 abstract 是反义词。想要让一个类永远不被继承,就可以用 final 修饰,但要注意:final 类中所有的成员方法都会隐式的定义为 final 方法。

将变量声明为 final,可以保证它们在使用中不被改变,被声明为 final 的变量必须在声明时给定初值,在以后的引用中只能读取不可修改。

当 final 修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化。
当 final 修饰一个引用类型时,则在初始化之后便不能再让其指向其它对象了,但该引用所指向的对象的内容是可以发生变化的。本质上是一回事,因为引用的值是一个地址,final 要求该值,即地址的值不发生变化。
final 修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。
当函数的参数类型声明为 final 时,说明该参数是只读型的,无法改变该参数的值。

  • finalize
    finalize是object的方法,用来处理垃圾的回收,但是在JDK1.9之后垃圾机制已经很便捷了,所以官方把垃圾回收机制作为不推荐的方法了。

  • finally
    finally 作为异常处理的一部分,它只能在 try/catch 语句中,并且附带一个语句块表示这段语句最终一定被执行(无论是否抛出异常),经常被用在需要释放资源的情况下,System.exit (0) 可以阻断 finally 执行。

7 String、StringBuffer、StringBuilder的区别,如何实现?

String 类是不可变类,即一旦一个 String 对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。
StringBuilder 类是 JDK 1.5 新增的类,它也代表可变字符串对象。StringBuilder 和 StringBuffer 功能基本相似,方法也差不多。StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能,所以性能略高。因此在通常情况下,如果需要创建一个内容可变的字符串对象,则应该优先考虑使用 StringBuilder 类。

StringBuffer、StringBuilder、String 中都实现了 CharSequence 接口。CharSequence 是一个定义字符串操作的接口,它只包括 length()、charAt(int index)、subSequence(int start, int end) 这几个 API。

8 什么是序列化,如何实现序列化?

序列化就是一种用来处理对象流的机制,对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

将需要被序列化的类实现Serializable接口就可以实现序列化。该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

9 String temp=new String("abc");创建了几个StringObject?

先了解这个语句的执行步骤:

  • 在虚拟机栈中为String类型的temp分配内存
  • 在堆中为分配一块内存用来保存"abc"
  • 将堆中指向"abc"的地址赋值给temp

JVM维持了一个字符串常量池,如果池子中没有"abc",就创建了值为"abc"的对象和temp两个对象,否则就是只创建一个temp对象。再看看下面的代码:

String m = "abc";
String n = "abc";
String temp = new String("abc");
System.out.println(m == n); // 输出 true
System.out.println(m == temp); // 输出 false

10 int和Integer有什么区别?Integer值缓存范围是什么?

  • Integer是int的包装类,int则是java的一种基本数据类型
  • Integer变量必须实例化后才能使用,而int变量不需要
  • Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
  • Integer的默认值是null,int的默认值是0

Integer会缓存-128到127之间的数。比如,Integer i = 127时,将127缓存,下次再写Integer j = 127时,直接从缓存中取。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注