这道面试题,大部分人都答错了

附Java/C/C++/机器学习/算法与数据结构/前端/安卓/Python/程序员必读书籍书单大全:

书单导航页(点击右侧 极客侠栈 即可打开个人博客):资源栈
【Java】学习之路吐血整理技术书从入门到进阶最全50+本(珍藏版)
【算法数据结构+acm】从入门到进阶吐血整理书单50+本(珍藏版)
【数据库】从入门到进阶必读18本技术书籍网盘吐血整理网盘(珍藏版)
【Web前端】从HTML到JS到AJAX到HTTP从框架到全栈帮你走更少弯路(珍藏版)   
【python】书最全已整理好(从入门到进阶)(珍藏版)

【机器学习】+python整理技术书(从入门到进阶已经整理好)(珍藏版)
【C语言】推荐书籍从入门到进阶带你走上大牛之路(珍藏版)
【安卓】入门到进阶推荐书籍整理pdf书单整理(珍藏版)

【架构师】之路史诗级必读书单吐血整理四个维度系列80+本书(珍藏版)

【C++】吐血整理推荐书单从入门到进阶成神之路100+本(珍藏)

【ios】IOS书单从入门到进阶吐血整理(珍藏版)

⑫【Web安全】从入门到进阶书单(珍藏版)
⑬【Linux和操作系统】从入门到进阶书单(珍藏版)
⑭【Office】从入门到进阶书单(珍藏版)

-------------------------------------------------------------------------------------------------------------------------------------------

面试题

public class AddTest {
    public static void main(String[] args) {
        int i = 0;
        i = i++;
        System.out.println("i=" + i);
    }
}

输出结果是多少呢?自己思考后继续往下看效果更好哦

正确答案是 0

如果能完全想明白,可以结束往下阅读了。如果有疑惑,请继续读下去

我刚看到这道题,给的答案也是 1,因为我以往的理解是 i++ 是先赋值,然后再进行 ++ 操作,在赋值时,i 确实为 0,但 i 应该完成了自增操作,输出的 i 应该为 1 呀,自己也验证了一下,的确是 0。想不明白那就看看字节码吧,也许从中能找到答案

先通过 javac AddTest.java 生成 AddTest.class 文件,然后通过 javap -v AddTest.class 查看具体的字节码(只截取了部分)

i++字节码

首先说明左边的数字序号表示字节码的偏移量(偏移量和前面的字节码长度有关),即当前字节码所在的位置,很像行号,但不是行号

下面我们用图解的方式分析下主要步骤 i++字节码图解

通过图解我们发现操作数栈中的 0 把局部变量表 1 位置的 1 覆盖了,所以最后输出的结果是 0

指令说明

xconst_n (x为 i 表示整数,l 表示长整数,f 表示浮点数,d 表示双精度浮点数,a 表示对象引用;n 为 0~5):常量入栈指令,代表将 n 压入栈

xload_n(x 取值和 const 一样,n 为 0~3):局部变量压栈指令,将第n个局部变量压入操作数栈

xstore_n(x 取值和 const一样,n 为 0~3):出栈装入局部变量表指令,从操作数栈中弹出,赋值给局部变量 n

iinc arg1,arg2:对给定的局部变量做自增操作。执行过程中不需要修改操作数栈。接收两个操作数,第一个为局部变量表的位置,第二个为累加数

++i 呢?

说完了 i++ 就不能落下它的好兄弟 ++i

public class Add2Test {
    public static void main(String[] args) {
        int i = 0;
        i = ++i;
        System.out.println("i=" + i);
    }
}

这个结果我想大家都能答对,输出 1,但是我还是想把 ++i 的字节码打出来,然后和 i++ 的进行对比

++i字节码

字节码图解如下所示

++i字节码图解

i++ 与 ++i 对比

我们把这两个图放在一起对比看下

对比

反思

为何一道简单的 i++ 的输出问题,我都能弄错?追根是因为对字节码底层的不了解,虽然我们通过字节码和画图分析出了原因,但这并不够,最好做到看到代码,对应的字节码就映射到脑中。说实话,对我来说挺难的。需要不断练习。懂了字节码会对 Java 中更多底层的知识不止知其然,更知其所以然。

思考题

  1. switch-case 是如何支持 String 类型的?
  2. try-catch-finally 中 finally 里面的代码为何一定会执行?

附Java/C/C++/机器学习/算法与数据结构/前端/安卓/Python/程序员必读书籍书单大全:

书单导航页(点击右侧 极客侠栈 即可打开个人博客):资源栈
【Java】学习之路吐血整理技术书从入门到进阶最全50+本(珍藏版)
【算法数据结构+acm】从入门到进阶吐血整理书单50+本(珍藏版)
【数据库】从入门到进阶必读18本技术书籍网盘吐血整理网盘(珍藏版)
【Web前端】从HTML到JS到AJAX到HTTP从框架到全栈帮你走更少弯路(珍藏版)   
【python】书最全已整理好(从入门到进阶)(珍藏版)

【机器学习】+python整理技术书(从入门到进阶已经整理好)(珍藏版)
【C语言】推荐书籍从入门到进阶带你走上大牛之路(珍藏版)
【安卓】入门到进阶推荐书籍整理pdf书单整理(珍藏版)

【架构师】之路史诗级必读书单吐血整理四个维度系列80+本书(珍藏版)

【C++】吐血整理推荐书单从入门到进阶成神之路100+本(珍藏)

【ios】IOS书单从入门到进阶吐血整理(珍藏版)

⑫【Web安全】从入门到进阶书单(珍藏版)
⑬【Linux和操作系统】从入门到进阶书单(珍藏版)
⑭【Office】从入门到进阶书单(珍藏版)

天下没有不劳而获的果实,望各位年轻的朋友,想学技术的朋友,在决心扎入技术道路的路上披荆斩棘,把书弄懂了,再去敲代码,把原理弄懂了,再去实践,将会带给你的人生,你的工作,你的未来一个美梦。

发布了14 篇原创文章 · 获赞 6 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43554593/article/details/104267169
今日推荐