java 面试突击-(21-30)

Posted 栗子~~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 面试突击-(21-30)相关的知识,希望对你有一定的参考价值。

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


java 面试突击-(21-30)

21 常见的内存泄漏有哪些?

21::01 常见性内存泄漏

发生内存泄漏的代码会被多次执行到,每次都会导致一次内存泄漏;

21::02 偶发性内存泄漏

发生内存泄漏的代码只有在某些特定环境和特定操作过程中,才会执行的到;

21::03 一次性内存泄漏

发生内存泄漏的代码只会执行一次,或者由于算法上的缺陷,导致仅有一块代码发生内存泄漏,比如说在单例类型的类构造器中分配内存,在解析函数中没有释放该内存,但是这个类是单例类,一个类只有一个实例,因此只会发生一次内存泄漏;

21::04 隐式性内存泄漏

如果内存分配管理不当,在程序运行时分配的内存,只有在程序终止时才会释放,例:一个服务端程序,运行几天,几周,甚至几个月,不及时释放内存,也会最终导致耗尽系统的全部内存。

注:从用户使用程序的角度来看,内存泄漏不是什么大问题,问题是内存泄漏的堆积,最终导致耗尽系统的全部内存。


22 JVM 垃圾回收原理?

22::01 标识

在标识阶段,所有的被JVM活动状态引用、或者静态的、或者固化字符串以及被JNI引用的对象都被标识,
首先创建了JVM引用的根对象,由于这些根对象会依次引用其他对象,那么标识的第二阶段部分工作就是
从这些跟对象出发,依次扫描其他被引用的对象,这两步工作产生一个活动对象集合,即活动的对象,和被活动对象引用的对象

22::02 清理

标识阶段之后,标识集合中已含有堆中所有可达对象的标识,清理阶段的工作就是将这些已经分配的,但不在引用的对象清理掉。

22::03 压缩

垃圾回收机制,将哪些已经分配但是不在引用的对象从堆中移除之后,将剩下的对象向一侧进行压缩排列,以便移除这些对象之间空闲的空间


23 简单说一下JVM里的栈与堆?

栈是运行时的单位,而堆是存储的单位。
栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;
堆解决的是数据存储的问题,即数据怎么放、放在哪儿;

23::01 栈

栈中存放基础数据类型,自定义对象的引用(非对象),每个线程一个栈区,生命周期与线程相同
栈内数据私用,线程独享;
概念:在java方法所执行的【线程内存模型】中,【每个方法】被执行的时候,java虚拟机栈同步创建一个【栈帧】,用于存储【局部变量表,操作数栈,动态链接,方法出口等信息】。
栈分三部分:基本类型变量、执行环境上下文、操作指令区
特点:每个方法被调用至执行完毕的过程,对应着一个【栈帧】在虚拟机栈中从入栈到出栈的过程。
优缺点:速度快,但是大小、生命周期固定,不灵活

23::02 堆

堆中存放对象。
jvm中只有一个堆区,各线程共享;
概念:虚拟机启动时创建,唯一目的存放对象实例【几乎所有的对象实例以及数组都应当在堆上分配】。
特点:java堆既可以实现成固定大小,也可以是可扩展的【通过参数 -Xmx和-Xms设定】
优缺点:内存是动态的,生命周期不定GC自动回收,速度慢。

注:Main函数就是栈的起始点,也是程序的起始点。


24 什么是JVM类加载机制?

java JVM 把【描述类的数据】从class文件中加载到内存,并对该数据进行验证,转换解析和初始化,最终形成可以
【被虚拟机直接使用的java类型】,这个过程我们成为【JVM的类加载机制】。


25 类加载的五个阶段是什么?

  1. 加载
    1)通过一个类的全路径名来获取【定义此类的二进制字节流】。
    2)将这个字节流中所代表的【静态存储结构】转化为【方法区中的运行时数据结构】。
    3)在内存中生成一个【代表这个类的 java.lang.Class 对象】,作为方法区这个类的各种数据的入口。
  2. 验证
    确保 Class 文件的字节流中包含的信息是否符合【当前虚拟机】的要求,保证这些信息被当做代码运行后,不会对JVM造成自身安全
  3. 准备
    在方法区中分配这些变量所使用的内存空间。
  4. 解析
    虚拟机将常量池中的符号引用替换为直接引用的过程。
  5. 初始化
    执行类中定义的 Java 程序代码。

注:初始化阶段,主要通过类构造器来实现,即初始化阶段是执行类构造器方法的过程


26 什么类型的数据不会初始化?

所有【引用类型】外加【常量】的方式都不会触发初始化,我们称之为【被动引用】,即被动引用不会被初始化。

如:
1)使用类字段:

public class SuperClass 
       static 
              System.out.println("This is SuperClass !!!");
       
       public static int index = 55555;

public class NodeClass extends SuperClass
       static 
              System.out.println("This is NodeClass");
       

通过子类引用父类的静态字段,不会导致子类初始化,对于静态字段,只有直接定于这个字段的类才会初始化。
2)通过数组定义来引用类,不会触发此类的初始化
因为数组是引用类型。
3)常量测试,不会触发定义常量所在类的初始化

public class ConstClass 
       static 
              System.out.println("This is ConseClass");
       
       public static final String HELLO_WORLD  = "hello world !!!";
       public static String index = "Hello World !!!";

因为在源码阶段,确实引用常量类ConstClass中的HELLO_WORLD,但实际上在编译阶段通过常量传播优化,
已经将此常量的值"hello world !!!" 直接存在ConstClass类的常量池中,因此ConstClass类对HELLO_WORLD中的引用,
其实都转化成类对自身【常量池】的引用了。
详情:类加载机制


27 类加载器的特点?

27:: 01 特点

类加载器的特点:双亲委派;
双亲委派的原理和好处

当一个类收到了类加载器的请求时,他首先不会尝试自己去加载这个类,而是把这个请求委派给【父类加载器】去完成,每一个层次的【类加载器】都是如此,因此所有的加载请求都应该传送到最顶层的【启动类加载器】其中, 只有当【当父类加载器】反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的 Class),【子类加载器】才会尝试自己去加载。

27::02 双亲委派打破的例子

OSGI实现的模块化部署打破双亲委派模型;
即在OSGI环境下,类加载器不在是双亲委派模型推荐的【树状结构】,而是进一步发展为更加复杂的【网状结构】。


28 GC 如何判断对象可以被回收?

可达性分析:从GC ROOTS 开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC ROOTS 没有任何引用链时,证明对象不可用,可以被回收。

GC ROOTS是什么?
栈中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象

注:可达性算法中的不可达对象并不是立即死亡!!!
对象拥有一次拯救自己的机会,即对象被系统宣告死亡至少要经历两次标记过程:
第一次可达性分析发现没有与GC ROOTS相连接的引用链,第二次是由虚拟机自动建立的finalizer队列中判断是否要执行
finalizer方法


29 你用过的数据结构都有哪些?

  1. 数组:
    数组是可以再内存中连续存储多个元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进行访问,数组下标从0开始;
  2. 栈:
    栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。 栈的特点是:先进后出,或者说是后进先出;
  3. 队列:
    队列与栈一样,也是一种线性表,不同的是,队列可以在一端添加元素,在另一端取出元素,也就是:先进先出;
  4. 链表:
    链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个结点,一个是存储元素的数据域 (内存空间),另一个是指向下一个结点地址的指针域。根据指针的指向,链表能形成不同的结构,例如单链表,双向链表,循环链表等;
  5. 树:
    树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做 “树” 是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
    1)、每个节点有零个或多个子节点;
    2)、没有父节点的节点称为根节点;
    3)、每一个非根节点有且只有一个父节点;
    4)、除了根节点外,每个子节点可以分为多个不相交的子树;
    在日常的应用中,我们讨论和用的更多的是树的其中一种结构,就是二叉树;
  6. 散列表:
    散列表,也叫哈希表,是根据关键码和值 (key和value) 直接进行访问的数据结构,通过key和value来映射到集合中的一个位置,这样就可以很快找到集合中的对应元素;
  7. 堆:
    堆是一种比较特殊的数据结构,可以被看做一棵树的数组对象,具有以下的性质:
    堆中某个节点的值总是不大于或不小于其父节点的值;
    堆总是一棵完全二叉树;
  8. 图:
    图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系;

30 ArrayList 和LinkedList区别?

30::01 结构上

ArrayList:基于动态数组;
LinkedList:基于链表;

30::02 内存上

ArrayList:连续内存存储、相比LinkedList浪费内存;
LinkedList:可以存储在分散的内存中;

30::03 操作使用上

ArrayList:适合下标访问,支持随机访问;
LinkedList:适合数据插入、删除操作,不适合查询操作;

30::04 注意事项

注:ArrayList扩容机制:
集合中的数组默认是10的容量,在调用add方法时如果容量已满,会将数组的容量扩大1.5倍的容量。
注:当ArrayList指定初始容量,并使用尾插法(防止ArrayList里数组元素复制的消耗),它的性能甚至超过LinkedList
注:ArrayList消耗性能最大的行为是初始容器


创作不易、点关注、不迷路

点击主页、更精彩 !!!

以上是关于java 面试突击-(21-30)的主要内容,如果未能解决你的问题,请参考以下文章

java 面试突击-(31-40)

白嫖版-Java工程师面试突击视频2020

java 面试突击-(1-10)

java 面试突击-(11-20)

java 面试知识点突击-(41-50)

java 面试知识点突击-(61-70)