Java面试题及答案总结(精选版)
一、Java基础
-
Java平台无关性如何实现?
Java源码编译为字节码(.class
文件),JVM在不同操作系统上解释执行字节码。
关键公式:$$ \text{跨平台性} = \text{JVM} + \text{字节码} $$ -
final
关键字的用法- 修饰类:不可继承
- 修饰方法:不可重写
- 修饰变量:常量(基本类型值不变,引用类型地址不变)
-
重载(Overload)与重写(Override)的区别
// 重载示例:同一类中方法名相同,参数不同 void print(int a) {} void print(String s) {} // 重写示例:子类覆盖父类方法 class Parent { void show() {} } class Child extends Parent { @Override void show() {} }
二、面向对象编程
-
封装、继承、多态的理解
- 封装:隐藏实现细节(如
private
字段 +public
方法) - 继承:
extends
实现代码复用 - 多态:父类引用指向子类对象(
Animal a = new Dog();
)
- 封装:隐藏实现细节(如
-
接口 vs 抽象类
特性 接口 抽象类 方法实现 Java 8+ 支持 default
方法可包含实现方法 构造器 无 有 多继承 支持多实现( implements A,B
)单继承
三、集合框架
-
HashMap
工作原理- 结构:数组 + 链表/红黑树(JDK8+)
- 哈希冲突:
hash(key)
计算桶位置,链表解决冲突 - 扩容:负载因子$0.75$,扩容时重建桶数组
-
ArrayList
vsLinkedList
操作 ArrayList
LinkedList
随机访问 $O(1)$ $O(n)$ 头部插入 $O(n)$ $O(1)$ 内存占用 数组连续空间 节点指针额外开销
四、多线程与并发
-
创建线程的三种方式
// 1. 继承Thread类 class MyThread extends Thread { public void run() {} } // 2. 实现Runnable接口 Runnable task = () -> System.out.println("Run"); new Thread(task).start(); // 3. 实现Callable接口(带返回值) FutureTask<String> future = new FutureTask<>(() -> "Result"); new Thread(future).start();
-
synchronized
和ReentrantLock
区别特性 synchronized
ReentrantLock
锁获取 自动获取/释放 需手动 lock()
/unlock()
公平锁 非公平 可配置公平性 条件变量 wait()
/notify()
Condition
API
五、JVM内存模型
-
运行时数据区
- 堆:对象实例(GC主区域)
- 栈:线程私有,存储局部变量表
- 方法区:类信息、常量池(JDK8+为元空间)
- 程序计数器:当前线程执行位置
-
GC算法
- 标记-清除:产生内存碎片
- 复制算法:空间分为两块(新生代使用)
- 标记-整理:老年代常用,避免碎片
GC性能指标:$$ \text{吞吐量} = \frac{\text{用户代码时间}}{\text{总执行时间}} $$
六、Spring框架
-
IoC(控制反转)原理
- 容器管理Bean生命周期
- 依赖注入方式:构造器注入、Setter注入、注解注入
@Service public class UserService { @Autowired // 自动注入 private UserDao userDao; }
-
AOP应用场景
- 日志记录:
@Before
/@After
- 事务管理:
@Transactional
- 性能监控:统计方法执行时间
- 日志记录:
七、数据库与JDBC
-
事务ACID特性
- 原子性(Atomicity):事务全部成功或全部失败
- 隔离性(Isolation):并发事务互不干扰
- 持久性(Durability):提交后数据永久保存
-
PreparedStatement
vsStatement
// Statement:易引发SQL注入 Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM users WHERE id=" + input); // PreparedStatement:预编译防注入 PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id=?"); ps.setInt(1, input); // 安全参数绑定
高频算法题(附代码)
-
反转链表
public ListNode reverseList(ListNode head) { ListNode prev = null; while (head != null) { ListNode next = head.next; head.next = prev; prev = head; head = next; } return prev; }
-
二分查找
int binarySearch(int[] nums, int target) { int left = 0, right = nums.length - 1; while (left <= right) { int mid = left + (right - left) / 2; // 防溢出 if (nums[mid] == target) return mid; else if (nums[mid] < target) left = mid + 1; else right = mid - 1; } return -1; }
总结:本文涵盖Java核心知识点约3000字(实际面试需结合项目深化),建议重点掌握:
- JVM内存模型与GC机制
- 并发编程工具(
ThreadPoolExecutor
/ConcurrentHashMap
)- Spring设计思想(IoC/AOP)
- 数据库优化(索引/事务隔离级别)
Java面试题扩展:分布式(ZooKeeper)、缓存(Redis)、网络(TCP/UDP)专题
在Java面试中,分布式系统、缓存技术和网络协议是常见的高级主题。我将分步解析每个专题,涵盖核心概念、常见问题和代码示例,确保内容真实可靠。所有内容基于标准Java生态系统知识。
1. 分布式系统:ZooKeeper
ZooKeeper是一个分布式协调服务,用于管理配置信息、实现分布式锁和领导者选举。它基于ZAB协议(ZooKeeper Atomic Broadcast)保证数据一致性。
常见面试题:
- ZooKeeper的工作原理是什么?(例如,通过树形结构znode存储数据)
- 如何用ZooKeeper实现分布式锁?
- ZooKeeper的CAP理论中,它偏向于哪两个属性?(一致性C和分区容忍性P)
代码示例:Java中使用ZooKeeper客户端 以下是一个简单示例,展示如何连接到ZooKeeper服务器并创建节点:
import org.apache.zookeeper.*;
public class ZKExample {
private static final String ZK_ADDRESS = "localhost:2181";
private static final int SESSION_TIMEOUT = 3000;
public static void main(String[] args) throws Exception {
ZooKeeper zk = new ZooKeeper(ZK_ADDRESS, SESSION_TIMEOUT, new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println("Event: " + event.getType());
}
});
// 创建持久节点
String path = zk.create("/testNode", "data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("Created node: " + path);
zk.close();
}
}
解释:
- 使用
ZooKeeper
类连接服务器,设置会话超时。 create
方法创建节点,参数包括路径、数据、权限和模式(如持久节点)。- 注意:实际应用中需处理异常和重连逻辑。
2. 缓存技术:Redis
Redis是一个高性能的内存数据库,支持多种数据结构(如字符串、哈希、列表)。常用于缓存、会话管理和消息队列。
常见面试题:
- Redis的数据类型有哪些?各适用什么场景?(例如,哈希适合存储对象)
- Redis的持久化机制(RDB和AOF)如何工作?
- 如何解决Redis缓存雪崩问题?(例如,设置过期时间随机化)
代码示例:Java中使用Jedis操作Redis 以下示例展示连接Redis并进行基本操作:
import redis.clients.jedis.Jedis;
public class RedisExample {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
// 设置键值对
jedis.set("key", "value");
System.out.println("Get value: " + jedis.get("key"));
// 使用哈希类型
jedis.hset("user:1", "name", "Alice");
System.out.println("User name: " + jedis.hget("user:1", "name"));
jedis.close();
}
}
解释:
Jedis
是Redis的Java客户端,连接本地服务器。set
和get
操作字符串值;hset
和hget
操作哈希结构。- 时间复杂度:例如,
set
操作是$O(1)$,表示常数时间。
3. 网络协议:TCP/UDP
TCP和UDP是传输层协议,TCP提供可靠连接(如文件传输),UDP提供快速无连接通信(如视频流)。在Java中,通过Socket
和DatagramSocket
实现。
常见面试题:
- TCP三次握手过程是什么?(SYN, SYN-ACK, ACK)
- UDP vs TCP的主要区别?(例如,TCP有流量控制,UDP无)
- 如何用Java实现简单的TCP服务器和客户端?
代码示例:Java中使用TCP和UDP
-
TCP示例:简单服务器和客户端
// TCP服务器端 import java.io.*; import java.net.*; public class TCPServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8080); Socket clientSocket = serverSocket.accept(); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); out.println("Hello from TCP server"); clientSocket.close(); serverSocket.close(); } } // TCP客户端 import java.io.*; import java.net.*; public class TCPClient { public static void main(String[] args) throws IOException { Socket socket = new Socket("localhost", 8080); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println("Server response: " + in.readLine()); socket.close(); } }
-
UDP示例:简单发送和接收
// UDP发送端 import java.net.*; public class UDPSender { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(); byte[] buffer = "Hello from UDP".getBytes(); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("localhost"), 9090); socket.send(packet); socket.close(); } } // UDP接收端 import java.net.*; public class UDPReceiver { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(9090); byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); System.out.println("Received: " + new String(packet.getData(), 0, packet.getLength())); socket.close(); } }
解释:
- TCP使用
ServerSocket
和Socket
,确保可靠传输。 - UDP使用
DatagramSocket
和DatagramPacket
,无连接,速度快。 - 网络延迟模型:例如,TCP的吞吐量受带宽$B$和往返时间$RTT$影响,近似为$\frac{B}{RTT}$。
总结
这些专题覆盖了Java面试中常见的高级主题:
- ZooKeeper用于分布式协调,重点在一致性和锁实现。
- Redis优化缓存性能,掌握数据结构和持久化。
- TCP/UDP是网络基础,理解协议差异和Java实现。 建议通过实际项目练习,如使用Spring Boot整合Redis或ZooKeeper。有问题可进一步讨论!