文章目录
- 1. 不通过构造函数也可以创建对象
- 2. java创建对象的几种方式
- 3. 常用算法
- 4. 什么是面向对象
- 5. ==:运算符与equals()方法的使用区别
- 6. 网络三次握手:
- 7. throw 和 throws区别:
- 8. 单例模式与多例模式
- 9. hashCode与equals
- 10. final、finally、finalize三者的区别
- 11. String、StringBuffer、StringBuilder
- 12. 重载和重写的区别
- 13. 接口和抽象类的区别
- 14. List和Set的区别
- 15. ArrayList和LinkedList区别
- 16. HashMap和HashTable有什么区别?其底层实现是什么?
- 17. mybatisde${}和#{}区别
- 18. springboot与springmvc的区别
- 19. java集合框架
- 20. Spring常用注释
- 21. SpringMVC 工作流程
- 21. Spring框架的优点
- 22. springboot优点
- 23. Java中的异常体系
- 24. 递归排序
- 25. 快速排序
- 26. 数据库题目,多表联合查询
- 27. Mybatis是如何进行分页的?分页插件的原理是什么?
- 28. String类中常用的方法
- 29. Java高级特性-反射
- 30. Oracle与Sql server的区别
- 31. 什么是字节码?采用字节码的好处是什么?
- 32. Java类加载器
- 33. 双亲委托模型
- 34. GC如何判断对象可以被回收
- 35. 关于 JVM JDK 和 JRE 最详细通俗的解答
1. 不通过构造函数也可以创建对象
1.1 static不能修饰局部变量
1.2 多态中的成员访问特点
我们在编译期只能调用父类的方法,在执行期执行子类重写父类的方法
有重写的才看子类。static修饰静态方法除外
- 成员变量:看父类
- 构造方法:创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
- 成员方法:编译看左边,运行看右边。由于成员方法存在方法重写,所以它运行看右边。
- 静态方法:看父类,静态和类相关,算不上重写,所以,访问还是左边的
1.3. 二叉树
- 遍历:
- 先序遍历:先(根)序遍历–根左右
- 中序遍历:中(根)序遍历–左根右
- 后序遍历:后(根)序遍历–左右根
1.4.continue与 break
- continue是结束本次循环
- break是跳出循环
2. java创建对象的几种方式
使用new关键字 | 使用new关键字 |
使用Class类的newInstance方法 | 调用了构造函数 |
使用Constructor类的newInstance方法 | 调用了构造函数 |
使用clone方法 | 没有调用构造函数 |
使用反序列化 | 没有调用构造函数 |
3. 常用算法
常用的对称加密算法有:DES、3DES、RC2、RC4、AES
常用的非对称加密算法有:RSA、DSA、ECC
使用单向散列函数的加密算法:MD5、SHA
4. 什么是面向对象
将现实的事物抽象出来,通过继承,实现,组合的方式,把万物容纳。
- 对象的三大特征:
封装,继承,多态 - 五大原则:
单一职责原则(SRP)
开放封闭原则(OCP)
里氏替换原则(LSP)
依赖倒置原则(DIP)
接口隔离原则(ISP)
5. ==:运算符与equals()方法的使用区别
- ==
- 可以使用在基本数据变量类型和引用数据变量类型;
- 如果比较的是基本数据类型变量:比较变量保存的数据是否相等。(不一定类型要相同)
如果比较的是引用数据类型,比较的是两个地址值是否相同
- equals()
- 是一个方法而非运算符
- 只能适用于引用数据类型
- Object类中equals()的定义:
public boolean equals(Object obj) {
return (this == obj);
}
//Object类中定义的equals()和==的作用是相同的:
//比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体
- 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是 两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
- 通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们就需要对Object类中的equals()进行重写. 重写的原则:比较两个对象的实体内容是否相同.
6. 网络三次握手:
第一次,建立连接,客户端发送数据包
第二次,服务器收到数据包,确认,返回数据包
第三次,客户端收到数据包,向服务器发送确认信息
完成开始客户端与服务端的数据传送
7. throw 和 throws区别:
throw 表示抛出一个异常类的对象,生成异常对象的过程。声明在方法体内。
throws 属于异常处理的一种方式,声明在方法的声明处。
8. 单例模式与多例模式
单例减少新生成的消耗、减少垃圾回收、快速获取bean,但是线程不安全
9. hashCode与equals
- HashCode如果相等的情况下,对象值不一定相等,但是如果equals比较对象的内容相同,那么HashCode一定相同
- 如果我们重写了equals方法之后,一定要重写HashCode
10. final、finally、finalize三者的区别
- 【重】final为常量关键字,用来修饰类,方法,变量(一个类不能被final与static同时修饰)
- finally为异常关键字,用在异常处理中,用于处理异常后的清理工作,实际中一般用于关闭文件流,释放资源等操作。
- finalize为object自带方法名
11. String、StringBuffer、StringBuilder
String | StringBuffer | StringBuilder |
---|---|---|
string值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量优先的内存空间 | StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,会自动增加容量 | 可变类,速度更快 |
不可变 | 可变 | 可变 |
线程安全 | 线程不安全 | |
多线程操作字符串 | 单线程操作字符串 |
12. 重载和重写的区别
-
重载
重载发生在本类,方法名相同,参数列表不同,与返回值无关,只和方法名,参数列表,参数的类型有关(方法名可以一样,参数列表,参数类型可以不同) -
重写
子类与父类之间他们要方法名相同,参数相同,但是具体的实现可以不同。(构造方法不能被重写)
13. 接口和抽象类的区别
Java中接口和抽象类的定义语法分别为interface与abstract关键字
- 抽象类
在java中被abstract关键字修饰的类称为抽象类,被abstract关键字修饰的方法称为抽象方法,抽象方法只有方法的声明,没有方法体。抽象类的特点:
a. 抽象类不能被实例化只能被继承;
b. 包含抽象方法的一定是抽象类,但是抽象类不一定含有抽象方法;
c. 抽象类中抽象方法的修饰符只能为public或者protected,默认为public
d. 一个子类继承一个抽象类,则子类必须实现父类抽象方法,否则子类也必须定义为抽象类;
e. 抽象类可以包含属性、方法、构造方法,但是构造方法不能用于实例化,主要用途是被子类调用。 - 接口:java中接口使用interface关键字修饰,特点为:
a. 接口可以包含变量、方法
b. 接口支持多继承,即一个接口可以扩展多个接口,间接的解决了java类的单继承问题
c. 一个类可以实现多个接口 - 接口与抽象类的区别
a. 相同点
(1)都不能被实例化 (2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
b. 不同点
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
14. List和Set的区别
list与set方法的区别有:
- 重复对象
list方法允许重复对象而set不允许 - null元素
list可以插入多个null元素,而set只能插入一个 - 容器是否有序
list是一个有序容器,保持了每个元素的插入顺序,即输出顺序就是输入顺序,set方法是无序容器,不能保证每个元素的存储顺序 - 常用实现类
List:ArrayList,LinkedList, Vector
其中ArrayList 最为流行,它提供了使用索引的随意访问,而LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适,Vector 表示底层数组,线程安全
Set: HashSet、LinkedHashSet 、 TreeSet
最流行的是基于 HashMap实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和compareTo() 的定义进行排序的有序容器
15. ArrayList和LinkedList区别
- 相同点
都实现了List接口和Collection - 基本区别
- ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
- 对于随机访问get和set,ArrayList觉得优于LinkedList(因为LinkedList要移动指针)。
- linkedlist的增删要优于arraylist(因为ArrayList要移动数据)。
- 区别原理解析
* ArrayList是基于数组实现的,他的特性就是可以使用索引来提升查询效率;插入和删除数组中某个元素,会导致其后面的元素需要重新调整索引,产生一定的性能消耗;
* LinkedList是基于链表实现的,没有索引,所以查询效率不高,但是插入和删除效率却很高;为什么呢?因为链表里插入或删除某个元素,只需要调整前后元素的引用即可
16. HashMap和HashTable有什么区别?其底层实现是什么?
- 区别
- 继承的父类不同
HashTable继承Dictionary类,而hashMap继承了AbstractMap类,但是二者都实现了map接口。 - 线程安全性不同
Hashtable 线程安全,因为它每个方法中都加入了Synchronize。HashMap是线程不安全的。
HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组位置存放链表的头结点。对链表而言,新加入的节点会从头结点加入。在hashmap做put操作的时候可能会造成数据丢失。现在假如A线程和B线程同时对同一个数组位置调用addEntry,两个线程会同时得到现在的头结点,然后A写入新的头结点之后,B也写入新的头结点,那B的写入操作就会覆盖A的写入操作造成A的写入操作丢失
- 是否提供contains方法
- HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey
- Hashtable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同。
- key和value是否允许null值
Hashtable中,key和value都不允许出现null值。但是如果在Hashtable中有类似put(null,null)的操作 - 两个遍历方式的内部实现上不同
Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。 - hash值不同
哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
17. mybatisde${}和#{}区别
- ${ } 变量的替换阶段是在动态 SQL 解析阶段,而 #{ }变量的替换是在 DBMS 中。
- #方式能够很大程度防止sql注入。
- $方式无法防止Sql注入。
- $方式一般用于传入数据库对象,例如传入表名.
- 一般能用#的就别用$.
18. springboot与springmvc的区别
- spring boot只是一个配置工具,整合工具,辅助工具.
Spring Boot实现了自动配置,降低了项目搭建的复杂度。 - springmvc是框架,项目中实际运行的代码
Spring MVC提供了一种轻度耦合的方式来开发web应用。它是Spring的一个模块,是一个web框架。
19. java集合框架
- List ,Set, Map是否继承来自Collection接口? 存取元素时, 有何差异?
- List、Set 是继承 Collection 接口; Map不是。
- List:元素有放入顺序,元素可重复,通过下标来存取。
- Map:元素按键值对存取,无放入顺序。
- Set:元素无存取顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在 set 中的位置是有该元素的 hashCode 决定的,其位置其实是固定的)。
20. Spring常用注释
- 注册bean对象注解
- @Component
- @Controller
- @Service
- @Repository
- 用于依赖注入的注解
- @Autowired(type)
- @Qualifier(name要和Autowired一起使用)
- @Resource
- @Value(可以将外部的值注入到bean中)
- 用于改变bean作用范围的注解
- @Scope
value:
1)singleton:单例
2)prototype:多例
3)request:
4)session:
5)globalsession:
- 生命周期相关的注解
- @PostConstruct(指定初始化方法)
- @PreDestroy(指定销毁方法)
21. SpringMVC 工作流程
-
用户发送请求至前端控制器 DispatcherServlet。
-
DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
-
处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
-
DispatcherServlet 调用 HandlerAdapter 处理器适配器。
-
HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)
-
Controller 执行完成返回 ModelAndView。
-
HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。
-
DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。
-
ViewReslover 解析后返回具体 View。
-
DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
-
DispatcherServlet 响应用户。
21. Spring框架的优点
- 非侵入式设计
Spring是一种非侵入式(non-invasive)框架,它可以使应用程序代码对框架的依赖最小化。 - 方便解耦、简化开发
Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护工作都交给Spring容器的管理,大大的降低了组件之间的耦合性。 - 支持AOP
Spring提供了对AOP的支持,它允许将一些通用任务,如安全、事物、日志等进行集中式处理,从而提高了程序的复用性。 - 支持声明式事务处理
只需要通过配置就可以完成对事物的管理,而无须手动编程。 - 方便程序的测试
Spring提供了对Junit4的支持,可以通过注解方便的测试Spring程序。 - 方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如Struts、Hibernate、MyBatis、Quartz等)的直接支持。 - 降低Jave EE API的使用难度。
Spring对Java EE开发中非常难用的一些API(如JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低。
22. springboot优点
- 配置变得简单
- springboot内嵌了servlet容器,降低了对环境的要求,机器有java运行环境,可以将项目打包成jar包,通过java命令 java -jar ***.jar 来执行。
- 快速整合第三方框架,无需配置文件
- 解决了Spring的弊端
- 代码少了、配置文件少了、不需要对第三方框架烦恼了、项目精简了,对整个团队的开发及维护来说,更大的节约了成本。
- 使用Java或Groovy开发基于Spring的应用程序非常容易。
- 它减少了大量的开发时间并提高了生产力。
- 它避免了编写大量的样板代码,注释和XML配置。
- Spring Boot应用程序与其Spring生态系统(如Spring JDBC,Spring ORM,Spring Data,Spring Security等)集成非常容易。
23. Java中的异常体系
- 所有的异常都是从Throwable继承而来的,是所有异常的共同祖先。
- Throwable有两个子类,Error和Exception。
- error
Error是错误,对于所有的编译时期的错误以及系统错误都是通过Error抛出的。 - Exception
Exception是另外一个非常重要的异常子类。它规定的异常是程序本身可以处理的异常。异常和错误的区别是,异常是可以被处理的,而错误是没法处理的。 - 异常的处理
* 通过try…catch语句块来处理
* 也可以在具体位置不处理,直接抛出,通过throws/throw到上层再进行处理
* finally关键字,收尾:无论异常如何,总会被执行的代码
24. 递归排序
25. 快速排序
26. 数据库题目,多表联合查询
- 大学生春季运动会的数据库,保存了比赛信息的三个表如下:
运动员 sporter(运动员编号 sporterid,姓名name,性别 sex,所属系号 department),
项目 item(项目编号 itemid,名称 itemname,比赛地点 location), 成绩 grade(运动员编号 id,项目编号 itemid,积分 mark)。
用SQL语句完成在“体育馆”进行比赛的各项目名称及其冠军的姓名:
SELECT i.itemname,s.name
FROM grade g,
(SELECT itemid iid,MAX(mark) max
FROM grade
WHERE itemid IN
( SELECT itemid
FROM item
WHERE location='体育馆')
GROUP BY itemid) temp,
item i,sporter s
WHERE
g.itemid=temp.iid
AND g.mark=temp.max
AND temp.iid=i.itemid
AND s.sporterid=g.sporterid;
1,首先找出在“体育馆”中进行的比赛项目id;
SELECT itemid
FROM item
WHERE location='体育馆'
2,然后在成绩表中根据项目id进行分组后找出单个项目最高分;
SELECT itemid iid,MAX(mark) max
FROM grade
//条件限制地点在体育馆
WHERE itemid IN ( SELECT itemid FROM item WHERE location='体育馆')
GROUP BY itemid
3,接下来将上面含有项目id和项目最高分信息的表与另外三张表连接;
grade g, (上面含有项目最高分信息的表) temp, item i,sporter s
WHERE g.itemid=temp.iid
AND g.mark=temp.max
AND temp.iid=i.itemid
AND s.sporterid=g.sporterid
4,最后按要求从连接后的表中选出项目名称和冠军姓名。
SELECT i.itemname,s.name
FROM (以上连接后的表)
- 关键字功能
ALTER TABLE <表名> [修改选项]
{ ADD COLUMN <列名> <类型>
CHANGE COLUMN <旧列名> <新列名> <新列类型>
ALTER COLUMN <列名> { SET DEFAULT <默认值> | DROP DEFAULT }
MODIFY COLUMN <列名> <类型>
DROP COLUMN <列名>
RENAME TO <新表名>
//CHANGE 用来修改字段名字以及类型
//modify 用来修改字段类型
//aiter column ... set 用来修改字段数据
- 在SQL中语法规范中,having子句的使用下面描述正确的是
* having子句即可包含聚合函数作用的字段也可包括普通的标量字段
* having子句必须于group by 子句同时使用,不能单独使用 - SQL中的聚合函数
count():总数
avg():平均
sum():总和
max():最大值
min():最小值
27. Mybatis是如何进行分页的?分页插件的原理是什么?
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10
28. String类中常用的方法
- 构造方法
- String(String original):把字符串数据封装成字符串对象
- String(char[] value):把字符数组的数据封装成字符串对象
- String(char[] value, int index, int count):把字符数组中的一部分数据封装成字符串对象
- 常用方法
- length():获取长度
- charAt(int index):获取指定索引处的字符
- indexOf(String str):获取str在字符串对象中第一次出现的索引
- substring(int start):从start开始截取字符串
- trim():去除字符串两端空格
29. Java高级特性-反射
- 什么是反射
(反射就是根据字节码文件, 获得类的信息,字段信息,方法信息等内容, 创建实例,调用方法的技术)
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。 - 怎么实现反射方法
- 定义一个类
- 得到class方法
1)通过对象调用 getClass()
(Person p1 = new Person();Class c1 = p1.getClass();
)
2)直接通过 类名.class 的方式得到
(Class c2 = Person.class;
)
3)通过 Class 对象的 forName() 静态方法来获取
(Class c3 = Class.forName("com.ys.reflex.Person");
) - 通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等。
getName()、getMethods():
- 反射机制的优缺点
优:可以动态执行,在运行期间根据业务功能动态执行方法、访问属性,提高了程序的灵活性和扩展性,在底层框架中用的比较多
缺:对性能有影响,这类操作总是慢于直接执行java代码。 - 哪里用到反射机制
- JDBC中,利用反射动态加载了数据库驱动程序。
- Web服务器中利用反射调用了Sevlet的服务方法。
- 很多框架都用到反射机制,注入属性,调用方法,如Spring
30. Oracle与Sql server的区别
- 操作的平台不同
- Oracle可在所有主流平台上运行
- SQL Server却只能在Windows上运行
- 文体结构不同
- oracle的文件体系结构为:
* 数据文件 .dbf(真实数据)
* 日志文件 .rdo
* 控制文件 .ctl
* 参数文件 .ora - sql server的文件体系结构为:
* .mdf (数据字典)
* .ndf (数据文件)
* .ldf (日志文件)
- 存储结构不同
- 块(block)是 Oracle 中最小的空间分配单位。
- SQL Server 中数据存储的基本单位是页。SQL Server 读取或写入所有数据页。
- 安全性
- Oracle的安全认证获得最高认证级别的ISO标准认证
- 性能不同
- SQL Server 多用户时性能不佳
- Oracle 性能最高, 保持windowsNT下的TPC-D和TPC-C的世界记录。
- 开放性
- SQL Server 只能在windows 上运行
- Oracle能在大多数主流平台运行
31. 什么是字节码?采用字节码的好处是什么?
在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以 Java 程序运行时比较高效,而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。
32. Java类加载器
33. 双亲委托模型
34. GC如何判断对象可以被回收
35. 关于 JVM JDK 和 JRE 最详细通俗的解答
- JVM
Java 虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。
- Java 程序从源代码到运行一般有下面 3 步:
- 我们需要格外注意的是 .class->机器码 这一步。在这一步 JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。而且,有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了 JIT 编译器,而 JIT 属于运行时编译。当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。而我们知道,机器码的运行效率肯定是高于 Java 解释器的。这也解释了我们为什么经常会说 Java 是编译与解释共存的语言。
- HotSpot 采用了惰性评估(Lazy Evaluation)的做法,根据二八定律,消耗大部分系统资源的只有那一小部分的代码(热点代码),而这也就是 JIT 所需要编译的部分。JVM 会根据代码每次被执行的情况收集信息并相应地做出一些优化,因此执行的次数越多,它的速度就越快。JDK 9 引入了一种新的编译模式 AOT(Ahead of Time Compilation),它是直接将字节码编译成机器码,这样就避免了 JIT 预热等各方面的开销。JDK 支持分层编译和 AOT 协作使用。但是 ,AOT 编译器的编译质量是肯定比不上 JIT 编译器的。
总结:
Java 虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处可以运行”的关键所在。
- JDK 和 JRE
- JDK 是 Java Development Kit 缩写,它是功能齐全的 Java SDK。它拥有 JRE 所拥有的一切,还有编译器(javac)和工具(如 javadoc 和 jdb)。它能够创建和编译程序。
- JRE 是 Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,java 命令和其他的一些基础构件。但是,它不能用于创建新程序。
- 如果你只是为了运行一下 Java 程序的话,那么你只需要安装 JRE 就可以了。如果你需要进行一些 Java 编程方面的工作,那么你就需要安装 JDK 了。但是,这不是绝对的。有时,即使您不打算在计算机上进行任何 Java 开发,仍然需要安装 JDK。例如,如果要使用 JSP 部署 Web 应用程序,那么从技术上讲,您只是在应用程序服务器中运行 Java 程序。那你为什么需要 JDK 呢?因为应用程序服务器会将 JSP 转换为 Java servlet,并且需要使用 JDK 来编译 servlet。
- Oracle JDK 和 OpenJDK 的对比
- 可能在看这个问题之前很多人和我一样并没有接触和使用过 OpenJDK 。那么 Oracle 和 OpenJDK 之间是否存在重大差异?下面我通过收集到的一些资料,为你解答这个被很多人忽视的问题。
- 对于 Java 7,没什么关键的地方。OpenJDK 项目主要基于 Sun 捐赠的 HotSpot 源代码。此外,OpenJDK 被选为 Java 7 的参考实现,由 Oracle 工程师维护。
关于 JVM,JDK,JRE 和 OpenJDK 之间的区别,Oracle 博客帖子在 2012 年有一个更详细的答案:
问:OpenJDK 存储库中的源代码与用于构建 Oracle JDK 的代码之间有什么区别?
答:非常接近 - 我们的 Oracle JDK 版本构建过程基于 OpenJDK 7 构建,只添加了几个部分,例如部署代码,其中包括 Oracle 的 Java 插件和 Java WebStart 的实现,以及一些封闭的源代码派对组件,如图形光栅化器,一些开源的第三方组件,如 Rhino,以及一些零碎的东西,如附加文档或第三方字体。展望未来,我们的目的是开源 Oracle JDK 的所有部分,除了我们考虑商业功能的部分。