保存成功
订阅成功
保存失败,请重试
提交成功
Limynl

Limynl

Java高级工程师
高级工程师,多年互联网从业及架构经验,专注于Java领域技术栈,擅长阅读常见开源项目源码,包括但不限于JDK源码、Spring、SpringBoot、Dubbo等。...更多
创作文章7

面试指南:深度剖析线程池

线程池作为面试的网红题之一,对于一般的考察点就是简单说说线程池的常见参数、以及线程池工作流程,或者说说线上各个参数的选择等,其实这样回答的话,很难在众多的候选人中脱颖而出,很难给面试官留下深刻映象。 如果对线程池的原理理解不是很深刻的话,可以移步看看上篇文章 [《手写线程池,全面了解 JDK 线程池实现原理》](https://gitbook.cn/m/mazi/activity/5f5dd38d8351d121c278df55),对本篇文章的理解将会有很大帮助。 本文将会从线程池的深度与广度全面剖析,让你成为面试官眼中那个最亮的仔,具体将会从如下问题着手分析: - 源码层面线程池执行流程 - 线程池状态流转过程 - 线程池如何实现线程复用 - 线程池中异常处理方式 - 线程池的 feature 模式 - submit 获取执行结果的原理 - CompleteService 使用及原理 - 如何监控线程池线程数与任务数 - 阻塞队列原理 - 高效选取阻塞队列 - 自定义阻塞队列实现吞吐量优先 - 生产上如何选取拒绝策略以及自定义 - 生产上核心线程数、最大线程数设置 - 任务积压、任务丢失处理方案 - 如何优雅关闭线程池 - 场景题:给一定参数条件,分析线程池运行流程
面试
89 订阅

手把手实现雪花算法 SnowFlake

随着服务化的流行,服务拆分越来越精细,一个业务拆分成多个库经常发生,但是如果我们还是依赖传统的数据库自增主键,或者单体的自增主键,将无法满足需求。因此分布式 ID 应运而生,分布式 ID 能够快速稳定生成唯一的主键,生成 ID 时不依赖于数据库,完全在内存生成,高性能高可用。 常见分布式 ID 生成方式有: - 雪花算法 - 数据库号段自增模式 - UUID 方式 - Redis 方式 - Zookeeper 方式 本文将分享雪花算法,相信很多人都使用过雪花算法,但是对于雪花算法的生成很多人都是一知半解,究其原因其实就是对**位运算的知识**掌握不够,因此本文将会手把手实现雪花算法,对每一行代码负责。并且针对雪花算法的时钟回拨问题,提供多种解决方案。实现一个高性能高可用生产级的雪花算法。
算法
102 订阅

接口重试机制的最佳实践

随着微服务的盛行,重试机制为系统的高可用做出了巨大贡献,在微服务治理框架中,通常都有自己的重试与超时配置。但是在我们后端业务系统可能会出现接口调用失败、网络拥塞超时、任务执行失败、系统错误等异常情况,我们需要实现业务的重试机制。 对于业务系统实现重试机制,常见的重试方案有: - AOP+注解:在需要添加重试的方法上添加一个用于重试的自定义注解,然后在切面中实现重试的逻辑,主要的配置参数则根据注解中的选项来初始化 - 消息总线方式:在需要重试的方法中,发送一个消息,并将业务逻辑作为回调方法传入;由一个订阅了重试消息的 consumer 来执行重试的业务逻辑 - spring-retry:使用模板方法模式,通过AOP机制来实现对业务代码的重试”入侵“ - guava-retrying:是一个线程安全的 Java 重试类库,提供了一种通用方法去处理任意需要重试的代码,可以方便灵活地控制重试次数、重试时机、重试频率、停止时机等,并具有异常处理功能。 在本场 Chat 中,将会涉及如下内容: - 手写基于 AOP+ 注解的重试方式 - 剖析 spring-retry 工具实现重试机制的内部原理 - guava-retrying 框架源码解析 - 解读应用命令设计模式解耦正常和重试逻辑
微服务
177 订阅

责任链模式+脚本引擎实战

责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某个节点处理完了就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。 责任链常见应用场景有: - 同一请求需要处理多个对象,但具体需要处理哪些请求在运行时动态决定 - 例如 OA 系统中的流程审批,不同流程对应不同的处理对象 对于责任链的实现形式,常见的有: - 节点控制模式:每个节点自由控制是否继续往下传递链的进度,类似于 Netty 中的责任链模式 - 外部调用方式:通过外部调用的方式对链的各个节点调用进行控制,从而实现链的各个节点之间的切换 因此通过责任链模式我们将对系统中各个处理对象**划分边界**,各个对象就是一个处理阶段,通过**自由组合**不同阶段能够快速响应业务需求变化。 上面提到自由组合处理对象,传统的方式就是在代码中实现规定好各个处理对象的顺序,这种方式不能做到对需求的即时响应。因此我们使用阿里开源的 QLExpress 脚本引擎,能够实现动态替换、快速组装各个处理对象。同时基于 QLExpress 的强大,对于处理对象的配置,业务人员也能够简便而不失灵活的进行配置。 在这篇 Chat 中,将会根据实际的业务场景进行提炼,实现一套通用责任链模式进行业务解耦,配合脚本引擎快速响应业务。
严选设计模式
231 订阅

面试指南:高并发限流姿势详解

在微服务复杂拓扑的情况下,限流是保障服务弹性和拓扑健壮的重中之重。限流是限制系统的输入和输出流量,以达到保护系统的目的,限流主要作用就是当高并发或者瞬时高并发时,为了保证系统的稳定性、可用性、系统以牺牲部分请求为代价或者延迟处理请求为代价,保证系统整体服务可用。 对于常见的限流策略有: - 延迟处理 - 拒绝处理 - 部分拒绝处理等 常见的限流方法可以分为: - 单机环境即应用级别限流 - 全局限流即分布式限流和接入层限流 在这篇 Chat 中,将会对以上的限流方法进行全方位的讲解,无论是对于业务来说,还是应对面试,都会给大家带来很大帮助。 在本场 Chat 中,将会涉及如下内容: - 基于 AtomicXXX、信号量、线程池实现计数器方式限流 - 实现固定窗口、滑动窗口计算方式限流 - 基于令牌桶算法、漏桶算法计算限流 - Google Guava 实现的令牌桶算法源码剖析 - Redis+拦截器实现分布式限流 - Tomcat、Nginx 调整配置参数实现接入层限流
高并发
111 订阅

手写线程池,全面了解 JDK 线程池实现原理

线程池,顾名思义就是存放线程的池子,池子中存放了很多可复用的线程。同时作为面试必备考点,大多数面试者对线程池还是停留在一些基础概念上,对其中的关键点及原理理解不到位或者不深刻,这将会为自己的面试大大减分。本篇 Chat 将以 JDK 线程池为背景,从零到一实现自己的线程池,麻雀虽小,五脏俱全。如果对本 Chat 都理解了,再返回去看 JDK 线程池,例如 ThreadPoolExecutor 等源码,将会得心应手。 在本场 Chat 中,将会涉及如下内容: - 基于 Runnable 实现不带返回值的任务 - 基于 Callable 实现带返回值的任务 - 实现任务的异常处理,将线程中的异常能够抛到线程外 - 利用 AtomicXXX 原子类的 CAS 特性并发控制变量的原子操作 - 基于自旋方式从队列中获取任务并执行,实现线程复用机制 - 基于 LockSupport.park/unpark 实现主线程获取任务返回值 - 控制线程数量,做到线程队列良好的伸缩性 - 灵活实现任务拒绝策略
严选线程池
348 订阅

动态代理种类及原理,你知道多少?

动态代理是代理模式的一种,指在不改动目标对象的基础上,通过一些辅助技术,能够对目标对象实现功能扩展。动态代理的应用场景也是非常广泛,比如常见 Hibernate、Spring、Dubbo 等框架均有运用,因此在了解了常见的动态代理种类及原理后,无疑对这些框架相关部分会理解得更加透彻。同时在面试中,如果能把本文涉及的知识点都讲到,那将会大大增加录用的几率。 在本场 Chat 中,将会涉及如下内容: - 对静态代理回顾,与动态代理本质区别 - JDK 动态代理实现,动态生成代理类源码剖析 - Cglib 代理方式实现,反编译代理类源码剖析 - Javassist 字节码 API 两种情景演示 - 使用 Javassist 动态生成代理类,模拟 JDK 动态代理 - Cglib 底层字节码 ASM 框架介绍
严选代理
363 订阅