
面试知识清单
文章平均质量分 76
悠然予夏
(考研备战中)纵有疾风起,人生不言弃;风乍起,合当奋意向此生;熬过无人问津的日子,才有诗和远方。
喜欢Java,热爱编程。
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
Gossip 协议
介绍了Gossip 协议原创 2022-06-01 21:28:47 · 2620 阅读 · 0 评论 -
Raft 算法
另一种共识算法,目的是比 Paxos 更易理解整个 Raft 算法分解为三部分:1. Leader 选举① 只有一个 Server 能作为 Leader② 一旦此 Server 崩溃,选举新 Leader2. 执行操作,以日志复制为例(Log replication)① 由 Leader 执行自己的日志记录② 将日志复制到其它 Server,会覆盖掉不一致的部分③ 多数派记录日志成功,Leader 才能执行命令,向客户端返回结果3. 确保安全① 保证日志记录的一致性② 拥有最新日志的 Server 才能成为原创 2022-06-01 21:21:37 · 527 阅读 · 0 评论 -
Paxos 算法
集群中有 N 个节点,如果一个节点写入后要求同步到剩余 N-1 个节点后再向客户端返回 ok,虽然看起来最保险,但其中任意一个节点同步失败,势必造成整个集群不可用,能否在此基础上稍微提高可用性呢? 答案是 (写)多数派,集群节点设置为奇数,同步超过集群中 N/2 个节点成功,则向客户端返回 ok,但存在顺序性问题,如 3 描述多数派写操作成功后的读一致性暂不考虑,思考下图中的两项操作,都满足了多数派通过,但 S3 这台服务器并没有与 S1,S2 达成一致,要达到多数派内部一致性 Paxos 是一种共识算法,原创 2022-06-01 21:02:01 · 3428 阅读 · 1 评论 -
CAP 定理
Consistency 一致性:访问分布式系统中任意节点,总能返回一致的结果Every read receives the most recent write or an errorAvailability 可用性:分布式系统总能向客户端返回响应Every request receives a (non-error) response, without the guarantee that it contains the most recent writePartition tolerance 分区容忍:当原创 2022-06-01 20:50:52 · 353 阅读 · 0 评论 -
Redis LRU Cache 实现
Least Recently Used,将最近最少使用的 key 从缓存中淘汰掉。以链表法为例,最近访问的 key 移动到链表头,不常访问的自然靠近链表尾,如果超过容量、个数限制,移除尾部的例如有原始数据如下,容量规定为 3如何断开节点链接如何链入头节点 参考代码一(纯手写实现) 参考代码二(借助LinkedHashMap实现)原创 2022-05-31 22:49:56 · 461 阅读 · 0 评论 -
Redis 缓存原子性
介绍了Redis 缓存原子性原创 2022-05-31 22:21:39 · 1212 阅读 · 0 评论 -
Redis 缓存问题
1、缓存击穿 缓存击穿是指:某一热点 key 在缓存和数据库中都存在,它过期时,这时由于并发用户特别多,同时读缓存没读到,又同时去数据库去读,压垮数据库 解决方法 热点数据不过期 对【查询缓存没有,查询数据库,结果放入缓存】这三步进行加锁,这时只有一个客户端能获得锁,其它客户端会被阻塞,等锁释放开,缓存已有了数据,其它客户端就不必访问数据库了。但会影响吞吐量(有损方案) 2、缓存雪崩 情况1:由于大量 key 设置了相同的过期时间(数据在缓.原创 2022-05-31 11:58:58 · 744 阅读 · 0 评论 -
Redis 持久化
1、AOF 持久化 AOF - 将每条写命令追加至 aof 文件,当重启时会执行 aof 文件中每条命令来重建内存数据 AOF 日志是写后日志,即先执行命令,再记录日志 Redis 为了性能,向 aof 记录日志时没有对命令进行语法检查,如果要先记录日志,那么日志里就会记录语法错误的命令 记录 AOF 日志时,有三种同步策略 Always 同步写,日志写入磁盘再返回,可以做到基本不丢数据,性能不高 为什么说基本不丢呢,因为 aof 是在 se原创 2022-05-31 11:53:19 · 285 阅读 · 0 评论 -
Redis keys 命令问题 与 过期 key 的删除策略
1、keys 命令问题问题描述 redis有一亿个 key,使用 keys 命令是否会影响线上服务? 解答 keys 命令时间复杂度是 O(n),n 即总的 key 数量,n 如果很大,性能非常低 redis 执行命令是单线程执行,一个命令执行太慢会阻塞其它命令,阻塞时间长甚至会让 redis 发生故障切换 改进方案 可以使用 scan 命令替换 keys 命令,语法 scan 起始游标 match 匹配规则 count 提示数目,返回值代表下次的起点 虽然原创 2022-05-31 09:32:41 · 615 阅读 · 0 评论 -
Redis 数据类型
概述数据类型实际描述的是 value 的类型,key 都是 string,常见数据类型(value)有 string(embstr、raw、int) list(quicklist,由多个 ziplist 双向链表组成) hash(ziplist、hashtable) set(intset、hashtable) sorted set(ziplist、skiplist) bitmap hyperloglog 每一种类型都用 redisOb原创 2022-05-31 09:26:09 · 348 阅读 · 0 评论 -
MySQL数据库之锁
1、全局锁用作全量备份时,保证表与表之间的数据一致性如果不加任何包含,数据备份时就可能产生不一致的情况,如下图所示全局锁的语法:flush tables with read lock; 使用全局读锁锁定所有数据库的所有表。这时会阻塞其它所有 DML 以及 DDL 操作,这样可以避免备份过程中的数据不一致。接下来可以执行备份,最后用 unlock tables 来解锁 注意但 flush tables 属于比较重的操作,可以使用 --single-tra...原创 2022-05-29 20:22:42 · 665 阅读 · 0 评论 -
数据库之查询语句执行流程、 undo log 与 redo log
1、查询语句执行流程执行 SQL 语句 select * from user where id = 1 时发生了什么 连接器:负责建立连接、检查权限、连接超时时间由 wait_timeout 控制,默认 8 小时 查询缓存:会将 SQL 和查询结果以键值对方式进行缓存,修改操作会以表单位导致缓存失效 分析器:词法、语法分析 优化器:决定用哪个索引,决定表的连接顺序等 执行器:根据存储引擎类型,调用存储引擎接口 存储引擎:数据的读写接口,索引、表原创 2022-05-29 19:01:48 · 421 阅读 · 0 评论 -
数据库之命中索引
准备数据 修改 MySQL 配置文件,在 [mysqld] 下添加 secure_file_priv= 重启 MySQL 服务器,让选项生效 执行 db.sql 内的脚本,建表 执行 LOAD DATA INFILE 'D:\\big_person.txt' INTO TABLE big_person; 注意实际路径根据情况修改 测试表 big_person(此表数据量较大,如果与其它表数据一起提供不好管理,故单独提供),数据行数 100 万条,列个数 15 列。为了更快原创 2022-05-29 15:55:17 · 1176 阅读 · 0 评论 -
数据库之索引基础
1、常见索引 哈希索引 理想时间复杂度为 O(1) 适用场景:适用于等值查询的场景,内存数据的索引 典型实现:Redis,MySQL 的 memory 引擎 平衡二叉树索引 查询和更新的时间复杂度都是 O(log_2(n)) 适用场景:适用于等值查询以及范围查询;适合内存数据的索引,但不适合磁盘数据的索引,可以认为树的高度决定了磁盘 I/O 的次数,百万数据树高约为 20 BTree 索引 B原创 2022-05-29 13:10:16 · 437 阅读 · 0 评论 -
数据库之InnoDB vs MyISAM
1、InnoDB 索引分为聚簇索引与二级索引 聚簇索引:主键值作为索引数据,叶子节点还包含了所有字段数据,索引和数据是存储在一起的 二级索引:除主键外的其它字段建立的索引称为二级索引。被索引的字段值作为索引数据,叶子节点还包含了主键值 支持事务 通过 undo log 支持事务回滚、当前读(多版本查询) 通过 redo log 实现持久性 通过两阶段提交实现一致性 通过当前读、锁实现隔离性原创 2022-05-29 10:40:35 · 269 阅读 · 0 评论 -
数据库之快照读与当前读
1、当前读即读取最新提交的数据 select … for update select ... lock in share mode insert、update、delete,都会按最新提交的数据进行操作 当前读本质上是基于锁的并发读操作2、快照读读取某一个快照建立时(可以理解为某一时间点)的数据,也称为一致性读。快照读主要体现在 select 时,而不同隔离级别下,select 的行为不同 在 Serializable 隔离级别下 - 普通 select原创 2022-05-29 10:02:56 · 4734 阅读 · 2 评论 -
数据库之隔离级别
1、未提交读 读到其它事务未提交的数据(最新的版本) 错误现象:有脏读、不可重复读、幻读现象 脏读现象tx1 tx2 set session transaction isolation level read uncommitted; start transaction; select * from account; /两个账户都为 1000/ start transaction; update原创 2022-05-29 09:57:07 · 253 阅读 · 0 评论 -
Spring 中的设计模式
1. Spring 中的 Singleton请大家区分 singleton pattern 与 Spring 中的 singleton bean 根据单例模式的目的 Ensure a class only has one instance, and provide a global point of access to it 显然 Spring 中的 singleton bean 并非实现了单例模式,singleton bean 只能保证每个容器内,相同 id 的 bean 单实例原创 2022-05-28 20:48:13 · 239 阅读 · 0 评论 -
SpringBoot 自动配置原理
1、自动配置原理@SpringBootConfiguration 是一个组合注解,由 @ComponentScan、@EnableAutoConfiguration 和 @SpringBootConfiguration 组成 @SpringBootConfiguration 与普通 @Configuration 相比,唯一区别是前者要求整个 app 中只出现一次 @ComponentScan excludeFilters - 用来在组件扫描时进行排除,也会排除自动配置类原创 2022-05-28 19:13:48 · 404 阅读 · 0 评论 -
Spring 注解
注解大全原创 2022-05-28 12:46:36 · 214 阅读 · 0 评论 -
Spring MVC 执行流程
1、准备阶段 在 Web 容器第一次用到 DispatcherServlet 的时候,会创建其对象并执行 init 方法 init 方法内会创建 Spring Web 容器,并调用容器 refresh 方法 refresh 过程中会创建并初始化 SpringMVC 中的重要组件, 例如 MultipartResolver,HandlerMapping,HandlerAdapter,HandlerExceptionResolver、ViewResolver 等 容器初始化后原创 2022-05-28 10:34:37 · 294 阅读 · 0 评论 -
Spring 事务失效
1、 抛出检查异常导致事务不能正确回滚@Servicepublic class Service1 { @Autowired private AccountMapper accountMapper; @Transactional public void transfer(int from, int to, int amount) throws FileNotFoundException { int fromBalance = accountMappe原创 2022-05-28 09:41:39 · 534 阅读 · 0 评论 -
spring bean循环依赖
1、创建代理代码演示package day04.tx;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.springframework.aop.aspectj.AspectJExpressionPointcut;import org.springframework.aop.framework.ProxyFactory原创 2022-05-27 19:20:46 · 539 阅读 · 0 评论 -
Spring bean 生命周期
protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)阶段1:处理名称,检查缓存 阶段2:检查父工厂 阶段3:检查 DependsOn 阶段4:按 Scope 创建 bean 创建 singleton 创建 prototype 创建其它 scope 阶段5:创建 be...原创 2022-05-26 13:16:54 · 280 阅读 · 0 评论 -
Spring refresh 流程
Spring refresh 概述refresh 是 AbstractApplicationContext 中的一个方法,负责初始化 ApplicationContext 容器,容器必须调用 refresh 才能正常工作。它的内部主要会调用 12 个方法,我们把它们称为 refresh 的 12 个步骤: prepareRefresh obtainFreshBeanFactory prepareBeanFactory postProcessBeanFactory原创 2022-05-25 21:20:12 · 395 阅读 · 0 评论 -
finalize 的工作原理与缺点
finalize 它是 Object 中的一个方法,如果子类重写它,垃圾回收时此方法会被调用,可以在其中进行资源释放和清理工作 将资源释放和清理放在 finalize 方法中非常不好,非常影响性能,严重时甚至会引起 OOM,从 Java9 开始就被标注为 @Deprecated,不建议被使用了 finalize 原理(1)对 finalize 方法进行处理的核心逻辑位于 java.lang.ref.Finalizer 类中,它包含了名为 unfinalized 的静态变量(双向链原创 2022-05-25 14:34:41 · 801 阅读 · 0 评论 -
对象的四种引用
强引用 普通变量赋值即为强引用,如 A a = new A(); 通过 GC Root 的引用链,如果强引用不到该对象,该对象才能被回收 软引用(SoftReference) 例如:SoftReference a = new SoftReference(new A()); 如果仅有软引用该对象时,首次垃圾回收不会回收该对象,如果内存仍不足,再次回收时才会释放对象 软引用自身需要配合引用队列来释放 典型例子是反射数据 弱引用(WeakRe..原创 2022-05-25 14:28:06 · 1089 阅读 · 0 评论 -
类加载的方式
类加载过程的三个阶段 加载 将类的字节码载入方法区,并创建类.class 对象 如果此类的父类没有加载,先加载父类 加载是懒惰执行 链接 验证 – 验证类是否符合 Class 规范,合法性、安全性检查 准备 – 为 static 变量分配空间,设置默认值 解析 – 将常量池的符号引用解析为直接引用 初始化 静态代码块、static 修饰的变量赋值、static final 修饰原创 2022-05-25 14:20:45 · 849 阅读 · 0 评论 -
内存溢出的典型情况
1、误用线程池导致的内存溢出import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;// -Xmx64m// 模拟短信发送超时,但这时仍有大量的任务进入队列public class TestOomThreadPool { public static void main(String[] args) {原创 2022-05-24 11:21:07 · 1109 阅读 · 0 评论 -
JVM 垃圾回收
三种垃圾回收算法标记清除法解释: 找到 GC Root 对象,即那些一定不会被回收的对象,如正执行方法内局部变量引用的对象、静态变量引用的对象 标记阶段:沿着 GC Root 对象的引用链找,直接或间接引用到的对象加上标记 清除阶段:释放未加标记的对象占用的内存 标记整理法解释: 前面的标记阶段、清理阶段与标记清除法类似 多了一步整理的动作,将存活对象向一端移动,可以避免内存碎片产生 特点: 标记速度与存活对象线性关系 .原创 2022-05-24 10:06:52 · 208 阅读 · 0 评论 -
JVM 内存参数
堆内存,按大小设置解释:-Xms 最小堆内存(包括新生代和老年代) -Xmx 最大对内存(包括新生代和老年代) 通常建议将 -Xms 与 -Xmx 设置为大小相等,即不需要保留内存,不需要从小到大增长,这样性能较好 -XX:NewSize 与 -XX:MaxNewSize 设置新生代的最小与最大值,但一般不建议设置,由 JVM 自己控制 -Xmn 设置新生代大小,相当于同时设置了 -XX:NewSize 与 -XX:MaxNewSize 并且取值相等 保留是指,一开始不会占用那么...原创 2022-05-24 09:35:40 · 1220 阅读 · 0 评论 -
JVM 内存结构
结合一段 java 代码的执行理解内存划分 执行 javac 命令编译源代码为字节码 执行 java 命令 创建 JVM,调用类加载子系统加载 class,将类的信息存入方法区 创建 main 线程,使用的内存区域是 JVM 虚拟机栈,开始执行 main 方法代码 如果遇到了未见过的类,会继续触发类加载过程,同样会存入方法区 需要创建对象,会使用堆内存来存储对象 不再使用的对象,会由垃圾回收器在内存不足时回收其内存原创 2022-05-24 09:25:14 · 203 阅读 · 0 评论 -
悲观锁 vs 乐观锁、Hashtable vs ConcurrentHashMap与 ThreadLocal
1、悲观锁 vs 乐观锁对比悲观锁与乐观锁 悲观锁的代表是 synchronized 和 Lock 锁 其核心思想是【线程只有占有了锁,才能去操作共享变量,每次只有一个线程占锁成功,获取锁失败的线程,都得停下来等待】 线程从运行到阻塞、再从阻塞到唤醒,涉及线程上下文切换,如果频繁发生,影响性能 实际上,线程在获取 synchronized 和 Lock 锁时,如果锁已被占用,都会做几次重试操作,减少阻塞的机会 乐观锁的代表是 AtomicI原创 2022-05-23 19:15:07 · 662 阅读 · 0 评论 -
wait vs sleep、lock vs synchronized与volatile
1、wait与sleep共同点 wait() ,wait(long) 和 sleep(long) 的效果都是让当前线程暂时放弃 CPU 的使用权,进入阻塞状态 不同点 方法归属不同 sleep(long) 是 Thread 的静态方法 而 wait(),wait(long) 都是 Object 的成员方法,每个对象都有 醒来时机不同 执行 sleep(long) 和 wait(long) 的线程都会在等待相应毫秒后醒来原创 2022-05-23 19:11:22 · 230 阅读 · 0 评论 -
线程状态与线程池
1、线程状态1.1、六种状态及转换分别是 新建 当一个线程对象被创建,但还未调用 start 方法时处于新建状态 此时未与操作系统底层线程关联 可运行 调用了 start 方法,就会由新建进入可运行 此时与底层线程关联,由操作系统调度执行 终结 线程内代码已经执行完毕,由可运行进入终结 此时会取消与底层线程关联 阻塞 当获取锁失败后,由可运行进入 Moni原创 2022-05-22 22:09:34 · 341 阅读 · 0 评论 -
HashMap
1、基本数据结构 1.7 数组 + 链表 1.8 数组 + (链表 | 红黑树) 2、 树化与退化树化意义 红黑树用来避免 DoS 攻击,防止链表超长时性能下降,树化应当是偶然情况,是保底策略 hash 表的查找,更新的时间复杂度是 O(1),而红黑树的查找,更新的时间复杂度是 O(log₂n ),TreeNode 占用空间也比普通 Node 的大,如非必要,尽量还是使用链表 hash 值如果足够随机,则在 hash 表内按泊松分布,在负载因子 .原创 2022-05-22 18:27:04 · 662 阅读 · 0 评论 -
ArrayList、LinkedList
1、ArrayList扩容规则 ArrayList() 会使用长度为零的数组 ArrayList(int initialCapacity) 会使用指定容量的数组 public ArrayList(Collection<? extends E> c) 会使用 c 的大小作为数组容量 add(Object o) 首次扩容为 10,再次扩容为上次容量的 1.5 倍 addAll(Collection c) 没有元素时,扩容为 Math.max(10,原创 2022-05-21 21:49:26 · 162 阅读 · 0 评论