21xrx.com
2025-03-29 13:29:29 Saturday
文章检索 我的文章 写文章
题目及解析
2023-06-15 16:36:37 深夜i     9     0
多态性 访问修饰符 线程安全

Java面试常见题目及解析

在Java开发中,面试是一个必不可少的环节。许多公司会在面试中考察候选人的基本Java知识和实践经验。下面我们根据常见的Java面试题目,分析解析其答案。

1. 请解释一下Java中的多态性。

多态是Java中的一个重要特性,它指的是在不同的对象上调用同一方法时,会展现出不同的行为方式。这种行为方式的不确定性,是由于不同对象的内部实现方式不同,从而导致了不同的行为结果。

下面是一段代码示例:

public class Animal {
  void sound() {
    System.out.println("Animal makes sound");
  }
}
public class Dog extends Animal {
  void sound() {
    System.out.println("Dog barks");
  }
}
public class Cat extends Animal {
  void sound() {
    System.out.println("Cat meows");
  }
}
public class Main {
  public static void main(String[] args) {
    Animal a = new Animal();
    Animal b = new Dog();
    Animal c = new Cat();
    
    a.sound();
    b.sound();
    c.sound();
  }
}

以上代码定义了 Animal, Dog, Cat 三个类,其中 Animal 类提供了 sound() 方法,在 Dog 和 Cat 类中均重写了此方法。在 Main 类中,分别创建了 Animal、Dog、Cat 三个对象,并调用了它们的 sound() 方法。

编译运行以上代码,会得到如下的输出结果:

Animal makes sound
Dog barks
Cat meows

这就是多态的表现形式。在 Animal 类型的变量 a 中调用 sound() 方法,会执行 Animal 的 sound() 方法;在类型为 Dog 的变量 b 中调用 sound() 方法,会执行 Dog 的 sound() 方法;在类型为 Cat 的变量 c 中调用 sound() 方法,会执行 Cat 的 sound() 方法。

2. 请解释一下Java中的四种访问修饰符:public, protected, private, default。

Java中有四种访问修饰符,它们的作用分别是:

- public:公共访问修饰符,可以被任何其他类所访问。

- protected:受保护的访问修饰符,可以被同一包内的其他类以及其他包中的子类所访问。

- private:私有的访问修饰符,只能被同一类的成员所访问,不能被其他类访问。

- default:默认的访问修饰符,即在没有显式使用任何修饰符的情况下,所声明的变量、方法或类等,只能被同一个包内的其他类所访问。

下面是一段代码示例:

public class MyClass {
  public int publicVar;
  protected int protectedVar;
  private int privateVar;
  int defaultVar;
  
  public int getPrivateVar()
    return privateVar;
  
  
  public void setPrivateVar(int var)
    this.privateVar = var;
  
}
public class Main {
  public static void main(String[] args) {
    MyClass obj = new MyClass();
    obj.publicVar = 100;
    obj.protectedVar = 200;
    obj.setPrivateVar(300);
    obj.defaultVar = 400;
  }
}

以上代码定义了 MyClass 类,其中包含了 publicVar、protectedVar、privateVar、defaultVar 四个成员变量,它们的访问修饰符分别是 public、protected、private、default。在 Main 类中,创建了 MyClass 对象,并分别对其成员变量赋值。

在这个例子中,publicVar 可以被任何其他类所访问,protectedVar 可以被同一包内的其他类或其他包中的子类访问,privateVar 只能被 MyClass 类中的成员访问,defaultVar 只能被同一包内的其他类所访问。

3. 请解释一下Java中的线程安全和线程不安全。

线程安全是指,在多线程环境下,对共享资源的访问不会产生冲突和未定义的结果。

线程不安全则是指,在多线程环境下,对共享资源的访问可能产生冲突和未定义的结果。

在Java中,线程安全问题常常是由于多个线程同时访问了同一个共享资源导致的。为了保证线程安全,可以采用以下方法:

- 加锁:使用 synchronized 关键字或 Lock 接口实现线程同步。

- 使用线程安全的类:例如使用 Vector 替换 ArrayList,使用 ConcurrentHashMap 替换 HashMap。

- 避免共享资源:例如使用 ThreadLocal 类,分别为每个线程创建不同的实例。

下面是一个线程安全的代码示例:

public class Counter {
  private AtomicInteger count = new AtomicInteger(0);
  
  public void increment() {
    count.incrementAndGet();
  }
  
  public int getCount() {
    return count.get();
  }
}
public class MyThread extends Thread {
  private Counter counter;
  
  public MyThread(Counter counter)
    this.counter = counter;
  
  
  public void run() {
    for (int i = 0; i < 10000; i++) {
      counter.increment();
    }
  }
}
public class Main {
  public static void main(String[] args) {
    Counter counter = new Counter();
    MyThread t1 = new MyThread(counter);
    MyThread t2 = new MyThread(counter);
    t1.start();
    t2.start();
    try {
      t1.join();
      t2.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println(counter.getCount());
  }
}

以上代码定义了一个 Counter 类,并提供了 increment()、getCount() 两个方法。increment() 方法会对成员变量 count 进行自增操作,而 getCount() 方法则会返回 count 的值。

在 Main 类中,创建了两个线程 t1 和 t2,它们共同访问同一个 Counter 对象 counter,并调用 increment() 方法进行自增操作。为了保证线程安全,Count 类中的 count 变量使用了原子类实现,在自增操作时不会发生竞态条件。

最后,Main 类输出了 count 的值,结果为 20000。

  
  

评论区