目录
1.通过字面量创建字符串和new一个字符串对象有什么区别?那什么是常量池呢?
2. String适合做字符串拼接吗?String,StringBuffer和StringBuilder有什么区别?
3.子类重写父类方法的要求
4. final,finally,finalize有什么区别?
5.List集合和Set集合的区别是什么?
6.集合中的泛型有什么用?
7.常见的List集合有哪些?有什么区别
8.什么是队列,什么是栈?
9.HashMap的初始长度是多少?在什么时候进行扩容?
10.HashMap的底层数据结构是什么?那什么时候变为红黑树呢?
11.HashMap,HashTable,ConcurrentHashMap有什么区别?
12.什么是CAS算法?
13. 我们能否使用任何类作为HashMap的key?
14. 你能说说 sleep wait notify notifyAll的作用吗?
15. 创建线程有哪些方法?
16.Java的线程池有哪些?那你最常用的线程池是哪个?
内存的分配方式不一样:
-- 通过字面量创建的字符串对象会分配到常量池中
-- 通过new创建的字符串对象会分配到堆中
常量池:
-- 它存在于方法区(元空间中),使用字面量创建的字符串会直接缓存到常量池中,若再次使用该字面量创建新字符串时,不再创建新对象,而是从常量池中获取
String是只读字符串,不适合
jdk1.8之后字符串拼接底层就是创建了一个StringBuilder,然后调用append方法,最后调用toString转化成String
1 、数据可变和不可变① String 底层使用一个不可变的字符数组,由final修饰, 所以它内容不可变② StringBuffer 和 StringBuilder 都继承了 AbstractStringBuilder 底层使用的是可变字符数组2 、线程安全StringBuilder 是线程不安全的,效率较高;而 StringBuffer 是线程安全的,效率较低。通过他们的 append() 方法来看, StringBuffer 是有同步锁,而 StringBuilder 没有
3、 相同点
StringBuilder 与 StringBuffer 有公共父类 AbstractStringBuilder
方法重写的具体要求: 1.方法名和形参列表一样。 2.返回值类型一样或更小。 3.修饰符权限相同或者更大。 4.抛出的异常一样或者范围数量更小。 方法重写的规范: 1.加上@Override注解。 2.建议“申明不变,重新实现”。
final用于修饰类,变量,方法
1.final修饰类,类不能被继承了。 2.final可以修饰方法,方法就不能被重写了。 3.final修饰变量总规则:变量有且仅能被赋值一次。finally用于try-catch捕获异常,无论代码是否发生异常,finally中的代码一定会被执行,通常用来关闭资源
finalize属于Object类中的一个方法,当对象被回收的时候,会调用此方法
List集合是可重复集合,且有序
Set集合是不可重复集 ,且无序
集合中的泛型是用来约束元素类型的
ArrayList 底层是数组,查询快,增删慢
LinkedList 底层是链表,增删快,查询慢
Vector 底层是数组,是线程安全的
是用于存储数据的数据结构
队列 遵循先进先出原则
栈 遵循先进后出原则
HashMap的初始长度是16
当容量达到加载因子0.75的时候进行扩容
扩容后的大小一定是2的N次方
在JDK1.7的时候是数组+链表;
在JDK1.8的时候是数组+链表+红黑树;
当链表的长度大于8的时候,就会变成红黑树
HashMap是线程不安全的;
HashTable是线程安全的,其内部使用了synchronize关键字进行加锁;
ConcurrentHashMap结合了HashMap和HashTable,是线程安全的,
JDK1.7,其内部使用了分段锁的思想来进行加锁
JDK1.8,其内部是用来CAS+synchonized来保证并发安全
全称为CompareAndSwap,比较和更新,是能保证当前操作安全性和原子性的算法
Java并发包中的很多类都使用了CAS技术,如ConcurrentHashMap,AtomicInteger原子操作类等等.
CAS操作涉及到三个操作值:当前内存中的值,预估值,即将修改的新值.
当且仅当预估值等于内存中的值得时候,才将新的值保存到内存中,否则什么都不做.
CAS是从乐观的角度出发:
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。
CAS这种机制我们也可以将其称之为乐观锁。综合性能较好!
可以
需要注意的是,如果类重写了equals方法,我们应当连同重写hashcode方法;因为hashcode的值应当与equals的结果相对应,两个对象若equals比较为true,hashcode值应当相同.两个对象若equals比较结果为false.hashcode值最好不同.若依然相同,那么作为key存入HashMap中时会产生链表现象,影响HashMap查询性能.
sleep方法是Thread类的静态方法
调用sleep方法可以让当前正在运行的线程进入睡眠状态,即暂时停止运行指定的单位时间。并且该线程在睡眠期间不会释放对象锁。
wait是Object提供的一个方法
调用wait方法可以让当前线程进入等待唤醒状态,并释放锁。该线程会处于等待唤醒状态直到另一个线程调用了object对象的notify方法或者notifyAll方法。
notify也是Object提供的一个方法
当其它线程调用该对象的notifyAll()方法(唤醒所有wait线程)或notify()方法(只随机唤醒一个wait线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去公平竞争该对象锁。
(1)直接定义一个类继承Thread类,重写run()方法,创建线程对象 调用线程对象的start()方法启动线程。 (2)定义一个线程任务类实现Runnable接口,重写run()方法,创建线程任务对象,把 线程任务对象包装成线程对象, 调用线程对象的start()方法启动线程。 (3)实现Callable接口。 (4)使用线程池创建
newCachedTheadPool 动态的线程池
newFixedThreadPool 固定线程数的线程池
newSingleThreadExecutorPool 固定只有一条线程的线程池
newSCheduledThreadPool 以固定频率执行的线程池
一般来说,这四种线程池都不使用,一般使用ThreadPoolExecutor来自定义线程池