【Java】JDK试题

问:为什么反射的性能较差?有没有什么方法可以让他变快?

参考答案: java反射要解析字节码,将内存中的对象进行解析,包括了一些动态类型,JVM难以优化,而且在调用时还需要拼接参数,执行步骤也更多。因此,反射操作的效率要更低

​ 常用的改进性能方法主要有:

  • m.setAccessible(true);

由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的;

  • 用缓存将反射得到的元数据保存起来;
  • 利用一些高性能的反射库,如ReflectASM ReflectASM 使用字节码生成的方式实现了更为高效的反射机制。执行时会生成一个存取类来 set/get 字段,访问方法或创建实例。一看到 ASM 就能领悟到 ReflectASM 会用字节码生成的方式,而不是依赖于 Java 本身的反射机制来实现的,所以它更快,并且避免了访问原始类型因自动装箱而产生的问题。

问:java当中的四种引用分别指什么?

参考答案:

强引用,软引用,弱引用,虚引用。不同的引用类型主要体现在GC上:

强引用,如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象;

软引用,在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收;

弱引用,具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象;

虚引用,顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收;

问:为什么要有不同的引用类型?

参考答案:

Java语言有时需要我们适当的控制对象被回收的时机,因此就诞生了不同的引用类型,可以说不同的引用类型实则是对GC回收时机不可控的妥协。比如说以下应用场景:

利用软引用和弱引用解决OOM问题:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题;

问:虚拟机是如何实现多态的?

参考答案:

动态绑定技术(dynamic binding),执行期间判断所引用对象的实际类型,根据实际类型调用对应的方法.

问:静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?

参考答案:

Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化

问:内部类的作用

参考答案:

内部类可以有多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。在单个外围类当中,可以让多个内部类以不同的方式实现同一接口,或者继承同一个类.

创建内部类对象的时刻不依赖于外部类对象的创建.内部类并没有令人疑惑的”is-a”关系,它就像是一个独立的实体。内部类提供了更好的封装,除了该外围类,其他类都不能访问

问:3*0.1==0.3返回值是什么

参考答案:

false,因为有些浮点数不能完全精确的表示出来。

问:a=a+b与a+=b有什么区别吗?

参考答案:

+=操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型,而a=a+b则不会自动进行类型转换。

举个例子,如: byte a = 23; byte b = 22; b = a + b;//编译出错 而 b += a; // 编译OK

问:int 和Integer谁占用的内存更多?

参考答案:

Integer 对象会占用更多的内存。Integer是一个对象,需要存储对象的元数据。但是int是一个原始类型的数据,所以占用的空间更少;

问:JVM、JRE、JDK及 JIT 之间有什么不同

参考答案:

java 虚拟机 (JVM),是实现java语言平台独立性的基础,可以理解伪代码字节码,提供对多个平台的良好支持,在用户和操作系统之间建立了一层枢纽。

java 运行时环境 (JRE),是JVM 的一个超集。JVM 对于一个平台或者操作系统是明确的,而 JRE 确实一个一般的概念,他代表了完整的运行时环境。在 jre 文件夹中的jar 文件和可执行文件都会变成运行时的一部分。事实上,运行时 JRE 变成了 JVM。所以对于一般情况时候使用 JRE,对于明确的操作系统来说使用 JVM。当你下载了 JRE 的时候,也就自动下载了 JVM。

java 开发工具箱 (JDK),java 开发工具箱指的是编写一个 java 应用所需要的所有 jar 文件和可执行文件。事实上,JRE 是 JDK 的一部分。如果你下载了 JDK,你会看到一个名叫 JRE 的文件夹在里面。JDK 中要被牢记的 jar 文件就是 tools.jar,它包含了用于执行 java 文档的类还有用于类签名的 jar 包。

即时编译器 (JIT),即时编译器是种特殊的编译器,它通过有效的把字节码变成机器码来提高 JVM 的效率。JIT 这种功效很特殊,因为他把检测到的相似的字节码编译成单一运行的机器码,从而节省了 CPU 的使用。这和其他的字节码编译器不同,因为他是运行时编译(从字节码到机器码)而不是在程序运行之前。正是因为这些,动态编译这个词汇才和 JIT 有那么紧密的关系。

问:Java 泛型类在什么时候确定类型?

参考答案:

在编译期间确定变量类型。类型擦除。

问:引用类型是占用几个字节?

参考答案:

hotspot在64位平台上,占8个字节,在32位平台上占4个字节。

问:JDK主流版本的差异

参考答案:

  • Java 5(2004年发行),影响很大的一个版本;

    • 1、泛型
    • 2、Metadata,元数据,描述数据的数据。
    • 3、自动装箱和拆箱,也就是基本数据类型(如 int)和它的包装类型(如 Integer)自动帮你转换(其实背后是相关的方法帮你做了转换工作)。
    • 4、枚举
    • 5、可变参数,一个函数可以传入数量不固定的参数值。
    • 6、增强版的 for 循环
    • 7、改进了 Java 的内存模型,提供了 java.util.concurrent 并发包。
  • Java 6(2006年发行),这个版本的 Java 更多是对之前版本功能的优化,增强了用户的可用性和修复了一些漏洞,

    • 1、提供动态语言支持。
    • 2、提供编译 API,即 Java 程序可以调用 Java 编译器的 API。
    • 3、Swing 库的一些改进
    • 4、JVM 的优化
    • 5、微型 HTTP 服务器 API ;
  • Java 7(2011年发行)

    • 1、放宽 switch 的使用,可以在 switch 中使用字符串;
    • 2、try-resource-with 语句,帮助自动化管理资源,如打开文件,对文件操作结束后,JVM 可以自动帮我们关闭文件资源,当然前提是你要用 try-resource-with 语句。
    • 3、加入了类型推断功能,比如你之前版本使用泛型类型时这样写 ArrayList userList= new ArrayList();,这个版本只需要这样写 ArrayList userList= new ArrayList<>();,也即是后面一个尖括号内的类型,JVM 帮我们自动类型判断补全了。
    • 4、简化了可变参数的使用。
    • 5、支持二进制整数,在硬件开发中,二进制数更常用,方便人查看。
    • 6、支持带下划线的数值,如 int a = 100000000;,0 太多不便于人阅读,这个版本支持这样写 int a = 100_000_000,这样就对数值一目了然了吧。
    • 7、异常处理支持多个 catch 语句。
    • 8、NIO 库的一些改进,增加多重文件的支持、文件原始数据和符号链接。
  • Java 8(2014年发行)

    • 1、Lambda 表达式,简化代码
    • 2、注解功能的增强。重复注解和注解扩展,现在几乎可以为任何东西添加注解:局部变量、泛型类、父类与接口的实现,就连方法的异常也能添加注解。
    • 3、新的时间和日期 API,在这之前 Java 的时间和日期库被投票为最难用的 API 之一,所以这个版本就改进了。
    • 4、JavaFX,一种用在桌面开发领域的技术(也是和其他公司竞争,这个让我们拭目以待吧)。
    • 5、静态链接 JNI 程序库(这个做安卓开发的同学应该熟悉)。
    • 6、接口默认方法和静态方法
    • 7、函数式接口
    • 8、方法引用
    • 9、java.util.stream
    • 10、HashMap的底层实现有变化
    • 11、JVM内存管理方面,由元空间代替了永久代。
  • Java 9 (2017年发行)

    • 1、模块化(这点也是向其他语言学习的,如 JavaScript)。
    • 2、Java Shell(这点也是向其他语言学习的,如 Python),在这之前总有人说 Java 太麻烦,写个 Hello Word 都要新建个类,有时候测试个几行的代码都不方便,Java Shell 推出后,Java 开发者不用眼馋其他语言的 Shell 了;
    • 3、即时编译功能的增强
    • 4、XML Catalogs,XML 文件自动校验。
  • Java 10(2018年发行)

    • 1、局部变量的类型推断 var关键字
    • 2、GC改进和内存管理 并行全垃圾回收器 G1
    • 3、垃圾回收器接口
    • 4、线程-局部变量管控
    • 5、合并 JDK 多个代码仓库到一个单独的储存库中
  • Java 11(2018年发行)

    • 1、本地变量类型推断
    • 2、字符串加强
    • 3、集合加强
    • 4、Stream 加强
    • Optional 加强
    • 5、InputStream 加强
    • 6、HTTP Client API
    • 7、化繁为简,一个命令编译运行源代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值