Java基础
String、StringBuffer、StringBuilder 有什么区别?
String是Java语言非常基础和重要的类,提供了构造和管理字符串的基本逻辑,它本身是一个典型的Immutable类(Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构)),被final所修饰的类,所有属性也是final的。对String的每一次操作都会产生新的String对象
StringBuffer是为了解决上述对String操作太多产生大量中间对象影响效率而提供的一个类,可以用append或add方法把字符串添加到已有序列末尾或指定位置,StringBuffer本质是一个线程安全的可修改字符序列(给每个方法加关键字synchronized),它保证了线程安全,也随之带来了额外的性能开销
StingBuilder Java1.5中新增的, 同StringBuffer作用一样,但去掉了其中线程安全的部分,减小了开销
JMM JVM
HashMap 底层数据结构
在 JDK 1.7 中 HashMap 是以数组加链表的形式组成的,JDK 1.8 之后新增了红黑树的组成结构,当链表大于 8 并且容量大于 64时,链表结构会转换成红黑树结构,是因为一旦链表过长,会严重影响 HashMap 的性能,而红黑树具有快速增删改查的特点,这样就可以有效的解决链表过长时操作比较慢的问题.HashMap死循环是因为 JDK 1.7 链表插入方式为首部倒序插入,这个问题在 JDK 1.8 得到了改善,变成了尾部正序插入
进程 线程
概念区分:
进程可以简单理解为一个可以独立运行的程序单位,它是线程的集合,进程是由一个或多个线程构成的; 线程是进程中的实际运行单位是操作系统进行调度的最小单位。多进程就是指计算机同时执行多个进程,一般指运行多个软件。凡是用于完成操作系统各种功能的进程就是系统进程,由用户所启动进程为用户进程。多线程就是指一个进程中同时有多个线程正在执行
为什么要使用多线程?
在一个程序中,有很多操作是非常耗时的,比如数据库的读写、IO操作等,如果采用单线程,那么在进行这些操作时其他操作只能等待;使用多线程,可以将耗时任务放在后台执行的同时,继续执行其他任务。可以提高程序的效率;
缺点:使用太多线程很耗系统资源,因为线程需要开辟内存,要在多个线程之间来回切换,影响系统性能;线程使用不当也会引发很多问题。
线程之间进行通信的方法
1️⃣ 同步 : 多个线程之间通过Synchronized关键字方式,多个线程需要访问同一个共享变量,谁拿到了锁(获得了访问权限),谁就可以执行,从而实现线程间的通信
2️⃣ While轮询:一个线程A不断地改变条件,另一个线程B通过while语句判断条件是否成立,从而实现通信。但是这种方式会浪费CPU资源。
3️⃣ wait/notify机制:用到了Object类的 wait() 和 notify() 方法,当条件未满足时线程A调用wait() 放弃CPU,并进入阻塞状态。---不像②while轮询那样占用CPU,当条件满足时,线程B调用 notify()通知 线程A,所谓通知线程A,就是唤醒线程A,并让它进入可运行状态。这种方式的一个好处就是CPU的利用率提高了。缺点:通知过早,会打乱程序的执行逻辑
4️⃣ 管道通信:使用java.io.PipedInputStream 和 java.io.PipedOutputStream进行通信