1>String,StringBuilder和StringBuffer的区别
1)String不可变字符串,适合少量数据的操作
2)StringBuffer和StringBuilder 可变字符串,适合大量数据的操作
3)StringBuffer是单线程,安全性低,但效率高
4)StringBuilder是多线程,安全性高,但效率低
2>equals 与 == 的区别
1)== 一种操作符, 对于基本类型,比较的是值,对于引用类型,比较的是内存地址(指针操作)
2)equals是Object中的方法,用到的还是"==",如果对象不重写equals方法,那么equals和"=="作用是一样的,都是比较的地址值,但是大部分类都会重写父类的equals方法,用来检测两个对象的内容是否相等,例如String就重写了equals方法,用来比较两个字符串内容是否相同
3)== 的 运行速度快于equals()方法
3>HashMap和Hashtable的区别
1)HashMap线程不安全 HashTable线程安全
2)HashMap效率高,HashTable效率低
3)HashMap的KV对支持null值,HashTable不支持
4)HashMap默认容量初始化为16,之后每次扩容都是原来的2倍
HashTable默认容量初始化为11,之后每次扩容都是原来的2n+1
5)HashMap的迭代方式为Iterator HashTable为Enumeration
4>ArrayList和LinkedList的区别
同:
都实现了List接口,都能实现增删改查的操作
两者都不能保证线程同步(不安全)
异:
1)ArrayList的数据结构是动态数组,LinkedList的数据结构是链表
2)ArrayList的改查方法效率高于LinkedList,后者需要移动指针
3)ArrayList的增删方法效率低于LinkedList,前者需要移动数据
5>final关键字修饰类,方法,字段会有什么效果
final根据语义,是最后的,不可终止的
1)修饰类,表示该类不能被继承,不存在子类
2)修饰方法,表示该方法不能被修改,不能被子类方法覆盖,但可以被继承
3)修饰字段,表示常量,初始化之后不能被修改,只出现一次
6>线程的生命周期
线程的生命周期一共分为五个部分:新建,就绪,运行,阻塞以及死亡
7>start和run方法有什么区别
1)程序调用start()方法,将会创建一个新线程去执行run()方法中的代码。但是如果直接调用run()方法的话,会直接在当前线程中执行run()中的代码,注意,这里不会创建新线程。这样run()就像一个普通方法一样
2)另外当一个线程启动之后,不能重复调用start(),否则会报异常。但是可以重复调用run()方法
总结起来就是run()就是一个普通的方法,而start()会创建一个新线程去执行run()的代码
3)run()方法必须用public修饰
8>sleep方法和对象的wait方法有什么区别
(摘抄自sleep()方法与wait()方法的区别_李太白不太白的博客-CSDN博客_wait与sleep方法的区别)
同:
都是让线程停止
异:
1)原理不同。sleep()是Thread类的静态方法,是线程用来控制自身流程的,它会使线程暂停一段时间,把执行机会让给其他线程,等计时时间一到,此线程会自动“苏醒”;而wait()方法是Object类的方法,用于线程之间的通信,这个方法会使拥有对象锁的线程进入等待状态,直到其他线程调用notify方法才能“唤醒”,当然也可以指定一个时间醒来。
2)对锁的处理机制不同。由于sleep()方法主要是让线程暂停执行一段时间,时间一到则立即恢复运行,不涉及线程之间的通信,所以调用sleep()方法不会释放锁;当调用wait()方法后,线程释放它所占有的锁,让给其他线程去争夺锁。
3)使用区域不同。sleep()可以放在任何地方使用,而wait()只能放在同步方法或者同步块中使用。
4)sleep()必须捕获异常,而wait()不用,由于,在sleep()的时间当中有可能被对象调用interrupt()方法,产生InterruptException。
5)由于sleep()不会释放锁,容易导致“死锁”的情况发生,在多线程的时候,一般情况下用wait()方法好。
9>线程之间如何进行通讯
- wait 和 notify
- await 和 signal
- park 和 unpark
10>什么是线程不安全,请举例说明
线程不安全是指多个线程在访问临界资源(多个线程都能访问到的资源)时,由于访问非原子性导致的产生结果和预期结果不同。
举个栗子-->
上厕所的时候,厕门不关,多个人进同一个坑,一个人还没完,另一个人就进去了