208道Java常见面试题
一、Java 基础
1.JDK 和 JRE 有什么区别?
JRE=JVM+各种基础类库+java类库(String\System) JDK>JRE>JVM JRE:是java运行时环境 JDK:是java开发工具包 |
2. == 和 equals 的区别是什么?
1、对象类型不同:a:equals():是超类Object中的方法。b:==:是操作符。 2、比较的对象不同:a:equals():用来检测两个对象是否相等,即两个对象的内容是否相等。b:==:用于比较引用和比较基本数据类型时具有不同的功能。 3、运行速度不同:a:equals():没有==运行速度快。b:==:运行速度要比equals()快,因为==只是比较引用。 |
3. 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
不对,两个对象的 hashCode()相同,equals()不一定 true。 |
4. final 在 java 中有什么作用?
final:作为java中的关键字可以用于三个地方。用于修饰类、类属性和类方法。特征:凡是引用final关键字的地方皆不可修改! (1)、修饰类:表示该类不能被继承。 (2)、修饰方法:表示该方法不能被重写。 (3)、修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。 |
5. java 中的 Math.round(-1.5) 等于多少?
round是四舍五入 负数5是舍的 所以Math.round(-1.5)等于-1 Math.round(1.5)值是2 |
6. String 属于基础的数据类型吗?
不是 基本数据类型包括byte、int、char、long、float、double、boolean和short。 因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类。 |
7. java 中操作字符串都有哪些类?它们之间有什么区别?
String、StringBuffer、StringBuilder String是不可变的对象,对每次对String类型的改变时都会生成一个新的对象,StringBuffer和StringBuilder是可以改变对象的。 对于操作效率:StringBuilder > StringBuffer > String 对于线程安全:StringBuffer 是线程安全,可用于多线程;StringBuilder 是非线程安全,用于单线程。 不频繁的字符串操作使用 String。反之,StringBuffer 和 StringBuilder 都优于String。 |
8. String str="i"与 String str=new String(“i”)一样吗?
不一样,因为他们不是同一个对象。 |
9. 如何将字符串反转?
有多种方法: 第一种:
第二种:
第三种:
|
10. String 类的常用方法都有那些?
从对字符常规操作来看: 增-删-改-查 删:trim subString 改:valueOf toUpperCase toLowerCase 查:length indexOf charAt startsWith endsWith |
11. 抽象类必须要有抽象方法吗?
抽象类中不一定要包含抽象方法。也就是抽象中可以没有抽象方法,反之,类中含有抽象方法,那么类必须声明为抽象类。 |
12. 普通类和抽象类有哪些区别?
抽象类不能被实例;抽象类不能有构造函数,抽象方法也不能被声明为静态;抽象类可以有抽象方法;抽象类的抽象方法必须被非抽象子类继承。 |
13. 抽象类能使用 final 修饰吗?
不能,抽象类中的抽象方法是未来继承之后的重写方法,而用final修饰的类,无法被继承。final关键字不能用来抽象类和接口。 |
14. 接口和抽象类有什么区别?
抽象类是被子类继承,接口是被类实现;接口只能做方法申明,抽象类可以做方法申明,也可以做方法实现;接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普遍变量;接口是设计的结果。抽象类是重构的结果。 |
15. java 中 IO 流分为几种?
4中:字节输入流(InputStream);字节输出流(OutputStream);字符输入流(Reader);字符输出流(Writer) |
16. BIO、NIO、AIO 有什么区别?
BIO和NIO是两种不同的网络通信模型,现如今NIO已经大量应用在Jetty、ZooKeeper、Netty等开源框架中。一个面向流、一个面向缓冲区;一个是阻塞式的、一个是非阻塞;一个没有io多路复用器、一个有io多路复用器。 |
17. Files的常用方法都有哪些?
创建: 删除: 文件夹相关: |
二、容器
18. java 容器都有哪些?
List、Set、Map |
19. Collection 和 Collections 有什么区别?
Collection是集合类的顶级接口,其派生了两个子接口Set和List。Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对象对集合元素进行排序、搜索以及线程安全等各种操作。Collection是一个接口,而Collections是个类。 |
20. List、Set、Map 之间的区别是什么?
List:a、可以允许重复对象;b、可以插入多个null元素;c、是一个有序容器。Set:a、不允许重复对象;b、只允许一个null元素;c、无序容器。Map:a、Map不是collection的子接口或实现类。Map是一个接口;b、Map的每个Entry都特有两个对象,也就是一个键一个值,Map可能会持有相同的值对象但键对象必须是唯一的;c、Map里可以拥有随意null值但最多只能有一个null键。 |
21. HashMap 和 Hashtable 有什么区别?
存储:HashMap运行key和value为null,而HashTable不允许;线程安全:HashTable是线程安全的,而HashMap是非线程安全的。 |
22. 如何决定使用 HashMap 还是 TreeMap?
对于在 Map 中插入、删除、定位一个元素这类操作,HashMap 是最好的选择,因为相对而言 HashMap 的插入会更快,但如果你要对一个 key 集合进行有序的遍历,那 TreeMap 是更好的选择。 |
23. 说一下 HashMap 的实现原理?
24. 说一下 HashSet 的实现原理?
25. ArrayList 和 LinkedList 的区别是什么?
ArrayList与LinkedList都实现了list接口;ArrayList是线程表,底层是使用数组实现的,它在尾端插入和访问数据时效率较高;LinkedList是双向链表,它在中间插入或者插入时效率较高,在访问数据时效率较低。 |
26. 如何实现数组和 List 之间的转换?
数组转list:Arrays.asList();list转数组:list.toArray() |
27. ArrayList 和 Vector 的区别是什么?
28. Array 和 ArrayList 有何区别?
Array 与 ArrayList 都是用来存储数据的集合。ArrayList 底层是使用数组实现的,但是ArrayList对数组进行了封装和功能扩展 |
29. 在 Queue 中 poll()和 remove()有什么区别?
https://blog.csdn.net/qq_36101933/article/details/83145869 |
30. 哪些集合类是线程安全的?
线程安全的集合对象:Vector、HashTable、StringBuffer 非线程安全的集合对象:ArrayList、LinkedList、HashMap、HashSet、TreeMap、TreeSet、StringBulider https://www.cnblogs.com/huangdabing/p/9249233.html |
31. 迭代器 Iterator 是什么?
Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包括了可以返回迭代器实例的迭代方法。迭代器可以在迭代过程中删除底层集合的元素,但是不可以直接调用集合的remove(Object obj)删除,可以通过迭代器的remove()方法删除 https://blog.csdn.net/qq_18433441/article/details/78223502 |
32. Iterator 怎么使用?有什么特点?
33. Iterator 和 ListIterator 有什么区别?
34. 怎么确保一个集合不能被修改?
三、多线程
35. 并行和并发有什么区别?
并发:并发在单核和多核都可存在,就是同一时间有多个可以执行的进程。但是在单核中同一时刻只有一个进程获取CPU,虽然宏观上你认为多个进程都在进行。 并行:并行是指同一时间多个进程在微观上都在真正的执行,这就只有在多核的情况下了。 |
36. 线程和进程的区别?
区别:地址空间、资源拥有
|
37. 守护线程是什么?
守护线程是个服务线程,服务于其他线程 典型案列:垃圾回收线程 |
38. 创建线程有哪几种方式?
继承Threa类创建线程;实现Runnable接口创建线程;通过Callable和Future创建线程。 |
39. 说一下 runnable 和 callable 有什么区别?
runnable没有返回值,callable可以拿到有返回值,callable可以看作是runnable的补充。 |
40. 线程有哪些状态?
创建、就绪、运行、阻塞、死亡 |
41. sleep() 和 wait() 有什么区别?
sleep()可以在任何地方使用;wait()只能在同步方法或者同步块中使用。 |
42. notify()和 notifyAll()有什么区别?
notify()是唤醒某个线程;notifyAll()是唤醒所有暂停的线程。 |
43. 线程的 run()和 start()有什么区别?
run()相当于线程的任务处理逻辑的入口方法;start()的作用是启动相应的线程。 |
44.创建线程池有哪几种方式?
线程池创建有七种方式,最核心的是最后一种:
|
45.线程池都有哪些状态?
|
46. 线程池中 submit()和 execute()方法有什么区别?
execute():只能执行Runnable类型的任务;submit():可以执行Runnable和Callable类型的任务。 |
47. 在 java 程序中怎么保证多线程的运行安全?
方法一:使用安全类,比如java.util.concurrent下的类。方法二:使用自动锁synchronized。方法三:使用手动锁Lock。
|
48. 多线程锁的升级原理是什么?
synchronized 锁升级原理:在锁对象的对象头里面有一个 threadid 字段,在第一次访问的时候 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id,再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了 synchronized 锁的升级。 锁的升级的目的:锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗。 |
49. 什么是死锁?
当线程A持有独占锁a,并尝试去获取独占锁b的同时,线程B持有独占锁b,并尝试获取获取独占锁a的情况下,就会发生AB两个线程由于相互持有对方需要的锁,而发生了阻塞的现象,称为死锁。 |
50. 怎么防止死锁?
尽量使用tryLock的方法,设置超时时间,超时可以退出防止死锁;尽量使用java.util.concurrent并发类代替自己手写锁;尽量降低锁的使用粒度,尽量不要几个功能用同一把锁;尽量减少同步的代码块。 |
51. ThreadLocal 是什么?有哪些使用场景?
ThreadLocal用于保存某个线程共享变量。使用场景:解决数据库连接,Session管理 |
52. 说一下 synchronized 底层实现原理?
synchronized 是由一对 monitorenter/monitorexit 指令实现的,monitor 对象是同步的基本实现单元。在 Java 6 之前,monitor 的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作,性能也很低。但在 Java 6 的时候,Java 虚拟机 对此进行了大刀阔斧地改进,提供了三种不同的 monitor 实现,也就是常说的三种不同的锁:偏向锁(Biased Locking)、轻量级锁和重量级锁,大大改进了其性能。 |
53. synchronized 和 volatile 的区别是什么?
|
54. synchronized 和 Lock 有什么区别?
|
55. synchronized 和 ReentrantLock 区别是什么?
synchronized 早期的实现比较低效,对比 ReentrantLock,大多数场景性能都相差较大,但是在 Java 6 中对 synchronized 进行了非常多的改进。 主要区别如下:
|
56. 说一下 atomic 的原理?
atomic 主要利用 CAS (Compare And Wwap) 和 volatile 和 native 方法来保证原子操作,从而避免 synchronized 的高开销,执行效率大为提升。 |
四、反射
57. 什么是反射?
可以将一个程序(类)在运行的时候获得该程序(类)的信息的机制,也就是获得在编译期不可能获得的类的信息,因为这些信息是保存在Class对象中的,而这个Class对象是在程序运行时动态加载的 |
58. 什么是 java 序列化?什么情况下需要序列化?
序列化就是把java对象转换为字节序列的方法。把对象的字节序列化到永久的保存到硬盘中;在网络上传递对象的字节序列。 |
59. 动态代理是什么?有哪些应用?
动态代理是运行时动态生成代理类。
|
60. 怎么实现动态代理?
JDK动态代理;cglib动态代理。 |
五、对象拷贝
61. 为什么要使用克隆?
克隆的对象可能包含一些已经修改过的属性,而 new 出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠克隆方法了。 |
62. 如何实现对象克隆?
|
63. 深拷贝和浅拷贝区别是什么?
|
六、Java Web
64. jsp 和 servlet 有什么区别?
|
65. jsp 有哪些内置对象?作用分别是什么?
Jsp共有九种内置的对象:request 用户端请求,此请求会包含来自GET/POST请求的参数;response 网页传回用户端的回应;pageContext 网页的属性是在这里管理;session 与请求有关的会话期;application servlet 正在执行的内容;out 用来传送回应的输出;config servlet的构架部件;page JSP网页本身;exception 针对错误网页,未捕捉的例外; https://www.cnblogs.com/dqh94/p/6062703.html |
66. 说一下 jsp 的 4 种作用域?
Web应用中,JSP创建的对象有一定的生命周期,也有可能被其他组件或者对象访问。对象的声明周期和可访问性称为作用域。四种范围对象作用域从小到大顺序如下:pageContext----request----session----application。 https://blog.csdn.net/qq208617107/article/details/51213745 |
67. session 和 cookie 有什么区别?
存储位置不同:session存储在服务器端;cookie存储在浏览器端。安全性不同:cookie安全性一般,在浏览器存储,可以被伪造和修改。容量和个数限制:cookie有容量限制,在每个站点下的cookie也有个数限制。存储多样性:session可以存储在Redis中、数据库中、应用程序中;而cookie只能存储在浏览器中。 |
68. 说一下 session 的工作原理?
session 的工作原理是客户端登录完成之后,服务器会创建对应的 session,session 创建完之后,会把 session 的 id 发送给客户端,客户端再存储到浏览器中。这样客户端每次访问服务器时,都会带着 sessionid,服务器拿到 sessionid 之后,在内存找到与之对应的 session 这样就可以正常工作了。 |
69. 如果客户端禁止 cookie 能实现 session 还能用吗?
可以用,session 只是依赖 cookie 存储 sessionid,如果 cookie 被禁用了,可以使用 url 中添加 sessionid 的方式保证 session 能正常使用。 |
70. spring mvc 和 struts 的区别是什么?
|
71. 如何避免 sql 注入?
使用预处理PreparedStatement。使用正则表达式过滤字符中的特殊字符。 |
72. 什么是 XSS 攻击,如何避免?
XSS 攻击:即跨站脚本攻击,它是 Web 程序中常见的漏洞。原理是攻击者往 Web 页面里插入恶意的脚本代码(css 代码、Javascript 代码等),当用户浏览该页面时,嵌入其中的脚本代码会被执行,从而达到恶意攻击用户的目的,如盗取用户 cookie、破坏页面结构、重定向到其他网站等。 预防 XSS 的核心是必须对输入的数据做过滤处理。 |
73. 什么是 CSRF 攻击,如何避免?
CSRF:Cross-Site Request Forgery(中文:跨站请求伪造),可以理解为攻击者盗用了你的身份,以你的名义发送恶意请求,比如:以你名义发送邮件、发消息、购买商品,虚拟货币转账等。 防御手段:
|
七、异常
74. throw 和 throws 的区别?
throw是指抛出的一个具体异常类型;throws是用来声明一个方法可能抛出的所有异常信息。 |
75. final、finally、finalize 有什么区别?
|
76. try-catch-finally 中哪个部分可以省略?
try-catch-finally 其中 catch 和 finally 都可以被省略,但是不能同时省略,也就是说有 try 的时候,必须后面跟一个 catch 或者 finally。 |
77. try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
一定会, catch 中 return会等finally中的代码执行完之后才会执行。 |
78. 常见的异常类有哪些?
|
八、网络
79. http 响应码 301 和 302 代表的是什么?有什么区别?
|
80. forward 和 redirect 的区别?
|
81. 简述 tcp 和 udp的区别?
tcp 和 udp 是 OSI 模型中的运输层中的协议。tcp 提供可靠的通信传输,而 udp 则常被用于让广播和细节控制交给应用的通信传输。 两者的区别大致如下:
|
82. tcp 为什么要三次握手,两次不行吗?为什么?
如果采用两次握手,那么只要服务器发出确认数据包就会建立连接,但由于客户端此时并未响应服务器端的请求,那此时服务器端就会一直在等待客户端,这样服务器端就白白浪费了一定的资源。若采用三次握手,服务器端没有收到来自客户端的再此确认,则就会知道客户端并没有要求建立请求,就不会浪费服务器的资源。 |
83. 说一下 tcp 粘包是怎么产生的?
tcp 粘包可能发生在发送端或者接收端,分别来看两端各种产生粘包的原因:
|
84. OSI 的七层模型都有哪些?
|
85. get 和 post 请求有哪些区别?
|
86. 如何实现跨域?
使用CORS技术;使用JSONP。 |
87. 说一下 JSONP 实现原理?
jsonp是一种轻量级的数据交换格式。 jsonp:JSON with Padding,它是利用script标签的 src 连接可以访问不同源的特性,加载远程返回的“JS 函数”来执行的。 |
九、设计模式
88. 说一下你熟悉的设计模式?
|
89. 简单工厂和抽象工厂有什么区别?
|
十、Spring/Spring MVC
90. 为什么要使用 spring?
spring是一个开源框架,是个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架
|
91. 解释一下什么是 aop?
AOP即面向切面编程,是OOP编程的有效补充。使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。 AOP分为静态AOP和动态AOP:
|
92. 解释一下什么是 ioc?
即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。 IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。 |
93. spring 有哪些主要模块?
core模块、aop模块、data access模块、web模块、test模块
|
94. spring 常用的注入方式有哪些?
构造方法注入、setter注入、基于注解注入。 https://blog.csdn.net/a909301740/article/details/78379720 |
95. spring 中的 bean 是线程安全的吗?
spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。 实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。
|
96. spring 支持几种 bean 的作用域?
singleton、prototype、request、session、globalSession五中作用域。
|
97. spring 自动装配 bean 有哪些方式?
|
98. spring 事务实现方式有哪些?
|
99. 说一下 spring 的事务隔离?
spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致:
|
100. 说一下 spring mvc 运行流程?
|
101. spring mvc 有哪些组件?
|
102. @RequestMapping 的作用是什么?
将http请求映射到相应的类/方法上。 |
103. @Autowired 的作用是什么?
@Autowired它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作,通过@Autowired的使用来消除set/get方法。 |
十一、Spring Boot/Spring Cloud
104. 什么是 spring boot?
SpringBoot是一个构建在Spring框架顶部的项目。它提供了一个更简单、更快捷的方法来设置、配置和运行简单和基于web的应用程序。 |
105. 为什么要用 spring boot?
配置简单、独立运行、自动装配、无代码生成和xml配置、提供应用监控、易上手、提升开发效率。 |
106. spring boot 核心配置文件是什么?
spring boot 核心的两个配置文件:
|
107. spring boot 配置文件有哪几种类型?它们有什么区别?
配置文件有.properties格式和.yml格式,它们主要的区别是书法风格不同。 .properties配置如下:
.yml配置如下:
|
108. spring boot 有哪些方式可以实现热部署?
|
109. jpa 和 hibernate 有什么区别?
jpa全称Java Persistence API,是Java持久化接口规范,hibernate属于jpa的具体实现。 |
110. 什么是 spring cloud?
spring cloud 是一系列框架的有序集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 spring boot 的开发风格做到一键启动和部署。 |
111. spring cloud 断路器的作用是什么?
在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。 |
112. spring cloud 的核心组件有哪些?
|
十二、Hibernate
113. 为什么要使用 hibernate?
|
114. 什么是 ORM 框架?
对象-关系映射(Object-Relational Mapping,简称ORM),面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。 |
115. hibernate 中如何在控制台查看打印的 sql 语句?
116. hibernate 有几种查询方式?
|
117. hibernate 实体类可以被定义为 final 吗?
可以将Hibernate的实体类定义为final类,但这种做法并不好。因为Hibernate会使用代理模式在延迟关联的情况下提高性能,如果你把实体类定义成final类之后,因为 Java不允许对final类进行扩展,所以Hibernate就无法再使用代理了,如此一来就限制了使用可以提升性能的手段。不过,如果你的持久化类实现了一个接口而且在该接口中声明了所有定义于实体类中的所有public的方法轮到话,你就能够避免出现前面所说的不利后果。 |
118. 在 hibernate 中使用 Integer 和 int 做映射有什么区别?
在Hibernate中,如果将OID定义为Integer类型,那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。 |
119. hibernate 是如何工作的?
|
120. get()和 load()的区别?
|
121. 说一下 hibernate 的缓存机制?
Hibernate中的缓存分为一级缓存和二级缓存。 一级缓存就是 Session 级别的缓存,在事务范围内有效是,内置的不能被卸载。二级缓存是 SesionFactory级别的缓存,从应用启动到应用结束有效。是可选的,默认没有二级缓存,需要手动开启。保存数据库后,缓存在内存中保存一份,如果更新了数据库就要同步更新。 扩展:hibernate的二级缓存默认是不支持分布式缓存的。使用 memcahe,redis等中央缓存来代替二级缓存。 |
122. hibernate 对象有哪些状态?
hibernate里对象有三种状态:
|
123. 在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?
|
124. hibernate 实体类必须要有无参构造函数吗?为什么?
hibernate中每个实体类必须提供一个无参构造函数,因为hibernate框架要使用reflection api,通过调用Classnewlnstance()来创建实体类的实例,如果没有无参的构造函数就会抛弃异常。 |
十三、Mybatis
125. mybatis 中 #{}和 ${}的区别是什么?
|
126. mybatis 有几种分页方式?
分页方式:逻辑分页和物理分页。 逻辑分页:使用MyBatis自带的RowBounds进行分页,它是一次性查询很多数据,然后在数据中进行检索。 物理分页:自己手写SQL分页或使用分页插件PageHelper,去数据库查询指定条数的分页数据形式。 |
127. RowBounds 是一次性查询全部结果吗?为什么?
RowBounds表面是在“所有”数据中检索数据,其实并非是一次性查询出所有的数据。因为MyBatis是对jdbc的封装,在jdbc驱动中有一个Fetch Size的配置,它规定了每次最多从数据库查询多少条数据,假如你要查询更多数据,它会在你执行next()的时候,去查询更多的数据。就好比你去自动取款机取10000元,但是取款机每次只能取2500元,所以你需要取4次才能把钱取完。对于jdbc来说,当你调用next()的时候会自动帮你完成查询工作。这样的好处可以有效的防止内存溢出。 |
128. mybatis 逻辑分页和物理分页的区别是什么?
|
129. mybatis 是否支持延迟加载?延迟加载的原理是什么?
MyBatis支持延迟加载,设置lazyLoadingEnabled=true即可。 延迟加载的原理是调用的时候触发加载,而不是在初始化的时候就加载信息。比如调用a.getB().getName(),这个时候发现a.get()的值为null,此时会单独触发事先保存好的关联B对象的SQL,先查询出来B,然后在调用a.setB(b),而这个时候在调用a.getB().getName()就有值了,这就是延迟加载的基本原理。 |
130. 说一下 mybatis 的一级缓存和二级缓存?
一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ; 对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。 |
131. mybatis 和 hibernate 的区别有哪些?
|
132. mybatis 有哪些执行器(Executor)?
Mybatis有三种基本的执行器(Executor): SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。 ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。 BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。 |
133. mybatis 分页插件的实现原理是什么?
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。 |
134. mybatis 如何编写一个自定义插件?
Mybatis自定义插件针对Mybatis四大对象(Executor、StatementHandler 、ParameterHandler 、ResultSetHandler )进行拦截,具体拦截方式为: Executor:拦截执行器的方法(log记录) StatementHandler :拦截Sql语法构建的处理 ParameterHandler :拦截参数的处理 ResultSetHandler :拦截结果集的处理 Mybatis自定义插件必须实现Interceptor接口:
intercept方法:拦截器具体处理逻辑方法 plugin方法:根据签名signatureMap生成动态代理对象 setProperties方法:设置Properties属性 自定义插件demo:
一个@Intercepts可以配置多个@Signature,@Signature中的参数定义如下:
|
十四、RabbitMQ
135. rabbitmq 的使用场景有哪些?
|
136. rabbitmq 有哪些重要的角色?
RabbitMQ 中重要的角色有:生产者、消费者和代理:
|
137. rabbitmq 有哪些重要的组件?
|
138. rabbitmq 中 vhost 的作用是什么?
vhost:每个RabbitMQ都能创建很多vhost,我们称之为虚拟主机,每个虚拟主机其实都是mini版的RabbitMQ,它拥有自己的队列,交换器和绑定,拥有自己的权限机制。 |
139. rabbitmq 的消息是怎么发送的?
首先客户端必须连接到 RabbitMQ 服务器才能发布和消费消息,客户端和 rabbit server 之间会创建一个 tcp 连接,一旦 tcp 打开并通过了认证(认证就是你发送给 rabbit 服务器的用户名和密码),你的客户端和 RabbitMQ 就创建了一条 amqp 信道(channel),信道是创建在“真实” tcp 上的虚拟连接,amqp 命令都是通过信道发送出去的,每个信道都会有一个唯一的 id,不论是发布消息,订阅队列都是通过这个信道完成的。 |
140. rabbitmq 怎么保证消息的稳定性?
|
141.rabbitmq 怎么避免消息丢失?
|
142. 要保证消息持久化成功的条件有哪些?
以上四个条件都满足才能保证消息持久化成功。 |
143. rabbitmq 持久化有什么缺点?
持久化的缺地就是降低了服务器的吞吐量,因为使用的是磁盘而非内存存储,从而降低了吞吐量。可尽量使用 ssd 硬盘来缓解吞吐量的问题。 |
144. rabbitmq 有几种广播类型?
三种广播模式:
|
145. rabbitmq 怎么实现延迟消息队列?
|
146. rabbitmq 集群有什么用?
集群主要有以下两个用途:
|
147. rabbitmq 节点的类型有哪些?
|
148. rabbitmq 集群搭建需要注意哪些问题?
|
149. rabbitmq 每个节点是其他节点的完整拷贝吗?为什么?
不是,原因有以下两个:
|
150. rabbitmq 集群中唯一一个磁盘节点崩溃了会发生什么情况?
如果唯一磁盘的磁盘节点崩溃了,不能进行以下操作:
唯一磁盘节点崩溃了,集群是可以保持运行的,但你不能更改任何东西。 |
151. rabbitmq 对集群节点停止顺序有要求吗?
RabbitMQ 对集群的停止的顺序是有要求的,应该先关闭内存节点,最后再关闭磁盘节点。如果顺序恰好相反的话,可能会造成消息的丢失。 |
十五、Kafka
152. kafka 可以脱离 zookeeper 单独使用吗?为什么?
kafka不能脱离zookeeper单独使用,因为kafka使用zookeeper管理和协调kafka的节点服务器。 |
153. kafka 有几种数据保留的策略?
有两种数据保存策略,按照过期时间和按照存储的消息大小。 |
154. kafka 同时设置了 7 天和 10G 清除数据,到第五天的时候消息达到了 10G,这个时候 kafka 将如何处理?
这个时候kafka会执行数据清除工作,时间和大小不论那个满足条件,都会清空数据。 |
155. 什么情况会导致 kafka 运行变慢?
1、cpu性能瓶颈 2、磁盘读写瓶颈 3、网络瓶颈 |
156. 使用 kafka 集群需要注意什么?
|
十六、Zookeeper
157. zookeeper 是什么?
zookeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 google chubby 的开源实现,是 hadoop 和 hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。 |
158. zookeeper 都有哪些功能?
|
159. zookeeper 有几种部署模式?
zookeeper 有三种部署模式:
|
160. zookeeper 怎么保证主从节点的状态同步?
zookeeper 的核心是原子广播,这个机制保证了各个 server 之间的同步。实现这个机制的协议叫做 zab 协议。 zab 协议有两种模式,分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,zab 就进入了恢复模式,当领导者被选举出来,且大多数 server 完成了和 leader 的状态同步以后,恢复模式就结束了。状态同步保证了 leader 和 server 具有相同的系统状态。 |
161. 集群中为什么要有主节点?
在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果,这样可以大大减少重复计算,提高性能,所以就需要主节点。 |
162. 集群中有 3 台服务器,其中一个节点宕机,这个时候 zookeeper 还可以使用吗?
可以继续使用,单数服务器只要没超过一半的服务器宕机就可以继续使用。 |
163. 说一下 zookeeper 的通知机制?
客户端端会对某个 znode 建立一个 watcher 事件,当该 znode 发生变化时,这些客户端会收到 zookeeper 的通知,然后客户端可以根据 znode 变化来做出业务上的改变。 |
十七、MySql
164. 数据库的三范式是什么?
|
165. 一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?
InnoDB 表只会把自增主键的最大 id 记录在内存中,所以重启之后会导致最大 id 丢失。 |
166. 如何获取当前数据库版本?
使用 select version() 获取当前 MySQL 数据库版本。 |
167. 说一下 ACID 是什么?
|
168. char 和 varchar 的区别是什么?
char(n) :固定长度类型,比如订阅 char(10),当你输入"abc"三个字符的时候,它们占的空间还是 10 个字节,其他 7 个是空字节。 chat 优点:效率高;缺点:占用空间;适用场景:存储密码的 md5 值,固定长度的,使用 char 非常合适。 varchar(n) :可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度。 所以,从空间上考虑 varcahr 比较合适;从效率上考虑 char 比较合适,二者使用需要权衡。 |
169. float 和 double 的区别是什么?
|
170. mysql 的内连接、左连接、右连接有什么区别?
内连接关键字:inner join;左连接:left join;右连接:right join。 内连接是把匹配的关联数据显示出来;左连接是左边的表全部显示出来,右边的表显示出符合条件的数据;右连接正好相反。 |
171. mysql 索引是怎么实现的?
索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。 具体来说 MySQL 中的索引,不同的数据引擎实现有所不同,但目前主流的数据库引擎的索引都是 B+ 树实现的,B+ 树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整的数据结构了,所有索引的性能也是更好的。 |
172. 怎么验证 mysql 的索引是否满足需求?
使用 explain 查看 SQL 是如何执行查询语句的,从而分析你的索引是否满足需求。 explain 语法:explain select * from table where type=1。 |
173. 说一下数据库的事务隔离?
MySQL 的事务隔离是在 MySQL. ini 配置文件里添加的,在文件的最后添加:transaction-isolation = REPEATABLE-READ 可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。 READ-UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读)。 READ-COMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读)。 REPEATABLE-READ:可重复读,默认级别,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读)。 SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。 脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。 不可重复读 :是指在一个事务内,多次读同一数据。 幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。 |
174. 说一下 mysql 常用的引擎?
InnoDB 引擎:InnoDB 引擎提供了对数据库 acid 事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行 select count(*) from table 指令的时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。 MyIASM 引擎:MySQL 的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数,于是当进行 select count(*) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。 |
175. 说一下 mysql 的行锁和表锁?
MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。
|
176. 说一下乐观锁和悲观锁?
数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次修改的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就不修改,这样就实现了乐观锁。 |
177. mysql 问题排查都有哪些手段?
|
178. 如何做 mysql 的性能优化?
|
十八、Redis
179. redis 是什么?都有哪些使用场景?
Redis是一个使用c语言开发的高速缓存数据库。 Redis使用场景:
|
180. redis 有哪些功能?
|
181. redis 和 memecache 有什么区别?
|
182. redis 为什么是单线程的?
|
183. 什么是缓存穿透?怎么解决?
缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。 解决方案:最简单粗暴的方法如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们就把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。 |
184. redis 支持的数据类型有哪些?
Redis支持的数据类型:string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。 |
185. redis 支持的 java 客户端都有哪些?
支持的java客户端有redisson、jedis、lettuce等。 |
186. jedis 和 redisson 有哪些区别?
|
187. 怎么保证缓存和数据库数据的一致性?
|
188. redis 持久化有几种方式?
Redis 的持久化有两种方式,或者说有两种策略:
|
189.redis 怎么实现分布式锁?
Redis 分布式锁其实就是在系统里面占一个“坑”,其他程序也要占“坑”的时候,占用成功了就可以继续执行,失败了就只能放弃或稍后重试。 占坑一般使用 setnx(set if not exists)指令,只允许被一个程序占有,使用完调用 del 释放锁。 |
190. redis 分布式锁有什么缺陷?
Redis 分布式锁不能解决超时的问题,分布式锁有一个超时时间,程序的执行如果超出了锁的超时时间就会出现问题。 |
191. redis 如何做内存优化?
尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。 比如你的web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面。 |
192. redis 淘汰策略有哪些?
|
193. redis 常见的性能问题有哪些?该如何解决?
|
十九、JVM
194. 说一下 jvm 的主要组成部分?及其作用?
组件的作用: 首先通过类加载器(ClassLoader)会把 Java 代码转换成字节码,运行时数据区(Runtime Data Area)再把字节码加载到内存中,而字节码文件只是 JVM 的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能 |
195. 说一下 jvm 运行时数据区?
不同虚拟机的运行时数据区可能略微有所不同,但都会遵从 Java 虚拟机规范, Java 虚拟机规范规定的区域分为以下 5 个部分:
|
196. 说一下堆栈的区别?
功能方面:堆是用来存放对象的,栈是用来执行程序的 |
197. 队列和栈是什么?有什么区别?
队列和栈都是被用来预存储数据的。 队列允许先进先出检索元素,但也有例外的情况,Deque 接口允许从两端检索元素。 栈和队列很相似,但它运行对元素进行后进先出进行检索 |
198. 什么是双亲委派模型?
在介绍双亲委派模型之前先说下类加载器。对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立在 JVM 中的唯一性,每一个类加载器,都有一个独立的类名称空间。类加载器就是根据指定全限定名称将 class 文件加载到 JVM 内存,然后再转化为 class 对象。 类加载器分类:
双亲委派模型:如果一个类加载器收到了类加载的请求,它首先不会自己去加载这个类,而是把这个请求委派给父类加载器去完成,每一层的类加载器都是如此,这样所有的加载请求都会被传送到顶层的启动类加载器中,只有当父加载无法完成加载请求(它的搜索范围中没找到所需的类)时,子加载器才会尝试去加载类 |
199. 说一下类加载的执行过程?
类装载分为以下 5 个步骤: 加载:根据查找路径找到相应的 class 文件然后导入 检查:检查加载的 class 文件的正确性 准备:给类中的静态变量分配内存空间 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。 符号引用就理解为一个标示,而在直接引用直接指向内存中的地址 初始化:对静态变量和静态代码块执行初始化工作 |
200. 怎么判断对象是否可以被回收?
一般有两种方法来判断:
|
201. java 中都有哪些引用类型?
|
202. 说一下 jvm 有哪些垃圾回收算法?
|
203. 说一下 jvm 有哪些垃圾回收器?
|
204. 详细介绍一下 CMS 垃圾回收器?
CMS 是英文 Concurrent Mark-Sweep 的简称,是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上,这种垃圾回收器非常适合。在启动 JVM 的参数加上“-XX:+UseConcMarkSweepGC”来指定使用 CMS 垃圾回收器 CMS 使用的是标记-清除的算法实现的,所以在 gc 的时候回产生大量的内存碎片,当剩余内存不能满足程序运行要求时,系统将会出现 Concurrent Mode Failure,临时 CMS 会采用 Serial Old 回收器进行垃圾清除,此时的性能将会被降低 |
205. 新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?
新生代回收器:Serial、ParNew、Parallel Scavenge 老年代回收器:Serial Old、Parallel Old、CMS 整堆回收器:G1 新生代垃圾回收器一般采用的是复制算法,复制算法的优点是效率高,缺点是内存利用率低;老年代回收器一般采用的是标记-整理的算法进行垃圾回收 |
206. 简述分代垃圾回收器是怎么工作的?
分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3 新生代使用的是复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,它的执行流程如下: 把 Eden + From Survivor 存活的对象放入 To Survivor 区 清空 Eden 和 From Survivor 分区 From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor 每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。大对象也会直接进入老生代。 老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记整理的执行算法。以上这些循环往复就构成了整个分代垃圾回收的整体执行流程 |
207. 说一下 jvm 调优的工具?
JDK 自带了很多监控工具,都位于 JDK 的 bin 目录下,其中最常用的是 jconsole 和 jvisualvm 这两款视图监控工具 jconsole:用于对 JVM 中的内存、线程和类等进行监控; jvisualvm:JDK 自带的全能分析工具,可以分析:内存快照、线程快照、程序死锁、监控内存的变化、gc 变化等 |
208. 常用的 jvm 调优的参数都有哪些?
-Xms2g:初始化推大小为 2g -Xmx2g:堆最大内存为 2g -XX:NewRatio=4:设置年轻的和老年代的内存比例为 1:4 -XX:SurvivorRatio=8:设置新生代 Eden 和 Survivor 比例为 8:2 –XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合 -XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器组合 -XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组合 -XX:+PrintGC:开启打印 gc 信息 -XX:+PrintGCDetails:打印 gc 详细信息 |