1.什么是线程局部变量?(答案)
线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java 提供 ThreadLocal 类来支持线程局部变量,是一种实现线程安全的方式。但是在管理环境下(如 web 服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期都要长。任何线程局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险。
2.用 wait-notify 写一段代码来解决生产者-消费者问题?(答案)
请参考答案中的示例代码。只要记住在同步块中调用 wait() 和 notify()方法,如果阻塞,通过循环来测试等待条件。
3. 用 Java 写一个线程安全的单例模式(Singleton)?(答案)
请参考答案中的示例代码,这里面一步一步教你创建一个线程安全的 Java 单例类。当我们说线程安全时,意思是即使初始化是在多线程环境中,仍然能保证单个实例。Java 中,使用枚举作为单例类是最简单的方式来创建线程安全单例模式的方式。
4.Java 中 sleep 方法和 wait 方法的区别?(答案)
虽然两者都是用来暂停当前运行的线程,但是 sleep() 实际上只是短暂停顿,因为它不会释放锁,而 wait() 意味着条件等待,这就是为什么该方法要释放锁,因为只有这样,其他等待的线程才能在满足条件时获取到该锁。
5.什么是不可变对象(immutable object)?Java 中怎么创建一个不可变对象?(答案)
不可变对象指对象一旦被创建,状态就不能再改变。任何修改都会创建一个新的对象,如 String、Integer及其它包装类。详情参见答案,一步一步指导你在 Java 中创建一个不可变的类。
6.我们能创建一个包含可变对象的不可变对象吗?
是的,我们是可以创建一个包含可变对象的不可变对象的,你只需要谨慎一点,不要共享可变对象的引用就可以了,如果需要变化时,就返回原对象的一个拷贝。最常见的例子就是对象中包含一个日期对象的引用。
数据类型和 Java 基础面试问题
7.Java 中应该使用什么数据类型来代表价格?(答案)
如果不是特别关心内存和性能的话,使用BigDecimal,否则使用预定义精度的 double 类型。
8.怎么将 byte 转换为 String?(答案)
可以使用 String 接收 byte[] 参数的构造器来进行转换,需要注意的点是要使用的正确的编码,否则会使用平台默认编码,这个编码可能跟原来的编码相同,也可能不同。
9.Java 中怎样将 bytes 转换为 long 类型?
这个问题你来回答 :-)
10.我们能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?
是的,我们可以做强制转换,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,如果强制转化是,int 类型的高 24 位将会被丢弃,byte 类型的范围是从 -128 到 128。
11.存在两个类,B 继承 A,C 继承 B,我们能将 B 转换为 C 么?如 C = (C) B;(answer答案)
12.哪个类包含 clone 方法?是 Cloneable 还是 Object?(答案)
java.lang.Cloneable 是一个标示性接口,不包含任何方法,clone 方法在 object 类中定义。并且需要知道 clone() 方法是一个本地方法,这意味着它是由 c 或 c++ 或 其他本地语言实现的。
13.Java 中 ++ 操作符是线程安全的吗?(答案)
不是线程安全的操作。它涉及到多个指令,如读取变量值,增加,然后存储回内存,这个过程可能会出现多个线程交差。
14.a = a + b 与 a += b 的区别(答案)
+= 隐式的将加操作的结果类型强制转换为持有结果的类型。如果两这个整型相加,如 byte、short 或者 int,首先会将它们提升到 int 类型,然后在执行加法操作。如果加法操作的结果比 a 的最大值要大,则 a+b 会出现编译错误,但是 a += b 没问题,如下:
byte a = 127;
byte b = 127;
b = a + b; // error : cannot convert from int to byte
b += a; // ok
(译者注:这个地方应该表述的有误,其实无论 a+b 的值为多少,编译器都会报错,因为 a+b 操作会将 a、b 提升为 int 类型,所以将 int 类型赋值给 byte 就会编译出错)
15.我能在不进行强制转换的情况下将一个 double 值赋值给 long 类型的变量吗?(答案)
不行,你不能在没有强制类型转换的前提下将一个 double 值赋值给 long 类型的变量,因为 double 类型的范围比 long 类型更广,所以必须要进行强制转换。
16. 3*0.1 == 0.3 将会返回什么?true 还是 false?(答案)
false,因为有些浮点数不能完全精确的表示出来。
17.int 和 Integer 哪个会占用更多的内存?(答案)
Integer 对象会占用更多的内存。Integer 是一个对象,需要存储对象的元数据。但是 int 是一个原始类型的数据,所以占用的空间更少。
18.为什么 Java 中的 String 是不可变的(Immutable)?(answer答案)
Java 中的 String 不可变是因为 Java 的设计者认为字符串使用非常频繁,将字符串设置为不可变可以允许多个客户端之间共享相同的字符串。更详细的内容参见答案。
19.我们能在 Switch 中使用 String 吗?(answer答案)
从 Java 7 开始,我们可以在 switch case 中使用字符串,但这仅仅是一个语法糖。内部实现在 switch 中使用字符串的 hash code。
20.Java 中的构造器链是什么?(answer答案)
当你从一个构造器中调用另一个构造器,就是Java 中的构造器链。这种情况只在重载了类的构造器的时候才会出现。
JVM 底层 与 GC(Garbage Collection) 的面试问题
21.64 位 JVM 中,int 的长度是多数?
Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位。意思就是说,在 32 位 和 64 位 的Java 虚拟机中,int 类型的长度是相同的。
22.Serial 与 Parallel GC之间的不同之处?(答案)
Serial 与 Parallel 在GC执行的时候都会引起 stop-the-world。它们之间主要不同 serial 收集器是默认的复制收集器,执行 GC 的时候只有一个线程,而 parallel 收集器使用多个 GC 线程来执行。
23. 32 位和 64 位的 JVM,int 类型变量的长度是多数?(答案)
32 位和 64 位的 JVM 中,int 类型变量的长度是相同的,都是 32 位或者 4 个字节。
24.Java 中 WeakReference 与 SoftReference的区别?(答案)
虽然 WeakReference 与 SoftReference 都有利于提高 GC 和 内存的效率,但是 WeakReference ,一旦失去最后一个强引用,就会被 GC 回收,而软引用虽然不能阻止被回收,但是可以延迟到 JVM 内存不足的时候。
25.WeakHashMap 是怎么工作的?(答案)
WeakHashMap 的工作与正常的 HashMap 类似,但是使用弱引用作为 key,意思就是当 key 对象没有任何引用时,key/value 将会被回收。
26.JVM 选项 -XX:+UseCompressedOops 有什么作用?为什么要使用?(答案)
当你将你的应用从 32 位的 JVM 迁移到 64 位的 JVM 时,由于对象的指针从 32 位增加到了 64 位,因此堆内存会突然增加,差不多要翻倍。这也会对 CPU 缓存(容量比内存小很多)的数据产生不利的影响。因为,迁移到 64 位的 JVM 主要动机在于可以指定最大堆大小,通过压缩 OOP 可以节省一定的内存。通过 -XX:+UseCompressedOops 选项,JVM 会使用 32 位的 OOP,而不是 64 位的 OOP。
27.怎样通过 Java 程序来判断 JVM 是 32 位 还是 64 位?(答案)
你可以检查某些系统属性如 sun.arch.data.model 或 os.arch 来获取该信息。
28.32 位 JVM 和 64 位 JVM 的最大堆内存分别是多数?(答案)
理论上说上 32 位的 JVM 堆内存可以到达 2^32,即 4GB,但实际上会比这个小很多。不同操作系统之间不同,如 Windows 系统大约 1.5 GB,Solaris 大约 3GB。64 位 JVM允许指定最大的堆内存,理论上可以达到 2^64,这是一个非常大的数字,实际上你可以指定堆内存大小到 100GB。甚至有的 JVM,如 Azul,堆内存到 1000G 都是可能的。
29.JRE、JDK、JVM 及 JIT 之间有什么不同?(答案)
JRE 代表 Java 运行时(Java run-time),是运行 Java 引用所必须的。JDK 代表 Java 开发工具(Java development kit),是 Java 程序的开发工具,如 Java 编译器,它也包含 JRE。JVM 代表 Java 虚拟机(Java virtual machine),它的责任是运行 Java 应用。JIT 代表即时编译(Just In Time compilation),当代码执行的次数超过一定的阈值时,会将 Java 字节码转换为本地代码,如,主要的热点代码会被准换为本地代码,这样有利大幅度提高 Java 应用的性能。
30.解释 Java 堆空间及 GC?(答案)
当通过 Java 命令启动 Java 进程的时候,会为它分配内存。内存的一部分用于创建堆空间,当程序中创建对象的时候,就从对空间中分配内存。GC 是 JVM 内部的一个进程,回收无效对象的内存用于将来的分配。
相关文章
- 03-242021年最新Android大厂面试题来袭!附答案解析
- 03-242021金三银四:20道高频面试题(含答案)
- 03-24你头秃都没想到还能这样吧!面试题附答案
- 03-24350道Android面试真题分享,附面试答案
- 03-24Android开发必须掌握!20道高频面试题(含答案)
- 03-242021年12月1日30道面试题
- 03-249.牛批了 Android 2022高级 资深面试题 一线大厂和二线大厂面试真题精选 (字节跳动 附答案)第九套 38k+
- 03-24没想到一个Handler还有中高级几种问法,附面试题答案
- 03-24没想到一个Handler还有中高级几种问法,附面试题答案
- 03-24腾讯、网易必问的20道题Android面试题,已拿offer附真题解析