Java面试题总结(附答案)

目录

1、JDK和JRE有什么区别?

2、== 和 equals 的区别是什么?

3、final 在 java 中有什么作用?

4、java 中的 Math.round(-1.5) 等于多少?

5、Java面向对象下的三个特征?

6、Java中基本的数据类型有哪些,以及它们的占用字节?

7、int和integer的区别?

8、String、StringBuilder、StringBuffer的区别以及使用场景?

9、ArrayList、Vector和LinkedList的区别以及使用场景

10、Collection和Collections的区别

11、List和Map的区别

12、HashMap和HashTable的区别

13、HashMap底层实现原理和扩容机制

14、HashMap什么样的类适合作为键

15、final、finally、finalize的区别

16、sleep和wait的区别

17、抽象类和接口的区别、以及使用场景

18、java 中 IO 流分为几种?

19、BIO、NIO、AIO 有什么区别?

20、Files的常用方法都有哪些?

21、什么是反射?

22、什么是 java 序列化?什么情况下需要序列化?

23、throw 和 throws 的区别?

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

25、常见的异常类有哪些?

26、hashcode是什么?有什么作用?

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

28、java 中都有哪些引用类型?

29、在 Java 中,为什么不允许从静态方法中访问非静态变量?

30、说说Java Bean的命名规范

31、多线程中 synchronized 锁升级的原理是什么?

32、synchronized 和 ReentrantLock 区别是什么?

33、Java Concurrency API 中的 Lock 接口(Lock interface)是什么?对比同步它有什么优势?

34、jsp 和 servlet 有什么区别?

35、jsp 有哪些内置对象?作用分别是什么?

36、sleep()和wait()的区别

37、抽象类和接口的区别、以及使用场景

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

39、forward(转发)和redirect(重定向)的区别

40、连接池的工作机制

41、什么是序列化

42、什么是AOP、Spring AOP的底层原理是什么

43、什么是IOC、IOC注入方式有哪些

44、Mybatis中 #{} 和 ${}的区别

45、Spring Boot的核心注解是什么,它是由哪几个注解组成的

46、SpringBoot 怎么读取配置文件

47、SpringCloud和Dubbo的区别

48、SpringCloud的Hystrix断路器特性

49、事物的四大特性和隔离级别

50、MySQL优化相关

51、MySQL存储引擎InnoDB和MyISAM的区别

52、MySQL在哪些情况下不使用索引

53、MySQL分库分表策略

54、jsp 有哪些内置对象?作用分别是什么?

55、forward 和 redirect 的区别?

56、session 和 cookie 有什么区别?

57、如果客户端禁止 cookie 能实现 session 还能用吗?

58、什么是上下文切换?

59、http 响应码 301 和 302 代表的是什么?有什么区别?

60、简述 tcp 和 udp的区别?

61、get 和 post 请求有哪些区别?

62、说一下session的工作原理?

63、tcp粘包是怎么产生的?

64、请列出在jdk中几个常用的设计模式?

65、什么是设计模式?是否使用过任何设计模式?

66、使用工厂模式最主要的好处是什么?在哪里使用?

67、什么是Spring框架?Spring框架有哪些主要模块?

68、使用Spring框架能带来哪些好处?

69. spring 常用的注入方式有哪些?

70. spring 支持几种 bean 的作用域?


1、JDK和JRE有什么区别?

JDK(Java Development Kit),Java开发工具包

JRE(Java Runtime Environment),Java运行环境

JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,lib就是JVM工作所需要的类库。

2、== 和 equals 的区别是什么?

  • 对于基本类型,==比较的是值;
  • 对于引用类型,==比较的是地址;
  • equals不能用于基本类型的比较;
  • 如果没有重写equals,equals就相当于==;
  • 如果重写了equals方法,equals比较的是对象的内容;

3、final 在 java 中有什么作用?

(1)用来修饰一个引用

 如果引用为基本数据类型,则该引用为常量,该值无法修改;

 如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改。

 如果引用时类的成员变量,则必须当场赋值,否则编译会报错。

(2)用来修饰一个方法

当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。

(3)用来修饰类

当用final修改类时,该类成为最终类,无法被继承。

 比如常用的String类就是最终类。

4、java 中的 Math.round(-1.5) 等于多少?

Math提供了三个与取整有关的方法:ceil、floor、round

(1)ceil:向上取整;

Math.ceil(11.3) = 12;

Math.ceil(-11.3) = 11;

(2)floor:向下取整;

Math.floor(11.3) = 11;

Math.floor(-11.3) = -12;

(3)round:四舍五入;

加0.5然后向下取整。

Math.round(11.3) = 11;

Math.round(11.8) = 12;

Math.round(-11.3) = -11;

Math.round(-11.8) = -12;

5、Java面向对象下的三个特征?

封装:对象只需要选择性的对外公开一些属性和行为

继承:子对象可以继承父对象的属性和行为,并且可以在其之上进行修改以适合更特殊的场景和需求。

多态:允许不同类的对象对同一消息做出响应。

6、Java中基本的数据类型有哪些,以及它们的占用字节?

数据类型

占用字节

byte

1

short

2

int

4

long

8

float

4

double

8

char

2

boolean

4

7、int和integer的区别?

int是Java中的原始类型,integer是Java为int提供的封装类,它们有不同的特征和用法,包括大小、速度、默认值。

8、String、StringBuilder、StringBuffer的区别以及使用场景?

String一旦定义就不可改变,可空赋值。操作少量数据时使用。

StringBuilder可改变,线程不安全。操作单线程大量数据时使用。

StringBuffer可改变,线程安全。操作多线程大量数据时使用。

9、ArrayList、Vector和LinkedList的区别以及使用场景

ArrayList和Vector都是使用数组方式存储数据,允许按序号索引元素,但是插入数据会涉及到元素移动等内存操作,所以索引块插入慢。

ArrayList懒加载 默认大小为10 每次扩容1.5倍 线程不安全 性能较高

Vector实例化时初始化 默认大小为10 每次扩容2倍 线程安全 性能较低 已弃用

多读少写建议使用CopyOnWriteArrayList

CopyOnWriteArrayList原理是发生修改的时候复制一份

多写少读或读写比较均匀建议使用Connections.synchronizedList

LinkedList使用双向链表方式存储数据,插入只需要记录本项的前后项,索引需要向前或向后进行遍历,所以插入速度较快,线程不安全,

频繁在任意位置插入和删除的情况可以使用,如果需要多线程访问,可以使用Connections.synchronizedList()或ConcurrentLinkedQueue

10、Collection和Collections的区别

Conllection是集合类上级接口,继承他的主要有list和set

Conllections是集合类的帮助类,提供了对集合的搜索、排序、线程安全化等操作。

11、List和Map的区别

List是存储单列数据的集合,Map是存储键值对双列数据的集合。

List存储数据是有顺序且可重复的,Map存储的数据是无顺序,键不可重复,值可重复的。

12、HashMap和HashTable的区别

HashMap是Map接口的实现,非线程安全,允许空键值。

HashTable是Dictionnary的子类,线程安全,不允许空键值。几乎被淘汰。建议使用ConcurrentHashMap来替代它。

HashMap使用的是快速失败迭代器,在迭代器创建后,除非通过迭代器自身的remove或者add方法,其他任何方式的修改都会抛出异常。

13、HashMap底层实现原理和扩容机制

JDK1.8以前:数组+单链条的组合,以键值对的方式存储元素。

JDK1.8及以后:引入红黑树结构,添加元素时,若链表个数大于8,链表会转换为红黑树,反之小于6时会修剪或还原成链表结构。

选择6和8可以有效防止频繁的链表和红黑树转换。

扩容条件:

  1. 存放新值的时候当前已有元素个数大于阈值。
  2. 存放新值的时候当前存放数据发生hash碰撞(当前key计算的hash值换算出来的数组下标位置已经存在值)
    默认容量是16,负载因子0.75,所以扩容阈值是12。
    每次扩容的容量是原有的2倍。

14、HashMap什么样的类适合作为键

String最为常见,因为String对象不可变,且重写了equals和hashcode方法。

不可变性是必要的,如果key的hashcode存入和获取是不一致,就无法找到。

获取对象时需要用到equals和hashcode方法,正确的重写这两个方法是非常重要的,因为两个不相等的对象

返回不同的hashcode的话,碰撞的几率就会小些,就可以提高HashMap的性能。

15、final、finally、finalize的区别

final是用于修饰属性、方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

finally是异常处理语句结构的一部分,表示总是执行。

finalize是Object类的一个方法,在GC执行时会调用被回收对象的方法。

16、sleep和wait的区别

sleep是Thread类的,wait是Object的方法

sleep不会释放锁,wait会释放锁。

sleep可在任意地方使用,wait notify notifyAll只能在synchronized块方法中使用。

sleep必须捕获异常,而wait不需要。

17、抽象类和接口的区别、以及使用场景

(1)接口

接口使用interface修饰;

接口不能实例化;

类可以实现多个接口;

①java8之前,接口中的方法都是抽象方法,省略了public abstract。②java8之后;接口中可以定义静态方法,静态方法必须有方法体,普通方法没有方法体,需要被实现;

(2)抽象类

抽象类使用abstract修饰;   

抽象类不能被实例化;

抽象类只能单继承;

抽象类中可以包含抽象方法和非抽象方法,非抽象方法需要有方法体;

如果一个类继承了抽象类,①如果实现了所有的抽象方法,子类可以不是抽象类;②如果没有实现所有的抽象方法,子类仍然是抽象类。

18、java 中 IO 流分为几种?

(1)按流划分,可以分为输入流和输出流;

(2)按单位划分,可以分为字节流和字符流;

字节流:inputStream、outputStream;

字符流:reader、writer;

19、BIO、NIO、AIO 有什么区别?

(1)同步阻塞BIO

一个连接一个线程。

JDK1.4之前,建立网络连接的时候采用BIO模式,先在启动服务端socket,然后启动客户端socket,对服务端通信,客户端发送请求后,先判断服务端是否有线程响应,如果没有则会一直等待或者遭到拒绝请求,如果有的话会等待请求结束后才继续执行。

(2)同步非阻塞NIO

NIO主要是想解决BIO的大并发问题,BIO是每一个请求分配一个线程,当请求过多时,每个线程占用一定的内存空间,服务器瘫痪了。

JDK1.4开始支持NIO,适用于连接数目多且连接比较短的架构,比如聊天服务器,并发局限于应用中。

一个请求一个线程。

(3)异步非阻塞AIO

一个有效请求一个线程。

JDK1.7开始支持AIO,适用于连接数目多且连接比较长的结构,比如相册服务器,充分调用OS参与并发操作。

20、Files的常用方法都有哪些?

  • exist
  • createFile
  • createDirectory
  • write
  • read
  • copy
  • size
  • delete
  • move

21、什么是反射?

所谓反射,是java在运行时进行自我观察的能力,通过class、constructor、field、method四个方法获取一个类的各个组成部分。

在Java运行时环境中,对任意一个类,可以知道类有哪些属性和方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于反射机制。

22、什么是 java 序列化?什么情况下需要序列化?

序列化就是一种用来处理对象流的机制。将对象的内容流化,将流化后的对象传输于网络之间。

序列化是通过实现serializable接口,该接口没有需要实现的方法,implement Serializable只是为了标注该对象是可被序列化的,使用一个输出流(FileOutputStream)来构造一个ObjectOutputStream对象,接着使用ObjectOutputStream对象的writeObejct(Object object)方法就可以将参数的obj对象到磁盘,需要恢复的时候使用输入流。

序列化是将对象转换为容易传输的格式的过程。

例如,可以序列化一个对象,然后通过HTTP通过Internet在客户端和服务器之间传输该对象。在另一端,反序列化将从流中心构造成对象。

一般程序在运行时,产生对象,这些对象随着程序的停止而消失,但我们想将某些对象保存下来,这时,我们就可以通过序列化将对象保存在磁盘,需要使用的时候通过反序列化获取到。

对象序列化的最主要目的就是传递和保存对象,保存对象的完整性和可传递性。

譬如通过网络传输或者把一个对象保存成本地一个文件的时候,需要使用序列化。

23、throw 和 throws 的区别?

(1)throw

作用在方法内,表示抛出具体异常,由方法体内的语句处理;

一定抛出了异常;

(2)throws

作用在方法的声明上,表示抛出异常,由调用者来进行异常处理;

可能出现异常,不一定会发生异常;

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

final可以修饰类,变量,方法,修饰的类不能被继承,修饰的变量不能重新赋值,修饰的方法不能被重写

finally用于抛异常,finally代码块内语句无论是否发生异常,都会在执行finally,常用于一些流的关闭。

finalize方法用于垃圾回收。

一般情况下不需要我们实现finalize,当对象被回收的时候需要释放一些资源,比如socket链接,在对象初始化时创建,整个生命周期内有效,那么需要实现finalize方法,关闭这个链接。

但是当调用finalize方法后,并不意味着gc会立即回收该对象,所以有可能真正调用的时候,对象又不需要回收了,然后到了真正要回收的时候,因为之前调用过一次,这次又不会调用了,产生问题。所以,不推荐使用finalize方法。

25、常见的异常类有哪些?

NullPointerException:空指针异常;

SQLException:数据库相关的异常;

IndexOutOfBoundsException:数组下角标越界异常;

FileNotFoundException:打开文件失败时抛出;

IOException:当发生某种IO异常时抛出;

ClassCastException:当试图将对象强制转换为不是实例的子类时,抛出此异常;

NoSuchMethodException:无法找到某一方法时,抛出;

ArrayStoreException:试图将错误类型的对象存储到一个对象数组时抛出的异常;

NumberFormatException:当试图将字符串转换成数字时,失败了,抛出;

IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。

ArithmeticException当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。

26、hashcode是什么?有什么作用?

Java中Object有一个方法:

public native int hashcode();

(1)hashcode()方法的作用

hashcode()方法主要配合基于散列的集合一起使用,比如HashSet、HashMap、HashTable。

当集合需要添加新的对象时,先调用这个对象的hashcode()方法,得到对应的hashcode值,实际上hashmap中会有一个table保存已经存进去的对象的hashcode值,如果table中没有改hashcode值,则直接存入,如果有,就调用equals方法与新元素进行比较,相同就不存了,不同就存入。

(2)equals和hashcode的关系

如果equals为true,hashcode一定相等;

如果equals为false,hashcode不一定不相等;

如果hashcode值相等,equals不一定相等;

如果hashcode值不等,equals一定不等;

(3)重写equals方法时,一定要重写hashcode方法

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

(1)String

String是不可变对象,每次对String类型的改变时都会生成一个新的对象。

(2)StringBuilder

线程不安全,效率高,多用于单线程。

(3)StringBuffer

线程安全,由于加锁的原因,效率不如StringBuilder,多用于多线程。

不频繁的字符串操作使用String,操作频繁的情况不建议使用String。

StringBuilder > StringBuffer > String。

28、java 中都有哪些引用类型?

(1)强引用

Java中默认声明的就是强引用,比如:

Object obj = new Object();

obj = null;

只要强引用存在,垃圾回收器将永远不会回收被引用的对象。如果想被回收,可以将对象置为null;

(2)软引用(SoftReference)

在内存足够的时候,软引用不会被回收,只有在内存不足时,系统才会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会跑出内存溢出异常。

byte[] buff = new byte[1024 * 1024];

SoftReference<byte[]> sr = new SoftReference<>(buff);

(3)弱引用(WeakReference)

进行垃圾回收时,弱引用就会被回收。

(4)虚引用(PhantomReference)

(5)引用队列(ReferenceQueue)

引用队列可以与软引用、弱引用、虚引用一起配合使用。

当垃圾回收器准备回收一个对象时,如果发现它还有引用,就会在回收对象之前,把这个引用加入到引用队列中。

程序可以通过判断引用队列中是否加入了引用,来判断被引用的对象是否将要被垃圾回收,这样可以在对象被回收之前采取一些必要的措施。

29、在 Java 中,为什么不允许从静态方法中访问非静态变量?

静态变量属于类本身,在类加载的时候就会分配内存,可以通过类名直接访问;

非静态变量属于类的对象,只有在类的对象产生时,才会分配内存,通过类的实例去访问;

静态方法也属于类本身,但是此时没有类的实例,内存中没有非静态变量,所以无法调用。

30、说说Java Bean的命名规范

JavaBean 类必须是一个公共类,并将其访问属性设置为 public

JavaBean 类必须有一个空的构造函数:类中必须有一个不带参数的公用构造器,此构造器也应该通过调用各个特性的设置方法来设置特性的缺省值。

一个javaBean类不应有公共实例变量,类变量都为private

持有值应该通过一组存取方法(getXxx 和 setXxx)来访问:对于每个特性,应该有一个带匹配公用 getter 和 setter 方法的专用实例变量。

属性为布尔类型,可以使用 isXxx() 方法代替 getXxx() 方法。

通常属性名是要和 包名、类名、方法名、字段名、常量名作出区别的:

首先:必须用英文,不要用汉语拼音

(1)包(package)

用于将完成不同功能的类分门别类,放在不同的目录(包)下,包的命名规则:将公司域名反转作为包名。比如www.sohu.com 对于包名:每个字母都需要小写。比如:com.sohu.test;该包下的Test类的全名是:com.sohu.Test.Java 。

如果定义类的时候没有使用package,那么java就认为我们所定义的类位于默认包里面(default package)。

(2)类

首字母大写,如果一个类由多个单词构成,那么每个单词的首字母都大写,而且中间不使用任何的连接符。尽量使用英文。如ConnectionFactory

(3)方法

首单词全部小写,如果一个方法由多个单词构成,那么从第二个单词开始首字母大写,不使用连接符。addPerson

(4)字段

与方法相同。如ageOfPerson

(5)常量

所有单词的字母都是大写,如果有多个单词,那么使用下划线链接即可。

31、多线程中 synchronized 锁升级的原理是什么?

synchronized 锁升级原理:在锁对象的对象头里面有一个 threadid 字段,在第一次访问的时候 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id,再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了 synchronized 锁的升级。

锁的升级的目的:锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗。

32、synchronized 和 ReentrantLock 区别是什么?

synchronized 是和 if、else、for、while 一样的关键字,ReentrantLock 是类,这是二者的本质区别。既然 ReentrantLock 是类,那么它就提供了比synchronized 更多更灵活的特性,可以被继承、可以有方法、可以有各种各样的类变量

synchronized 早期的实现比较低效,对比 ReentrantLock,大多数场景性能都相差较大,但是在 Java 6 中对 synchronized 进行了非常多的改进。

相同点:两者都是可重入锁

两者都是可重入锁。“可重入锁”概念是:自己可以再次获取自己的内部锁。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可锁重入的话,就会造成死锁。同一个线程每次获取锁,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。

主要区别如下:

ReentrantLock 使用起来比较灵活,但是必须有释放锁的配合动作;

ReentrantLock 必须手动获取与释放锁,而 synchronized 不需要手动释放和开启锁;

ReentrantLock 只适用于代码块锁,而 synchronized 可以修饰类、方法、变量等。

二者的锁机制其实也是不一样的。ReentrantLock 底层调用的是 Unsafe 的park 方法加锁,synchronized 操作的应该是对象头中 mark word

Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:

普通同步方法,锁是当前实例对象

静态同步方法,锁是当前类的class对象

同步方法块,锁是括号里面的对象

33、Java Concurrency API 中的 Lock 接口(Lock interface)是什么?对比同步它有什么优势?

Lock 接口比同步方法和同步块提供了更具扩展性的锁操作。他们允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的条件对象。

它的优势有:

(1)可以使锁更公平

(2)可以使线程在等待锁的时候响应中断

(3)可以让线程尝试获取锁,并在无法获取锁的时候立即返回或者等待一段时间

(4)可以在不同的范围,以不同的顺序获取和释放锁

整体上来说 Lock 是 synchronized 的扩展版,Lock 提供了无条件的、可轮询的(tryLock 方法)、定时的(tryLock 带参方法)、可中断的(lockInterruptibly)、可多条件队列的(newCondition 方法)锁操作。另外 Lock 的实现类基本都支持非公平锁(默认)和公平锁,synchronized 只支持非公平锁,当然,在大部分情况下,非公平锁是高效的选择。

34、jsp 和 servlet 有什么区别?

(1)servlet是服务器端的Java程序,它担当客户端和服务端的中间层。

(2)jsp全名为Java server pages,中文名叫Java服务器页面,其本质是一个简化的servlet设计。JSP是一种动态页面设计,它的主要目的是将表示逻辑从servlet中分离出来。

(3)JVM只能识别Java代码,不能识别JSP,JSP编译后变成了servlet,web容器将JSP的代码编译成JVM能够识别的Java类(servlet)。

(4)JSP有内置对象、servlet没有内置对象。

35、jsp 有哪些内置对象?作用分别是什么?

JSP九大内置对象:

pageContext,页面上下文对象,相当于页面中所有功能的集合,通过它可以获取JSP页面的out、request、response、session、application对象。

request

response

session

application,应用程序对象,application实现了用户间数据的共享,可存放全局变量,它开始于服务器启动,知道服务器关闭。

page,就是JSP本身。

exception

out,out用于在web浏览器内输出信息,并且管理应用服务器上的输出缓冲区,作用域page。

config,取得服务器的配置信息。

36、sleep()和wait()的区别

sleep()是Thread类的,wait()是Object类的方法

sleep不会释放锁,wait会释放锁。

sleep可在任意地方使用,wait notify notifyAll只能在synchronized块\方法中使用。

sleep必须捕获异常,而wait不需要。

37、抽象类和接口的区别、以及使用场景

抽象类中可以有构造方法、静态方法、普通方法、普通成员变量。接口中不能有。

抽象类中的抽象方法访问类型可以是public、protected和默认类型,接口中只能是public。

抽象类中的静态成员变量访问类型可以任意,接口中只能是public的。

一个类只能继承一个类,但是可以实现多个接口。

抽象类和子类为“是不是”的关系。主要用于为一些类提供公共实现代码。

接口和实现为“有没有”的关系。主要用于代码的扩展性和可维护性。

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

重载是一个类中多态性的一种表现,在一个类中定义了多个同名的方法,他们有不同的参数列表。

重写是父类与子类之间多态的一种表现,子类中定义了与父类有相同名称和参数的方法时,子类对象使用该方法会调用子类中的定义。

39、forward(转发)和redirect(重定向)的区别

forward是服务器请求资源,服务器访问目标URL,把响应内容发给用户,用户不知道数据是从哪来的。

redirect是服务器向客户端发送一个状态码,告知重新请求该URL。

40、连接池的工作机制

服务器启动时会建立一定数量的池连接,客户端需要连接时,池会返回一个未使用的连接并将其标记为忙,如果没有空闲连接,池会新建一定数量的连接,当连接使用完毕后,池会将其标记为空闲

41、什么是序列化

序列化就是一种用来处理对象流的机制,就是将对象的内容进行流化,可以对流化后的对象进行读写操作,也可以将流化后的对象传输于网络之间。

可通过实现java.io.Serializable接口来实现序列化。

42、什么是AOP、Spring AOP的底层原理是什么

AOP是面向切面编程,用于在不改变原有逻辑的基础上增加一些额外的功能,如事务管理、日志、缓存、权限控制等。

Spring AOP是基于代理的。

如果目标对象实现了接口,则默认采用JDK动态代理。

如果目标对象没有实现接口,则采用CgLib进行动态代理。

如果目标对象实现了接口,且强制CgLib代理,则采用CgLib动态代理。

43、什么是IOC、IOC注入方式有哪些

IOC翻译为控制反转,他还有个别名为DI(依赖注入)。

IOC就是由IOC容器来负责对象的生命周期和对象之间的关系。

控制反转就是本来应该你做的事情,让系统去做,比如通常获取一个对象需要通过new,而使用IOC则是IOC将对象创建后注入到被注入的对象中。

注解注入(Spring)、构造器注入、setter方法注入、接口方式注入(不推荐)

44、Mybatis中 #{} 和 ${}的区别

#{}是预编译,可防止SQL注入。

${}是直接拼接在SQL语句中。

45、Spring Boot的核心注解是什么,它是由哪几个注解组成的

核心注解:@SpringBootApplication

包含:

@SpringBootConfiguration 实现配置文件功能

@EnableAutoConfiguration 打开自动配置功能

@CompoentScan 组件扫描功能

46、SpringBoot 怎么读取配置文件

属性上使用@Value注解

类上使用@ConfigurationProperties注解

读取指定文件注解可在类上使用@PropertySource(不支持yml文件读取)

注入Environment对象获取到。

47、SpringCloud和Dubbo的区别

SpringCloud采用基于HTTP的REST API,Dubbo采用RPC方式。

48、SpringCloud的Hystrix断路器特性

请求熔断:请求服务失败量超过一定比例(默认50%)断路器会切换到开路状态,这时所有请求不会发送到后端服务,断路器在保持开路状态一段时间后(默认5秒),自动切换到半开路状态。这时如果下一次请求成功,断路器切回闭路状态,否则重新切换到开路状态。

服务降级:对于查询操作,可以实现一个fallback方法。当请求服务出现异常时,可以使用fallback方法返回的值。

依赖隔离:通过线程池来实现资源隔离,比如一个服务调用另外两个服务,如果这两个服务在同一线程池,那么如果一个服务卡住,后面的请求又来了,就会导致后面的请求都会卡住等待。

请求缓存:缓存上次请求结果,返回给后续请求。

请求合并:把多个请求合并成一个请求,提升效率。

49、事物的四大特性和隔离级别

原子性:不可分割的操作单元,要么全部成功,要么回滚。

一致性:如果执行事物之前数据库是一致的,那么执行后还是一致的。

隔离性:事物操作之间彼此独立和透明,互不影响。

持久性:事物一旦提交,其结果就是永久的。

未提交读:允许脏读,其他事物只要修改了数据,即使未提交,本事物也能看到修改后的数据值。

提交读:只能读取到已提交的数据。

可重复读(innoDB默认):无论其他事物是否修改并提交了数据,这个事物中的数据不受影响。

串行读:完全串行化的读,每次读都要获得锁,读写相互都会阻塞。

50、MySQL优化相关

使用更小的整数类型、尽可能的定义字段为not null(否则会导致索引复杂)、

只创建需要的索引、分库分表。

使用explain检查复杂SQL语句、LIMIT语句尽量要跟order by或distinct、

插入多条数据时使用单条INSERT语句。

51、MySQL存储引擎InnoDB和MyISAM的区别

InnoDB支持事物,MyISAM不支持。

InnoDB支持外键,MyISAM不支持。

InnoDB是聚集索引,MyISAM是非聚集索引。索引和数据文件是分离的。

InnoDB必须要有主键(没有会自己找或创建),MyISAM可以没有。

InnoDB不保存表的行数,MyISAM用了一个变量保存表的行数。

InnoDB支持表、行级锁 默认行级锁,MyISAM只支持表级锁。

52、MySQL在哪些情况下不使用索引

like查询使用%开头不能使用索引,但用%结尾的可以使用索引。

where语句中使用<>或!=。

where语句中使用or,且没有把or中的所有字段加上索引。

where语句中对字段表达式操作。

where语句中使用NOT IN。使用简单的IN会使用索引。

53、MySQL分库分表策略

垂直切分:某个表字段过多,可以将不常用或字段长度较大的字段拆分出去到扩展表中。

水平切分:分为库内分表和分库分表,是根据表内数据的逻辑关系,按照不同的条件分散到多个数据库或表中。

54、jsp 有哪些内置对象?作用分别是什么?

JSP九大内置对象:

  • pageContext,页面上下文对象,相当于页面中所有功能的集合,通过它可以获取JSP页面的out、request、response、session、application对象。
  • request
  • response
  • session
  • application,应用程序对象,application实现了用户间数据的共享,可存放全局变量,它开始于服务器启动,知道服务器关闭。
  • page,就是JSP本身。
  • exception
  • out,out用于在web浏览器内输出信息,并且管理应用服务器上的输出缓冲区,作用域page。
  • config,取得服务器的配置信息。

55、forward 和 redirect 的区别?

forward是直接请求转发;redirect是间接请求转发,又叫重定向。

forward,客户端和浏览器执行一次请求;redirect,客户端和浏览器执行两次请求。

forward,经典的MVC模式就是forward;redirect,用于避免用户的非正常访问。(例如用户非正常访问,servlet就可以将HTTP请求重定向到登录页面)。

forward,地址不变;redirect,地址改变。

forward常用方法:RequestDispatcher类的forward()方法;redirect常用方法:HttpServletRequest类的sendRedirect()方法。

56、session 和 cookie 有什么区别?

(1)存储位置不同

cookie在客户端浏览器;

session在服务器;

(2)存储容量不同

cookie<=4K,一个站点最多保留20个cookie;

session没有上线,出于对服务器的保护,session内不可存过多东西,并且要设置session删除机制;

(3)存储方式不同

cookie只能保存ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据;

session中能存储任何类型的数据,包括并不局限于String、integer、list、map等;

(4)隐私策略不同

cookie对客户端是可见的,不安全;

session存储在服务器上,安全;

(5)有效期不同

开发可以通过设置cookie的属性,达到使cookie长期有效的效果;

session依赖于名为JESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session达不到长期有效的效果;

(6)跨域支持上不同

cookie支持跨域;

session不支持跨域;

57、如果客户端禁止 cookie 能实现 session 还能用吗?

一般默认情况下,在会话中,服务器存储 session 的 sessionid 是通过 cookie 存到浏览器里。

如果浏览器禁用了 cookie,浏览器请求服务器无法携带 sessionid,服务器无法识别请求中的用户身份,session失效。

但是可以通过其他方法在禁用 cookie 的情况下,可以继续使用session。

通过url重写,把 sessionid 作为参数追加的原 url 中,后续的浏览器与服务器交互中携带 sessionid 参数。

服务器的返回数据中包含 sessionid,浏览器发送请求时,携带 sessionid 参数。

通过 Http 协议其他 header 字段,服务器每次返回时设置该 header 字段信息,浏览器中 js 读取该 header 字段,请求服务器时,js设置携带该 header 字段。

58、什么是上下文切换?

多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。

概括来说就是:当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时,可以再加载这个任务的状态。任务从保存到再加载的过程就是一次上下文切换。

上下文切换通常是计算密集型的。也就是说,它需要相当可观的处理器时间,在每秒几十上百次的切换中,每次切换都需要纳秒量级的时间。所以,上下文切换对系统来说意味着消耗大量的 CPU 时间,事实上,可能是操作系统中时间消耗最大的操作。

Linux 相比与其他操作系统(包括其他类 Unix 系统)有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少。

59、http 响应码 301 和 302 代表的是什么?有什么区别?

301和302状态码都表示重定向,当浏览器拿到服务器返回的这个状态码后悔自动跳转到一个新的URL地址。

301代表永久性重定向,旧地址被永久移除,客户端向新地址发送请求。

302代表暂时性重定向,旧地址还在,客户端继续向旧地址发送请求。

303代表暂时性重定向,重定向到新地址时,必须使用GET方法请求新地址。

307代表暂时性重定向,与302的区别在于307不允许从POST改为GET。

307代表永久性重定向,与301的区别在于308不允许从POST改为GET。

60、简述 tcp 和 udp的区别?

TCP是传输控制协议,UDP是用户数据表协议;

TCP长连接,UDP无连接;

UDP程序结构较简单,只需发送,无须接收;

TCP可靠,保证数据正确性、顺序性;UDP不可靠,可能丢数据;

TCP适用于少量数据,UDP适用于大量数据传输;

TCP速度慢,UDP速度快;

61、get 和 post 请求有哪些区别?

get请求参数是连接在url后面的,而post请求参数是存放在requestbody内的;

get请求因为浏览器对url长度有限制,所以参数个数有限制,而post请求参数个数没有限制;

因为get请求参数暴露在url上,所以安全方面post比get更加安全;

get请求只能进行url编码,而post请求可以支持多种编码方式;

get请求参数会保存在浏览器历史记录内,post请求并不会;

get请求浏览器会主动cache,post并不会,除非主动设置;

get请求产生1个tcp数据包,post请求产生2个tcp数据包;

在浏览器进行回退操作时,get请求是无害的,而post请求则会重新请求一次;

浏览器在发送get请求时会将header和data一起发送给服务器,服务器返回200状态码,而在发送post请求时,会先将header发送给服务器,服务器返回100,之后再将data发送给服务器,服务器返回200 OK;

62、说一下session的工作原理?

当客户端登录完成后,会在服务端产生一个session,当时服务端会将sessionid返回给客户端浏览器。

客户端将sessionid储存在浏览器的cookie中,当用户再次登陆时,会获得相对应的sessionid,然后

将sessionid发送到服务端请求登录,服务端在内存中找到对用的sessionid,完成登录,如果找不到,返回登录界面。

63、tcp粘包是怎么产生的?

发送方需要等待缓冲区满才能发送出去,造成粘包;

接收方不及时接受缓冲区的包,造成粘包。

64、请列出在jdk中几个常用的设计模式?

1.单例模式

作用:保证类只有一个实例

JDK中体现:Runtime类

2.静态工厂模式

作用:代替构造函数创建对象,方法名比构造函数清晰。

JDK中体现:Integer、valueOf、Class.forName

3.抽象工厂

作用:创建某一中类的对象。

JDK中体现:java.sql包

4.原型模式

Clone();

原型模式的本质是拷贝原型来创建新的对象,拷贝是比new更快的创建对象的方法,当需要大批量

创建新对象而且都是同一个类的对象的时候考虑使用原型模式。

一般的克隆只是浅拷贝(对象的hash值不一样,但是对象里面的成员变量的hash值是不一样的)。

有些场景需要深拷贝,这时我们就要重写clone方法,以ArrayList为例

5.适配器模式

作用:使不兼容的接口相容。

JDK中体现:InputStream、OutputStream。

6.装饰器模式

作用:为类添加新的功能,防止类继承带来的类爆炸。

JDK中体现:io类,Collections,List类。

7.外观模式

作用:封装一组交互类,一直对外提供接口。

JDK中体现:logging包。

8.享元模式

作用:共享对象、节省内存

JDK中体现:Integer,valueOf,String常量池。

9.代理模式

作用:

(1)透明调用被代理对象,无须知道复杂实现细节

(2)增加被代理类的功能

Jdk中体现:动态代理。

10.迭代器模式

作用:将集合的迭代和集合本身分离。

JDK中体现:Iterator

11.命令模式

作用:封装操作,使接口一致。

jdk中体现:Runable、Callable、ThreadPoolExecutor

65、什么是设计模式?是否使用过任何设计模式?

1.什么是设计模式?

设计模式是解决软件开发某些特定问题而提出的一些解决方案,也可以理解为解决问题的一些固定思路。

通过设计模式可以帮助我们增强代码的可复用性,可扩展性,灵活性。

我们使用设计模式的最终目的是实现代码的高内聚,低耦合。

2.设计模式的七大原则

(1)单一职责原则

(2)接口隔离原则

(3)依赖倒转原则

(4)里式替换原则

(5)开闭原则

(6)迪米特法则

(7)合成复用原则

3.

单例模式:jdk中的runtime,spring中的singeton

简单工厂模式:spring的beanfactory,根据传入一个唯一标识来获得bean对象。

原型模式:clone()

代理模式:spring的AOP中,spring实现AOP功能的原理就是代理模式,JDK动态代理,CGLIB动态代理,使用Advice对类进行方法级别的切面增强

装饰器模式:为类添加新的功能,防止类爆炸,IO流、数据源包装,Spring中用到的装饰器模式表现在Wrapper。

66、使用工厂模式最主要的好处是什么?在哪里使用?

1.工厂模式好处

良好的封装性、代码结构清晰

扩展性好,如果想增加一个产品,只需扩展一个工厂类即可

典型的解耦框架

2.在哪里使用?

需要生成对象的地方

不同数据库访问

67、什么是Spring框架?Spring框架有哪些主要模块?

Spring是一个控制反转和面向切面的容器框架。

Spring有七大功能模块:

1.Core

Core模块是Spring的核心类库,Core实现了IOC功能。

2.AOP

Apring AOP模块是Spring的AOP库,提供了AOP机制,并提供常见的拦截器,供用户自定义和配置。

3.orm

提供对常用ORM框架的管理和支持,hibernate、mybatis等。

4.Dao

Spring提供对JDBC支持,对JDBC进行封装。

5.Web

对Structs2的支持

6.Context

Context模块提供框架式的Bean的访问方式,其它程序可以通过Context访问Spring的Bean资源,相当于资源注入。

7.MVC

MVC模块为spring提供了一套轻量级的MVC实现,即Spring MVC。

68、使用Spring框架能带来哪些好处?

1.轻量级框架、容器

Spring是一个容器,管理对象的生命周期和配置。基于一个可配置原型prototype,你的bean可以使单利的,也可以每次需要时都生成一个新的实例。

2.控制反转IOC

Spring提供控制反转实现松耦合

3.支持AOP

Spring提供对AOP的支持,它允许将一些通用任务,如安全、事务、日志等进行集中式处理,从而提高了程序的复用性。

4.轻量级框架

5.方便测试

Spring提供Junit4的支持,可以通过注解方便测试spring程序。

6.对Java中很多API进行了封装

7.方便集成各种优秀框架

如Struts、hibernate、mybatis。

8.支持声明式事务处理

只需通过配置就可以完成对事务的管理,而无须手动编程。

69. spring 常用的注入方式有哪些?

  • setter 属性注入
  • 构造方法注入
  • 注解方式注入

70. spring 支持几种 bean 的作用域?

  • spring 支持 5 种作用域,如下:
  • singleton:spring ioc 容器中只存在一个 bean 实例,bean 以单例模式存在,是系统默认值;
  • prototype:每次从容器调用 bean 时都会创建一个新的示例,既每次 getBean()相当于执行 new Bean()操作;
  • Web 环境下的作用域:
  • request:每次 http 请求都会创建一个 bean;
  • session:同一个 http session 共享一个 bean 实例;
  • global-session:用于 portlet 容器,因为每个 portlet 有单独的 session,globalsession 提供一个全局性的 http session。
  • 「注意:」 使用 prototype 作用域需要慎重的思考,因为频繁创建和销毁 bean 会带来很大的性能开销。

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值