JAVA基础知识(一)

  • 1.JDKJREJVM三者的区别

JDKjava development kit是提供给开发人员使用的其中包含了Java的开发工具以及JRE

JREjava runtime environment包括了java虚拟机和java程序所需要的核心类库如过需要运行开发完成的Java程序计算机中只需要安装jre即可

JVMJava virtual machinejava虚拟机java程序需要在虚拟机上运行不同的平台有不同的虚拟机因此java可以实现跨平台

  • 2.java的跨平台性以及实现的原理是什么

所谓的java跨平台型就是Java语言所编写的程序,一次编译后,可以在多个部署java环境的系统中运行。

java程序的运行是在Java虚拟机中运行的只要该系统配置Java的环境该系统就可以运行Java程序

  • 3.什么是字节码采用字节码最大的好处是什么

字节码即JAVA源代码经过javac编译后生成的class文件而在java虚拟机中运行的就是字节码文件

java采用字节码可以实现一次编程到处运行也就是java的跨平台性

java语言通过字节码的方式在一定程度上解决类传统解释型语言执行效率低的问题同时还保留了解释型语言可移植性的特点因此java程序在运行时比较高效而且字节码并不专对某一种特定的机器所有java程序无需重新编译即可在多种不同系统平台上运行

拓展

  什么是虚拟机虚拟机的作用是什么

  虚拟机指通过软件模拟的具有完整系统功能的能够独立运行在一个隔离环境中的计算机系统虚拟机还分为系统虚拟机以及进程虚拟机具体的介绍在虚拟机系统与进程的通用平台一书中有详细的介绍

  解释型语言和编译型语言

  编译型语言需要通过编译器将源代码编译成机器码才能够执行的语言一般是通过编译和链接两个步骤编译是将程序编译成机器码链接是将程序和依赖库等串联起来例如C/C++pascalobject-cswiftgo等就是编译型语言

  优点编译器一般会有预编译的过程对代码进行优化因为编译只做一次运行时不会在编译所以编译型语言效率高

  缺点编译之后如果想要修改某一个功能就需要将整个模块重新编译编译的时候根据对应的运行环境生成不同的机器码不同的操作系统之间可能会出现问题需要根据不同的运行环境生成不同的可执行文件

  解释型语言解释型语言不需要编译解析型语言在运行程序的时候才逐行翻译字节码也是解释型语言的一部分例如javaScriptpythonphp等都是解释型语言

  优点有良好的平台兼容性只要安装了虚拟机就可以运行维护比较容易部署也比较方便不用停机维护

  缺点每次运行的时候都要解释一遍性能上不如编译型语言

  Java 编译与解释共存

  java通过javacjava源文件编译称class文件jvmclass文件解释称二进制机器码class文件到二进制机器码jvm类加载器首先加载字节码文件然后通过解释器逐行解释执行这种方式的执行速度相对比较慢而且有些方法和代码块是经常被调用的之后引进jit编译器jit属于运行时编译jit编译完成第一次编译后会将字节码对应的机器码保存下来而我们知道机器码的运行效率是高于java解释器高的

  • 4.javaC++的区别

java不提供指针来直接访问内存程序内存更安全java的类是单继承的c++的类支持多重继承虽然java的类不支持多继承但可以实现多个接口java有自动内存管理机制不需要程序员手动释放无用内存

  • 5.Oracle JDKOpen JDK的对比

Oracle jdk版本是每三年发布一次Open jdk每三个月发布一次

Open Jdk是一个参考模型并且是完全开源的Oracle jdkOpen jdk的一个实现并不是全部开源的

Oracle jdkOpen jdk更稳定Open jdkOracle jdk的代码几乎相同Oracle jdk有更多的类和一些错误修复因此如果开发企业/商业型软件最好使用Oracle jdk因为Oracle jdk经彻底的测试较为稳定

在响应性和JVM性能上Oracle jdkOpen jdk相比提供类更好的性能

  • 6.面向对象的特征

封装继承多态有时还会加上抽象

  • 7.多态的好处

允许不同类对象对同一消息做出响应即同一消息可以根据不同的发送对象采用不同的行为方式主要有以下特点

可替换性多态对已存在的代码具有可替换性

可扩充性增加新的子类不影响已经存在的类结构

接口性多态是超类通过方法签名向子类提供一个公共接口由子类重写完善

  • 8.接口的意义

规范扩展以及回调

  • 9.抽象类的意义

为其他的子类提供一个公共的类型封装子类中重复定义的内容定义抽象方法

  • 10.抽象类与接口的区别

子类使用extends关键字来继承抽象类如果子类不是抽象类子类需要提供抽象类中所声明的方法子类使用implements来实现接口需要提供接口中所有声明的实现

抽象类方法可以使用publicprotect等修饰接口默认是public不能使用其他修饰符

添加新方法时抽象类可以默认实现该方法因此可以不修改子类的代码接口添加新方法则子类需要实现该方法

一个子类只能继承一个抽象类一个子类可以存在多个接口

  • 11.静态变量和实例变量的区别

静态变量存储在方法区,属于类所有。实例变量存储在堆中,器引用当前线程栈。从jdk1.8开始用于实现方法区的PermSpace由MetaSpace取代了。

拓展:

  jvm的内存分区

jvm从逻辑上把内存分为5个区域即方法区、堆、虚拟机栈、本地方法栈、程序计数器。其中方法区和堆是线程共享区域,其他三个区域为线程隔离区域。

  一、方法区

jvm方法区是用于保存已经被虚拟机价值的类元信息(包括类的版本、字段、方法、接口和父类等信息)、运行时的常量信息(static、final定义的常量)、字符串常量信息(String a = "abc")。

  1.方法区、永久代、元数据区的关系

方法区是jvm定义的一种规范,是所有java虚拟机都需要遵循的规范。而永久代(PermGen space)和元数据(MetaSpace)都是实际某个虚拟机针对方法区的实现。永久代是jdk1.7之前hotspot虚拟机对方法区的实现,而元数据是jdk1.8之后hotspot虚拟机对方法区的实现。

  2.PermGen space和MetaSpace的区别?

不管是PermGen space还是MetaSpace他们都是Hotspot针对方法区的一种实现,两者最大的区别在于PermGen space在jvm虚拟机中分配内存,而MetaSpace则是分配本地内存。

因为在很多类是在运行期间加载的,这部分加载的空间不可控,如果这部分内存是在JVM内存里分配的话,永久代分配太大,那么JVM其他区域(比如堆)的内存就会变小,反之如果设置太小,就容易出现方法区内存溢出,因为本身存储的类信息属于不确定大小,类信息在我们运行的时候可以动态加载。所以jdk1.8中选择把MetaSpace内存分配在本地内存,这样做的好处是MetaSpace空间的大小不会受限于虚拟机分配的内存大小,只会首先于机器内存,可分配的内存大了那么就不那么容易出现内存溢出。

  3.字符串常量、静态常量数据存放区域

java6中所有常量池数据存放在永久代中,但到java7后hotspot把永久代中的字符串常量、静态变量数据迁移到了堆中,后面的java8并没有对这部分内容进行迁移,在java8中字符串常量、静态变量数据还是放在堆中,所以常量池只是在jvm规范定义上属于方法区,但hotspot在实现的时候部分常量池的内容实际上是保存在堆中。

  二、虚拟机栈

栈这部分区域主要是用于线程运行方法的区域,此区域属于线程私有的空间,每一个线程创建后都会申请一个自己单独的栈空间,每一个方法区的调用都会对应着一个栈帧。

栈帧里存储着方法的局部变量表(保存着变量的数据)、操作数栈(进行运算时存放数据的空间)、动态连接(指向常量池的引用)和方法返回地址(当前方法返回后的数据存放的地方)信息。

每调用一个方法都会生成一个新栈,调用方法的过程就是一个压栈和出栈的过程,遵循先进后出的原则。

  三、本地方法栈

由于java需要与一些底层系统如操作系统或某些硬件交换信息,这个时候就需要通过调用native本地方法来实现,本地方法栈和虚拟机栈功能差不多,区别在于本地方法是虚拟机调用native方法时使用。

  四、程序计数器

程序计数器是一个较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器,程序计数器记录着某个线程当前执行指令的位置,此区域属于线程隔离区。

因为cpu是根据记录某个线程当前执行指令的位置,此区域属于线程隔离区。

因为cpu是根据时间片的方式分配资源的,它在某一个线程上进行调度的时间是一个或者多个时间片,所以当cpu从线程A切换到线程B执行时,就需要记录A线程当前指令的位置,方便cpu再次切回A线程时可以从上次位置继续执行指令,而程序计数器就是用了记录线程指令历史位置的区域。

  五、堆

堆内存主要是用于存放创建的对象数据,此区域是属于线程共享区域,对于开发人员来说这块区域是我们关注比较多的地方,因为很多优化都是针对这块区域进行的,为了能更清楚的描述堆里的数据和分区信息,所以会结合垃圾回收的一些机制来描述此区域。

posted @ 2021-12-23 17:04  jkbolck  阅读(33)  评论(0)    收藏  举报