当前位置: 首页 > news >正文

Java 面试题超详细解析(二)

1. 是否可以继承String类?

不可以继承String类,因为String类被final关键字修饰。在Java中,final修饰的类不能被继承,这是为了保证String类的不可变性、安全性和效率。不可变性使得String对象在多线程环境下是线程安全的,并且在字符串常量池的实现中起到关键作用。

2. String s = new String(“xyz”);创建了几个String Object? 二者之间有什么区别?

创建了一个或两个String对象。如果字符串常量池中已经存在"xyz",则只在堆中创建一个String对象;如果常量池中不存在"xyz",则先在常量池中创建一个"xyz"对象,再在堆中创建一个String对象。常量池中的对象是共享的,而堆中的对象是独立的。

3. String 和StringBuffer的区别

  • 可变性String是不可变的,一旦创建,其值不能被改变。每次对String进行修改操作时,都会创建一个新的String对象。而StringBuffer是可变的,可以通过appendinsert等方法对其内容进行修改。
  • 线程安全性StringBuffer是线程安全的,因为它的方法大多使用synchronized关键字修饰。而String由于是不可变的,天然就是线程安全的。
  • 性能:在单线程环境下,由于String的不可变性,频繁修改会产生大量临时对象,性能较差。而StringBuffer的性能相对较好。但在多线程环境下,由于StringBuffer的同步机制,会有一定的性能开销。

4. 如何把一段逗号分割的字符串转换成一个数组?

可以使用String类的split方法。示例代码如下:

String str = "apple,banana,orange";
String[] arr = str.split(",");
for (String s : arr) {System.out.println(s);
}

split方法根据指定的分隔符将字符串分割成一个字符串数组。

5. 数组有没有length()这个方法? String有没有length()这个方法?

数组没有length()方法,数组有一个length属性,用于获取数组的长度。而Stringlength()方法,用于获取字符串的长度。示例代码如下:

int[] arr = {1, 2, 3};
System.out.println(arr.length); String str = "hello";
System.out.println(str.length()); 

6. 下面这条语句一共创建了多少个对象? String s=“a”+“b”+“c”+“d”;

在编译期,Java编译器会对字符串常量的拼接进行优化,将其合并为一个字符串常量。所以这条语句只会在字符串常量池中创建一个"abcd"对象。

7. try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

finally块里的代码会被执行。在try块中的return语句执行前,finally块中的代码会先执行。但需要注意的是,finally块中的代码不会影响try块中return语句的返回值(除了一些特殊情况,如在finally块中也有return语句)。示例代码如下:

public class FinallyExample {public static int test() {try {return 1;} finally {System.out.println("Finally block executed");}}public static void main(String[] args) {System.out.println(test());}
}

8. 下面的程序代码输出的结果是多少?

由于没有给出具体的程序代码,这里无法给出具体结果。但在分析代码输出结果时,需要考虑变量的初始化、方法的调用、控制流语句(如ifforwhile等)以及异常处理等因素。

9. final, finally, finalize的区别。

  • final:是一个关键字,用于修饰类、方法和变量。修饰类时,类不能被继承;修饰方法时,方法不能被重写;修饰变量时,变量成为常量,一旦赋值就不能再改变。
  • finally:是try-catch异常处理机制的一部分,无论try块中是否发生异常,finally块中的代码都会被执行。常用于释放资源,如关闭文件、数据库连接等。
  • finalize:是Object类的一个方法,用于在对象被垃圾回收之前执行一些清理工作。但由于垃圾回收的不确定性,不建议依赖finalize方法进行资源清理。

10. 运行时异常与一般异常有何异同?

  • 相同点:都是Throwable的子类,都表示程序运行过程中出现的异常情况。
  • 不同点:运行时异常(RuntimeException及其子类)是可以不被捕获或声明抛出的异常,通常是由程序逻辑错误引起的,如NullPointerExceptionArrayIndexOutOfBoundsException等。而一般异常(受检查异常)必须被捕获或在方法签名中声明抛出,如IOExceptionSQLException等。

11. error和exception有什么区别?

  • error:表示系统级的错误,是程序无法处理的严重问题,如OutOfMemoryErrorStackOverflowError等。这些错误通常是由系统资源耗尽、硬件故障等原因引起的,程序一般无法通过代码来解决这些问题。
  • exception:表示程序可以处理的异常情况,分为运行时异常和受检查异常。程序可以通过try-catch语句捕获并处理异常,或者在方法签名中声明抛出异常。

12. Java中的异常处理机制的简单原理和应用。

Java的异常处理机制基于try-catch-finally语句和throws关键字。当程序执行过程中发生异常时,会创建一个异常对象,并将控制权转移到最近的异常处理代码块。try块中包含可能抛出异常的代码,catch块用于捕获并处理特定类型的异常,finally块中的代码无论是否发生异常都会被执行。throws关键字用于在方法签名中声明该方法可能抛出的异常。示例代码如下:

public class ExceptionExample {public static void main(String[] args) {try {int result = 1 / 0;} catch (ArithmeticException e) {System.out.println("Division by zero error: " + e.getMessage());} finally {System.out.println("Finally block executed");}}
}

13. 请写出你最常见到的5个runtime exception。

  • NullPointerException:当试图访问一个null对象的方法或属性时抛出。
  • ArrayIndexOutOfBoundsException:当访问数组时,使用的索引超出了数组的有效范围。
  • ArithmeticException:当进行算术运算时出现错误,如除以零。
  • ClassCastException:当试图将一个对象强制转换为不兼容的类型时抛出。
  • IllegalArgumentException:当传递给方法的参数不合法时抛出。

14. java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?

  • 实现线程的方法
    • 继承Thread类,重写run方法。
    • 实现Runnable接口,实现run方法,并将其传递给Thread类的构造函数。
    • 实现Callable接口,实现call方法,并通过FutureTaskThread类来启动线程。
  • 同步方法:使用synchronized关键字修饰同步方法,确保同一时间只有一个线程可以访问该方法。
  • 不推荐使用stop()suspend()方法的原因stop()方法会立即终止线程,可能导致线程持有的资源无法正确释放,造成数据不一致等问题。suspend()方法会暂停线程,但不会释放线程持有的锁,可能导致死锁。

15. sleep() 和 wait() 有什么区别?

  • 所属类sleep()Thread类的静态方法,wait()Object类的实例方法。
  • 作用sleep()用于暂停当前线程的执行,让出CPU资源,但不会释放对象的锁。wait()用于线程间的协作,调用该方法的线程会释放对象的锁,并进入等待状态,直到其他线程调用该对象的notify()notifyAll()方法唤醒它。
  • 使用场景sleep()常用于模拟延迟、定时任务等。wait()常用于生产者 - 消费者模型等线程间的同步场景。

16. 同步和异步有何异同,在什么情况下分别使用他们?举例说明。

  • 相同点:都是用于处理多个任务的执行方式。
  • 不同点:同步是指在执行一个任务时,必须等待该任务完成后才能继续执行下一个任务。而异步是指在执行一个任务时,不需要等待该任务完成,可以继续执行其他任务,当任务完成后会通过回调等方式通知调用者。
  • 使用场景:同步适用于对数据一致性要求较高的场景,如银行转账操作。异步适用于处理耗时较长的任务,如文件下载、网络请求等,可以提高系统的并发性能。示例代码如下:
// 同步示例
public class SynchronousExample {public static void main(String[] args) {long startTime = System.currentTimeMillis();task1();task2();long endTime = System.currentTimeMillis();System.out.println("Total time: " + (endTime - startTime) + " ms");}public static void task1() {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task 1 completed");}public static void task2() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task 2 completed");}
}// 异步示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class AsynchronousExample {public static void main(String[] args) {long startTime = System.currentTimeMillis();ExecutorService executor = Executors.newFixedThreadPool(2);executor.submit(() -> task1());executor.submit(() -> task2());executor.shutdown();while (!executor.isTerminated()) {// 等待所有任务完成}long endTime = System.currentTimeMillis();System.out.println("Total time: " + (endTime - startTime) + " ms");}public static void task1() {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task 1 completed");}public static void task2() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task 2 completed");}
}

17. 多线程有几种实现方法?同步有几种实现方法?

  • 多线程实现方法:继承Thread类、实现Runnable接口、实现Callable接口。
  • 同步实现方法
    • 使用synchronized关键字修饰方法或代码块。
    • 使用ReentrantLock类。
    • 使用SemaphoreCountDownLatch等并发工具类。

18. 启动一个线程是用run()还是start()?

启动一个线程应该使用start()方法。start()方法会启动一个新的线程,并调用线程的run()方法。而直接调用run()方法只是在当前线程中执行run()方法的代码,不会启动新的线程。示例代码如下:

public class ThreadStartExample {public static void main(String[] args) {Thread thread = new Thread(() -> {System.out.println("Thread is running");});// 正确启动线程thread.start(); // 错误,不会启动新线程// thread.run(); }
}

19. 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

这取决于其他方法是否也是同步方法以及是否使用了相同的锁。如果其他方法不是同步方法,那么其他线程可以进入该方法。如果其他方法也是同步方法,并且使用了相同的锁(即同一个对象的锁),那么其他线程必须等待当前线程释放锁后才能进入该方法。示例代码如下:

public class SynchronizedMethodExample {public synchronized void method1() {System.out.println("Method 1 is running");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Method 1 completed");}public synchronized void method2() {System.out.println("Method 2 is running");}public void method3() {System.out.println("Method 3 is running");}public static void main(String[] args) {SynchronizedMethodExample example = new SynchronizedMethodExample();Thread t1 = new Thread(() -> example.method1());Thread t2 = new Thread(() -> example.method2());Thread t3 = new Thread(() -> example.method3());t1.start();try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}t2.start();t3.start();}
}

20. 线程的基本概念、线程的基本状态以及状态之间的关系。

  • 线程的基本概念:线程是程序执行的最小单位,是进程中的一个执行单元。一个进程可以包含多个线程,这些线程共享进程的资源。
  • 线程的基本状态
    • 新建状态(New):当创建一个Thread对象时,线程处于新建状态。
    • 就绪状态(Runnable):调用start()方法后,线程进入就绪状态,等待CPU调度。
    • 运行状态(Running):当CPU调度该线程时,线程进入运行状态。
    • 阻塞状态(Blocked):线程在等待某个资源或锁时,进入阻塞状态。
    • 等待状态(Waiting):调用wait()join()等方法后,线程进入等待状态,需要其他线程唤醒。
    • 超时等待状态(Timed Waiting):调用sleep()wait(long timeout)等方法后,线程进入超时等待状态,在指定时间后自动唤醒。
    • 终止状态(Terminated):线程执行完run()方法或因异常终止后,进入终止状态。
  • 状态之间的关系:新建状态的线程调用start()方法后进入就绪状态,就绪状态的线程获得CPU调度后进入运行状态。运行状态的线程可能因为等待资源、调用wait()等方法进入阻塞、等待或超时等待状态,当条件满足时,线程可以从这些状态转换回就绪状态。线程执行完任务或出现异常后进入终止状态。
http://www.dtcms.com/a/273776.html

相关文章:

  • Windows下的redis
  • 小木的机器学习日记——KNN
  • lua中检查静态常量是否正确引用
  • 每天一个前端小知识 Day 28 - Web Workers / 多线程模型在前端中的应用实践
  • 【web应用】若依框架前端报表制作与导出全攻略(ECharts + html2canvas + jsPDF)
  • 界面组件DevExpress WPF中文教程:Grid - 如何检查节点?
  • Windows 应用程序的 UI 框架:WPF、WinUI 3 和 UWP的差异区别
  • VMware安装Centos 7
  • pandas销售数据分析
  • 十年架构心路:从单机到云原生的分布式系统演进史
  • 七牛云运维面试题及参考答案
  • MySQL 的语言体系
  • 【InnoDB存储引擎4】行结构
  • 报错 | “pnpm : 无法将“pnpm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,
  • day17 力扣654.最大二叉树 力扣617.合并二叉树 力扣700.二叉搜索树中的搜索 力扣98.验证二叉搜索树
  • 数据库迁移人大金仓数据库
  • 多表查询-2-多表查询概述
  • 黑马点评系列问题之P55优惠券秒杀 快捷键问题 Ctrl+D显示不出来老师给的界面
  • 第八章 STM32之IAP编程
  • mysql数据库导入导出命令
  • ARM架构CPU的市场和生态
  • 欢乐熊大话蓝牙知识26:想让设备秒连?Connection Interval 配得对吗?
  • 零碳园区:安科瑞EMS如何破解新能源消纳难与高耗能产业转型困局
  • 锁的艺术:从Mutex到ReentrantLock,掌握并发编程的脉搏
  • 大模型使用
  • Qt 实现新手引导
  • Windows解决 ping 127.0.0.1 一般故障问题
  • unity 有打击感的图片,怎么做动画,可以表现出良好的打击效果
  • STM32串口通信(寄存器与hal库实现)
  • 2025年7月11日学习笔记一周归纳——模式识别与机器学习