1.字符串String和StringBuilder 、StringBuffer的区别?StringBuilder和StringBuffer的区别?
分析:java提供了String和StringBuilder 、StringBuffer三种表示和操作字符串的类。字符串就是有多个字符的数组。
①String和StringBuilder 、StringBuffer的区别:
String是内容不可改变的字符串,它的底层是由final修饰的字符数组实现。
StringBuilder 、StringBuffer是内容可变的字符串,底层由不是final修饰的字符数组实现。
②StringBuilder和StringBuffer的区别:
StringBuilder线程不安全,效率较高;StringBuffer线程安全,效率较低。(底层加了同步锁)
③延伸问题,字符串拼接使用哪一个?
字符串拼接不使用String,因为String拼接会创建多个对象,效率低。例:String s="a"+"b";
使用StringBuilder或StringBuffer,例:StringBuffer sb=new StringBuffer(); sb.append("a").append("b");
2.讲一下Java中的集合
答:java中的集合分为值存储和键值对存储
值存储(value):List和Set
List:有序的,可重复;
Set:无序的,不可重复,不可重复是通过equals和hashCode方法来实现的,因此一个对象想通过Set存储,需要重写equals和hashCode方法。
键值对存储(key--value):Map
3.ArrayLsit 和LinkedList的区别和使用场景
答:区别:ArrayList底层通过数组实现,LinkedList底层通过链表实现。
使用场景:
数组对查询特定的元素效率高,对插入,删除,修改较慢,因为数组在内存中是一组连续的内存地址,插入和删除需要移动内存。
链表不要求内存连续,在当前元素中存放上一个或下一个元素的地址,查询需要从头部开始,一个一个找,效率低,而插入和删除不需要移动内存,只需要改变引用指向。
因此ArrayList常用于查询多,插入和删除,修改少的地方;LinkedList常用于查询少,插入和删除,修改多的地方。
4.讲一下HashMap和HashTable的区别?HashMap和ConcurrentHashMap(jdk1.5以后)的区别?
答:相同点:HashMap和HashTable都可以存储键值对。
区别:1)HashMap可以将null作为key或value存储,但HashTable不可以;
2)HashMap线程不安全,效率较高,HashTable线程安全按,效率较低。
ConcurrentHashMap:就是既可以保证安全又可以保证效率。
它是将整个Map分为N个segment(类似HashTable),可以提供相同的线程安全,效率却提高了N倍,默认提高了16倍。
5.实现一个拷贝文件的工具类使用字节流还是字符流?
答:使用字节流(因为拷贝的文件不确定只含有字符流,有可能有字节流(图片、声音、图像),为保证通用性,使用字节流)。
6.
1)讲一下线程的几种实现方式?
答:⑴通过继承Thread类
⑵通过实现Runnable接口
2)怎么启动?
答:Thread thread=new Thread(继承Thread/实现Runnable接口的类);
thread.setName("线程名称");
thread.start();//线程启动使用start方法,启动后执行run方法
3)怎么区分线程?在一个系统中有很多线程,每个线程都会打印日志,我想区分是哪个线程打印的怎么办?
答:thread.setName("线程名称");这是一种规范,在创建线程后,都要给线程起一个新的名称。
4)线程池,线程并发库?
①java如何创建线程池?
答:Java通过Executors提供四种静态方法创建四种线程池:分别为
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行
②为什么要使用线程池?
1.限定线程的个数,保证不会因线程过多导致系统运行缓慢或崩溃;
2.线程池不需要每次都去创建或销毁,节约了资源;
3.线程池不需要每次都创建,响应时间更快。
或者:为了减少创建和销毁线程的次数,让每个线程多次使用,可根据系统情况调整指向线程的数量,防止消耗过多内存,所以要使用线程池。