虾皮 Java后端开发一面面经
面试时间一个小时。
- Java中的锁机制,什么是可重入锁
- 主要包括synchronized关键字、Lock接口及其实现类(如ReentrantLock)、原子类(如AtomicInteger)、volatile关键字等。可重入锁是指同一个线程在外层方法获取锁时,再进入该线程的内层方法会自动获取锁,不会因为之前已经获取过还没释放而阻塞。Java中的ReentrantLock和synchronized都是可重入锁。
- AQS(AbstractQueuedSynchronizer)
- AQS是Java并发包中的核心基础组件,用于构建锁或者其他同步组件。它使用一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。
- Redis相关数据结构,为什么每种数据类型一般都有两种数据结构
- Redis的主要数据结构包括String、List、Hash、Set和Sorted Set。每种数据类型一般都有两种数据结构的原因是为了在空间和时间之间取得平衡。
- JVM相关内存结构,GC
- JVM内存结构包括堆(年轻代和老年代)、方法区、程序计数器、虚拟机栈和本地方法栈。垃圾回收算法有标记-清除算法、复制算法、标记-整理算法和分代收集算法。
- HashMap底层原理
- HashMap的底层数据结构是数组+链表+红黑树(JDK 1.8及以后)。主要属性包括存储数据的数组、实际存储的键值对数量、扩容阈值和负载因子。
- MySQL索引类型,索引失效,覆盖索引,hash索引
- MySQL索引类型包括B+树索引(默认)、Hash索引和全文索引。索引失效的情况有使用!=或<>操作符、使用函数或表达式、类型隐式转换、使用OR连接条件、like以%开头、不满足最左前缀原则等。
- Spring IOC AOP原理,循环依赖解决
- IOC的核心是BeanFactory和ApplicationContext,通过反射机制实例化bean并建立bean之间的依赖关系。AOP的核心是ProxyFactory,通过织入切面来实现功能的统一维护。Spring通过三级缓存解决循环依赖。
- MyBatis相关,#和$区别
- {}是预编译处理,会将参数替换为?;${}是字符串替换,直接将参数值拼接到SQL中。#{}可以防止SQL注入,而${}不能防止SQL注入。
- 线程池相关,流程,拒绝策略,如何设计线程池最大线程数和核心线程数
- 线程池执行流程包括创建新线程处理请求、将请求加入队列、创建新线程处理请求、任务被拒绝等。拒绝策略有AbortPolicy、DiscardPolicy、DiscardOldestPolicy和CallerRunsPolicy。设计线程池最大线程数和核心线程数时,CPU密集型任务的线程数为CPU核心数+1,IO密集型任务的线程数为CPU核心数*(1+平均等待时间/平均工作时间)。
- HashMap和ConcurrentHashMapHashMap是非线程安全的,允许null键和null值。ConcurrentHashMap是线程安全的,不允许null键和null值,JDK 1.8使用CAS+Synchronized实现。
- 红黑树,二叉查找树,红黑树高度差二叉查找树的左子树所有节点的值均小于根节点的值,右子树所有节点的值均大于根节点的值。红黑树的每个节点要么是红色,要么是黑色,根节点是黑色,每个叶子节点是黑色。
- MySQL索引MySQL索引类型包括普通索引、唯一索引、主键索引、联合/组合索引和全文索引。B+树索引的特点是所有数据都存储在叶子节点,叶子节点形成一个单向链表,非叶子节点只存储键值信息。
- 如何判断链表有环,如何判断树是二叉查找树判断链表是否有环可以使用快慢指针法或哈希表法。判断树是否为二叉搜索树可以使用中序遍历法或递归法。
- Redis分布式锁Redis分布式锁的实现原理包括使用SETNX命令设置一个键值对、删除该键值对、设置键的过期时间等。实现细节包括使用Lua脚本保证加锁操作的原子性、使用唯一标识符防止误删其他客户端的锁、考虑Redis主从复制的延迟问题等。
- 限流算法限流算法包括计数器算法、滑动窗口、令牌桶算法和漏桶算法。