高分面试分析jvm如何实现多态

目录
  • 这样说,六十分
  • 这样说,七八十分

昨天就有一个小伙伴被一道面试题虐了,我也给了他一定深度的答案。但是我觉得不够,我觉得应该让小伙伴们像我一样,答题能答出惊喜感,于是就有了这篇文章。我会从Java层面到Hotshot源码层面再到C++层面,完整分析这个问题。

这道面试题在好一些的互联网公司,尤其是一二线,问到的概率非常大,建议小伙伴们把这篇文章吃透。

这样说,六十分

多态是面向对象的三大特性之一,我个人认为,当时设计OOP机制的时候,能够想到多态的人,真特么太牛叉了。

多态理论第一次有了具体实现是在第一款面向对象的编程语言中,这个语言可能很多人没听过:smalltalk。此后出现的只要具备OOP机制的语言,都或多或少模仿或借鉴了前面语言的OOP实现机制。C++有没有模仿或借鉴smalltalk,我不敢说,没特别研究过smalltalk。但是我敢说,Java的多态是几乎百分百模仿C++的多态实现的,不过做了一些细化。C++中只有直接调用、间接调用,而JVM通过不同的invoke指令来实现不同属性的方法调用,这点后文会讲到。

那什么是多态呢,满足下面这几个条件就可以称为多态:

1、继承了某个类、实现了某个接口

2、重写父类的方法、实现接口中的方法

3、父类引用指向子类对象

其实面试官问的这个问题,你这样回答也算就着他这个问题做了回答。但是显然,面试官想听的不是这些,而是父类引用指向子类对象,进行方法调用,这个JVM底层是如何实现的。面试题就是为了筛人,所以面试的时候,能答多深就答多深,绝对加分。

顺便说下,经常跟多态联系在一起的两个词:动态绑定、晚绑定。别到时面试官说这两个词,你一脸懵,那真的很掉分,面试官的脸色一下就暗淡灰沉下去了。当面试官看到你的第一眼,心里给了你60分钟时间来表现,这下直接掉到5分钟。更直接一点的,可能找个借口就走人了。

这样说,七八十分

C++中的间接调用与直接调用,JVM抽象成了4个指令来完成:

1、invokevirtual:咱们平时写代码调用方法,最常用的就是这个指令。这个指令用于调用public、protected修饰,且不被static、final修饰的方法。跟多态机制有关。

2、invokeinterface:跟invokevirtual差不多。区别是多态调用时,如果父类引用是对象,就用invokevirtual。如果父类引用是接口,就用这个。

3、invokespecial:只用于调用私有方法,构造方法。跟多态机制无关。

4、invokestatic:只用于调用静态方法。与多态机制无关。

跟面试官当然要扯点高逼格的对吧,那咱们就讲讲invokeinterface。这个指令为什么逼格高呢?因为它的底层实现比其他几个指令都要复杂,如图

其他的invoke指令的后面就是2个字节的操作数,拿着操作数去常量池中就可以找到类信息、方法信息。但是invokeinterface你会发现,它后面操作数占了4个字节,这4个字节还不全是常量池索引,一起看下这个指令的结构,上图:

这个指令格式我解释一下:

1、第二个字节跟第三个字节合起来是常量池的索引,对应常量池项JVM_CONSTANT_InterfaceMethodref,这里面包含接口的元信息、方法信息。

2、第四个字节是这个方法的参数个数。是不是有小伙伴觉得很奇怪,show方法没有参数呀,这边怎么是1,是JVM的bug?呵,如果JVM有这么低级的bug,JVM也不会有今天的地位了。非静态方法就算没有参数,也默认有一个,就是this指针。

其实这个参数个数完全没必要记录,可以通过解析方法的签名计算出来,不明白当时为什么做这样的设计。面试的时候这点记得说,很加分。其实字节码文件中有很多可以优化的点,后面准备共享这方面的面试题,没人想打我吧。^_^

3、第五个字节永远为0,历史原因遗留。我查了一些资料,得到的答案是:为额外的运算元预留空间。子牙老师表示这个字我都认识,但是它组合在一起表达的意思我真不懂,是不是我太菜了。哎,还是太菜了。

有些小伙伴可能就想:答到这个份上才七八十分?那后面还能怎么说哦。咱们现在才只说到invokeinterface指令,那这个指令是怎么找到要调用的方法的呢?JVM的虚表机制到底是什么样的呢?又是怎么与C++的虚表机制合二为一的呢?虚表分发机制又是怎样的呢?这些才是这个问题的精髓。

这点就留到下篇文章写吧。文章太长,读起来也疲惫。

传送门 高分面试从Hotspot源码层面剖析java多态实现原理

以上就是高分面试分析jvm如何实现多态的详细内容,更多关于jvm实现多态的资料请关注我们其它相关文章!

(0)

相关推荐

  • JVM内置函数Intrinsics介绍

    目录 1.什么是内置? 2.JVM上的内置函数 3.性能收益 4.不可能的实现 5.识别Java中的Intrinsics语言 6.总结 1.什么是内置? 内置函数是由我们的编程语言的编译器或解释器进行特殊处理的函数.更具体地说,这是一种特殊情况,因为各种原因,编译器或解释器可以用替代实现替换函数. 编程语言通常通过理解一个特定的方法调用是特殊的来处理这个问题,无论何时我们调用这个方法,结果都是不同的.这样一来,我们的代码看起来与正常代码没有什么不同,但编程语言的实现可以在特殊情况下进行干预,以提

  • JVM内存参数配置详解

    首先我们知道:JVM发生内存错误的类型 1.堆内存泄漏:OutOfMemory:Java heap space 此种内存泄漏,增加内存,只能暂时解决问题,并不能根治问题.必须要优化代码,一定是代码的问题:排查堆中的大量对象,就会发现,这些对象都被引用,对象不能及时被回收,导致超出了堆的设定最大内存. 2.老年代内存泄漏:OutOfMemoryError:PermGen space 类名.访问修饰符.字段描述.方法描述等,所占空间大于永久代最大值,就会出现,一般都是初始化内存的时候,空间太小,解决

  • 高分面试分析jvm如何实现多态

    目录 这样说,六十分 这样说,七八十分 昨天就有一个小伙伴被一道面试题虐了,我也给了他一定深度的答案.但是我觉得不够,我觉得应该让小伙伴们像我一样,答题能答出惊喜感,于是就有了这篇文章.我会从Java层面到Hotshot源码层面再到C++层面,完整分析这个问题. 这道面试题在好一些的互联网公司,尤其是一二线,问到的概率非常大,建议小伙伴们把这篇文章吃透. 这样说,六十分 多态是面向对象的三大特性之一,我个人认为,当时设计OOP机制的时候,能够想到多态的人,真特么太牛叉了. 多态理论第一次有了具体

  • 高分面试从Hotspot源码层面剖析java多态实现原理

    目录 C++是如何实现多态的 JVM中的虚表 Java是如何实现虚表分发 本篇文章是接上篇文章[JVM的多态是如何实现的]写的,如果你还没看过,墙裂都建议你看一下. 传送门  高分面试分析jvm如何实现多态 上篇文章我给出了这道面试题的及格分的回答及七八十分的回答,今天我就告诉大家如果想回答得接近满分,应该怎么回答.因为会设计到C++的虚表及C++的多态实现,如何这块你不理解或不熟,面试中建议别拿出来说,免得碰到懂C++给你来个连环call把你问懵了. 这边给大家补一个知识点.我在昨天的文章里说

  • 分析JVM的组成结构

    目录 一.JavaSE体系 二.运行时数据区 三.程序计数器 3.1.什么是程序计数器 3.2.程序计数器有什么特点 3.3.用个例子来说明 四.虚拟机栈 4.1.局部变量表 4.2.操作数据栈 4.3.动态链接 4.4.方法出口 4.5.栈溢出 五.本地方法栈 六.方法区 七.堆 八.运行时常量池 8.1.符号引用 8.2.字面量 8.3.jvm各版本运行时常量池变化 8.4.直接内存 一.JavaSE体系 JavaSE,Java 平台标准版,为 Java EE 和 Java ME 提供了基础

  • 分析JVM源码之Thread.interrupt系统级别线程打断

    目录 一.interrupt的使用特点 二.jvm层面上interrupt方法的本质 三.ParkEvent对象的本质 四.Park()对象的本质 五.利用jni实现一个可以被打断的MyThread类 六.总结 一.interrupt的使用特点 我们先看2个线程打断的示例 首先是可打断的情况: @Test public void interruptedTest() throws InterruptedException { Thread sleep = new Thread(() -> { tr

  • 分析JVM的执行子系统

    目录 一.Class类文件结构 1.1.JVM的平台无关性 1.2.Class类文件 二.类的加载机制 2.1.加载 2.2.验证 2.3.准备阶段 2.4.解析阶段 2.5.初始化阶段 三.类加载器 3.1.双亲委派模型 3.2.Tomcat是怎么保证两个应用相同名称类的隔离性 一.Class类文件结构 1.1.JVM的平台无关性 与平台无关性是建立在操作系统上,虚拟机厂商提供了许多可以运行在各种不同平台的虚拟机,它们都可以载入和执行字节码,从而实现程序的一次编写,到处运行. 各种不同平台的虚

  • 面试分析分布式架构Redis热点key大Value解决方案

    目录 引言 1.面试官:你在项目中有没有遇到Redis热点数据问题,一般都是什么原因引起的? 2.面试官:真实项目中,那热点数据问题你是如何准确定位的呢? 3.如何解决热点数据问题 4.面试官:关于Redis最后一个问题,Redis支持丰富的数据类型,那么这些数据类型存储的大Value如何解决,线上有遇到这种情况吗? 总结 引言 关于 Redis 热点数据 & 大 key 大 value 问题也是容易被问的高阶问题,不如一次痛快点说完,让面试官无话可说,个人工作经验中,热点数据问题在工作中相比雪

  • 详细分析JVM类加载机制

    目录 前言 1. jvm 的组成 2. 类加载 1. 加载 2. 链接 3. 初始化 3. 类加载器 引导类加载器(启动类加载器) 扩展类加载器 应用程序类加载器 4. 双亲委派机制 5. 类的主动/被动使用 结语 前言 ladies and gentleman , 你们好 ,我是羡羡 , 这节我们进入jvm的学习 , 我们知道 , jvm是java虚拟机, java代码的执行与 jvm 息息相关, 接下来我们来依次介绍 , 首先这节先来介绍 jvm 中的类加载部分 1. jvm 的组成 jvm

  • JVM中的GC初识

    目录 GC简介 何为GC 为何要学习GC GC垃圾对象判定 引用计数法 可达性分析法 常见GC算法分析 标记清除 标记复制 标记整理 分代回收 章节面试分析 GC简介 何为GC GC(Garbage Collection)称之为垃圾回收,是对内存中的垃圾对象,采用一定的算法进行内存回收的一个动作.比方说,java中的垃圾回收会对内存中的对象进行遍历,对存活的对象进行标记,其未标记对象可认为是垃圾对象,然后基于特定算法进行回收. 为何要学习GC 深入理解GC的工作机制,可以帮你写出更好的Java应

  • 深入解析JVM对dll文件和对类的装载过程

    JVM的对dll文件的装载过程 操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境. 1.创建JVM装载环境和配置 2.装载JVM.dll 3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例 4.调用JNIEnv实例装载并处理class类. 一.JVM装入环境,JVM提供的方式是操作系统的动态连接文件.     既然是文件那就一个装入路径的问题,Java是怎么找这个路径的呢?当你在调用Java test的时候,操作系统会在path下在你的Java

  • 深入JVM剖析Java的线程堆栈

    在这篇文章里我将教会你如何分析JVM的线程堆栈以及如何从堆栈信息中找出问题的根因.在我看来线程堆栈分析技术是Java EE产品支持工程师所必须掌握的一门技术.在线程堆栈中存储的信息,通常远超出你的想象,我们可以在工作中善加利用这些信息. 我的目标是分享我过去十几年来在线程分析中积累的知识和经验.这些知识和经验是在各种版本的JVM以及各厂商的JVM供应商的深入分析中获得的,在这个过程中我也总结出大量的通用问题模板. 那么,准备好了么,现在就把这篇文章加入书签,在后续几周中我会给大家带来这一系列的专

随机推荐