您的位置:首页 > 职场人生

【Java面试系列】语言基础(一)

2017-11-23 21:56 477 查看

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

1.abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
2.在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
3.abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。
4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
5.接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
6.抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。
7.接口中的方法默认都是 public,abstract 类型的。

1、String StringBuffer StringBuilder 区别

StringBuffer和StringBuilder是线程安全问题,String和StringBuilder是效率以及内存分配问题。

加分1: String和StringBuilder在编译优化之后结果基本一致;

加分2: String在循环中
4000
操作,回导致声明很多的StringBuilder,因此禁止这种操作;

2.重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

答:方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。

3、ArrayList和LinkedList的区别,数据结构实现,扩容机制 

(1) ArrayList是实现了基于动态数组的数据结构,LinkedList基于双向循环链表的数据结构。 

(2) 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 

(3) 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

(4) 查找操作indexOf,lastIndexOf,contains等,两者差不多。

(5) 随机查找指定节点的操作get,ArrayList速度要快于LinkedList. 当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在 一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
扩容: 针对ArrayList,在新增的时候,容量不够就需要扩容,2倍。
解题思路:基础知识
考察点:ArrayList和LinkedList的区别,ArrayList的扩容

4、HashMap的实现原理(内部数据结构,null key,rehash);为什么说hashMap不是线程安全的。 

参考答案:

(1)内部数据结构实现:数组+链表 (最好画个图能解释清楚) (2)key值不能重复,只能put一个key为null的键值对。可以更深层次考察对put(null,value)以及get(null)的 理解。 (3)HashMap在put时,经过了两次hash,一个是JDK自带的对对象key的hash,然后再对结果使用HashMap内部函数hash(int h);hash(int h)方法根据key的hashCode重新计算一次散列。可以更深入考察对hash(int
h)以及indexFor(int h, int length)两个函数的理解。 (4)在put时如果空间不够就需要扩容resize(),考察扩容过程--重新计算复制。 (5)在并发的多线程使用场景中,使用HashMap形成环链,造成死循环,CPU飙升至100%。例子见链接。
解题思路:基础知识
考察点: 考察HashMap的底层实现远离
分类:Java集合框架

5、wait()和notify(),wait和sleep的区别 

wait()和notify()的区别:

http://blog.csdn.net/oracle_microsoft/article/details/6863662
wait和sleep的区别:
(1)sleep是Thread类的方法,是线程用来 控制自身流程的,比如有一个要报时的线程,每一秒中打印出一个时间,那么我就需要在print方法前面加上一个sleep让自己每隔一秒执行一次。 就像个闹钟一样。 wait是Object类的方法,用来线程间的通信,这个方法会使当前拥有该对象锁的进程等待知道其他线程调用notify方法时再醒来,不过你也可以给 他指定一个时间,自动醒来。这个方法主要是用走不同线程之间的调度的。
(2)关于锁的释放 ,在这里假设大家已经知道了锁的概念及其意义。调用sleep方法不会释放锁(自己的感觉是sleep方法本来就是和锁没有关系的,因为他是一个线 程用于管理自己的方法,不涉及线程通信)
(3)使用区域
由于wait函数的特殊意义,所以他是应该放在同步语句块中的,这样才有意义 。
注意:两个方法都需要抛出异常
解题思路:基础知识

6、ThreadPool中线程是如何做到重用的?

线程池在执行execute方法的时候,会根据初始化参数的大小以及线程池已有的线程数,来创建核心线程或者把task塞入任务队列;其中创建的核 心线程创建后会启动,run方法内会执行一个runWork函数,此函数会不断地从任务队列中获取task执行。
解题思路:线程池的工作原理和工作流程。
考察点:线程池

当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
1.其他方法前是否加了synchronized关键字,如果没加,则能。
2.如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3.如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。

如何实现字符串的反转?
答:方法很多,可以自己写实现也可以使用String或StringBuffer/StringBuilder中的方法。有一道很常见的面试题是用递归实现字符串反转,代码如下所示:

 
public static String reverse(String originStr) {
if(originStr == null || originStr.length() <= 1)
return originStr;
return reverse(originStr.substring(1)) + originStr.charAt(0);
}

   
反射的原理是什么
反射是为了能够动态的加载一个类,动态的调用一个方法,动态的访问一个属性等动态要求而设计的。它的出发点就在于JVM会为每个类创建一个java.lang.Class类的实例,通过该对象可以获取这个类的信息,然后通过使用java.lang.reflect包下得API以达到各种动态需求。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: