后端面试相关笔记
文章平均质量分 91
记录后端面试题
颜妮儿
学不完,根本学不完
展开
-
面试笔记——工厂模式(简单工厂、工厂方法模式、抽象工厂模式)
场景需求:设计一个咖啡店点餐系统。设计一个咖啡类(Coffee),并定义其两个子类(美式咖啡【AmericanCoffee】和拿铁咖啡【LatteCoffee】);再设计一个咖啡店类(CoffeeStore),咖啡店具有点咖啡的功能。在不使用工厂模式情况下,类设计如下:泛化关系(继承)实现关系依赖关系。原创 2024-05-07 16:59:43 · 1395 阅读 · 0 评论 -
面试笔记——垃圾回收
ps:在看上面的过程的时候,可能对from和to的相关操作有些疑惑(一会儿的是to一会儿又是from的),其实他们只是一个名字而已,实际就是两块内存,我们可以认为,在进行扫描时,内存中带有数据的为from,即将把数据复制到对应的内存为to。将原有的内存空间一分为二,每次只用其中的一块,正在使用的对象复制到另一个内存空间中,然后将该内存空间清空,交换两个内存的角色,完成垃圾的回收;无碎片,内存使用率低。标记清除算法一样,将存活对象都向内存另一端移动,然后清理边界以外的垃圾,无碎片,对象需要移动,效率低。原创 2024-05-07 13:41:21 · 1062 阅读 · 0 评论 -
面试笔记——类加载器
类从加载到虚拟机中开始,直到卸载为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。加载某一个类,先委托上一级的加载器进行加载,如果上级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载该类。比如:方法中调用了其他方法,方法名可以理解为符号引用,而直接引用就是使用指针直接指向方法。其中,前三项都是格式检查,如——文件格式是否错误、语法是否错误、字节码是否合规。:JVM只会运行二进制文件,类加载器的作用就是将。把类中的符号引用转换为直接引用。原创 2024-05-06 16:45:47 · 1003 阅读 · 0 评论 -
面试笔记——JVM组成
JVM: Java Virtual Machine Java程序的运行环境(java二进制字节码的运行环境)一次编写,到处运行自动内存管理,垃圾回收机制。原创 2024-05-06 13:46:47 · 1263 阅读 · 0 评论 -
面试笔记——多线程使用场景
在实现搜索功能的时候,不能让搜索功能受到保存搜索记录的影响,通常采取异步的方式来保存搜索记录,通过异步线程来实现该功能。当用户输入关键字开始搜索后,正常返回用户搜索的相关数据,再开一个线程来记录用户的历史记录,并把这个新开的线程放到线程池中去执行。上图中,给定初始值count = 3,调用await方法来判断count是否为0,若不为0,则将线程挂起等待,当count等于0之后,该线程才能继续执行。T2,T3,T4执行时,它们都调用了countdown(),每一次调用这个方法,都会对count减一。原创 2024-04-30 14:12:38 · 1752 阅读 · 0 评论 -
面试笔记——线程池
newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任 务,保证所有任务按照指定顺序(FIFO)执行。newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。workQueue:当没有空闲核心线程时,新来任务会加入到此队列排队,队列满会创建救急线程执行任务。原创 2024-04-29 22:53:30 · 1092 阅读 · 0 评论 -
面试笔记——线程安全
简而言之,它是一种资源竞争的情况,其中每个进程或线程都在等待其他资源的释放,而同时也不释放自己的资源,从而导致所有的进程或线程都陷入了僵局,无法继续执行下去。公平锁的效率往往没有非公平锁的效率高,在许多线程访问的情况下,公平锁表现出较低的吞吐量。在很多的情况下,在Java程序运行时,同步块中的代码都是不存在竞争的,不同的线程交替的执行同步块中的代码。如当state的状态还是0,此时多个线程请求该资源,则通过CAS设置state状态,保证操作的原子性,没有抢到资源的线程从尾部添加到FIFO队列中。原创 2024-04-29 11:27:28 · 1071 阅读 · 0 评论 -
面试笔记——多线程基础
操作系统中有一个组件叫做任务调度器,将cpu的时间片(windows下时间片最小约为 15 毫秒)分给不同的程序使用,只是由于cpu在线程间(时间片很短)的切换非常快,人类感觉是同时运行的。wait() ,wait(long) 和 sleep(long) 的效果都是让当前线程暂时放弃 CPU 的使用权,进入阻塞状态;t.join() 阻塞调用此方法的线程进入timed_waiting,直到线程t执行完成后,此线程再继续执行。一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给 CPU 执行。原创 2024-04-24 19:07:44 · 824 阅读 · 0 评论 -
面试笔记——Java集合篇
Arrays.asList转换list之后,如果修改了数组的内容,list会受影响,因为它的底层使用的Arrays类中的一个内部类ArrayList来构造的集合,在这个集合的构造器中,把我们传入的这个集合进行了包装而已,最终指向的都是。不过,二叉树并不要求每个节点都有两个子节点,有的节点只有左子节点,有的节点只有右子节点。二叉查找树要求,在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值。HashMap的数据结构: 底层使用hash表数据结构,即。原创 2024-03-26 19:27:46 · 918 阅读 · 0 评论 -
面试笔记——MyBatis(执行流程、延迟加载和缓存)
是一个持久层框架,用于简化Java 应用程序与数据库之间的交互过程。具体而言,它提供了一种将数据库操作映射到 Java 方法的方式,通过 XML 文件或注解配置 SQL 语句与 Java 方法的映射关系。使用 MyBatis,开发人员可以通过简单的配置文件或注解来管理 SQL 语句,而不需要直接编写 JDBC 代码。原创 2024-03-25 15:49:21 · 1180 阅读 · 0 评论 -
面试笔记——框架篇Spring系列(Spring、SpringMVC、SpringBoot)
由于一般在spring的bean的中都是注入无状态的对象,没有线程安全问题,如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例或者加锁来解决。Spring容器在进行实例化时,会将xml配置的的信息封装成一个BeanDefinition对象,Spring根据BeanDefinition来创建Bean对象,里面有很多的属性用来描述Bean。Spring bean并没有可变的状态(比如Service类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。原创 2024-03-25 13:57:56 · 1481 阅读 · 0 评论 -
面试笔记——MySQL(主从同步原理、分库分表)
具体的同步流程为:当主库的数据发生变化,会把操作语句写入到binlog的文件中;读取完成之后,就会把数据写入到从库的中继日志Relay log中;再由从库的SQLthread线程读取Relay log,并执行里面的命令;执行完成之后,主库与从库的数据就会保持一致。MySQL主从复制的核心就是二进制日志(BINLOG),它记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但不包括数据查询(SELECT、SHOW)语句。主从同步结构:主库负责写数据,从库负责读数据,如图——原创 2024-03-22 14:30:40 · 594 阅读 · 0 评论 -
面试笔记——MySQL(事务:事务特性、并发事务、事务隔离、Redo Log与Undo Log、MVCC)
这种方式也称为WAL。假设事务 A 在执行查询时读取了某一行数据,然后事务 B 修改了这行数据并提交了事务,之后事务 A 再次执行相同的查询,此时得到的数据就可能与之前不同,导致了不一致的读取结果。若数据还未完成同步,而服务器发生宕机,那么内存中的数据就会丢失,已经操作完成的数据(在缓存中)也会丢失,因此违背了事务的持久化的特性。假设有两个事务,事务 A 读取了事务 B 修改但尚未提交的数据,然后事务 B 回滚了修改,那么事务 A 所读取的数据就是不正确的,因为它读取到了未提交的、“脏”的数据。原创 2024-03-22 12:51:59 · 1375 阅读 · 0 评论 -
面试笔记——MySQL(优化篇:定位慢查询、SQL执行计划、索引、SQL优化)
因为,当在进行分页查询时,如果执行 limit 9000000,10 ,此时需要MySQL排序前9000010 记录,仅仅返回 9000000 - 9000010 的记录,其他记录丢弃,查询排序的代价非常大。是指一个索引包含了查询语句所需的所有列,从而使得查询可以直接从索引中获取所需的数据,而无需回表查询。覆盖索引通常用于查询语句的列与索引列完全匹配的情况。最左前缀法则(或最左前缀匹配)指的是当一个查询包含了多列的复合索引时,查询条件查询从索引的最左前列开始,并且不跳过索引中的列。原创 2024-03-21 16:20:01 · 1437 阅读 · 0 评论 -
面试笔记——Redis(集群方案:主从复制、哨兵模式和分片集群)
如图,若将老的master(左边的redis)强制降为Slave,此时这个Slave就会去新的master中去同步数据,将自己的数据清空,也因此丢掉了脑裂过程中(它还作为master)写入的数据。读写数据:根据key的有效部分计算哈希值,对16384取余(有效部分,如果key前面有大括号,大括号的内容就是有效部分,如果没有,则以key本身做为有效部分)余数做为插槽,寻找插槽所在的实例。每个部分的哨兵节点都会尝试选举新的主节点,导致整个集群中出现多个主节点,这将导致数据不一致和服务不可用。原创 2024-03-20 15:41:48 · 714 阅读 · 0 评论 -
面试笔记——Redis(分布式锁的使用场景及实现原理)
上图的流程为:首先,8080的线程1尝试获取分布锁,获取锁后,分布式锁中会添加记录“线程1”,证明该线程已经持有锁了,随后执行自己的业务代码;答:根据业务执行时间预估(但是该方式不太靠谱,万一出现抖动或网络卡顿,都会导致执行时间变慢,这个时间是不好控制的)或 采取给锁续期(创建一个新的线程用于监控,若业务执行时间较长时,就增加这个当前业务线程持有锁的时长——通过redisson实现)。此时,若又有一个新的应用获取到分布式锁,则出现了两个线程同时持有同一把锁的情况,丧失了锁的互斥性,有可能出现脏数据的现象。原创 2024-03-20 11:17:51 · 1240 阅读 · 0 评论 -
面试笔记——Redis(数据过期策略、数据淘汰策略)
可以按照不同的规则进行删除,这种删除规则就被称之为数据的删除策略(数据过期策略)——惰性删除、定期删除。当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。扫描缓存中的数据(从一定数量的数据库中取出一定数量的随机key进行检查),并删除那些已经过期的数据项。缺点 :对内存不友好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放。惰性删除+定期删除。原创 2024-03-19 19:49:10 · 506 阅读 · 0 评论 -
面试笔记——Redis(双写一致、持久化)
当有数据被写入数据库,会把数据库发生的变化记录到BINLOG(二进制日志)文件中(如DDL【数据定义语言】语句和DML【数据操纵语言】语句),但不包括数据查询语句(如,SELECT、SHOW)。因为是记录命令,AOF文件会比RDB文件大的多。:由于数据库一般采取的是主从模式,当主节点的数据发生改变时,需要一定的时间等待其他的从结点完成数据同步,因此需要延时删除缓存。在执行更新操作之前,先进行一次删除缓存操作(删除旧数据),等数据库修改之后,再进行一次删除缓存操作(确保删除旧数据),降低脏数据的出现。原创 2024-03-19 12:45:05 · 871 阅读 · 0 评论 -
面试笔记——Redis(缓存击穿、缓存雪崩)
流程如图:在该例子中,线程1发现数据的逻辑时间过期后,申请获取互斥锁,在申请成功后,重新创建一个线程——线程2用于更新缓存数据,但线程1不必等到线程2执行结束后再继续执行,而是获取缓存中的旧数据(没有到达物理过期时间,因此还可以获取该数据)继续执行;主要作用是监控 Redis 实例的健康状态,当主节点出现故障或不可用时,自动完成故障转移,并选择一个合适的从节点升级为新的主节点,以保证 Redis 服务的可用性,是Redis提供的一种高可用性解决方案。然后,更新逻辑过期时间,同时更新物理过期时间。原创 2024-03-18 19:37:18 · 1558 阅读 · 0 评论 -
面试笔记——Redis(使用场景、面临问题、缓存穿透)
这意味着在将数据加载到缓存中的同时,也对这些数据应用布隆过滤器的哈希函数,并将对应的比特位设置为1。因此,在正式使用之前,布隆过滤器已经包含了预先加载的数据集合,从而在后续的查询过程中,可以利用布隆过滤器先行判断一个元素是否可能存在于缓存中,以提高查询效率。因此,在使用布隆过滤器时,通常是在初始化时构建好布隆过滤器,然后对其进行查询操作,而不是对其进行频繁的更新操作。的数据时,缓存系统无法命中缓存,而每次请求都会直接访问底层存储系统,从而绕过了缓存系统,这种情况就称为缓存穿透。原创 2024-03-18 14:02:40 · 990 阅读 · 0 评论