今年的行情,让招聘面试变得雪上加霜。已经有不少大厂,如腾讯、字节跳动的招聘名额明显减少,面试门槛却一再拔高,如果不用心准备,很可能就被面试官怼得哑口无言,甚至失去了难得的机会。
现如今,情势依然严峻,未来充满着不定性,想要跳槽涨薪的小伙伴,在面试前更是要做好充足的准备!
如果你参加过一些大厂面试,肯定会遇到一些这样的问题:
- 应届生:你该如何准备简历,面试项目和面试说辞?Spring 底层逻辑是什么?
- 1-3 年经验的程序员:面试中你该讲哪些值钱的技术?如何用这些值钱的技术最大程度展示自己的技能?分布式组件底层逻辑是什么?
- 3-5 年经验的程序员:k8s 怎么搭建实践?
是不是看上去很难,是不是和自己准备的“题库”中的问题不一样?不知道从何处下手?
所以,要想在这个环境下拿下心仪的Offer,咱就一定要做好准备,把那些必考点、套路都给吃透了!
今天为大家整理了Java工程师高级面试题及一些大厂Java开发面试宝典,面试经验技巧等,应届生,实习生,企业工作过的,都可参考学习,需要完整的朋友可以在文末获取
- 专题一:JavaOOP 面试题
- 专题二:Java 集合/泛型面试题
- 专题三:Java 中的 IO 与 NIO 面试题
- 专题四:Java 反射面试题
- 专题五:Java 序列化面试题
- 专题六:Java 注解面试题
- 专题七:多线程 &并发面试题
- 专题八:JVM 面试题
- 专题九:Mysql 面试题
- 专题十:Redis 面试题
- 专题十一:Memcached 面试题
- 专题十二:MongoDB 面试题
- 专题十三:Spring 面试题
- 专题十四:Spring Boot 面试题
- 专题十五:Spring Cloud 面试题
- 专题十六:RabbitMQ 面试题
- 专题十七:Dubbo 面试题
- 专题十八:MyBatis 面试题
- 专题十九:ZooKeeper 面试题
- 专题二十:数据结构面试题
- 专题二十一:算法面试题
- 专题二十二:Elasticsearch 面试题
- 专题二十三:Kafka 面试题
- 专题二十四:微服务面试题
- 专题二十五:Linux面试题
1、面向对象编程(OOP)有哪些优点?
- 代码开发模块化,更易维护和修改。
- 代码复用。
- 增强代码的可靠性和灵活性。
- 增加代码的可理解性。
2、面向对象编程有哪些特性?
封装、继承、多态、抽象
封装
封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法来改变它内部的数据。在Java当中,有3种修饰符:public,private和protected。每一种修饰符给其他的位于同一个包或者不同包下的对象赋予了不同的访问权限。
下面列出了使用封装的好处:
- 通过隐藏对象的属性来保护对象内部的状态。
- 提高了代码的可用性和可维护性,因为对象的行为可以被单独的改变或者是扩展。
- 禁止对象之间的不良交互提高模块化。
继承
继承给对象提供了从基类获取字段和方法的能力。继承提供了代码的重用,也可以在不修改类的情况下给现存的类添加新特性。
多态
多态是编程语言给不同的底层数据类型做相同的接口展示的一种能力。一个多态类型上的操作可以应用到其他类型的值上面。
抽象
抽象是把想法从具体的实例中分离出来的步骤,因此,要根据他们的功能而不是实现细节来创建类。Java支持创建只暴露接口而不包含方法实现的抽象的类。这种抽象技术的主要目的是把类的行为和实现细节分离开。
3、什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?
Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。
Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。
4、JDK和JRE的区别是什么?
JRE(Java运行时环境) 是将要执行Java程序的Java虚拟机。它同时也包含了执行applet需要的浏览器插件。JDK(Java开发工具包) 是完整的Java软件开发包,包含了JRE,编译器和其他的工具(比如:JavaDoc,Java调试器),可以让开发者 开发、编译、执行Java应用程序。
5、”static”关键字是什么意思?Java中是否可以覆盖(override) 一个private或者是static的方法?
“static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例的情况下被访问。
Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。
6、是否可以在static环境中访问非static变量?
不可以。static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。
7、Java支持的数据类型有哪些?什么是自动拆装箱?
Java支持的基本数据类型有:
- byte
- short
- int
- long
- float
- double
- boolean
- char
自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer。反之就是自动拆箱。
8、Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?
方法覆盖是说子类重新实现父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。
方法重载发生在同一个类里面,两个或者是多个方法的方法名相同但是参数列表不同。
9、Java中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?
当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一个默认的构造函数。
Java中构造函数重载和方法重载很相似。可以为一个类创建多个构造函数。每一个构造函数必须有它自己唯一的参数列表。
Java不支持像C++那样的复制构造函数,这个不同点是因为如果你不自己写构造函数的情况下,Java不会创建默认的复制构造函数。
10、Java支持多继承么?
不支持,Java不支持多继承。每个类都只能继承一个类,但是可以实现多个接口。
11、抽象类和接口的区别是什么?
Java支持创建抽象类和接口。它们的区别在于:
- 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
- 类可以实现很多个接口,但是只能继承一个抽象类
- 类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,在这种情况下,类也必须得声明成是抽象的。
- 抽象类在实现接口时,可以不实现接口里面的方法。
- Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
- Java接口中的成员方法默认是public的。抽象类的成员方法可以是private,protected或者是public。
- 接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。
12、什么是值传递?什么是引用传递?
对象被值传递,意味着传递了对象的一个副本。因此,就算是改变了对象副本,也不会影响源对象的值。
对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的改变会反映到所有的对象上。
13、进程和线程的区别是什么?
进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。
14、创建线程有几种不同的方式?你喜欢哪一种?为什么?
创建线程有以下几种方式:
- 继承Thread类
- 实现Runnable接口
- 应用程序可以使用Executor框架来创建线程池
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在已经继承了别的类的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。
15、解释一下线程的几种可用状态
线程可以处于以下几种状态:
- 就绪(Runnable):线程准备运行,不一定立马就能开始执行。
- 运行中(Running):程序正在执行线程的代码。
- 等待中(Waiting):线程处于阻塞的状态,等待外部的处理结束。
- 睡眠中(Sleeping):线程被强制睡眠。
- I/O阻塞(Blocked on I/O):等待I/O操作完成。
- 同步阻塞(Blocked on Synchronization):等待获取锁。
- 死亡(Dead):线程完成了执行。
16、同步方法和同步代码块的区别是什么?
同步方法就是在方法前加关键字synchronized,然后被同步的方法一次只能有一个线程进入,其他线程等待。
而同步代码块则是在方法内部使用大括号使得一个代码块得到同步。同步块会有一个锁定的“对象”。同步代码块的同步范围更加准确。
17、在监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?
监视器和锁在Java虚拟机中是一起使用的。监视器监视同步代码块,确保一次只有一个线程执行同步代码块。每一个监视器都和一个对象引用相关联。线程在获取锁之前不允许执行同步代码。
18、什么是死锁(deadlock)?
两个线程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是两个线程都陷入了无限的等待中。
19、如何确保N个线程可以访问N个资源同时又不导致死锁?
使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。
20、Java集合类框架的基本接口有哪些?
Java集合类里面最基本的接口有:
- Collection:代表一组对象,每一个对象都是它的子元素。
- Set:不包含重复元素的Collection。
- List:有顺序的Collection,并且可以包含重复元素。
- Map:可以把键(key)映射到值(value)的对象,键不能重复。
21、为什么集合类没有实现Cloneable和Serializable接口?
克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。
22、什么是迭代器(Iterator)?
Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的迭代方法。迭代器可以在迭代的过程中删除底层集合的元素。
23、Iterator和ListIterator的区别是什么?
他们的区别如下:
- Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
- Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
- ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
24、快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
Iterator的安全失败是基于对底层集合做拷贝,因此,它不受源集合上修改的影响。java.util包下面的所有的集合类都是快速失败的,而java.util.concurrent包下面的所有的类都是安全失败的。快速失败的迭代器会抛出ConcurrentModificationException异常,而安全失败的迭代器永远不会抛出这样的异常。
25、Java中的HashMap的工作原理是什么?
Java中的HashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode()和equals()方法来向集合添加元素和从集合检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合中合适的索引上。如果key已经存在了,value会被更新成新值。
26、hashCode()和equals()方法的重要性体现在什么地方?
Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。如果没有正确的实现这两个方法,两个不同的键可能会有相同的hash值,因此,可能会被集合认为是相等的。而且,这两个方法也用来发现重复元素。所以这两个方法的实现对HashMap的精确性和正确性是至关重要的。
27、HashMap和Hashtable有什么区别?
HashMap和Hashtable都实现了Map接口,他们有以下不同点:
- HashMap允许键和值是null,而Hashtable不允许键或者值是null。
- Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
- HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。
28、数组(Array)和列表(ArrayList)有什么区别?什么时候应该使用Array而不是ArrayList?
Array 和ArrayList 有以下的不同点:
- Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
- Array大小是固定的,ArrayList的大小是动态变化的。
- ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
对于基本类型数据,ArrayList 使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢,这时候应该使用Array。
29、ArrayList和LinkedList有什么区别?
ArrayList和LinkedList 有以下的不同点:
- ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。而 LinkedList是以链表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
- 相对于ArrayList,LinkedList的插入、添加、删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
- LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
30、Comparable和Comparator接口是干什么的?列出它们的区别。
Java提供了只包含一个compareTo()方法的Comparable接口。这个方法可以个给两个对象排序。具体来说,它返回负数,0,正数来表明输入对象小于,等于,大于已经存在的对象。
Java提供了包含compare()和equals()两个方法的Comparator接口。compare()方法用来给两个输入参数排序,返回负数,0,正数表明第一个参数是小于,等于,大于第二个参数。equals()方法需要一个对象作为参数,它用来决定输入参数是否和Comparator相等。只有当输入参数也是一个Comparator并且输入参数和当前Comparator的排序结果是相同的时候,这个方法才返回true。
31、什么是Java优先级队列(Priority Queue)?
PriorityQueue是一个基于优先级堆的无界队列,它的元素是按照自然顺序(natural order)排序的。在创建的时候,我们可以给它提供一个负责给元素排序的比较器。PriorityQueue不允许null值,因为他们没有自然顺序,或者说他们没有任何的相关联的比较器。最后,PriorityQueue不是线程安全的,入队和出队的时间复杂度是O(log(n))。
32、你了解大O符号(big-O notation)么?你能给出不同数据结构的例子么?
大O符号描述了当数据结构里面的元素增加的时候,算法的规模或者是性能在最坏的场景下有多么好。
大O符号也可用来描述其他的行为,比如:内存消耗。因为集合类实际上是数据结构,我们一般使用大O符号基于时间,内存和性能来选择最好的实现。大O符号可以对大量数据的性能给出一个很好的说明。
33、如何权衡是使用无序的数组还是有序的数组?
有序数组最大的好处在于查找的时间复杂度是O(log n),而无序数组是O(n)。有序数组的缺点是插入操作的时间复杂度是O(n),因为值大的元素需要往后移动来给新元素腾位置。相反,无序数组的插入时间复杂度是常量O(1)。
34、Java集合类框架的最佳实践有哪些?
根据应用的需要正确选择要使用的集合的类型对性能非常重要,比如:元素的大小是固定的,而且能事先知道,我们就应该用Array而不是ArrayList。
有些集合类允许指定初始容量。因此,如果我们能估计出存储的元素的数目,我们可以设置初始容量来避免重新计算hash值或者是扩容。
为了类型安全,可读性和健壮性的原因总是要使用泛型。同时,使用泛型还可以避免运行时的ClassCastException。
使用JDK提供的不变类(immutable class)作为Map的键可以避免为我们自己的类实现hashCode()和equals()方法。
编程的时候接口优于实现。
底层的集合实际上是空的情况下,返回长度是0的集合或者是数组,不要返回null。
35、Enumeration接口和Iterator接口的区别有哪些?
Enumeration速度是Iterator的2倍,同时占用更少的内存。但是,Iterator远远比Enumeration安全,因为其他线程不能够修改正在被iterator遍历的集合里面的对象。同时,Iterator允许调用者删除底层集合里面的元素,这对Enumeration来说是不可能的。
36、HashSet和TreeSet有什么区别?
HashSet是由一个hash表来实现的,因此,它的元素是无序的。add(),remove(),contains()方法的时间复杂度是O(1)。
TreeSet是由一个树形的结构来实现的,它里面的元素是有序的。因此,add(),remove(),contains()方法的时间复杂度是O(logn)。
37、Java中垃圾回收(GC)有什么目的?什么时候进行垃圾回收?
垃圾回收(GC)的目的是识别并且丢弃应用不再使用的对象来释放和重用资源。
38、System.gc()和Runtime.gc()会做什么事情?
这两个方法用来提示JVM要进行垃圾回收。但是,立即开始还是延迟进行垃圾回收是取决于JVM的。
39、finalize()方法什么时候被调用?析构函数(finalization)的目的是什么?
在释放对象占用的内存之前,垃圾收集器会调用对象的finalize()方法。一般建议在该方法中释放对象持有的资源。
40、如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存?
不会,在下一个垃圾回收周期中,这个对象将是可被回收的。
41、Java堆的结构是什么样子的?什么是堆中的永久代(Perm Gen space)?
JVM的堆是运行时数据区,所有类的实例和数组都是在堆上分配内存。它在JVM启动的时候被创建。对象所占的堆内存是由自动内存管理系统也就是垃圾收集器回收。
堆内存是由存活和死亡的对象组成的。存活的对象是应用可以访问的,不会被垃圾回收。死亡的对象是应用不可访问尚且还没有被垃圾收集器回收掉的对象。一直到垃圾收集器把这些对象回收掉之前,他们会一直占据堆内存空间。
42、串行(serial)收集器和吞吐量(throughput)收集器的区别是什么?
吞吐量收集器使用并行版本的新生代垃圾收集器,它用于中等规模和大规模数据的应用程序。而串行收集器对大多数的小应用(在现代处理器上需要大概100M左右的内存)就足够了。
43、在Java中,对象什么时候可以被垃圾回收?
当对象对当前使用这个对象的应用程序变得不可触及的时候,这个对象就可以被回收了。
44、JVM的永久代中会发生垃圾回收么?
垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC)。如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的。这就是为什么正确的永久代大小对避免Full GC是非常重要的原因。
45、Java中的两种异常类型是什么?他们有什么区别?
Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常。不受检查的异常不需要在方法或者是构造函数上声明,就算方法或者是构造函数的执行可能会抛出这样的异常。而且不受检查的异常可以传播到方法或者是构造函数的外面。相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。
46、Java中Exception和Error有什么区别?
Exception和Error都是Throwable的子类。Exception用于用户程序可以捕获的异常情况。Error定义了不期望被用户程序捕获的异常。
47、Java 为什么是高效的 ( High Performance )?
因为 Java 使用 Just-In-Time (即时) 编译器。
把Java字节码转换成可以直接发送给处理器的指令。
48、列举出2个 IDE
Eclipse
IntelliJ IDEA
49、面向对象的特征有哪些?
- 封装
- 继承
- 多态
- 抽象
50、JDK JRE JVM?
- JDK
Java Development Kit 用作开发, 包含了JRE,编译器和其他的工具(比如: JavaDoc,Java调试器),可以让开发者开发、编译、执行Java应用程序。
- JRE
Java 运行时环境,是将要执行 Java 程序的 Java 虚拟机,可以想象成它是一个容器,JVM 是它的内容。
JRE = JVM + Java Packages Classes(like util, math, lang, awt, swing etc) + runtime libraries.
- JVM
Java virtual machine (Java 虚拟机) 是一个可以执行 Java 编译产生的 Java class 文件 (bytecode) 的虚拟机进程,是一个纯的运行环境。
51、什么是对象 (Object)?
- 对象是程序运行时的实体
- 它的状态存储在 fields (也就是变量)
- 行为是通过方法 (method) 实现的
- 方法上操作对象的内部的状态
- 方法是对象对对象的通信的主要手段
52、一个类是由哪些变量构成的?
- 本地变量:在方法体,构造体内部定义的变量,在方法结束的时候就被摧毁
- 实例变量:在类里但是不在方法里,在类被载入的时候被实例化
- 类变量:在类里但是不在方法里,加了 static 关键字,也可以叫做静态变量
53、静态变量和实例变量的区别?
- 在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
- 在程序运行时的区别:
- 实例变量属于某个对象的属性,必须创建了实例对象,才能使用这个实例变量。
- 静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就可以被使用了。
- 总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来使用。
Java 集合框架
- 说说 List,Set,Map 三者的区别?三者底层的数据结构?
- 有哪些集合是线程不安全的?怎么解决呢?
- 比较 HashSet、LinkedHashSet 和 TreeSet 三者的异同
- HashMap 和 Hashtable 的区别?HashMap 和 HashSet 区别?HashMap 和 TreeMap 区别?
- HashMap 的底层实现
- HashMap 的长度为什么是 2 的幂次方
- ConcurrentHashMap 和 Hashtable 的区别?
- ConcurrentHashMap 线程安全的具体实现方式/底层具体实现
Java 并发(进阶)
- 什么是线程和进程?线程与进程的关系,区别及优缺点?
- 为什么要使用多线程呢?
- 什么是上下文切换?
- 什么是线程死锁?如何避免死锁?
- 乐观锁和悲观锁了解么?如何实现乐观锁?
- 说说
sleep()方法和wait()方法区别和共同点? - 讲一下 JMM(Java 内存模型)。
volatile关键字解决了什么问题?说说synchronized关键字和volatile关键字的区别。 - Java 内存区域和 JMM 有何区别?
- happens-before 原则
synchronized关键字的作用synchronized和ReentrantLock的区别synchronized和volatile的区别。synchronized关键字的底层原理ThreadLocal关键字的作用,内存泄露问题- 线程池有什么用?为什么不推荐使用内置线程池?
- Java 线程池有哪些参数?阻塞队列有几种?拒绝策略有几种?
- 线程池处理任务的流程了解吗?
- 实现
Runnable接口和Callable接口的区别。 - 如何给线程池命名?为什么建议给线程池命名?
- 如何动态修改线程池参数?
- AQS 的作用是什么/为什么要有 AQS?
- AQS 组件有哪些?
- AQS 原理了解么?
Semaphore有什么用?原理是什么?CountDownLatch有什么用?原理是什么?CyclicBarrier有什么用?原理是什么?- 多个任务的编排可以怎么做?项目用到了
CompletableFuture吗?
JVM(进阶)
- 运行时数据区中包含哪些区域?哪些线程共享?哪些线程独享?哪些区域可能会出现
OutOfMemoryError?哪些区域不会出现OutOfMemoryError? - 方法区和永久代的关系
- 栈中存放什么数据,堆中呢?
- 为什么要将永久代 (PermGen) 替换为元空间 (MetaSpace) 呢?
- 字符串常量池在什么位置(JDK1.7 之前在永久代,JDK1.7 在堆)?JDK 1.7 为什么要将字符串常量池移动到堆中?
- 堆空间的基本结构了解吗?什么情况下对象会进入老年代?
- 大对象放在哪个内存区域?
- 直接内存有什么用?如何使用?
- Java 对象的创建过程(五步,建议能默写出来并且要知道每一步虚拟机做了什么)
- 对象的访问定位的两种方式(句柄和直接指针两种方式)
- 为什么需要GC?
- 有哪些常见的 GC?谈谈你对 Minor GC、还有 Full GC 的理解。Minor GC 与 Full GC 分别在什么时候发生? Minor GC 会发生 stop the world 现象吗?
- 如何判断对象是否死亡(引用计数法和可达性分析算法两种方法)?
- 讲一下可达性分析算法的流程。 哪些对象可以作为 GC Roots 呢?
- 如何判断一个常量是废弃常量?如何判断一个类是无用的类?
- 垃圾收集有哪些算法,各自的特点?
- 默认的垃圾回收器是哪一个?ZGC 了解吗?
- 讲一下 CMS 垃圾收集器的四个步骤。CMS 有什么缺点?
- 并发标记要解决什么问题?并发标记带来了什么问题?如何解决并发扫描时对象消失问题?
- G1 垃圾收集器的步骤。有什么缺点?
- JVM 中的安全点和安全区各代表什么?
- 什么是类加载?何时类加载?类加载流程?
- 知道哪些类加载器。类加载器之间的关系?
- 类加载器的双亲委派了解么? 结合 Tomcat 说一下双亲委派(Tomcat 如何打破双亲委托机制?...)。
- 为什么需要双亲委派?
- 堆内存相关的 JVM 参数有哪些?你在项目中实际配置过了吗?
- 你在项目中遇到过 GC 问题吗?怎么分析和解决的?
- 如何降低 Full GC 的频率?
- 项目中实践过 JVM 调优吗?怎么做的?
- 线上 CPU 飙升怎么排查?
数据库
MySQL
MySQL 存储引擎
- MySQL 支持哪些存储引擎?默认使用哪个?
- MyISAM 和 InnoDB 有什么区别?
MySQL 事务
- 事务的四大特性了解么?
- 并发事务带来了哪些问题?不可重复读和幻读有什么区别?
- MySQL 事务隔离级别?默认是什么级别?
- MySQL 的隔离级别是基于锁实现的吗?
- InnoDB 对 MVCC 的具体实现
MySQL 字段类型
- char 和 varchar 的区别是什么?
- varchar(100)和 varchar(10)的区别是什么?
- decimal 和 float/double 的区别是什么?存储金钱应该用哪一种?
- 为什么不推荐使用 text 和 blob?
MySQL 索引
- 为什么索引能提高查询速度?
- 聚集索引和非聚集索引的区别?非聚集索引一定回表查询吗?
- 索引这么多优点,为什么不对表中的每一个列创建一个索引呢?(使用索引一定能提高查询性能吗?)
- 索引底层的数据结构了解么?Hash 索引和 B+树索引优劣分析
- B+树做索引比红黑树好在哪里?
- 最左前缀匹配原则了解么?
- 什么是覆盖索引
- 如何查看某条 SQL 语句是否用到了索引?
MySQL 锁
- 表级锁和行级锁有什么区别?
- 哪些操作会加表级锁?哪些操作会加行级锁?请简单举例说一下。
- InnoDB 有哪几类行锁?
- Next-Key Lock 的加锁范围?
- 当前读和快照读有什么区别?
- MySQL 如何使用乐观锁和悲观锁?
MySQL 日志
- MySQL 中常见的日志有哪些?
- 慢查询日志有什么用?
- binlog 主要记录了什么?
- redo log 如何保证事务的持久性?
- 页修改之后为什么不直接刷盘呢?
- binlog 和 redolog 有什么区别?
- undo log 如何保证事务的原子性?
- ……
MySQL 性能优化
- 能用 MySQL 直接存储文件(比如图片)吗?
- MySQL 如何存储 IP 地址?
- 如何分析 SQL 的性能?
- 有哪些常见的 SQL 优化手段?
- 简单说一下大表优化的思路。
- 读写分离如何实现?
- 为什么要分库分表?有哪些常见的分库分表工具?
- 深度分页如何优化?
- 数据冷热分离如何做?
- 常见的数据库优化方法有哪些?
Redis
Redis 基础
- Redis 为什么这么快?
- 分布式缓存常见的技术选型方案有哪些?说一下 Redis 和 Memcached 的区别和共同点
- 本地缓存和分布式缓存有什么区别?如何选择?
- 说一下有缓存情况下查询数据和修改数据的流程。
- 常见的缓存读写策略有哪些?
- 什么是 Redis Module?有什么用?项目使用过吗?
Redis 应用
- Redis 除了做缓存,还能做什么?
- 如何基于 Redis 实现分布式锁?
- Redis 可以做消息队列么?
- Redis 可以做搜索引擎么?
Redis 数据结构
- Redis 有哪些数据结构?
- String 的底层实现是什么?为什么实现了 SDS?
- Redis 为什么用跳表,而不用平衡树、红黑树或者B+树?
- Redis为什么使用 ListPack 替代 ZipList?
- Zset 的应用场景是什么?项目哪里用到了?
Redis 持久化机制
- 宕机了,Redis 如何避免数据丢失?
- 如何选择 RDB 和 AOF?
Redis 线程模型
- Redis 是单线程,那怎么监听大量的客户端连接呢?
- Redis6.0 之前为什么不使用多线程?
- Redis6.0 之后为何引入了多线程?
Redis 内存管理
- Redis 给缓存数据设置过期时间有啥用? Redis 是如何判断数据是否过期的呢?过期数据是如何被删除的?
- Redis 内存满了怎么办?
- Redis 内存淘汰算法除了 LRU 还有哪些?
Redis 事务
- Redis 事务支持原子性吗?
- Redis 事务支持持久性吗?
- Redis 事务有什么缺陷?如何解决?
Redis 性能优化
- Redis 批量操作的方式有哪些?
- Redis 大 key 有什么危害?如何排查和处理?
- 如何发现 Redis 热 Key,有哪些解决方案?
- 为什么会有 Redis 内存碎片?如何清理 Redis 内存碎片?
- 为什么会有慢查询命令?为什么会有慢查询命令?
Redis 生产问题
- 什么情况会出现缓存穿透?有哪些解决办法?
- 什么情况会出现缓存击穿?有哪些解决办法?
- 什么情况会出现缓存雪崩?有哪些解决办法?
- 缓存穿透和缓存击穿有什么区别?缓存雪崩和缓存击穿有什么区别?
- 缓存预热如何实现?
Redis 集群
- 什么是 Sentinel? 有什么用?
- Sentinel 如何检测节点是否下线?主观下线与客观下线的区别?
- Sentinel 是如何实现故障转移的?
- Sentinel 如何选择出新的 master(选举机制)?
- 如何从 Sentinel 集群中选择出 Leader ?
- Sentinel 可以防止脑裂吗?
- 为什么需要 Redis Cluster?解决了什么问题?有什么优势?
- Redis Cluster 是如何分片的?
- 为什么 Redis Cluster 的哈希槽是 16384 个?
- 如何确定给定 key 的应该分布到哪个哈希槽中?
- Redis Cluster 支持重新分配哈希槽吗?
- Redis Cluster 扩容缩容期间可以提供服务吗?
- Redis Cluster 中的节点是怎么进行通信的?
ES
- 项目中用 ES 做了什么?ES 可以帮助我们做什么?
- Lucene 是什么?为什么不直接用 Lucene?
- 为什么用 ES 不用 MySQL?(两者应用场景不同)
- 为什么用 ES 不用 Hbase?(两者应用场景不同)
- 为什么 ES 检索比较快?倒排索引和正排索引是什么?倒排索引由什么组成?两者区别是什么?
- 分词器什么用?项目用的是什么分词器?如果我们要基于拼音搜索应该如何做?
- 项目中 ES 和 MySQL 的数据是如何进行同步的?
- ES 集群中的数据是如何被分配的(分片)?自定义路由有什么好处?
TCP 与 UDP
- TCP 的三次握手与四次挥手的内容? TCP 为什么连接是三次握手而断开是四次握手?
- TCP 与 UDP 的区别及使用场景?
- 为什么 DNS 协议使用 UDP?只使用了 UDP 吗?
- TCP 是如何保证传输的可靠性?(里面涉及到的知识点非常多,每个都能挖掘不少问题,例如重传机制、流量控制、拥塞控制。如果目标是大厂的话,一定要吃透,面试经常会问的)
- 使用 TCP 的协议有哪些?使用 UDP 的协议有哪些?HTTP 基于 TCP 还是 UDP?
HTTP
- HTTP 状态码有哪些?
- 一次完整的 HTTP 请求所经的步骤
- HTTP 协议了解么?HTTP 是基于 TCP 还是 UDP 的?
- HTTP 报文的内容简单说一下! HTTP 请求报文和响应报文中有哪些数据?
- HTTP 和 HTTPS 的区别了解么?
- HTTPS 的安全性体现在什么方面?(本质还是在问 HTTPS 原理)
- HTTPS 加密过程是怎么样的?
- HTTP/1.0 和 HTTP/1.1 有什么区别?
- HTTP/1.1 和 HTTP/2.0 有什么区别?
- HTTP/2.0 和 HTTP/3.0 有什么区别?
- HTTP 长连接和短连接了解么?
- Cookie 和 Session 的关系
- URI 和 URL 的区别是什么?
- GET 和 POST 的区别?
DNS
- DNS 是什么?解决了什么问题?
- DNS 能解析端口吗?
- DNS 服务器有哪些?
- DNS 解析的过程是什么样的?
- DNS 劫持了解吗?如何应对?
进程和线程
- 进程和线程的区别
- 进程有哪几种状态?
- 进程间的通信方式
- 线程间的同步的方式
- PCB
- 进程的调度算法
死锁
- 什么是死锁?
- 能列举一个操作系统发生死锁的例子吗?
- 死锁的四个必要条件,解决死锁的方法
内存管理
- 常见的内存管理机制
- 内存碎片
- 分段机制和分页机制的区别和共同点
- 分段机制和分页机制下的地址翻译过程分别是怎样的
- 单级页表有什么问题?为什么需要多级页表?
- TLB 有什么用?使用 TLB 之后的地址翻译流程是怎样的?
- 页缺失,常见的页面置换算法有哪些?
文件系统
- 硬链接和软链接有什么区别?
- 硬链接为什么不能跨文件系统?
- 提高文件系统性能的方式有哪些?
- 常见的磁盘调度算法有哪些?
算法和数据结构
- 写出三种单例模式的实现?你推荐哪一种?
- LRU 算法了解吗?你能实现一个吗?
- 写排序算法(快排、堆排)
- 使用数组实现一个栈
- 使用数组实现一个队列
- 实现一个链表、反转链表
- 加权轮询算法实现
- 实现一个死锁
- 生产者和消费者实现
- ……
数据结构
- 数组 vs 链表
- 栈的应用场景
- 队列的分类、应用场景
- 红黑树的特点、红黑树 vs 二叉查找树
- 哈希表应用场景
- 布隆过滤器应用场景
- ……
设计模式
- 设计模式是什么?有哪些常见的设计模式?
- 你的项目用到了哪些设计模式?能简单讲讲吗?(我在考察设计模式时,最喜欢问的就是这个问题)
- 单例模式了解么?说一下单例模式的使用场景。手写一个单例模式的实现。
- 观察者模式了解么?说一下观察者模式的使用场景。
- 工厂模式了解么?说一下工厂模式的使用场景。
- 简单工厂模式、工厂方法模式和抽象工厂模式有何区别?
- 链式处理适合哪种设计模式?(责任链模式)
- 哪些开源项目(Netty、MyBatis ...)中用到了责任链模式?怎么用的?
- SOLID 原则了解么?简单谈谈自己对于单一职责原则和开闭原则的理解。
- 阅读 Spring 源码的时候什么设计模式最让你影响深刻?能简单讲讲吗?
Spring/Spring Boot
- 什么是 Spring 框架?为什么要用?
- 列举一些重要的 Spring 模块?
- 谈谈自己对于 Spring IoC 的理解
- 什么是 Spring Bean?
- Bean 的作用域有哪些? Bean 是线程安全的吗?
- Spring Bean 的生命周期说一下
BeanDefinition的作用?BeanDefinition中的懒加载是什么?@Autowired和@Resource的区别是什么?- 注入 Bean 的方式有哪些?你的项目是构造函数注入还是 Setter 注入?
- 拦截器和过滤器了解么?
- Spring AOP 有什么用?你的项目哪里用到了 AOP?
- Spring 读取配置信息可以用什么注解?
- Spring 的事务管理了解吗?
@Transactional注解有什么用?你的项目是如何使用的? - Spring 循环依赖了解吗,怎么解决(三级缓存要吃透)?SpringBoot 允许循环依赖发生么?
@Lazy能解决循环依赖吗? - Spring MVC包含哪些组件?当收到请求时的处理流程是什么样的?
- Spring, SpringMVC 和 SpringBoot 的区别
- 说出使用 Spring Boot 的主要优点
- 什么是 Spring Boot Starter?
- 介绍一下
@SpringBootApplication注解 - Spring Boot 的自动配置是如何实现的?
- Spring Boot 支持哪些嵌入式 Web 容器?默认用的是哪个?
- SpringBoot 如何实现定时任务?
Netty
- BIO,NIO 和 AIO 有啥区别?
- Netty 是什么?为啥不直接用 NIO 呢?
- 为什么要用 Netty?Netty 应用场景了解么?
- 介绍一下 Netty 的核心组件?
- Bootstrap 和 ServerBootstrap 了解么?
- NioEventLoopGroup 默认的构造函数会起多少线程?
- Netty 线程模型了解么?
- 什么是 TCP 粘包/拆包?有什么解决办法呢?
- Netty 长连接、心跳机制了解么?
RPC 基础:
- 了解 RPC 吗?有哪些常见的 RPC 框架?
- 如果让你自己设计 RPC 框架你会如何设计?
- 服务之间的调用为啥不直接用 HTTP 而用 RPC?
Dubbo:
- Dubbo 了解吗?
- Dubbo 的工作原理了解么?注册中心扮演了什么角色?注册中心挂了可以继续通信吗?
- Dubbo 的负载均衡策略了解么?
- Dubbo 的 SPI 机制了解么?带来了啥好处?
RocketMQ:
- RocketMQ 中的消息模型是什么?
- RocketMQ 如何实现分布式事务?
- RocketMQ 延时消息用过吗?
- RocketMQ 重试机制?
- RocketMQ 刷盘机制?
- RocketMQ 如何保证高可用?
- RocketMQ 如何保证高性能读写?
Kafka:
- Kafka 中的消息模型是什么?
- Kafka 的多副本机制了解吗?带来了什么好处?
- Zookeeper 在 Kafka 中的作用是什么?使用 Kafka 能否不引入 Zookeeper?
- Kafka 重试机制?
- Kafka 刷盘机制?
- Kafka 如何保证高可用?
- Kafka 如何保证高性能读写?
内容精选
写在最后的总结
最后想说的是,无论你是小白菜鸟,还是技术大牛,日常都不能够落下学习这件事情。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。
今天为大家整理了Java工程师高级面试题及一些大厂Java开发面试宝典,面试经验技巧等,应届生,实习生,企业工作过的,都可参考学习,需要完整的朋友可以点击下方名片获取