Skip to content

面试题

TCP/IP协议、TCP和UDP的区别


1. TCP/IP协议族

TCP/IP是一组网络通信协议的集合,定义了互联网的数据传输标准。它分为四层(或五层)模型:

  • 应用层(HTTP、FTP、DNS等)
  • 传输层(TCP、UDP)
  • 网络层(IP、ICMP)
  • 网络接口层(以太网、Wi-Fi等)

作用:提供端到端的数据传输,涵盖寻址(IP)、可靠性(TCP)、效率(UDP)等。


2. TCP vs UDP

二者均属于传输层协议,但设计目标不同:

特性TCP(传输控制协议)UDP(用户数据报协议)
连接方式面向连接(三次握手)无连接
可靠性可靠(确认、重传、排序)不可靠(尽最大努力交付)
数据顺序保证数据顺序不保证顺序
速度/开销慢(头部大,控制机制复杂)快(头部小,无控制机制)
流量控制有(滑动窗口)
拥塞控制有(慢启动、拥塞避免等)
适用场景网页(HTTP)、邮件(SMTP)、文件传输(FTP)视频流、语音通话(VoIP)、DNS查询、游戏

3. 关键区别总结

  • 可靠性需求:TCP适合需要数据完整性的场景(如文件下载),UDP适合容忍丢包但追求低延迟的场景(如直播)。
  • 连接管理:TCP需建立连接,UDP直接发送数据。
  • 头部大小:TCP头部至少20字节,UDP仅8字节。

4. 为什么需要UDP?

尽管TCP可靠,但其复杂机制会引入延迟。UDP通过牺牲可靠性换取效率,适合实时性要求高的应用。例如:

  • DNS查询:快速响应比重传更重要。
  • 在线游戏:延迟比偶尔丢包更影响体验。

5. 协议选择建议

  • TCP:当数据必须完整到达(如银行交易)。
  • UDP:当速度优先,且应用层可处理丢包(如视频会议)。

理解这些差异有助于根据需求选择合适的传输协议。

TCP、UDP、HTTP、WebSocket 和 Socket 的区别


1. TCP 和 UDP(传输层协议)

TCP(传输控制协议)

  • 特点
    • 面向连接:通信前需三次握手建立连接(可靠)。
    • 可靠传输:数据确认、重传、排序、流量/拥塞控制。
    • 速度较慢:因额外控制机制,头部较大(至少20字节)。
  • 适用场景
    • 需要数据完整性的应用(如网页浏览、文件传输、电子邮件)。

UDP(用户数据报协议)

  • 特点
    • 无连接:直接发送数据,无需建立连接。
    • 不可靠:不保证数据到达、不排序、无重传机制。
    • 速度快:头部小(仅8字节),适合低延迟场景。
  • 适用场景
    • 实时性要求高的应用(如视频流、语音通话、在线游戏)。

对比

特性TCPUDP
连接方式面向连接无连接
可靠性可靠(确认+重传)不可靠
数据顺序保证顺序不保证顺序
速度
头部大小至少20字节8字节

2. HTTP(应用层协议)

  • 特点
    • 基于TCP:默认使用TCP端口80(HTTP)或443(HTTPS)。
    • 无状态:每次请求独立,服务器不记录客户端状态(依赖Cookie/Session)。
    • 短连接:传统HTTP/1.1每次请求需新建TCP连接(HTTP/1.1支持长连接,但本质仍是请求-响应模式)。
  • 适用场景
    • 网页浏览、API调用等单向请求-响应场景。

3. WebSocket(应用层协议)

  • 特点
    • 基于TCP:在HTTP协议升级后建立持久化连接(端口80/443)。
    • 全双工通信:服务器和客户端可主动双向实时推送数据
    • 有状态:连接建立后保持活跃,避免重复握手开销。
  • 适用场景
    • 实时聊天、股票行情、在线游戏等需要持续双向通信的场景。

HTTP vs WebSocket

特性HTTPWebSocket
通信模式请求-响应(单向)全双工(双向)
连接生命周期短连接(默认)长连接
协议基础基于TCP基于TCP(HTTP升级)
实时性低(需轮询)高(服务器可主动推送)

4. Socket(编程接口,非协议)

  • 特点
    • 操作系统提供的API:用于网络通信(如send(), recv())。
    • 支持TCP/UDP:开发者可通过Socket编程直接使用TCP或UDP。
    • 灵活但复杂:需手动处理连接、数据包等底层细节。
  • 适用场景
    • 需要自定义协议或底层控制的场景(如开发P2P应用、自定义实时通信协议)。

Socket 与 TCP/UDP 的关系

  • Socket是编程接口,TCP/UDP是传输层协议
  • 通过Socket可以调用TCP(SOCK_STREAM)或UDP(SOCK_DGRAM)。

5. 总结:关键区别与联系

名称层级特点典型应用场景
TCP传输层可靠、面向连接、速度慢网页、文件传输、电子邮件
UDP传输层不可靠、无连接、速度快视频流、游戏、DNS查询
HTTP应用层基于TCP、无状态、短连接网页浏览、REST API
WebSocket应用层基于TCP、全双工、长连接实时聊天、股票推送
Socket接口提供TCP/UDP的编程能力自定义网络应用开发

关系示意图

txt
Socket(API)

├── TCP → HTTP(单向请求-响应)
│        └── WebSocket(双向通信)

└── UDP → 实时音视频、游戏

如何选择?

  • 需要可靠传输:TCP + HTTP/WebSocket。
  • 需要低延迟:UDP(如QUIC协议已用于HTTP/3)。
  • 需要双向实时通信:WebSocket。
  • 需要完全自定义协议:Socket + TCP/UDP。

理解这些概念后,可以更精准地选择适合业务需求的网络技术。

Java I/O 操作详解

Java I/O (输入/输出) 是 Java 中处理数据输入和输出的核心 API。Java 提供了丰富的 I/O 类库,可以分为几个主要类别:

1. 基本 I/O 流分类

按数据流向

  • 输入流:从数据源读取数据 (InputStream/Reader)
  • 输出流:向目标写入数据 (OutputStream/Writer)

按数据类型

  • 字节流:以字节为单位 (InputStream/OutputStream)
  • 字符流:以字符为单位 (Reader/Writer)

按功能

  • 节点流:直接与数据源连接
  • 处理流:对节点流进行包装,提供额外功能

2. 核心 I/O 类

字节流

  • InputStream (抽象类)
    • FileInputStream (文件输入)
    • ByteArrayInputStream (字节数组输入)
    • ObjectInputStream (对象反序列化)
  • OutputStream (抽象类)
    • FileOutputStream (文件输出)
    • ByteArrayOutputStream (字节数组输出)
    • ObjectOutputStream (对象序列化)

字符流

  • Reader (抽象类)
    • FileReader (文件读取)
    • InputStreamReader (字节到字符转换)
    • BufferedReader (缓冲读取)
  • Writer (抽象类)
    • FileWriter (文件写入)
    • OutputStreamWriter (字符到字节转换)
    • BufferedWriter (缓冲写入)

3. 常用 I/O 操作示例

文件复制 (字节流)

java
try (InputStream in = new FileInputStream("source.txt");
     OutputStream out = new FileOutputStream("target.txt")) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = in.read(buffer)) != -1) {
        out.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
}

读取文本文件 (字符流)

java
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

写入文本文件 (字符流)

java

java
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
    writer.write("Hello, World!");
    writer.newLine();
    writer.write("This is a test.");
} catch (IOException e) {
    e.printStackTrace();
}

4. NIO (New I/O)

Java NIO 提供了更高效的 I/O 操作方式:

核心组件

  • Channel:双向数据传输通道
  • Buffer:数据容器
  • Selector:多路复用器

NIO 文件复制示例

java
try (FileChannel inChannel = new FileInputStream("source.txt").getChannel();
     FileChannel outChannel = new FileOutputStream("target.txt").getChannel()) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    while (inChannel.read(buffer) != -1) {
        buffer.flip();  // 切换为读模式
        outChannel.write(buffer);
        buffer.clear(); // 清空缓冲区
    }
} catch (IOException e) {
    e.printStackTrace();
}

5. Java 7 引入的 Files 类

Java 7 在 java.nio.file 包中引入了 Files 类,简化了文件操作:

java
// 读取所有行
List<String> lines = Files.readAllLines(Paths.get("file.txt"), StandardCharsets.UTF_8);

// 写入文件
Files.write(Paths.get("output.txt"), "Hello".getBytes());

// 复制文件
Files.copy(Paths.get("source.txt"), Paths.get("target.txt"));

// 移动/重命名文件
Files.move(Paths.get("old.txt"), Paths.get("new.txt"));

6. 最佳实践

  1. 始终关闭流 - 使用 try-with-resources 语句
  2. 对于大文件,使用缓冲流提高性能
  3. 考虑使用 NIO 处理高并发 I/O
  4. 注意字符编码问题 (推荐明确指定 UTF-8)
  5. 处理路径时使用 Paths.get()Path 接口

Java I/O 系统非常强大,选择适当的类和方法可以显著提高应用程序的性能和可靠性。

Java 多线程编程详解

Java 多线程是 Java 并发编程的核心部分,允许程序同时执行多个任务。以下是 Java 多线程的全面介绍:

1. 线程基础概念

线程与进程的区别

  • 进程:操作系统分配资源的基本单位,独立内存空间
  • 线程:进程内的执行单元,共享进程资源

Java 线程实现方式

  1. 继承 Thread 类
java
class MyThread extends Thread {
    public void run() {
        System.out.println("线程运行中");
    }
}

MyThread t = new MyThread();
t.start();
  1. 实现 Runnable 接口 (推荐)
java
class MyRunnable implements Runnable {
    public void run() {
        System.out.println("线程运行中");
    }
}

Thread t = new Thread(new MyRunnable());
t.start();
  1. 实现 Callable 接口 (可返回结果)
java
class MyCallable implements Callable<String> {
    public String call() throws Exception {
        return "任务完成";
    }
}

FutureTask<String> task = new FutureTask<>(new MyCallable());
Thread t = new Thread(task);
t.start();
System.out.println(task.get()); // 获取返回结果

Java 网络编程详解

Java 网络编程主要基于 TCP/IP 协议栈,提供了丰富的 API 来实现网络通信。以下是 Java 网络编程的核心内容:

1. 网络编程基础

网络模型

  • OSI 七层模型:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
  • TCP/IP 四层模型:网络接口层、网络层(IP)、传输层(TCP/UDP)、应用层(HTTP/FTP等)

关键概念

  • IP地址:标识网络中的设备(IPv4/IPv6)
  • 端口号:标识应用程序(0-65535)
  • Socket:网络通信的端点

2. Java 网络编程核心类

InetAddress 类

java
// 获取本地主机信息
InetAddress localHost = InetAddress.getLocalHost();

// 通过主机名获取IP
InetAddress address = InetAddress.getByName("www.example.com");

// 获取所有IP
InetAddress[] addresses = InetAddress.getAllByName("www.example.com");

3. TCP 编程

服务端实现

java
// 创建ServerSocket,监听指定端口
try (ServerSocket serverSocket = new ServerSocket(8888)) {
    System.out.println("服务器启动,等待连接...");
    
    // 接受客户端连接
    Socket socket = serverSocket.accept();
    System.out.println("客户端连接成功: " + socket.getInetAddress());
    
    // 获取输入输出流
    try (InputStream in = socket.getInputStream();
         OutputStream out = socket.getOutputStream();
         BufferedReader reader = new BufferedReader(new InputStreamReader(in));
         PrintWriter writer = new PrintWriter(out, true)) {
        
        // 读取客户端数据
        String clientMessage = reader.readLine();
        System.out.println("收到客户端消息: " + clientMessage);
        
        // 发送响应
        writer.println("你好,客户端!");
    }
} catch (IOException e) {
    e.printStackTrace();
}

客户端实现

java

java
// 创建Socket连接服务器
try (Socket socket = new Socket("localhost", 8888);
     OutputStream out = socket.getOutputStream();
     InputStream in = socket.getInputStream();
     PrintWriter writer = new PrintWriter(out, true);
     BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
    
    // 发送消息
    writer.println("你好,服务器!");
    
    // 接收响应
    String serverResponse = reader.readLine();
    System.out.println("服务器响应: " + serverResponse);
} catch (IOException e) {
    e.printStackTrace();
}

4. UDP 编程

服务端实现

java

java
// 创建DatagramSocket,监听指定端口
try (DatagramSocket socket = new DatagramSocket(8888)) {
    byte[] buffer = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    
    System.out.println("UDP服务器启动...");
    socket.receive(packet); // 接收数据包
    
    String message = new String(packet.getData(), 0, packet.getLength());
    System.out.println("收到来自 " + packet.getAddress() + " 的消息: " + message);
    
    // 发送响应
    byte[] response = "UDP服务器响应".getBytes();
    DatagramPacket responsePacket = new DatagramPacket(
        response, response.length, packet.getAddress(), packet.getPort());
    socket.send(responsePacket);
} catch (IOException e) {
    e.printStackTrace();
}

客户端实现

java
try (DatagramSocket socket = new DatagramSocket()) {
    InetAddress address = InetAddress.getByName("localhost");
    byte[] message = "你好,UDP服务器".getBytes();
    
    // 发送数据包
    DatagramPacket packet = new DatagramPacket(
        message, message.length, address, 8888);
    socket.send(packet);
    
    // 接收响应
    byte[] buffer = new byte[1024];
    DatagramPacket response = new DatagramPacket(buffer, buffer.length);
    socket.receive(response);
    
    System.out.println("收到服务器响应: " + 
        new String(response.getData(), 0, response.getLength()));
} catch (IOException e) {
    e.printStackTrace();
}

MySQL 索引与事务详解

一、索引(Index)

1. 索引是什么?

索引是数据库中一种特殊的数据结构,它类似于书籍的目录,能够帮助数据库系统快速定位数据,而无需扫描整个表。

2. 索引的作用

  • 加速数据检索:显著提高SELECT查询速度
  • 保证数据唯一性:唯一索引可防止重复数据
  • 加速表连接:提高多表连接查询效率
  • 优化排序和分组:对ORDER BY和GROUP BY操作有帮助

3. 常见索引类型

索引类型描述
B-Tree索引MySQL默认索引类型,适合全键值、键值范围或键前缀查找
哈希索引基于哈希表实现,仅支持等值比较查询,Memory引擎默认使用
全文索引用于全文搜索,仅MyISAM和InnoDB(5.6+)支持
空间索引用于地理空间数据类型,MyISAM支持

4. 索引使用示例

sql
-- 创建普通索引
CREATE INDEX idx_name ON users(username);

-- 创建唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);

-- 创建复合索引
CREATE INDEX idx_name_age ON users(username, age);

-- 查看表索引
SHOW INDEX FROM users;

5. 索引优化建议

  • 为WHERE、JOIN、ORDER BY子句中的列创建索引
  • 避免过度索引,每个索引都会占用空间并降低写入性能
  • 使用复合索引时遵循"最左前缀原则"
  • 对区分度高的列建索引(如身份证号比性别更适合建索引)
  • 长字符串列考虑使用前缀索引

二、事务(Transaction)

1. 事务是什么?

事务是一组原子性的SQL操作,要么全部执行成功,要么全部失败回滚。

2. 事务的特性(ACID)

  • 原子性(Atomicity):事务是不可分割的工作单位
  • 一致性(Consistency):事务使数据库从一个一致状态变到另一个一致状态
  • 隔离性(Isolation):事务执行不受其他事务干扰
  • 持久性(Durability):事务一旦提交,其结果就是永久性的

3. 事务控制语句

sql

sql
-- 开始事务
START TRANSACTION;
-- 或
BEGIN;

-- 提交事务
COMMIT;

-- 回滚事务
ROLLBACK;

-- 设置保存点
SAVEPOINT point_name;

-- 回滚到保存点
ROLLBACK TO point_name;

4. 事务隔离级别

隔离级别脏读不可重复读幻读说明
READ UNCOMMITTED可能可能可能最低隔离级别,可读取未提交数据
READ COMMITTED不可能可能可能只能读取已提交数据(Oracle默认)
REPEATABLE READ不可能不可能可能同一事务中多次读取结果一致(MySQL默认)
SERIALIZABLE不可能不可能不可能最高隔离级别,完全串行执行,性能最差

设置隔离级别:

sql
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

5. 事务使用示例

sql
START TRANSACTION;

UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;

-- 如果执行成功
COMMIT;

-- 如果出现错误
-- ROLLBACK;

6. 事务最佳实践

  • 尽量缩短事务执行时间
  • 避免在事务中进行耗时操作(如网络请求)
  • 根据业务需求选择合适的隔离级别
  • 注意死锁问题,尽量按相同顺序访问多表
  • 大事务可考虑拆分为多个小事务

三、索引与事务的关系

  1. 索引影响事务性能
    • 索引加速读操作,但会增加写操作的开销
    • 事务中的大量写操作在有索引的表上会更慢
  2. 事务隔离级别影响索引使用
    • 高隔离级别可能导致更多的锁争用,影响索引效率
    • REPEATABLE READ下可能出现"幻读"问题,即使使用了索引
  3. InnoDB的聚簇索引
    • InnoDB表的数据存储本身就是按主键组织的聚簇索引
    • 事务的原子性和隔离性实现依赖于索引结构

理解索引和事务是优化MySQL性能的关键,合理使用索引可以显著提高查询效率,而正确使用事务可以保证数据的一致性和完整性。

StringBuffer 和 StringBuilder 详解

1. 基本概念

StringBuffer

  • 线程安全:所有方法都是同步的(synchronized)
  • 性能:由于同步开销,性能相对较低
  • 适用场景:多线程环境下需要修改字符串内容

StringBuilder

  • 非线程安全:没有同步方法
  • 性能:比StringBuffer更高
  • 适用场景:单线程环境下需要修改字符串内容

2. 共同特点

  • 都是java.lang包下的类
  • 都继承自AbstractStringBuilder
  • 都是可变字符序列
  • 都提供了一系列修改字符串的方法
  • 初始容量都是16个字符,可自动扩容

3. 主要区别

特性StringBufferStringBuilder
线程安全是 (方法同步)
性能较低较高
版本引入Java 1.0Java 5.0
适用场景多线程环境单线程环境
同步开销

4. 常用方法

两者提供相同的API:

java
// 创建
StringBuffer sb1 = new StringBuffer();  // 初始容量16
StringBuilder sb2 = new StringBuilder("初始值");

// 追加内容
sb1.append("追加文本");
sb1.append(100);       // 追加数字
sb1.append(true);      // 追加布尔值

// 插入内容
sb1.insert(2, "插入"); // 在指定位置插入

// 删除内容
sb1.delete(1, 3);      // 删除1-3位置的字符
sb1.deleteCharAt(0);   // 删除指定位置字符

// 替换内容
sb1.replace(0, 2, "替换"); // 替换指定范围内容

// 反转
sb1.reverse();

// 获取长度和容量
int len = sb1.length();
int cap = sb1.capacity();

// 设置长度
sb1.setLength(10);

// 转换为String
String result = sb1.toString();

Java集合框架详解及对比

一、Java集合框架全景图

text
Collection接口
├── List接口 (有序、可重复)
│   ├── ArrayList
│   ├── LinkedList
│   ├── Vector
│   └── Stack

├── Set接口 (无序、唯一)
│   ├── HashSet
│   │   └── LinkedHashSet
│   ├── TreeSet
│   └── EnumSet

└── Queue接口 (队列)
    ├── PriorityQueue
    ├── Deque接口
    │   ├── ArrayDeque
    │   └── LinkedList
    └── BlockingQueue接口
        ├── ArrayBlockingQueue
        ├── LinkedBlockingQueue
        └── PriorityBlockingQueue

Map接口 (键值对)
├── HashMap
│   └── LinkedHashMap
├── TreeMap
├── Hashtable
└── ConcurrentHashMap

二、主要集合类详细对比

1. List系列对比

特性ArrayListLinkedListVectorStack
底层实现动态数组双向链表动态数组继承自Vector
线程安全是(synchronized)是(synchronized)
随机访问性能O(1) 极快O(n) 慢O(1)O(1)
插入删除性能末尾O(1),中间O(n)头尾O(1),中间O(n)类似ArrayList类似Vector
内存占用较小(连续内存)较大(节点开销)类似ArrayList类似Vector
扩容机制1.5倍无需扩容2倍同Vector
最佳使用场景查询多,增删少增删多,查询少已淘汰已淘汰

2. Set系列对比

特性HashSetLinkedHashSetTreeSetEnumSet
底层实现HashMapLinkedHashMapTreeMap位向量
排序特性无序插入顺序自然排序/Comparator枚举定义顺序
null值允许1个null允许1个null不允许(除非Comparator允许)不允许
时间复杂度添加/删除/查找O(1)添加/删除/查找O(1)添加/删除/查找O(log n)O(1)
线程安全
最佳使用场景常规去重需求需要保持插入顺序需要排序枚举类型集合

3. Queue/Deque对比

特性ArrayDequeLinkedListPriorityQueueArrayBlockingQueue
底层实现循环数组双向链表二叉堆(数组)数组
是否阻塞
排序FIFO/LIFOFIFO/LIFO优先级排序FIFO
线程安全
null值不允许允许不允许不允许
最佳使用场景高频插入删除同时需要List功能任务调度生产者-消费者模型

4. Map系列对比

特性HashMapLinkedHashMapTreeMapHashtableConcurrentHashMap
底层实现数组+链表/红黑树链表维护插入顺序红黑树数组+链表分段数组+链表/红黑树
排序特性无序插入顺序/访问顺序键的自然排序无序无序
null键值允许1个null键和多个null值同HashMap不允许不允许不允许
线程安全是(synchronized)是(分段锁)
时间复杂度O(1)O(1)O(log n)O(1)O(1)
扩容机制2倍同HashMap无需扩容2倍+1分段扩容
最佳使用场景常规键值存储需要保持插入顺序需要键排序已淘汰高并发环境

三、集合选择指南

  1. 需要键值对存储
    • 单线程:HashMap
    • 多线程:ConcurrentHashMap
    • 需要排序:TreeMap
    • 保持插入顺序:LinkedHashMap
  2. 只需要存储元素
    • 允许重复:ArrayList(查询多)/LinkedList(增删多)
    • 不允许重复:
      • 常规:HashSet
      • 需要排序:TreeSet
      • 保持插入顺序:LinkedHashSet
  3. 队列需求
    • 普通队列:ArrayDeque
    • 优先级队列:PriorityQueue
    • 阻塞队列:ArrayBlockingQueue/LinkedBlockingQueue
  4. 线程安全选择
    • List:Collections.synchronizedList(new ArrayList<>())
    • Set:Collections.synchronizedSet(new HashSet<>())
    • Map:ConcurrentHashMap(优于Hashtable)

四、Java 8+新特性对集合的影响

  1. HashMap优化

    • 当链表长度>8时转为红黑树,提高最坏情况性能
    • 链表长度<6时转回链表
  2. 新增API

    java
    // forEach
    map.forEach((k, v) -> System.out.println(k + ": " + v));
    
    // removeIf
    list.removeIf(e -> e.length() > 5);
    
    // computeIfAbsent
    map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
  3. Stream API

    java

    java
    List<String> filtered = list.stream()
        .filter(s -> s.startsWith("A"))
        .sorted()
        .collect(Collectors.toList());

五、性能优化建议

  1. 初始化容量

    java

    java
    new ArrayList<>(100);  // 避免频繁扩容
    new HashMap<>(256, 0.75f);
  2. 遍历选择

    • ArrayList:普通for循环最快
    • LinkedList:使用迭代器
    • HashMap:entrySet遍历最优
  3. 避免装箱拆箱

    • 考虑使用IntArrayList(第三方库)替代ArrayList<Integer>
  4. 并发控制

    • 读多写少:CopyOnWriteArrayList
    • 写多:ConcurrentHashMap
  5. 特殊场景

    • 枚举集合:EnumSet/EnumMap性能最优
    • 原始类型集合:考虑Trove、FastUtil等第三方库

六、总结图谱

text
选择集合的决策树:
是否需要键值对?
├── 是 → 是否需要线程安全?
│   ├── 是 → ConcurrentHashMap
│   └── 否 → 是否需要排序?
│       ├── 是 → TreeMap
│       ├── 否 → 是否需要插入顺序?
│           ├── 是 → LinkedHashMap
│           └── 否 → HashMap
└── 否 → 是否允许重复?
    ├── 是 → List
    │   ├── 查询多 → ArrayList
    │   └── 增删多 → LinkedList
    └── 否 → Set
        ├── 需要排序 → TreeSet
        ├── 需要插入顺序 → LinkedHashSet
        └── 常规需求 → HashSet

Java集合框架提供了丰富的数据结构实现,理解各集合类的特点及适用场景,能够帮助开发者编写出更高效、更健壮的代码。

如有转载或 CV 的请标注本站原文地址

访客数 --| 总访问量 --