自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

yangnk的技术记录

记录爱好者

  • 博客(80)
  • 收藏
  • 关注

原创 设计模式中继承和组合的总结

继承就是子类继承父类的特征和行为,使得子类具有和父类一样的属性和方法,在Java中通过extends关键字来实现继承。组合是对现有对象进行拼装组合实现更复杂的功能,在Java中通过引用其他的类做自身的属性实现类间的组合。面向对象程序的设计原则是:组合优于继承,多用组合少用继承。但在实际的开发过程中,需要根据具体情况来选择继承还是组合:当类间的关系层次较浅(不多于3层),类间的联系也比较稳定,建议采用继承的模式,否则采用组合的模式更好。本文由博客一文多发平台OpenWrite发布!

2023-10-24 22:32:11 498

原创 分布式服务调用(1)——Dubbo原理篇

Dubbo是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。首先需要回答一个问题:为什么需要远程调用RPC?为了解决高并发的问题,引入了微服务的架构,即将整体业务拆封层多个微服务,单个微服务能独立运行,那服务与服务间的调用如何保障呢?这就需要通过远程调用RPC来实现。在将应用改造成异构、微服务的架构下,就需要再不同服务间进行数据通信,甚至在不同语言编写的服务间进行通信,所以就需要像dubbo这样的RPC框架。

2023-10-20 10:25:29 243

原创 红包场景的系统设计和实践

红包的业务场景主要是:包红包-->发红包-->抢红包-->拆红包技术和架构特点:多写少读的场景,瞬时并发量比较大,拆红包和转账可以异步执行,可以实现双缓存操作解决高并发的方案:服务多实例,按照订单号进行动态路由;实现双缓存设计,热点数据可以提前预热;红包算法在内存中进行实时计算;提升高可用的方案:利用异步机制将拆红包和转账操作异步化;利用流控和降级措施避免服务不可用的场景出现;人工干预有问题的记录;对计划内风险因素做好规划和定时处理,计划外风险因素做好演练和预案;本文由博客一文多发平台。

2023-10-18 09:44:00 199

原创 分库分表(4)——ShardingJDBC原理和源码分析

使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。对于携带分片键的 SQL,根据分片键的不同可以划分为单片路由(分片键的操作符是等号)、多片路由(分片键的操作符是 IN)和范围路由(分片键的操作符是 BETWEEN)。SQL中如果无分片字段,将执行全路由,性能较差。

2023-10-13 00:09:24 345

原创 分库分表(3)——ShardingJDBC实践

Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 JDBC、Proxy 和 Sidecar(规划中)这 3 款相互独立,却又能够混合部署配合使用的产品组成。它们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。一套开源的分布式数据库中间件解决方案。有三个产品:JDBC、Proxy、Sidecar。

2023-10-10 22:29:52 384

原创 分库分表(2)——动态数据源实践

当把数据库进行分布分表等集群化部署后,在应用层就需要能够随时切换访问数据源,这就需要用到动态数据源的技术。应用是通过DataSource来访问数据库的,所以动态数据源实现的技术归根结底是在能够根据情况动态切换DataSource。基于Spring提供的AbstractRoutingDataSource组件,实现快速切换后端访问的实际数据库,该类实质充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上。源码分析。

2023-10-10 21:56:18 161

原创 分库分表理论总结

分库分表是在面对高并发、海量数量时常见的数据库层面的解决方案。通过把数据分散到不同的数据库中,使得单一数据库的数据量变小来缓解单一数据库的性能问题,从而达到提升数据库性能的目的。比如:将电商数据库拆分为若干独立的数据库,并且对于大表来说也拆分为若干小表,通过这种数据库拆分的方法来解决数据库的性能问题。数据库分布式核心内容无非就是数据切分(Sharding),以及切分后对数据的定位、整合。

2023-10-06 16:11:30 316 1

原创 xxl-job的原理(2)—调度中心管理注册信息

执行器通过restful api形式注册到调度中心来,调度中心JobApiController对应有3个注册、下线和回调的方法实现;通过AdminBizImpl的adminBiz.registry(registryParam)来实际执行注册方法,实际使用JobRegistryHelper类;在JobRegistryHelper类中在初始化的时候会创建一个线程池,每次注册执行器的时候会创建一个异步线程来将注册信息持久化的数据库;

2023-10-06 16:09:19 241

原创 多线程和并发编程(6)—并发编程的设计模式

为每一个处理任务分配一个线程。在 Java 中的线程是一个重量级的对象,创建成本很高,一方面创建线程比较耗时,另一方面线程占用的内存也比较大。Future未来模式是一种异步处理的模式,就是在针对处理事件比较长的任务时,创建一个异步线程来处理任务,返回一个Future的引用,等到后面必须要要结果的时候,可以通过Future的引用来获取异步线程处理的结果。Copy-on-Write模式适合读多写少的场景,他的实现思路是在需要进行写操作时候,会复制一个副本,在副本中进行写的操作,在写完之后再合并到原来的变量中。

2023-09-27 00:51:42 167

原创 TreeMap的排序

Map是键值对的集合接口,它的实现类主要包括:HashMap、Hashtable以及LinkedHashMap等。TreeMap:基于红黑树(Red-Black tree)的 NavigableMap 实现,该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。HashMap的值是没有顺序的,它是按照key的HashCode来实现的,对于这个无序的HashMap我们要怎么来实现排序呢?参照TreeMap的value排序。

2023-09-26 23:39:34 1227

原创 xxl-job的原理(1)

XxlJobConfig 配置类中实例化XxlJobSpringExecutor执行器类,该类是XxlJobExecutor类的实现类,在XxlJobSpringExecutor类中还实现了ApplicationContextAware, SmartInitializingSingleton, DisposableBean的接口,能够在实例化后将带有@Xxljob注解的方法当多JobHandler,将其解析后放到本地缓存jobHandlerRepository中。

2023-09-19 00:51:54 164

原创 系统稳定性保障设计总结和思考

针对SLA要求比较高的服务,在并发量比较大的情况下,可能会涉及到一些幂等性问题,这就需要在进行系统或架构设计的时候进行幂等性设计,幂等性设计的一种思路就是有一个状态值能够表征该次请求是否为重复下发的,这个状态值既能在Mysql数据库中保存,也能在redis缓存中保存,另一种思路是有机制保障重读请求会失败,比如通过mysql数据库的唯一性主键来保障。服务与服务之间的调用可能有失败的可能,比如两个业务服务间,因业务服务和数据库服务间都有可能,所以针对可靠性要求比较高的场景,就需要设置合理的重试机制。

2023-09-18 20:16:37 237

原创 计算机IO原理

select和poll的实现都是监听对象轮训文件描述符集合中事件,select中文件描述符集合有限,poll中文件描述符集合理论上上无限,但其工作线程其实是阻塞的,就是一直在等待他们将事件报送过来在进行处理。epoll是基于事件机制来实现,其实现是在对每个文件描述符后都记录其对应的工作线程信息,但监听到事件就能直接通知工作线程来工作。本文由博客一文多发平台。

2023-09-18 20:13:47 311

原创 多线程和并发编程(4)—并发数据结构之BlockingQueue

队列(Queue)就是一种满足先进先出(FIFO)特性的数据结构。Java中阻塞队列(BlockingQueue)具有当队列满了再添加元素则会阻塞,当队列空了再获取元素则会阻塞的特性。

2023-09-18 19:53:41 80

原创 多线程和并发编程(3)—AQS和ReentrantLock实现的互斥锁

AQS的数据结构包括同步等待队列和条件等待队列,同步等待队列是一个双端队列CLH,每个队列元素为一个Node,Node中保存前驱后置节点、当前线程状态、当前线程以及下一个等待线程。MESA模型的核心是需要一个共享变量来表示共享资源的数量,同步等待队列中的线程请求到一个共享资源,相应共享变量要减一,一直到共享变量为0,则请求的线程阻塞在同步等待队列中,如果需要满足某些条件才能竞争共享资源,这些线程会阻塞在条件等待队列中,但条件满足后要么转移到同步等待队列中,要么直接占有共享资源。本文由博客一文多发平台。

2023-09-14 21:08:54 245

原创 多线程和并发编程(2)—CAS和Atomic实现的非阻塞同步

CAS是一种非阻塞同步方法处理并发问题,相较于synchronize加锁操作,其操作上更轻量级,不会阻塞线程,但针对并发量很大并且竞争非常激烈的场景,可能使用CAS就不太合适,由于竞争到锁的概率很低,这就会造成CPU空转,导致资源浪费。本文由博客一文多发平台OpenWrite发布!

2023-09-12 10:06:25 158

原创 JVM GC垃圾回收

当前放对象的Survivor区域里(其中一块区域,放对象的那块s区),一批对象的总大小大于这块Survivor区域内存大小的50%(-XX:TargetSurvivorRatio可以指定),那么此时大于等于这批对象年龄最大值的对象,就可以直接进入老年代了,例如Survivor区域里现在有一批对象,年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%,此时就会把年龄n(含)以上的对象都放入老年代。也可以反过来,标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

2023-09-11 09:31:15 301

原创 JVM类加载和双亲委派机制

当我们用java命令运行某个类的main函数启动程序时,首先需要通过类加载器把类加载到JVM,本文主要说明类加载机制和其具体实现双亲委派模式。

2023-09-09 15:55:10 430

原创 Arthas 排查JVM问题总结

https://www.pdai.tech/md/interview/x-interview.html#_5-4-问题排查本文由博客一文多发平台OpenWrite发布!

2023-09-08 10:55:24 722

原创 JVM问题排查

cpu飙升可能的原因大概为:代码存在死循环,导致消耗cpu;代码一直在创建大对象,导致频繁GC,这个时候内存占用率也会很高;

2023-09-07 23:13:16 916

原创 定时任务实现方案总结

定时任务的作用是在设定的时间和日期后自动执行任务,执行任务的周期既能是单次也能是周期性。本文重点说明Timer、ScheduledThreadPoolExecutor、Spring Task、Quartz等几种定时任务技术方案。TimerQuartzLinux Cron优点JDK原生自带,简单轻便JDK原生自带,简单轻便Spring框架实现,和springboot集成非常简单,支持cron表达式Quartz功能非常丰富,支持cron表达式、支持持久化和分布式部署。

2023-09-07 16:26:44 154

原创 Java泛型

他为了解决这样一个问题,就是在没有类型规定的前提下,这个集合类可以防止任何类型,这样在编译期他是没问题的,但是在运行期他可能报错,这样就不符合提早暴露问题的原则。在类名之后使用尖括号声明类型参数,声明的类型参数可以像普通类型一样用在类型声明处使用,到使用时再决定其具体类型,然后编译器会帮我们处理一些类型类型转换的细节。在使用泛型的时候,我们还可以为传入的泛型参数进行上下边界的限制,如:类型参数只准传入某种类型的父类或某种类型的子类。声明类上界后,在使用该泛型类时指定的类型只能为上界或其子类。

2023-09-06 22:09:27 174

原创 RabbitMQ、Kafka和RocketMQ比较

消息队列中间件(MQ)是不同系统之间消息传递,异步通信的常见组件,RabbitMQ、Kafka和RocketMQ是目前业界常见的3种消息中间件,本文重点阐述了他们特性差异、架构设计和处理常见问题的方案。

2023-09-04 22:33:38 1088

原创 Mysql数据库(3)—架构和日志

主要包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。mysql执行一句更新操作的数据不会立即写入磁盘,会先放到buffer pool中,这是内存中的一片暂存区,等一段时间会刷入磁盘中。首先连接器会判断该用户提交的SQL是否有权限,如果有权限才会进行后续的执行操作,连接器负责跟客户端建立连接、获取权限、维持和管理连接。本文由博客一文多发平台。

2023-09-03 00:27:23 422

原创 Mysql数据库(2)—事务和锁

Mysql的加锁对象是索引而不是记录,所以当一个事务对该记录的非主键索引加锁,并请求主键索引的锁,但另一个事务对该记录的主键索引已加锁,并请求该记录的非主键索引的锁,那么就会进入死锁状态。锁是计算机中协调多线程并发访问共享资源的机制,在数据库中就是协调多个事务同时访问同一数据记录的机制,在Mysql数据库中进行加锁的对象是索引中的索引项,会在索引项上做加锁标记。就是多个事务在进行插入的时候,已经有事务在进行插入操作了,另一个在等待的事务需要加上插入意向锁,用以表面针对目前的间隙位置有插入的需求;

2023-09-01 00:56:22 143

原创 Mysql数据库(1)—索引

联合索引的最左匹配原则,在遇到范围查询(如>、<)的时候,就会停止匹配,也就是范围查询前的字段可以用到联合索引,但是在范围查询字段的后面的字段无法用到联合索引。注意,对于 >=、<=、BETWEEN、like 前缀匹配的范围查询,并不会停止匹配。

2023-08-31 21:55:25 308

原创 三个线程循环顺序打印

通过wait()/notiyf()来实现等待/通知模型,首先线程A获取锁后执行线程A中的打印逻辑,然后线程A调用了lock对象的notifyAll()方法进入释放lock对象,线程B获取到锁后执行线程B中的打印逻辑,然后线程B调用了lock对象的notifyAll()方法进入释放lock对象,线程C获取到锁后执行线程C中的打印逻辑,然后线程C调用了lock对象的notifyAll()方法进入释放lock对象。主要考虑的是线程间同步问题,可以通过线程间等待/通知模型来解决顺序性。本文由博客一文多发平台。

2023-08-29 14:35:41 132

原创 高性能服务器设计思路和方案

互联网海量并发和海量数据处理背后涉及到高性能服务器的请求和响应,这里面如何处理成千上万的的用户请求?涉及到哪些技术?有哪些方向是可以进行优化的呢?本文总结了几种方案供参考。

2023-08-29 14:32:06 134

原创 多线程和并发(1)—等待/通知模型

通过wait()/notiyf()来实现等待/通知模型,是指一个线程A调用了对象O的wait()方法进入等待状态,而另一个线程B调用了对象O的notify()或者notifyAll()方法,线程A收到通知后从对象O的wait()方法返回,进而执行后续操作。Thread类中的run()方法中说明的是任务的处理逻辑,执行线程的start()方法让一个线程进入就绪队列等待分配cpu,分到cpu后才调用实现的run()方法,执行任务的处理逻辑,start()方法不能重复调用,如果重复调用会抛出异常。

2023-08-27 09:01:42 1003

原创 常见API架构介绍

两个服务间进行接口调用,通过调用API的形式进行交互,这是常见CS架构实现的模式,客户端通过调用API即可使用服务端提供的服务。相较于SPI这种模式,就是服务端只规定服务接口,但具体实现交由第三方或者自身来实现,API这种模式是具体的实现和API接口都是服务端来实现的。API 使用协议或规范来定义那些通过网络传输的消息的语义和信息。这些规范构成了 API 的体系结构。选择RPC场景:服务内部通信,需要高性能;选择RESTful场景:提供公共web api服务。

2023-08-24 21:07:32 2864 2

原创 分布式定时任务框架Quartz总结和实践(2)—持久化到Mysql数据库

Quartz提供两种基本作业存储类型,包括将任务数据保存在内存中的RAMJobStore模式和保存在数据库中的JDBC作业存储模式,上篇说明了RAMJobStore 模式,本篇说明JDBC作业存储。RAMJobStore :RAM也就是内存,默认情况下Quartz会将任务调度存在内存中,这种方式性能是最好的,因为内存的速度是最快的。不好的地方就是数据缺乏持久性,但程序崩溃或者重新发布的时候,所有运行信息都会丢失JDBC作业存储:存到数据库之后,可以做单点也可以做集群,当任务多了之后,可以统一进行管理。

2023-08-24 00:08:18 1567

原创 JVM理论知识

选择GC主要考虑的是使用场景,一般嵌入式、内存较小的选择串行GC回收器;对于需求吞吐量大的常见可以选择并行GC回收器;对于需要时延少的场景可以选择CMS或者G1回收器;CMS回收器整体更侧重增大吞吐量,G1回收器整体是平衡了降低时延和增大吞吐量的要求;serial GC垃圾回收器:serial GC就是串行的GCCMS GC垃圾回收器:CMS经过(1)初始标记;(2)并发标记;(3)重新标记;(4)并发清除;四个阶段来完成。

2023-08-22 19:33:00 806 1

原创 CompletableFuture总结和实践

CompletableFuture和Future出现的原因是继承Thread或者实现Runnable接口的异步线程没有返回值,需要返回值的异步线程可以通过CompletableFuture和Future来创建。CompletableFuture和Future都可以获取到异步线程的返回值,但是Future只能通过get()方法阻塞式获取,CompletableFuture由于实现了CompletionStage接口,可以通过丰富的异步回调方式来执行后续的操作,同时还能对多个任务按照先后顺序进行任务编排。

2023-08-20 22:15:59 209

原创 Websocket原理和实践

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。WebSocket与HTTP协议不同,它使用了独立的端口,并且在建立连接后,不需要在每次数据传输时重新建立连接。这使得它特别适合于实时应用程序,例如聊天,在线游戏和股票交易等,这些应用程序需要高速,双向的数据传输。

2023-08-17 18:07:59 868

原创 设计模式

模式定义:允许通过拷贝原始对象的属性创建一个相同的对象,而不需要关注这个对象怎么创建的。解决问题:不需要关注怎么创建一个新的对象。解决方案:在Java中年通过实clone()方法,在Spring中通过声明bean为Prototype类型来实现。应用场景:通过Java中的clone方法可以根据模板对象克隆一个原型对象,这就是原型模式的应用。在使用原型模式的时候要着重关注浅克隆还是深克隆。比较适合创建一个实例化比较复杂的时候,比如创建网络链接或数据库连接;

2023-08-14 22:29:19 759

原创 多线程与并发编程面试题总结

JVM中会维护两个线程队列来区分加锁情况,包括:同步队列:保存一起竞争同一把锁对象的线程。阻塞队列:保存调用wait()后,竞争获取锁的线程。

2023-08-12 01:13:18 718

原创 ThreadLocal原理和实践

ThreadLocal是线程本地变量,解决多线程环境下成员变量共享存在的问题。ThreadLocal为每个线程创建独立的的变量副本,他的特性是该变量的引用对全局可见,但是其值只对当前线程可用,每个线程都将自己的值保存到这个变量中而各线程不受影响。

2023-08-09 14:53:33 83

原创 Java SPI机制的原理和实践

Java SPI是SPI的一种重要实现方式,是JDK内置的一种服务发现方法,实现逻辑是:调用方通过调用JDK提供的标准化的服务接口,通过本地服务发现,加载第三方或者本地实现了该接口的类,通过这种方式,服务规范制定者制定接口规范,服务提供者按照接口进行实现。在JDK中实现数据库驱动按需加载就是利用SPI的方式实现的,JDK规定了java.sql.Driver接口,其具体实现可以是MySQL或者PostgreSQL,具体实现是第三方的驱动服务方提供,通过SPI机制加载供调用方使用。(1)SPI的核心思路是什么。

2023-08-08 21:42:15 243

原创 gRPC中interceptor拦截器的总结和实践

拦截器是调用在还没有到达目的地之前进行处理的逻辑,类似于Spring框架中存在的Interceptor。gRPC 拦截器主要分为两种:客户端拦截器(ClientInterceptor),服务端拦截器(ServerInterceptor),顾名思义,分别于请求的两端执行相应的前拦截处理。

2023-08-08 11:21:48 1111

原创 Problem: 6953. 判断是否能拆分数组

针对题目中的以下目标,可以转换寻求数组中是否存在前后两个元素之和>=m的情况,如果存在则返回ture,如果不存在则返回false。能这样转换的原因是,如果存在则这两个元素可以当做最后一次进行以下操作的字数组,因为从他向前或向后,起组成的数组肯定都>=m。

2023-08-07 10:07:20 97

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除