Java快速开发学习

锁清秋

基础面试题

一、变量赋值和计算

题目

  1. public static void main(String[] args) {
  2. int i = 1;
  3. i = i++;
  4. int j = i++;
  5. int k = i + ++i * i++;
  6. System.out.println("i=" + i);
  7. System.out.println("j=" + j);
  8. System.out.println("k=" + k);
  9. }

分析

①把i的值压入操作数栈
②i变量自增1
③把i的值压入操作数栈
④把i的值压入操作数栈
⑤i变量自增1
⑥把操作数栈中前两个弹出求乘积结果再压入栈
⑦把操作数栈中的值弹出求和再赋值给k

总结

赋值=,最后计算
=右边的从左到右加载值依次压入操作数栈
实际先算哪个,看运算符优先级
自增、自减操作都是直接修改变量的值,不经过操作数栈
最后的赋值之前,临时结果也是存储在操作数栈中

二、类的初始化、实例初始化、方法重载和重写

考点:

  • 类初始化过程
  • 实例初始化过程
  • 方法的重写

    题目

    题目2
    基础面试题1 - 图3

    一、类初始化过程

    一个类要创建实例需要先加载并初始化该类
    main方法所在的类需要先加载和初始化
    一个子类要初始化需要先初始化父类
    一个类初始化就是执行()方法
    ()方法由静态类变量显示赋值代码和静态代码块组成
    类变量显示赋值代码和静态代码块代码从上到下顺序执行
    ()方法只执行一次

    二、实例初始化

    实例初始化就是执行()方法
    ()方法可能重载有多个,有几个构造器就有几个方法
    ()方法由非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成
    非静态实例变量显示赋值代码和非静态代码块代码从上到下顺序执行,而对应构造器的代码最后执行
    每次创建实例对象,调用对应构造器,执行的就是对应的方法
    方法的首行是super()或super(实参列表),即对应父类的方法

    三、方法的重写 Override 和重载 Overload

重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。
重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。如果父类的方法是private类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。

  • 哪些方法不可以被重写
    final方法
    静态方法
    private等子类中不可见方法
  • 对象的多态性
    子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过的代码
    非静态方法默认的调用对象是this
    this对象在构造器或者说方法中就是正在创建的对象

四、Override重写的要求?

1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。

三、方法的参数传递、String、包装类等对象的不可变性

一、题目

题目3

二、方法的参数传递机制

  • 形参是基本数据类型
  • 传递数据值
  • 实参是引用数据类型
  • 传递地址值
  • 特殊的类型:String、包装类等对象不可变性

四、成员变量与局部变量

一、题目

题目4

二、分析

1)、考点

1、就近原则
2、变量的分类

  • 成员变量:类变量、实例变量
  • 局部变量

3、非静态代码块的执行:每次创建实例对象都会执行
4、方法的调用规则:调用一次执行一次

2)局部变量与成员变量的区别

  • 声明的位置
  • 局部变量:方法体{}中,形参,代码块{}中
  • 成员变量:类中方法外
  • 类变量:有static修饰
  • 实例变量:没有static修饰
  • 修饰符
  • 局部变量:final
  • 成员变量:public、protected、private、final、static、volatile、transient
  • 值存储的位置
  • 局部变量:栈
  • 实例变量:堆
  • 类变量:方法区

3)变量分析

变量分析

4)局部变量与成员变量的区别

  • 作用域
  • 局部变量:从声明处开始,到所属的}结束
  • 实例变量:在当前类中“this.”(有时this.可以缺省),在其他类中“对象名.”访问
  • 类变量:在当前类中“类名.”(有时类名.可以省略),在其他类中“类名.”或“对象名.”访问
  • 生命周期
  • 局部变量:每一个线程,每一次调用执行都是新的生命周期
  • 实例变量:随着对象的创建而初始化,随着对象的被回收而消亡,每一个对象的实例变量是独立的
  • 类变量:随着类的初始化而初始化,随着类的卸载而消亡,该类的所有对象的类变量是共享的

不同变量在JVM中的存储位置

三、当局部变量与xx变量重名时,如何区分

  • 局部变量与实例变量重名在实例变量前面加 “this.”
  • 局部变量与类变量重名在类变量前面加 “类名.”

    JVM 相关面试题

    JVM内存相关

    知识回顾:
    JVM内存
    runtime-dataarea
    考题:

    1. JVM 三大性能调优参数-Xms -Xmx -Xss的含义 ?

  • -Xss : 规定了每个线程虚拟机栈(堆栈)的大小,一般256k就可以了。

  • -Xms : 堆的初始值。
  • -Xmx : 堆能达到的最大值。
    (在很多情况下,会将-Xms 和 -Xmx 设置为相同,应为当heap不够用需要扩容时,会发生内存抖动,影响程序的稳定性)

    2. Java内存模型中堆和栈的区别 ?

  1. 程序运行时的内存分配策略:
  1. 静态存储:程序在编译时就确定了每个数据目标在运行时的存储空间要求。
  1. 栈式存储:数据区在编译时未知,在运行时模块入口前确定
  1. 堆式存储:编译时或运行时模块入口都无法确定,动态分配
  1. Java内存模型中堆和栈的联系:
    应用对象、数组时,栈中定义的引用变量保存着堆中目标的首地址。 堆和栈的联系
  1. Java内存模型中栈和堆的区别:
  • 管理方式:栈:自动释放;堆:GC
  • 空间大小:栈比堆小的多
  • 碎片问题:堆比栈产生的内存碎片多很多
  • 分配方式:栈支持静态和动态分配,而堆仅支持动态分配
  • 效率:栈的效率比堆高