type
status
date
slug
summary
tags
category
icon
password
comment
update_time
Sep 28, 2024 10:49 AM
create_time
Sep 13, 2024 01:50 AM
去面试了一个天使轮的公司,八股文基本没准备,记录一下
线程池的原理
Java 线程池(
ThreadPoolExecutor
)的实现原理基于一个核心思想:基于池化思想 复用线程 来避免频繁的线程创建和销毁的开销,提高系统的响应速度和资源利用率。线程池在内部实际上构建了一个生产者消费者模型,将线程和任务两者解耦,并不直接关联,从而良好的缓冲任务,复用线程。


核心组件
- 核心线程数(corePoolSize):线程池在保持的最小线程数量,即使线程处于空闲状态也不会被回收。
- 最大线程数(maximumPoolSize):线程池可以容纳的最大线程数,超出这个数量的线程将被拒绝。
- 任务队列(BlockingQueue):用于存放等待执行的任务。当所有核心线程都在工作时,新的任务会被放入队列中等待。
- 线程工厂(ThreadFactory):用于创建新线程的工厂,允许为每个线程设置名字、优先级等属性。
- 拒绝策略(RejectedExecutionHandler):当任务无法被执行(例如任务队列满了且线程数已经达到最大)时的处理方式。
- 存活时间(keepAliveTime):当线程池中的线程数量超过核心线程数时,多余的空闲线程等待新任务的时间,超时后将被终止。
线程池优势
- 提高性能:通过减少线程创建和销毁的开销来提高性能。
- 更好的资源管理:通过控制最大线程数和任务队列来有效管理系统资源。
- 任务调度:支持任务的定时执行和周期执行。
线程数如何估算
合理设置线程池大小的主要目标是最大化利用系统资源(特别是 CPU 和内存),减少任务执行的延迟,并避免系统过载。
CPU 密集型任务
设置原则:对于 CPU 密集型任务,线程数的设置应尽量接近 CPU 的核心数,因为过多的线程会导致线程频繁上下文切换,增加开销,反而降低系统的性能。
解释:
CPU 核心数
是线程池中能够同时执行的线程的上限,因为 CPU 资源是有限的,过多的线程无法并发执行。
+1
是为了应对意外的任务阻塞或线程上下文切换开销,使得系统可以继续高效运行。
I/O 密集型任务
设置原则:对于 I/O 密集型任务,可以创建比 CPU 核心数更多的线程,因为大多数线程在等待 I/O 操作时,CPU 实际上是空闲的。
解释:
(线程等待时间 + 线程 CPU 时间) / 线程 CPU 时间
是任务的等待与计算时间的比率。这个比率越高,说明任务在等待的时间越长,意味着更多的线程可以有效利用 CPU。美团的线程池文章
说出 MySQL 中 InnoDB 的设计原理
MySQL5.5 版本后,默认使用 InnoDB 存储引擎,它擅长事务处理,具有崩溃恢复性特性!
Redis 的使用场景,在项目中和登录功能结合起到了什么作用
Redis 在登录功能中的使用场景:
- Session 管理
- Spring Boot 项目中的登录功能需要跟踪用户的会话(Session)。通常,用户的 Session 存储在服务器内存中,但如果服务器出现故障,Session 数据可能丢失。
- Redis 提供了一种分布式 Session 解决方案。通过将 Session 存储在 Redis 中,多个服务器节点可以共享 Session 数据,实现集群环境下的 Session 统一管理,保证了高可用性和持久性。
- Token 管理
- 在基于 Token 的身份验证中(如 JWT 或 OAuth2),Redis 可以用来存储已生成的 Token 信息。通过缓存 Token 和用户信息,减少频繁的数据库查询。
- 当用户登出时,系统可以将 Token 置于 Redis 的黑名单中,防止已注销的 Token 再次使用。
- 登录限制和防暴力破解
- Redis 可用于限制用户的登录尝试次数,防止暴力破解攻击。例如,用户登录失败后,记录该用户的 IP 地址或用户名,并将登录失败次数存入 Redis。如果失败次数超出设定值,可以暂时禁止该用户进行进一步的登录尝试。
- Redis 具有 TTL(过期时间)机制,适合这种短时间内频繁请求的场景。
- 单点登录(SSO)
- 在多个系统之间实现单点登录时,Redis 可以用于存储和共享用户的登录状态。每次用户访问不同系统时,都可以通过 Redis 查询用户的登录状态,避免重复登录。
- 验证码校验
- 登录时的图形验证码或短信验证码可以存储在 Redis 中,设置短期有效期(TTL),并通过 Redis 校验用户提交的验证码是否正确。
在项目中结合登录的具体作用:
- 性能优化
- Redis 作为内存型数据库,读取和写入速度非常快。将用户的登录状态、Session、Token、验证码等信息放入 Redis,避免每次都访问数据库,从而提高了系统性能和响应速度。
- 高可用性与扩展性
- Redis 支持集群,具备高可用和可扩展的特性。在分布式系统中,登录状态和会话信息可以通过 Redis 实现多节点共享,确保登录功能的稳定性和一致性。
- 降低数据库压力
- 对于频繁查询的登录相关数据(如 Token、用户 Session、验证码等),Redis 可以充当缓存层,减少对后端数据库的访问压力,尤其在高并发场景下,提升系统的整体性能。