8.moka一面
-
线程池的使用与原理:
-
实习业务中使用线程池:在实习中,我使用线程池来处理大量的异步任务,如数据处理、文件上传下载等,以提高系统的响应速度和吞吐量。
-
如何复用线程池:通过配置核心线程数和最大线程数,线程池可以在不销毁核心线程的情况下复用线程,从而减少线程创建和销毁的开销。
-
确保线程正常执行任务:通过实现
Runnable
或Callable
接口,并将任务提交给线程池执行。 -
线程池底层原理:线程池通过维护一个线程集合和一个任务队列(通常是阻塞队列)来工作。当任务提交时,线程池会根据当前线程数和任务队列的情况来决定是创建新线程还是复用已有线程。
-
为什么使用阻塞队列:阻塞队列可以有效地将任务的生产者和消费者分离,同时支持线程间的协作和资源的合理利用。
-
单线程优先级调节:在Java中,可以通过
Thread.setPriority()
方法调节线程的优先级,但实际效果依赖于操作系统的调度策略。 -
阻塞队列的作用:提供线程安全的任务队列,并支持阻塞操作,确保生产者和消费者之间的同步。
-
-
线程池相关问题:
-
任务超时解决:可以设置任务执行的超时时间,使用
Future
对象来取消或检查任务的状态。 -
CountDownLatch
操作:CountDownLatch
可以在任何地方调用countDown()
方法来减少计数,通常在线程完成任务后调用。它是局部的,可以在局部变量中使用。 -
红锁算法:Redis分布式锁的红锁算法通过多个Redis实例上的锁来实现分布式环境下的锁,确保在多个节点上锁的原子性。
-
-
Redis分布式锁与看门狗机制:
-
SETNX
原理:SETNX
(Set If Not Exists)是一个原子操作,如果键不存在,则设置键值对并返回1,否则返回0。 -
看门狗机制:用于自动续期锁的过期时间,防止任务未完成时锁过期。
-
-
订单操作一致性:保持订单操作一致性是为了确保数据的一致性和准确性,避免出现数据冲突和错误。
-
复用样式对象方案:可能使用的是享元模式(Flyweight Pattern),通过共享相同或相似的对象来减少内存使用。
-
架构设计问题:为了防止静态变量被修改,可以将其设置为私有并通过公共方法提供访问,或者使用枚举类型来定义常量。
-
MQ(消息队列)相关:
-
基础模型:生产者-消费者模型,生产者发送消息,消费者接收消息。
-
消息可靠性:通过消息确认机制、持久化存储、事务消息等手段保证消息的可靠性。
-
消息刷盘时机:通常在消息被确认消费后或在特定时间间隔后刷盘。
-
死信队列:用于处理无法正常消费的消息。
-
延迟队列:用于延迟处理消息。
-
-
Java数据类型与集合:
-
Java数据类型:基本数据类型(如int, float, double)和引用数据类型(如类、接口、数组)。
-
常见集合:
ArrayList
、LinkedList
、HashMap
、HashSet
等。 -
LinkedList
与ArrayList
效率:ArrayList
在随机访问上效率更高,LinkedList
在插入和删除操作上效率更高。
-
-
锁结构与JUC工具类:
-
锁结构:如
synchronized
、ReentrantLock
、ReadWriteLock
等。 -
JUC工具类:如
Semaphore
、CountDownLatch
、CyclicBarrier
、Exchanger
等。
-
-
线程安全性与锁:
-
线程安全性:当多个线程访问同一资源时,不会出现数据不一致或错误的情况。
-
线程安全问题防范:使用同步机制、锁、原子变量等。
-
synchronized
使用:通常锁住共享资源或方法。 -
锁失效场景:如锁定的对象发生变化。
-
ReentrantLock
底层数据结构与原理:基于AQS(AbstractQueuedSynchronizer)实现,通过一个状态变量来控制锁的获取和释放。
-
锁的深入讨论:
-
公平锁与非公平锁:
ReentrantLock
的公平锁和非公平锁通过构造函数中的参数来区分。公平锁保证等待时间最长的线程先获取锁,非公平锁则允许新来的线程抢占锁。 -
锁竞争优先级:在非公平锁中,新来的线程可能会抢占已经在等待的线程,而在公平锁中,则是先来先服务的原则。
-
其他锁:除了
ReentrantLock
,还有ReentrantReadWriteLock
、StampedLock
等。 -
信号量保证线程安全:
Semaphore
可以用来限制对某个资源的访问数量,从而在一定程度上保证线程安全。
-
-
MySQL的隔离级别与索引:
-
隔离级别:MySQL支持以下隔离级别:
-
READ UNCOMMITTED
-
READ COMMITTED
-
REPEATABLE READ(默认隔离级别)
-
SERIALIZABLE
-
-
索引创建条件:索引通常在以下情况下创建:
-
经常用于查询的列
-
经常用于排序或分组的列
-
经常用于连接的列
-
-
索引创建原则:选择区分度高的列,避免过度索引,考虑索引维护的成本等。
-
联合索引失效:如果查询条件不满足联合索引的最左前缀原则,则可能导致索引失效。
-
索引下推:索引下推(Index Condition Pushdown)是MySQL的一种优化技术,它将部分过滤条件下推到存储引擎层,减少数据访问量。
-
-
线程安全与锁的深入讨论:
-
线程锁住的对象变化:如果锁住的对象发生变化,可能会导致锁失效或出现线程安全问题。通常应该锁住不会变化的对象,或者使用不可变对象。
-
如果不是锁住对象实例:可以考虑锁住一个特定的锁对象,比如
Lock
实例,或者使用类锁(Class
对象锁)。 -
ReentrantLock
的底层数据结构与原理:ReentrantLock
底层依赖于AbstractQueuedSynchronizer
(AQS),它使用一个int类型的变量来表示同步状态,并通过队列来管理等待的线程。
-
-
JUC工具类与线程安全:
-
JUC工具类:Java并发工具类,如
Semaphore
、CountDownLatch
、CyclicBarrier
、Exchanger
等,提供了丰富的并发编程工具。 -
线程安全:当多个线程访问同一个对象时,如果不需要考虑线程间的同步问题,那么这个对象就是线程安全的。
-
-
synchronized
的深入讨论:-
synchronized
锁住的是什么:synchronized
可以锁住代码块或方法,实际上锁住的是对象监视器(monitor),对于同步方法,锁的是当前对象实例;对于静态同步方法,锁的是类的Class
对象。 -
锁住对象实例的变化:如果对象实例在锁住期间发生变化,可能会导致锁的粒度不正确或锁失效。
-
使用
ReentrantLock
:ReentrantLock
提供了比synchronized
更灵活的锁操作,可以显式地获取和释放锁,还可以实现公平锁等。
-
MySQL索引与性能优化:
-
索引失效的情况:除了不满足最左前缀原则外,以下情况也可能导致索引失效:
-
使用函数或计算表达式导致索引列无法直接使用。
-
在WHERE子句中使用不等于(
<>
)或IS NULL可能会导致索引失效。 -
使用LIKE操作符时,如果通配符不在字符串的开头,例如
LIKE '%value'
,可能会导致索引失效。
-
-
索引优化的原则:
-
选择合适的索引类型,如BTREE或HASH。
-
避免过多的索引,因为每个索引都会增加写操作的成本。
-
定期分析查询日志和执行计划,优化慢查询。
-
-
-
线程锁的深入讨论:
-
锁的粒度:选择合适的锁粒度是重要的,过粗的锁可能导致不必要的阻塞,而过细的锁可能导致复杂的代码逻辑和性能开销。
-
锁竞争和线程饥饿:在高并发环境下,锁竞争可能导致某些线程长时间无法获取锁,造成线程饥饿。
-
锁的公平性和非公平性:公平锁虽然可以避免线程饥饿,但可能会降低系统的吞吐量;非公平锁可以提高吞吐量,但可能导致某些线程长时间等待。
-
-
Java集合类的深入讨论:
-
LinkedList
和ArrayList
的选择:-
ArrayList
适合随机访问操作,因为它的时间复杂度为O(1)。 -
LinkedList
适合插入和删除操作,因为它的时间复杂度为O(1)。
-
-
Java中复用链表的数据结构:除了
LinkedList
,还有LinkedHashMap
和LinkedHashSet
等,它们在哈希表的基础上增加了链表结构,以保持元素的插入顺序。
-
-
数据结构与算法的深入讨论:
-
支持二分查找的链表:理论上,链表不支持高效的二分查找,因为链表不支持随机访问。但是,可以通过平衡二叉搜索树(如AVL树或红黑树)来实现类似的功能,这些树结构可以在O(log n)时间内进行查找、插入和删除操作。
-
-
锁结构与JUC工具类的深入讨论:
-
JUC工具类
Semaphore
:Semaphore
可以用来实现资源池,限制同时访问资源的线程数,从而保证线程安全。 -
CountDownLatch
和CyclicBarrier
:这两个类可以用于线程间的协作,CountDownLatch
用于等待多个线程完成任务,而CyclicBarrier
则用于多个线程在某个点上同步。
-
-
线程安全性的深入讨论:
-
线程安全性问题的防范:除了使用锁,还可以通过以下方式来防范线程安全性问题:
-
使用原子变量,如
AtomicInteger
、AtomicReference
等。 -
使用线程安全集合类,如
ConcurrentHashMap
、CopyOnWriteArrayList
等。 -
使用不可变对象,如
String
、Integer
等。
-
-
-
synchronized
的深入讨论:synchronized
锁住的对象实例变化:如果对象实例在锁住期间被修改,可能会导致锁的粒度不正确或锁失效。为了避免这种情况,可以锁住一个不可变的对象或使用final
关键字确保对象引用不会改变。
-
ReentrantLock
的深入讨论:-
ReentrantLock
的公平锁和非公平锁的实现:公平锁在tryAcquire
方法中会检查队列中是否有等待的线程,而非公平锁则可能会直接尝试获取锁。 -
锁竞争的优先级:在非公平锁中,新来的线程可能会抢占已经在等待的线程,这取决于线程调度和锁的实现。
-
-
-
八股文分类整理 老哥们点点赞,订阅一下,纯福利做数据。