个人的java面试题整理

(1)String a = “1”;与String b = new String(“1”)
由于new是在堆上新建了一个区域,两个a。b的指向地址不同,所以,==为false,而equal为true
(2)堆、栈和堆栈的区别
速度:cpu-栈-堆
栈:
int b; 栈
char s[] = “abc”; 栈
char *p2; 栈
堆:
new
全局:
static int c =0; 全局(静态)初始化区
堆栈:stack 一种存储的数据结构,为先进后出,与之对应为queue队列。
(3)arraylist和linklist的区别
1.ArrayList是基于动态数组,LinkedList基于链表。
2.对于随机访问get和set,ArrayList优于LinkedList,因为ArrayList可以随机定位,而LinkedList要移动指针
一步一步的移动到节点处,但是linkList的增删快,而arrayList对于删除则需要对数组进行维护:
删除元素会造成底层数组重排,重新复制。
当我们用下标方式去删除元素时,如果删除的是最后一个元素,不会触发数组底层的复制,时间复杂度为O(1)。
如果删除第i的元素,会触发底层数组复制n-i次,根据最坏情况,时间复杂度为O(n)。
当我们用查找元素的方式去删除元素时,假设这个元素在第i个位置,我们要先查找i次,找到元素后,
会触发底层数组n-i次复制,两个值相加i+(n-i) = n,时间复杂度为O(n)。而linkedlist删除则是通过修改指针,复杂度只有O(1)。
3.ArrayList的动态扩容实际上是每次超出最大后扩容1.5倍:

//源代码
int newCapacity = oldCapacity + (oldCapacity >> 1);
每次扩容都是通过拷贝旧list到新的list中:
这里写图片描述
这个扩容方法为native,是用其他语言写的,如c/c++,源码如下:
这里写图片描述
先判断大小,然后grow:
这里写图片描述
进行扩容:
这里写图片描述
最后拷贝:
这里写图片描述

(4)String,StringBuffer与StringBuilder的区别
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型
进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响
(5)线程的问题:
http://blog.csdn.net/pengbin790000/article/details/74527870
(6)HashMap和Hashtable有什么区别:
HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
HashMap允许键和值是null,而Hashtable不允许键或者值是null。
HashMap的最底层是数组来实现的,数组里的元素可能为null,也有可能是单个对象,还有可能是单向链表或是红黑树,在JDK1.7及以前的版本中,HashMap里是没有红黑树的实现的,在JDK1.8中加入了红黑树是为了防止哈希表碰撞攻击,当链表链长度为8时,及时转成红黑树,提高map的效率。
Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。
ConcurrentHashMap也是线程安全的,但性能比HashTable好很多,HashTable是锁整个Map对象,而ConcurrentHashMap是锁Map的部分结构。
一般认为Hashtable是一个遗留的类。
(7)HashSet和TreeSet有什么区别
HashSet是由一个hash表来实现的,因此,它的元素是无序的。add(),remove(),contains()方法的时间复杂度是O(1)。
另一方面,TreeSet是由一个树形的结构来实现的,它里面的元素是有序的。因此,add(),remove(),contains()方法的时间复杂度是O(logn)

猜你喜欢

转载自blog.csdn.net/pengbin790000/article/details/76126583