前提
一日,王者峡谷深处,一阵躁动,只见一孩童脚穿AJ,头顶阿玛尼,身着爱马仕,肩挎古驰,手持乐高玩具手枪,口中时不时呢喃到:“检测了对面的智商,嘿嘿嘿,看来无法发挥全部实力啦!!“定睛一看,这不是小卤蛋吗!!对面站着一位手拿教尺身披长袍还有点秃顶的白胡子老头,俩人你一句我一句,好像在说着什么!!
小卤蛋目视着老头,结结巴巴的说到:”秃顶面试官你好,我叫鲁班七号,业界人士都尊称我为鲁班大师,因为我经常给救济那些贫困的人,所以别人也叫我提款机; 哦差点忘了,我还给自己起了一个非常霸气的外号,宇智波斑;下面我说一下我的技能树,我精通Java,精通各种甩锅摸鱼技巧,哦对了,最让我自豪的当属我的演技和我那二百五的智商,我一直认为我是集外貌与才华与一身的美男子,奈何美丽的皮囊掩饰了我盖世的才华和我超群的智商....巴拉巴拉巴拉“
白胡子老头早已经听的不耐烦,拿着小卤蛋递给他的三页白纸不停的来回扫描,好像是在找一些什么,突然他脸上闪过一丝邪恶的笑容,然后装作漫不经心的说到:”刚刚你说自己精通Java,智商二百五,既然你那么厉害,那老夫就问你一个基础问题吧!“
一听是基础问题小卤蛋心中暗喜:”检测了对面的智商,嘿嘿嘿,看来无法发挥全部实力啦!!“
白胡子老头好像看透了小短腿内心的想法,心里默念到:”好好教导你,什么是尊师重道!“ 便甩给了小短腿一段代码,并让他说出输出结果。
// eg1
public static void main(String[] args) {
int a = 1;
a = a++;
System.out.println(a);
}
小短腿瞟了一眼题目之后不屑一顾的说到:”我智商二百五,你就给我看这?这不就是输出2吗?“说完后嘴角轻轻上扬,目光斜视上方45°,双手叉腰,右脚跟随着耳机里面传来的”左手右手一个慢动作“打着节拍,像极了他拿滋水枪抢到别人的红蓝爸爸时候的样子。但此时小卤蛋的心理涌上来一股莫名的不安感,这种感觉让他很熟悉,他使劲回想着,但是又一下子想不起来自己什么时候出现过这种感觉。
白胡子老头不愧是久经沙场,早就料想到这样的回答,只见他邪恶一笑告诉他这题的结果是1,还没等小卤蛋反驳便又写下一题:
//eg2
public static void main(String[] args) {
int a = 1;
a = ++a;
System.out.println(a);//输出2
}
小卤蛋看后感觉这两道题没什么区别啊,终于他知道了,原来之前出现的那种不安的感觉和他一个人准备进草丛时候的感觉一模一样,原来这道题暗藏杀机,处处是陷阱。此时他戴着耳机像是在思考这道题,其实他的内心只有一个想法,我想静~静~~
白胡子老头见状心里暗喜到:”人生如此艰难,对会输这事,就不好拆穿了!“便让小短腿回家等通知了。
虽然此时天已经暗下来,但是小卤蛋还是连夜赶回了家,买的站票!!!
回到家后便问自己的老师诸葛暗,诸葛暗口中呢喃:”智商太低会传染,离我远点!“但是看到小卤蛋头上飘过一个数组{0,5,0},还是决定帮一下这个送财童子。便和他说,想要了解这道题,首先需要知道虚拟机栈的结构,看下面这个图:
jvm栈结构
这是一个虚拟机内存结构图,现在咱只重点看虚拟机栈的结构
先看一下周志明的深入理解Java虚拟机中是怎么说的
”Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。“
我们通常说的栈也就是上面说的栈帧,每个栈帧中还有局部变量表,操作数栈,动态连接,返回地址;本章我们也只需要了解局部变量表和操作数栈就可以搞明白a++和++a的过程了
小卤蛋目光呆滞的看着诸葛暗,好像在说:
诸葛亮不慌不忙的画出了下面几幅图,真可谓是”天下如棋,一步三算。“
看完这几幅图,我们再看你说的那两道题。
a++
// eg1
public static void main(String[] args) {
int a = 1;
a = a++;
System.out.println(a);
}
让我们看一下他的反编译结果:
看到这,小卤蛋又露出了天真可爱的表情和那呆滞的眼神。但诸葛暗是谁,他总是挂在嘴边的那句话:”运筹帷幄之中,决胜千里之外!“,这些指令作用他也早已准备好了:
不仅如此,诸葛暗从不做没有胜算的事,所以他还画了一副流程图,帮助小卤蛋理解:
可以看到第五步在局部变量表中做完a的变量自增操作后,又把操作数栈中的值1出栈赋值给了局部变量表中的a,导致最后a的值为1。再来看++a
++a
//eg2
public static void main(String[] args) {
int a = 1;
a = ++a;
System.out.println(a);//输出2
}
从反编译的结果中看得出来,++a和a++的反编译结果区别在于,iinc 1,1和iload_1的执行顺序。诸葛暗早就看出了小卤蛋只想看图的内心,所以把++a的执行顺序图也准备好了:
看完图后,小卤蛋恍然大悟,对诸葛暗竖起了大拇指说到:“啦哈哈哈哈,不得了了。噢哦,其实你才是最终boss。”
诸葛暗:“智商太低会传染,离我远点!”
写这种文章的目的就是自己也想分享知识,但是才疏学浅,所以想通过这种方式博君一笑,毕竟996已经很辛苦了,顺便分享一些自己刚从学校出来面试的时候遇到的面试题和工作一年自己对一些知识点的一个理解的过程。希望可以帮助到和我一样在努力触摸编程门栏的人。
各位人才,各位大佬,有不对的地方各位请不吝指教!都看到这儿了,点赞收藏转发三连一下?祝各位早日找到女朋友。喜欢的朋友可以关注一下我的公众号敲代码的蛋蛋,一起成长,一起骚起来呀!!!
我是敲代码的蛋蛋,一个努力触摸编程门栏的新手。今天的你是否比昨天的你更优秀了呢?