乐趣区

关于java:在阿里做了3年码农竟然不知道JDK和JRE背后的秘密我慌了

今日分享开始啦,请大家多多指教~

这篇文章给大家介绍一下 JDK 和 JRE、final 与 static、堆和栈;为了放弃 JDK 的独立性和完整性,在 JDK 的装置过程中,JRE 也是装置的一部分。所以,在 JDK 的装置目录下有一个名为 jre 的目录,用于寄存 JRE 文件。

一、JDK 和 JRE 的区别?

JDK:java development kit(java 开发工具)

JRE:java runtime environment(java 运行时环境)

JVM:java virtuak machine(java 虚拟机)

1、jdk– 开发环境(外围)

Java development kit 的缩写,意思是 Java 开发工具,咱们写文档做 PPT 须要 office 办公软件,开发当然须要开发工具了,说到开发工具大家必定会想到 Eclipse,然而如果间接装置 Eclipse 你会发现它是运行不起来 是会报错的,只有装置了 JDK,配置好了环境变量和 path 才能够运行胜利。这点置信很多人都深有体会。

jdk 次要蕴含三个局部:

  • 第一局部是 Java 运行时环境,JVM
  • 第二局部是 Java 的根底类库,这个类库的数量还是相当可观的
  • 第三局部是 Java 的开发工具,它们都是辅助你更好地应用 Java 的利器

2、jre– 运行环境

① jdk 中的 jre

如下图:jdk 中蕴含的 jre,在 jre 的 bin 目录里有个 jvm.dll,既然 JRE 是运行时环境,那么运行在哪?必定是 JVM 虚拟机上了。另,jre 的 lib 目录中放的是一些 JAVA 类库的 class 文件,曾经打包成 jar 文件。

② 第二个 JRE(独立进去的运行时环境)

如下图,不论是 JDK 中的 JRE 还是 JRE 既然是运行时环境必须有 JVM。所以 JVM 也是有两个的。

3、JVM——转换环境

java virtuak machine(java 虚拟机)的缩写。

大家一提到 JAVA 的长处就会想到:一次编译,随处运行,说白了就是跨平台性好,这点 JVM 功不可没。

Java 的程序也就是咱们编译的代码都会编译为 class 文件,class 文件就是在 jvm 上运行的文件,只有 JVM 还不能齐全反对 class 的执行,因为在解释 class 的时候 JVM 须要调用解释所须要的类库 lib,而 jre 蕴含 lib 类库。

JVM 屏蔽了与具体操作系统平台相干的信息,使得 Java 程序只需生成在 Java 虚拟机上运行的指标代码(字节码),就能够在多种平台上不加批改的运行。

JVM 也是一门很深的学识,感兴趣的同学能够深入研究,只有益处,没有害处。

其实有时候面试官问 JDK 和 JRE 的区别的目标不是想让你解释什么名词的,而是想看看你的根底和钻研 Java 的深浅,还有另一方面就是你是不是常常喜爱问为什么。

二、final 与 static 的区别?

都能够润饰类、办法、成员变量

  • static 能够润饰类的代码块,final 不能够
  • static 不能够润饰办法内局部变量,final 能够
  • static 润饰示意动态或全局
  • static 润饰的代码块示意动态代码块,当 JVM 加载类时,只会被创立一次
  • static 润饰的变量能够从新赋值
  • static 办法中不能用 this 和 super 关键字

因为 this 代表的是调用这个函数的对象的援用,而静态方法是属于类的,不属于对象,静态方法胜利加载后,对象还不肯定存在。this 代表对本类对象的援用,指向本类已创立的对象。super 代表对父类对象的援用,指向父类对象。动态优先于对象存在,办法被 static 润饰之后,办法先存在,所需的父类援用对象晚于该办法的出 现,也就是 super 所指向的对象还没呈现,当然就会报错。

  • static 办法必须被实现,而不能是形象的 abstract
  • static 办法只能被 static 办法笼罩
  1. final 润饰示意常量、一旦创立不可被批改
  2. final 标记的成员变量必须在申明的同时赋值,或在该类的构造方法中赋值,不可从新赋值
  3. final 办法不能被子类重写
  4. final 类不能被继承,没有子类,final 类中的办法默认是 final 的
  5. final 不能用于润饰构造方法
  • private 类型的办法默认是 final 类型的

三、final 与 static 的区别

get 和 post 是表单提交的两种形式,get 申请数据通过域名后缀 URL 传送,用户可见,不平安,post 申请数据通过在申请报文注释里传输,绝对比拟平安。get 是通过 URL 传递表单值,post 通过 URL 看不到表单域的值。

get 传递的数据量是无限的,如果要传递大数据量不能用 get,不如 type=“file”上传文章、type=“password”传递明码,get 和 post 是表单提交数据的两种形式,get 申请数据通过地域名后缀 URL 传送,用户可见,不平安,post 申请数据通过将在申请报文注释里传输,绝对比拟平安。

get 是通过 url 传递表单值,post 通过 url 看不到表单域的值;

get 传递的数据量是无限的,如果要传递大数据量不能用 get,比方 type=“file”上传文章、type=“password”传递明码或者 < text area > 发表大段文章,post 则没有这个限度;

post 会有浏览器提醒从新提交表单的问题,get 则没有 (加分的答复)

对于 Post 的表单从新敲地址栏再刷新就不会提醒从新提交了,因为从新敲地址就没有偷偷提交的数据了。Post 形式的正确的地址很难间接发给他人。

四、get 和 post 的区别

1.get 提交的数据放在 URL 之后,以?宰割 URL 和传输数据,参数之间以 & 相连,如 EditPosts.aspx?name=test1&id=123456. post 办法是把提交的数据放在 HTTP 包的 body 中。

2.get 提交的数据大小有限度(因为浏览器对 URL 的长度有限度),而 post 办法提交的数据没有限度。

3.get 形式须要应用 request.querystring 来获得变量的值,而 post 形式通过 request.form 来获取变量的值。

4.get 形式提交数据会带来平安问题,比方一个登陆页面,通过 get 提交数据时,用户名和明码将呈现在 URL 中,如果页面能够被缓存或者其他人能够拜访这台机器,就能够从历史记录取得该用户的账户和明码。

get 是从服务器获取数据,post 向服务器传送数据。

get 是把参数数据队列加到提交表单的 action 属性所指的 URL 中,值和表单内各个字段一一对应,在 URL 中能够看到。post 是通过 HTTP post 机制,将表单内各个字段与其内容搁置在 HTML.header 内一起传送到 action 属性所指的 URL 地址。用户看不到这个过程。

对于 get 形式,服务器端用 request.querystring 获取变量的值,对于 post 形式,服务器端用 request.form 获取提交的数据

get 传送的数据量较小,不能大于 2KB.POST 传送的数据量较大,个别被默认为不受限制。但实践上,限度取决于服务器的解决能力。

get 安全性较低。post 安全性较高。

五、堆和栈的概念和区别

在说堆和栈之前,先说一下 JVM(虚拟机)内存的划分:

Java 程序在运行时都要开拓空间,任何软件在运行时都要在内存中开拓空间,Java 虚拟机运行时也是要开拓空间的。JVM 运行时在内存中开拓一片内存区域,启动时在本人的内存区域中进行更粗疏的划分,因为虚拟机中每一片内存解决的办法都不同,所以要独自进行治理。

JVM 内存的划分有五片:

1. 寄存器

2. 本地办法区

3. 办法区

4. 栈内存

5. 堆内存

咱们来重点说一下堆和栈:

栈内存:栈内存首先是一片内存区域,存储的都是局部变量,但凡定义在办法中的都是局部变量,for 循环外部定义的也是局部变量,是先加载函数能力进行局部变量的定义,所以办法先进栈,而后再定义变量,变量有本人的作用于,一旦来到作用域,变量就会被开释。栈内存的更新速度很快,因为局部变量的申明周期都很短。

堆内存:存储的是数组和对象(其实数组就是对象),但凡 new 建设的都是在堆中,堆中寄存的都是实体(对象),实体用于封存数据,而且是封存多个(实体的多个属性),如果一个数据隐没,这个实体也没有隐没,还能够用,所以堆是不会随时开释的,然而栈不一样,栈里寄存的都是单个变量,变量被开释了,也就没有了。堆里的实体尽管不会被开释,然而会被当做垃圾,Java 有垃圾回收机制不定时的收取。

上面咱们通过一个图例具体讲一下堆和栈:

比方主函数里的语句

int[] arr = new int[3];

在内存中是怎么被定义的:

主函数先进栈,在栈中定义一个变量 arr,接下来为 arr 赋值,然而左边不是一个具体值,是一个实体。实体创立在堆里,在堆里首先通过 new 关键字开拓一个空间,内存在存储数据的时候都是通过地址来实现的,地址是一块间断的二进制,而后给这个实体调配一个内存地址。数组都有一个索引,数组这个实体在堆内存中产生之后每一个空间都会默认的初始化(这是堆内存的特点,未初始化的数据是不能用的,然而在堆里是能够用的,因为初始化过了,然而栈里没有),不同的类型初始化的值不一样,所以堆和栈里就创立了变量和实体:

那么堆和栈怎么分割起来的呢?

咱们刚刚说过给堆调配一个地址,把堆的地址赋给 arr,arr 就通过地址只想了数组。所以 arr 想操作数组时,就通过地址,而不是间接把四蹄都赋给它。这种咱们不再叫它根本数据类型,而叫援用数据类型。称为 arr 援用了堆内存当中的实体

如果当 int[] arr = null;

arr 不做任何指向,null 的作用就是勾销援用数据类型的指向。

当一个实体,没有援用数据类型指向的时候,它在堆内存中不会被开释,而被当作一个垃圾,在不定时的工夫内主动回收,因为 Java 有一个主动回收机制。主动回收机制主动监测堆里是否有垃圾,如果有,就会主动地做垃圾回收的动作,然而什么时候回收不肯定。

所以堆和栈的区别很显著:

1. 栈内存存储的是局部变量而堆内存存储的是实体;

2. 栈内存的更新速度要快于堆内存,因为局部变量的申明周期很短;

3. 栈内存寄存的变量申明周期一旦完结就会被开释,而堆内存寄存的实体会被垃圾啊回收机制不定时的回收。

六、浅谈 Java 反射机制

1、反射的定义是什么?

Java 反射机制是在运行状态中,对于任意一个类,都可能晓得这个类的所有属性和办法;对于任意一个对象,都可能调用它的任意一个办法,这种动静获取、调用对象办法的性能成为 Java 语言的反射机制。

2、反射存在的必要性?

反射机制是很多 Java 框架的基石。

① 在 xml 文件或 properties 外面写好了配置,而后再 Java 类外面解析 xml 或 properties 外面的内容,失去一个字符串,而后用反射机制,依据这个字符串取得某个类的 Class 实例,这样就能够动静配置一些货色,不必每一次都要在代码里去 new 或者做其它事件,当前要改的话间接改配置文件,代码保护起来就很不便了。

② 有时候要适应某些需要,Java 类外面不肯定能间接调用另外的办法,这时候也能够通过反射机制来实现。

3、反射的毛病?

反射的代码比失常调用的代码更多,性能更慢,应防止应用反射。

String 中 intern() 办法的应用:

String s1 = new String("1") + new String("1");//s1 变量记录的地址为:new String
s1.intern();// 在字符串常量池中生成 "11"。如何了解:jdk6:创立了一个新的对象 "11",也就有新的地址;jdk7:此时常量池中并没有创立 "11",而是创立了一个指向堆空间中 new String("11") 的地址;String s2 = "11";
System.out.println(s1 == s2);//jdk6:false;jdk7:true

jdk6 中:

将这个字符串常量池尝试放入字符串常量池。

如果常量池中有,则不会办法。返回已有的常量池中对象的地址;

如果没有,会把此对象复制一份,放入串池,并返回串池中的对象地址;

jdk7 中:

将这个字符串常量池尝试放入字符串常量池。

如果常量池中有,并不会放入。返回已有的常量池中的对象的地址;

如果没有,会把对象的援用地址复制一份,放入常量池,并返回常量池中的援用地址;

今日份分享已完结,请大家多多包涵和指导!

退出移动版