一、Java 基础
1.JDK 和 JRE 有什么区别?
== 和 equals 的区别是什么?
两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
final 在 java 中有什么作用?
java 中的 Math.round(-1.5) 等于多少?
String 属于基础的数据类型吗?
java 中操作字符串都有哪些类?它们之间有什么区别?
String str="i"与 String str=new String(“i”)一样吗?
如何将字符串反转?
String 类的常用方法都有那些?
抽象类必须要有抽象方法吗?
普通类和抽象类有哪些区别?
抽象类能使用 final 修饰吗?
接口和抽象类有什么区别?
java 中 IO 流分为几种?
BIO、NIO、AIO 有什么区别?
Files的常用方法都有哪些?
二、容器
java 容器都有哪些?
Collection 和 Collections 有什么区别?
List、Set、Map 之间的区别是什么?
HashMap 和 Hashtable 有什么区别?
如何决定使用 HashMap 还是 TreeMap?
说一下 HashMap 的实现原理?
说一下 HashSet 的实现原理?
ArrayList 和 LinkedList 的区别是什么?
如何实现数组和 List 之间的转换?
ArrayList 和 Vector 的区别是什么?
Array 和 ArrayList 有何区别?
在 Queue 中 poll()和 remove()有什么区别?
哪些集合类是线程安全的?
迭代器 Iterator 是什么?
Iterator 怎么使用?有什么特点?
Iterator 和 ListIterator 有什么区别?
怎么确保一个集合不能被修改?
三、多线程 35. 并行和并发有什么区别? 36. 线程和进程的区别? 37. 守护线程是什么? 38. 创建线程有哪几种方式? 39. 说一下 runnable 和 callable 有什么区别? 40. 线程有哪些状态? 41. sleep() 和 wait() 有什么区别? 42. notify()和 notifyAll()有什么区别? 43. 线程的 run()和 start()有什么区别? 44.创建线程池有哪几种方式? 45.线程池都有哪些状态? 46. 线程池中 submit()和 execute()方法有什么区别? 47. 在 java 程序中怎么保证多线程的运行安全? 48. 多线程锁的升级原理是什么? 49. 什么是死锁? 50. 怎么防止死锁? 51. ThreadLocal 是什么?有哪些使用场景? 52. 说一下 synchronized 底层实现原理? 53. synchronized 和 volatile 的区别是什么? 54. synchronized 和 Lock 有什么区别? 55. synchronized 和 ReentrantLock 区别是什么? 56. 说一下 atomic 的原理?
四、反射 57. 什么是反射? 58. 什么是 java 序列化?什么情况下需要序列化? 59. 动态代理是什么?有哪些应用? 60. 怎么实现动态代理?
五、对象拷贝 61. 为什么要使用克隆? 62. 如何实现对象克隆? 63. 深拷贝和浅拷贝区别是什么?
六、Java Web 64. jsp 和 servlet 有什么区别? 65. jsp 有哪些内置对象?作用分别是什么? 66. 说一下 jsp 的 4 种作用域? 67. session 和 cookie 有什么区别? 68. 说一下 session 的工作原理? 69. 如果客户端禁止 cookie 能实现 session 还能用吗? 70. spring mvc 和 struts 的区别是什么? 71. 如何避免 sql 注入? 72. 什么是 XSS 攻击,如何避免? 73. 什么是 CSRF 攻击,如何避免?
七、异常 74. throw 和 throws 的区别? 75. final、finally、finalize 有什么区别? 76. try-catch-finally 中哪个部分可以省略? 77. try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 78. 常见的异常类有哪些?
八、网络 79. http 响应码 301 和 302 代表的是什么?有什么区别? 80. forward 和 redirect 的区别? 81. 简述 tcp 和 udp的区别? 82. tcp 为什么要三次握手,两次不行吗?为什么? 83. 说一下 tcp 粘包是怎么产生的? 84. OSI 的七层模型都有哪些? 85. get 和 post 请求有哪些区别? 86. 如何实现跨域? 87. 说一下 JSONP 实现原理?
九、设计模式 88. 说一下你熟悉的设计模式? 89. 简单工厂和抽象工厂有什么区别?
十、Spring/Spring MVC 90. 为什么要使用 spring? 91. 解释一下什么是 aop? 92. 解释一下什么是 ioc? 93. spring 有哪些主要模块? 94. spring 常用的注入方式有哪些? 95. spring 中的 bean 是线程安全的吗? 96. spring 支持几种 bean 的作用域? 97. spring 自动装配 bean 有哪些方式? 98. spring 事务实现方式有哪些? 99. 说一下 spring 的事务隔离? 100. 说一下 spring mvc 运行流程? 101. spring mvc 有哪些组件? 102. @RequestMapping 的作用是什么? 103. @Autowired 的作用是什么?
十一、Spring Boot/Spring Cloud 104. 什么是 spring boot? 105. 为什么要用 spring boot? 106. spring boot 核心配置文件是什么? 107. spring boot 配置文件有哪几种类型?它们有什么区别? 108. spring boot 有哪些方式可以实现热部署? 109. jpa 和 hibernate 有什么区别? 110. 什么是 spring cloud? 111. spring cloud 断路器的作用是什么? 112. spring cloud 的核心组件有哪些?
十二、Hibernate 113. 为什么要使用 hibernate? 114. 什么是 ORM 框架? 115. hibernate 中如何在控制台查看打印的 sql 语句? 116. hibernate 有几种查询方式? 117. hibernate 实体类可以被定义为 final 吗? 118. 在 hibernate 中使用 Integer 和 int 做映射有什么区别? 119. hibernate 是如何工作的? 120. get()和 load()的区别? 121. 说一下 hibernate 的缓存机制? 122. hibernate 对象有哪些状态? 123. 在 hibernate 中 getCurrentSession 和 openSession 的区别是什么? 124. hibernate 实体类必须要有无参构造函数吗?为什么?
十三、Mybatis 125. mybatis 中 #{}和 ${}的区别是什么? 126. mybatis 有几种分页方式? 127. RowBounds 是一次性查询全部结果吗?为什么? 128. mybatis 逻辑分页和物理分页的区别是什么? 129. mybatis 是否支持延迟加载?延迟加载的原理是什么? 130. 说一下 mybatis 的一级缓存和二级缓存? 131. mybatis 和 hibernate 的区别有哪些? 132. mybatis 有哪些执行器(Executor)? 133. mybatis 分页插件的实现原理是什么? 134. mybatis 如何编写一个自定义插件?
十四、RabbitMQ 135. rabbitmq 的使用场景有哪些? 136. rabbitmq 有哪些重要的角色? 137. rabbitmq 有哪些重要的组件? 138. rabbitmq 中 vhost 的作用是什么? 139. rabbitmq 的消息是怎么发送的? 140. rabbitmq 怎么保证消息的稳定性? 141.rabbitmq 怎么避免消息丢失? 142. 要保证消息持久化成功的条件有哪些? 143. rabbitmq 持久化有什么缺点? 144. rabbitmq 有几种广播类型? 145. rabbitmq 怎么实现延迟消息队列? 146. rabbitmq 集群有什么用? 147. rabbitmq 节点的类型有哪些? 148. rabbitmq 集群搭建需要注意哪些问题? 149. rabbitmq 每个节点是其他节点的完整拷贝吗?为什么? 150. rabbitmq 集群中唯一一个磁盘节点崩溃了会发生什么情况? 151. rabbitmq 对集群节点停止顺序有要求吗?
十五、Kafka 152. kafka 可以脱离 zookeeper 单独使用吗?为什么? 153. kafka 有几种数据保留的策略? 154. kafka 同时设置了 7 天和 10G 清除数据,到第五天的时候消息达到了 10G,这个时候 kafka 将如何处理? 155. 什么情况会导致 kafka 运行变慢? 156. 使用 kafka 集群需要注意什么?
十六、Zookeeper 157. zookeeper 是什么? 158. zookeeper 都有哪些功能? 159. zookeeper 有几种部署模式? 160. zookeeper 怎么保证主从节点的状态同步? 161. 集群中为什么要有主节点? 162. 集群中有 3 台服务器,其中一个节点宕机,这个时候 zookeeper 还可以使用吗? 163. 说一下 zookeeper 的通知机制?
十七、MySql 164. 数据库的三范式是什么? 165. 一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几? 166. 如何获取当前数据库版本? 167. 说一下 ACID 是什么? 168. char 和 varchar 的区别是什么? 169. float 和 double 的区别是什么? 170. mysql 的内连接、左连接、右连接有什么区别? 171. mysql 索引是怎么实现的? 172. 怎么验证 mysql 的索引是否满足需求? 173. 说一下数据库的事务隔离? 174. 说一下 mysql 常用的引擎? 175. 说一下 mysql 的行锁和表锁? 176. 说一下乐观锁和悲观锁? 177. mysql 问题排查都有哪些手段? 178. 如何做 mysql 的性能优化?
十八、Redis 179. redis 是什么?都有哪些使用场景? 180. redis 有哪些功能? 181. redis 和 memecache 有什么区别? 182. redis 为什么是单线程的? 183. 什么是缓存穿透?怎么解决? 184. redis 支持的数据类型有哪些? 185. redis 支持的 java 客户端都有哪些? 186. jedis 和 redisson 有哪些区别? 187. 怎么保证缓存和数据库数据的一致性? 188. redis 持久化有几种方式? 189.redis 怎么实现分布式锁? 190. redis 分布式锁有什么缺陷? 191. redis 如何做内存优化? 192. redis 淘汰策略有哪些? 193. redis 常见的性能问题有哪些?该如何解决?
十九、JVM 194. 说一下 jvm 的主要组成部分?及其作用? 195. 说一下 jvm 运行时数据区? 196. 说一下堆栈的区别? 197. 队列和栈是什么?有什么区别? 198. 什么是双亲委派模型? 199. 说一下类加载的执行过程? 200. 怎么判断对象是否可以被回收? 201. java 中都有哪些引用类型? 202. 说一下 jvm 有哪些垃圾回收算法? 203. 说一下 jvm 有哪些垃圾回收器? 204. 详细介绍一下 CMS 垃圾回收器? 205. 新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别? 206. 简述分代垃圾回收器是怎么工作的? 207. 说一下 jvm 调优的工具? 208. 常用的 jvm 调优的参数都有哪些?
1.JDK 和 JRE 有什么区别? JDK是java的开发工具包,包含各种类库,并且包含了JRE,javac是在JDK中的; JREjava程序的运行环境,安装过程中自动添加PATH. 2. == 和 equals 的区别是什么? 一. 对于==,比较的是值是否相等,如果比较的是基本数据类型的变量,则直接比较其存储的值是否相等, 如果比较的是引用数据类型,则比较的是所指向的对象的地址值. 二. equals不能作用于基本数据类型,它比较的是是否是同一个对象 如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址值. 如String,Date等类对equals方法进行了重写,比较的则是所指向的对象的内容 3. 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗? 首先,两个对象equals相等,hashcode一定相等;但是hashcode相等时,equals不一定相等. 其次,两个不同的对象,因为可能存在哈希碰撞,所以hashcode可能是相等的,但是显然equals不为true. 还有就是,在object类中,euqals方法还是用的==来判断的,对于对象而言比较的是地址值,所以equals相等 hashcode一定一样,反之就不一定了. 4. final 在 java 中有什么作用? final关键字可作用于类,类属性和方法; 作用于类上时,该类不能被继承 作用于属性时,该属性不能被重新复制 作用于方法时,该方法不能被重写 5. java 中的 Math.round(-1.5) 等于多少? Math的round方法是四舍五入,如果参数是负数,则往大的数如,Math.round(-1.5)=-1 6. String 属于基础的数据类型吗? 不是,String是一个类,是引用数据类型. 7. java 中操作字符串都有哪些类?它们之间有什么区别? 有String,StringBuilder,StringBuffer 1. String是不可变的,每次对String的操作都会产生一个String对象 2. StringBuilder和StringBuffer是可变的,能够被多次修改,并不会产生新的对象. 3. StringBuilder是线程不安全的,StringBuffer是线程安全的. 4. StringBuilder的处理速度比StringBuffer要快 8. String str="i"与 String str=new String(“i”)一样吗? 他们的值相等,用equals得到true,但是他们是两个对象,如果用判断返回false. 且str="i"是直接在常量池中引用字符串,而new String(“i”)是在堆中根据i再创建一个对象. 9. 如何将字符串反转? 1. 通过StringBuilder的reverse()方法可以直接反转 StringBuilder sb = new StringBuilder(“abc”); sb.reverse().toString(); 2. 通过String的toCharArray方法可以获得字符串每一个字符并且转换为字符数组 然后循环从后往拼接即可 3. 递归的方法反转(当只有一个字符时,返回原字符;当有两个以上的字符时,返回结果为第二个字符串开始的子串+第一个字符) public String reverseString(String str) { if ((null == str) || str.length()<2) { return str; } return reverseString(str.subString(1)) +str.charAt(0); } 10. String 类的常用方法都有那些? charAt(int index)返回指定索引处的字符 length()返回字符串长度 split()根据给定的正则表达式拆分字符串 toString()返回此对象本身 11. 抽象类必须要有抽象方法吗? 抽象类可以没有抽象方法,但是如果一个类已经声明为抽象类,那么它也不能再实例化,不能直接构造该类对象. 12. 普通类和抽象类有哪些区别? 1. 抽象类不能被实例化,普通类反之 2. 抽象类的访问权限限于public和protected,如果为private的话,就不能被子类继承了. 3. 如果一个类继承于抽象类,则它必须实现父类的抽象方法.如果不想实现,那么子类也必须是抽象类. 13. 抽象类能使用 final 修饰吗? 不能,final修饰的类是不能被继承的,如果抽象类不能继承,就没有意义了. 14. 接口和抽象类有什么区别? 1. 抽象类可以有构造方法,接口不能有构造方法. 2. 抽象类可以包含非抽象方法,接口则不能. 3. 抽象类方法访问权限是public、protected,接口中只能是public. 4. 只能单继承,但是可以多实现. 15. java 中 IO 流分为几种? 大的方面来说有两种:字节流和字符流 字节流继承于InputStream、OutputStream 字符流继承于Reader、Writer
BIO、NIO、AIO 有什么区别? BIO表示同步阻塞式IO,交互方式是同步、阻塞方式,即客户端有连接请求时服务端就需要启动一个线程进行处理, 如果这个连接不做任何事情会造成不必要的开支.NIO表示同步非阻塞IO,客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求 时才启动一个线程处理.AIO表示异步非阻塞IO,客户端的I/O请求都是由操作系统先完成IO操作后再通知服务器应用来启动线程处理. Files的常用方法都有哪些? String getName():返回File对象所表示的文件名或文件路径 String getPath():返回File对象所对应的相对路径 boolean exists():判断File对象的文件或者目录是否存在 boolean isDirectory():判断File对象是否是目录java 容器都有哪些? String,数组以及java.util下面的集合类 List:存放有序,列表存储,元素可重复 ArrayList LinkedList Vector Set:无序,元素不可重复 HashSet TreeSet Map:无序,元素可重复 HashMap TreeMap LinkedHashMap HashTable
Collection 和 Collections 有什么区别? Collection是集合类的一个顶级接口,它提供了对集合对象进行基本操作的通用接口方法. Collections是集合类的一个工具类,它提供了一系列的静态方法,用于对集合中元素进行排序,搜索以及线程同步等操作.
List、Set、Map 之间的区别是什么? List: 可以允许重复的对象; 可以插入多个null元素; 有序,输入顺序就是输出顺序; Set: 不允许重复对象; 无序,且只允许一个null对象; Map: 存储键值对,只能有唯一的key,value可以重复 只能有一个null键
HashMap 和 Hashtable 有什么区别? 一. HashMap可以接受null键和值,HashTable不行 二. HashTable是线程安全的,通过synchronized来保证,而HashMap线程不安全 三. HashMap的迭代器是fail-fast迭代器,而HashTable的enumerator迭代器不是fail-fast.
如何决定使用 HashMap 还是 TreeMap? HashMap基于散列表实现,适用于查询频繁的情况 TreeMap基于红黑树实现,适用于创建比较多的情况.且TreeMap存储数据是按照字母表的顺序存储的, 如果对顺序有要求也可以选用TreeMap.
说一下 HashMap 的实现原理? 数组+链表,初始16,75扩容,数据存在内部类Map.Entry中,其中包含key value hashcode和next.
说一下 HashSet 的实现原理? HashSet基于HashMap实现,默认构造函数是构造一个初始容量为16的HashMap,所有放入HashSet 集合的元素实际上由HashMap的key来保存,而value则保存了一个PRESENT的静态Object对象,因为元素都保存在key 中,所以才能不重复.
ArrayList 和 LinkedList 的区别是什么?
ArrayList底层基于动态数组,LinkedList基于链表实现,底层是循环双向链表对于随机访问get和set,ArrayList优于LinkedList.对于新增add和删除remove,LinkedList比较快如何实现数组和 List 之间的转换? List转数组:toArray()方法.在方法参数中指定原集合的长度的数组即可. 数组转List:Arrays的asList()方法.
ArrayList 和 Vector 的区别是什么?
Vector的方法都是同步的,是线程安全的,ArrayList则不是.在进行扩容的时候,Vector扩容至原来的一倍,ArrayList增加至原来的0.5倍.Array 和 ArrayList 有何区别?
Array(数组)可以包含基本数据类型和对象类型,ArrayList只能包含对象类型.ArrayList可以自动扩容,Array则不行.在 Queue 中 poll()和 remove()有什么区别? Queue中,add方法和offer方法都可以添加元素,而remove和poll都是删除队列的头元素,区别在于: add方法在队列满的情况下抛异常,而offer方法则返回false. remove方法在队列为空时抛异常,poll方法将返回null.
哪些集合类是线程安全的? Vector HashTable ConcurrentHashMap Stack
迭代器 Iterator 是什么? Iterator是个接口,它提供了很多对元素进行迭代的方法.迭代器可以在迭代过程中删除 底层集合的元素,可以直接调用Iterator的remove()方法来删除. 因为在Conllection接口中定义了获取集合迭代器的方法,所以每一个集合都包括了可以返回迭代器实例的方法.
Iterator 怎么使用?有什么特点? 每个集合都可以用iterator()方法一个Iterator实例. 使用next()方法获取序列中的下一个元素,使用hasNext()方法检查序列中是否有元素 使用remove()方法将迭代器新返回的方法删除. 特点:Iterator将集合的遍历和其底层的结构分离.
Iterator 和 ListIterator 有什么区别? ListIterator是Iterator的子接口,用于扩展Iterator. 在Iterator中,我们只能向前移动,无法操纵或者修改集合中的元素.ListIterator弥补了这种缺点 区别: 1.范围不同,Iterator适用于所有集合,而ListIterator只适用于List及其子类 2.ListIterator有add方法可以添加元素,Iterator则不行. 3.ListIterator可以实现双向遍历,Iterator则不行. 4.ListIterator可以实现对象的修改,Iterator不行 5.ListIterator可以获取集合中的所有,Iterator不行.
怎么确保一个集合不能被修改? 可以使用Collections或者Guava来快速实现.如Collections.unmodifiableMap(xxxMap); 三、多线程
并行和并发有什么区别? 并行是多个事件同时进行,并发是多个事件在某一时间段内间隔发生. 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。 你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。
线程和进程的区别? 进程是操作系统资源分配的基本单位,线程是任务调度和执行的基本单位. 进程有独立的地址空间,一个进程崩溃后在保护模式下不会对其他进程产生影响,而线程只是一个进程中的 不同执行路径,线程有自己的堆栈和局部变量.在操作系统中能同时运行多个进程,而在同一个进程内有多个 线程同时执行.
守护线程是什么? 守护线程是服务其他线程的,在java中,线程有两种:守护线程和用户线程. java中的jvm垃圾回收线程就是一个典型的守护线程.当用户线程全部执行完,包括main线程也执行完毕,那么 jvm会自动退出,此时守护线程也就停止了.
创建线程有哪几种方式? 三种: 1. 继承Thread类,重写run方法,用子类实例调用start()方法; 2. 实现Runnable接口并重写run方法,创建Thread实例并传入Runnable实例,代用Thread的start()方法 3. 创建Callable接口的实现类,重写call方法; 构造此实现类的实例,将其作为参数构造一个FutureTask类的实例; 以FutureTask的实例为参数构造一个Thread对象执行start()方法. 第三种方式可以允许有返回值,也可以声明抛出异常类.
说一下 runnable 和 callable 有什么区别? runnable方式时,多个线程间可以共享实例变量,callable方式则不行 runnable方式没有返回值,callable有返回值 runnable方式run方法的异常只能在内部消化,callable的call()方法允许抛出异常
线程有哪些状态?
NEW 新建状态,此时线程还没有运行线程中的代码RUNNABLE 就绪状态;处于就绪状态的线程并不一定立即运行run方法,必须还要和其他线程竞争CPU时间RUNNING 运行状态;线程获得CPU时间后才进入运行状态,开始执行run方法BLOCKED 阻塞状态;线程运行过程中会有各种原因来进入阻塞状态,如:调用sleep方法进入休眠; 在IO操作中被阻塞;试图得到一个锁,该锁正被其他线程持有;等待某个触发条件. 阻塞状态的线程此时没有结束,暂时让出CPU时间给其他线程.DEAD 死亡状态;有两个原因导致线程死亡:第一是run方法正常退出自然死亡;第二是一个未捕获的 异常终止了run方法使线程死亡. 为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法,如果是可运行或被阻塞,这个方法返回true;如果线程仍旧是new状态且不是可运行的,或者线程死亡了,则返回false。sleep() 和 wait() 有什么区别?
sleep方法使Thread类的,而wait方法使Object类中的sleep方法使线程暂停指定的时间,让出CPU给其他线程,但是他的监控状态依然保持着,时间到了以后会自动恢复运行状态 在这个过程中,线程不会释放同步对象锁. 而调用wait方法,线程会放弃对象锁,进入等待队列,待调用notify/notifyAll方法后才会进入锁池,获取对象锁后才进入运行状态.notify()和 notifyAll()有什么区别? notify()方法随机唤醒一个wait线程到锁池中去竞争锁,而notifyAll方法唤醒所有wait线程到锁池. notity()方法可能产生死锁,notifyAll则不会.
线程的 run()和 start()有什么区别? run()方法只是定义了线程的执行单元并非直接开启了线程资源,只有start()方法被调用,才可以启动一个线程. 如果直接调用run方法,会被当成普通方法在main线程执行,并不会创建线程. 44.创建线程池有哪几种方式? java中的Executors可以为我们创建现成的线程池,有以下几种:
newSingleThreadExecutor 创建一个单线程的线程池,它只有一个工作线程,操作无界工作队列,可以保证任务顺序newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待newCachedThreadPool 创建一个可缓存线程池,有空闲线程时会回收,但是任务过多,会一直创建,消耗资源newScheduledThreadPool 创建一个大小无线的线程池,此线程池支持定时以及周期性任务的需求. 45.线程池都有哪些状态?RUNNING:一旦被创建,就处于此状态,可以接受新任务以及对已经添加的任务进行处理.SHUTDOWN:此时不接收新任务,但是可以处理已添加的任务STOP:此状态不接收新任务,不处理已添加任务,并且会中断正在处理的任务.TIDYING:当所有的任务已终止,ctl记录的任务数变为0,线程池会变成tidying状态.当线程池变为TIDYING状态会执行terminated()方法. 当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。 当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。TERMINATED:线程池彻底终止会变成这个状态.当在TIDYING状态,执行完terminated()函数后,就会由TIDYING状态变为TERMINATED状态.线程池中 submit()和 execute()方法有什么区别?
接受参数不一样,execute()方法接收Runnable类型的参数;submit()可以接收runnable和callable类型的参数submit方法有返回值,返回一个Future类型的对象,execute方法没有返回值.submit方法方便处理Exception异常.在 java 程序中怎么保证多线程的运行安全?
最简单的方式是加入synchronized关键字,在共享数据语句中加入该关键字可以在某一时段指挥让一个线程执行,其他线程不能执行.使用锁Lockredis?多线程锁的升级原理是什么? 在java中,锁有三种状态,级别从低到高依次为:偏向锁、轻量级锁、重量级锁,这几个状态会随着竞争情况逐渐升级,但是不能降级. 先说为什么要有锁升级:因为synchronized是重量级锁,每次在进行锁请求时,如果当前资源被其他线程占有,就要将当前线程阻塞,加入到阻塞队列中然后 清空当前线程的缓存,等到锁释放时再通过notify或者notifyAll方法唤醒当前线程,让其处于就绪状态.在这个过程中是非常消耗资源的,而且有时候线程刚挂起,锁就释放了. 而java的线程是映射到操作系统的原生线程之上的,每次线程的阻塞和唤醒都要在用户态和核心态之间转换,十分浪费资源.所以jvm对syncronized进行了优化,分为三种锁.
当锁对象第一次被线程获取的时候,虚拟机会将对象头中的锁标志位设置成01,并将偏向锁标志设置为1,线程通过CAS的方式将自己的ID值放到对象头中.这样每次该线程每次 再进入锁对象的时候不用任何的同步操作,直接比较当前锁对象头中是不是该线程的ID,如果是就可以直接进入.当有其他线程来尝试获取锁的时候,发现偏向锁标示是1,说明 锁已经被占用,则会使用CAS将对象头的偏向锁指向当前线程. 需要注意的是,偏向锁使用一种等待竞争出现才会释放锁的机制,当有其他线程尝试获取锁的时候,才会释放锁.首先它会暂停拥有偏向锁的线程,然后检查持有偏向锁的线程 是否活着,如果不处于活动状态,则将对象头设置为无锁状态;如果活着,那么拥有偏向锁的栈会被执行,遍历偏向对象的锁记录,使之要么恢复到无锁要么标记对象不适合作为 偏向锁.最后唤醒暂停的线程.假设线程1持有偏向锁,线程2来竞争偏向锁: 一. 首先线程2会检查偏向锁标记,如果是1,说明是偏向锁,那么JVM会找到线程1看其是否还活着. 二. 如果线程1已经执行完毕,那么先将偏向锁置为0,对象头设置为无锁的状态,用CAS的方式尝试将线程2的ID放入对象头,此时锁不升级,还是偏向锁. 三. 如果线程1还活着,先暂停线程1,将锁标志位变为00(轻量级锁),然后在线程1的栈帧中开辟出一块空间将对象头的Mark word置换到线程1的栈帧中,而对象头 中存储的是指向当前线程栈帧的指针.此时变为轻量级锁,线程1继续执行,线程2采用CAS的方式尝试获取锁.轻量级锁是通过CAS的方式尝试获取锁对象,一旦失败会先检查对象头中存储的是否是指向当前线程栈帧的指针,如果是,就可以获取锁对象,如果不是说明存在竞争那么久 膨胀成为重量级锁.一旦有两个以上的线程竞争锁,轻量级锁就会膨胀为重量级锁,锁的状态变为10,此时对象头中存储的就是指向重量级锁的栈帧的指针,而且其他等待所的线程要进入阻塞状态, 等待重量级锁释放后被唤醒然后去竞争.重量级锁是由操作系统来负责线程的调度,会消耗大量的系统资源.什么是死锁? 死锁是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种相互等待的过程,如果没有外力作用,他们讲无法推进下去.
怎么防止死锁?
以确定的顺序获取锁超时放弃.(Lock锁中就使用了这种方式)银行家算法ThreadLocal 是什么?有哪些使用场景? 也成为线程本地变量,ThreadLocal在每个线程中对一个变量创建了一个副本,且在线程内部任何地方都可以使用,线程间互不影响. 应用场景:spring的声明式事物管理.
说一下 synchronized 底层实现原理? 首先,每个对象都有一个监视器锁(monitor),当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:
如果monitor的进入数为0,则线程进入monitor,将进入数设置为1,该线程为monitor的所有者如果线程已经占有monitor,只是重新进入,则进入数+1如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获得所有权 执行monitorexit的线程必须是objectref所对应的monitor的所有者.指令执行时,monitor的进入数-1,如果减为0,那么线程退出monitor,不再是持有者. 在将synchronized代码块反编译以后,我们可以发现调用了monitorenter和monitorexit指令. 所以如果synchronized同步代码块,底层是调用monitor的两个指令来实现锁 如果synchronized同步方法,底层是读取运行时常量池的ACC_SYNCHRONIZED标志来实现的.synchronized 和 volatile 的区别是什么?
volatile修饰的变量,jvm每次都从主内run读取,不会从工作内存读取 而synchronized是锁住当前变量,同一时刻只有一个线程能访问当前变量.volatile只是作用于变量,synchronized可以用在变量,方法中valatile仅能实现变量修改的可见性,无法保证原子性. synchronized可以实现变量修改的可见性和原子性.synchronized 和 Lock 有什么区别?
synchronized是java内置的关键字,Lock是个接口synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁.synchronized会自动释放锁,Lock需要手动释放synchronized可重入(同一个类中两个同步方法,获取到锁后不用每次都去获取),不可中断,非公平;Lock可判断可公平.synchronized获得锁的线程阻塞,其他线程都会无线等待,Lock不会synchronized 和 ReentrantLock 区别是什么?
synchronized遇到异常不catch,锁会自动释放,ReentrantLock需要手动释放synchronized是非公平锁,ReentrantLock可以实现公平锁.前者无法获取锁的状态,后者可以tryLock()方法可以返回是否获得了锁.说一下 atomic 的原理? atomic包用中的类可以实现多线程环境下的变量操作,底层是调用CPU的CAS指令来进实现线程安全的. CAS,比较并操作,每次在set前,对比一下当前值和预期值是否一样,一样则set,否则认为失败,循环对比直到成功.
七、异常 74. throw 和 throws 的区别? throws:用来声明一个方法可能抛出的所有异常信息,不会处理异常,只是将异常向上传,交给调用者 throw:抛出一个具体的异常类型. throws出现在方法声头,而throw出现在函数体 throws表示出现异常的可能,并不一定会发生,throw则是抛出了一个存在的异常实例.
final、finally、finalize 有什么区别? final: 修饰类,表示该类不可继承 修饰方法,表示该方法不可重写 修饰变量,表示该变量不允许被修改 finally:是保证代码一定要被执行的一种机制.常用来关闭连接资源或者解锁等. finalize:是Object的一个方法,它的目的是保证对象在被垃圾收集前完成特定资源的回收.1.9后已经过时.try-catch-finally 中哪个部分可以省略? catch可以省略 不管有没有捕获到异常,finally中的代码都会被执行; finally是在return之后执行的,程序在执行完return之后,会将值保存起来,当执行完finally中的代码之后再将return值返回 如果finally中存在return,会导致最后返回的是finally中的值.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 会执行,return的值会暂时保存.等到运行完finally中的代码块时才会返回return的值常见的异常类有哪些? 空指针异常类型:NullPointerException 类型强制转换类型:ClassCastException 数组下标越界异常:ArrayIndexOutOfBoundsException 输入输出异常:IOException为什么要使用 hibernate? 1.对JDBC访问数据库的代码做了大量的封装,简化开发 2.性能好,支持各种关系数据库.
什么是 ORM 框架? ORM的意思是对象关系映射,它的作用是在关系型数据库和业务实体对象之间做映射 这样我们在操作具体业务对象的时候,就不需要去和具体的SQL语句打交道,只需要操作对象的属性和方法.
hibernate 中如何在控制台查看打印的 sql 语句? 在hibernate配置文件中配置hibernate.show_sql属性
hibernate 有几种查询方式? 三种:HQL查询 QBC查询(也叫Criteria查询) 本地SQL查询
hibernate 实体类可以被定义为 final 吗? 不能,因为hibernate使用代理方式在延迟加载的情况下提高性能,如果定义为final 就不能继承,也就无法实现代理.
在 hibernate 中使用 Integer 和 int 做映射有什么区别? 1.如果数据库返回字段值是null的话,int类型会报错,Integer则不会
hibernate 是如何工作的?
通过Configuration config = new Configuration().configure();解析配置文件
由hibernate.cfg.xml中的读取并解析映射信息
通过SessionFactory sf = config.buildSessionFactory();//创建SessionFactory
Session session = sf.openSession();//打开Sesssion
Transaction tx = session.beginTransaction();//创建并启动事务Transation
persistent operate操作数据,持久化操作
tx.commit();//提交事务
关闭session和sessionFactory
get()和 load()的区别?
get方式会直接触发sql语句查出对象,load方式会使用延迟加载的机制加载这个对象,此时是个代理对象 只保存实体对象的id值,只有用到其他属性的时候才会调用sql查出来.
如果对象不存在,get方式会抛出空指针异常,load方式会抛出ObjectNotFoundException
说一下 hibernate 的缓存机制? hibernate为了降低对数据库访问的频率,加入了缓存机制.缓存内的数据是对物理数据库数据的复制, 应用程序在运行时,从缓存中读写数据. Hibernate的缓存包括两大类:session一级缓存和sessionFactory二级缓存.一级缓存不可卸载. 当根据ID查询数据的时候,首先从session缓存中查,查不到,如果设置了二级缓存,那么从二级缓存中查, 如果都查不到,再查数据库.将查到的数据按照ID放入缓存中,在删除,更新,增加数据的时候更新缓存.
hibernate 对象有哪些状态? Hibernate对象有三种状态
Transient 瞬时态, 此时对象刚new出来,还没有save()
Persistent 持久态, 调用了save方法或者游离态的对象调用了update方法后会变成持久态 如果对象是持久化对象时,那么对该对象的任何修改,都会在提交事务时才会与之进行比较
当调用了session.clear()方法,以后 对象就会变成游离态
在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?
采用getCurrentSession()获得的session会绑定到当前线程,而openSession则不会
getCurrentSession()获得的session在commit或者rollback后会自动关闭,而openSession必须手动关闭
hibernate 实体类必须要有无参构造函数吗?为什么? 必须要有,以为hibernate是通过反射的方式来获得对象实例的,此时会调用默认的无参构造.
mybatis 中 #{}和 ${}的区别是什么?
前者会将传入的数据当成字符串,在之前加入双引号,后者是直接将数据显示在sql中
前者会当做占位符,防sql注入,后者不能
mybatis 有几种分页方式? 两种,一种是内存分页,一种是物理分页 内存分页: 一次性查询出所有满足条件的数据,临时保存在集合中,通过List的subList的方式获取分页数据. 物理分页: 借助sql进行分页或者利用拦截器分页
RowBounds 是一次性查询全部结果吗?为什么? 不是,因为mybatis是对JDBC的封装,在JDBC的驱动中有一个Fetch Size的配置,它规定了每次最多从数据库查询多少条数据.这样做可以防止内存溢出.
mybatis 逻辑分页和物理分页的区别是什么?
逻辑分页一次性查询很多数据,然后再结果中检索分页的数据,消耗内存.
物理分页是从数据库查询指定条数的数据.
mybatis 是否支持延迟加载?延迟加载的原理是什么? 支持,在配置文件的标签中设置就可以激活 原理: 在调用的时候出发加载,而不是在初始化的时候加载信息.如a.getB().getName(),如果a.getB()的值为null,会触发保存好的关联B对象的sql语句查询出B,然后再调用getName().
说一下 mybatis 的一级缓存和二级缓存?
一级缓存是SqlSession级别的,在一个sqlsession中,第一次查询缓存中是否有数据,没有就会查询数据库,并将数据保存在一级缓存中.第二次去查的时候会直接从缓存中查询.如果这中间sqlsession进行了commit操作则会清空缓存.
二级缓存是Mapper级别的,多个sqlsession共享,默认关闭.它基于Mapper文件的namespace,如果两个mapper的namespace相同,那么会共享缓存的数据.使用二级缓存要在配置文件中开启,并且序列化po类.
mybatis 和 hibernate 的区别有哪些?
mybatis灵活,可以写sql,hibernate学习困难
mybatis 有哪些执行器(Executor)?
SimpleExecutor:每执行一次 update 或 select 就开启一个 Statement 对象,用完立刻关闭 Statement 对象
ReuseExecutor:执行update或select以SQL作为key查找Statement对象,存在就使用,不存在就创建,用完后不关闭,可以重复使用
BatchExecutor:执行update(没有select,jdbc批处理不支持select)时,将所有SQL都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象.
mybatis 分页插件的实现原理是什么? 分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的SQL,然后重写SQL,根据dialect方言,添加对应的物理分页语句和参数
mybatis 如何编写一个自定义插件? 只需实现Interceptor接口,并指定要拦截的方法签名 @Intercepts({ @Signature( type=Executor.class,method=“update”,args={ MappedStatement.class,Object.class })}) public class ExamplePlugin implements Interceptor { public Object intercept(Invocation invocation) throws Throwable { //自定义实现 return invocation.proceed(); } public Object plugin(Object target){ return Plugin.wrap(target,this) } public void setProperties(Properties properties){ //传入配置项 String size = properties.getProperty(“size”); } }
<!-- mybatis-config.xml --> <plugins> <plugin interceptor="org.mybatis.example.ExamplePlugin"> <!-- 这里的配置项就传入setProperties方法中 --> <property name="size" value="100"> </plugin> </plugins>