大厂经验的MYSQL面试深度总结
### 1. **不使用任何优化,直接访问数据库,如何优化?**
**优化思路**:
- **Redo、Undo Log**的开销:数据库的事务日志(Redo和Undo日志)在事务处理过程中会产生大量的I/O操作。如果数据库没有优化,事务的回滚或提交会产生很大的性能开销。为了优化,可以减少事务的提交频率,或者批量处理多条SQL语句。
- **批处理(Batch Processing)**:将多个SQL语句合并成一个批处理,减少与数据库的交互次数。这可以大幅降低网络延迟及数据库I/O负担。
- **连接池(Connection Pool)**:数据库连接的创建和销毁是非常耗时的,使用连接池可以重用现有的连接,避免频繁的连接和断开数据库。常见的连接池有HikariCP、C3P0等。
- **缓存**:使用缓存技术减少对数据库的频繁访问,例如通过Redis等内存数据库缓存热点数据。
### 2. **行锁锁的是索引,如果一个表没有主键怎么加锁?**
如果表没有主键,InnoDB会选择使用一行记录的最左边的唯一索引作为锁定对象。如果表没有任何唯一索引,InnoDB将使用一个隐式的“隐藏主键”(实际上是一个基于行数据的聚簇索引)来执行锁定操作。由于没有显式的主键或唯一索引,锁定可能会影响性能,因此推荐给每个表添加主键或唯一索引。
### 3. **HashMap 为什么不直接用红黑树,还要用链表?**
- **性能考虑**:HashMap的设计目的是在平均情况下提供O(1)的查找速度,而链表作为HashMap中“碰撞”处理的方式,在大多数情况下非常高效。红黑树的查找操作复杂度为O(log n),相比之下,链表的查找复杂度虽然为O(n),但是对于大多数情况下的哈希冲突,它足够快。
- **空间和复杂度**:红黑树需要更多的内存空间来保存平衡信息。链表结构简单,占用内存较少且实现起来更容易,适合哈希表的冲突处理。
- **链表转红黑树**:如果哈希冲突过于严重,Java 8中的HashMap会在链表长度超过一定阈值时(如8个元素)转为红黑树,从而提高性能。
### 4. **红黑树的特性?各种操作的时间复杂度?最多旋转几次达到平衡?**
**红黑树的特性**:
- 每个节点是红色或黑色。
- 根节点为黑色。
- 所有叶子节点(NIL节点)为黑色。
- 如果一个红色节点有子节点,它的两个子节点都为黑色(即不允许有两个连续的红色节点)。
- 从任意节点到其子孙节点的路径上,黑色节点的数量是相同的(称为黑色高度)。
**时间复杂度**:
- 插入、删除、查找的时间复杂度均为O(log n),这是因为红黑树保证了树的高度是对数级别。
**最多旋转次数**:
- 插入和删除操作在最坏情况下最多需要进行2次旋转来保持红黑树的平衡。
### 5. **finally 中 return 会发生什么?**
- 在`finally`块中使用`return`会导致它覆盖`try`或`catch`块中的`return`,并且`finally`中的`return`会在方法执行完成之前先执行。
- **注意**:如果在`finally`中使用`return`,方法会返回`finally`中的值,而不是`try`或`catch`中的值。这是因为`finally`块中的`return`会先执行,且覆盖了之前的`return`。
### 6. **如何破坏双亲委派?**
双亲委派模型是Java类加载机制的核心原则,即加载器委托给父类加载器加载类。要破坏双亲委派模型,可以通过自定义类加载器来实现:
- 在自定义类加载器中,重写`findClass()`方法,直接加载类文件而不委托给父类加载器。
- 通过设置`setParent()`方法或其他方式改变父加载器,或者将父加载器设置为`null`。
### 7. **浏览器中用户信息和密码的安全有没有考虑过?**
在浏览器中存储用户信息和密码时,需要考虑以下安全措施:
- **加密存储**:密码应在客户端或服务器端加密存储。常用的加密算法包括AES、SHA等。
- **SSL/TLS**:使用HTTPS协议(即SSL/TLS)加密用户和服务器之间的通信,防止信息被中间人攻击窃取。
- **JWT**:使用JWT(JSON Web Token)来确保身份验证的安全性,并确保令牌的有效期。
- **输入验证**:对密码和用户信息进行严格的输入验证,防止SQL注入等攻击。
### 8. **两个线程如何交替打印A和B?**
可以使用`Object`的`wait()`和`notify()`方法来实现线程交替打印:
```java
class PrintAB {
private static final Object lock = new Object();
private static boolean printA = true;
public static void main(String[] args) {
Thread threadA = new Thread(() -> {
while (true) {
synchronized (lock) {
while (!printA) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.println("A");
printA = false;
lock.notify();
}
}
});
Thread threadB = new Thread(() -> {
while (true) {
synchronized (lock) {
while (printA) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.println("B");
printA = true;
lock.notify();
}
}
});
threadA.start();
threadB.start();
}
}
```
### 9. **100万个数,数写一篇某电商大厂某里的场景面试相关的文章,并回答以下问题:类型是int,给你8核CPU,8G内存,如何求数组的和?**
可以利用多线程来并行计算数组的和。由于有8个核心,可以将数组分成8个部分,每个核心计算一部分的和,然后将各部分的结果相加:
- 切分数组成8个部分。
- 每个线程计算一个部分的和。
- 汇总各线程的结果。
**代码示例**:
```java
public class SumArray {
public static void main(String[] args) {
int[] arr = new int[1000000];
// 填充数组
for (int i = 0; i < arr.length; i++) {
arr[i] = i + 1;
}
int numThreads = 8;
int chunkSize = arr.length / numThreads;
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
List<Future<Integer>> results = new ArrayList<>();
// 分配任务给线程
for (int i = 0; i < numThreads; i++) {
int start = i * chunkSize;
int end = (i == numThreads - 1) ? arr.length : (i + 1) * chunkSize;
results.add(executor.submit(() -> {
int sum = 0;
for (int j = start; j < end; j++) {
sum += arr[j];
}
return sum;
}));
}
// 汇总结果
int totalSum = 0;
for (Future<Integer> result : results) {
try {
totalSum += result.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("Total Sum: " + totalSum);
executor.shutdown();
}
}
```
### 10. **很多个不重复的数,假设用的数组来装,我希望你实现一个方法,每次调用这个方法给我随机返回100个不重复,记住是随机的。**
可以通过`Collections.shuffle()`方法来随机打乱数组,然后取前100个数:
```java
import java.util.*;
public class RandomSelector {
private List<Integer> list;
public RandomSelector(List<Integer> numbers) {
this.list = new ArrayList<>(numbers);
}
public List<Integer> getRandom100() {
Collections.shuffle(list);
return list.subList(0, 100);
}
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
更多推荐


所有评论(0)