面试题-01

本文深入解析Java多态性,区分重载与重写,详述JVM内存模型及分配策略,探讨final关键字的多场景应用,是Java开发者提升技能的必备指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Java 部分

1.如何理解 Java 的多态?其中,重载和重写有什么区别?
多态:

  • 父类引用指向子类对象
  • 引用指向的对象和应用调用的方法在编译期不能确定,在运行期确定
  • 除非静态方法外,父类对象的引用访问的都是父类的属性和静态方法
  • 父类对象的引用要访问子类的属性和方法,需要向下转型

重载:

  • 方法参数列表不同
  • 方法返回值可以不同(表明不同通过返回值进行方法重载)
  • 方法访问修饰符可以不同(表明不同通过访问修饰符进行方法重载)
  • 可以抛不同的异常(表明不同通过抛出的异常进行方法重载)
  • 注:如果父类方法访问修饰符为 private,子类无法重载,只是定义了一个新的方法

重写:

  • 方法参数列表相同
  • 方法返回值相同
  • 方法访问修饰符的限制大于被重写的方法的访问修饰符(public > protected > default > private)
  • 不能抛新异常或异常不能比被重写方法的异常类型更宽泛(所抛出的异常为被重写方法的子类)
  • 注:如果父类方法访问修饰符为 private,子类无法重写,否则只是定义了一个新的方法

2.谈一下 JVM 虚拟机内存分配?哪部分是线程公有的,哪部分是私有的?
内存分配:方法区(运行时常量池)、堆、虚拟机栈、本地方法栈、程序计数器
线程公有:方法区、堆
线程私有:虚拟机栈、本地方法栈、程序计数器

线程共享:

方法区:

  • 存储被虚拟机加载的类版本、字段、方法、接口、等描述信息和编译器编译后的代码(字节码 .class 文件)等数据
  • 常量在方法区中,因为方法区中有一个运行时常量池,存放编译器生成的各种字面量和符号引用,类加载后,会把常量池中的内容放入运行时常量池中(运行时常量池在方法区中)
  • 编译期:生成的各种字面量(int i = 3,3 就是字面量)和符号引用,这些存放在常量池(常量池在字节码文件中)
  • 运行时常量池不一定从字节码常量池中获取常量,可能在程序运行期间将新的常量放入池中。如:String.intern(),作用:先从方法区的运行时常量池查找是否有该值,有则返回该值引用,无则将该值加入到运行时常量池

堆:

  • 虚拟机中管理的内存中最大的一块,改内存存放对象实例,几乎所有的对象实例都在这里分配内存,通常对应我们说的 new 对象
  • 随着 JIT(Java In Time Compiler)编译器的发展与逃逸分析技术的逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上不再那么绝对
  • 堆是垃圾收集器管理的主要区域
  • 栈中存放的局部引用变量所指向的内容都在堆中存放

线程私有:

虚拟机栈:

  • 生命周期和线程相同
  • 描述方法执行的内存模型,每个方法会在执行的同时创建一个栈帧,用于存储局部变量表、操作数表、动态链接、方法出口等信息
  • 方法的调用过程对应一个栈帧在虚拟机栈中从入栈到出栈的过程

本地方法栈:为 Native 方法服务

程序计数器:

  • 当前线程所执行的字节码的行号指示器,生命周期和线程相同
  • 通过改变计数器的值来选取吓一跳需要执行的字节码的指令,分支、循环、跳转、异常处理、线程恢复等基础功能依赖计数器来完成
  • 线程切换不影响各自计数器的记录
  • 执行的是 Java 方法,计数器记录的是正在执行的虚拟机字节码指令的地址
  • 执行的是 Native 方法,计数器值为空(Undefined)
  • 此内存区域是唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域

3.final 关键字的用法?

  • final 修饰基本类型数据,数据本身不可变
  • final 修饰对象,对象的引用不可变。引用指向的内容可变final 修饰类属性和类方法,不能被覆盖(重写),方法
  • final 修饰类,类无法被继承
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值