Java面试黄金宝典40
1. 进程线程区别
- 定义:
- 进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。每个进程都有独立的地址空间、内存、数据栈等资源。
- 线程是进程中的一个执行单元,是 CPU 调度和分派的基本单位。线程共享所属进程的资源,如地址空间、打开的文件等,但有自己独立的栈空间和程序计数器。
- 要点:
- 资源分配:进程有独立资源,线程共享进程资源。
- 调度:进程调度开销大,线程调度开销小。
- 并发性:进程之间相互独立,线程之间可以并发执行,且同一进程内的线程切换效率更高。
- 应用:在 Java 中,多线程编程常用于提高程序的并发性能,例如 Web 服务器中,每个请求可以分配到一个线程来处理,以提高服务器的响应能力。而进程间通信相对复杂,常用于不同应用程序之间的交互。
- 代码示例:以下是一个简单的 Java 多线程示例,创建两个线程并启动,它们共享同一个 Runnable 对象的资源。
java
public class ThreadExample {
public static void main(String[] args) {
Runnable runnable = new MyRunnable();
Thread thread1 = new Thread(runnable);
Thread thread2 = new Thread(runnable);
thread1.start();
thread2.start();
}
}
class MyRunnable implements Runnable {
private int count = 0;
@Override
public void run() {
for (int i = 0; i < 5; i++) {
count++;
System.out.println(Thread.currentThread().getName() + " count: " + count);
}
}
}
2. 进程通信方式
- 定义:进程通信是指在不同进程之间进行数据交换和信息传递的机制。
- 要点:
- 管道:具有亲缘关系的进程间通信方式,半双工,数据只能单向流动。
- 消息队列:进程间通过发送和接收消息来进行通信,消息具有类型,可按类型接收。
- 共享内存:多个进程共享同一块内存区域,实现数据的快速交换,但需要同步机制来保证数据的一致性。
- 信号量:用于控制多个进程对共享资源的访问,通过 P、V 操作实现进程的同步和互斥。
- 套接字:可用于不同主机间的进程通信,是网络编程中常用的通信方式。
- 应用:在分布式系统中,进程通信方式常用于不同节点之间的信息交互。例如,通过套接字实现服务器与客户端之间的通信;在并发程序中,使用信号量来控制多个进程对共享资源的访问。
- 代码示例:以下是一个使用 Java 套接字进行进程通信的简单示例,实现了一个服务器端和一个客户端的通信。
java
// 服务器端
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hello from server!");
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 客户端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8888);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = in.readLine();
System.out.println("Received from server: " + message);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 僵尸进程
- 定义:当子进程完成任务终止运行后,父进程没有及时调用
wait
或waitpid
系统调用获取子进程的终止状态信息,子进程就会变成僵尸进程。僵尸进程虽然已经停止运行,但仍会在系统中保留一些资源,如进程控制块(PCB)。 - 要点:
- 产生原因:父进程未回收子进程资源。
- 危害:占用系统资源,如果大量产生,可能会耗尽系统的进程资源,影响系统性能。
- 应用:在实际开发中,需要注意避免产生僵尸进程,特别是在多进程编程中,要确保父进程及时回收子进程的资源。
- 代码示例:以下是一个可能产生僵尸进程的 Java 代码示例(通过调用系统命令创建子进程),在实际中可以通过
Process.waitFor
方法来等待子进程结束并回收资源