> ## Documentation Index
> Fetch the complete documentation index at: https://amigoer.mintlify.app/llms.txt
> Use this file to discover all available pages before exploring further.

# 计算机基础面经

本章节汇总了面试中常见的通用技术概念，不局限于特定语言或数据库，是考察技术内功的关键考点。

***

## 一、并发与锁的设计理念

### Q1: 悲观锁 vs 乐观锁（看待冲突的态度）

| 特性     | 悲观锁 (Pessimistic Lock)                 | 乐观锁 (Optimistic Lock)  |
| :----- | :------------------------------------- | :--------------------- |
| **心态** | “总有刁民想害朕”（保守）                          | “大家都是好人”（乐观）           |
| **做法** | 操作前先上锁，锁死资源                            | 全程不加锁，提交时检查版本          |
| **实现** | `SELECT ... FOR UPDATE`、`synchronized` | 版本号机制 (version)、CAS 算法 |
| **场景** | 写操作频繁、竞争激烈                             | 读操作频繁、竞争较少             |

**生活案例：**

* **悲观锁**：进卫生间先锁门。你在里面的时候，外面的人只能等（阻塞）。
* **乐观锁**：Git 代码提交。写代码时不锁文件，push 时检查版本，版本冲突则报错。

***

### Q2: 自旋锁 (Spin Lock)（等待的方式）

自旋锁并不属于某种特定的锁实现，而是一种**等待策略**。

* **传统互斥锁**：如果拿不到锁，线程就**挂起（睡觉）**，等待系统唤醒。
* **自旋锁**：如果拿不到锁，线程**不睡觉**，而是原地打转（死循环）不停询问：“好了没？好了没？”

**优缺点：**

* **优点**：避免了线程上下文切换（上下文切换很贵）的开销。如果锁很快就释放了，效率极高。
* **缺点**：如果对方占用时间很长，你会白白浪费 CPU 资源在转圈圈上。

**生活案例：**

* **互斥锁**：饭店没位子，领个号去逛街，等服务员电话。
* **自旋锁**：卫生间有人，你在门口每隔 10 秒敲一次门询问。

***

### Q3: 可重入锁 (Reentrant Lock)（身份的识别）

指一个线程已经获得了某个锁，它可以**再次获取**这个锁而不会被自己锁死。

* **可重入**：锁能认出“你是自己人”，直接放行。Java 的 `synchronized` 和 `ReentrantLock` 都是可重入的。
* **不可重入**：再次尝试获取锁时会因为之前已经加过锁而导致死锁（自己把自己锁在外面）。

**生活案例：**

* 你拿着家里的钥匙开了大门进入院子，内屋的门也需要同样的钥匙。如果你能直接刷卡进去就是**可重入**；如果系统说“你还没出门不能再进”，那你就被困在院子里（死锁）了。

***

### Q4: 公平锁 vs 非公平锁（排队的规则）

* **公平锁**：排队。严格按先来后到，谁等得久谁拿。
* **非公平锁**：插队。锁一释放，新来的人如果正好赶上，可以直接抢走。抢不到才去排队。

**对比：**

* **公平锁**：公平，不会有人“饿死”，但性能差（要维护队列）。
* **非公平锁**：性能高，吞吐量大。但可能导致排在后面的人一直抢不到。

***

### Q5: 什么是死锁？如何预防？

**死锁的四个必要条件：**

1. **互斥**：资源一次只能被一个线程占用。
2. **请求与保持**：占着碗里的，还要抢锅里的。
3. **不可剥夺**：不能去强制抢别人正在用的资源。
4. **循环等待**：A 等 B，B 等 C，C 等 A。

**预防方案：**

* **资源有序分配**：规定所有线程必须按相同的顺序获取锁。
* **超时退出**：尝试获取锁时设置超时时间。
* **银行家算法**：动态分配资源前预测风险。
