Java面试考题集锦之Java基础

这篇文章记录在准备Java后端面试复习过程中网上常见的考题,同时也会标明题目出现频率,方便大家参考。有缺少、错误的部分欢迎大家补充纠正。–持续更新
推荐https://download.csdn.net/download/qq_41011723/12255299,基本涵盖了面试题的原理

也欢迎大家来我自己搭建的博客看看,之后博客也会同步更新
hofe’s blog

文章目录

    • 数据类型
          • Java中的八大类型及其包装类型(占用字节数)
          • String类为什么是final的/li>
          • string、stringbuilder、stringbuffer区别/li>
          • String 类的常用方法/li>
    • Java面向对象
          • Java 接口抽象类区别/li>
          • 重载和重写/li>
          • Java对象的生命周期/li>
    • List、Set、Map
        • 高频
      • List
          • ArrayList和LinkedList、Vector的区别/li>
          • ArrayList和LinkedList的区别别用在什么场景/li>
      • Set
        • HashSet
          • 重写equals为何要重写hashCode/li>
        • TreeSet
        • LinkHashSet(HashSet+LinkHashMap)
      • Map
        • HashMap
        • Hashtable
        • CurrentHashMap
        • TreeMap
        • LinkedHashMap
          • hashtable和hashmap的区别及实现原理,
          • Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题
          • 请你说明HashMap和Hashtable的区别/li>
          • HashMap 和 ConcurrentHashMap区别/li>
          • 如何使HashMap变得安全/li>
          • ConcurrentHashMap如何保证线程安全的/li>
        • 常见
          • 请说明Collection 和 Collections的区别/li>
          • HashMap底层实现/li>
          • hash冲突了解哪些/li>
        • 少见
          • Collection集合接口和Map接口有什么关系/li>
          • Map的各种实现类,它们有什么区别/li>
          • Hash冲突怎么办些解决散列冲突的方法/li>
          • HashMap冲突很厉害,最差性能,你会怎么解决/li>
          • rehash
          • hashCode() 与 equals() 生成算法、方法怎么重写
    • JVM
        • 高频
          • JVM 的内存结构/li>
          • 分代/li>
          • 垃圾清除算法/li>
          • 垃圾回收器/li>
          • 类的实例化顺序/li>
          • java的.class加载机制,java到class到二进制字节码文件的转化过程/li>
          • 描述一下JVM加载class文件的原理机制/li>
          • 双亲委派/li>
          • Minor GC和Full GC的触发时机
        • 常见
          • JVM 调优/li>
          • 垃圾回收器的基本原理是什么圾回收器可以马上回收内存吗什么办法主动通知虚拟机进行垃圾回收/li>
          • java中会存在内存泄漏吗,请简单描述。
          • 内存泄漏会导致什么/li>
          • 内存泄漏检查
        • 少见
          • CGLib
          • JVM的作用/li>
    • Java 并发编程
        • 高频
          • 什么是线程/li>
          • 线程和进程有什么区别/li>
          • Java中sleep方法和wait方法的区别/li>
          • Thread 类中的start() 和 run() 方法有什么区别/li>
          • 终止线程4种方式/li>
          • 什么是线程池为什么要使用它/li>
          • 线程池原理/li>
          • Java线程池工作过程 /li>
          • 什么是ThreadLocal/li>
          • Java中Runnable和Callable有什么不同/li>
          • 提交任务时,线程池队列已满。会发生什么工作过程、拒绝策略)
          • 乐观锁与悲观锁/li>
          • 同步锁与死锁/li>
          • 共享锁与独占锁/li>
        • 常见
          • Java中如何停止一个线程/li>
          • 线程基本方法/li>
          • synchronized/li>
          • volatile/li>
          • 如何在Java中实现线程/li>
          • 线程池的组成/li>
          • 线程池,threadpool有哪些重要的参数/li>
          • 拒绝策略 /li>
          • JAVA阻塞队列原理/li>
          • Java中的同步集合与并发集合有什么区别/li>
        • 少见
          • Java中CyclicBarrier 和 CountDownLatch有什么不同/li>
          • Java中如何停止一个线程/li>
          • 一个线程运行时发生异常会怎样/li>
          • 如何在两个线程间共享数据/li>
          • Java中notify 和 notifyAll有什么区别/li>
          • Java中interrupted 和 isInterruptedd方法的区别/li>
          • 为什么wait和notify方法要在同步块中调用/li>
          • 有哪些不同的线程生命周期/li>
          • 你对线程优先级的理解是什么/li>
          • Sleep()、suspend()和wait()之间有什么区别/li>
          • 什么是线程饿死,什么是活锁/li>
          • 什么是Java Timer类何创建一个有特定时间间隔的任务/li>
          • 同步方法和同步块,哪个是更好的选择/li>
          • Java中invokeAndWait 和 invokeLater有什么区别/li>
          • 多线程中的忙循环是什么/li>
    • Java IO
          • 讲讲IO里面的常见类,字节流、字符流、接口、实现类、方法阻塞。
          • 讲讲NIO
          • String 编码UTF-8 和GBK的区别/li>
          • 什么时候使用字节流、什么时候使用字符流/li>
          • 递归读取文件夹下的文件,代码怎么实现
    • 引用
    • 异常
        • 高频
          • Exception 与 Error/li>
        • 常见
          • Throw和throws的区别:
    • 反射
          • 什么是反射/li>
          • Java反射机制的作用/li>
          • 哪里用到反射机制/li>
          • 如何使用Java的反射/li>
          • 反射用到了哪些接口,哪些类/li>
          • 反射机制中可以获取private成员的值吗/li>
          • 反射机制的优缺点/li>
    • 注解
          • Java中有哪些注解SpringMVC中,requestmapping是自定义注解,问:如何实现自定义注解/li>
          • JSR-250注解
          • JSR-330注解
          • JPA注解
          • Spring自带依赖注入注解

图片来源:牛客网面经

Java面试考题集锦之Java基础
String类为什么是final的/h5>

https://www.jianshu.com/p/9c7f5daac283

string、stringbuilder、stringbuffer区别/h5>

https://www.cnblogs.com/liyy7520/p/11899260.html

String 类的常用方法/h5>

equals:字符串是否相同
compareTo:根据字符串中每个字符的Unicode编码进行比较
indexOf:目标字符或字符串在源字符串中位置下标
valueOf:其他类型转字符串
concat:追加字符串到当前字符串
isEmpty:字符串长度是否为0
contains:是否包含目标字符串

Java面向对象

Java 接口抽象类区别/h5>

https://www.cnblogs.com/zzfpz/p/10990210.html

重载和重写/h5>

https://blog.csdn.net/qunqunstyle99/article/details/81007712

Java对象的生命周期/h5>

创建阶段 、 应用阶段 、不可见阶段 、不可达阶段 、收集阶段 、终结阶段、 对象空间重新分配阶段。

创建阶段系统通过下面的几个步骤来完成对象的创建过程

  1. 为对象分配存储空间
  2. 开始构造对象
  3. 从超类到子类对static成员进行初始化
  4. 超类成员变量按顺序初始化,递归调用超类的构造方法
  5. 子类成员变量按顺序初始化,子类构造方法调用
    一旦对象被创建,并被分派给某些变量赋值,这个对象的状态就切换到了应用阶段

应用阶段
对象至少被一个强引用持有着

当一个对象处于不可见阶段时,说明程序本身不再持有该对象的任何强引用,虽然该这些引用仍然是存在着的。

简单说就是程序的执行已经超出了该对象的作用域了

不可达阶段(Unreachable)
对象处于不可达阶段是指该对象不再被任何强引用所持有。
与“不可见阶段”相比,“不可见阶段”是指程序不再持有该对象的任何强引用,这种情况下,该对象仍可能被JVM等系统下的某些已装载的静态变量或线程或JNI等强引用持有着,这些特殊的强引用被称为”GC root”。存在着这些GC root会导致对象的内存泄露情况,无法被回收。

收集阶段(Collected)
当垃圾回收器发现该对象已经处于“不可达阶段”并且垃圾回收器已经对该对象的内存空间重新分配做好准备时,则对象进入了“收集阶段”。则对象进入了“收集阶段”。如果该对象已经重写了finalize()方法,则会去执行该方法的终端操作。

这里要特别说明一下:不要重载finazlie()方法!原因有两点:

  1. 会影响JVM的对象分配与回收速度
    在分配该对象时,JVM需要在垃圾回收器上注册该对象,以便在回收时能够执行该重载方法;在该方法的执行时需要消耗CPU时间且在执行完该方法后才会重新执行回收操作,即至少需要垃圾回收器对该对象执行两次GC。

  2. 可能造成该对象的再次“复活”
    在finalize()方法中,如果有其它的强引用再次持有该对象,则会导致对象的状态由“收集阶段”又重新变为“应用阶段”。这个已经破坏了Java对象的生命周期进程,且“复活”的对象不利用后续的代码管理。

终结阶段
当对象执行完finalize()方法后仍然处于不可达状态时,则该对象进入终结阶段。在该阶段是等待垃圾回收器对该对象空间进行回收

对象空间重新分配阶段
垃圾回收器对该对象的所占用的内存空间进行回收或者再分配了,则该对象彻底消失了,称之为“对象空间重新分配阶段”



List、Set、Map

Java面试考题集锦之Java基础
ArrayList和LinkedList的区别别用在什么场景/h5>

①ArrayList和LinkedList可想从名字分析,它们一个是Array(动态数组)的数据结构,一个是Link(链表)的数据结构,此外,它们两个都是对List接口的实现。
前者是数组队列,相当于动态数组;后者为双向链表结构,也可当作堆栈、队列、双端队列
②当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
③当对数据进行增加和删除的操作时(add和remove操作),LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
④从利用效率来看,ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。
⑤ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。

场景:
链表,插入删除快,查找修改慢。 适用于频繁增删的场景。
数组,查找快,插入删除慢。 适用于频繁查找和修改的场景。

Set

Java面试考题集锦之Java基础

TreeSet

  1. TreeSet()是使用二叉树的原理对新add()的对象按照指定的顺序排序(升序、降序),每增 加一个对象都会进行排序,将对象插入的二叉树指定的位置。
  2. Integer和String对象都可以进行默认的TreeSet排序,而自定义类的对象是不可以的,自 己定义的类必须实现Comparable接口,并且覆写相应的compareTo()函数,才可以正常使 用。
  3. 在覆写compare()函数时,要返回相应的值才能使TreeSet按照一定的规则来排序
  4. 比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整 数、零或正整数

LinkHashSet(HashSet+LinkHashMap)

对于 LinkedHashSet 而言,它继承与 HashSet、又基于 LinkedHashMap 来实现的。 LinkedHashSet 底层使用 LinkedHashMap 来保存所有元素,它继承与 HashSet,其所有的方法 操作上又与HashSet相同,因此LinkedHashSet 的实现上非常简单,只提供了四个构造方法,并 通过传递一个标识参数,调用父类的构造器,底层构造一个 LinkedHashMap 来实现,在相关操 作上与父类HashSet的操作相同,直接调用父类HashSet的方法即可

Map

HashMap

Java面试考题集锦之Java基础
大方向上,HashMap 里面是一个数组,然后数组中每个元素是一个单向链表。上图中,每个绿色 的实体是嵌套类 Entry 的实例,Entry 包含四个属性:key, value, hash 值和用于单向链表的 next。
  1. capacity:当前数组容量,始终保持 2^n,可以扩容,扩容后数组大小为当前的 2 倍。
  2. loadFactor:负载因子,默认为 0.75。
  3. threshold:扩容的阈值,等于 capacity * loadFactor

Java8实现
数组+链表+红黑树
Java8 对 HashMap 进行了一些修改,大的不同就是利用了红黑树,所以其由 数组+链表+红黑 树 组成。
根据 Java7 HashMap 的介绍,我们知道,查找的时候,根据 hash 值我们能够快速定位到数组的 具体下标,但是之后的话,需要顺着链表一个个比较下去才能找到我们需要的,时间复杂度取决 于链表的长度,为 O(n)。为了降低这部分的开销,在 Java8 中,当链表中的元素超过了 8 个以后, 会将链表转换为红黑树,在这些位置进行查找的时候可以降低时间复杂度为 O(logN)。

Java面试考题集锦之Java基础
jdk1.8:segment数组+数组+红黑树
Java面试考题集锦之Java基础
Java面试考题集锦之Java基础
MinorGC的过程
采用复制算法
Java面试考题集锦之Java基础
确定垃圾算法
  • 引用计数法:在 Java 中,引用和对象是有关联的。如果要操作对象则必须用引用进行。因此,很显然一个简单 的办法是通过引用计数来判断一个对象是否可以回收。简单说,即一个对象如果没有任何与之关 联的引用,即他们的引用计数都不为 0,则说明对象不太可能再被用到,那么这个对象就是可回收 对象

  • 可达性分析:为了解决引用计数法的循环引用问题,Java 使用了可达性分析的方法。通过一系列的“GC roots” 对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的。要注意的是,不可达对象不等价于可回收对象,不可达对象变为可回收对象至少要经过两次标记 过程。两次标记后仍然是可回收对象,则将面临回收。

标记清除算法(mark-sweep)
最基础的垃圾回收算法,分为两个阶段,标注和清除。标记阶段标记出所有需要回收的对象,清 除阶段回收被标记的对象所占用的空间
缺陷:大的问题是内存碎片化严重,后续可能发生大对象不能找到可 利用空间的问题

Java面试考题集锦之Java基础

标记整理算法(mark-compact)
结合了以上两个算法,为了避免缺陷而提出。标记阶段和Mark-Sweep算法相同,标记后不是清 理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象

Java面试考题集锦之Java基础
  • 老年代-标记整理算法:因为对象存活率高、没有额外空间对它进行分配担保, 就必须采用“标记—清理”或“标 记—整理”算法来进行回收, 不必进行内存复制, 且直接腾出空闲内存。
    1. JAVA虚拟机提到过的处于方法区的永生代(Permanet Generation),它用来存储class类, 常量,方法描述等。对永生代的回收主要包括废弃常量和无用的类。
    2. 对象的内存分配主要在新生代的Eden Space和Survivor Space的From Space(Survivor目 前存放对象的那一块),少数情况会直接分配到老生代。
    3. 当新生代的Eden Space和From Space空间不足时就会发生一次GC,进行GC后,Eden Space和From Space区的存活对象会被挪到To Space,然后将Eden Space和From Space进行清理。
    4. 如果To Space无法足够存储某个对象,则将这个对象存储到老生代。
    5. 在进行GC后,使用的便是Eden Space和To Space了,如此反复循环。
    6. 当对象在Survivor区躲过一次GC 后,其年龄就会+1。默认情况下年龄到达15 的对象会被 移到老生代中

    分区收集算法:分区算法则将整个堆空间划分为连续的不同小区间, 每个小区间独立使用, 独立回收. 这样做的 好处是可以控制一次回收多少个小区间 , 根据目标停顿时间, 每次合理地回收若干个小区间(而不是 整个堆), 从而减少一次GC 所产生的停顿。

    垃圾回收器/h5>

    Java 堆内存被划分为新生代和年老代两部分,新生代主要使用复制和标记-清除垃圾回收算法; 年老代主要使用标记-整理垃圾回收算法,因此 java 虚拟中针对新生代和年老代分别提供了多种不 同的垃圾收集器,JDK1.6中Sun HotSpot虚拟机的垃圾收集器如下

    Java面试考题集锦之Java基础
    • 新生代垃圾收集器
    1. Serial(英文连续)是基本垃圾收集器,使用复制算法,曾经是JDK1.3.1之前新生代唯一的垃圾 收集器。Serial 是一个单线程的收集器,它不但只会使用一个 CPU 或一条线程去完成垃圾收集工 作,并且在进行垃圾收集的同时,必须暂停其他所有的工作线程,直到垃圾收集结束。 Serial 垃圾收集器虽然在收集垃圾过程中需要暂停所有其他的工作线

      来源:hofe

      声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2020年2月16日
    下一篇 2020年2月16日

    相关推荐