Browse Source

新增kafka面经

seamew 1 year ago
parent
commit
ce7469559d

+ 2 - 2
面经/问答/Mysql.md

@@ -14,13 +14,13 @@
 5. 定期维护数据库:数据库的性能和稳定性需要定期进行维护,包括定期清理无用的数据和索引,进行数据库备份和日志管理,定期更新统计信息等。定期维护可以保持数据库的健康状态,提升查询性能。
 6. 可以考虑使用分库分表技术,例如对于用户中奖详情单我选择了分库分表,因为有多个用户和不同活动同时竞争这个表,数据库访问压力比较大,所以就要选择分库分表
 
-## mysql层数据结构
+## mysql层数据结构
 
 1. B+ 树索引:MySQL 使用 B+ 树作为默认的索引结构。索引数据最好能按顺序排列,这样可以使用「二分查找法」高效定位数据,而且还要支持排序操作。这就天然要求我们使用平衡二叉树作为默认的数据结构,而平衡二叉树本身是一个B树,每个节点只能有两个子节点那么当节点个数越多的时候,树的高度也会相应变高,这样就会增加磁盘的 I/O 次数,从而影响数据查询的效率。B 树的每一个节点最多可以包括 M 个子节点,M 称为 B 树的阶,所以 B 树就是一个多叉树。B+ 树就是对 B 树做了一个升级,他和B树相比有如下几个优点
    1. B+ 树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的 B 树查询效率更高,因为IO次数更少
    2. B+ 树在删除根节点的时候,由于存在冗余的节点,所以不会发生复杂的树的变形,B 树则不同,B 树没有冗余节点,删除节点的时候非常复杂
    3. B+ 树所有叶子节点间还有一个链表进行连接,这种设计对范围查找非常有帮助
-2. 数据文件:MySQL 数据库将数据存储在磁盘上的数据文件中,层由表空间构成,表空间由段(segment)、区(extent)、页(page)、行(row)组成
+2. 数据文件:MySQL 数据库将数据存储在磁盘上的数据文件中,层由表空间构成,表空间由段(segment)、区(extent)、页(page)、行(row)组成
 3. InnoDB 存储引擎:InnoDB 是 MySQL 的一种常用存储引擎,它使用了多版本并发控制(MVCC)和行级锁来实现高并发性和事务支持。InnoDB 存储引擎的核心数据结构包括页(page)、记录(record)、索引(index)和事务日志(transaction log)等。
 
 ## 联合索引定义要注意哪些点

BIN
面经/问答/assets/image-20230519214345638.png


+ 29 - 0
面经/问答/kafka.md

@@ -0,0 +1,29 @@
+## kafka为什么快?
+
+### 顺序读写
+
+kafka的存储方案是**顺序追加写日志 + 稀疏哈希索引**
+
+![image-20230519214345638](assets/image-20230519214345638.png)
+
+1. kafka 中消息是以主题 Topic 为基本单位进行归类的,这里的 Topic 是逻辑上的概念,实际上在磁盘存储是根据分区 Partition 存储的, 即每个 Topic 被分成多个 Partition,分区 Partition 的数量可以在主题 Topic 创建的时候进行指定。
+
+2. Partition 分区主要是为了解决 Kafka 存储的水平扩展问题而设计的, 如果一个 Topic 的所有消息都只存储到一个 Kafka Broker上的话, 对于 Kafka 每秒写入几百万消息的高并发系统来说,这个 Broker 肯定会出现瓶颈, 故障时候不好进行恢复,所以 Kafka 将 Topic 的消息划分成多个 Partition, 然后均衡的分布到整个 Kafka Broker 集群中。
+
+3. Partition 分区内每条消息都会被分配一个唯一的消息 id,即我们通常所说的 偏移量 Offset, 因此 kafka 只能保证每个分区内部有序性,并不能保证全局有序性。
+
+4. 然后每个 Partition 分区又被划分成了多个 LogSegment,这是为了防止 Log 日志过大,Kafka 又引入了日志分段(LogSegment)的概念,将 Log 切分为多个 LogSegement,相当于一个巨型文件被平均分割为一些相对较小的文件,这样也便于消息的查找、维护和清理。这样在做历史数据清理的时候,直接删除旧的 LogSegement 文件就可以了。
+
+4. Log 日志在物理上只是以文件夹的形式存储,而每个 LogSegement 对应磁盘上的一个日志文件和两个索引文件,以及可能的其他文件(比如以".snapshot"为后缀的快照索引文件等)
+
+### 页缓存
+
+页缓存相对来说比较简单,页缓存在操作系统层面是保存数据的一个基本单位,Kafka 避免使用 JVM,直接使用操作系统的页缓存特性提高处理速度,进而避免了JVM GC 带来的性能损耗。
+
+### 零拷贝
+
+
+
+### 批量操作
+
+在 kafka 中页提高了大量批处理的 API ,可以对数据进行统一的压缩合并,通过更小的数据包在网络中进行数据发送,再进行后续处理,这在大量数据处理中,效率提高是非常明显的。

+ 9 - 9
面经/问答/并发编程.md

@@ -8,7 +8,7 @@
 
 同样,`notify()`方法也必须在同步块中使用。如果一个线程在未获得锁的情况下调用`notify()`方法,那么它将无法通知任何等待的线程。因为它没有获取锁,所以它不能访问共享数据或执行必要的同步操作来确保正确的通知。
 
-因此,使用`wait()`和`notify()`方法时,必须在同步块中使用它们,以确保线程之间的安全性并避免出现竞态条件。
+因此,使用`wait()`和`notify()`方法时,必须在同步q块中使用它们,以确保线程之间的安全性并避免出现竞态条件。
 
 ## volatile 关键字
 
@@ -158,7 +158,7 @@ AQS提供了一种通用的框架,用于实现线程间的协作和同步操
 * **`ThreadPoolExecutor.DiscardPolicy`:** 不处理新任务,直接丢弃掉。
 * **`ThreadPoolExecutor.DiscardOldestPolicy`:** 此策略将丢弃最早的未处理的任务请求。
 
-### 如何设定线程池的大小?
+### 如何设定线程池的大小?(CPU 核心数 - N)
 
 * **CPU 密集型任务(N+1)**
 
@@ -171,13 +171,13 @@ CPU 密集型简单理解就是利用 CPU 计算能力的任务比如你在内
 * Future类的get方法
 
 ```java
-private static final int NEW          = 0;
-private static final int COMPLETING   = 1;
-private static final int NORMAL       = 2;
-private static final int EXCEPTIONAL  = 3;
-private static final int CANCELLED    = 4;
-private static final int INTERRUPTING = 5;
-private static final int INTERRUPTED  = 6;
+private static final int NEW          = 0; // 初始状态,FutureTask刚被创建,正在计算中都是该状态。
+private static final int COMPLETING   = 1; // 中间状态,表示计算已完成正在对结果进行赋值,或正在处理异常
+private static final int NORMAL       = 2; // 终止状态,表示计算已完成,结果已经被赋值。
+private static final int EXCEPTIONAL  = 3; // 终止状态,表示计算过程已经被异常打断。
+private static final int CANCELLED    = 4; // 终止状态,表示计算过程已经被cancel操作终止。
+private static final int INTERRUPTING = 5; // 中间状态,表示计算过程已开始并且被中断,正在修改状态。
+private static final int INTERRUPTED  = 6; // 终止状态,表示计算过程已开始并且被中断,目前已完全停止。
 
 public V get() throws InterruptedException, ExecutionException {
     int s = state;