贡献一道超高套路JVM面试题

简介: 哈喽,我是子牙。十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业。技术栈如汇编、C语言、C++、Windows内核、Linux内核。特别喜欢研究虚拟机底层实现,对JVM有深入研究。分享的文章偏硬核,很硬的那种。

哈喽,我是子牙。十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业。技术栈如汇编、C语言、C++、Windows内核、Linux内核。特别喜欢研究虚拟机底层实现,对JVM有深入研究。分享的文章偏硬核,很硬的那种。

手撸过JVM、内存池、垃圾回收算法、synchronized、线程池、NIO、三色标记算法…

erafbbd8u7.png

最近在手撸JVM实现OOP的封装机制的时候,有个问题引起了我的眉头紧锁。代码如下

image.png

于是我把这个让我眉头紧锁的问题提炼成了一个面试题:这段创建对象的代码,在JVM内部创建了几个对象?

正方

两个:一个是Test_2对象,一个是Object对象。

会创建Test_2对象就不用说了。为什么会创建Object对象呢?因为Java中所有的类都继承自Object类,所有对象的创建都会调用类的构造方法,而这些构造方法中都会调用Object的构造方法。如图

image.png

图说明:这个图是Test_2的构造方法对应的字节码指令。有小伙伴不了解字节码的建议补一补,这玩意很重要。JVM的黑科技玩的就是这个!

逻辑紧凑,毫无破绽,有木有?多少小伙伴也是这样认为的留言区举个爪。

如何证明创建了两个对象?不知道!

反方

一个:只会创建Test_2对象。

那调用Object的构造函数干吗?反方内心开始慌乱~
如果Object类有属性,不创建Object对象,如何访问Object类中的属性?反方内心动摇:我支持正方观点。

image.png

你跑来反方干什么?反奸!

正解

为什么我把创建两个对象定义为正方呢?呵,惭愧,我之前也是这样认为的。所以,答案是反方观点是正确的。那那两个问题怎么解释?呵,稳住,听我娓娓道来。

调用父类的构造函数,目的是什么?解释这个问题前,先说构造函数是干什么的:完成非静态属性的赋值。所以,调用父类的构造函数,目的是为了完成父类中的非静态属性的赋值。这是第一个问题。

接下来第二个问题:不创建父类对象如何访问父类的属性?其实这个问题的本质是:父类中的属性到底存储在哪?其实父类的属性是存储在子类对象上的,所以没必要创建父类对象!是不是有小伙伴不服气啦,没事,上图

image.png

你也可以通过HSDB查看JVM内存,结论是一样的

image.png

再多讲一个问题吧:父类的属性是如何存储到子类对象上的?因为调用父类对象是以子类对象身份调用的,所以父类构造函数中的非静态属性赋值语句,作用的都是子类对象。

image.png

如何证明?跟着我学习过JVM的小伙伴应该知道吧。借助Idea的调试功能。如图

image.png
image.png

为什么会出现两种不同的观点呢?我后面想了想:大部分小伙伴把调用构造函数等同于创建对象。其实从函数的本质来看:函数只是接受外面传参,执行相关逻辑,传出参数。构造函数本质上还是函数,并不具备创建对象的能力。

我有话说

答应我,如果你学会了,不要拿这道题去为难别人好吗?如果你实在忍不住,不要告诉别人是子牙老师那边学来的。我不想承担无谓的仇恨:NND,这是哪个抽风的面试官想到的面试题!同是程序猿,相煎何太急!

看到这篇文章的小伙伴,如果你在哪里面试遇到了这道面试题,请留言告诉我。我再发几个声讨!我与罪恶不同戴天!

我是子牙老师,喜欢钻研底层,深入研究Windows、Linux内核、JVM。如果你也喜欢研究底层,欢迎关注我的公众号【硬核子牙】

相关文章
|
1月前
|
SQL 缓存 监控
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
本文详细解析了数据库、缓存、异步处理和Web性能优化四大策略,系统性能优化必知必备,大厂面试高频。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
|
1月前
|
存储 算法 安全
JVM常见面试题(四):垃圾回收
堆区域划分,对象什么时候可以被垃圾器回收,如何定位垃圾——引用计数法、可达性分析算法,JVM垃圾回收算法——标记清除算法、标记整理算法、复制算法、分代回收算法;JVM垃圾回收器——串行、并行、CMS垃圾回收器、G1垃圾回收器;强引用、软引用、弱引用、虚引用
|
1月前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。
|
3月前
|
安全 Java 应用服务中间件
JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
什么是类加载器,类加载器有哪些;什么是双亲委派模型,JVM为什么采用双亲委派机制,打破双亲委派机制;类装载的执行过程
107 35
JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
|
2月前
|
存储 监控 算法
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程 ?
尼恩提示: G1垃圾回收 原理非常重要, 是面试的重点, 大家一定要好好掌握
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程  ?
|
2月前
|
Java 应用服务中间件 程序员
JVM知识体系学习八:OOM的案例(承接上篇博文,可以作为面试中的案例)
这篇文章通过多个案例深入探讨了Java虚拟机(JVM)中的内存溢出问题,涵盖了堆内存、方法区、直接内存和栈内存溢出的原因、诊断方法和解决方案,并讨论了不同JDK版本垃圾回收器的变化。
43 4
|
2月前
|
Java API 对象存储
JVM进阶调优系列(2)字节面试:JVM内存区域怎么划分,分别有什么用?
本文详细解析了JVM类加载过程的关键步骤,包括加载验证、准备、解析和初始化等阶段,并介绍了元数据区、程序计数器、虚拟机栈、堆内存及本地方法栈的作用。通过本文,读者可以深入了解JVM的工作原理,理解类加载器的类型及其机制,并掌握类加载过程中各阶段的具体操作。
|
2月前
|
存储 缓存 JavaScript
JVM面试真题总结(一)
JVM面试真题总结(一)
|
2月前
|
存储 Kubernetes 架构师
阿里面试:JVM 锁内存 是怎么变化的? JVM 锁的膨胀过程 ?
尼恩,一位经验丰富的40岁老架构师,通过其读者交流群分享了一系列关于JVM锁的深度解析,包括偏向锁、轻量级锁、自旋锁和重量级锁的概念、内存结构变化及锁膨胀流程。这些内容不仅帮助群内的小伙伴们顺利通过了多家一线互联网企业的面试,还整理成了《尼恩Java面试宝典》等技术资料,助力更多开发者提升技术水平,实现职业逆袭。尼恩强调,掌握这些核心知识点不仅能提高面试成功率,还能在实际工作中更好地应对高并发场景下的性能优化问题。
|
4月前
|
存储 安全 Java
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别;什么是程序计数器,堆,虚拟机栈,栈内存溢出,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存