单链表中间节点搜索和快慢指针

前提

今天中午吃饭的时候刷了下技术类型的公众号,看到有前辈过了Ant的高P面试,其中有一道题考查了单链表搜索位于中间的节点的算法。觉得解决方案很有趣,于是这里尝试重现一下。

阅读更多
设计模式概念和七大原则

什么是设计模式

在GoF(Gang of Four)的书籍《Design Patterns - Elements of Reusable Object-Oriented Software(设计模式-可复用面向对象软件的基础)》中是这样定义设计模式的:Christopher Alexander说过:“每一个模式描述了一个在我们周围不断重复发生的问题以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动” [AIS+77,第10页]。尽管Alexander所指的是城市和建筑模式,但他的思想也同样适用于面向对象设计模式,只是在面向对象的解决方案里, 我们用对象和接口代替了墙壁和门窗。两类模式的核心都在于提供了相关问题的解决方案。一般而言,设计模式有四个基本要素:

  1. 模式名称(pattern name):一个助记名,它用一两个词来描述模式的问题、解决方案和效果。
  2. 问题(problem):描述了应该在何时使用模式。
  3. 解决方案(solution):描述了设计的组成成分,它们之间的相关关系以及各自的职责和协作方案。
  4. 效果(consequences):描述了模式应用的效果以及使用模式应该权衡的问题。

设计模式的创始人很明确地指出了设计模式的基本要素,但是由于现实中浮躁、偏向过度设计等因素的干扰,开发者很多时候会重点关注第1和第3点要素(过度关注设计模式和设计模式的实现),忽略第2和第4点要素(忽视使用设计模式的场景和目标),导致设计出来的编码逻辑可能过于复杂或者达不到预期的效果。

总的来说,设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。也就是本来并不存在所谓设计模式,用的人多了,也便成了设计模式。

阅读更多
Spring Cloud Gateway-自定义GatewayFilter

前提

GatewayFilter的作用域是指定的路由配置,路由配置选项里面需要通过filters指定想要使用的GatewayFilter列表。我们可以通过自定义GatewayFilter,做额外的扩展,实现一些内建GatewayFilter不存在的功能,并且应用到我们的路由配置中。

阅读更多
Spring Cloud Gateway-自定义GlobalFilter

前提

GlobalFilter的作用域是所有的路由配置,我们可以通过自定义GlobalFilter,做额外的扩展,用来实现一些全局的功能。

阅读更多
Spring Cloud Gateway入坑记

前提

最近在做老系统的重构,重构完成后新系统中需要引入一个网关服务,作为新系统和老系统接口的适配和代理。之前,很多网关应用使用的是Spring-Cloud-Netfilx基于Zuul1.x版本实现的那套方案,但是鉴于Zuul1.x已经停止迭代,它使用的是比较传统的阻塞(B)IO + 多线程的实现方案,其实性能不太好。后来Spring团队干脆自己重新研发了一套网关组件,这个就是本次要调研的Spring-Cloud-Gateway

简介

Spring Cloud Gateway依赖于Spring Boot 2.0, Spring WebFlux,和Project Reactor。许多熟悉的同步类库(例如Spring-DataSpring-Security)和同步编程模式在Spring Cloud Gateway中并不适用,所以最好先阅读一下上面提到的三个框架的文档。

Spring Cloud Gateway依赖于Spring BootSpring WebFlux提供的基于Netty的运行时环境,它并非构建为一个WAR包或者运行在传统的Servlet容器中。

阅读更多
深入理解Object提供的阻塞和唤醒API
深入理解Object提供的阻塞和唤醒API前提前段时间花了大量时间去研读JUC中同步器AbstractQueuedSynchronizer的源码实现,再结合很久之前看过的一篇关于Object提供的等待和唤醒机制的JVM实现,发现两者有不少的关联,于是决定重新研读一下Object中提供的阻塞和唤醒方法。本文阅读JDK类库源码使用的JDK版本是JDK11,因为本文内容可能不适合于其他版本。 Object提供的阻塞和唤醒APIjava.lang.Object作为所有非基本类型的基类,也就是说所有java.lang.Object的子类都具备阻塞和唤醒的功能。下面详细分析Object提供的阻塞和唤醒AP ...
阅读更多
通过micrometer实时监控线程池的各项指标
通过micrometer实时监控线程池的各项指标前提最近的一个项目中涉及到文件上传和下载,使用到JUC的线程池ThreadPoolExecutor,在生产环境中出现了某些时刻线程池满负载运作,由于使用了CallerRunsPolicy拒绝策略,导致满负载情况下,应用接口调用无法响应,处于假死状态。考虑到之前用micrometer + prometheus + grafana搭建过监控体系,于是考虑使用micrometer做一次主动的线程池度量数据采集,最终可以相对实时地展示在grafana的面板中。 实践过程下面通过真正的实战过程做一个仿真的例子用于复盘。 代码改造首先我们要整理一下Threa ...
阅读更多
JUC同步器框架AbstractQueuedSynchronizer源码图文分析

前提

Doug Lea大神在编写JUC(java.util.concurrent)包的时候引入了java.util.concurrent.locks.AbstractQueuedSynchronizer,Abstract Queued Synchronizer,也就是”基于队列实现的抽象同步器”,一般我们称之为AQS。其实Doug Lea大神编写AQS是有严谨的理论基础的,他的个人博客上有一篇论文《The java.util.concurrent Synchronizer Framework》,文章在http://ifeve.com上可以找到相关的译文(《JUC同步器框架》),如果想要深入研究AQS必须要理解一下该论文的内容,然后详细分析一下AQS的源码实现。本文在阅读AQS源码的时候选用的JDK版本是JDK11。

AQS的主要功能

AQS是JUC包中用于构建锁或者其他同步组件(信号量、事件等)的基础框架类。AQS从它的实现上看主要提供了下面的功能:

  • 同步状态的原子性管理。
  • 线程的阻塞和解除阻塞。
  • 提供阻塞线程的存储队列。

基于这三大功能,衍生出下面的附加功能:

  • 通过中断实现的任务取消,基于线程中断实现。
  • 可选的超时设置,也就是调用者可以选择放弃等待。
  • 定义了Condition接口,用于支持管程形式的await/signal/signalAll操作,代替了Object类基于JNI提供的wait/notify/notifyAll。

AQS还根据同步状态的不同管理方式区分为两种不同的实现:独占状态的同步器共享状态的同步器

阅读更多
特别教程-CronTrigger教程
特别教程-CronTrigger教程介绍cron表达式是一个已经存在了很长时间的UNIX工具,因此它的调度功能非常强大且已经经过验证。CronTrigger类的功能是基于cron的调度功能实现的。 CronTrigger使用”cron表达式”,可以创建诸如“每周一至周五上午8:00”或“每月最后一个星期五上午1:30”的触发调度时间表(调度计划)。 cron表达式很强大,但是它使用起来也有可能相当混乱(这里大概的意思是说cron的用法相对复杂,容易出错)。本教程旨在解决创建cron表达式的一些谜题,为用户提供一个资源,让他们可以在论坛或邮件列表中提问之前访问这个教程(减少在论坛或者邮件中的提问 ...
阅读更多
第十二章:其他特性
第十二章:其他特性插件Quartz提供了一个用于插入附加功能的接口org.quartz.spi.SchedulerPlugin。 你可以从org.quartz.plugins包中找到提供各种实用功能的Quartz插件。它们提供诸如在调度器启动时自动调度Job的功能,记录Job和Trigger相关事件的历史,并确保当JVM退出时调度器能够彻底关闭。 Job工厂当Trigger触发时,通过Scheduler上配置的JobFactory实例化与之关联的Job。默认的JobFactory只是在Job类上(反射)调用newInstance()。你可能需要创建自己的JobFactory实现,以完成诸如让应 ...
阅读更多