最近在看面试题的时候遇到很多同类型的题,我自己先总结下来以下内容,以后每次遇到新的问题我都会追加上来
一、解释一下静态绑定,动态绑定,多态
1)静态绑定是编译时期就确定的函数调用,jvm反编译指令是invokeStatic,例如类的静态函数的调用都是静态绑定。
2)动态绑定是运行时期才确定的函数调用,jvm反编译指令是invokeVirtual,例如多态调用时,对象的普通方法的调用都是动态绑定。
3)多态是OOP语言的一个非常重要的特征,由基类的引用变量(或者接口定义的引用变量)引用不同的派生类对象,调用同名覆盖方法,基类引用变量引用哪个派生类对象,就会调用哪个派生类对象的同名覆盖方法,这样的语言特性可以使软件做到模块化设计,降低模块之间的耦合度,遵循软件设计的高内聚-低耦合原则,多态也是很多OOP设计模式所依赖的语言特性。
二、类加载器相关的问题
1.请简述JDK的类加载器以及功能?
Bootstrap classloader : 加载jvm运行依赖的jar包,用原生代码实现,在jdk安装目录的jre/lib下面加载jar包
Extclassloader:加载扩展类的jar包,路径在jdk安装目录的jre/lib/ext目录下的jar包
Appclassloader:根据CLASSPATH指定的路径,寻找应用程序加载的class字节码文件,从字节码文件中加载类型对应的Class对象
2.请描述Java的类加载过程
1)加载:类加载器使用“双亲委托”模型在指定的类路径下搜索相应的class字节码文件,从class字节码文件内容生成类的Class对象。
2)链接:验证字节码文件的合法性,是否能在当前JVM版本环境下运行,为类的静态域分配内存空间,如果当前类引用了其它类,则继续解析对其它类的引用。
3)执行静态成员变量和静态块的初始化。
三、final、finally、finalize的功能描述以及应用场景
1.final 修饰变量成为常量;final修饰类,表示密封类,不能再被继承;final修饰方法,表示该方法在子类中不能被重写
2.final 用于异常处理,try块中的代码不管有没有发生异常,finally块的代码都会执行的,一般用于释放资源
3.finalize 用于对象的回收,在GC回收某个对象的时候,对象的finalize方法会被先执行一遍
四、简述Java中的异常结构
Java中的异常都继承自Throwable类,从Throwable派生出Error和Exception,Error一般是JVM抛出的错误,比如StackOverFlowError,OutOfMemoryError,这些错误是无法挽回的,只能结束当前Java进程的执行;而Exception异常是Java应用抛出的,分为编译时期可检测的异常(如IOException)和运行时期的异常(NullPointerException),编译时期可检测的异常必须要处理,否则编译器会报错误,而运行时期的异常RuntimeException不需要强制处理,Exception异常一般可以通过捕获处理以后,程序可以继续正常执行。
五、抽象类和接口的区别
1)抽象类可以提供方法实现;接口不能提供方法实现,但是Java 8以后,接口的方法可以提供默认实现。
2)抽象类可以定义任意访问限定的成员方法,接口中的方法默认是public abstract修饰的。
3)抽象类可以定义普通成员变量和常量,接口中定义的变量默认是public static final修饰的。
4)一次派生类只能继承一个抽象类,但是可以实现多个接口。
5)继承抽象类一般表示is a的关系,而实现接口一般表示的是has a的关系,表示类拥有接口定义的功能。
六、KMP 算法(字符串匹配算法)较 BF(朴素的字符串匹配)算法有哪些改进
1)在主串和子串匹配的过程中,主串不再回退,只改变子串的比较位置。
2)为子串生成对应的next数组,每次匹配失败,通过访问next数组获知子串再一次开始匹配的位置。
七、请描述Java泛型的类型擦除机制
Java的泛型类型在编译时期做类型安全检查和类型强转,编译完成后,
被擦除成泛型类型的上界类型,如果未指定上界类型,则擦除成Object类型
Java的泛型没有下界
八、String,StringBuffer,StringBuilder之间区别与联系
1)String,StringBuffer,StringBuilder都是操作字符串的类,但String是字符串常量,也就是不可变量;StringBuffer和StringBuilder是字符串变量
2)String和StringBuffer的联系:String的字符串拼接底层就是通过StringBuilder的append函数来实现的,在循环中进行字符串拼接的时候,直接用String对象的“+”操作进行拼接效率很低,应该使用StringBuilder主动拼接字符串来提高效率,减少无效对象的产生。
3)StringBuffer和StringBuilder的联系和区别是:可以说StringBuilder和StringBuffer的append(String str)方法都是通过getChars方法来实现字符串拼接的。
但是StringBuilder多线程不安全:
StringBuilder中的append方法没有使用synchronized关键字,意味着多个线程可以同时访问这个方法。
StringBuffer是多线程安全的:
StringBuffer的方法多被Synchorized修饰,表示可以直接使用在多线程环境当中,是线程安全的字符串操作类
4)三者在执行速度方面的比较:StringBuilder > StringBuffer > String
5)三者的应用场景:
1.如果要操作少量的数据用String类型提高速度
2.单线程操作字符串缓冲区下操作大量数据用StringBuilder提高效率
3.多线程操作字符串缓冲区下操作大量数据用StringBuffer保证安全性