目录
5. hashCode()介绍,为什么要有 hashCode,hashCode 与 equals (重要)
10. 在Java中定义一个不做事且没有参数的构造方法的作用
11. break ,continue ,return 的区别及作用
12. static的注意事项,应用场景,独特之处,存在的主要意义
18. 构造器(constructor)是否可被重写(override)?
24. Java 中操作字符串都有哪些类?它们之间有什么区别?
28. Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
32. 什么是Java程序的主类?应用程序和小程序的主类有何不同?
【写在前面】
此文题目和答案都非原创。
是搜集了网络上分享的关于Java面试常见问题汇总,然后又逐个搜寻了答案,整理于此。
供自学,感谢相关题目和答案的原创分享者。
【相关链接】
常见面试题和答案汇总(3):SpringCloud
1. JDK动态代理和CGLIB动态代理的区别
1.1代理模式:
代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法、实际执行的是被代理类的方法。AOP是通过动态代理实现的。
1.2 两者区别:
JDK动态代理只能对实现了接口的类生成代理,而不能针对类
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承)
1.3 Spring在选择用JDK还是CGLiB的依据:
1)当Bean实现接口时,Spring就会用JDK的动态代理
2)当Bean没有实现接口时,Spring使用CGlib是实现
3)可以强制使用CGlib(在spring配置中加入
<aop:aspectj-autoproxy proxy-target-class="true"/>)
1.4 两者效率比较
1)使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
2)在对JDK动态代理与CGlib动态代理的代码实验中看,1W次执行下,JDK7及8的动态代理性能比CGlib要好20%左右。
2. 静态代理和动态代理的区别
2.1 静态代理
创建一个接口 -> 然后创建被代理的类实现该接口并且实现该接口中的抽象方法 >之后再创建一个代理类,同时使其也实现这个接口。在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法, 做一些加工处理(代理功能)。
静态代理的本质:
由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
2.2 动态代理
动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
2.3 区别
(1)静态代理在程序运行前就已经存在代理类的字节码文件,并确认了代理类和委托类的关系;
(2)动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。 动态代理根据接口或目标对象,计算出代理类的字节码,然后再加载到JVM中使用。
其实现原理如下:由于JVM通过字节码的二进制信息加载类的,那么,如果我们在运行期系统中,遵循Java编译系统组织.class文件的格式和结构,生成相应的二进制数据,然后再把这个二进制数据加载转换成对应的类,这样,就完成了在代码中动态创建一个类的能力了。
(3)静态代理的缺点是在程序规模稍大时,维护代理类的成本高,静态代理无法胜任;
(4)动态代理只能为了实现接口的类创建代理。
3. ArrayList和LinkedList有什么区别?
3.1 数据结构不同
ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。
3.2 效率不同
(1)当随机访问List(get和set操作)时, ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
(2)当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。【视频教程推荐:Java视频教程】
3.3 自由性不同
(1)ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;
(2)而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。
3.4 主要控件开销不同
(1)ArrayList主要控件开销在于需要在lList列表预留一定空间;
(2)而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。
4. Java 8的接口新增了哪些特性?
在jdk1.8以前接⼝中,只能有抽象方法,不能有任何方法的实现(方法体)。
而在jdk1.8中打破常规,接口添加静态方法和默认方法。
引入了新的关键字default,在接口中使default修饰的方法,可以在接口编写方法体。实现了该接口的类,可以直接调用接口的默认方法。
可直接使用 接口名.静态方法 来调用接口中的静态方法。(如:Animal.run();)
5. hashCode()介绍,为什么要有 hashCode,hashCode 与 equals (重要)
(1)equals()用于判断两个对象是否相等,这是大家公认的。
hashCode()被设计是用来使得哈希容器能高效的工作。
(2)在Java中,有一些哈希容器,比如Hashtable,HashMap等等。当我们调用这些容器的诸如get(Object obj)方法时,容器的内部肯定需要判断一下当前obj对象在容器中是否存在,然后再进行后续的操作。一般来说,判断是否存在,肯定是要将obj对象和容器中的每个元素一一进行比较,要使用equals()才是正确的。
(3)但是如果哈希容器中的元素有很多的时候,使用equals()必然会很慢。这个时候用替代方案hashCode():当我们调用哈希容器的get(Object obj)方法时,它会首先利用查看当前容器中是否存在有相同哈希值的对象,如果不存在,那么直接返回null;如果存在,再调用当前对象的equals()方法比较一下看哈希处的对象是否和要查找的对象相同;如果不相同,那么返回null。如果相同,则返回该哈希处的对象。
(4)hashCode()返回一个int类型,两个int类型比较起来要快很多。
(5)hashCode()被设计用来使得哈希容器能高效的工作。也只有在哈希容器中,才使用hashCode()来比较对象是否相等,但要注意这种比较是一种弱的比较,还要利用equals()方法最终确认。
(6)hashCode()相等看成是两个对象相等的必要非充分条件,把equals()相等看成是两个对象相等的充要条件。因此,在自定义一个类时,必须要同时重写equals()和hashCode(),并且必须保证:
其一:如果两个对象的equals()相等,那么他们的hashCode()必定相等。
其二:如果两个对象的hashCode()不相等,那么他们的equals()必定不等。
6. 什么是方法的返回值?返回值的作用是什么?
返回值常用的有String,int,boolean等, 一个方法就是实现一个功能。
而那个返回值就是方法执行完后返回的那个结果(也就是我们需要的)。
通常调用一个方法要么让它完成某项功能,要么就是获得它的返回值。
7. 静态方法和实例方法有何不同?
(1)静态方法:在加载类时就加载静态方法,在外部调用静态方法时,可使用 " 类名.方法名 " 的方式,也可使用 "对象名.方法名 "的方式。而实例方法只有"对象名.方法名 "方式。即调用静态方法可以无需创建对象。实例方法在调用时才被加载。
(2)静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制 .