Loading

Java面试基础知识整理

Java面试基础知识汇总

1、Java语言有哪些优点

(1)面向对象。

(2)平台无关性,“一次编译,到处执行”。

(3)Java提供了很多的类库,通过这些类库简化了开发人员程序设计工作。

(4)提供了对Web应用开发的支持,例如Applet、Servlet和Jsp可以用来开发Web应用程序。

(5)具有较好的安全性和健壮性。

2、面向对象的特征

封装:封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。

继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类/基类),得到继承信息的被称为子类(派生类)。

多态:指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。实现多态需要做两件事情:继承(子类继承父类并重写父类的方法)和父类型引用指向子类对象。

3、Java基本的数据类型与其包装类有哪些

java中有8种基本数据类型,默认值和对应的包装类如下:

数据类型字节长度默认值包装类
byte 1 0 Byte
short 2 0 Short
int 4 0 Integer
long 8 0L或0l Long
float 4 0.0F或0.0f Float
double 8 0.0 Double
char 2 u0000 Character
boolean 1 false Boolean

4、Java中的访问权限修饰符有哪些

Java中有四种权限修饰符,权限如下所示:

注意:没有default这个关键字,它就是代表默认的意思,即什么修饰符也不加。一个Java文件中可以定义多个类,但最多只有一个类能被public修饰,并且这个类的类名与文件名必须相同。

 当前类同包子类其他包
public
protected ×
default × ×
private × × ×

(1)public:表明该成员变量或方法对所有类或对象都是可见的,所有类或对象都可以直接访问

(2)protected:表明该成员变量或方法对自己及其子类是可见的,即自己和子类具有权限访问。除此之外的其他类或对象都没有访问权限

(3)default:表明该成员变量或方法只有自己和与其位于同一包内的类可见。若父类与子类位于同一包内,则子类对父类的default成员变量或方法都有访问权限,若父类与子类位于不同的包,则没有访问权限。

(4)private:表明该成员变量或方法是私有的,只有当前类对其有访问权限。

5、重载和重写(覆盖)的区别

重载:重载发生在同一个类中,同名的方法具有不同的参数(参数个数不同、参数类型不同、参数顺序不同),不能通过方法的访问权限、返回值类型和抛出的异常类型来进行重载。

重写:重写发生在子类和父类之间,子类中的重写方法必须和父类中被重写的方法有相同的函数名和参数、相同的返回值类型。子类重写方法比父类被重写方法更好的访问,子类的重写方法所抛出的异常必须和父类中被重写的方法所抛出的异常一致。父类中被重写的方法不能为private。

6、什么是构造函数

构造函数是一种特殊的函数,用来在对象实例化时初始化对象的成员变量。构造函数具有以下特点:

(1)构造函数必须与类的名字相同,并且不能有返回值(返回值也不能为void)

(2)每个类可以有多个构造函数

(3)构造函数可以有0个或多个以上的参数

(4)构造函数伴随着new操作一起调用,且不能由程序的编写者直接调用,必须由系统调用构造函数在对象实例化时会被自动调用,且只运行一次。

(5)构造函数不能被继承,因此,它不能被覆盖,但是构造函数可以被重载,可以使用不同的参数个数或参数类型来定义多个构造函数。

(6)子类可以通过super关键字来显示地调用父类的构造函数。当父类没有提供无参数的构造函数时,子类的构造函数必须显式地调用父类的构造函数。如果父类提供了无参数的构造函数,子类的构造函数就可以不显式地调用父类的构造函数,这种情况下编译器会默认调用父类提供的无参数构造函数。在实例化对象时,会先执行父类的构造函数,然后在执行子类的构造函数。

7、抽象类和接口有什么异同

(1)通过把类或类中的某些方法声明为abstract(abstract只能用来修饰类或方法,不能用来修饰属性),来表示一个类是抽象类。接口通过关键字interface来实现,接口中的方法没有方法体。

(2)接口和抽象类都不能被实例化。

(3)抽象类中可以有抽象方法和具体方法,接口中只能有抽象方法。

(4)一个类可以实现多个接口,但一个类只能继承一个抽象类。因此,使用接口可以间接地达到多重继承的目的。

(5)接口中的成员变量默认为 public static final,只能够有静态的不被修改的成员。所有成员方法都都必须是public、abstract的。抽象类中的成员变量可以是public、default、protected、private。抽象类中的抽象方法(abstract修饰)不能用private、static、synchronized、native等访问修饰符修饰。

8、this和super有什么区别

(1)在Java中,this用来指向当前实例对象,用来区分对象的成员变量和方法的参数。

class People{
    String name;
    //正确写法
    public People(String name){
        this.name = name;
    }
    //错误写法
    public People(String name){
        name = name;
    }
}
上例中,第一个构造函数使用 this.name 来表示左边的值是成员变量,而不是这个构造函数的成员参数。

(2)super可以用来访问父类的成员方法或成员变量。

(3)this和super都必须放在构造方法内的第一行

(4)this和super不能出现在同一个构造函数内。

(5)this和super都不能在static环境中使用。

9、short s1 = 1; s1 = s1 + 1 有错吗?short s1 = 1; s1 += 1 有没有错误?

对于short s1 = 1;s1 = s1 + 1,在 s1 + 1 运算时会自动提升表达式的类型为int ,那么将 int 型值赋值给 short 型变量,s1 会出现类型转换错误。

而对于short s1 = 1; s1 += 1," += "是 Java 语言的运算符,Java 编译器会对其进行特殊处理,因此编译通过。

10、length和length()的区别

length属性是用来统计数组的长度

length()方法是用来计算字符串的长度

11、&和&&的区别?

&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边表达式的结果都为true时,整个运算结果才为true。

否则,结果为false。&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式。

12、static关键字有哪些作用

(1)静态变量 Java类中提供了两种类型的的变量。用static修饰的静态变量和不用static修饰的实例变量,静态变量属于类,在内存中只有一个复制。只要静态变量所在的类被加载,这个静态变量就会被被分配空间。对静态变量的引用有两种方式,分别为" 类.静态变量 "和" 对象.静态变量 "。

(2)静态方法 与变量类似,Java也同时提供了static方法和非static方法。static方法是类方法,不需要创建对象就可以被调用。static方法不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态变量和静态方法。

(3)静态代码块 static代码块经常被用来初始化静态变量。static代码块不在任何一个方法体内,JVM在加载类时会执行static代码块,如果有多个static代码块,JVM会按顺序来执行。需要注意的是,static代码块只会被执行一次

(4)静态内部类 静态内部类可以不依赖于外部类实例对象而被实例化,而通常的内部类需要在外部类实例化后才能实例化。静态内部类不能与外部类有相同的名字,不能访问外部类的普通成员变量,只能访问外部类的静态成员和静态方法。

13、使用switch时的注意事项

在使用switch(expr)时,expr只能是一个枚举常量或一个整数表达式,整数表达式可以是基本类型int或其包装类Integer,当然也包括不同的长度整型,例如short。由于byte、short和char类型的值都能被隐式的转换为int类型,因此这些类型以及他们对应的包装类型都可以作为switch的表达式。但是,long、float、double、String不能隐式的转换为int类型,因此不能被作为switch的表达式,如果一定要作为switch的表达式的话,必须将其强制转换为int才可以。注意:在JDK1.7版本之后 switch开始支持String类型了。

14、transient 关键字的作用

对于不想被序列化的变量,使用transient关键字修饰,transient 关键字只能修饰变量,而不能修饰方法和类。

15、用最有效率的方法计算2乘以8

2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。

16、Math类中round、ceil和floor方法的作用

(1)round:表示四舍五入,是在原来数字的基础上先加 0.5 ,然后在向下取整。Math.round(-11.5)的结果是-11,Math.round(11.5)的结果是12

(2)ceil:表示向上取整,Math.ceil(a) 就是取大于a的最小整数值。

(3)floor:表示向下取整,Math.floor(a) 就是取小于a的最大整数值。

17、== 和 equals、hashCode的区别

==:对于基本数据类型,== 比较的是数值是否相等。对于引用数据类型,则比较的是对象的地址值是否相等。

equals:equals()方法用来比较两个对象的是否相等,即引用类型的变量所指向的对象的地址。但是String、Integer 重写了equals方法,所以 equals 比较的是值是否相等。

public class test {
	public static void main(String[] args) {
		String s1 = "abc";
		String s2 = "abc";
		String s3 = new String("abc");
		String s4 = new String("abc");

		System.out.println(s1 == s2); //true
		System.out.println(s1 == s3); //false
		System.out.println(s3 == s4); //false

		System.out.println(s1.equals(s2)); //true
		System.out.println(s1.equals(s3)); //true
		System.out.println(s3.equals(s4)); //true     
    }
}

hashCode:hashCode()用来返回这个对象的散列码。散列码可以是任何整数,包括正数和负数。这个散列码可以用来确定该对象在哈希表中的索引位置。使用哈希表的话,可以快速定位到对象的大概存储位置,而且如果两个对象的hashCode不相同,就不在需要调用 equals() 方法。  

(1)如果两个对象相等,则 hashCode 一定也是相同的。

(2)两个对象相等,对两个对象分别调用 equals 方法都返回 true。

(3)两个对象有相同的 hashCode 值,它们也不一定是相等的。

(4)因此,equals 方法被重写过,则 hashCode 方法也必须被重写。

(5)hashCode() 的默认是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。

18、String 和 StringBuffer、StringBuilder 的区别是什么?

可变性

String 类中使用 final 关键字字符数组保存字符串, private final char value[] ,所以String对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder中也是使用字符数组保存字符串 char[]value 但是没有用 final 关键字修饰,所以这两种对象都是可变的。

线程安全性

String 中的对象是不可变的,线程安全。 StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,是线程安全的。 StringBuilder 没有对方法进行加同步锁,是非线程安全的。

执行效率

在执行效率方面,StringBuilder最高,StringBuffer 次之,String 最低。一般而言,如果要操作的数据量比较小,应优先使用String类。如果在单线程下操作大量数据,应优先使用StringBuilder类。如果是在多线程下操作大量数据,应优先考虑StringBuffer类。

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

  • indexOf():返回指定字符的索引。

  • charAt():返回指定索引处的字符。

  • replace():字符串替换。

  • trim():去除字符串两端空白。

  • split():分割字符串,返回一个分割后的字符串数组。

  • getBytes():返回字符串的 byte 类型数组。

  • length():返回字符串长度。

  • toLowerCase():将字符串转成小写字母。

  • toUpperCase():将字符串转成大写字符。

  • substring():截取字符串。

  • equals():字符串比较。

20、String字符串修改实现的原理

当用String类型来对字符串进行修改时,其实现方法是首先创建一个StringBuffer,其次调用StringBuffer的append()方法,最后调用StringBuffer的toString()方法将结果返回。

21、是否可以继承String类?

String 类是final类,不可以被继承。

22、final、finally和finalize的区别

(1)final用于声明属性方法和类,分别表示属性不可变,方法不可覆盖,和类不可被继承。

(2)finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行。

(3)finalize是Object类的一个方法,在垃圾回收器执行时会调用被回收对象的finalize()方法

23、finally块中的代码什么时候被执行

finally块的作用就是为了保证代码一定会被执行,而且是在return之前执行。

但是如下两种情况finally代码块不会被执行:

(1)当程序在进入try语句块之前就出现异常时,会直接结束。不会执行finally块中的代码。

(2)当程序在try语句块中强制退出时也不会去执行finally块中的代码,比如在 try 块中执行了exit()方法。

24、java 异常有哪几种

java.lang 包中 Throwable 类是所有异常的父类,它有两个直接子类 Error 和 Exception。

Error(错误):表示系统的内部错误和资源耗尽错误,通常不能预期和恢复(譬如 JVM 崩溃、内存不足等)。

Exception(异常):是程序本身可以处理的异常,分为运行时异常(runtime exception)和受检查的异常(checked exception)。

 25、java中运行时异常和受检查的异常有什么区别

运行时异常:编译器没有强制对其进行捕获并处理,当出现这种异常时,会由JVM来处理,例如NullPointerException(空指针异常)、ClassCastException(类型转换异常)、ArrayIndexOutOfBoundsException(数组越界异常)。

受检查的异常:要么用 try … catch… 捕获,要么用 throws 声明抛出,交给父类处理。

26、throw 和 throws 的区别?

throw用于方法内部,throws用于方法声明上。

throw后跟异常对象,throws后跟异常类型。

throw后只能跟一个异常对象,throws后可以一次声明多种异常类型

27、什么是Java的序列化

当进行远程通信时,无论是何种类型的数据,都会以二进制序列的形式在网络上传送。序列化是将对象以一连串的字节描述的过程。序列化可以将对象的状态写在流里进行网络传输,或者保存到文件、数据库等系统中。

28、如何实现序列化

要实现序列化的类都必须实现Serializable接口,Serializable接口位于java.lang包中,它里面没有包含任何方法。使用一个输出流(例如FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着使用该对象的writeObject(Object obj)方法就可以将obj对象写出,要恢复时可以使用其对应的输入流。

 

posted @ 2019-12-25 16:26  charlatte  阅读(677)  评论(0编辑  收藏  举报