Java面试基础

1、面向对象的三大特性:封装、继承、多态

每个说重点,方便记忆。

什么是封装?

1、封装是把一个对象的属性私有化,同时提供一些能被外界访问属性的getter和setter方法。
2、封装能容易地修改类的内部实现,无需修改使用了该类的代码,让代码更容易理解和维护。

什么是继承?

1、子类能够继承父类中的非private的属性、方法,让代码得到复用。
2、继承具有传递性,子类继承父类,父类继承爷爷类。
3、一个类只能继承一个父类,一个接口可以继承多个父类。

什么是多态?
多态

1、多态是同一个行为具有不同的表现形式,使用同一个接口,不同的实例具有不同的操作。
2、多态三个必要条件:继承、重写、父类引用指向子类对象 Parent p = new Child();
3、多态调用方法时,先检查父类是否有该方法,没有就编译错误,有就调用子类同名方法。

2、String,StringBuffer与StringBuilder的区别?

String类采用利用final修饰的字符数组进行字符串保存,因此不可变。如果对String类型对象修改,需要新建对象,将老字符和新增加的字符一并存进去。

StringBuffer,采用无final修饰的字符数组进行保存,可理解为实现线程安全的StringBuilder。

StringBuilder,采用无final修饰的字符数组进行保存,因此可变。但线程不安全。

3、JAVA垃圾回收

1、引用计数:一个对象被引用计数器加一,取消引用计数器减一。缺点是不能解决循环引用,A和B互相引用时无法回收。

2、可达性分析法(根搜索算法),将内存中每个对象看作一个节点,以 GC Root为起始点搜索,搜索路径上的对象可以到达,不可到达的对象被回收。缺点产生大量内存碎片,不利于大对象分配。

3、复制算法,将内存等分为两块,使用一块,将使用的存活对象复制到另一块中,清除使用的所有对象,适用于新生代垃圾回收。优点:不存在内存碎片。缺点:系统内存折半。

4、标记压缩算法,在可达性分析法基础上,先标记,再将存活对象移动到一起,不可达对象清除。

5、分代算法,新生代回收对象多,使用复制算法,老生带回收对象少,使用标记压缩算法。

4、GC是什么时候触发的?

GC 有 两种类型。YGC 和 FGC

1、YGC:当生成新对象并且向Eden申请空间失败时,就会触发 YGC。将 Eden存活的对象移动到survivor区,清空 Eden区。

2、FGC:当老年代或持久代被写满,或调用system.gc() 时触发。

5、List中的 ArrayList和 LinkedList?

ArrayList的底层数据结构是数组,LinkedList底层数据结构是链表。

数组创建时需要定义大小,而 ArrayList不用。当我们new ArrayList()的时候,默认会有一个空的Object数组,大小为0。当我们第一次add添加数据的时候,会给这个数组初始化一个大小,这个大小默认值为10。使用ArrayList在每一次add的时候,它都会先去计算这个数组够不够空间,如果空间是够的,那直接追加上去就好了。如果不够,那就得扩容。在源码里边,有个grow方法,每一次扩原来的1.5倍。比如说,初始化的值是10嘛。现在我第11个元素要进来了,发现这个数组的空间不够了,所以会扩到15。空间扩完容之后,会调用arraycopy来对数组进行拷贝。

ArrayList、Vector和LinkedList都是可伸缩的数组,即可以动态改变长度的数组。

ArrayList和Vector都是基于存储元素的Object[] array来实现的,它们会在内存中开辟一块连续的空间来存储,支持下标、索引访问。但在涉及插入元素时可能需要移动容器中的元素,插入效率较低。当存储元素超过容器的初始化容量大小,ArrayList与Vector均会进行扩容。

Vector是线程安全的,其大部分方法是直接或间接同步的。ArrayList不是线程安全的,其方法不具有同步性质。LinkedList也不是线程安全的。

LinkedList采用双向列表实现,对数据索引需要从头开始遍历,因此随机访问效率较低,但在插入元素的时候不需要对数据进行移动,插入效率较高。


源码:
源码:

//ArrayList Add方法:
public boolean add(E e){ 
ensureCapacity(size+1); //Increment modCount!! 
elementData[size++] = e; //在数组末尾追加一个元素,并修改size
return true;
}
 
//ensureCapacity方法:处理ArrayList的大小
public void ensureCapacity(int minCapacity) { 
modCount++; 
int oldCapacity = elementData.length; 
if (minCapacity > oldCapacity) { 
Object oldData[] = elementData; 
int newCapacity = (oldCapacity * 3)/2 + 1;//每次扩容,增大50% 
if (newCapacity < minCapacity) 
newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
}

6、重写和重载区别?

重写即子类重写父类的方法,方法对应的形参和返回值类型都不能变。

  • 重写遵循“两同两小一大”
  • “两同”,方法名相同、形参列表相同
  • “两小”,子类返回值类型 ≤ 父类、子类抛出异常 ≤ 父类
  • “一大”,子类方法的访问权限 ≥ 父类

重载即在一个类中,方法名相同,参数类型、数量、顺序不同,返回值类型和访问修饰符也可以不同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值