Java基础常见面试题
- 2019 年 10 月 5 日
- 筆記
- 什么是类与对象?类和对象实例之间的关系?
答∶ 类具有继承、数据隐藏和多态三种主要特性。类是同一类对象实例的共性的抽象,对象是类的实例化;类是静态的,对象是动态的,对象可以看作是运行中的类。类负责产生对象,可以将类当成生产对象的工厂
- 构造函数的特点有哪些?
答∶
1)构造函数的方法名与类名相同。
2)构造函数没有返回类型。
3)构造函数的主要作用是完成对类对象的初始化工作。
4)构造函数不能由编程人员显式地直接调用。
5)在创建一个类的新对象的同时,系统会自动调用 该类的构造函数为新对象初始化。
构造函数不可以被继承
默认构造函数指没有参数的构造函数
如果编写的类没有构造函数,系统会自动提供一个默认构造函数,它把所有的属性设为默认值(比如一些基本数据类型)。
- 是否可以从一个static方法内部发出对非static方法的调用?
答∶
不可以。因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用。
- JAVA中怎样去识别方法?
答∶ 根据方法名、参数列表、参数类型、参数顺序去识别的
- 创建对象的方法?
答∶
1、用new语句创建对象,这是常见的创建对象的方法
2、运用反射手段,调用java.lang.Class 或者 java.lang.reflect.Construct类的newInstance()实例方法
3、调用对象的clone方法
4、运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法
- 面向对象的特征有哪些方面?
答∶
1.抽象:
抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象包括两个方面,一是过程抽象,二是数据抽象。
2.继承:
继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。
3.封装:
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
- 抽象类和接口有什么区别?
答∶
一 接口和抽象类的相似性
1 接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。
2 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
二 接口和抽象类的区别
1 接口里只能包含抽象方法,静态方法和默认方法,不能为普通方法提供方法实现,抽象类则完全可以包含普通方法。
2 接口里只能定义静态常量,不能定义普通成员变量,抽象类里则既可以定义普通成员变量,也可以定义静态常量。
3 接口不能包含构造器,抽象类可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。
4 接口里不能包含初始化块,但抽象类里完全可以包含初始化块。
5 一个类最多只能有一个直接父类,包括抽象类,但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承不足。
- final 、finally、finallize区别?
答∶
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
- OverLoading 和OverRiding的区别?
答∶ 是Java多态性的不同表现。重写是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载。重载的方法是可以改变返回值的类型。
- JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
答∶ Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。
Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理。
用try来指定一块预防所有“异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的“异常”的类型。
throw语句用来明确地抛出一个“异常”。
throws用来标明一个成员函数可能抛出的各种“异常”。
Finally为确保一段代码不管发生什么“异常”都被执行一段代码。
可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,“异常”的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种“异常”进行处理,堆栈就会展开,直到遇到有处理这种“异常”的try语句。
- 列举常见的5个运行时异常?
答∶ 运行时异常,父类是RuntimeException 例如有:
ClassCastException |
---|
NullPointException |
AirthmeticException |
IndexOutOfBoundsException |
JMRuntimeException |
- error 和 exception区别?
答∶
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
- int 和 Integer 有什么区别?
答∶ Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。
原始类型封装类
boolean |
Boolean |
---|---|
char |
Character |
byte |
Byte |
short |
Short |
int |
Integer |
long |
Long |
float |
Float |
double |
Double |
引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。
- “==” 和 equals区别?
答∶
第一种比较的是两个字符串对象的内存地址是否相同,如果是基本数据类型则对比的是值。
第二种比较的是两个字符串对象的值是否相同,equals继承Object类,比较的是否是同一个对象,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
- String 与StringBuffer的区别,实际项目中什么情况下用String什么情况下用StringBuffer?
答∶
String的长度是不可变的
StringBuffer的长度是可变的。如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法
- String s = new String("xyz");创建了几个String Object?
答∶ 两个对象,一个是“xyx”,一个是指向“xyx”的引用对象
- 说出ArrayList,Vector, LinkedList的存储性能和特性?
答∶ ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
- List、Map、Set三个接口,存取元素时,各有什么特点?
答∶
List接口
ArrayList:一个可增长的数组,提供快速遍历和快速随机访问,当需要快速遍历时而不是做大量删除和插入时,用ArrayList
Vector(Hashtable)为了线程安全,Vector方法被同步,通常使用ArrayList 而不用Vector
Set接口
重在数据的唯一性,不允许重复,set接口通过equals()方法确定两个对象是否相等,重复时只能有一个放在set中
Map接口:
按 “键-值”对进行插入,(键、值都是对象)可以按照键来搜索值对象,可以查找值的集合,也可以查找键的集合, key 不可重复,value可重复。
- 什么是java序列化,如何实现java序列化?
答∶
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。
序列化的实现:将需要被序列化的类实现Serializable接口
ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流
- java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
答:字节流,字符流。字节流继承于InputStream OutputStream,字符流继承于InputStreamReader OutputStreamWriter。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便
- HashTable和HashMap区别?
答∶ HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
- 怎么遍历HashMap集合?
答∶ 首先要通过keySet()方法得到键的集合,再得到键集合的迭代器,进行迭代,通过get(key)得到值
- Collection与Collections区别?
答∶Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
- 什么叫单例模式?
答∶ 私有化构造方法,只有在本类中才可以new 那个对象,通过一个方法返回出去
public class Singleton {
private static Singleton instance = null
private Singleton(){
}
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次使用时生成实例,提高了效率!
if (instance==null){
instance=new Singleton();
return instance;
}
}
- 什么叫工厂模式?
答∶ 工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。
- 创建线程的方式,以及分别怎么启动线程?
答∶ 有两种实现方法,分别是继承Thread类与实现Runnable接口。继承Thread 可直接用对象.start()方法启动线程,实现Runnable接口的可以定义一个Thread类的对象,通过构造方法把实现Runnable接口的类的对象初始化进去,用Thread类对象.start()方法启动线程。
- 通讯的方式有几种,以及区别?
答∶ UDP 和 Tcp/Ip UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!通信效果高,但也正因为如此,它的可靠性不如TCP协议高。 UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。 TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接,适用于一次传输大量数据,对可靠性要求高的应用环境。
- 什么是多态,举例在代码那些地方用到了?
答∶ 相同的操作不同的实现,例如在方法重载重写及接口的实现。
- list与普通数组的区别?
答∶ 前者的长度是动态的,类型为object,后者在申明是需确定长度且类型是一致的。
- string stringbuffer StringBuilder 有什么区别?
答∶
String是“字符串常量”,也就是不可改变的对象。
StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。
StringBuffer:线程安全的,StringBuilder:线程非安全的
1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
- 流按方向划分分为?按传送的内容划分分为?
答∶ 方向划分:输入输出流。 内容分为:字节流,字符流,对象流
- 访问修饰符有哪些?分别的作用?
答∶
public |
能被所有的类(接口、成员)访问。 |
---|---|
protected |
只能被本类、同一个包中的类访问;如果在其他包中被访问,则必须是该成员所属类的子类。 |
private |
成员变量和方法都只能在定义它的类中被访问,其他类都访问不到。对成员变量的进行获取和更改,一般用get(),set() ,public 方法。实现了Java面向对象的封装思想。 |
缺省 |
访问权限与protected相似,但修饰类成员时不同包中的子类不能访问。 |
