1.String和StringBuiler、StringBuffer区别
String底层是不可变字符串,底层是final修饰的char数组,且String类也是被final关键字修饰的
StringBuilder和StringBuffer的底层也是char数组,只不过没有fianl修饰,而且可变,StringBuilder线程不安全,StringBuffer线程安全,因为StringBuffer的方法上有Synchronized修饰
String的拼接操作的底层原理实际上是先创建StringBuilder对象然后调用append方法进行追加,最后再转换成String
2. ArrayList和LinkedList的区别?
ArrayList的底层是基于Object数组,对内存的要求较高,因为数组的创建需要连续的内存空间,Arraylist的默认大小为10。
LinkedList的底层是基于双向链表,链表不需要连续的内存空间,只需要将链表的next和prev指向相应的对象即可
ArrayList和Linkedlist的add方法默认都是添加到末尾。
ArrayList的查询快,而插入和删除慢,为什么查询快,因为ArrayList基于数组,数组有下标,通过下标查询元素的时间复杂度为O(1),为什么插入和删除慢呢,因为在ArrayList的底层,插入操作会把插入位置上的元素和后面的元素通过System.arrayCopy方法向后进行移位,删除方法也会将进行移位。
LinkedList的插入和删除快,查找慢,LinkedList查找只能从链表头开始遍历查找,时间复杂度为O(n),插入快是因为linkedlist插入只需将上一个节点的next节点和下一个节点的prev指向要插入的元素即可。删除只需要将元素删除再将next和prev节点重新指向即可。
3.创建线程有哪几种方法?
1.写一个类继承Thread类,覆写run方法,调用start方法启动
2.写一个类实现Runnable接口,覆写run方法,将该类作为参数传递给Thread有参构造创建线程
3.写一个类实现Callable接口,覆写call方法,将该类作为参数传递给FutureTask有参构造创建对象,再把该对象作为参数传递给Thread有参构造创建线程
优先选择方式2和方式3,方式1有单继承的局限性,方式3适合有返回值的场景
4.调用线程的Start方法和run方法有什么区别
调用start方法代表开启新线程,将线程转为就绪状态,而run方法则是业务方法,直接调用run方法就是执行业务代码,是执行在main线程中的
扩展:为什么调用start就是开启新线程?
Thread类中有一个volatile修饰的成员变量threadStatus,默认值为0,当调用start方法时,会判断threadStatus是否为0,为0就将执行start0方法开启线程。start0方法是native修饰的本地方法,是由jvm实现的,最终调用的是jvm_startThread方法
扩展:什么本地方法?
本地方法就是jvm调用非java代码实现的方法
5.ArrayList和Vector的区别?
Vector是线程安全的,ArrayList线程不安全,Vector的方法上有Synchronized关键字修饰。Vector默认扩容是1倍,Arraylist默认扩容0.5倍
6.面向对象的特征?
1.封装:将对象的属性私有化,隐藏实现细节,对外界提供公共的访问方式,目的是提高代码安全性
2.继承:是类的抽象,将子类和父类的公共代码抽取出来,提高代码的复用性
3.多态:就是对象的多种形态,运行时类型和编译时类型不相同就是多态,提高了代码的扩展性,不需要指定类型,用父类型接收即可
7.接口和抽象类
接口有全局常量,抽象方法(jdk8后加入了静态方法和默认方法)
抽象类有构造方法,普通方法,抽象方法
抽象类是用来捕捉子类的共同特征的,提高代码的复用,是对类的抽象,是一种模板设计
接口则是对象的行为集合,提高扩展性和可维护性,是对行为的抽象,是一种行为的规范
8.==和equals()的区别
==是运算符,equals()是Object类中的方法,Object类中的equals方法默认是使用==比较,一般会重写equals方法
当比较的类型是基本数据类型时,== 比较的是值,当比较的类型是引用数据类型时,比较的是对象的地址
equals比较的是对象的内容是否相同,基本数据类型的包装类的equals方法则要看equals方法是怎样重写的。
9.Int和Interger的区别
int是基本数据类型,Integer是引入数据类型
Integer是int的包装类
Interger和int的比较:
int和Integer进行比较时,如果值相等,则一定相等,因为integer会自动拆箱转化为int
通过非new方式创建的Integer对象,如果传入的值在-127-128之间,就会被缓存,下次再通过非new创建Interger对象,就会直接从缓存中拿,即享元模式,类似通过非new方式创建String字符串
扩展:什么是享元模式?
共享已经存在的对象,减少对象创建的数量以及类似的系统开销,提高利用率,如通过非new方式创建String、Integer对象等...
10.说一下java中的集合体系
Collection接口下有List、set、queue
List下有:
Arraylist:基于Object数组,随机访问快,插入和删除慢
vector: 相当于线程安全的ArrayList,方法上有Synchronized修饰
LinkedList:基于双向链表,查询慢,删除插入快
List可以保证元素的添加顺序
Set下有:
HashSet:底层基于HashMap,不能保证元素的添加顺序,也不能保证自然排序,通过构造方法创建HashSet时,其底层其实是创建了一个HashMap。HashSet的元素是保存在Hash Map的key中,value则是统一的private static final Object PRESENT = new Object();对象,调用add方法其实是调用了hashmap的put方法
TreeSet :底层基于TreeMap,不能保证元素的添加顺序,可以进行自然排序,也可以指定排序,通过构造方法创建TreeSet时,其实是创建了一个TreeMap,TreeSet的元素是保存在TreeMap的key中,value则是统一的private static final Object PRESENT = new Object();对象,调用add方法其实是调用了treemap的put方法