【面试】一、我瑟瑟发抖的第一个面试小笔记

这篇博客主要介绍了Java面试中常见的自增运算符的理解,包括其操作数栈和局部变量表的区别,并通过实例分析了自增运算的顺序。此外,详细探讨了单例设计模式,包括饿汉式和懒汉式的实现方式,强调了线程安全和效率的平衡。还涉及类初始化、实例初始化、方法参数传递机制以及成员变量与局部变量的区别。最后提到了volatile关键字的作用和JMM内存模型在多线程中的意义。
摘要由CSDN通过智能技术生成


一、自增自减运算符

面试题:

public class Test01 {
   
    public static void main(String[] args) {
   
        int i = 1;
        i = i++;
        int j = i++;

        int k = i + ++i * i++;

        System.out.println(i);// 4
        System.out.println(j);// 1
        System.out.println(k);// 11
    }
}

1.1 基础自增举例

		//再看一个基础得例子

		int i = 1;
        i = i++;
		//这里变量i还是等于1的

        int j = i++;
        
        System.out.println(i);// 2
        System.out.println(j);// 1

参考博文 https://blog.csdn.net/qq_37937537/article/details/79931157
涉及到操作数栈与局部变量值的区别

粗略理解:
首先看 i= i++; 的操作

要清楚这个语句的步骤,第一步是先算右边的 i++ ,第二步将右边的结果赋值给变量 i

那么 i ++ 的结果大家都知道,还是 1 。
那么这个结果赋值给变量 i ,i 仍然 等于 1 .

原理详解:

明确一个知识点:自增运算是在局部变量表中进行,赋值语句是将操作数栈的结果取出。

为什么 i++ 叫做“先赋值后运算”?

(1)i ++ 时,先将 i 的值压入操作数栈
(2)随后 i 进行自增操作,局部变量表中值自增为 2
(3)最后执行赋值操作,将操作数栈 中的结果,赋值给变量 i,仍然是 1

字节码逐条分析:

image-20200701181358868
 0 iconst_1 //常量值1
 1 istore_1 //将常量值1存储到局部变量表--变量1
 2 iload_1  //取变量1到操作数栈
 3 iinc 1 by 1 //自增,在局部变量表
 6 istore_1 //操作完毕,将操作数栈的栈顶值取出,赋给局部变量表对应变量。也就是将值1又赋给变量1
 7 iload_1  //加载变量1到操作数栈
 8 iinc 1 by 1 //局部变量自增 i变2
11 istore_2 //操作完毕,操作数栈顶值1赋给变量j(变量2),所以变量j值为1
12 getstatic #2 <java/lang/System.out>
15 iload_1
16 invokevirtual #3 <java/io/PrintStream.println>
19 getstatic #2 <java/lang/System.out>
22 iload_2
23 invokevirtual #3 <java/io/PrintStream.println>
26 return

1.2 面试题举例

在这里插入图片描述 在这里插入图片描述

对于K的求值,这里说一下我的粗暴理解
i ++ 是先将操作数压入操作数栈当中,然后局部变量表自增,最后从操作数栈取出赋值给变量 i。
++ i 是先在局部变量表 i 自增,再将 i 的值压入操作数栈,最后执行赋值操作取操作数栈的值赋值给变量 i。

所以对比发现这个区别就是 将 i 的值压入操作数栈 和 局部变量中自增 的顺序,决定了这两个东西最后结果的差异。你明白他俩到底哪里不一样才会出现不同结果了吗?

下面看一个我瞎画得图解:

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

柴林燕老师得PPT讲解:

在这里插入图片描述

字节码分析

image-20200701182332418
 0 iconst_1
 1 istore_1
 2 iload_1
 3 iinc 1 by 1
 6 istore_1
 7 iload_1
 8 iinc 1 by 1
11 istore_2
12 iload_1
13 iinc 1 by 1
16 iload_1
17 iload_1
18 iinc 1 by 1
21 imul
22 iadd
23 istore_3
24 getstatic #2 <java/lang/System.out>
27 iload_1
28 invokevirtual #3 <java/io/PrintStream.println>
31 getstatic #2 <java/lang/System.out>
34 iload_2
35 invokevirtual #3 <java/io/PrintStream.println>
38 getstatic #2 <java/lang/System.out>
41 iload_3
42 invokevirtual #3 <java/io/PrintStream.println>
45 return

二、单例设计模式

2.1 概

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_popo_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值