java面试题整理

1、线程池状态:

一、状态类型
RUNNING(运行)
线程池被创建后处于运行状态。
接受新任务,并处理排队中的任务。
SHUTDOWN(关闭)
调用shutdown()方法后,线程池进入关闭状态。
不再接受新任务,但会继续处理已经提交到任务队列中的任务。
STOP(停止)
调用shutdownNow()方法后,线程池进入停止状态。
不再接受新任务,并尝试停止所有正在执行的任务,同时会忽略任务队列中等待的任务。
TIDYING(整理)
当线程池中的所有任务都已经终止,工作线程数量为零时,线程池会进入整理状态。
在这个状态下,线程池会进行一些清理工作,例如释放资源等。
TERMINATED(终止)
线程池执行完terminated()方法后进入此状态。
表示线程池已经完全终止,所有任务已经完成,并且所有线程都已经退出。线程池进入此状态后,将不能再恢复。
二、状态转换
线程池的状态转换主要通过调用shutdown()和shutdownNow()方法来实现,具体转换路径如下:

RUNNING → SHUTDOWN:调用shutdown()方法后,线程池从运行状态切换到关闭状态。
RUNNING → STOP:调用shutdownNow()方法后,线程池从运行状态切换到停止状态。
SHUTDOWN/STOP → TIDYING:当线程池中的所有任务都已经完成(对于SHUTDOWN状态)或被中断(对于STOP状态),且工作线程数量为零时,线程池会从关闭或停止状态切换到整理状态。
TIDYING → TERMINATED:线程池执行完terminated()方法后,从整理状态切换到终止状态。

2、线程池的执行过程

Java中的线程池主要用于管理线程组及其运行状态,以便Java虚拟机(JVM)更好地利用CPU资源。Java线程池的执行过程涉及多个组件和步骤,以下是详细的解释:

一、线程池的主要组件
Java中的线程池主要由java.util.concurrent.ThreadPoolExecutor类实现,其核心组件包括:

工作队列:如ArrayBlockingQueue,用于存储等待执行的任务。
线程池:包含核心线程和非核心线程。核心线程是线程池即使在空闲时也会维持的最小线程数量,非核心线程则是根据需求动态创建的线程。
拒绝策略:当线程池和任务队列都无法处理新的任务时,会采用拒绝策略来处理被拒绝的任务。Java提供了几种内置的拒绝策略,如AbortPolicy(默认,直接抛出异常)、CallerRunsPolicy(调用者线程执行任务)、DiscardPolicy(默默丢弃任务)和DiscardOldestPolicy(移除最旧的任务)。
二、线程池的执行过程
线程池的执行过程主要分为以下四个阶段:

任务提交阶段:当调用ThreadPoolExecutor.execute(Runnable task)方法向线程池提交一个任务时,线程池内部会进行一系列判断和处理。
如果当前线程池中的线程数量小于核心线程数,线程池会创建一个新的工作线程来执行这个任务,并将其初始化,然后调用线程的start()方法启动它。
如果当前线程数不小于核心线程数,线程池会尝试将任务添加到工作队列中。如果队列已满,则会进入下一步处理。
如果工作队列已满,线程池会检查当前线程数是否小于最大线程数。如果小于最大线程数,线程池会创建一个新的线程来处理这个任务;否则,就需要采取拒绝策略来处理无法接受的新任务。
任务执行阶段:每个工作线程都在一个无限循环中运行,它们会不断从工作队列中获取任务并执行。获取任务的过程通常涉及阻塞等待(如使用BlockingQueue的take()方法)。一旦获取到任务,线程就会执行Runnable.run()方法,完成任务的实际工作。
线程扩展阶段:当线程池需要创建新线程来处理任务时,会调用ThreadFactory.newThread(Runnable r)方法创建新线程。默认的线程工厂会为每个线程赋予有意义的名字,比如“pool-1-thread-1”。
线程收缩阶段:线程池中的非核心线程在完成任务后不会立即销毁,而是进入保持存活状态。只有当这些线程在指定时间内(keepAliveTime参数指定)没有接收到新的任务,并且线程池中的线程数大于核心线程数时,这些空闲线程才会被终止。
三、线程池的优势
线程池提供了几个显著的优点:

资源管理:通过重用线程,线程池减少了线程创建和销毁的开销。
性能:线程池管理固定数量的线程,防止系统因线程创建过多而受到影响。
可伸缩性:线程池可以处理大量任务,所有线程如果都忙则排队,确保任务被有效地处理。
四、线程池的动态调整
在实际应用中,线程池的大小和配置可能需要根据任务的负载和性质进行动态调整。ThreadPoolExecutor提供了灵活的机制来动态调整线程池的核心线程数和最大线程数。开发者可以根据系统负载、任务队列长度等因素来动态调整线程池的大小,以实现最佳的性能和资源利用率。

综上所述,Java线程池的执行过程是一个涉及多个组件和步骤的复杂过程。通过合理配置和动态调整线程池,开发者可以确保系统在高并发环境下的高效运行,并避免资源过载。

3、kafka为啥这么快

 4、kafka如何保证消息不丢失

 producer的ack确认机制,kafka的数据持久化,消费组手动提交偏移量。

 

5、kafka如何顺序消费

同一个partion分区

6、kafka选举过程:

 7、kafka如何提高吞吐量

增加分区

8、redis为啥这么快

 mysql的别名问题

where不能用别名进行查询,因为where执行靠前

sql执行过程

 

 mysql性能系统参数查询:

 线程状态:

在Java中,线程的状态是一个重要的概念,它描述了线程在其生命周期中的不同阶段。以下是Java线程的主要状态:

1. 新建状态(New)
线程对象被创建后,就进入了新建状态。此时,线程对象只是一个普通的Java对象,还没有被分配操作系统资源,也没有调用start()方法启动线程。
示例代码:Thread thread = new Thread(); 此时的thread线程处于新建状态。
2. 就绪状态(Runnable)
也被称为“可执行状态”。当调用了线程对象的start()方法后,线程就进入了就绪状态。
在这个状态下,线程已经被加入到线程调度器的就绪队列中,等待被分配CPU时间片来执行任务。处于就绪状态的线程,随时可能被CPU调度执行。
示例代码:thread.start(); 此时thread线程进入就绪状态。
3. 运行状态(Running)
当线程获得了CPU时间片,开始执行任务时,它处于运行状态。
需要注意的是,线程只能从就绪状态进入到运行状态。
4. 阻塞状态(Blocked)
线程进入阻塞状态通常是因为某些原因导致了线程无法继续执行。常见的阻塞原因包括等待I/O操作完成、等待获取锁(如synchronized锁)等。
线程在阻塞状态时不会消耗CPU资源,直到阻塞的原因消失后,线程会重新进入就绪状态等待执行。
阻塞状态可以细分为以下几种情况:
等待阻塞:通过调用线程的wait()方法,让线程等待某工作的完成。
同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程所占用)时,会进入同步阻塞状态。
其他阻塞:通过调用线程的sleep()或join()方法,或发出I/O请求时,线程会进入阻塞状态。当sleep()状态超时、join()等待线程终止或超时、或I/O处理完毕时,线程重新转入就绪状态。
5. 等待状态(Waiting)
线程进入等待状态是因为它在某个对象上等待。例如,线程调用了Object.wait()方法或Thread.join()方法时会进入等待状态。
在等待状态下,线程会释放掉它所持有的锁(如果有的话),直到其他线程通过调用Object.notify()或Object.notifyAll()等方法来唤醒它。
6. 定时等待状态(Timed Waiting)
和等待状态类似,但是在这个状态下,线程在等待一段时间或者等待某个条件满足之前会超时返回。
例如,调用Thread.sleep(long millis)方法或Object.wait(long timeout)方法时会使线程进入定时等待状态。
当指定的等待时间超时或等待条件满足时,线程会重新进入就绪状态。
7. 终止状态(Terminated)
线程处于终止状态表示它已经执行完任务或者被提前中断。
当线程的run()方法执行完毕或者调用了Thread.interrupt()方法中断线程时,线程会进入终止状态。
综上所述,Java线程的状态包括新建状态、就绪状态、运行状态、阻塞状态、等待状态、定时等待状态和终止状态。这些状态之间的转换反映了线程在其生命周期中的不同阶段和状态变化。理解这些状态及其转换对于编写高效、可靠的多线程程序至关重要。

 java内存分配

jvm有jit优化机制,对象可能会进行标量替换,可能在栈上分配,如果关闭jit编译技术,对象会在堆上分配

 垃圾回收器算法:标记清除,产生碎片,标记复制,浪费空间 标记整理 时间长

对象如何计算是否引用,引用计数器,可达性分析算法

 

posted @ 2025-03-11 14:21  刘百会  阅读(21)  评论(0)    收藏  举报