Java基础面试题-第一集
Posted 唐僧洗澡不秃头
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础面试题-第一集相关的知识,希望对你有一定的参考价值。
1. 面向对象与面向过程
面向对象和面向过程是两种不同的处理问题的角度
面向过程更注重事情的每一个步骤以及顺序,面向对象更注重事务有哪些(对象)、以及各自需要做什么
比如:洗衣机洗衣服
面向过程会将任务拆解成一些列的步骤(函数),1.打开洗衣机 2.放衣服 3.放洗衣粉 4.清洗 5.烘干
面向对象会拆出人和洗衣机两个对象:
人:打开洗衣机 放衣服 放洗衣粉
洗衣机:清洗 烘干
可以看出,面向过程比较直接高效,而面向对象更易于复用、拓展和维护
2.类的三大特性
1.封装:属性私有化,公开访问方法,不能让外部所以修改属性,修改的规则有,这个类自己决定
2.继承:允许在基类的基础上进行扩充,抽象层次不同,基类是个大的比较抽象的类,而子类相较与基类是一个比较具体的类,如鸟和麻雀
3.多态:通过继承以及重写,实现在父类引用指向子类对象时,只有在运行时才能确定具体执行的方法,外部对同一个方法调用有着不一样的实现
3.JDK、JRE、JVM
JDK:Java Develpment Kit java开发工具
JRE:Java Runtime Environment java运行时环境
JVM:Java Virtual Machine java 虚拟机
4.==与equals比较
==对于原始类型比较的是ICMP指令,比的是变量值,而引用类型比较的是ACMP指令,比的是对象的地址
Object中的equals方法默认也是采用==比较,通常会重写
5.简述final的作用
1.修饰变量:
修饰基本数据类型变量:数值一旦初始化就不能再改
修饰引用类型的变量:对其初始化之后就不能再让其指向另一个对象
2.修饰类:
被修饰的类不能被继承
3.修饰方法:
被修饰的方法不能被子类重写
6.匿名内部类和局部内部类只能访问外部类的局部final变量
1.如果外部类是Test1,内部类是Test2,编译之后会生成两个class文件,Test1.class、Test2.class
2.内部类不会随着方法的调用结束而被销毁
3.此时会产生一个问题,当外部内的方法结束时,局部变量就会被销毁了,但内部类对象可能还存在(没有人引用它时,才会死亡)。这是就出现了一个矛盾,内部类访问了一个不存在的变量。
4.为了解决这个问题,此时会将局部变量复制一份作为内部类的成员变量,这样当局部变量死亡,内部类仍然可以访问它,但实际上访问得是局部变量的拷贝,这样就像是延长了局部变量的生命周期
5.但是这时又会出现一个问题,如果我们再内部类修改了这个局部变量,方法的局部变量此时也需要改变,保证两个变量是一致的,所以我们就将局部变量设置为final,对它初始化后,就不能修改这个变量,保证了内部类的成员变量和方法的局部变量的一致性。实际上这也是一种妥协。
7.引申出finally,finalize
1.try catch finally异常处理块,finally是一定要执行的块,在try 块 return 前,会先执行finally,如果finally块有return语句的话,会覆盖掉try块的return结果。
2.内部是在try块执行完后会跳转到finally块,同时finally块也有一个异常处理器,如果发生异常,先存储异常类型,然后跳转回finally块,之后执行完回到异常处理,抛出异常
1.finalize是Object类的方法,在对象被回收前调用,类比C++的析构函数,可以用来做析构的功能或者在让一个引用指向它,从而达到不让它被回收的目的
8.String、StringBuffer、StringBuilder
1.public final class String:
底层用的final char value[],String中的对象是不可变的,也就可以理解为常量,线程安全
同时String也是用final修饰的,不可以被继承
2.public final class StringBuffer:
底层用的char[] value,
3.public final class StringBuilder:
底层用的char[] value,都是在原数组对象上进行操作的
4.StringBuffer和StringBulider同时实现了AbstractStringBuilder接口,只是StringBuffer的基本上都加上了synchronized
5.操作少量字符数据用 String;单线程操作大量数据用 StringBuilder;多线程操作大量数据用 StringBuffer
9.重载和重写的区别
1.重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
2.重写:发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出异常范围小于等于父类,访问修饰符大于等于父类;如果父类方法访问修饰符为private,则子类不能重写该方法。
3.子类不能重写父类的构造函数:因为子类没有继承父类的构造函数,只是能够调用而已
10.接口和抽象类的区别
实现区别
1.抽象类可以存在普通成员函数,而接口只能存在public abstract方法
2.抽象类中的成员变量可以使各种类型的,而接口的成员变量只能是public static final类型的
3.抽象类只能继承一个,接口可以实现多个
4.抽象类的功能远超于接口,但是定义抽象类的代价高,设计会比较困难,对Java来说每个类只能继承一个类,在这个类中,你必须继承或编写出其所有子类的所有共性。接口虽然在功能上会有所弱化,但是它只是针对一个动作的描述,并且每一个类可以实现多个接口,所以设计相较于抽象类还是更为简单
5.jdk1.8以后接口的default方法可以有默认实现
作用:它的出现解决接口升级问题。1万个类实现了一个接口,这时候对接口进行了升级,按照jdk1.7的规则,加方法的话只能加抽象方法,当加完抽象方法之后1万个类瞬间编译报错。因为必须要重写抽象方法。有的时候我们希望1万个类如果有类想升级那么重写,有类的不想升级就别重写了。这时候我们就可以用default了
6.jdk1.8以后接口中方法如果加了static,它不会默认加public abstract,也就是接口也可以有静态方法了,通过接口名.静态方法名调用
设计目的
1.接口的设计目的,是对类的行为进行约束(准确来说是对类行为”有“的一种约束,因为接口不能规定类不能有什么行为),接口提供了一种机制,可以强制要求不同的实现了它的类具有相同行为。它只约束行为的”有“,但不对其如何实现进行约束。
2.抽象类的设计目的,是为了代码复用,是对类的抽象,是⼀种模板设计。
3.抽象类是对类本质的抽象,表达的是一种is a的关系,比如:宝马 is a Car。抽象类包含并实现子类的通用特性,将子类存在差异化的特性进行抽象,交由子类去实现。
4.接口是对行为的抽象,表达的是like a的关系,比如 鸟 like a 飞行器(想飞行器一样可以飞)。接口的核心是定义行为,即实现类可以做什么,至于实现类是谁,如何实现这个接口并不关注。
11.List和Set的区别
1.List:有序,按对象进入的顺序保存对象,可重复,所以允许存储多个Null元素对象,可以使用Iterator取出所有元素,然后逐一遍历,同时还可以通过get(int index)获取指定下标的元素
2.Set:无序,不可重复,最多允许一个Null元素对象,取元素时只能用Iterator接口取得所有对象,然后再逐一遍历各个元素
12.hashCode与equals
1.hashCode:hashCode()是Object类的方法,作用是获取哈希码,也称为散列码,返回的是一个int整数。哈希码的作用是确定该对象在哈希表(堆会维护一个哈希表,键是对象的hashCode,值是对象在堆中的位置)的索引位置。
hashCode作用:可以快速定位散列位置,减少equals的次数,可以大大提高执行速度
2.equals:定义对对判断相等的逻辑
如果两个对象相等,则hashCode也一定是相同的
如果两个对象具有相同的hashCode,它们也不一定相等
因此,如果equals被覆盖过,则hashCode方法也必须被覆盖
由于hashCode的默认行为是对堆中的对象进行映射,如果没有重写hashCode(),则该class的两个对象都不会 相等,即使它们拥有相同的属性。
以上是关于Java基础面试题-第一集的主要内容,如果未能解决你的问题,请参考以下文章