2022-03-23 03:50:41
虾皮春招全流程面经主要涵盖技术一面、技术二面和HR面三个环节,各环节面试内容及流程如下:
技术一面Redis相关
常用数据类型:包括字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Zset)等。
Zset底层原理:Zset的底层数据结构可能是ziplist或skiplist。当元素数量较少且元素长度较小时使用ziplist,以节省内存;当元素数量较多或元素长度较大时使用skiplist,以提高查询效率。
跳表(Skiplist)原理:是一种有序的数据结构,它通过在每个节点中维护多个指向其他节点的指针,从而形成多层链表结构,使得查询操作可以在对数时间内完成。
缓存穿透、雪崩、击穿问题:缓存穿透是指查询一个不存在的数据,由于缓存中没有,导致每次请求都直接访问数据库;缓存雪崩是指大量缓存同时失效,导致大量请求直接访问数据库;缓存击穿是指一个热点数据缓存过期时,大量并发请求同时访问该数据,导致数据库压力过大。
持久化机制:包括RDB(Redis Database)和AOF(Append Only File)两种方式。RDB是定时将内存中的数据快照保存到磁盘;AOF是将每次对Redis的操作以追加的方式写入文件。
分布式锁Redisson工作原理:基于Redis实现分布式锁,通过设置锁的键和值,以及过期时间,来保证锁的唯一性和自动释放。
集群方案及哨兵模式:集群方案有主从复制、哨兵模式、集群模式等。哨兵模式的作用是监控主从服务器的状态,当主服务器出现故障时,自动将某个从服务器升级为主服务器,保证系统的可用性。
为什么用来做缓存不做数据库:Redis是内存数据库,数据存储在内存中,读写速度快,但内存容量有限,且数据容易丢失;而数据库通常将数据存储在磁盘上,容量大,数据持久化,但读写速度相对较慢。
为什么快:基于内存操作、单线程模型避免了多线程的上下文切换开销、使用高效的数据结构等。
与MySQL数据同步(双写一致性):可以通过消息队列、定时任务等方式实现。
数据库相关
索引数据结构及用B+树原因:数据库索引通常使用B+树数据结构。B+树具有多路平衡查找树的特性,查询效率高;且数据都存储在叶子节点,便于范围查询。跳表虽然查询效率也较高,但在范围查询和磁盘存储方面不如B+树。
MySQL索引及失效情况:常见的索引类型有普通索引、唯一索引、主键索引、复合索引等。索引失效的情况包括使用函数操作索引列、使用不等于操作符、使用OR条件连接非索引列等。
SQL优化:可以通过合理使用索引、避免全表扫描、优化查询语句等方式进行优化。
事务隔离级别及问题解决:事务隔离级别有读未提交、读已提交、可重复读、串行化。默认级别通常是可重复读。脏读是指一个事务读取了另一个未提交事务修改的数据;不可重复读是指一个事务内多次读取同一数据,结果不同;幻读是指一个事务内多次查询,结果集的记录数不同。可以通过设置事务隔离级别、使用锁等方式解决这些问题。
其他
Setnx底层原理:Setnx是Redis的一个命令,用于设置键值对,如果键不存在则设置成功,返回1;如果键已存在则设置失败,返回0。其底层原理是基于Redis的字符串类型和哈希表实现。
垃圾回收算法:常见的垃圾回收算法有标记 - 清除算法、标记 - 整理算法、复制算法、分代收集算法等。
分布式事务:是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上,保证多个节点上的事务操作的原子性、一致性、隔离性和持久性。
TCP和UDP区别:TCP是面向连接的、可靠的传输协议,提供流量控制和拥塞控制;UDP是无连接的、不可靠的传输协议,不提供流量控制和拥塞控制。
TCP 4次挥手出现TIME - WAIT的原因:为了保证最后一个ACK报文能够到达对方,让对方有足够的时间重新发送FIN报文,以及确保本次连接的所有报文都从网络中消失,避免新旧连接混淆。
HTTPS及安全保证:HTTPS是在HTTP的基础上加入了SSL/TLS协议,通过数字证书、加密算法等方式保证数据传输的安全性。
DNS域名解析全过程:包括递归查询和迭代查询两种方式,从本地DNS服务器开始,逐步向上查询,直到找到对应的IP地址。
JVM相关
JVM组成:包括类加载子系统、运行时数据区、执行引擎、本地方法接口等。
运行时数据区组成及作用:由方法区、堆、虚拟机栈、本地方法栈、程序计数器组成。方法区存储类信息、常量、静态变量等;堆存储对象实例;虚拟机栈存储方法调用的局部变量表、操作数栈等;本地方法栈为本地方法服务;程序计数器记录线程执行的字节码行号。
Java对象从新生代转移到老年代:经过多次Minor GC后,存活的对象会从新生代转移到老年代。
JVM垃圾回收器:常见的有Serial、Parallel Scavenge、Parallel Old、CMS、G1等。
Java并发相关
Volatile作用及可见性保证:Volatile保证变量的可见性和有序性,通过内存屏障和禁止指令重排序来保证可见性。
线程池处理任务流程:线程池先判断核心线程数是否已满,若未满则创建新线程处理任务;若已满则将任务放入工作队列;若工作队列已满,则判断线程数是否达到最大线程数,若未达到则创建新线程处理任务,若已达到则执行拒绝策略。
数据库相关
数据库3大范式:第一范式要求字段不可再分;第二范式要求非主键字段完全依赖于主键;第三范式要求非主键字段不依赖于其他非主键字段。
Mysql主从复制原理:主服务器将数据更改记录到二进制日志,从服务器的I/O线程从主服务器获取二进制日志并写入中继日志,从服务器的SQL线程从中继日志读取并执行日志中的SQL语句,实现数据同步。
HashMap底层实现及选红黑树原因:HashMap底层使用数组 + 链表 + 红黑树实现。当链表长度超过阈值时,将链表转换为红黑树,以提高查询效率。
ConcurrentHashMap线程安全实现方式:通过分段锁(Java 7)或CAS + synchronized(Java 8)的方式保证线程安全。
网络相关
TCP和UDP区别及应用场景:TCP适用于对可靠性要求高的场景,如文件传输、网页浏览等;UDP适用于对实时性要求高、允许少量丢包的场景,如视频直播、在线游戏等。
UDP实现可靠传输:可以通过添加确认机制、重传机制、流量控制等方式实现。
IO多路复用:是一种同时监控多个文件描述符的I/O操作的技术,通过一个线程管理多个I/O通道,提高系统的并发处理能力。
进程、线程和协程
概念及实际例子:进程是资源分配的基本单位,线程是CPU调度的基本单位,协程是一种用户态的轻量级线程。例如,一个浏览器可以是一个进程,浏览器中的多个标签页可以是不同的线程,而协程可以用于实现异步编程。
虚拟线程:Java 19引入的虚拟线程,是一种轻量级的线程,由JVM管理,而不是操作系统,可以提高并发处理的效率。