2022年Java(1~5年经验)面试题100题_第1页
2022年Java(1~5年经验)面试题100题_第2页
2022年Java(1~5年经验)面试题100题_第3页
2022年Java(1~5年经验)面试题100题_第4页
2022年Java(1~5年经验)面试题100题_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2022年Java(l~5年经验)面试题100题(一)

一、Java基础篇

1、抽象类必须要有抽象方法吗?

【仅供参考】

不需要,抽象类不一定非要有抽象方法。

示例代码:

abstractclassCat{

publicstaticvoidsayHi(){

System,out.printin("hi~");

上面代码,抽象类并没有抽象方法但完全可以正常运行。

2、Object常用方法有哪些?

【仅供参考】

Java面试经常会出现的一道题目,Object的常用方法。下面给大家整理一下。

Object常用方法有:toStringO、equals。、hashCode()、clone。等。

3、JDK/JRE/JVM三者的关系

【仅供参考】

JVM

英文名称(JavaVirtualMachine),就是我们耳熟能详的Java虚拟机。Java能够跨平台运

行的核心在于JVMo

所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。也就是说

class文件并不直接与机器的操作系统交互,而是经过虚拟机间接与操作系统交互,由虚拟机将

程序解释给本地系统执行。

针对不同的系统有不同的jvm实现,有Linux版本的jvm实现,也有Windows版本的jvm

实现,但是同一段代码在编译后的字节码是一样的。这就是Java能够跨平台,实现一次编写,

多处运行的原因所在。

JRE

英文名称(JavaRuntimeEnvironment),就是Java运行时环境。我们编写的Java程序必须要

在JRE才能运行。它主要包含两个部分,JVM和Java核心类库。

JRE是Java的运行环境,并不是一个开发环境,所以没有包含任何开发工具,如编译器和调试器

等。

如果你只是想运行Java程序,而不是开发Java程序的话,那么你只需要安装JRE即可。

JDK

第1/23页

JDK目录下有个JRE,也就是JDK中已经集成了JRE,不用单独安装JRE。

另外,JDK中还有一些好用的工具,如jinfo,jps,jstack等。

JRE=JVM+Java核心类库

JDK=JRE+Java工具+编译器+调试器

4、阐述final、finally、finalize的区别。

【仅供参考】

其实是三个完全不相关的东西,只是长的有点像。。

final如上所示。

finally:finally是对Java异常处理机制的最佳补充,通常配合try、catch使用,用于存

放那些无论是否出现异常都一定会执行的代码。在实际使用中,通常用于释放锁、数据库连接

等资源,把资源释放方法放到finally中,可以大大降低程序出错的几率。

finalize:Object中的方法,在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

finalize。方法仅作为了解即可,在Java9中该方法已经被标记为废弃,并添加新的

java.lang.ref.Cleaner,提供了更灵活和有效的方法来释放资源。这也侧面说明了,这个方法

的设计是失败的,因此更加不能去使用它。

5、JDK1.8之后有哪些新特性?

【仅供参考】

接口默认方法:Java8允许我们给接口添加一个非抽象的方法实现,只需要使用default关键

字即可

Lambda表达式和函数式接口:Lambda表达式本质上是一段匿名内部类,也可以是一段可以传

递的代码。Lambda允许把函数作为一个方法的参数(函数作为参数传递到方法中),使用

Lambda表达式使代码更加简洁,但是也不要滥用,否则会有可读性等问题,《Effective

Java》作者JoshBloch建议使用Lambda表达式最好不要超过3行。

StreamAPI:用函数式编程方式在集合类上进行复杂操作的工具,配合Lambda表达式可以方便

的对集合进行处理。Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操

作,可以执行非常复杂的查找、过滤和映射数据等操作。使用StreamAPI对集合数据进行操

作,就类似于使用SQL执行的数据库查询。也可以使用StreamAPI来并行执行操作。简而言

之,StreamAPI提供了一种高效且易于使用的处理数据的方式。

方法引用:方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法

或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。

日期时间API:Java8引入了新的日期时间API改进了日期时间的管理。

Optional类:著名的NullPointerException是引起系统失败最常见的原因。很久以前

GoogleGuava项目引入了Optional作为解决空指针异常的一种方式,不赞成代码被null检

查的代码污染,期望程序员写整洁的代码。受GoogleGuava的鼓励,Optional现在是Java8库

的一部分。

新工具:新的编译工具,如:Nashorn引擎jjs、类依赖分析器jdeps。

6、讲讲什么是泛型?

【仅供参考】

T。工开||曰TN/Cr+iPI的入立匚灶,卜4"士,/来工门士也Lt钻1AWAU来并II五期r主口口

第2/23页

java忆生7EJDA。十71H'J丁捌付1土,儿好伍止乂天他攸1TJTJ1I天1丈天生经奴。尸叨TJ失

型参数在使时具体的类型来替换。

泛型最的好处是可以提代码的复性。以List接口为例,我们可以将String、Integer等

类型放List中,如不泛型,存放String类型要写个List接口,存放Integer要写另外

个List接口,泛型可以很好的解决这个问题。

7、为什么要使用克隆?

【仅供参考】

克隆的对象可能包含一些已经修改过的属性,而new出来的对象的属性都还是初始化时候的

值,所以当需要一个新的对象来保存当前对象的“状态”就靠克隆方法了。

8、为什么不能用浮点型表示金额?

【仅供参考】

由于计算机中保存的小数其实是十进制的小数的近似值,并不是准确值,所以,千万不要在代

码中使用浮点数来表示金额等重要的指标。

建议使用BigDecimal,或者Long来表示金额。

9、说说类实例化的顺序

【仅供参考】

静态属性,静态代码块。

普通属性,普通代码块。

构造方法。

10、BIO、NIO、AI0有什么区别?

【仅供参考】

BIO:Block10同步阻塞式10,就是我们平常使用的传统10,它的特点是模式简单使用方

便,并发处理能力低。

NIO:Non10同步非阻塞10,是传统10的升级,客户端和服务器端通过Channel(通道)通

讯,实现了多路复用。

AIO:Asynchronous10是NI0的升级,也叫NI02,实现了异步非堵塞10,异步10的操作

基于事件和回调机制。

11、抽象类能使用final修饰吗?

【仅供参考】

不能,定义抽象类就是让其他类继承的,如果定义为final该类就不能被继承,这样彼此就会

产生矛盾,所以final不能修饰抽象类,编辑器也会提示错误信息:

12、两个对象的hashCode0相同,则equals()也一定为true,对吗?

【仅供参考】

不对,两个对象的hashCode()相同,equals()不一定true。

代码示例:

第3/23页

Stringstrl="通话";

Stringstr2="重地”;

System,out.printin(String,format(/zstrl:%d|str2:%d”,strl.hashCode(),str2.

hashCode()));

System,out.printin(strl.equals(str2));

执行的结果:

strl:1179395str2:1179395

false

代码解读:很显然“通话”和“重地”的hashCode0相同,然而equals()则为false,因

为在散列表中,hashCode0相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得

出键值对相等。

13、面向对象和面向过程的区别?

【仅供参考】

面向对象和面向过程是一种软件开发思想。

面向过程就是分析出解决问题所需要的步骤,然后用函数按这些步骤实现,使用的时候依次调

用就可以了。

面向对象是把构成问题事务分解成各个对象,分别设计这些对象,然后将他们组装成有完整功

能的系统。面向过程只用函数实现,面向对象是用类实现各个功能模块。

以五子棋为例,面向过程的设计思路就是首先分析问题的步骤:

1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、

判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用分别的函数来实现,问题就

解决了。

而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为:

黑白双方

棋盘系统,负责绘制画面

规则系统,负责判定诸如犯规、输赢等。

黑白双方负责接受用户的输入,并告知棋盘系统棋子布局发生变化,棋盘系统接收到了棋子的

变化的信息就负责在屏幕上面显示出这种变化,同时利用规则系统来对棋局进行判定。

14、那为什么String要设计成不可变的?

【仅供参考】

主要有以下几点原因:

线程安全。同一个字符串实例可以被多个线程共享,因为字符串不可变,本身就是线程安全

的。

支持hash映射和缓存。因为String的hash值经常会使用到,比如作为Map的键,不可变的特性

使得hash值也不会变,不需要重新计算。

出于安全考虑。网络地址URL、文件路径path、密码通常情况下都是以String类型保存,假若

String不是固定不变的,将会引起各种安全隐患。比如将密码用String的类型保存,那么它将

一直留在内存中,直到垃圾收集器把它清除。假如String类不是固定不变的,那么这个密码可

能会被改变,导致出现安全隐患。

第4/23页

字符串常量池优化。String对象创建之后,会缓存到字符串常量池中,下次需要创建同样的对

象时,可以直接返回缓存的引用。

15、重载(Overload)和重写(Override)的区别?

【仅供参考】

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现

的是运行时的多态性。

重载:一个类中有多个同名的方法,但是具有有不同的参数列表(参数类型不同、参数个数不

同或者二者都不同)。

重写:发生在子类与父类之间,子类对父类的方法进行重写,参数都不能改变,返回值类型可

以不相同,但是必须是父类返回值的派生类。即外壳不变,核心重写!重写的好处在于子类可

以根据需要,定义特定于自己的行为。

16、Java中操作字符串都有哪些类?它们之间有什么区别?

【仅供参考】

操作字符串的类有:String^StringBuffer、StringBuilder。

String和StringBuffer、StringBuilder的区别在于String声明的是不可变的对象,每次

操作都会生成新的String对象,然后将指针指向新的String对象,而StringBuffer、

StringBuilder可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好

不要使用Stringo

StringBuffer和StringBuilder最大的区别在于,StringBuffer是线程安全的,而

StringBuilder是非线程安全的,但StringBuilder的性能却高于StringBuffer,所以在单

线程环境下推荐使用StringBuilder,多线程环境下推荐使用StringBuffer。

17、final、finally、finalize有什么区别?

【仅供参考】

final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重

写、

修饰变量表示该变量是一个常量不能被重新赋值。

finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方

finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的

代码。

finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,Java中允许使

finalize。方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

18、Error和Exception区别是什么?

【仅供参考】

Error类型的错误通常为虚拟机相关错误,如系统崩溃,内存不足,堆栈溢出等,编译器不会

对这

第5/23页

类错误进行检测,JAVA应用程序也不应对这类错误进行捕获,一旦这类错误发生,通常应用程

会被终止,仅靠应用程序本身无法恢复;

Exception类的错误是可以在应用程序中进行捕获并处理的,通常遇到这种错误,应对其进行

理,使应用程序可以继续正常运行。

19、try-catch-finally中,如果catch中return了,finally还会执行吗?

【仅供参考】

finally一■定会执行,即使是catch中return了,catch中的return会等finally中的

代码执行完之后,才会执行。

20、运行时异常和一般异常(受检异常)区别是什么?

【仅供参考】

运行时异常包括RuntimeException类及其子类,表示JVM在运行期间可能出现的异常。

Java编

译器不会检查运行时异常。

受检异常是Exception中除RuntimeException及其子类之外的异常。Java编译器会检查受

检异常。

RuntimeException异常和受检异常之间的区别:是否强制要求调用者必须处理此异常,如果强

制要求调用者必须进行处理,那么就使用受检异常,否则就选择非受检异常

(RuntimeException)o一般来讲,如果没有特殊的要求,我们建议使用RuntimeException异

常。

二、Java进阶篇

1、如何决定使用llashMap还是TreeMap?

【仅供参考】

对于在Map中插入、删除、定位一个元素这类操作,HashMap是最好的选择,因为相对而言

llashMap的插入会更快,但如果你要对一个key集合进行有序的遍历,那TreeMap是更好的

选择。

2、怎么唤醒一个阻塞的线程

【仅供参考】

如果线程是因为调用了wait。、sleep。或者join()方法而导致的阻塞,可以中断线程,并

且通过抛出InterruptedException来唤醒它;如果线程遇到了10阻塞,无能为力,因为10

是操作系统实现的,Java代码并没有办法直接接触到操作系统。

3、ReadWriteLock是什么

第6/23页

首先明确一下,不是说ReentrantLock不好,只是ReentrantLock某些时候有局限。如果使

用ReentrantLock,可能本身是为了防止线程A在写数据、线程B在读数据造成的数据不一

致,但这样,如果线程C在读数据、线程D也在读数据,读数据是不会改变数据的,没有必

要加锁,但是还是加锁了,降低了程序的性能。因为这个,才诞生了读写锁ReadWriteLock

□ReadWriteLock是一个读写锁接口,ReentrantReadWriteLock是ReadWriteLock

接口的一个具体实现,实现了读写的分离,读锁是共享的,写锁是独占的,读和读之间不会互

斥,读和写、写和读、写和写之间才会互斥,提升了读写的性能。

4、什么是线程池?有哪几种创建方式?

【仅供参考】

线程池就是提前创建若干个线程,如果有任务需要处理,线程池里的线程就会处理任务,处理

完之后线程并不会被销毁,而是等待下一个任务。由于创建和销毁线程都是消耗系统资源的,

所以当你想要频繁的创建和销毁线程的时候就可以考虑使用线程池来提升系统的性能。

java提供了一个

java.util,concurrent.Executor接口的实现用于创建线程池。

5、线程池的核心属性有哪些?

【仅供参考】

threadFactory(线程工厂):用于创建工作线程的工厂。

corePoolSize(核心线程数):当线程池运行的线程少于corePoolSize时,将创建一个新线

程来处理请求,即使其他工作线程处于空闲状态。

workQueue(队列):用于保留任务并移交给工作线程的阻塞队列。

maximumPoolSize(最大线程数):线程池允许开启的最大线程数。

handler(拒绝策略):往线程池添加任务时,将在下面两种情况触发拒绝策略:1)线程池运

行状态不是RUNNING;2)线程池已经达到最大线程数,并且阻塞队列已满时。

keepAliveTime(保持存活时间):如果线程池当前线程数超过corePoolSize,则多余的线程

空闲时间超过keepAliveTime时会被终止。

6、什么是多线程的上下文切换

【仅供参考】

多线程的上下文切换是指CPU控制权由一个已经正在运行的线程切换到另外一个就绪并等待获

取CPU执行权的线程的过程。

7、synchronized、volatile、CAS比较

【仅供参考】

(1)synchronized是悲观锁,属于抢占式,会引起其他线程阻塞。

(2)volatile提供多线程共享变量可见性和禁止指令重排序优化。

(3)CAS是基于冲突检测的乐观锁(非阻塞)

8、多线程同步有哪几种方法?

Lr皿也毒著

第7/23页

Synchronized关键字,Lock锁实现,分布式锁等。

9、线程的run()和start()有什么区别?

【仅供参考】

start()方法用于启动线程,run()方法用于执行线程的运行时代码。run()可以重复调用,

而start()只能调用一次。

10、synchronized和volatile的区别是什么?

【仅供参考】

volatile是变量修饰符;synchronized是修饰类、方法、代码段。

volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的

修改可见性和原子性。

volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。

11、什么是Future?

【仅供参考】

在并发编程中,我们经常用到非阻塞的模型,在之前的多线程的三种实现中,不管是继承

thread类还是实现runnable接口,都无法保证获取到之前的执行结果。通过实现Callback

接口,并用Future可以来接收多线程的执行结果。

Future表示一个可能还没有完成的异步任务的结果,针对这个结果可以添加Callback以便在

任务执行成功或失败后作出相应的操作。

12、如何停止一个正在运行的线程?

【仅供参考】

有几种方式。

1、使用线程的stop方法。

使用Stop。方法可以强制终止线程。不过stop是一个被废弃掉的方法,不推荐使用。

使用Stop方法,会一直向上传播ThreadDeath异常,从而使得目标线程解锁所有锁住的监视器,

即释放掉所有的对象锁。使得之前被锁住的对象得不到同步的处理,因此可能会造成数据不一

致的问题。

2、使用interrupt方法中断线程,该方法只是告诉线程要终止,但最终何时终止取决于计算

机。调用interrupt方法仅仅是在当前线程中打了一个停止的标记,并不是真的停止线程。

接着调用Thread.currentThreadO.islnterrupted()方法,可以用来判断当前线程是否被终

止,通过这个判断我们可以做一些业务逻辑处理,通常如果islnterrupted返回true的话,会抛

一个中断异常,然后通过try-catch捕获。

3、设置标志位

设置标志位,当标识位为某个值时,使线程正常退出。设置标志位是用到了共享变量的方式,

为了保证共享变量在内存中的可见性,可以使用volatile修饰它,这样的话,变量取值始终会

从主存中获取最新值。

但是这种volatile标记共享变量的方式,在线程发生阻塞时是无法完成响应的。比如调用

Thread,sleep()方法之后,线程处于不可运行状态,即便是主线程修改了共享变量的值,该线

第8/23页

程此时根本无法检查循环标志,所以也就无法实现线程中断。

因此,interrupt。加上手动抛异常的方式是目前中断一个正在运行的线程最为正确的方式

了。

13、实现可见性的方法有哪些?

【仅供参考】

synchronized或者Lock:保证同一个时刻只有一个线程获取锁执行代码,锁释放之前把最新

的值刷新到主内存,实现可见性。

14、反射有哪些应用场景呢?

【仅供参考】

川BC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序

Eclispe、IDEA等开发工具利用反射动态解析对象的类型与结构,动态提示对象的属性和方法

Web服务器中利用反射调用了Sevlet的service方法

JDK动态代理底层依赖反射实现

15、反射的实现式都有什么?

【仅供参考】

获取Class对象,有4种法:(l)Class.forName(“类的路径”);(2)类名.class;(3)对象

名.getClassO;(4)基本类型的包装类,可以调包装类的Type属性来获得该包装类的Class对

象。

16、什么是简单工厂模式?

【仅供参考】

答:简单工厂模式又叫静态工厂方法模式,就是建立一个工厂类,对实现了同一接口的一些类

进行实例的创建。比如,一台咖啡机就可以理解为一个工厂模式,你只需要按下想喝的咖啡品

类的按钮(摩卡或拿铁),它就会给你生产一杯相应的咖啡,你不需要管它内部的具体实现,

只要告诉它你的需求即可。

优点:

工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除

直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的

分割,它提供了专门的工厂类用于创建对象;

客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于

一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量;

通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一

定程度上提高了系统的灵活性。

缺点:

不易拓展,一旦添加新的产品类型,就不得不修改工厂的创建逻辑;

产品类型较多时,工厂的创建逻辑可能过于复杂,一旦出错可能造成所有产品的创建失败,不

利于系统的维护。

第9/23页

17、Java中什么叫单例设计模式?请用Java写出线程安全的单例模式

【仅供参考】

单例模式重点在于在整个系统上共享一些创建时较耗资源的对象。整个应用中只维护一个特定

类实例,它被所有组件共同使用。Java.lang.Runtime是单例模式的经典例子。从Java5开始

你可以使用枚举(enum)来实现线程安全的单例。

18、说一下JVM有哪些垃圾回收算法?

【仅供参考】

标记-清除算法:标记无用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片。

标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外

的内存。

复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另

一块上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半。

分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本

采用复制算法,老年代采用标记整理算法。

19、说一下JVM调优的工具?

【仅供参考】

JDK自带了很多监控工具,都位于JDK的bin目录下,其中最常用的是jconsole和

jvisualvm这两款视图监控工具。

jconsole:用于对JVM中的内存、线程和类等进行监控;

jvisualvm:JDK自带的全能分析工具,可以分析:内存快照、线程快照、程序死锁、监控内存

的变化、gc变化等。

20、常用的JVM调优的参数都有哪些?

【仅供参考】

-Xms2g:初始化推大小为2g;

-Xmx2g:堆最大内存为2g;

-XX:NewRatio=4:设置年轻的和老年代的内存比例为1:4;

-XX:SurvivorRatio=8:设置新生代Eden和Survivor比例为8:2;

-XX:+UseParNewGC:指定使用ParNew+SerialOld垃圾回收器组合;

-XX:+UseParallel01dGC:指定使用ParNew+ParNewOld垃圾回收器组合;

-XX:+UseConcMarkSweepGC:指定使用CMS+SerialOld垃圾回收器组合;

-XX:+PrintGC:开启打印gc信息;

-XX:+PrintGCDetails:打印gc详细信息。

三、JavaWeb篇

1、osi的七层模型都有哪些?

第10/23页

【仅供参考】

物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。

数据链路层:负责建立和管理节点间的链路。

网络层:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。

传输层:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。

会话层:向两个实体的表示层提供建立和使用连接的方法。

表示层:处理用户信息的表示问题,如编码、数据格式转换和加密解密等。

应用层:直接向用户提供服务,完成用户希望在网络上完成的各种工作。

2、解释一下什么是aop?

【仅供参考】

aop是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技

术。

简单来说就是统一处理某一“切面”(类)的问题的编程思想,比如统一处理日志、异常等。

3、为什么要使用spring?

【仅供参考】

spring提供ioc技术,容器会帮你管理依赖的对象,从而不需要自己创建和管理依赖对象

了,更轻松的实现了程序的解耦。

spring提供了事务支持,使得事务操作变的更加方便。

spring提供了面向切片编程,这样可以更方便的处理某一类的问题。

更方便的框架集成,spring可以很方便的集成其他框架,比如MyBatis、hibernate等。

4、说一下springmvc运行流程?

【仅供参考】

springmvc先将请求发送给DispatcherServleto

DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controllero

DispatcherServlet再把请求提交到对应的Controller。

Controller进行业务逻辑处理后,会返回一个ModelAndView。

Dispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视

图对象。

视图对象负责渲染返回给客户端。

5、SpringBoot实现热部署有哪几种方式?

【仅供参考】

主要有两种方式:

1、SpringLoaded

2、Spring-boot-devtools

6、SpringBoot的核心注解是哪个?它主要由哪几个注解组成的?

【仅供参考】

第'11/23页

启动类上面的注解是@SpringBootApplication,它也是SpringBoot的核心注解,主要组合包

含了以下3个注解:

©SpringBootConfiguration:组合了©Configuration注解,实现配置文件的功能。

@Enab1eAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭

数据源自动配置功能:

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})。

@ComponentScan:Spring组件扫描。

7、Springboot有哪些优点?

【仅供参考】

-快速创建独立运行的spring项目与主流框架集成

-使用嵌入式的servlet容器,应用无需打包成war包

-starters自动依赖与版本控制

-大量的自动配置,简化开发,也可修改默认值

-准生产环境的运行应用监控

-与云计算的天然集成

8、SpringCloud优点?

【仅供参考】

集大成者,SpringCloud包含了微服务架构的方方面面。

约定优于配置,基于注解,没有配置文件。

轻量级组件,SpringCloud整合的组件大多比较轻量级,且都是各自领域的佼佼者。

开发简便,SpringCloud对各个组件进行了大量的封装,从而简化了开发。

开发灵活,SpringCloud的组件都是解耦的,开发人员可以灵活按需选择组件。

9、jpa和hibernate有什么区别?

【仅供参考】

jpa全称JavaPersistenceAPI,是Java持久化接口规范,hibernate属于jpa的具体实

现。

10、JPA和Hibernate有哪些区别?

【仅供参考】

简而言之

JPA是一个规范或者接口

Hibernate是JPA的一个实现

当我们使用JPA的时候,我们使用javax.persistence包中的注释和接口时,不需要使用

hibernate的导入包。

我们建议使用JPA注释,因为哦我们没有将其绑定到Hibernate作为实现。后来(我知道-

小于百分之一的几率),我们可以使用另一种JPA实现。

11、如何在SpringBoot中添加通用的JS代码?

第12/23页

【仅供参考】

在源文件夹下,创建一个名为static的文件夹。然后,你可以把你的静态的内容放在这里

面。

例如,myapp.js的路径是resources\static\js\myapp.js

12、springcloud断路器的作用是什么?

【仅供参考】

在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生

短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不

是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分

布式系统中的蔓延。

13、SpringBoot支持哪些日志框架?推荐和默认的日志框架是哪个?

【仅供参考】

SpringBoot支持JavaUtilLogging,Log4j2,Lockback作为日志框架,如果你使用

Starters启动器,SpringBoot将使用Logback作为默认日志框架.

14、什么是springboot?

【仅供参考】

springboot是为spring服务的,是用来简化新spring应用的初始搭建以及开发过程的。

15、说一下MyBatis的一级缓存和二级缓存?

【仅供参考】

一级缓存:基于PerpetualCache的llashMap本地缓存,它的声明周期是和SQLSession一致

的,有多个SQLSession或者分布式的环境中数据库操作,可能会出现脏数据。当Session

flush或close之后,该Session中的所有Cache就将清空,默认一级缓存是开启的。

二级缓存:也是基于PerpetualCache的HashMap本地缓存,不同在于其存储作用域为

Mapper级别的,如果多个SQLSession之间需要共享缓存,则需要使用到二级缓存,并且二级缓

存可自定义存储源,如Ehcacheo默认不打开二级缓存,要开启二级缓存,使用二级缓存属性

类需要实现Serializable序列化接口(可用来保存对象的状态)。

开启二级缓存数据查询流程:二级缓存->一级缓存->数据库。

缓存更新机制:当某一个作用域(一级缓存Session/二级缓存Mapper)进行了C/U/D操作后,

默认该作用域下所有select中的缓存将被clear.,

16、hibernate有几种查询方式?

【仅供参考】

三种:hql、原生SQL、条件查询Criteria。

17、hibernate是如何工作的?

【仅供参考】

读取并解析配置文件。

第13/23页

读取并解析映射文件,创建SessionFactoryo

打开Session。

创建事务。

进行持久化操作。

提交事务。

关闭Sessiono

关闭SessionFactoryo

18、hibernate中如何在控制台查看打印的SQL语句?

【仅供参考】

在Config里面把hibernate.show_SQL设置为true就可以。但不建议开启,开启之后会降

低程序的运行效率。

19^MyBatis有几种分页方式?

【仅供参考】

分页方式:逻辑分页和物理分页。

「逻辑分页:」使用MyBatis自带的RowBounds进行分页,它是一次性查询很多数据,然后

在数据中再进行检索。

「物理分页:」自己手写SQL分页或使用分页插件PageHelper,去数据库查询指定条数的分

页数据的形式。

20、hibernate实体类可以被定义为final吗?

【仅供参考】

实体类可以定义为final类,但这样的话就不能使用hibernate代理模式下的延迟关联提供

性能了,所以不建议定义实体类为finale

四、Java数据缓存,消息队列篇

1、RabbitMQ中vhost的作用是什么?

【仅供参考】

vhost:每个RabbitMQ都能创建很多vhost,我们称之为虚拟主机,每个虚拟主机其实都是

mini版的RabbitMQ,它拥有自己的队列,交换器和绑定,拥有自己的权限机制。

2、RabbitMQ怎么避免消息丢失?

【仅供参考】

把消息持久化磁盘,保证服务器重启消息不丢失。

每个集群中至少有一个物理磁盘,保证消息落入磁盘。

3、RabbitMQ每个节点是其他节点的完整拷贝吗?为什么?

第14/23页

「nx於分专,

不是,原因有以下两个:

存储空间的考虑:如果每个节点都拥有所有队列的完全拷贝,这样新增节点不但没有新增存储

空间,反而增加了更多的冗余数据;

性能的考虑:如果每条消息都需要完整拷贝到每一个集群节点,那新增节点并没有提升处理消

息的能力,最多是保持和单节点相同的性能甚至是更糟。

4、RabbitMQ的消息是怎么发送的?

【仅供参考】

首先客户端必须连接到RabbitMQ服务器才能发布和消费消息,客户端和rabbitserver之间

会创建一个tcp连接,一旦tcp打开并通过了认证(认证就是你发送给rabbit服务器的用

户名和密码),你的客户端和RabbitMQ就创建了一条amqp信道(channel),信道是创建

在“真实”tcp上的虚拟连接,amqp命令都是通过信道发送出去的,每个信道都会有一个唯

一的id,不论是发布消息,订阅队列都是通过这个信道完成的。

5、RabbitMQ持久化有什么缺点?

【仅供参考】

持久化的缺地就是降低了服务器的吞吐量,因为使用的是磁盘而非内存存储,从而降低了吞吐

量。可尽量使用ssd硬盘来缓解吞吐量的问题。

6、RabbitMQ怎么保证消息的稳定性?

【仅供参考】

提供了事务的功能。

通过将channel设置为confirm(确认)模式。

7、RabbitMQ有哪些重要的组件?

【仅供参考】

ConnectionFactory(连接管理器):应用程序与Rabbit之间建立连接的管理器,程序代码中使

用。

Channel(信道):消息推送使用的通道。

Exchange(交换器):用于接受、分配消息。

Queue(队列):用于存储生产者的消息。

RoutingKey(路由键):用于把生成者的数据分配到交换器上。

BindingKey(绑定键):用于把交换器的消息绑定到队列上。

8、RabbitMQ的使用场景有哪些?

【仅供参考】

抢购活动,削峰填谷,防止系统崩塌。

延迟信息处理,比如10分钟之后给下单未付款的用户发送邮件提醒。

解耦系统,对于新增的功能可以单独写模块扩展,比如用户确认评价之后,新增了给用户返积

分的功能,这个时候不用在业务代码里添加新增积分的功能,只需要把新增积分的接口订阅确

第15/23页

认评价的消息队列即可,后面再添加任何功能只需要订阅对应的消息队列即可。

9、RabbitMQ集群有什么用?

【仅供参考】

集群主要有以下两个用途:

高可用:某个服务器出现问题,整个RabbitMQ还可以继续使用;

高容量:集群可以承载更多的消息量。

10、RabbitMQ节点的类型有哪些?

【仅供参考】

磁盘节点:消息会存储到磁盘。

内存节点:消息都存储在内存中,重启服务器消息丢失,性能高于磁盘类型。

11、什么情况下一个broker会从isr中踢出去?

【仅供参考】

leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-syncReplica),每个

Partition都会有一个ISR,而且是由leader动态维护,如果一个follower比一个leader落后太

多,或者超过一定时间未发起数据复制请求,则leader将其重ISR中移除。

12、说一下zookeeper的通知机制?

【仅供参考】

客户端端会对某个znode建立一个watcher事件,当该znode发生变化时,这些客户端会收

到zookeeper的通知,然后客户端可以根据znode变化来做出业务上的改变。

13、zookeeper怎么保证主从节点的状态同步?

【仅供参考】

zookeeper的核心是原子广播,这个机制保证了各个server之间的同步。实现这个机制的协

议叫做zab协议。zab协议有两种模式,分别是恢复模式(选主)和广播模式(同步)。当服

务启动或者在领导者崩溃后,zab就进入了恢复模式,当领导者被选举出来,且大多数server

完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和server

具有相同的系统状态。

14、kafka有几种数据保留的策略?

【仅供参考】

kafka有两种数据保存策略:按照过期时间保留和按照存储的消息大小保留。

15、集群中为什么要有主节点?

【仅供参考】

在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这

个结果,这样可以大大减少重复计算,提高性能,所以就需要主节点。

第16/23页

16、kafka如何减少数据丢失?

【仅供参考】

一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数据不丢失,在面试中也会

问到相关的问题。但凡遇到这种问题,是指3个方面的数据不丢失,即:producerconsumer端

数据不丢失broker端数据不丢失

17、什么是缓存穿透?怎么解决?

【仅供参考】

缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数

据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

解决方案:最简单粗暴的方法如果一个查询返回的数据为空(不管是数据不存在,还是系统故

障),我们就把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

18、Redis持久化有几种方式?

【仅供参考】

Redis的持久化有两种方式,或者说有两种策略:

RDB(RedisDatabase):指定的时间间隔能对你的数据进行快照存储。

AOF(AppendOnlyFile):每一个收到的写命令都通过write函数追加到文件中。

19、Redis淘汰策略有哪些?

【仅供参考】

volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用

的数据淘汰。

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数

据淘汰。

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘

汰。

allkeys-lru:从数据集(server.db[i].diet)中挑选最近最少使用的数据淘汰。

allkeys-random:从数据集(server.db[i].diet)中任意选择数据淘汰。

no-enviction(驱逐):禁止驱逐数据。

20、Redis为什么是单线程的?

【仅供参考】

因为epu不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存或者网络带宽。既然单线程

容易实现,而且epu又不会成为瓶颈,那就顺理成章地采用单线程的方案了。

关于Redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求。

而且单线程并不代表就慢nginx和nodejs也都是高性能单线程的代表。

五、MySQL篇

第17/23页

1、为什么删除了表,表文件的大小还是没变?

【仅供参考】

数据项删除之后InnoDB某个页pageA会被标记为可复用。

delete命令把整个表的数据删除,结果就是,所有的数据页都会被标记为可复用。但是磁盘

上,文件不会变小。

经过大量增删改的表,都是可能是存在空洞的。这些空洞也占空间所以,如果能够把这些空洞

去掉,就能达到收缩表空间的目的。

重建表,就可以达到这样的目的。可以使用altertableAengine=InnoDB命令来重建表。

2、MySQL是如何判断一行扫描数的?

【仅供参考】

MySQL在真正开始执行语句之前,并不能精确地知道满足这个条件的记录有多少条。

而只能根据统计信息来估算记录数。这个统计信息就是索引的“区分度。

3、MySQL读写分离涉及到过期读问题的几种解决方案?

【仅供参考】

强制走主库方案

sleep方案

判断主备无延迟方案

配合semi-sync方案

等主库位点方案

GTID方案。

实际生产中,先客户端对请求做分类,区分哪些请求可以接受过期读,而哪些请求完全不能接

受过期读;然后,对于不能接受过期读的语句,再使用等GTID或等位点的方案。

4、MySQL的一主一备和一主多从有什么区别?

【仅供参考】

在一主一备的双M架构里,主备切换只需要把客户端流量切到备库;而在一主多从架构里,主

备切换除了要把客户端流量切到备库外,还需要把从库接到新主库上。

5、drop、truncate和delete的区别?

【仅供参考】

DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录

在日志中保存以便进行进行回滚操作。

TRUNCATETABLE则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,

删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。

drop语句将表所占用的空间全释放掉。

在速度上,一般来说,drop>truncate>delete。

如果想删除部分数据用delete,注意带上where子句,回滚段要足够大;

如果想删除表,当然用drop;如果想保留表而将所有数据删除,如果和事务无关,用

第18/23页

truncate即可;

如果和事务有关,或者想触发trigger,还是用delete;如果是整理表内部的碎片,可以用

truncate跟上reusestroage,再重新导入/插入数据。

6、MyISAM和InnoDB实现B树索引方式的区别是什么?

【仅供参考】

InnoDB存储引擎:B+树索引的叶子节点保存数据本身,其数据文件本身就是索引文件。

MylSAM存储引擎:B+树索引的叶子节点保存数据的物理地址,叶节点的data域存放的是数

据记录的地址,索引文件和数据文件是分离的。

7、说一下数据库的事务隔离?

【仅供参考】

MySQL的事务隔离是在MySQL.ini配置文件里添加的,在文件的最后添加:

*transaction-isolation=REPEATABLE-READ

可用的配置值:READ-UNCOMMITTED,READ-COMMITTED.REPEATABLE-READ>SERIALIZABLEo

READ-UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现

幻读、脏读、不可重复读)。

READ-COMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复

读)。

REPEATABLE-READ:可重复读,默认级别,保证多次读取同一个数据时,其值都和事务开始时候

的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读)。

SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、

幻读。

「脏读」:表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记

录A,此时该事务还未提交,然后另一个事务尝试读取到了记录Ao

「不可重复读」:是指在一个事务内,多次读同一数据。

「幻读」:指同一个事务内多次查询返回的结果集不一样。比如同一个事务A第一次查询时

候有n条记录,但是第二次同等条件下查询却有n+1条记录,这就好像产生了幻觉。发生幻

读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记

录的数据内容被修改了,所有数据行的记录就变多或者变少了。

8、为什么MySQL会抖一下?

【仅供参考】

脏页会被后台线程自动flush,也会由于数据页淘汰而触发flush,而刷脏页的过程由于会占

用资源,可能会让你的更新和查询语句的响应时间长一些。

9、MySQL索引是怎么实现的?

【仅供参考】

―1_•—«t■_»、一U.I-t-1__U.▼,_t____II、,一j,,,、“,I1-t/I,,••、、•>.、”,1t—>/IIfAr.>11.一,、,、!,一,、,,,>■-r>t..、-a

第19/23页

索引是满足某种特定查找算法的数据结构,血这些数据结构会以某种万式指向数据,从血实现

高效查找数据。

具体来说MySQL中的索引,不同的数据引擎实现有所不同,但目前主流的数据库引擎的索引都

是B+树实现的,B+树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整

的数据结构了,所有索引的性能也是更好的。

10、什么是WAL技术,有什么优点?

【仅供参考】

WAL,中文全称是Write-AheadLogging,它的关键点就是日志先写内存,再写磁盘。MySQL执

行更新操作后,在真正把数据写入到磁盘前,先记录日志。

好处是不用每一次操作都实时把数据写盘,就算crash后也可以通过redolog恢复,所以能

够实现快速响应SQL语句。

11、误删数据怎么办?

【仅供参考】

DBA的最核心的工作就是保证数据的完整性,先要做好预防,预防的话大概是通过这几个点:

权限控制与分配(数据库和服务器权限)

制作操作规范

定期给开发进行培训

搭建延迟备库

做好SQL审计,只要是对线上数据有更改操作的语句(DML和DDL)都需要进行审核

做好备份。备份的话又分为两个点(1)如果数据量比较大,用物理备份xtrabackupo定期对数

据库进行全量备份,也可以做增量备份。(2)如果数据量较少,用mysqldump或者

mysqldumpero再利用binlog来恢复或者搭建主从的方式来恢复数据。定期备份binlog文件

也是很有必要的

如果发生了数据删除的操作,又可以从以下几个点来恢复:

DML误操作语句造成数据不完整或者丢失。可以通过flashback,美团的myflash,也是一个

不错的工具,本质都差不多

都是先解析binlogevent,然后在进行反转。把delete反转为insert,insert反转为

delete,update前后image对调。

所以必须设置binlog_format=row和binlog_row_image=full,切记恢复数据的时候,应该先

恢复到临时的实例,然后在恢复回主库上。

DDL语句误操作(truncate和drop),由于DDL语句不管binlog_format是row还是statement

,在binlog里都只记录语句,不记录image所以恢复起来相对要麻烦得多。

只能通过全量备份+应用binlog的方式来恢复数据。一旦数据量比较大,那么恢复时间就特别

rm删除:使用备份跨机房,或者最好是跨城市保存。

12、索引的三种常见底层数据结构以及优缺点

【仅供参考】

三种常见的索引底层数据结构:分别是哈希表、有序数组和搜索树。

第20/23页

哈希表这种适用于等值查询的场景,比如memcached以及其它一些NoSQL引擎,不适合范围

查询。

有序数组索引只适用于静态存储引擎,等值和范围查询性能好,但更新数据成本高。

N叉树由于读写上的性能优点以及适配磁盘访问模式以及广泛应用在数据库引擎中。

扩展(以InnoDB的一个整数字段索引为例,这个N差不多是1200。棵树高是4的时候,就

可以存1200的3次方个值,这已经17亿了。考虑到树根的数据块总是在内存中的,一个

10亿行的表上一个整数字段的索引,查找一个值最多只需要访问3次磁盘。其实,树的第二

层也有很大概率在内存中,那么访问磁盘的平均次数就更少了。)

13、MySQL的并行策略有哪些?

【仅供参考】

按表分发策略:如果两个事务更新不同的表,它们就可以并行。因为数据是存储在表里的,所

以按表分发,可以保证两个worker不会更新同一行。缺点:如果碰到热点表,比如所有的更

新事务都会涉及到某一个表的时候,所有事务都会被分配到同一个worker中,就变成单线程

复制了。

按行分发策略:如果两个事务没

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论