您现在的位置: 首页 > 网站导航收录 > 百科知识百科知识
你经历过哪些有意思的面试题目?
线程,数组,方法你经历过哪些有意思的面试题目?
发布时间:2016-12-08加入收藏来源:互联网点击:
你经历过哪些有意思的面试题目?
回答于 2019-09-11 08:43:50
回答于 2019-09-11 08:43:50
你好,很高兴回答这个问题
回答于 2019-09-11 08:43:50
一、String 原理,String 、StringBuffer、StringBuilder区别。
String是final类,属于不可变字符串,采用char数组。
StringBuffer是线程安全的,内部采用synchronized。
StringBuilder是非线程安全的。
二、String与StringBuilder拼接字符串哪个性能好,为什么?
StringBuilder性能比较好,String在拼接的时候会new出多个对象,消耗资源。尤其是在for循环下进行拼接性能差距很明显。
三、接口与抽象类的区别
1. 接口的方法默认是 public,所有方法在接口中不能有实现(Java 8 开始接口方法可以有默认实现),抽象类可以有非抽象的方法
2. 接口中的实例变量默认是 final 类型的,而抽象类中则不一定
3. 一个类可以实现多个接口,但最多只能实现一个抽象类
4. 一个类实现接口的话要实现接口的所有方法,而抽象类不一定
5. 接口不能用 new 实例化,但可以声明,但是必须引用一个实现该接口的对象 从设计面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
四、重载与重写的区别
重载(Overload)是让类以统一的方式处理不同类型数据的一种手段,实质表现就是多个具有不同的参数个数或者类型的同名函数(返回值类型可随意,不能以返回类型作为重载函数的区分标准)同时存在于同一个类中,是一个类中多态性的一种表现(调用方法时通过传递不同参数个数和参数类型来决定具体使用哪个方法的多态性)。
重写(Override)是父类与子类之间的多态性,实质是对父类的函数进行重新定义,如果在子类中定义某方法与其父类有相同的名称和参数则该方法被重写,不过子类函数的访问修饰权限不能小于父类的;若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法,如需父类中原有的方法则可使用 super 关键字。
五、数组与链表的区别
1.数组是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。最大的特点就是支持随机访问,但插入、删除操作也因此变得比较低效,平均情况时间复杂度为O(n)。
2.链表它并不需要一块连续的内存空间,它通过“指针”(前后节点指向)将一组零散的内存,空间可扩容,比较常用的是单链表,双链表和循环链表。和数组相比,链表更适合插入、删除操作频繁的场景,查询的时间复杂度较高。
六、介绍一下ArrayList
1、ArrayList底层数据结构是一个数组,数组元素类型为Object,对ArrayList的所有操作都是基于数组。
2、ArrayList不是线程安全的。对ArrayList进行添加元素的操作的时候是分两个步骤进行的,即第一步先在object[size]的位置上存放需要添加的元素;第二步将size的值增加1。由于这个过程在多线程的环境下是不能保证具有原子性的,因此ArrayList在多线程的环境下是线程不安全的。
如果非要在多线程的环境下使用ArrayList,就需要保证它的线程安全性,通常有两种解决办法:第一,使用synchronized关键字;第二,可以用Collections类中的静态方法synchronizedList();
3、ArrayList默认大小为10
4、ArrayList扩容机制:
第一,在add()方法中调用ensureCapacityInternal(size + 1)方法来确定集合确保添加元素成功的最小集合容量minCapacity的值。参数为size+1,代表的含义是如果集合添加元素成功后,集合中的实际元素个数。换句话说,集合为了确保添加元素成功,那么集合的最小容量minCapacity应该是size+1。在ensureCapacityInternal方法中,首先判断elementData是否为默认的空数组,如果是,minCapacity为minCapacity与集合默认容量大小中的较大值。
第二,调用ensureExplicitCapacity(minCapacity)方法来确定集合为了确保添加元素成功是否需要对现有的元素数组进行扩容。首先将结构性修改计数器加一;然后判断minCapacity与当前元素数组的长度的大小,如果minCapacity比当前元素数组的长度的大小大的时候需要扩容,进入第三阶段。
第三,如果需要对现有的元素数组进行扩容,则调用grow(minCapacity)方法,参数minCapacity表示集合为了确保添加元素成功的最小容量。在扩容的时候,首先将原元素数组的长度增大1.5倍(oldCapacity + (oldCapacity >> 1)),然后对扩容后的容量与minCapacity进行比较:① 新容量小于minCapacity,则将新容量设为minCapacity;②新容量大于minCapacity,则指定新容量。最后将旧数组拷贝到扩容后的新数组中。
七、ArrayList在遍历的时候可以删除数据吗?
for循环遍历不可以,会报ConcurrentModificationException异常,迭代器Iterator下可以。
内部有一个modCount 进行修改次数检查。
如果没checkForComodification去检查expectedModCount与modCount相等,这个程序肯定会报ArrayIndexOutOfBoundsException
八、LinkedList底层数据结构是什么?说明ArrayList,LinkedList二者区别?
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构每个元素都包含了 上一个和下一个元素的引用,所以add/remove 只会影响到上一个和下一个元素,。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。
九、简单介绍一下HashMap?
1、负载因子0.75 , 提高空间利用率和 减少查询成本的折中,主要是泊松分布,0.75的话碰撞最小。
2、扰动函数就是解决碰撞问题,减少碰撞。
3、hasMap的容量尽量是2的倍数,这样使散列均匀,不易出现hash冲突
HashMap默认初始化大小16,数据结构是一个数组+链表+红黑树(平衡二叉树红黑节点)。
Put的时候首先拿到hash值看是否存在值如果没有值直接放入,存在则进行比较是否相等,不等生成链表,当链表大于8的时候生成红黑树。
HashMap是线程不安全的。
十、介绍一下ConcurrentHashMap
concurrentHashMap是一个线程安全的高可用HashMap。
1.8抛弃了之前的segement分段上锁,采用了CAS+synchronized来保证并发安全,并且吧put的流程更加细化,而且resize的时候不会阻塞任何一个线程。
下一篇:返回列表
相关链接 |
||
网友回复(共有 0 条回复) |