1. 什么是Java中的JVM,JRE和JDK,它们之间的关系是什么?
JVM(Java Virtual Machine,Java虚拟机)是Java程序运行时的执行环境,它负责将字节码(.class文件)转换为操作系统能够执行的机器码。JRE(Java Runtime Environment,Java运行环境)包含JVM以及Java类库,是运行Java程序所需的环境。JDK(Java Development Kit,Java开发工具包)包含JRE和开发工具(如编译器、调试工具等),用于开发Java应用。
关系:
- JDK > JRE > JVM,即JDK包含JRE,而JRE又包含JVM。
2. 为什么Java中String是不可变的(Immutable)?
Java中的String
类是不可变的,意味着一旦创建,字符串对象不能被修改。原因如下:
- 安全性:
String
在很多地方作为参数传递,比如网络连接、文件路径等。不可变性保证了这些参数的安全性。 - 线程安全:不可变对象是天然线程安全的,多个线程可以安全地共享同一个字符串实例,而不需要进行同步。
- 性能优化:Java中字符串常量池(String Pool)允许多个字符串对象共享同一内存,这在不可变性前提下成为可能。
3. 什么是Java中的值传递与引用传递?
Java中的参数传递采用的是值传递。当一个对象作为参数传递给方法时,传递的是对象的引用的拷贝,而不是对象本身。因此,方法内部可以通过引用来修改对象的内容,但无法改变引用本身指向的对象。
示例:
public class Test {
public static void main(String[] args) {
int num = 10;
changeValue(num);
System.out.println("After change: " + num); // 输出10
StringBuilder sb = new StringBuilder("Hello");
changeReference(sb);
System.out.println(sb); // 输出HelloWorld
}
public static void changeValue(int x) {
x = 20;
}
public static void changeReference(StringBuilder sb) {
sb.append("World");
}
}
在上述示例中,num
的值没有改变,因为Java使用的是值传递;而StringBuilder
对象的内容被修改了,因为修改的是对象引用指向的内容。
4. 请解释Java中的多态(Polymorphism)概念,并给出一个简单的例子
多态是面向对象编程的三大特性之一,指同一操作作用于不同的对象时可以表现出不同的行为。多态性通过方法重写(Override)和方法重载(Overload)实现。方法重写通常用于继承中的父类和子类之间,子类可以提供父类方法的具体实现。
示例:
class Animal {
public void sound() {
System.out.println("Animal is making a sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog is barking");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Cat is meowing");
}
}
public class TestPolymorphism {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.sound(); // 输出Dog is barking
myCat.sound(); // 输出Cat is meowing
}
}
在这个例子中,Animal
类具有一个sound()
方法,而其子类Dog
和Cat
重写了这个方法。通过多态性,myDog
和myCat
在运行时调用的都是其各自类的实现。
5. 什么是Java中的线程安全?如何实现线程安全?
线程安全是指多个线程同时访问某一代码块或资源时,能够保证数据的正确性。线程安全问题通常发生在共享变量或资源的读写上。
实现线程安全的方式有:
- 同步方法和同步块:使用
synchonized
关键字来确保线程安全,但可能导致性能下降。public synchronized void increment() { count++; }
- ReentrantLock:提供了更灵活的锁机制,如超时锁定等。
Lock lock = new ReentrantLock(); lock.lock(); try { // 临界区代码 } finally { lock.unlock(); }
- 线程安全的类:如
ConcurrentHashMap
、CopyOnWriteArrayList
等。
6. 什么是Java中的垃圾回收机制(GC),它是如何工作的?
Java中的垃圾回收(Garbage Collection)是自动管理内存的机制。JVM会自动检测不再使用的对象并释放它们占用的内存,从而避免内存泄漏。常见的GC算法包括:
- 标记-清除(Mark and Sweep):标记所有活动对象并清除未标记的对象。
- 复制算法:将活跃对象复制到另一块内存区域,并清空旧的内存区域。
- 标记-整理(Mark and Compact):标记活动对象并将它们整理到一端,清空另一端的内存。
JVM提供了不同的GC策略,如Serial GC
、Parallel GC
、G1 GC
等,适用于不同的应用场景。