JAVA学习实战
文章平均质量分 69
主要用于熟悉java的一些基本特性以及使用java完成各个框架的调用
会说话的皮卡丘
当初耿耿于怀的东西现在也没法放下
展开
-
设计模式-责任链
审批场景的普遍应用实际案例:HttpClient中的责任链模式责任链模式在事件处理、日志记录和过滤器链中的应用接口和具体处理器类的设计处理器类的链式结构客户端使用责任链的示例Spring框架的 @Order 注解的应用利用 @Order 注解实现的责任链模式客户端通过构造函数注入实现责任链。原创 2024-01-21 13:27:05 · 703 阅读 · 0 评论 -
CAS算法(compareAndSwap)
在并发编程中,我们大多数情况下都是显式地通过加锁来保证线程安全。这里我们来介绍一种在无锁条件下多线程变量同步的方法——CAS(Compare And Swap,比较与交换)算法在CAS中涉及3个操作数:变量当前内存值V、变量的预期值E、新值U。只有该变量当前的内存值V与预期值E相同时,才会将新值U写入内存完成变量修改,否则什么都不做。在Java中,java.util.concurrent.atomic包的原子变量类大量使用了Unsafe类提供的CAS操作。原创 2023-02-25 11:24:21 · 166 阅读 · 0 评论 -
高并发场景下机器性能优化sop
这时有经验的同学,就会改用 Iterator (迭代器)迭代循环该集合,这是因为 LinkedList是链表实现的,如果使用 for 循环获取元素,在每次循环获取元素时,都会去遍历一次List,这样会降低读的效率。之前接触过一些高并发场景下的性能优化,最近过年时候又碰巧看了一些相关资料,趁着还没忘干净,手动整理一下,有一些是在别处看到的,有一些是自己的亲身经历,因为偏向于自己整理笔记所以很多地方都只是列了一个大纲和解决办法,并没有详细涉及原理,感兴趣的朋友可以自行查阅相关文献。内存:内存溢出、内存泄露。原创 2023-02-25 11:09:07 · 600 阅读 · 0 评论 -
runnable、callable、consumer、supplier
Java 没有委托的概念;相反,如果需要一个指向函数的指针,可以创建内联匿名类(或 Java 8 的 lambda 表达式),它们是为此建议设计的某些接口的实现(也称为 Java 8 的功能接口)。然而,随着 Java 的发展,越来越多的此类接口被添加进来。虽然它们看起来非常相似且令人困惑,但它们中的每一个都有一个独特的特征,使其与众不同。可以将它们中的许多映射到 .NET 中的相同类型。下表列出了一些著名的接口,但还有更多。原创 2022-12-11 17:15:55 · 1335 阅读 · 0 评论 -
stream、lamda、optional
Java8中的Stream是对容器对象功能的增强,它专注于对容器对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。同时,它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用fork/join并行方式来拆分任务和加速处理过程。通常,编写并行代码很难而且容易出错, 但使用Stream API无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。简化我们匿名内部类的调用。原创 2022-12-11 11:16:53 · 404 阅读 · 0 评论 -
代理,反射,AOP
这篇文章主要讲三个点1.设计模式中的代理模式2.JAVA中的反射,因为用到了动态代理,这里举一下JDK代理和GCLIB代理的例子3.介绍一下spring的aop是怎么用到了代理。原创 2022-11-27 16:55:21 · 1382 阅读 · 3 评论 -
Hystirx限流:信号量隔离和线程池隔离
背景:最近工作中要处理服务高并发的问题,大流量场景下限流熔断降级可以说是必不可少的,打算对限流做一次改造,所以要先了解一下hytrix相关内容,比如了解一下线程池隔离和信号量隔离的区别。**信号量:**信号量Semaphore是一个并发工具类,用来控制可同时并发的线程数,其内部维护了一组虚拟许可,通过构造器指定许可的数量,每次线程执行操作时先通过acquire方法获得许可,执行完毕再通过release方法释放许可。如果无可用许可,那么acquire方法将一直阻塞,直到其它线程释放许可。原创 2022-11-27 11:04:52 · 1970 阅读 · 6 评论 -
redis缓存一致性以及解决方案
首先要到redis里面读取缓存,如果没有缓存,那么就到mysql里面去取数据,并且将其放置在缓存中关于解决缓存一致性的问题,不难想到主要有两种解决方案,**双更模式:**双更模式,顾名思义就是更新两次,一次更新redis,一次更新mysql不难想到,如果我们先更新redis,再更新mysql的话,是不是就可以保证每次缓存中的数据都是最新的了?但是这样做是有问题的,比如如果我们更新mysql的时候失败了怎么办?更新数据库可能会失败,发生了回滚。原创 2022-11-26 21:04:40 · 2470 阅读 · 0 评论 -
JAVA :Stream ,多线程
stream:Java 8 API添加了一个新的抽象称为流Stream这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。− 为集合创建串行流。− 为集合创建并行流。原创 2022-10-16 17:11:55 · 3518 阅读 · 0 评论 -
Redis:主从同步、哨兵、集群
从上面可以看到,主从同步并没有一个自动的管理机制,当出现主服务器宕机的情况,需要人工干预来进行恢复,但是如果主从服务器数量庞大,又或是因为高并发导致的大量崩溃,这时需要的时间和难度都是非常大的,于是Redis中又引入了**哨兵模式(Sentinel)**来作为解决方案,将管理由人工转向哨兵,使得Redis具有自动容灾恢复的能力。负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;原创 2022-10-03 17:32:57 · 184 阅读 · 0 评论 -
Redis:缓存雪崩,缓存击穿,缓存穿透,缓存预热
缓存雪崩指的是在短时间内,有大量缓存的键同时过期,由于缓存过期,导致此时所有的请求就直接查询数据库,而数据库很难抵挡这样巨大的压力,严重情况下就会导致数据库被大流量打死,直接宕机。缓存雪崩的解决方法有以下几种,为了避免缓存同时过期,,使失效时间分散开来,加锁排队可以起到缓冲的作用,防止大量请求同时操作数据库,但是也正因为如此也减少了吞吐量,导致响应时间变慢,用户体验变差。,即加入一个本地缓存作为备案,当Redis缓存失效后就暂时使用本地缓存进行代替,避免直接访问数据库。,有更新操作时直接更新缓存即可。原创 2022-10-03 16:06:30 · 288 阅读 · 0 评论 -
布隆过滤器
通常我们会遇到很多要判断一个元素是否在某个集合中的业务场景,一般想到的是将集合中所有元素保存起来,然后通过比较确定。但是随着集合中元素的增加,我们需要的存储空间也会呈现线性增长,最终达到瓶颈。当有变量被加入集合时,通过 K 个映射函数将这个变量映射成位图中的 K 个点,把它们置为 1(假定有两个变量都通过 3 个映射函数)。在程序的世界中,布隆过滤器是程序员的一把利器,利用它可以快速地解决项目中一些比较棘手的问题。一个元素如果判断结果为存在的时候元素不一定存在,但是判断结果为不存在的时候则一定不存在。原创 2022-10-03 15:52:24 · 730 阅读 · 0 评论 -
JAVA学习实战 reactor线程模型
但是随着连接数的增多,问题传统IO就不行了。同步非阻塞,服务器实现模式为一个请求一个线程,每个线程亲自处理io,但有另外的线程轮询检查是否io准备完毕,不必等待io完成,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,每个线程不必亲自处理io,而是委派os来处理,并且也不需要等待io完成了,如果完成后,os会通知的。原创 2022-09-18 20:07:34 · 955 阅读 · 0 评论 -
JVM监控:JMX组件与底层原理
JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架 ,从Java5.0开始引入到标准Java技术平台中。JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理。其实JMX也可以看作一个框架,和我们平时使用的Spring、Hibernate也没有什么区别。只不过他已经附带到了标准java技术平台当中。原创 2022-09-12 16:20:20 · 1723 阅读 · 0 评论 -
JVM:常用的四种垃圾回收机制
cms是一个基于标记-清除 算法的综合多种算法的老年代垃圾回收器适用场景:重视服务器响应速度,要求系统停顿时间最短。这里要说明下,这是一个老年代算法,年轻代怎么处理?不回收了嘛?这里其实年轻代是采用的其它算法,具体看策略,Java 参数可以选择策略。这里下文也会涉及到主要的pipeline如下1、初始标记(CMS initial mark)原创 2022-09-11 22:14:51 · 6762 阅读 · 0 评论 -
深入理解redis
如图,redis1.0也就只有几千行,代码很少,主要有上图的几个包组成,redis.c ,redis-cli.c(redis-client以及redis-server) ae.c(ae事件库),anet.c(ae网络库),zmalloc.c(内存库)redisclient主要有四个组成部分,fd文件描述符,db是一个指向redisDBList的指针,clients是指向redisClientList的指针,最后是最后一个最核心的事件循环,是指向AeEventLoop的指针。下图是redis的数据结构部分。原创 2022-09-03 16:09:04 · 1524 阅读 · 0 评论 -
分布式微服务定时任务方案
采用多路心跳,做服务级,进程级的,IP和端口级别的心跳检测,正常情况是主系统工作,备用系统守候,心跳检测主系统出现故障,备用系统启动,当再次检测到主系统工作,则将执行权交回主系统。A,B两台服务器同时工作,启动需要存在一前一后,谁先启动谁率先加锁,其他服务器只能等待,他们同时对互斥锁进行监控,一旦发现锁被释放,其他服务那个先抢到,那个运行,运行前加排他锁。功能相对简单,交互性差,任务部署效率低,开发和维护成本比较高,不能很好的满足各系统定时任务的管理和控制,尤其在多系统的环境下更加明显;...原创 2022-08-27 19:14:23 · 2843 阅读 · 2 评论 -
qps与线程大小数目
我们的请求变多了,随之而来的就是大量的上下文切换、大量的GC、大量的锁征用,这些会增加不可并行部分的总时间,也会大大的增加CPU Time。看似增加CPU核数(或者说线程数)可以成倍的增加系统QPS,但实际上增加线程数的同时也增加了很大的系统负荷,更多的上下文切换,最佳QPS和最大的QPS是有偏差的。看似增加CPU核数(或者说线程数)可以成倍的增加系统QPS,但实际上增加线程数的同时也增加了很大的系统负荷,更多的上下文切换,最佳QPS和最大的QPS是有偏差的。增加CPU核数对QPS的提升。转载 2022-08-24 20:23:21 · 1265 阅读 · 0 评论 -
redis学习随笔
底层是先将数据写入到一个临时文件,待数据持久化结束后,将临时文件替换上次持久化完成的文件,期间主进程不进行任何IO操作,保证了极高的性能,如果数据恢复的要求对数据的完整性不敏感,那么rdb方式是非常合适的,缺点是最后一次持久化后的数据可能会丢失,例如设置20秒至少3个数据变化则拍一次快照,如果修改了3个数据,但是20秒保存一次的时间间隔还没到服务器就宕机了,则会丢失最后一次修改的数据;对空结果缓存:如果一个查询返回是数据是空,仍然对空结果进行缓存,并设置很短的空结果过期时间,一般为5分钟;原创 2022-08-24 20:13:05 · 403 阅读 · 0 评论 -
java jvm用到的各种工具
可以看到jmap的主要功能是可以dump下来分析内存泄漏之类的问题,除此之外还可以用来直接查看内存详情,可以说jmp是以上这几个工具里面最重要的。我们都知道linux中ps是查看资源占用情况,java中jps也是相似的。jstat是用来查看内存的,注意jstat显示的基本都是内存占用的百分比。点进去之后可以看到内存监控会发现内存涨之后会进行gc使内存下降。4.jstack是用来分析线程的。主要用来监控内存的使用状况的。原创 2022-08-21 15:05:05 · 359 阅读 · 0 评论 -
深入理解netty(二)Channel
configHandler//其实就是把用户输入的handler给他拿到,然后通过pipeline.addLast的方式这样一个逻辑链处理列给他封装进去。上一篇文章介绍过channel,channel里面主要是封装了对于客户端连接的建立等的一些api,以及socket等,对于封装的api可以进行一些读写。好了,创建channel的步骤基本讲完了,后面要说一下他是如何进行初始化的。其中id是唯一标识,unsafe是底层关于tcp底层的读写的一些操作,.doregister()//调用jdk底层注册。...原创 2022-08-10 23:32:47 · 530 阅读 · 0 评论 -
深入理解netty
channel模块主要是用来创建客户端的连接,对于连接的一些封装,内部封装了比如socket等的一些功能,然后对于封装的api里面可以进行数据的一些读写。nioeventloop是netty的核心,也可以当成是netty的发动机,他主要是创建两种线程,一种是用来处理读写的,一种是用来监听客户端的连接。pipeline模块:数据的读写可以看作逻辑处理的链,逻辑处理的链的每一个逻辑处理的逻辑就是channelhandler。性能高,对比其他主流的NIO框架,Netty的性能最优。API使用简单,学习成本低。..原创 2022-08-08 23:40:40 · 219 阅读 · 0 评论 -
JAVA学习实战(十二)分库分表学习
个人理解垂直拆分的主要作用是尽可能少的减少不必要信息的检索,比如我要进行用户登录,那我就只需要用户名和密码,我如果把用户的手机号等个人信息全都查出来的话,那我理解其实没什么用,反而还加大了资源的浪费。比如你是后台管理的用户多(比如警察的内部系统),你就要按照orderid去进行拆分,因为当前的使用人员并不关心每一个用户他具体的信息,而关注的是别的粒度的信息。但是垂直拆分并没有解决数据库数据量大的时候的读写压力大的问题。每个拆分出来的表都具有不同的结构,但是他们的数据量是一样的。他是为了解决什么样的问题呢?.原创 2022-08-07 11:13:52 · 854 阅读 · 0 评论 -
JAVA学习实战(十一)@Transactional注解的失效场景
如果作用于类的话比较好理解,就是对于该类的所有public方法都保证相同的事务属性信息,作用于,作用于方法的话也很好理解,但如果类配置了@Transactional的同时方法也配置了@Transactional的话,以细粒度的方法级别的@Transactional配置为准。Propagation.REQUIRES_NEW重新创建一个新的事务,如果当前存在事务,暂停当前的事务。Propagation.REQUIRED如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。...........原创 2022-07-30 18:43:52 · 485 阅读 · 0 评论 -
设计模式(二)装饰器模式及代码实例
现在思考这样一种情况,我们有一个接口a,用它来实现了若干接口bcd,如果我们想要给bcd加上一个功能且不改变现有类的结构的话,一个显然的想法是继承,将其作为子类,但是这样来讲不是很灵活。现在的话我们有了两个Shape的实现类,如果我们想要扩展这个类,给他加上一个Function。我们首先要写一个抽象类。装饰类和被装饰类可以独立发展,不会相互耦合。于是有了装饰器这一设计模式。一边看代码一边解释吧。......原创 2022-07-17 17:19:55 · 388 阅读 · 0 评论 -
Metrics学习笔记
那么收集完数据之后可以使用自带的dashboard去进行监控,但是自带的dashboard相对来讲较为简陋,我们可以将数据收集起来存放到clickhouse等引擎,然后导入到Grafana等比较好的dashboard去进行监控。histogram用来度量统计数据中的各类指标,比如平均值,最大值最小值,中位数等指标,通常可以用来评估百分之n的数据都在哪个范围内。是一个六十四位的计数器,我们可以设置两个counter分别用来统计服务的请求数和处理数。然后在处理请求的时候将该请求自增。然后在处理请求的地方。...原创 2022-07-16 13:43:50 · 603 阅读 · 0 评论 -
JAVA学习实战(十)servlet
servlet是web客户端/http客户端和http服务器的数据库的中间层其实servlet的工作使用公共网关接口GCI也能正常进行,那为什么还要使用servlet呢?其有以下几点优势:1.性能更好2.没必要新建一个进程去执行servlet主要执行的工作有:1.读取客户端(浏览器)发送的数据比如html表单2.读取客户端发送的http请求数据,包括cookie或者浏览器能够理解的压缩格式3.处理数据并生成结果,这个过程可能需要访问数据库4.发送显式/隐式到客户端(浏览器)Servlet原创 2022-07-04 18:35:50 · 229 阅读 · 0 评论 -
JAVA学习实战(九)事务
当我们在java的service中想要保持事务的时候只需要使用注解@Transactional即可保证事务的一致性,但是如果是我们使用try catch呢?这时候由于异常被捕获,并不会抛出引发执行事务,那怎么办呢?其实很简单,只需要在执行的时候在catch语句内部加上一行就能够让事务回滚了完整的demo大概是...原创 2022-07-03 12:23:08 · 420 阅读 · 0 评论 -
JAVA学习实战(八)httpclient分析
之前使用clickhouse的时候由于创建太多httpclient造成了内存泄漏,使用单例模式解决了这个问题,为了深入了解httpclient,开始尝试阅读他的源码,个人觉得httpclient的精髓可能主要是他的责任链责任链,顾名思义是一条调用链,责任链模式是一种设计模式,链路上的每一个节点控制一个单独的功能,下图为httpclient的责任链CloseableHttpClient是一个外部的封装,封装的主要功能是各种各样的请求方法internalHttpclient可以说主要作用是封装配置和请求,将原创 2022-07-02 21:51:14 · 581 阅读 · 0 评论 -
JAVA学习实战(七)异步编程
之前写controller层某个模块的时候主要遇到过一个问题就是说执行时间太长导致前端超时,为了解决这个问题,采用了异步编程的方法使得函数正常运行下文将从几个不同的方式介绍异步调用1.异步调用的本质实际上是创建一个新线程来执行这个函数如上图所示,两个异步最后相当于两个线程执行两个函数,执行时间大约是5000ms,因为异步编程可以使用线程来实现,很自然的联想到由于线程池可以实现多线程,那么线程池也可以实现线程连接(减少重复创建造成的资源消耗以及大量线程消耗造成的线程浪费),使用方式大抵和创建线程相似(使原创 2022-07-02 21:47:51 · 426 阅读 · 0 评论 -
JAVA学习实战(六)Kafka简介
Apache Kafka是一个消息系统用作解决数据处理管道以及活动流的基础,现在已经被越来越多的公司用作多种类型的数据管道和消息系统使用活动流是所有网站做报表的时候最常规的部分,其包括页面的访问量,被查看内容方面的信息以及搜索情况等内容,这种数据通常的处理方式是先把各种活动存储为日志的形式,然后定期进行离线统计关于Kafka主要介绍四个概念1.生产者和消费者这个很好理解,kafka其实就是一个管道,生产者创建消息,消费者接受消息2.主题和分区这个其实也不算难理解吧,主题就是对于不同的主主题的消息各原创 2022-06-27 22:38:38 · 669 阅读 · 0 评论 -
JAVA学习实战(五) 多线程Callable和Future以及FutureTask
多线程据本人调研主要分为以下三种实现方法:1.实现Runnable 接口2.继承Thread类3.通过Callable和Future1和2的方法其实基本相似,翻看实现后发现Thread类的本质也是实现了Runnable接口,由于网上相似的资料实在太多,随便一搜就能找到很多用法,因此不在这里过多阐述,只是简单介绍一些实现细节而非使用方法进程和线程的区别可以理解为进程就是一个执行中的应用程序,线程是进程中的执行单元一个进程可以启动多个线程,比如JAVA的虚拟机其实就是一个进程,JVM的主线程调用mai原创 2022-06-20 10:52:25 · 2294 阅读 · 0 评论 -
JAVA学习实战(四)ElasticSearch原理及使用介绍
ElasticSearch是一个开源的,分布式的,可扩展的全文搜索引擎,它可以快速的存储,搜索数据ElasticcSearch是一个RESTful风格的搜哦和数据分析引擎,他的底层是Apache Lucene,Lucene使用过于复杂,因此ES应运而生,其使用JAVA编写,简单来说就是对Lucene去做了一层封装,提供了一套简单的API来帮助我们实现存储和检索的功能。ES概述:ES是面向文档的,这意味着它可以存储整个对象或者文档,并且他还有搜索功能,在ES中,你可以通过对文档进行索引,排序,搜索过滤简单原创 2022-06-10 20:35:57 · 1884 阅读 · 0 评论 -
JAVA学习实战(三)Redis实际使用
Redis的简单介绍以及内部的结构之前的帖子里已经写到过,感兴趣的可以看一下这一篇文章Redis介绍今天我们主要看Redis的使用以及使用Redis完成一些小的功能安装Redis。并且在pom.xml中加入 spring-boot-starter-data-redis 起步依赖。在 application.properties 上配置Redis。在 config 中配置 RedisConfig 类,返回 RedisTemplate 类。该类可以对 Redis 数据库进行操作。Redis中的key值原创 2022-06-09 17:22:08 · 570 阅读 · 2 评论 -
JAVA学习实战(二) Spring框架之AOP编程--@Aspect
AOP全名为Aspect Oriented Programming意思是面向切面编程通过预编译和运行期动态代理的方式实现程序的统一维护的一种技术利用AOP可以使得业务逻辑的各个部分进行隔离,从而使得业务逻辑的耦合性降低,提高程序的重用性想要在Spring中使用AOP,有两种方式1.注解2.XML配置本文主要讲解的是使用注解的方法Spring AOP中将日志记录,性能统计,安全控制事物处理,异常处理等与业务代码无关的代码从业务代码中剖离开来结合实例看一下具体用法@Component@Aspe原创 2022-06-09 09:56:53 · 878 阅读 · 0 评论 -
JAVA学习实战(一)登录拦截器实现以及注解LogRequired实现(内含拦截器 HandlerInterceptor 的详细讲解以及注解的具体实现方法)
前几天在学习一个网站项目的时候看到了Java的注解这个东西的实现感觉挺有意思的,想结合项目进行一个简单的讲解,希望能够帮助自己复习巩固一遍,同时也能够帮助更多学习过的人如图,上面是一个注解的实现,其实实现方法很简单,只需要加上@interface即可@interface用来定义一个自定义注解在Java中,定义注解其实和定义接口很相似,如上图所示,即定义了一个注解LogRequired,那么如果我们想要给注解中传入某些值其实也很简单,只需要如下定义这样如果要使用时,只需要@LogRequired(原创 2022-06-08 20:25:47 · 1911 阅读 · 0 评论