java经典面试题—2025

一、Java基础

Java基础知识

1、&和&&的区别?
&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。

2、final, finally, finalize的区别?
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖 此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

3、"= ="和 equals 方法究竟有什么区别?
答:== 操作符: 专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储 的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
equals: 方法是用于比较两个引用对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。

4、String 和StringBuffer的区别?
String 是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。
使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。

5、StringBuffer与StringBuilder的区别?
StringBuffer和StringBuilder类都表示内容可以被修改的字符串,**StringBuilder是线程不安全的,运行效率高,**如果一个字符串变量是在方法里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素了,则用StringBuilder。如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环
境下使用,那么最好用StringBuffer。

6、Overload(重载)和Override(重写)的区别?
两者都是多态的表现
1)重写(Override):
1.1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
1.2)遵循"运行期绑定",根据对象的类型来调用方法
2) 重载(Overload):
2.1)发生在一个类中,方法名称相同,参数列表不同,方法体不同
2.2)遵循"编译期绑定",根据引用的类型来绑定调用方法

篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记【点击此处即可】免费获取

7、接口和抽象类的区别是什么?
1).抽象类可以有构造方法,接口中不能有构造方法。
2).抽象类中可以有普通成员变量,接口中没有普通成员变量
3). 一个类可以实现多个接口,但只能继承一个抽象类
4). 抽象类中可以包含静态方法,接口中不能包含静态方法
5).抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普 通方法。

8、java中实现多态的机制是什么?
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。

9、面向对象的三大特征:
1.封装:
1)类:封装的是对象的属性和行为
2)方法:封装的是特定的业务逻辑实现
3)访问控制修饰符:封装的是访问的权限
2.继承:
1)作用:代码复用
2)超类:所有派生类所共有的属性和行为
接口:部分派生类所共有的行为
派生类:派生类所特有的属性和行为
3)传递性、单一继承,多接口实现
3.多态:
1)意义:行为多态(抽象方法都是多态的)
对象多态(所有对象都是多态的)
2)向上造型、强制类型转换、instanceof判断
3)多态的表现形式:
3.1)重写:根据对象的不同来表现多态
3.2)重载:根据参数的不同来表现多态

10、字节流和字符流的区别?
答:字节流读取的时候,读到一个字节就返回一个字节;字符流使用了字节流读到一个或多个字 节时。先去查指定的编码表,将查到的字符返回。
字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。
只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。

11、Java 中有几种类型的流?
(1)按照流的方向:输入流(inputStream)和输出流(outputStream);
(2)按照实现功能分:节点流(可以从或向一个特定的地方(节点)读写数据。
(3)按照处理数据的单位: 字节流和字符流。字节流继承于 InputStream 和 OutputStrea,字符 流继承于InputStreamReader 和 OutputStreamWriter 。

12、字节流如何转为字符流?
字节输入流转字符输入流通过 InputStreamReader 实现,该类的构造函数可以传入 InputStream 对象。
字节输出流转字符输出流通过 OutputStreamWriter 实现,该类的构造函数可以传入 OutputStream 对象。

13、什么是Java的反射?
在运行状态中,对于任意一个类,都能够知道这个类的属性和方法;

14、反射的作用?
如果给定一个类名,就可以通过反射机制来获取类的所有信息,也可以动态的创建对象和编译;

15、反射的原理?
Java语言在编译之后会生成一个class文件,反射就是通过字节码文件找到其类中的方法和属性等;
反射的实现主要借助以下四个类:
1、Class:类的对象;
2、Constructor:类的构造方法
3、Field:类中的属性对象
4、Method:类中的方法对象

16、什么是反射机制?
答:通过类(Class对象),可以当前类的filed,method,contrutor,interfqce,superClass
,modified等,同是可以通过类实例化一个类,设置属性,唤醒方法。在Spring中一切都是反射。

17、浅克隆和深克隆的区别
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原 有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

18、什么是java序列化,如何实现java序列化?
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

19、java有23中设计模式
设计模式分为三大类:

创建型模式,共五种:
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、
备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

20、单例模式:
什么叫单例模式?
指一个类只有一个实例,且该类能自行创建这个实例的一种模式。
例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪 费,或出现各个窗口显示内容的不一致等错误。
在计算机系统中,还有 Windows 的回收站、操作系统中的文件系统、多线程中的线程池、显卡的驱动程序对 象、打印机的后台处理服务都是单例模式

单例模式有什么特点?
1.单例类只有一个实例对象;
2. 该单例对象必须由单例类自行创建;
3. 单例类对外提供一个访问该单例的全局访问点;
主要:
饿汉式(线程安全,调用效率高,但是不能延时加载)
懒汉式(线程安全,调用效率不高,但是可以延时加载)
其他:
双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题。不建议使用)
静态内部类式(线程安全,调用效率高。但是可以延时加载)
枚举单例(线程安全,调用效率高,不能延时加载)
饿汉模式和懒汉模式相关代码实现

1.饿汉模式,线程安全

  public class Singleton {
 	     private Singleton(){};
 	     private static Singleton instance = new Singleton();
 	     public static Singleton get Instance(){
    	      return instance;
  	    }
	  }

    将需要获取的 instance 实例在类加载的时候就实例化完毕,由于类的加载机制,此时静态变量的实例化只会执行一遍,所以可以保证此实例变量的唯一性。但是此时不具有延迟加载的特性。

    2.面试官又问:线程安全还有其他写法吗?
    懒汉模式,线程不安全 用Synchronized 修饰表示线程安全

      public class Singleton {
          private Singleton(){};
          private static Singleton instance;
          public static Singleton get Instance(){
    	//public synchronized static Singleton get Instance(){Synchronized 修饰表示安全
              if(instance == null){
                  instance = new Singleton();
              }
              return instance;
          }
      }
    

      原来:懒汉模式指的是这个单例类在用的时候会延迟加载,但是这个单例类是线程不安全的,在多线程环境下很容易出现多个实例的情况。

      懒汉模式,线程安全
      原理:只要在上面的线程不安全模式下进行简单的修改就可以编程线程安全的,将 getInstance 方法 用 Synchronized 修饰,确保同一个时刻只能有一个线程访问此方法。

      21、工厂模式:
      简单工厂模式:用来生产同一等级结构中的任意产品(对已有产品新增功能,需要修改源代码)
      虽然能通过工厂来创建对象,但是违反了开闭原则。一旦增加功能需要在原有基础上修改代码。
      工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品,不用修改源代码)
      将工厂类调整为工厂接口,需要什么类型的工厂就使用该类实现该工厂,创建相应的产品。

      22、观察者模式:
      也叫(发布-订阅模式)定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题 对象,这个主题对象在状态发生变化时,会通知所有观察者对象。使它们能够自动更新自己。
      例如:发广播,游戏中大喇叭,群聊
      jdk中提供了抽象主题和抽象观察者的接口,我们可以使用这两个接口来方便的定义自己的观察者模式。

      23、代理模式:
      代理模式分类:

      1. 静态代理(静态定义代理类,我们自己静态定义的代理类。比如我们自己定义一个明星的经纪人类)
      2. 动态代理(通过程序动态生成代理类,该代理类不是我们自己定义的。而是由程序自动生成)比较 重要!!

      24、Java中有那些集合?
      Set,list,map,它们都处于java.util包中,Set、List和Map都是接口,它们有各自的实现类。
      list和set都继承自collection接口
      Set的实现类主要有HashSet,TreeSet和LinkedHashSet:
      List的实现类主要有ArrayList
      Map的实现类主要有HashMap和TreeMap

      25、List,Set和Map的区别?
      List: 有序集合,元素可重复
      Set: 不重复集合,LinkedHashSet按照插入排序,SortedSet可排序,HashSet无序
      Map: map集合是以键值对方式存储;Key无序,唯一;value 不要求有序,允许重复。

      26、HashMap和Hashtable有什么区别?
      1、HashMap是非线程安全的,HashTable是线程安全的。
      2、HashMap的键和值都允许有null值存在,而HashTable则不行。
      3、因为线程安全的问题,HashMap效率比HashTable的要高。
      4、Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
      一般现在不建议用HashTable, ①是HashTable是遗留类,内部实现很多没优化和冗余。②即 使在多线程环境下,现在也有同步的ConcurrentHashMap替代,没有必要因为是多线程而用 HashTable。

      27、Java中的HashMap的工作原理是什么?
      我们知道在Java中最常用的两种结构是数组和模拟指针(引用),几乎所有的数据结构都可以利用这两种来组合实现,HashMap也是如此。实际上HashMap是一个“链表散列”,如下是它数据结构:最左侧是一个数组,数组中的每一个元素都是一个链表,链表的每一个元素都是entry。
      HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,返回的hashCode用于找到bucket位置来储存Entry对象。

      28、Array和ArrayList有什么区别?什么时候应该使用Array而不是ArrayList?
      Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
      Array大小是固定的,ArrayList的大小是动态变化的。
      ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
      对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类 型的时候,这种方式相对比较慢。

      29、ArrayList和LinkedList有什么区别?
      ArrayList和LinkedList都实现了List接口,他们有以下的不同点:
      • ArrayList是基于索引的数据接口**,它的底层是数组**。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素链表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
      • 相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
      • LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
      也可以参考ArrayList vs. LinkedList。

      30、说出ArrayList,Vector, LinkedList的存储性能和特性

      ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而 Linke dList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

      List的子类特点:
      ArrayList:
      底层数据结构是数组,查询快,增删慢,线程不安全,效率高。
      Vector:
      底层数据结构是数组,查询快,增删慢,线程安全,效率低。
      LinkedList:
      底层数据结构是链表,查询慢,增删快,线程不安全,效率高。

      31、HashSet和TreeSet有什么区别?
      HashSet是由一个hash表来实现的,因此,它的元素是无序的。add(),remove(),contains()方法的时间复杂度是O(1)。
      另一方面,TreeSet是由一个树形的结构来实现的,它里面的元素是有序的。因此,add(),remove(),contains()方法的时间复杂度是O(logn)。

      32、HashSet实现原理?
      1、基于HashMap实现的,默认构造函数是构建一个初始容量为16,负载因子为0.75 的HashMap。封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT,它是一个静态的 Object 对象。
      2、当我们试图把某个类的对象当成 HashMap的 key,或试图将这个类的对象放入 HashSet 中保存时,重写该类的equals(Object obj)方法和 hashCode()方法,而且这两个方法的返回值必须保持一致:当该类的两个的 hashCode() 返回值相同时,它们通过 equals() 方法比较也应该返回 true。
      通常来说,所有参与计算 hashCode() 返回值的关键属性,都应该用于作为 equals() 比较的标准。
      3、HashSet的其他操作都是基于HashMap的。

      33、在JAVA中Map和HashMap有什么区别?
      Map集合的特点:
      1、Map集合一次存储两个对象,一个键对象,一个值对象
      2、键对象在集合中是唯一的,可以通过键来查找值
      HashMap特点:
      1、使用哈希算法对键去重复,效率高,但无序
      2、HashMap是Map接口的主要实现类

      34、什么是HashMap
      HashMap实现了Map接口,Map接口对键值对进行映射。Map中不允许重复的键。Map接口有两个基本的实现,HashMap和TreeMap。TreeMap保存了对象的排列次序,而HashMap则不能。HashMap允许键和值为null。HashMap是非synchronized的,但collection框架提供方法能保证HashMap synchronized,这样多个线程同时访问HashMap时,能保证只有一个线程更改Map。
      public Object put(Object Key,Object value)方法用来将元素添加到map中。

      35、HashSet和HashMap的区别
      HashMap HashSet
      HashMap实现了Map接口 HashSet实现了Set接口
      HashMap储存键值对 HashSet仅仅存储对象
      使用put()方法将元素放入map中 使用add()方法将元素放入set中
      HashMap中使用键对象来计算hashcode值 HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode
      可能相同,所以equals()方法用来判断对象的相等性,
      如果两个对象不同的话,那么返回false
      HashMap比较快,因为是使用唯一的键来获取对象 HashSet较HashMap来说比较慢

      36、如何在Java中实现线程?
      由于线程类本身就是调用的Runnable接口所以你可以继承java.lang.Thread 类或者直接调用Runnable接口来重写run()方法实现线程。

      37、线程和进程有什么区别?
      线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。

      38、线程的生命周期?
      线程一共有五个状态,分别如下:
      新建(new):当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
      运行(running):线程获得 CPU 资源正在执行任务(#run() 方法),
      死亡(dead):当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
      堵塞(blocked):由于某种原因导致正在运行的线程让出 CPU 并暂停自己的执行,即进入堵塞状态。直到线程进入可运行(runnable)状态,才有机会再次获得 CPU 资源,转到运行(running)状态。阻塞的情况有三种:
      调用 notify() 方法,回到就绪状态。

      39、创建线程有几种不同的方式?
      有三种方式可以用来创建线程:
      • 继承Thread类
      • 实现Runnable接口
      • 应用程序可以使用Executor框架来创建线程池
      实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别 的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非 常高效的,很容易实现和使用。

      40、sleep() 和 wait() 有什么区别?
      sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
      wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或not ifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

      41、Thread 类中的start() 和 run() 方法有什么区别?
      start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。

      42、同步和异步有何异同,在什么情况下分别使用他们?举例说明。
      如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
      当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。

      43、如何确保N个线程可以访问N个资源同时又不导致死锁?
      使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。

      44、什么是死锁(deadlock)?
      两个进程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是两个进程都陷 入了无限的等待中。

      45、java 线程安全和不安全

      线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。(Vector,HashTab;le)
      线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。(ArrayList,LinkedList,HashMap等)

      46、什么是线程安全?Vector是一个线程安全类吗?
      多个线程可能会同时运行同一段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。很显然你可以将集合类分成两组,线程安全和非线程安全的。Vector 是用同步方法来实现线程安全的, 而和它相似的ArrayList不是线程安全的。

      47、 什么是线程池? 为什么要使用它?
      创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。从JDK1.5开始,Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池,每次处理一个任务;数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)

      48、 如何避免死锁?
      Java多线程中的死锁
      死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:

      互斥条件: 一个资源每次只能被一个进程使用。
      请求与保持条件: 一个进程因请求资源而阻塞时,对已获得的资源保持不放。
      不剥夺条件: 进程已获得的资源,在末使用完之前,不能强行剥夺。
      循环等待条件: 若干进程之间形成一种头尾相接的循环等待资源关系。
      避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。

       篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

      需要全套面试笔记【点击此处即可】免费获取

      49、Java中活锁和死锁有什么区别?
      这是上题的扩展,活锁和死锁类似,不同之处在于处于活锁的线程或进程的状态是不断改变的,活锁可以认为是一种特殊的饥饿。一个现实的活锁例子是两个人在狭小的走廊碰到,两个人都试着避让对方好让彼此通过,但是因为避让的方向都一样导致最后谁都不能通过走廊。简单的说就是,活锁和死锁的主要区别是前者进程的状态可以改变但是却不能继续执行。

      50、有三个线程T1,T2,T3,怎么确保它们按顺序执行?

      在多线程中有多种方法让线程按特定顺序执行,你可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。

      51、守护线程和非守护线程有什么区别?
      程序运行完毕,JVM 会等待非守护线程完成后关闭,但是 JVM 不会等待守护线程

      JVM
      1、什么情况下会发生栈内存溢出?
      1、栈是线程私有的,栈的生命周期和线程一样,每个方法在执行的时候就会创建一个栈帧,它包含局部变量表、操作数栈、动态链接、方法出口等信息,局部变量表又包括基本数据类型和对象的引用;
      2、当线程请求的栈深度超过了虚拟机允许的最大深度时,会抛出StackOverFlowError异常,方法递归调用肯可能会出现该问题;
      3、调整参数-xss去调整jvm栈的大小

      2、什么是类加载器,常见的类加载器有哪些?
      类加载器是指:通过一个类的全限定性类名获取该类的二进制字节流叫做类加载器;
      类加载器分为以下四种:
      启动类加载器:
      用来加载java核心类库,无法被java程序直接引用;
      扩展类加载器:
      用来加载java的扩展库,java的虚拟机实现会提供一个扩展库目录,该类加载器在扩展库目录里面查找并加载java类;
      系统类加载器:
      它根据java的类路径来加载类,一般来说,java应用的类都是通过它来加载的;
      自定义类加载器:
      由java语言实现,继承自ClassLoader;

      3、Java内存模型是什么?
      Java内存模型规定和指引Java程序在不同的内存架构、CPU和操作系统间有确定性地行为。它在多线程的情况下尤其重要。Java内存模型对一个线程所做的变动能被其它线程可见提供了保证,它们之间是先行发生关系。

      4、heap和stack有什么区别?
      java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
      堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

      JDBC
      1、Statement对象
      优点: 在一次批处理中,SQL表现的更加灵活。
      缺点: 速度慢,不能防止SQL攻击

      2、PreparedStatement对象?
      优点: 速度快,可以防止SQL注入攻击
      缺点: 在一次批处理中,SQL不灵活,只处理骨架相同的SQL。

      3、Session生命周期?
      当程序第一次调用到request.getSession()代码时,服务器明确的知道了需要用到session了,此时创建session。
      如果session超过30分钟(可以在web.xml中配置的)没人使用,服务器认为这个session超时了,销毁session。
      明确的调用session.invalidate(),session立即销毁。
      服务器被非正常关闭或web应用被移除出容器,此时随着web应用的销毁session销毁.如果是正常关闭,session会被钝化.当下次服务器正常启动时,没有超时的session还会被活化回来。

      4、session的原理?
      session的原理:在服务器第一次调用request.getSession()方法的时候,会在内存中创建一个session对象,此对象具有一个独一无二的id值,此id值将会以cookie(JSESSIONID)的形式发送给浏览器,浏览器以后每次访问都会带着此cookie,服务器就利用此cookie区分浏览器找到对应的session空间。

      5、cookie与session的区别
      cookie数据存放在客户的浏览器上,session数据放在服务器上
      cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session
      session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE

      Java面试题–数据结构
      具体面试算法题—编程题2023

      1、排序算法对比
      算法 时间复杂度(平均) 最好 最坏 稳定性
      冒泡排序 o(n^2) n o(n^2) 稳定
      插入排序 o(n^2) n o(n^2) 稳定
      选择排序 o(n^2) o(n^2) o(n^2) 不稳定

      2、递归算法:
      优点: 代码简洁、清晰,并且容易验证正确性。
      缺点: 它的运行需要较多次数的函数调用,如果调用层数比较深,需要增加额外的堆栈处理(还有可能出现堆栈溢出的情况),比如参数传递需要压栈等操作,会对执行效率有一定影响。但是,对于某些问题,如果不使用递归,那将是极端难看的代码。在编译器优化后,对于多次调用的函数处理会有非常好的效率优化,效率未必低于循环。

      3.循环算法:
      优点: 速度快,结构简单。
      缺点: 并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环。

      Java面试题–网络

      1、当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤。
      (1)、解析域名。
      (2)、发起TCP的3次握手。
      (3)、建立TCP请求后发起HTTP请求。
      (4)、服务器相应HTTP请求。
      (5)、浏览器得到HTML代码,进行解析和处理JSON数据,并请求HTML代码中的静态资源(JS、CSS、图片等)。
      (6)、浏览器对页面进行渲染。

      2、什么是http协议?
      HTTP协议就是一套基于tcp/ip协议的应用层协议 。简单来说,就是一个基于应用层的通信规范,双方要进行通信,大家都要遵守一个规范,这个规范就是HTTP协议。它规定了客户端(通常是浏览器)和服务器之间的通信方式。

      3、Http与Https的区别:
      HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
      HTTP 是不安全的,而 HTTPS 是安全的
      HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
      在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
      HTTP 无法加密,而HTTPS 对传输的数据进行加密
      HTTP无需证书,而HTTPS 需要CA机构颁发的SSL证书

      6、get和post请求的区别?
      (1)get请求用来从服务器上获得资源,而post是用来向服务器提交数据;
      (2)get将表单中数据按照name=value的形式,添加到action 所指向的URL 后面,并且两者使用"?“连接, 而各个变量之间使用”&“连接;post是将表单中的数据放在HTTP协议的请求头或消息体中,传递到action 所指向URL;
      (3)get传输的数据要受到URL长度限制(1024字节);而post可以传输大量的数据, POST数据是没有限 制的,上传文件通常要使用post方式;
      (4)使用get时参数会显示在地址栏上,如果这些数据不是敏感数据,那么可以使用get;对于敏感数据还 是应用使用post;
      (5)get使用MIME类型application/x-www-form-urlencoded的URL编码(也叫百分号编码)文本的格式传递 参数,保证被传送的参数由遵循规范的文本组成,例如一个空格的编码是”%20"。
      (6)Jsp页面中的FORM标签里的method属性为get时调用doGet(),为post时调用doPost()。

      7、TCP三次握手:
      发送方: 我要和你建立链接?
      接收方: 你真的要和我建立链接么?
      发送方: 我真的要和你建立链接,成功。

      8、为什么 TCP 连接需要三次握手,两次不可以么,为什么?
      为了防止已失效的连接请求报文突然又传送到了服务端,因而产生错误。客户端发出的连接请求报文并未丢失,而是在某个网络节点长时间滞留了,以致延误到链接释放以后的某个时间才到达 Server 。

      9、什么是 TCP 四次挥手?
      四次挥手,简单来说,就是:
      发送方:我要和你断开连接!
      接收方:好的,断吧。
      接收方:我也要和你断开连接!
      发送方:好的,断吧。

      10、tcp与UDP的区别
      TCP 是面向连接的;UDP 是无连接的。
      TCP 是可靠的;UDP 是不可靠的。
      TCP 只支持点对点通信;UDP 支持一对一、一对多、多对一、多对多的通信模式。
      TCP 是面向字节流的;UDP 是面向报文的。
      TCP 有拥塞控制机制;UDP 没有拥塞控制,适合媒体通信。
      TCP 首部开销(20 个字节),比 UDP 的首部开销(8 个字节)要大。

      11、描述Servlet调用过程?
      (1)在浏览器输入地址,浏览器先去查找hosts文件,将主机名翻译为ip地址,如果找不到就再去查 询dns服务器将主机名翻译成ip地址。
      (2)浏览器根据ip地址和端口号访问服务器,组织http请求信息发送给服务器。
      (3)服务器收到请求后首先根据Host请求头判断当前访问的是哪台虚拟主机。
      (4)服务器根据http请求头中的请求URI判断当前访问的是哪个web应用。
      (5)服务器根据http请求头中的请求URI判断当前访问的是web应用中的哪个web资源。
      (6)检查web应用的web.xml文件,如果根据路径找到具体的servlet处理类的全路径名交给该 ervlet处理,如果找不到就交给缺省servlet处理。
      (7)这个过程中浏览器只知道自己发出来http请求,不久就收到了http响应,浏览器不知道也不关 心服务器内部是如何处理的。浏览器和服务器之间的关系是非常单纯的,只有HTTP协议。
      (8)解析请求、封装RequestResponse对象、创建Servlet、调用Service方法都是服务器自动进 行 的,开发人员只需要写好Servlet配置进容器中即可,无需操心具体的底层实现。

      12、Servlet的生命周期?
      1:实例化:容器收到请求时,会创建一个serlvet实例。
      2:初始化:容器在创建好servlet对象之后,会接着调用servlet对象的init()方法。
      注意:该方法只会执行一次。作用是,获取资源。
      3:就绪:调用servlet对象的service()方法
      4:销毁:容器会依据自身的算法,删除servlet对象。在删除之前,会先调用destroy()方法。

      13、重定向和转发的区别?
      重定向:两次请求,地址改变,可以重定向到外部资源,两次请求不能共享数据;
      转发:一次请求,地址不变,只能转发项目内的资源,转发时2个组件可以共用数据;

      14、404和500是什么意思
      答:404 :找不到url请求的路径,一般是工程名不对或者拼写错误
      500 :服务器内部错误,一般是服务器内部代码编写错误,也有可能是抛异常导致

      二、Java框架

      MyBatis

      1、谈谈你对mybatis架构的理解?
       MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis封装了几乎所有的JDBC代码和参数的手工设置以及结果集的检索;MyBatis使用简单的XML或注解做配置和定义映射关系,将Java的POJOs(Plain Old Java Objects)映射城数据库中的记录.
      MyBatis的优缺点
      优点:
      1、简单易学
      mybatis本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
      2、灵活
      mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和 优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
      3、解除sql与程序代码的耦合
      通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元 测试。sql和代码的分离,提高了可维护性。
      4、提供映射标签,支持对象与数据库的orm字段关系映射
      5、提供对象关系映射标签,支持对象关系组建维护
      6、提供xml标签,支持编写动态sql。

      缺点:
      1、编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
      2、SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
      3、框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
      4、二级缓存机制不佳。
      总结
      mybatis的优点同样是mybatis的缺点,正因为mybatis使用简单,数据的可靠性、完整性的瓶颈便更多依赖于程序员对sql的使用水平上了。sql写在xml里,虽然方便了修改、优化和统一浏览,但可读性很低,调试也非常困难,也非常受限。
      mybatis没有hibernate那么强大,但是mybatis最大的优点就是简单小巧易于上手,方便浏览修改sql

      2、MyBatis核心文件
      MyBatis 核心应用组件:
      配置文件(提供基础配置信息,例如连接配置,缓存配置,映射配置)
      映射文件(定义SQL映射):ORM

      3、MyBatis 核心API
      SqlSessionFactoryBuilder (负责读取配置文件,创建SqlSessionFactory对象)
      SqlSessionFactory(负责创建SqlSession对象)
      SqlSession(负责连接的维护,事务的处理,类似JDBC中的Connection)

      4、MyBatis 框架编程中映射文件内部的对象别名配置?
      配置文件中通过typeAliases元素进行配置
      应用于映射文件中参数类型(parameterType),结果类型(resultType)

      5、#{}和${}的区别是什么?

      1. #{} 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符,一个 #{ } 被解析为一个参数占位符;而${}仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。

      2. #{} 解析之后会将String类型的数据自动加上引号,其他数据类型不会;而${} 解析之后是什么就是什么,他不会当做字符串处理。

      3. #{} 很大程度上可以防止SQL注入(SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作);而${} 主要用于SQL拼接的时候,有很大的SQL注入隐患。

      4. 在某些特殊场合下只能用${},不能用#{}。例如:在使用排序时ORDER BY ${id},如果使用#{id},则会被解析成ORDER BY “id”,这显然是一种错误的写法。

      6、Mybatis是如何进行分页的?分页插件的原理是什么?
      答:Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
      分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

      举例: select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10

      10、MyBatis实现一对一有几种方式?具体怎么操作的
      有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap里面配置association节点配置一对一的类就可以完成;
      嵌套查询是先查一个表,根据这个表里面 的结果的外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表 的查询通过select属性配置

      11、MyBatis实现一对多有几种方式,怎么操作的
      有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,通过在resultMap里面配 置collection节点配置一对多的类就可以完成;
      嵌套查询是先查一个表,根据这个表里面的 结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的 查询通过select节点配置

      13、Mybatis 和 Mybatis Plus 的区别
      Mybatis-Plus是一个Mybatis的增强工具,只是在Mybatis的基础上做了增强却不做改变,MyBatis-Plus支持所有Mybatis原生的特性,所以引入Mybatis-Plus不会对现有的Mybatis构架产生任何影响。

      MyBatis-Plus 优点
      1、依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring 。
      2、损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 。
      3、预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击 。
      4、通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 。
      5、多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题 。
      6、支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
      7、支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
      8、支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码(生成自定义文件,避免开发重复代码),支持模板引擎、有超多自定义配置等。
      9、支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )。
      10、支持关键词自动转义:支持数据库关键词(order、key…)自动转义,还可自定义关键词 。
      11、内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询。
      12、内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询 。
      13、内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作。
      14、默认将实体类的类名查找数据库中的表,使用@TableName(value=”table1”)注解指定表名,@TableId指定表主键,若字段与表中字段名保持一致可不加注解。

      Spring框架

      1、什么是spring?
      spring 是个Java企业级应用的开源开发框架。Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用。
      Spring 框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯

      2、使用Spring框架的好处是什么?
      轻量:Spring 是轻量的,基本的版本大约2MB。
      控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
      面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
      容器:Spring 包含并管理应用中对象的生命周期和配置。
      MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
      事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
      异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,hibernate or JDO抛出的)转化为一致的unchecked 异常。

      3、什么是IOC
      1.IOC就是控制反转,就是将对象创建的权利交给spring容器来完成。
      从此程序员无需关注对象的创建过程。spring容器来维护对象的生命周期。

      4、什么是AOP
      1.切面(Aspect):就是完成额外任务的类
      2.连接点(Joinpoint):就是调用的目标方法
      3.通知(Advice):切面中的方法
      4.切入点(Pointcut):匹配连接点的断言。(执行通知的if,就是一个匹配规则)

      5、 IOC的优点是什么?
      IOC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。

      6、AOP的实现原理
      当获取对象时,首先将对象与切入点表达式进行匹配。如果匹配成功,
      则会创建代理对象。然后代理对象执行方法时就会执行通知。

      7、 在Spring AOP 中,关注点和横切关注的区别是什么?
      关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。
      横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如
      日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点

      8、 解释Spring支持的几种bean的作用域。
      Spring框架支持以下五种bean的作用域:
      singleton : bean在每个Spring ioc 容器中只有一个实例。
      prototype: 一个bean的定义可以有多个实例。
      request: 每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
      session: 在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
      global-session: 在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
      缺省的Spring bean 的作用域是Singleton.

      9、spring的核心类有哪些
      BeanFactory:产生一个新的实例,可以实现单例模式
      BeanWrapper:提供统一的get及set方法
      ApplicationContext:提供框架的实现,包括BeanFactory的所有功能

      10、spring的接口有哪些
      1.BeanFactory最基础最核心的接口
      2.Resource接口,可以通用地访问文件资源
      3.FactoryBean工厂bean
      4.MessageSource接口

      11、spring事务的回滚策略
      1.运行时异常:
      如果程序出现运行时异常,那么错误级别较高,spring会自动的回滚事务。
      2.检查异常:
      对于检查异常而言,spring认为检查异常是可以避免的,程序员 可以修复的,
      那么spring容器就不负责回滚检查异常。

      12、 Spring框架的事务管理有哪些优点?
      它为不同的事务API 如 JTA,JDBC,Hibernate,JPA 和JDO,提供一个不变的编程模式。
      它为编程式事务管理提供了一套简单的API而不是一些复杂的事务API如
      它支持声明式事务管理。
      它和Spring各种数据访问抽象层很好得集成

      13、解释Spring Bean的生命周期?
      在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。
      Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。
      1.初始化之后调用的回调方法。
      2.销毁之前调用的回调方法。

      Spring框架提供了以下四种方式来管理bean的生命周期事件:
      InitializingBean和DisposableBean回调接口
      针对特殊行为的其他Aware接口
      Bean配置文件中的Custom init()方法和destroy()方法
      @PostConstruct和@PreDestroy注解方式

      14、Spring框架中的单例Beans是线程安全的么?
      Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),
      所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。
      最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”。

      15、Spring 框架中都用到了哪些设计模式?
      代理模式—在AOP和remoting中被用的比较多。
      单例模式—在spring配置文件中定义的bean默认为单例模式。
      模板方法—用来解决代码重复的问题。
      比如. RestTemplate, JmsTemplate, JpaTemplate。
      前端控制器—Srping提供了DispatcherServlet来对请求进行分发。
      视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。
      依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念。
      工厂模式—BeanFactory用来创建对象的实例。

      Spring MVC框架

      1、什么是Spring MVC ?简单介绍下你对springMVC的理解?
      Spring MVC是一个基于MVC架构的用来简化web应用程序开发的应用开发框架,它是Spring的一个模块,无需中间整合层来整合 ,它和Struts2一样都属于表现层的框架。在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。

      2、SpringMVC的优点和缺点:
      优点:
      (1)使用简单,学习成本低。
      (2)很容易就可以写出性能优秀的程序.
      (3)灵活性强,Spring MVC的框架易扩展
      缺点:
      (1)Spring与MVC 的Servlet API 耦合,难以脱离容器独立运行
      (2)太过于细分,开发效率低
      (3)过度追求完美,有过度设计的危险解决的问题领域是:网站应用程序或者服务开发
      —— URL路由、Session、模板引擎、静态Web资源等等。

      3、Spring MVC的主要组键?
      (1)前端控制器 DispatcherServlet(不需要程序员开发)
      作用:接收请求、响应结果 相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
      (2)处理器映射器HandlerMapping(不需要程序员开发)
      作用:根据请求的URL来查找Handler
      (3)处理器适配器HandlerAdapter
      注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
      (4)处理器Handler(需要程序员开发)
      (5)视图解析器 ViewResolver(不需要程序员开发)
      作用:进行视图的解析 根据视图逻辑名解析成真正的视图(view)
      (6)视图View(需要程序员开发jsp)
      View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)

      4、SpringMVC工作原理:
      在这里插入图片描述
      1.spring mvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。
      2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller.
      3.DispatcherServlet请请求提交到目标Controller
      4.Controller进行业务逻辑处理后,会返回一个ModelAndView
      5.Dispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象
      6.视图对象负责渲染返回给客户端。

      5、Springmvc 拦截器
      概念:Java 里的拦截器是动态拦截 action 调用的对象。它提供了一种机制可以使开发者可以定义在一个 action 执行的前后执行的代码,也可以在一个 action 执行前阻止其执行,同时也提供了一种可以提取 action 中可重用部分的方式。在AOP(Aspect-Oriented Programming,面向切面编程)中拦截器用于在某个方法或字段被访问之前进行拦截,然后在之前或之后加入某些操作。
      **原理:**拦截器 Interceptor 的拦截功能是基于 Java 的动态代理来实现的,具体可以参考博文“ 用 Java 实现拦截器 Interceptor 的拦截功能 ”,也可以通过阅读 Spring 源代码来了解更为权威的实现细节。
      实现方法:在 Spring 框架之中,咱们要想实现拦截器的功能,主要通过两种途径,第一种是实现HandlerInterceptor接口,第二种是实现WebRequestInterceptor接口。接下来,咱们分别详细的介绍两者的实现方法。
      应用场景:
      1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
      2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
      3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
      4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
      5、OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。
      …………本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。

      实现方法:
      preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Controller实现);
      返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
      postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
      afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。

      6、拦截器的调用:
      Web请求被DispatcherServlet截获后,会调用DispatcherServlet的doDispatcher方法。在HandlerAdapter处理之后,以及处理完成之后会调用HandlerExecutionChain的方法。用内部实现HandlerInterceptor该接口集合的各个对应方法。

      7、MVC设计模式
      MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式: [1]
      Model(模型) 表示应用程序核心(比如数据库记录列表)。
      View(视图) 显示数据(数据库记录)。
      Controller(控制器) 处理输入(写入数据库记录)。
      MVC 模式同时提供了对 HTML、CSS 和 JavaScript 的完全控制。
      Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
      View(视图)是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
      Controller(控制器)是应用程序中处理用户交互的部分。
      通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
      MVC 分层有助于管理复杂的应用程序,因为您可以在一个时间内专门关注一个方面。例如,您可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。MVC 分层同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。

      8、springMVC和struts2的区别有哪些?
      (1)springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。
      (2)springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
      (3)Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。
      (4)springmvc可以单例开发,struts2只能是多例开发。

      9、SpringMVC怎么样设定重定向和转发的,以及他们的区别?
      (1)在返回值前面加"forward:“就可以让结果转发,譬如"forward:user.do?name=method4”
      (2)在返回值前面加"redirect:"就可以让返回值重定向,譬如"redirect:http://www.baidu.com”
      1、转发是一次请求,一次响应,而重定向是两次请求,两次响应。
      2、转发:servlet和jsp共享一个request,重定向:两次请求request独立,所以前面request里面 setAttribute()的任何东西,在后面的request里面都获取不到
      3、转发:地址栏不会改变,重定向:地址栏发生变化。

      10、SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决?
      答:是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写字段。

      11、@RequestMapping注解用在类上面有什么作用?
      答:是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
      怎么样把某个请求映射到特定的方法上面?
      答:直接在方法上面加上注解@RequestMapping,并且在这个注解里面写上要拦截的路径。

      三、Java微服务

      Spring boot

      1、SpringBoot简介
      SpringBoot 是一个快速开发的框架, 封装了Maven常用依赖、能够快速的整合第三方框架;简化XML配置,全部采用注解形式,内置Tomcat、Jetty、Undertow,帮助开发者能够实现快速开发,SpringBoot的Web组件 默认集成的是SpringMVC框架。

      SpringBoot原理介绍:

      1. 能够帮助开发者实现快速整合第三方框架 (原理:Maven依赖封装)
      2. 去除xml配置 完全采用注解化 (原理:Spring体系中内置注解方式)
      3. 无需外部Tomcat、内部实现服务器(原理:Java语言支持创建Tomcat服务器)

      2、Spring Boot优点?
      快速创建独立运行的spring项目与主流框架集成
      使用嵌入式的servlet容器,应用无需打包成war包
      starters自动依赖与版本控制
      大量的自动配置,简化开发,也可修改默认值
      准生产环境的运行应用监控
      与云计算的天然集成

      3、Spring Boot 缺点?
      入门简单精通难,各种强大的功能封装的太好了,内部原理比较难得参透!再就是用多了容易产 生依赖,就像嗑药似的,用了就离不开了;SpringBoot一旦出了错误,由于内部封装比较深,部分 错误调试难度比一般Spring应用程序要大很多

      4、SpringBoot和SpringMVC区别
      SpringBoot 是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,内置Tomcat容器,帮助开发者能够实现快速开发,SpringBoot的Web组件 默认集成的是SpringMVC框架。
      SpringMVC是控制层。

      5、SpringBoot和SpringCloud区别
      SpringBoot 是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,内置Tomcat容器,帮助开发者能够实现快速开发,SpringBoot的Web组件 默认集成的是SpringMVC框架。
      SpringMVC是控制层。
      SpringCloud依赖与SpringBoot组件,使用SpringMVC编写Http协议接口,同时SpringCloud是一套完整的微服务解决框架。

      6、Spring Boot 提供了哪些核心功能?
      1、独立运行 Spring 项目
      2、内嵌 Servlet 容器
      Spring Boot 可以选择内嵌 Tomcat、Jetty 或者 Undertow,这样我们无须以 war 包形式部署项目。
      3、提供 Starter 简化 Maven 配置
      例如,当你使用了 spring-boot-starter-web ,会自动加入如下依赖:spring-boot-starter-web 的 pom 文件

      7、自动配置 Spring Bean
      Spring Boot 检测到特定类的存在,就会针对这个应用做一定的配置,进行自动配置 Bean ,这样会极大地减少我们要使用的配置。

      8、准生产的应用监控
      Spring Boot 提供基于 HTTP、JMX、SSH 对运行时的项目进行监控。

      9、如何重新加载Spring Boot上的更改,而无需重新启动服务器?
      这可以使用DEV工具来实现。通过这种依赖关系,您可以节省任何更改,嵌入式tomcat将重新启动。
      Spring Boot有一个开发工具(DevTools)模块,它有助于提高开发人员的生产力。Java开发人员面临的一个主要挑战是将文件更改自动部署到服务器并自动重启服务器。
      开发人员可以重新加载Spring Boot上的更改,而无需重新启动服务器。这将消除每次手动部署更改的需要。Spring Boot在发布它的第一个版本时没有这个功能。
      这是开发人员最需要的功能。DevTools模块完全满足开发人员的需求。该模块将在生产环境中被禁用。它还提供H2数据库控制台以更好地测试应用程序。
      org.springframework.boot
      spring-boot-devtools
      true

      10、创建一个 Spring Boot Project 的最简单的方法是什么?
      Spring Initializr 是创建 Spring Boot Projects 的一个很好的工具

      11、运行 Spring Boot 有哪几种方式?
      1、打包成 Fat Jar ,直接使用 java -jar 运行。目前主流的做法,推荐。
      2、在 IDEA 或 Eclipse 中,直接运行应用的 Spring Boot 启动类的 #main(String[] args) 启动。适用于开发调试场景。
      3、如果是 Web 项目,可以打包成 War 包,使用外部 Tomcat 或 Jetty 等容器。

      12、Spring Boot中的监视器是什么?
      Spring boot actuator是spring启动框架中的重要功能之一。Spring boot监视器可帮助您访问生产环境中正在运行的应用程序的当前状态。
      有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为HTTP URL访问的REST端点来检查状态。

      13、什么是starter?
      Starter主要是用来简化maven依赖

      14、Spring Boot 常用的 Starter 有哪些?
      spring-boot-starter-web :提供 Spring MVC + 内嵌的 Tomcat 。
      spring-boot-starter-data-jpa :提供 Spring JPA + Hibernate 。
      spring-boot-starter-data-redis :提供 Redis 。
      mybatis-spring-boot-starter :提供 MyBatis 。

      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

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

      抵扣说明:

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

      余额充值