当前位置: 首页 > news >正文

Java面试题(2)

1、什么是JAVA的字节码(.class)文件

在 Java 中,字节码(.class)文件是 Java 编译器(javac)将 Java 源文件(.java)编译后生成的一种中间格式文件。它包含了 Java 虚拟机(JVM)能够理解的指令和符号表等信息。字节码文件是平台无关的,这是 Java“一次编写,到处运行” 特性的关键所在。

字节码构成:

  • 魔数(Magic Number):字节码文件的开头 4 个字节是魔数,固定值为 0xCAFEBABE。这个魔数用于识别该文件是否为一个有效的 Java 字节码文件,就像文件的 “身份证” 一样,JVM 在加载类文件时首先会检查这个魔数。
  • 版本信息:紧跟魔数之后的是版本信息,包括主版本号和次版本号。这用于 JVM 判断该字节码文件是否能被当前 JVM 版本所支持。例如,如果字节码文件的版本过高,而 JVM 版本较低,JVM 可能无法正确加载和执行该字节码文件。
  • 常量池(Constant Pool):常量池是字节码文件中非常重要的一个部分,它包含了各种字面量(如字符串常量、整数常量等)和符号引用(如类和接口的全限定名、字段和方法的名称和描述符等)。常量池就像是一个资源仓库,字节码指令在需要这些信息时会从中获取。例如,当执行一个字符串拼接操作时,用到的字符串常量就从常量池中获取。
  • 访问标志(Access Flags):用于表示类或者接口的访问权限等信息,如该类是 public、final 还是 abstract 等。这些标志位可以帮助 JVM 在加载类时确定类的访问性质。
  • 类索引、父类索引和接口索引集合:这些部分用于确定类的继承关系。类索引指向该类的全限定名在常量池中的索引,父类索引指向父类的全限定名在常量池中的索引,接口索引集合则包含了该类实现的接口的全限定名在常量池中的索引。通过这些信息,JVM 可以构建出类的继承层次结构。
  • 字段表集合(Fields):描述了类或者接口中声明的变量。对于每个字段,会记录其访问修饰符、名称、描述符等信息。例如,一个简单的 Java 类中有一个私有整型变量,字节码文件的字段表集合中就会记录这个变量是 private 的,它的名称以及它是一个整型变量等信息。
  • 方法表集合(Methods):包含了类或者接口中声明的方法的信息。对于每个方法,会记录其访问修饰符、名称、描述符、方法体中的字节码指令等。例如,一个有参数的方法,字节码文件会记录方法的参数类型和返回类型等信息,以及方法体中的实际操作指令,这些指令用于在 JVM 执行方法时进行运算、控制流程等操作。
  • 属性表集合(Attributes):可以包含多种不同的属性信息,比如代码属性(用于存储方法体的字节码指令)、源文件属性(记录源文件的名称)、行号表属性(用于在调试时将字节码指令和源文件中的行号对应起来)等。这些属性为字节码文件提供了额外的信息,以满足不同的需求,如调试和安全检查等。

我们需要格外注意的是 .class->机器码 这一步。在这一步 JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。而且,有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了 JIT(Just in Time Compilation) 编译器,而 JIT 属于运行时编译。当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。而我们知道,机器码的运行效率肯定是高于 Java 解释器的。这也解释了我们为什么经常会说 Java 是编译与解释共存的语言。

2.AOT和JIT的区别

  • AOT(Ahead - Of - Time)编译:是指在程序运行之前,将字节码文件直接编译成机器码的过程。这种编译方式可以在程序部署之前完成所有的编译工作,生成的机器码可以直接在目标机器上运行。
  • JIT(Just - In - Time)编译:是在程序运行过程中,将字节码动态地编译成机器码的编译方式。JIT 编译器会根据程序的运行情况,在需要的时候对字节码进行编译,并且会对频繁执行的代码段进行优化编译。
  • AOT 编译
    • AOT 编译生成的机器码通常会占用更多的磁盘空间,因为所有可能执行的代码都被提前编译成了机器码。同时,在内存方面,由于机器码的体积可能较大,加载到内存中时也会占用较多的内存空间。
  • JIT 编译
    • JIT 编译在内存占用方面相对灵活。它只会在需要的时候编译字节码,而且可以对编译后的机器码进行缓存和管理。在代码大小方面,字节码文件本身相对较小,并且只有被频繁调用的部分才会被编译成机器码,所以整体上内存占用和代码大小在初始阶段可能比较小。

http://www.mrgr.cn/news/70537.html

相关文章:

  • 基于yolov8、yolov5的番茄成熟度检测识别系统(含UI界面、训练好的模型、Python代码、数据集)
  • SIwave:释放 SIwizard 求解器的强大功能
  • vue计算属性 初步使用案例
  • FreeRTOS源码(二) 任务调度
  • TypeScript 中的三斜杠指令语法
  • Mybatis-plus学习
  • Java:JVM
  • 动态规划习题其七【力扣】【算法学习day.29】
  • LoRA(Low-Rank Adaptation)
  • 基于STM32的自行车户外运动系统设计
  • AIGC小红书新赛道,两个平台同时发,操作简单
  • 地下水数值模拟、 地下水环评、Visual modflow Flex、Modflow
  • 如何利用GNB外链提升网站的自然曝光!
  • FPGA实现光纤通信(2)——光纤眼图测试
  • Tidb数据恢复
  • 监控架构-Prometheus-普罗米修斯
  • QML —— ListView代理,附横向滑动效果(附源码)
  • 游戏引擎中LOD渲染技术
  • 【Linux探索学习】第十二弹——初识进程:进程的定义、描述和一些简单的相关操作
  • 软件测试计划和测试用例详解
  • Polybase要求安装orcale jre 7
  • 【随笔】做售前工程师的一些感悟
  • 卡内基音乐厅回响肖邦旋律:旅美钢琴学者何超与导师洪勋的师生情缘
  • Cesium基础-(Entity)-(label )
  • ggalign:热图等复杂组合图及图形数据对齐的 ggplot2 扩展
  • 计算机在启动一直到系统加载完成期间进行了哪些操作