【Java面试题】第五期:Java进阶篇,每周10道,根本停不下来~ 您所在的位置:网站首页 java的object方法有哪些 【Java面试题】第五期:Java进阶篇,每周10道,根本停不下来~

【Java面试题】第五期:Java进阶篇,每周10道,根本停不下来~

#【Java面试题】第五期:Java进阶篇,每周10道,根本停不下来~| 来源: 网络整理| 查看: 265

每周10道Java面试题~第五期 :one: Object类中常用的方法?:two: Java 中 IO 流分为几种?BIO、NIO、AIO有什么区别?:three: 对面向对象的理解?面向对象语言的三大特征?:four: 多线程创建的各种方式?:five: 进程和线程的区别?:six: 并行和并发的区别?:seven: 守护线程是什么?:eight: 线程有哪些状态?:nine: notify()和 notifyAll()有什么区别?:keycap_ten: sleep()和 wait()的区别?

1️⃣ Object类中常用的方法?

Object类是所有Java类的父类,它包含了一些常用的方法,其中一些如下:

boolean equals(Object obj):比较两个对象是否相等,返回布尔值;int hashCode():返回对象的哈希码hashCode;String toString():返回对象的字符串表示;Class getClass():返回对象的类;wait():让线程等待;notify():唤醒一个正在等待的线程;notifyAll():唤醒所有正在等待的线程;finalize():在垃圾回收器回收对象之前调用。 2️⃣ Java 中 IO 流分为几种?BIO、NIO、AIO有什么区别?

在Java中,IO流主要分为两类:字节流和字符流。每一类流都有输入流和输出流。

字节流:以字节为单位进行读写,常见的类有InputStream和OutputStream;字符流:以字符为单位进行读写,常见的类有Reader和Writer。

在字节流和字符流之间,可以通过InputStreamReader和OutputStreamWriter进行转换,将字节流转换为字符流,或者将字符流转换为字节流。这样可以在不同类型的IO流之间进行转换,方便进行数据读写操作。

BIO、NIO、AIO都是Java中的IO编程模型,它们之间的主要区别在于IO的实现方式、使用场景、性能等方面。

BIO(Blocking IO):同步阻塞 IO,即传统的 IO模型,属于一问一答式的通信方式。在这种模型中,一个客户端连接对应一个线程,当连接没有数据可读取时,线程会一直阻塞在那里,直到有数据可读取。BIO适合连接数目比较小的情况。

NIO(New IO):同步非阻塞 IO,属于一问多答式的通信方式。NIO采用了多路复用的机制,一个线程可以同时处理多个客户端连接,提高了IO的效率。但是,NIO编程模型相对BIO更加复杂,需要了解选择器等一些新的概念。

AIO(Asynchronous IO):异步非阻塞IO,也叫做NIO 2.0。AIO是一种完全不同的IO操作方式,它的读写操作都是异步的,不会阻塞线程。AIO适用于连接数目较多且连接时间较长的应用,比如聊天服务器、网络游戏、高性能Web服务器等。

总之,BIO适用于连接数目比较小的情况,NIO适用于连接数目比较多且连接时间较短的情况,而AIO则适用于连接数目比较多且连接时间较长的情况。

3️⃣ 对面向对象的理解?面向对象语言的三大特征?

面向对象是一种编程思想,强调将程序中的数据和操作数据的方法绑定在一起,以实现信息隐藏、封装和抽象化的编程模式。在面向对象编程中,数据和方法被封装到一个称为“对象”的实体中,并且对象之间可以相互通信和协作。

面向对象的编程语言中,一个对象通常包含一些属性和方法。属性是对象的数据成员,用于描述对象的状态;方法是对象的操作成员,用于描述对象的行为。通过定义对象的属性和方法,可以实现对对象的封装和抽象化,使得对象的内部实现细节对外部不可见,只暴露出一些公共接口供其他对象使用。

面向对象的编程思想强调代码的可重用性、可扩展性和可维护性,可以提高代码的开发效率和质量,因此被广泛应用于软件开发领域。

面向对象语言的三大特征:

封装:隐藏对象的属性和实现细节,仅对外开放接口,控制程序中属性读和修改的访问级别,将对象和操作封装成一个抽象的类,形成一个整体。目的:增强安全性、简化编程;继承:子类继承父类的特征和行为,即可以使用现有类的特征和功能,但无需重新编写原来类的情况下进行功能的扩展。Java中类之间的继承是单继承、多级继承;多态:多态的实现方式有重写和重载。重写就是子类重新定义父类中的方法;重载则是允许存在多个名字相同的方法,但这些方法参数列表不同。多态是在继承的基础上进行。 4️⃣ 多线程创建的各种方式? 自定义一个类,继承 java.lang包下的 Thread类并重写 run()方法,将要执行的代码写在 run()里面。使用时创建自定义类的对象,调用 start()方法启动线程;自定义一个类,实现 java.lang包下的 Runnable接口并重写 run()方法,将要执行的代码写在 run()里面。使用时创建自定义类的对象,再将该对象作为参数传入 Thread类构造方法中,调用 start()启动线程;自定义一个类,实现 java.util.concurrent包下的 Callable接口并重写 call()方法,将要执行的代码写在 call()中,可获取线程返回结果;使用 Executor框架中的内置线程池,或者通过ThreadPoolExecutor自定义线程池。

以上这些方法都可以用于创建多线程,但在实际开发中,一般使用 Runnable接口或者 Callable接口来创建多线程,因为这两种方式可以更好地实现线程之间的数据共享。而使用线程池则可以更好地管理线程,并且可以避免创建过多的线程造成系统资源的浪费。

5️⃣ 进程和线程的区别?

进程:并发执行的程序在执行过程中,分配和管理资源的基本单位,是竞争计算机系统资源的基本单位。 线程:是进程的一个执行单元,负责当前进程中程序的执行,线程也是CPU调度的基本单元。一个进程至少有一个线程,也可以拥有多个线程,多个线程间可以共享数据。

二者的区别:

地址空间:同一进程之间的线程共享地址空间,不同进程之间的线程则是独立的地址空间;共享资源:同一进程之间的线程共享资源,不同进程之间的资源则是独立的;一个进程崩溃不会影响到其他的进程,但是一个线程崩溃会导致整个进程崩溃,所以多进程比多线程健壮。 6️⃣ 并行和并发的区别?

并行和并发都是多任务处理的概念,但是它们的实现方式和效果不同。

并行指的是同时执行多个任务,通常需要多个处理器或者多核处理器来实现。例如,一个有4个核心的CPU可以同时执行4个任务,这些任务之间是真正的同时执行。

而 并发指的是在同一时间段内执行多个任务,通常是通过任务切换技术来实现的。例如,在一个单核处理器上,可以通过轮流执行多个任务的方式来实现并发。

因此,虽然并行和并发都可以实现多任务处理,但是并行更强调同时执行,而并发更强调任务之间的交替执行。

7️⃣ 守护线程是什么?

守护线程(Daemon Thread)是一种特殊的线程,它的优先级很低,并且主要被用来在后台提供一些服务,比如垃圾回收、内存管理 等。它们的生命周期与主线程不同,当所有非守护线程都执行完毕时,守护线程会自动退出。

守护线程通常用于一些不需要等待的任务,比如日志记录或后台监测等,这些任务不会影响程序的主要流程,但是如果没有守护线程,程序就需要等待它们执行完毕才能退出,这会影响程序的性能和用户体验。因此,守护线程可以提高程序的灵活性和稳定性。

在Java中,可以通过Thread类的setDaemon()方法来设置线程是否为守护线程,方法的语法如下:

public final void setDaemon(boolean on);

其中,on参数为true表示将线程设置为守护线程,为false则表示将线程设置为用户线程(非守护线程)。 需要注意的是,setDaemon()方法必须在start()方法之前调用,否则会抛出IllegalThreadStateException异常。

🍍 下面是一个设置守护线程的示例代码:

package net.xiaoshan; public class DaemonThreadExample { public static void main(String[] args) { Thread daemonThread = new Thread(() -> { while (true) { System.out.println("Daemon thread is running."); } }); daemonThread.setDaemon(true); // 设置为守护线程 daemonThread.start(); System.out.println("Main thread exits."); } }

结果: 在这里插入图片描述 说明: 在上面的代码中,我创建了一个线程daemonThread ,并通过setDaemon()方法将其设置为守护线程。 然后,启动线程并打印一条字符串信息,最后,主线程退出。由于守护线程的优先级比较低,因此在主线程退出后,守护线程也会随之退出。

8️⃣ 线程有哪些状态?

线程有以下几种状态:

新建状态(New):当线程对象被创建时,它处于新建状态。此时它还没有被执行,只是一个空的线程对象;就绪状态(Runnable):当线程处于就绪状态时,表示它已经准备好了运行,但是并没有获得 CPU 时间片。此时线程会进入就绪队列等待系统为它分配 CPU 时间;运行状态(Running):当线程获得了 CPU 时间片,它就会进入运行状态,开始执行线程体中的代码;阻塞状态(Blocked):当线程遇到某些情况时,比如等待某个输入输出操作完成、等待某个锁的释放等,它就会进入阻塞状态。在这种状态下,线程不会占用 CPU 时间,也不会进入就绪队列;销毁状态(Dead):当线程的 run() 方法执行完毕后,线程就会进入销毁状态。

线程状态之间的转换过程如下:

新建状态(New)-> 就绪状态(Runnable):当线程对象被创建时,它处于新建状态,当调用 start() 方法后就会进入就绪状态;就绪状态(Runnable)-> 运行状态(Running):当线程被系统调度执行时,就会进入运行状态;运行状态(Running)-> 阻塞状态(Blocked):当调用sleep()、suspend()、wait()等方法,线程都将进入阻塞状态。注意:阻塞时并不能进入排队队列,只有当引起阻塞的原因被消除后,线程才会转入就绪状态并重新排队等待;阻塞状态(Blocked)-> 就绪状态(Runnable):当等待的操作完成后,它就会回到就绪状态,等待系统为它分配 CPU 时间;运行状态(Running)-> 销毁状态(Dead):当线程的 run() 方法执行完毕,或者调用stop()方法,或者调用destory()方法后,线程处于销毁状态。

获取线程当前状态的方法:getState()。

9️⃣ notify()和 notifyAll()有什么区别?

notify()和notifyAll()都是Java中Object类的方法,用于在多线程环境下实现线程之间的通信。

notify()方法用于唤醒等待该对象锁的一个线程,如果有多个线程等待该对象锁,则只会唤醒其中一个线程;notifyAll()方法则会唤醒等待该对象锁的所有线程,让它们重新竞争该对象锁。

需要注意的是,notify()和 notifyAll()方法必须在同步块或同步方法中调用,否则会抛出IllegalMonitorStateException异常。另外,调用notify()和 notifyAll()方法并不会立即释放锁,而是在同步块或同步方法执行完后才会释放锁。 notify()可能导致死锁,notifyAll()不会。

🔟 sleep()和 wait()的区别?

sleep()和 wait()是两个不同的函数,sleep()函数是用于线程休眠,而wait()函数是用于线程等待通知。

sleep() 是线程类 Thread 的方法,作用是让当前线程休眠一段时间,单位是毫秒。在休眠期间,线程不会执行任何操作,直到休眠时间结束才会继续执行。会主动释放CPU,但监控依然保持,不会释放对象锁;wait() 是Object类的方法,作用是让当前线程等待另一个线程的唤醒通知。它会释放对象锁,进入等待队列,直到另一个线程调用 notify() / notifyAll() 才会被唤醒。

在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有