Java应届生高频面试题(JavaSE篇)

不知道你有没有遇到过这种情况,在大四准备面试时,看着一本厚厚的《Java从入门到精通》无从下手?甚至失去了干开发的欲望?面临着毕业即失业的窘境?这些我都在今年体验了一遍。。。不知道在经历了多少次的笔试面试之后,我终于在5.20当天收到Offer,这是个幸运的日子,在入职了将近一个半月后,我决定把我面试过程整理的高频“面点”分享出来,希望可以帮助更多刚毕业的小伙伴尽早找到工作!(因个人能力有限,面试次数有限,肯定还有还有漏掉的地方,大家谅解)

请列举你所知道的Object类的方法并简要说明

1、Object()默认构造方法。

2、clone() 创建并返回此对象的一个副本。

3、equals(Object obj) 指示某个其他对象是否与此对象“相等”。

4、finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

5、getClass()返回一个对象的运行时类。

6、hashCode()返回该对象的哈希码值。

7、notify()唤醒在此对象监视器上等待的单个线程

8、notifyAll()唤醒在此对象监视器上等待的所有线程。

9、toString()返回该对象的字符串表示。

10、wait()导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。

11、wait(long timeout)导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。

12、wait(long timeout, int nanos) 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量

请你讲讲abstract classinterface有什么区别?

抽象类和接口中,都有抽象方法需要实现,他们都不能创建实例对象,区别是:

1、抽象类可以有构造方法、普通成员变量、普通方法,但接口不行。

2、抽象类和接口都可以包含静态成员变量、静态方法,抽象类中的静态成员变量可以是任意访问类型,但接口必须是public(Java8支持default)。

3、抽象类的抽象方法的访问类型可以是public、protected,但接口必须是public。

4、一个类可以实现多个接口,但只能继承一个抽象类。

Java中常见的异常有哪些

java.lang.NullPointerException

空指针异常

java.lang.ClassNotFoundException

指定的类不存在

java.lang.ArithmeticException

数学运算异常

java.lang.ArrayIndexOutOfBoundsException

索引越界

java.lang.IllegalArgumentException

方法的参数错误

java.lang.IncompatibleClassChangeError

不兼容的类变化错误

java.lang.InstantiationError

实例化错误

java.lang.LinkageError

链接错误

java.lang.StackOverflowError

堆栈溢出

Overload和Override的区别,Overloaded的方法是否可以改变返回值的类型

Overload是重载的意思,Override是覆盖的意思,也就是重写。

重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)

重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。

如果两个方法的参数列表完全一样,是否可以让它们的返回值不同来实现重载Override。这是不行的

父类和子类中,静态代码块、代码块、构造方法、普通方法执行顺序

1、父类中的静态变量和静态代码块

2、子类中的静态变量和静态代码块

3、父类中的普通变量和代码块->构造方法

4、子类中的普通变量和代码块->构造方法

变量和代码块的执行与声明顺序有关,变量一般声明在代码块前

Java中权限修饰符及其作用范围

修饰符

同一个类

同一个包

子类

任何地方

private

 

 

 

default

 

 

protected

 

public

String,StringBuffer,StringBulider的区别

String只读字符串,意味着其引用的字符串内容不能发生改变

StringBuffer/StringBuilder 表示的字符串对象可以直接进行修改。

StringBuilder 是 Jdk1.5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,

因为它的所有方法都没有被 synchronized 修饰,因此它的效率理论上也比StringBuffer 要高。

final 、finally 、finalize之间的区别

final 用于声明变量,方法,类,表示变量不可改变(引用不能改变,只可以改变),方法不能重写,类不可以被继承

finally 用于异常处理中,表示,必须要执行的代码块,除非java虚拟机停止工作,否则一定会执行

finalize() 是Object类中的一个方法,用于java虚拟机的垃圾回收

多线程的创建方式

1、继承Thread类并重写run()方法;

2、实现Runnable接口并重写run方法;

3、实现Callable接口由FeatureTask创建

4、通过线程池创建 如ExecutorService

多线程的生命周期

新建:当通过new操作符创建一个线程时,处于新建状态

就绪:使用start()方法之后处于就绪状

运行:真正执行run()方法

阻塞:执行了sleep()、wait() 方法后

死亡:当线程执行完或者因为异常退出run()方法后

sleep(),wait()方法的区别

sleep()属于Thread类中,wait()属于Object类中的。

sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

在调用sleep()方法的过程中,线程不会释放对象锁。wait()会释放对象锁,重新进入就绪状态需要notify()或者notifyAll()方法

死锁现象以及解决办法

指的是两个或两个以上的线程执行过程中,为争夺资源出现相互等待的现象,当一下四个条件全部满足时便会产生死锁。

1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用

2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。

3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。

4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。

最简单的办法是阻止循环等待条件,规定线程争夺资源是以一定的顺序进行的

== 和 equale()区别

一个是修饰符,一个是方法,

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

equals():用来比较方法两个对象的内容是否相等,equals方法不能比较基本数据类型。

synchronized关键字

当synchronized修饰静态方法时,修饰的是当前类的class对象锁

当synchronized修饰实例方法时,修饰的时对象中的实例方法

Lock锁和synchronized的区别

Lock产生异常时不会自动释放锁所以要在finally中释放锁(lock.unlock();)

synchronized修饰的锁产生异常时会自动释放

什么是三次握手

在网络数据传输中,传输层协议TCP(传输控制协议)是建立连接的可靠传输,TCP建立连接的过程,我们称为三次握手。

第一次,客户端向服务器发送SYN同步报文段,请求建立连接

第二次,服务器确认收到客户端的连接请求,并向客户端发送SYN同步报文,表示要向客户端建立连接

第三次,客户端收到服务器端的确认请求后,处于建立连接状态,向服务器发送确认报文

客户端是在收到确认请求后,先建立连接

服务器是在收到最后客户端的确认后,建立连接

发起连接请求的一定是客户端

集合

之所以把集合单独列出来,是因为集合这块是高频中的高频,如果说前面的知识被面试到的概率是看面试官心情的话,那么这块就是面试官必问,鄙人面试了这么多次,可以说是没有一个面试官不问的!!!

常见的集合有哪些?

答:Map接口和Collection接口是所有集合框架的父接口:

Collection接口的子接口包括:Set接口和List接口

Map接口的实现类主要有:HashMap、TreeMap、Hashtable等,常用实现方式有:HashMap和TreeMap

Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等,常用实现方式有:HashSet和TreeSet

List接口的实现类主要有:ArrayList、LinkedList等,常用实现方式有:ArrayList和LinkedList

ArrayList和LinkedList的异同

1. 是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;

2. 底层数据结构: Arraylist 底层使用的是Object数组;LinkedList 底层使用的是双向循环链表数据结构;

3. 插入和删除是否受元素位置的影响: ① ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行add(E e)方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是O(1)。但是如果要在指定位置 i 插入和删除元素的话(add(int index, E element))时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 ② LinkedList 采用链表存储,所以插入,删除元素时间复杂度不受元素位置的影响,都是近似 O(1)而数组为近似 O(n)。

4. 是否支持快速随机访问: LinkedList 不支持高效的随机元素访问,而ArrayList 实现了RandmoAccess 接口,所以有随机访问功能。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。

5. 内存空间占用: ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)。

ArrayList 与 Vector 区别

Vector的线程同步,效率低

HashMap 和 Hashtable 的区别

HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过 synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!);

效率: 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。

HashMap 中,null 可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为 null。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛出 NullPointerException。

创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小。也就是说 HashMap 总是使用2的幂作为哈希表的大小底

层数据结构:JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。

iterator(),Iterator,Iterable之间的关系

Collection接口继承自Iterable接口,Iterable接口中有个抽象方法交iterator(),这个方法的返回值是Iterator,如ArrayList类,实现了Iterable接口,重写了iterator()

HashMap的遍历方式

//第一种:普遍使用,二次取值
System.out.println("通过Map.keySet遍历key和value:");
for(String key : map.keySet()) {
System.out.println("key= "+ key + " and value= "+ map.get(key));
}
//第二种
System.out.println("通过Map.entrySet使用iterator遍历key和value:");
Iterator> it = map.entrySet().iterator();
while(it.hasNext()) {
Map.Entry entry = it.next();
System.out.println("key= "+ entry.getKey() +" and value= "+ entry.getValue());
}
//第三种:推荐,尤其是容量大时
System.out.println("通过Map.entrySet遍历key和value");
for(Map.Entry entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() +" and value= "+ entry.getValue());
}

 

你可能感兴趣的:(面试题)