开发者社区 问答 正文

【精品问答】Java资深面试题

展开
收起
珍宝珠 2020-02-07 17:16:43 1703 分享 版权
阿里云 AI 助理回答
  1. 在Java中创建死锁并修复它:

    创建死锁的示例代码如下:

    public class DeadLockDemo {
       private static Object resource1 = new Object();
       private static Object resource2 = new Object();
    
       public static void main(String[] args) {
           Thread thread1 = new Thread(() -> {
               synchronized (resource1) {
                   System.out.println(Thread.currentThread() + " got resource1");
                   try {
                       Thread.sleep(100);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   synchronized (resource2) {
                       System.out.println(Thread.currentThread() + " got resource2");
                   }
               }
           });
    
           Thread thread2 = new Thread(() -> {
               synchronized (resource2) {
                   System.out.println(Thread.currentThread() + " got resource2");
                   try {
                       Thread.sleep(100);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   synchronized (resource1) {
                       System.out.println(Thread.currentThread() + " got resource1");
                   }
               }
           });
    
           thread1.start();
           thread2.start();
       }
    }
    

    修复死锁的方法是确保线程获取资源的顺序一致,例如,都先获取resource1再获取resource2

  2. 使用双重检查锁定创建线程安全的单例:

    双重检查锁定是一种常用的优化手段,用于减少同步开销,同时保证线程安全。示例代码如下:

    public class Singleton {
       private volatile static Singleton uniqueInstance;
    
       private Singleton() {}
    
       public static Singleton getInstance() {
           if (uniqueInstance == null) {
               synchronized (Singleton.class) {
                   if (uniqueInstance == null) {
                       uniqueInstance = new Singleton();
                   }
               }
           }
           return uniqueInstance;
       }
    }
    

    volatile关键字确保了多线程环境下实例变量被正确地初始化。

  3. char数组比String更适合存储密码:

    原因在于安全性。String对象在Java中是不可变的,一旦创建就无法修改,这意味着密码作为字符串存在内存中可能会留下痕迹,容易受到内存分析工具的攻击。而使用char数组可以手动覆盖敏感信息,比如在验证密码后将数组中的字符置为默认值,从而提高安全性。

  4. String在Java中是不可变的原因:

    String设计成不可变是为了实现线程安全、高效地共享和作为哈希码的键(如HashMap的键)。不可变性使得字符串池成为可能,减少了内存消耗,并且允许类库方法不必担心字符串内容被意外改变。

  5. Java不支持运算符重载的原因:

    Java设计者选择不支持运算符重载主要是为了保持语言的简单性和易读性。避免运算符重载可能导致的潜在滥用和理解上的复杂性,使得代码更易于阅读和维护。

  6. 等待和通知是在Object类而不是Thread中声明的原因:

    等待(wait)、通知(notify/notifyAll)方法与特定的对象监视器(即锁)相关联,而不是与线程本身关联。这些操作都是基于对象的,因为它们涉及到对象的状态和多个线程对该状态的访问控制。因此,将它们放在Object类中意味着任何对象都可以用作锁,进而实现线程间的同步。这符合面向对象编程的原则,即行为与数据紧密耦合。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答