JAVA面试题学习

本文是转载的JAVA面试题,希望在两周之内能够完成所有面试题的填充,持续更新

一、Java 基础

1.JDK 和 JRE 有什么区别?
JDK:JAVA Development Kit java开发包
JRE:JAVA Runtime Environment java运行环境
从名字上我们就很容易看出,JRE是JDK的子集,举个例子,如果只是想要运行简单的.class文件文件,只需要安装JRE就可以完成。如下图,如果相要编译.java文件,就需要JDK中包含的开发工具和编译器。值得一提的是,如果要使用 JSP 部署 Web 应用程序,那么从技术上讲,您只是在应用程序服务器中运行 Java 程序。那你为什么需要 JDK 呢?因为应用程序服务器会将 JSP 转换为 Java servlet,并且需要使用 JDK 来编译 servlet。
在这里插入图片描述
总体来看,JDK包含JRE和JVN,JRE又包含JVM。一般来说JDK中会有两个JRE:与JDK平行的JRE和JDK目录下的JDE,二者基本相同。jdk中带有jre是因为:

① jdk是开发包,在开发中肯定要运行调试,从逻辑上讲,jdk中包含jre也是必要的;

② jdk的很多命令比如javac等,本身也是由java写的应用程序,其运行需要jre环境的支持;

③ 单独的jre比jdk下的jre多了服务端的JVM,而独立的jre是安装时候就默认添加进系统的环境变量中的,jdk下的jre需要手动添加。

原文链接:https://blog.csdn.net/ProLayman/article/details/100120289
2.== 和 equals 的区别是什么?

= =的作用是判断两个对象的地址是不是相等。也就是判断两个对象是不是同一个对象(基本数据类型比较的是值,引用数据类型 ”= =“ 比较的是内存地址)。
equals():它的作用也是判断两个对象是否相等。但他一般具有两种情况:
情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来比较两个对象的内容是否相等;若它们的内容相等,则返回 true (即,认为这两个对象相等。
String中的equals方法是被重写过的,

String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);

这两个返回的结果都是true
这就涉及到了内存的常量池,常量池属于方法区的一部分,当s1创建对象时,如果常量池中没有,就在常量池中创建一个对象“abc”,String是属于final的,第二次创建时,就直接从常量池中取。所以这两个对象其实都是同一个对象。他们地址相同

String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2));
System.out.println(str1 == str2);

这个例子中,第一个返回true,第二个返回flase
这里创建了两次对象,第一次是常量池中创建的“abc”,第二次是在堆内存中创建了对象str1.所以str1和str2地址不同

3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
不对,hashCode()相同,equals()不一定为true
重写equals时必须重写hashCode方法,以HashSet如何检查重复为例来说明为什么要有hashCode:我们都知道HashSet不允许有重复元素,当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与该位置其他已经加入的对象的 hashcode 值作比较,如果没有相符的 hashcode,HashSet 会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。

hashCode()与 equals()的相关规定

1.如果两个对象相等,则 hashcode 一定也是相同的
2.两个对象相等,对两个对象分别调用 equals 方法都返回 true
3.两个对象有相同的 hashcode 值,它们也不一定是相等的
4.因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
5.hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

4.final 在 java 中有什么作用?

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

6.String 属于基础的数据类型吗?

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

8.String str="i"与 String str=new String(“i”)一样吗?

不一样
String str=“i”中,“i”被创建在常量池中,

  1. 首先在常量池中查找是否存在内容为"abc"字符串对象
  2. 如果不存在则在常量池中创建"abc",并让str引用该对象
  3. 如果存在则直接让str引用该对象

String str=new String(“i”)中创建了两次对象(如果常量池中没有“i”)

1.首先在堆中(不是常量池)创建一个指定的对象"abc",并让str引用指向该对象
2.在字符串常量池中查看,是否存在内容为"abc"字符串对象
3.若存在,则将new出来的字符串对象与字符串常量池中的对象联系起来
4.若不存在,则在字符串常量池中创建一个内容为"abc"的字符串对象,并将堆中的对象 与之联系起来

9.如何将字符串反转?

 [详情](https://blog.csdn.net/qq_37701443/article/details/81612099)

10.String 类的常用方法都有那些?

   https://blog.csdn.net/qq_25406669/article/details/79021911

11.抽象类必须要有抽象方法吗?

12.普通类和抽象类有哪些区别?

  1. 抽象类不需要实现方法的具体功能
  2. 抽象类不能被实例化
  3. 含有抽象方法的类必须被声明为抽象类
  4. 抽象类的子类必须实现抽象类的所以抽象方法,不然这个子类也是抽象类
  5. 抽象方法不能被声明为静态、不能用private、final修饰

13.抽象类能使用 final 修饰吗?

  • 不能,因为抽象类的产生就是为了被其他类继承实现,用final修饰的抽象类没有任何意义

14.接口和抽象类有什么区别?

  1. 接口的方法默认是public,所有方法在接口中不能有实现(Java 8开始接口方法可以有默认实现),而抽象类可以有非抽象的方法。
  2. 接口中除了static、final变量,不能有其他变量,而抽象类中则不一定
  3. 一个类可以实现多个接口,但只能继承一个抽象类。接口自己本身可以通过extends关键字扩展多个接口。
  4. 接口方法默认修饰符是public,抽象方法可以有public、protected和default这些修饰符(抽象方法就是为了被重写所以不能使用private关键字修饰!)。
  5. 从设计层面来说,抽象是对类的抽象,是一种模板设计,而接口是对行为的抽象,是一种行为的规范。

备注:

  1. 在 JDK8 中,接口也可以定义静态方法,可以直接用接口名调用。实现类和实现是不可以调用的。如果同时实现两个接口,接口中定义了一样的默认方法,则必须重写,不然会报错。
  2. jdk9的接口被允许定义私有方法
    总结一下 jdk7~jdk9 Java 中接口概念的变化:
    1、在 jdk 7 或更早版本中,接口里面只能有常量变量和抽象方法。这些接口方法必须由选择实现接口的类实现。
    2、jdk8 的时候接口可以有默认方法和静态方法功能。
    3、Jdk 9 在接口中引入了私有方法和私有静态方法。

15.java 中 IO 流分为几种?

  • 按照流的流向分,可以分为输入流和输出流
  • 按照操作单元划分,可以划分为字节流和字符流
  • 按照流的角色划分,可以分为节点流和处理流

Java Io流共涉及40多个,看似杂乱,实则很有规律,全部的IO流都是从以下四个抽象类基类中派生出来的

  • InputStream/Reader:所有的输入流的基类,前者是字节输入流,后者是字符输入流。
  • OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流。
    在这里插入图片描述
    在这里插入图片描述
    字符流是由Java虚拟机将字节转换得到的,问题就出在这个过程还算是非常耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。所以, I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。
    16.BIO、NIO、AIO 有什么区别?
  • BIO(Blocking I/O): 同步阻塞 I/O 模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机 1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的 I/O 并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。
  • NIO (Non-blocking/New I/O): NIO 是一种同步非阻塞的 I/O 模型,在 Java 1.4 中引入了 NIO 框架,对应 java.nio 包,提供了 Channel , Selector,Buffer 等抽象。NIO 中的 N 可以理解为 Non-blocking,不单纯是 New。它支持面向缓冲的,基于通道的 I/O 操作方法。 NIO 提供了与传统 BIO 模型中的 Socket 和 ServerSocket 相对应的 SocketChannel 和 ServerSocketChannel 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。对于低负载、低并发的应用程序,可以使用同步阻塞 I/O 来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发
  • AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的 IO 模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO 是异步 IO 的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO 操作本身是同步的。

17.Files的常用方法都有哪些?

  • Files.exists() 检测文件路径是否存在
  • Files.createFile()创建文件
  • Files.createDirectory()创建文件夹
  • Files.delete() 删除文件或者目录
  • Files.copy() 复制文件
  • Files.move() 移动文件
  • Files.size()查看文件个数
  • Files.read() 读取文件
  • Files.write()写入文件

二、容器

18.java 容器都有哪些?

  • Map、Set、List

19.Collection 和 Collections 有什么区别?
    Collection本身是一个集合类接口,是List和Set的父接口;
    
    Collections是一个集合工具类,包含一些对集合的排序,搜索以及序列化的操作;

    public static <T> void sort (List<T> list):排序,默认情况下是自然排序
      public static <T> int binarySearch (List<?> list, T key):二分查找
    public static <T> T max (Collection<?> coll):最大值(最小值类似用法)
    public static void reverse (List<?> list) :顺序反转
    public static void shuffle (List<?> list):随机置换

20.List、Set、Map 之间的区别是什么?

  • List(有序集合):存储一组不唯一(多个元素可以引用相同的对象)、有序的对象
  • Set(独一无二):存储的元素不允许引用相同的对象
  • Map(Key搜索):通过键值对的形式存储元素,可以引用相同对象,但key值不能相同

21.HashMap 和 Hashtable 有什么区别?

  1. 线程是否安全:hashMap是非线程安全的,hashTable线程安全,HashTable 内部的方法基本都经过synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap );
  2. 效率:因为线程安全的缘故,hashMap效率要高于hashTable,但hashTable已经被弃用,不要在代码中使用它
  3. 对Null key 和Null value的支持: HashMap 中,null 可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为 null。。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛出 NullPointerException。
  4. 初始容量大小和每次扩充容量大小的不同: ①创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小(HashMap 中的tableSizeFor()方法保证,下面给出了源代码)。也就是说 HashMap 总是使用2的幂作为哈希表的大小,后面会介绍到为什么是2的幂次方。
  5. 底层数据结构:JDK1.8以后hashMap在解决哈希冲突时有了较大变化,当链表长度大于阈值(默认为8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。

hashMap中带有初始容量的构造函数

public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }
     public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

下面这个方法保证了 HashMap 总是使用2的幂作为哈希表的大小。

/**
     * Returns a power of two size for the given target capacity.
     */
    static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

22.如何决定使用 HashMap 还是 TreeMap?

需要根据键值获取到元素值时就选用Map接口下的集合,需要排序时选择TreeMap,不需要排序时就选择HashMap,需要保证线程安全就选用ConcurrentHashMap

23.说一下 HashMap 的实现原理?

  • HashMap是一个映射存储集合,通过键值对的方式存储元素。底层使用数组+链表/红黑树实现。通过hash算法将存入元素的key值计算出一个散列值,存入对应的Node节点(Node是HashMap中的一个内部类,实现了Map.Entry接口,本质是就是一个映射(键值对))中,如果发生hash碰撞,就在链表后添加元素(当链表长度大于8时,会先判断哈希桶数组的长度是否大于64,如果小于64就将数组扩容),当链表长度大于8,就会将链表转为红黑树的存储结构,优化查询效率。
  • 值得一提的是,在多线程使用场景中,应该尽量避免使用线程不安全的HashMap,而使用线程安全的ConcurrentHashMap。

24.说一下 HashSet 的实现原理?

  • HashSet底层就是基于hashMap实现的,真正自己实现的代码很少,很多都是直接调用hashmap中的方法实现。HashSet存储的是对象值,添加元素时首先判断哈希值是否相同,如果相同就会通过equals方法来比较对象的内容是否真的相同,如果相同,就不会让操作成功,即HashSet中不会有重复的元素

25.ArrayList 和 LinkedList 的区别是什么?

  1. 是否保证线程安全:两者都不保证线程安全
  2. 底层数据结构: Arraylist 底层使用的是 Object 数组;LinkedList 底层使用的是 双向链表 数据结构(JDK1.6之前为循环链表,JDK1.7取消了循环。注意双向链表和双向循环链表的区别,下面有介绍到!)
  3. 插入和删除是否受元素位置的影响: ① ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行add(E e) 方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是O(1)。但是如果要在指定位置 i 插入和删除元素的话(add(int index, E element) )时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 ② LinkedList 采用链表存储,所以对于add(E e)方法的插入,删除元素时间复杂度不受元素位置的影响,近似 O(1),如果是要在指定位置i插入和删除元素的话((add(int index, E element)) 时间复杂度近似为o(n))因为需要先移动到指定位置再插入。
  4. 是否支持快速随机访问: LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index) 方法)。
  5. 内存空间占用: ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)。

26.如何实现数组和 List 之间的转换?

  • 数组转List:
    1、Arraty.asList()方法
    2、for循环
  • List转数组:
    1、for循环
    2、toArray()

27.ArrayList 和 Vector 的区别是什么?

  • 线程安全方面:ArrayList在多线程中,线程不安全,适合在单线程使用,效率较高。而Vector是一个线程安全的集合。
  • 扩充算法不同:ArrayList第一次添加元素,扩展容量为10,之后的扩充算法:原来数组大小+原来数组的一半;Vector当增量为0时,扩充为原来大小的2倍,当增量大于0时,扩充为原来大小+增量

28.Array 和 ArrayList 有何区别?

  • Array:高效,容量固定且不可动态改变
  • ArrayList:容量可动态增长,但牺牲效率。

29.在 Queue 中 poll()和 remove()有什么区别?

30.哪些集合类是线程安全的?

  • 安全:Vector、hashtable、collections包装方法、java.util.concurrent包中的集合(ConcurrentHashMap)。
    Vector和HashTable被弃用后,它们被ArrayList和HashMap代替,但它们不是线程安全的,所以Collections工具类中提供了相应的包装方法把它们包装成线程安全的集合

31.迭代器 Iterator 是什么?

32.Iterator 怎么使用?有什么特点?

33.Iterator 和 ListIterator 有什么区别?

34.怎么确保一个集合不能被修改?

三、多线程

35.并行和并发有什么区别?

  • **并行:**同一时间段内,多个任务都会发生(不一定是单位时间同时进行)
  • **并发:**单位时间,多个任务同时发生。

36.线程和进程的区别?

  • 线程是进程划分成的更小的运行单位,一个进程可以有多个线程,多个线程共享同一进程的堆和方法区(1.8后的元空间)资源,每个线程有自己的程序计数器、虚拟机栈、本地方法栈。进程之间基本上相互独立,而同一进程中的线程可能会相互影响。
  • 线程运行开销小,但不便于资源的管理和维护,进程则相反。
  • 为什么程序计数器、虚拟机栈、本地方法栈是线程私有的?:
    程序计数器
    主要有下面两个作用:

字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。
需要注意的是,如果执行的是 native 方法,那么程序计数器记录的是 undefined 地址,只有执行的是 Java 代码时程序计数器记录的才是下一条指令的地址。

所以,程序计数器私有主要是为了线程切换后能恢复到正确的执行位置。
虚拟机栈: 每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
本地方法栈:和虚拟机栈所发挥的作用非常相似,区别是: 虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。

37.守护线程是什么?

38.创建线程有哪几种方式?

39.说一下 runnable 和 callable 有什么区别?

40.线程有哪些状态?

  • 线程只可能存在6种状态:
  • 线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。
    在这里插入图片描述

41.sleep() 和 wait() 有什么区别?

  1. 两者最主要的区别在于,sleep()不会释放锁,wait()会释放锁
  2. 两者都可以暂停线程的执行
  3. wati()通常用于线程间交互/通信
  4. wait()方法被执行后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify()或者notifyAll()方法。sleep()方法执行完成后,线程会自动苏醒。或者可以使用 wait(long timeout)超时后线程会自动苏醒。

42.notify()和 notifyAll()有什么区别?

43.线程的 run()和 start()有什么区别?

  • new 一个 Thread,线程进入了新建状态;调用 start() 方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 start() 会执行线程的相应准备工作,然后自动执行 run() 方法的内容,这是真正的多线程工作。 而直接执行 run() 方法,会把 run 方法当成一个 main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。

总结: 调用 start 方法方可启动线程并使线程进入就绪状态,而 run 方法只是 thread 的一个普通方法调用,还是在主线程里执行。

44.创建线程池有哪几种方式?

45.线程池都有哪些状态?

46.线程池中 submit()和 execute()方法有什么区别?

47.在 java 程序中怎么保证多线程的运行安全?

48.多线程锁的升级原理是什么?

49.什么是死锁?

  • 死锁是指多个线程同时被阻塞,他们中的一个或者全部都在等待某个资源被释放,由于线程被无限期阻塞,线程不可能正常终止。
  • 产生死锁需要满足四个条件:
  1. 互斥条件:该资源任意一个时刻只由一个线程占用。
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:线程已获得的资源在末使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

50.怎么防止死锁?

  • 为了避免死锁,我们只要破坏产生死锁的四个条件中的其中一个就可以了。
  1. 破坏互斥条件:这个条件我们没有办法破坏,因为我们用锁本来就是想让他们互斥的(临界资源需要互斥访问)。
  2. 破坏请求与保持条件:一次性申请所有需要的资源
  3. 破坏不剥夺条件:占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。
  4. 破坏循环等待条件:靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。

51.ThreadLocal 是什么?有哪些使用场景?

52.说一下 synchronized 底层实现原理?

  • synchronized底层原理属于JVM层面

53.synchronized 和 volatile 的区别是什么?

54.synchronized 和 Lock 有什么区别?

55.synchronized 和 ReentrantLock 区别是什么?

56.说一下 atomic 的原理?

四、反射

57.什么是反射?

  • 反射是指在运行状态中,对于任意一个类都能够获取这个类的方法和属性;对于任意一个对象,都能够调用它的任意一个属性和方法;这种动态获取的信息以及动态获取的方法称为JAVA的反射机制
  • 获取Class对象的方式有两种:如果我们动态获取到这些信息,我们需要依靠 Class 对象。Class 类对象将一个类的方法、变量等信息告诉运行的程序。Java 提供了两种方式获取 Class 对象:
    1. 知道具体类的情况下
Class alunbarClass = TargetObject.class;

但是我们一般都是不知道具体类的,基本都是通过遍历包下面的类来获取Class对象

    1. 通过class.forName()传入类的路径获取
 Class alunbarClass1 = Class.forName("cn.javaguide.TargetObject");

58.什么是 java 序列化?什么情况下需要序列化?

59.动态代理是什么?有哪些应用?

60.怎么实现动态代理?

五、对象拷贝

61.为什么要使用克隆?

62.如何实现对象克隆?

63.深拷贝和浅拷贝区别是什么?

六、Java Web

64.jsp 和 servlet 有什么区别?

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

66.说一下 jsp 的 4 种作用域?

67.session 和 cookie 有什么区别?

68.说一下 session 的工作原理?

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

70.spring mvc 和 struts 的区别是什么?

71.如何避免 sql 注入?

72.什么是 XSS 攻击,如何避免?

73.什么是 CSRF 攻击,如何避免?

七、异常

74.throw 和 throws 的区别?

75.final、finally、finalize 有什么区别?

76.try-catch-finally 中哪个部分可以省略?

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

78.常见的异常类有哪些?

八、网络

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

80.forward 和 redirect 的区别?

81.简述 tcp 和 udp的区别?

82.tcp 为什么要三次握手,两次不行吗?为什么?

83.说一下 tcp 粘包是怎么产生的?

84.OSI 的七层模型都有哪些?

85.get 和 post 请求有哪些区别?

86.如何实现跨域?

87.说一下 JSONP 实现原理?

九、设计模式

88.说一下你熟悉的设计模式?

89.简单工厂和抽象工厂有什么区别?

十、Spring/Spring MVC

90.为什么要使用 spring?

91.解释一下什么是 aop?

92.解释一下什么是 ioc?

93.spring 有哪些主要模块?

  1. Spring Core 提供Bean工厂IOC:Core封装包是框架的最基础部分,提供IOC和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
  2. Spring AOP 面向切面编程:Spring的 AOP 封装包提供了符合AOP Alliance规范的面向方面的编程实现,让你可以定义,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。而且,利用source-level的元数据功能,还可以将各种行为信息合并到你的代码中。
  3. Spring Context构建于Core封装包基础上的 Context封装包,提供了一种框架式的对象访问方法,有些象JNDI注册器。Context封装包的特性得自于Beans封装包,并添加了对国际化(I18N)的支持(例如资源绑定),事件传播,资源装载的方式和Context的透明创建,比如说通过Servlet容器。
  4. Spring DaoDAO (Data Access Object)提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。 并且,JDBC封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对所有的POJOs(plain old Java objects)都适用。
  5. Spring ORM:ORM 封装包提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPA、JDO、Hibernate 和 iBatis 。利用ORM封装包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,如前边提到的简单声明性事务管理。
  6. Spring Web:Spring中的 Web 包提供了基础的针对Web开发的集成特性,例如多方文件上传,利用Servlet listeners进行IOC容器初始化和针对Web的ApplicationContext。当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。
  7. Spring Web MVC:Spring中的MVC封装包提供了Web应用的Model-View-Controller(MVC)实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和Web Form之间。并且,还可以借助Spring框架的其他特性。

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

95.spring 中的 bean 是线程安全的吗?

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

97.spring 自动装配 bean 有哪些方式?

98.spring 事务实现方式有哪些?

99.说一下 spring 的事务隔离?

100.说一下 spring mvc 运行流程?

101.spring mvc 有哪些组件?

102.@RequestMapping 的作用是什么?

103.@Autowired 的作用是什么?

十一、Spring Boot/Spring Cloud

104.什么是 spring boot?

105.为什么要用 spring boot?

106.spring boot 核心配置文件是什么?

107.spring boot 配置文件有哪几种类型?它们有什么区别?

108.spring boot 有哪些方式可以实现热部署?

109.jpa 和 hibernate 有什么区别?

110.什么是 spring cloud?

111.spring cloud 断路器的作用是什么?

112.spring cloud 的核心组件有哪些?

十二、Hibernate

113.为什么要使用 hibernate?

114.什么是 ORM 框架?

115.hibernate 中如何在控制台查看打印的 sql 语句?

116.hibernate 有几种查询方式?

117.hibernate 实体类可以被定义为 final 吗?

118.在 hibernate 中使用 Integer 和 int 做映射有什么区别?

119.hibernate 是如何工作的?

120.get()和 load()的区别?

121.说一下 hibernate 的缓存机制?

122.hibernate 对象有哪些状态?

123.在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?

124.hibernate 实体类必须要有无参构造函数吗?为什么?

十三、Mybatis

125.mybatis 中 #{}和 ${}的区别是什么?

126.mybatis 有几种分页方式?

127.RowBounds 是一次性查询全部结果吗?为什么?

128.mybatis 逻辑分页和物理分页的区别是什么?

129.mybatis 是否支持延迟加载?延迟加载的原理是什么?

130.说一下 mybatis 的一级缓存和二级缓存?

131.mybatis 和 hibernate 的区别有哪些?

132.mybatis 有哪些执行器(Executor)?

133.mybatis 分页插件的实现原理是什么?

134.mybatis 如何编写一个自定义插件?

十四、RabbitMQ

135.rabbitmq 的使用场景有哪些?

136.rabbitmq 有哪些重要的角色?

137.rabbitmq 有哪些重要的组件?

138.rabbitmq 中 vhost 的作用是什么?

139.rabbitmq 的消息是怎么发送的?

140.rabbitmq 怎么保证消息的稳定性?

141.rabbitmq 怎么避免消息丢失?

142.要保证消息持久化成功的条件有哪些?

143.rabbitmq 持久化有什么缺点?

144.rabbitmq 有几种广播类型?

145.rabbitmq 怎么实现延迟消息队列?

146.rabbitmq 集群有什么用?

147.rabbitmq 节点的类型有哪些?

148.rabbitmq 集群搭建需要注意哪些问题?

149.rabbitmq 每个节点是其他节点的完整拷贝吗?为什么?

150.rabbitmq 集群中唯一一个磁盘节点崩溃了会发生什么情况?

151.rabbitmq 对集群节点停止顺序有要求吗?

十五、Kafka

152.kafka 可以脱离 zookeeper 单独使用吗?为什么?

153.kafka 有几种数据保留的策略?

154.kafka 同时设置了 7 天和 10G 清除数据,到第五天的时候消息达到了 10G,这个时候 kafka 将如何处理?

155.什么情况会导致 kafka 运行变慢?

156.使用 kafka 集群需要注意什么?

十六、Zookeeper

157.zookeeper 是什么?

158.zookeeper 都有哪些功能?

159.zookeeper 有几种部署模式?

160.zookeeper 怎么保证主从节点的状态同步?

161.集群中为什么要有主节点?

162.集群中有 3 台服务器,其中一个节点宕机,这个时候 zookeeper 还可以使用吗?

163.说一下 zookeeper 的通知机制?

十七、MySql

164.数据库的三范式是什么?

165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?

166.如何获取当前数据库版本?

167.说一下 ACID 是什么?

  • ACID是指事物的四大特性,分别是:
  • 原子性:原子性是指事物是不可分割是一个最小单位,对于一个事物,要么全部完成提交事物,要么失败事物全部回滚,不能存在事物完成一部分的情况;
  • 一致性:指数据库只能从一个一致性状态变成另一种一致性状态,事务前后数据库数据都保证完整性;
  • 隔离性:当多个并发任务操作数据库时,相互之间的操作不能干扰到对方,数据相互隔离;
  • 持久性:数据一旦被存储到数据库,那么他就会永久保存;

168.char 和 varchar 的区别是什么?

169.float 和 double 的区别是什么?

170.mysql 的内连接、左连接、右连接有什么区别?

171.mysql 索引是怎么实现的?

172.怎么验证 mysql 的索引是否满足需求?

173.说一下数据库的事务隔离?

174.说一下 mysql 常用的引擎?

175.说一下 mysql 的行锁和表锁?

176.说一下乐观锁和悲观锁?

177.mysql 问题排查都有哪些手段?

178.如何做 mysql 的性能优化?

十八、Redis

179.redis 是什么?都有哪些使用场景?

180.redis 有哪些功能?

181.redis 和 memecache 有什么区别?

182.redis 为什么是单线程的?

183.什么是缓存穿透?怎么解决?

184.redis 支持的数据类型有哪些?

185.redis 支持的 java 客户端都有哪些?

186.jedis 和 redisson 有哪些区别?

187.怎么保证缓存和数据库数据的一致性?

188.redis 持久化有几种方式?

189.redis 怎么实现分布式锁?

190.redis 分布式锁有什么缺陷?

191.redis 如何做内存优化?

192.redis 淘汰策略有哪些?

193.redis 常见的性能问题有哪些?该如何解决?

十九、JVM

194.说一下 jvm 的主要组成部分?及其作用?

详见:这位博主的描述

195.说一下 jvm 运行时数据区?

JVM分为了线程共享部分和线程私有部分:

  • 线程共享部分有:堆、方法区、直接内存 (非运行时数据区的一部分)

  • 线程私有部分:虚拟机栈、本地方法栈、程序计数器
    堆(Heap):Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。
    Java世界中“几乎”所有的对象都在堆中分配,但是,随着JIT编译期的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。从jdk 1.7开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被外面使用(也就是未逃逸出去),那么对象可以直接在栈上分配内存。
    Java 堆是垃圾收集器管理的主要区域,因此也被称作GC 堆(Garbage Collected Heap).从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代:再细致一点有:Eden 空间、From Survivor、To Survivor 空间等。进一步划分的目的是更好地回收内存,或者更快地分配内存。
    JDK1.7之前,堆内存通常被分为以下三种状态

    1. 新生代内存(Young Generation)
    2. 老生代(Old Generation)
    3. 永生代(Permanent Generation

    JDK 8 版本之后方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 就已经开始了),取而代之是元空间,元空间使用的是直接内存。
    方法区(Method Area):方法区也称为 “永久代” 方法区与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然 Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。
    JDK 1.8 的时候,方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 就已经开始了),取而代之是元空间,元空间使用的是直接内存。
    虚拟机栈(JVM stack) 描述的是java方法执行的内存模型:每个方法被执行的时候都会创建一个"栈帧",用于存储局部变量表(包括参数)、操作栈、方法出口等信息。每个方法被调用到执行完的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。声明周期与线程相同,是线程私有的。栈帧由三部分组成:局部变量区、操作数栈、帧数据区。局部变量区被组织为以一个字长为单位、从0开始计数的数组,和局部变量区一样,操作数栈也被组织成一个以字长为单位的数组。但和前者不同的是,它不是通过索引来访问的,而是通过入栈和出栈来访问的,可以看作为临时数据的存储区域。除了局部变量区和操作数栈外,java栈帧还需要一些数据来支持常量池解析、正常方法返回以及异常派发机制。这些数据都保存在java栈帧的帧数据区中。

    局部变量表: 存放了编译器可知的各种基本数据类型、对象引用(引用指针,并非对象本身),其中64位长度的long和double类型的数据会占用2个局部变量的空间,其余数据类型只占1个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量是完全确定的,在运行期间栈帧不会改变局部变量表的大小空间。
    本地方法栈(Native Stack):与虚拟机栈基本类似,区别在于虚拟机栈为虚拟机执行的java方法服务,而本地方法栈则是为Native方法服务。(栈的空间大小远远小于堆)
    程序计数器(PC Register):是最小的一块内存区域,它的作用是当前线程所执行的字节码的行号指示器,在虚拟机的模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、异常处理、线程恢复等基础功能都需要依赖计数器完成
    直接内存(Direct Memory): 直接内存并不是虚拟机内存的一部分,也不是Java虚拟机规范中定义的内存区域。jdk1.4中新加入的NIO,引入了通道与缓冲区的IO方式,它可以调用Native方法直接分配堆外内存,这个堆外内存就是本机内存,不会影响到堆内存的大小.

196.说一下堆栈的区别?

197.队列和栈是什么?有什么区别?

198.什么是双亲委派模型?

199.说一下类加载的执行过程?

200.怎么判断对象是否可以被回收?

201.java 中都有哪些引用类型?

202.说一下 jvm 有哪些垃圾回收算法?

203.说一下 jvm 有哪些垃圾回收器?

204.详细介绍一下 CMS 垃圾回收器?

205.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

206.简述分代垃圾回收器是怎么工作的?

207.说一下 jvm 调优的工具?

208.常用的 jvm 调优的参数都有哪些?
————————————————
版权声明:本文为CSDN博主「王磊的博客」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sufu1065/article/details/88051083

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值