目录
- Java中的锁有哪些?以及区别?
- spring boot和spring的区别?
- SpringBoot的启动流程。
- java泛型
- JDK 和 JRE 有什么区别?
- == 和 equals 的区别是什么?
- List、Set、Map 之间的区别是什么?
- Array 和 ArrayList 有何区别?
- 什么是死锁?
- 怎么防止死锁?
一.Java中的锁有哪些?以及区别?
- 公平锁/非公平锁
- 可重入锁
- 独享锁/共享锁
- 互斥锁/读写锁
- 乐观锁/悲观锁
- 分段锁
- 偏向锁/轻量级锁/重量级锁
1.公平锁/非公平锁
- 公平锁是指多个线程按照申请锁的顺序来获取锁。
- 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。有可能,会造成优先级反转或者饥饿现象。
- 对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。
- 对于Synchronized而言,也是一种非公平锁。由于其并不像ReentrantLock是通过
2.可重入锁
- 可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁
3.独享锁/共享锁
- 独享锁是指该锁一次只能被一个线程所持有。
- 共享锁是指该锁可被多个线程所持有。
- 对于Java
ReentrantLock而言,其是独享锁。但是对于Lock的另一个实现类ReadWriteLock,其读锁是共享锁,其写锁是独享锁。 - 读锁的共享锁可保证并发读是非常高效的,读写,写读 ,写写的过程是互斥的。
- 独享锁与共享锁也是通过AQS来实现的,通过实现不同的方法,来实现独享或者共享。
- 对于Synchronized而言,当然是独享锁。
4.互斥锁/读写锁
- 互斥锁在Java中的具体实现就是ReentrantLock
- 读写锁在Java中的具体实现就是ReadWriteLock
5.乐观锁/悲观锁
- 乐观锁与悲观锁不是指具体的什么类型的锁,而是指看待并发同步的角度。
- 悲观锁认为对于同一个数据的并发操作,一定是会发生修改的,哪怕没有修改,也会认为修改。因此对于同一个数据的并发操作,悲观锁采取加锁的形式。悲观的认为,不加锁的并发操作一定会出问题。
- 乐观锁则认为对于同一个数据的并发操作,是不会发生修改的。在更新数据的时候,会采用尝试更新,不断重新的方式更新数据。乐观的认为,不加锁的并发操作是没有事情的。
6.分段锁
- 分段锁其实是一种锁的设计,并不是具体的一种锁,对于ConcurrentHashMap而言,其并发的实现就是通过分段锁的形式来实现高效的并发操作。
7.偏向锁/轻量级锁/重量级锁
- 这三种锁是指锁的状态,并且是针对Synchronized。在Java
5通过引入锁升级的机制来实现高效Synchronized。这三种锁的状态是通过对象监视器在对象头中的字段来表明的。 - 偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁。降低获取锁的代价。
- 轻量级锁是指当锁是偏向锁的时候,被另一个线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,提高性能。
- 重量级锁是指当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞,性能降低。
二.spring boot和spring的区别
- Spring Boot提供极其快速和简化的操作,让 Spring 开发者自快速上手。
- Spring Boot提供了 Spring 运行的默认配置。
- Spring Boot为通用 Spring项目提供了很多非功能度性特性,例如:嵌入式
Serve、Security、统知计、道健康检查、外部配置等等。
三.SpringBoot的启动流程
- 第一部分进行SpringApplication的初始化模块,配置一些基本的环境变量、资源、构造器、监听器
- 第二部分实现了应用具体的启动方案,包括启动流程的监听模块、加载配置环境模块、及核心的创建上下文环境模块
- 第三部分是自动化配置模块,该模块作为springboot自动配置核心,在后面的分析中会详细讨论。在下面的启动程序中我们会串联起结构中的主要功能。
启动:
- 每个SpringBoot程序都有一个主入口,也就是main方法,main里面调用SpringApplication.run()启动整个spring-boot程序,该方法所在类需要使用@SpringBootApplication注解,以及@ImportResource注解(if
need),@SpringBootApplication包括三个注解,功能如下: - @EnableAutoConfiguration:SpringBoot根据应用所声明的依赖来对Spring框架进行自动配置
- @SpringBootConfiguration(内部为@Configuration):被标注的类等于在spring的XML配置文件中(applicationContext.xml),装配所有bean事务,提供了一个spring的上下文环境
- @ComponentScan:组件扫描,可自动发现和装配Bean,默认扫描SpringApplication的run方法里的Booter.class所在的包路径下文件,所以最好将该启动类放到根包路径下
四.Java 泛型
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
假定我们有这样一个需求:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?
答案是可以使用 Java 泛型。
使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。
五.JDK 和 JRE 有什么区别?
- JDK:它是Java开发运行环境,在程序员的电脑上当然要安装JDK;
- JRE:Java Runtime
Environment它是Java运行环境,如果你不需要开发只需要运行Java程序,那么你可以安装JRE。例如程序员开发出的程序最终卖给了用户,用户不用开发,只需要运行程序,所以用户在电脑上安装JRE即可 - JDK包含了JRE。
- JRE中包含虚拟机JVM
六.== 和 equals 的区别是什么?
1、功能不同
- "=="是判断两个变量或实例是不是指向同一个内存空间。
- "equals"是判断两个变量或实例所指向的内存空间的值是不是相同。
2、定义不同
- "equals"在JAVA中是一个方法。
- "=="在JAVA中只是一个运算符合。
七.List、Set、Map 之间的区别是什么?
- List:有序集合,元素可重复
- Set:不重复集合,LinkedHashSet按照插入排序,SortedSet可排序,HashSet无序
- Map:键值对集合,存储键、值和之间的映射;Key无序,唯一;value 不要求有序,允许重复
八.Array和ArrayList有何区别?
- Array 即数组,声明方式可以如下:
int[] array = new int[3];
int array [] = new int[3];
int[] array = {1, 2, 3};
int[] array = new int[]{1, 2, 3};
- 定义一个 Array 时,必须指定数组的数据类型及数组长度,即数组中存放的元素个数固定并且类型相同。
- ArrayList 是动态数组,长度动态可变,会自动扩容。不使用泛型的时候,可以添加不同类型元素。
List list = new ArrayList(3);
list.add(1);
list.add("1");
list.add(new Double("1.1"));
list.add("第四个元素,已经超过初始长度");
for (Object o : list) {
System.out.println(o);
}
九.什么是死锁?
- 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
十.怎么防止死锁?
- 允许目的节点将不完整的报文递交给目的端系统;
- 一个不能完整重装的报文能被检测出来,并要求发送该报文的源端系统重新传送;
- 为每个节点配备一个后备缓冲空间,用以暂存不完整的报文。
1.有序资源分配法
这种算法资源按某种规则系统中的所有资源统一编号(例如打印机为1、磁带机为2、磁盘为3、等等),申请时必须以上升的次序。
2.银行家算法
避免死锁算法中最有代表性的算法是Dijkstra E.W 于1968年提出的银行家算法:
银行家算法是避免死锁的一种重要方法,防止死锁的机构只能确保上述四个条件之一不出现,则系统就不会发生死锁。通过这个算法可以用来解决生活中的实际问题,如银行贷款等。