自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(86)
  • 收藏
  • 关注

原创 mysql常见的日期函数

mysql常见的日期函数

2024-03-29 09:12:25 231

原创 62.日常问题整理[2023/02/20]excel获取列个数 getPhysicalNumberOfCells 和 getLastCellNum

excel获取列个数

2024-03-29 09:02:57 108

原创 使用redis RedisAtomicLong 生成订单号

公司系统有部署多台服务,这需要一个有序的序列不能重复而且得保证获取时的原子性这里 我们考虑使用了redis Incr 这个命令。产品需求要生成有序的订单 key+ 年月日时分秒 +6位序号 由00001-99999组成 且每天都是从00001开始。Redis Incr 命令能将 key 中储存的数字值增一,这样就不会取到重复的编号。需要提前引入Redis。

2024-03-27 08:57:04 298

原创 Path用法

Path接口 是JDK1.7中定义的接口,主要用来在文件系统中定位文件,通常表示系统相关的文件路径。1)path.getFileName():获取文件、目录或者其他类型文件(下文统统用文件指代这几种情况的任一)的名称,返回值类型是Path。Files.createDirectories(Path path) 是Java中用于创建多级目录的方法,它位于java.nio.file.Files类中。根据前面可以知道,Path接口主要是用来管理文件路径的,所以文件路径管理涉及的主要也是Path中的方法。

2024-03-27 08:28:31 338

原创 jdbc批量插入

使用addBatch()/executeBatch()/clearBatch()方法。addBatch(String):添加需要批量处理的sql语句。executeBatch():执行批量处理语句。clearBatch():清空缓存的数据。

2024-03-14 19:45:29 170

原创 rabbitmq消息重试

想想看,延时队列,不就是想要消息延迟多久被处理吗,TTL 则刚好能让消息在延迟多久之后成为死信,另一方面,成为死信的消息都会被投递到死信队列里,这样只需要消费者一直消费死信队列里的消息就完事了,因为里面的消息都是希望被立即处理的消息。一般来说,producer 将消息投递到 broker 或者直接到 queue 中,consumer 从 queue 取出消息进行消费,但某些时候由于特定的原因导致 queue 中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。

2024-03-07 14:38:45 1242

原创 一文彻底搞懂 TCP三次握手、四次挥手过程及原理

反过来说,看到首部,也就能够了解该协议必要的信息以及所要处理的数据。32位序号 seq:Sequence number 缩写seq ,TCP通信过程中某一个传输方向上的字节流的每个字节的序号,通过这个来确认发送的数据有序,比如现在序列号为1000,发送了1000,下一个序列号就是2000。客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务。

2024-03-07 09:34:50 277

原创 SpEL应用实战

通过使用 SpEL,我们可以将参数处理逻辑表达为字符串表达式,并在运行时动态地解析和执行表达式,从而实现对不同渠道参数的处理。通过以上设计思路,可以实现一个可配置的领域能力,提高代码的可维护性和扩展性,同时降低了开发和部署的工作量。表达式模板化:SpEL支持在表达式中使用模板语法,允许将一些常用的表达式作为模板,然后在运行时通过填充不同的值来生成最终的表达式。上述两种设计似乎对参数处理能力的抽象力度还不够,是否能将其抽象为一个领域能力,以实现参数处理的动态化或可配置化,而不再依赖于硬编码的参数处理逻辑。

2024-03-06 15:50:32 562

原创 epoll性能那么高,为什么?

而epoll不是这样,epoll只要有新的io就调用epoll_ctl()加入到红黑树里面,一旦有触发就用。那么就绪集合用什么数据结构呢,首先就绪集合不是以查找为主的,就绪集合的作用是将里面的元素拷贝给用户进行处理,所以集合里的元素没有优先级,那么就可以采用线性的数据结构,使用队列来存储,先进先出,先就绪的先处理。也就是说可以把epoll的工作环境看出三部分,左边应用程序的api,中间的epoll,右边是协议栈的回调(协议栈当然不能直接操作epoll,中间的vfs在此不是重点,就直接省略vfs这一层了)。

2024-03-06 14:34:57 712

原创 用过CompletableFuture吗?

需要注意的是,如果最快完成的任务出现异常,则返回的CompletableFuture 执行 get() 方法时会抛出异常。需要注意的是,如果任意一个任务出现异常,则返回的CompletableFuture 执行 get() 方法时会抛出异常。如 Demo2 所示,我们可以通过thenRun() 、thenAccept()、thenApply() 方法将前后任务连接起来,形成前后有依赖的任务链。通过CompletableFuture提供的方法,可以方便地对任务进行链式操作,构建复杂的任务依赖关系。

2024-03-06 14:03:48 252

原创 解锁Spring Security注解鉴权与CAS整合实践

在这个例子中,我们使用SimpleGrantedAuthority表示自定义权限,并在构造CustomUserDetails时进行相应的处理。在上述配置中,我们通过authenticationUserDetailsService()方法返回了一个自定义的AuthenticationUserDetailsService实现,用于从CAS验证结果中构建CustomUserDetails对象。在接口层面,我们可以使用Spring Security提供的注解鉴权功能,结合CAS验证结果的权限信息进行精细控制。

2024-03-06 11:59:12 1357

原创 Spring Boot 中 @Enablexx注解原理

ConfigurationClassPostProcessor既然是一个后置处理器,我们就直接从其后置处理方法入手即可,经过debug调试发现ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()是完成对@Component,@ComponentScan,@Bean,@Configuration,@Import等等注解的处理的入口方。之后就会回到processConfigBeanDefinitions方法,也就是执行完了。

2024-03-06 11:11:05 1102

原创 SpringBoot配置文件加载和生效顺序

我们先来看下ConfigDataImporter.resolveAndLoad()方法。通过以上结合源码的分析,小伙伴们是否清楚配置文件的加载顺序了呢?本章节就结合源码补充说明下。

2024-03-06 10:33:58 278

原创 Spring Boot 如何集成JWT实现Token验证

它定义了一种紧凑的,自包含的方式,用于通信双方之间以JSON对象的形式安全传递信息。JWT使用HMAC算法或者是RSA的公私秘钥的数字签名技术,所以这些信息是可被验证和信任的。近年来,随着前后端分离、微服务等架构的兴起,传统的cookie+session身份验证模式已经逐渐被基于Token的身份验证模式取代。然后,调用http://localhost:8080/testToken 验证token是否有效。JWT(Java版)的github地址:https://github.com/jwtk/jjwt。

2024-03-06 10:22:02 870

原创 SpringBoot 实现动态切换数据源

这两个方法,翻看源码我们会发现其实就是在使用ThreadLocal时使用了栈,这样的好处就是能使用多数据源嵌套,这里就不带大家实现了,有兴趣的小伙伴可以看看Mybatis-plus中动态数据源的源码。通过配置类,将配置文件中的配置的数据库信息转换成datasource,并添加到DynamicDataSource中,同时通过@Bean将DynamicDataSource注入Spring中进行管理,后期在进行动态数据源添加时,会用到。为了方便,我们将之前的从库录入到数据库中,修改数据库名称。

2024-03-06 08:41:58 934

原创 接口优化的常见方案实战总结

关于锁粒度:就是你要锁的范围有多大,不管是synchronized还是redis分布式锁,只需要在临界资源处加锁即可,不涉及共享资源的,不必要加锁,就好比你要上卫生间,只需要把卫生间的门锁上就可以,不需要把客厅的门也锁上。我们都用过数据库连接池,线程池等,这就是池思想的体现,它们解决的问题就是避免重复创建对象或创建连接,可以重复利用,避免不必要的损耗,毕竟创建销毁也会占用时间。变换思路,更高一级思考问题,站在接口设计者的角度去开发需求,会避免很多这样的问题,也是降本增效的一种行之有效的方式。

2024-03-06 08:19:41 506

原创 JAVA面试题分享五百四十二:如何向SpringBoot注入数据?

在这里插入图片描述在SpringBoot中常用的简单类型参数进行配置属性注入的注解有以下两个:@Value 注解: 用于从配置文件中注入简单类型的值@ConfigurationProperties 注解:用于将配置文件中的属性映射到对象中 接下来我们就详细介绍一下这个两个注解@Value 注解用于从配置文件中注入简单类型的值 @Value注解进行属性注入步骤如下:在项目application.yml添加参数注意:属性类上的@Component或者@Configuration一定要加上,只有加上该注解

2024-03-06 08:12:27 470

原创 用Spring AOP解决分布式锁问题:保障数据一致性,提升系统可靠性!

Spring AOP是Spring框架的一个重要组成部分,它通过在程序运行时动态地将代码切入到类的方法中,实现了横切关注点的模块化。分布式锁是一种常见的解决方案,它确保在某个时刻只有一个节点能够对共享资源进行操作,从而防止竞态条件的发生。这里我们以Redis作为分布式锁的存储介质,通过AOP的@Before和@After通知,在方法执行前后进行锁的获取和释放。避免使用过于宽泛的切入点,尽量将锁的范围限制在必要的方法上。使用合适的线程池配置,确保异步操作的执行效率和系统的稳定性。4.2 锁的配置和灵活性。

2024-03-06 08:12:15 238

原创 大厂都怎么防止重复下单?

系统异常时 666 请求到了,单号更成 666,接着 888 请求到了,单号又更新成 888,但是 666 更新成功的响应丢了,调用方没收到成功响应,自动重试,再次发起 666 请求,单号又被更新成 666了,这数据显然就错了。在用户进入创建订单页面时,前端页面先调用该 orderId 生成接口得到一个订单号,在用户提交订单时,在创建订单的请求中携带该订单号。更新订单服务,通过一个版本号机制,每次更新数据前校验版本号,更新数据同时自增版本号,这样的方式,来解决 ABA 问题,确保更新订单服务的幂等性。

2024-03-06 08:11:50 851

原创 什么是接口的幂等性,如何保证接口的幂等性?

简单的说就是调用方在调用接口的时候先向后端请求一个全局 ID(Token),请求的时候携带这个全局 ID 一起请求**(Token 最好将其放到 Headers 中)**,后端需要对这个 Token 作为 Key,用户信息作为 Value 到 Redis 中进行键值内容校验,如果 Key 存在且 Value 匹配就执行删除命令,然后正常执行后面的业务逻辑。更新数据的同时version+1,然后判断本次update操作的影响行数,如果大于0,则说明本次更新成功,如果等于0,则说明本次更新没有让数据变更。

2024-03-05 20:29:34 828

原创 JAVA面试题分享五百五十九:SSO 单点登录和 OAuth2.0 的区别和理解

在本例实现SSO的过程中,受保护的资源就是用户的信息(包括,用户的基本信息,以及用户所具有的权限),而我们想要访问这这一资源就需要用户登录并授权,OAuth2服务端负责令牌的发放等操作,这令牌的生成我们采用JWT,也就是说JWT是用来承载用户的Access_Token的。SSO大家应该比较熟悉,用户浏览器重定向到单点登录系统,系统检查该用户是否登录,这是SSO(这里是CAS)系统的第一个接口,该接口如果用户未登录,则将用户重定向到登录界面,如果已登录,则设置全局session,并重定向到业务系统。

2024-03-05 17:17:50 517

原创 JAVA面试题分享五百六十三:如何防止短信盗刷和短信轰炸?

添加图形验证码:用户发送短信前,需要先输入正确的图形验证码,或拖动验证码等验证,验证通过之后,才能正常发送短信验证码。后端程序拿到(图形)验证码之后,先验证(图形)验证码的正确性.如果正确,则发送短信验证码,否则,将不执行后续流程并返回执行失败给前端,核心实现代码如下。开启短信提供商的防控和报警功能:几乎所有的短信提供商都提供了,异常短信的防控和提醒功能,开启这些保护措施,可以尽可能的避免短信盗刷的问题。前端用户拿到图形验证码之后,输入图形验证码,请求后端程序验证,并发送短信验证码。

2024-03-05 17:02:27 340

原创 万字详解Ribbon架构,针对面试高频题多角度细说Ribbon

上一章节我们学习了注册中心《阿里面试官问我:到底知不知道什么是Eureka,这次,我没沉默》,我们知道但我们存在多个服务提供者的时候,我们会让所有的服务提供者将服务节点信息都注册到EurekaServer中,然后让客户端去拉取一份服务注册列表到本地,服务消费者会从服务注册列表中找到合适的服务实例信息,通过IP:Port的方式去调用服务。简单的说,Ribbon是Netflix发布的开源顶目,主要功能是解析配置中或注册中心的服务列表,通过客户端的软件负均衡算法来实现服务请求的分发。眼尖的同学肯定已经发现了,

2024-03-05 15:10:32 544

原创 京东面试题(Redis):为啥RedisCluster设计成16384个槽

Redis Cluster 是Redis的集群实现,内置数据自动分片机制,集群内部将所有的key映射到16384个Slot中,集群中的每个Redis Instance负责其中的一部分的Slot的读写。Redis主节点的配置信息中,它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中,会对bitmap进行压缩,但是如果bitmap的填充率slots / N很高的话(N表示节点数),bitmap的压缩率就很低。如上所述,集群节点越多,心跳包的消息体内携带的数据越多。没有必要拓展到65536个。

2024-03-05 14:54:30 769

原创 Redis性能瓶颈揭秘:如何优化大key问题?

对于大Key的操作,如读取、写入、删除等,都会消耗更多的CPU时间和内存资源,进一步降低系统性能。启用Redis的内存淘汰策略,例如LRU(Least Recently Used,最近最少使用),以便在内存不足时自动淘汰最近最少使用的数据,防止大Key长时间占用内存。没有固定的判别标准,通常认为字符串类型的key对应的value值占用空间大于1M,或者集合类型的k元素数量超过1万个,就算是大key。为每个key设置过期时间,并设置合理的过期时间,以便在数据失效后自动清理,避免长时间累积的大Key问题。

2024-03-05 14:44:38 594

原创 微服务 Spring Cloud 5,一图说透Spring Cloud微服务架构

每个微服务实例在启动时,将自己的IP地址和端口号等信息注册到DNS服务器,浏览器通过查询DNS服务器,获取可用的服务实例的网络位置信息,从而实现服务的自动发现和动态更新。静态资源服务,Nginx可以提供静态资源服务,如图片、视频、JavaScript文件、CSS文件、HTML静态文件等,减轻后端服务的压力,提高系统的响应速度和性能。配置中心:Nacos提供了动态配置服务,可以动态的修改配置中心中的配置项,不需要重启后台服务,即可完成配置的修改和发布,提高了系统的灵活性和可维护性。

2024-03-05 14:16:53 512

原创 微服务 Spring Cloud 8,开源RPC框架如何选型?

以上就是我对几种使用最广泛的开源RPC框架的选型建议,也是基于它们目前现状所作出的判断,从长远来看,支持多语言是RPC框架未来的发展趋势。此外,Dubbo的实现还采用了分层的思想,每层负责不同的职责,使得用户可以基于Dubbo框架进行二次开发,扩展其功能。Dubbo的RPC层负责建立网络通信连接,实现服务的远程调用。可以看出服务消费者和服务提供者都需要引入Dubbo的SDK才来完成RPC调用,因为Dubbo本身是采用Java语言实现的,所以要求服务消费者和服务提供者也都必须采用Java语言实现才可以应用。

2024-03-05 14:04:03 923

原创 微服务 Spring Cloud 9,RPC框架,客户端和服务端如何建立网络连接?

异步非阻塞方式AIO,客户端只需要发起一个IO操作,然后会立即返回,等IO操作完成后,客户端得到IO操作完成的通知,此时客户端再对返回值进行处理,不需要进行IO读写操作,真正的IO读取和写入操作已经由内核完成了。就是说服务端一旦接受客户端的连接,就可以建立通信套接字在这个通信套接字上进行读写操作,此时不能再接收其他客户端连接请求,只能等待同当前连接的客户端的操作执行完成,不过可以通过多线程来支持多个客户端的连接,循环导致高cpu消耗。Channel(通道) :通道是双向的,可读也可写,而流的读写是单向的。

2024-03-05 13:59:15 725

原创 解密Kafka主题的分区策略:提升实时数据处理的关键

轮询策略有着非常优秀的负载均衡表现,它总是能保证消息最大限度平均分配到所有分区上,所以一般情况下它是最合理的分区策略,也是我们常用的分区策略之一。在这种情况下,订单消息的关键信息是订单ID,你希望具有相同订单ID的消息被写入到同一个分区,以维护订单消息的有序性。吞吐量仍然取决于Kafka集群的性能和生产者的配置,但在这个示例中,重点是保持订单消息的顺序性。​本质上,随机策略也是力求将数据均匀地打散到各个分区,但是从实际表现来看,它要逊于轮询策略,所以如果追求数据的均匀分布,轮询策略比随机策略优秀。

2024-03-05 13:33:46 616

原创 Kafka事务是怎么实现的?Kafka事务消息原理详解

因此,在消息发送后,我们需要根据消息的处理结果来决定是提交事务还是中止事务。创建消费者需要配置参数,包括 Kafka 集群的地址、消息的键和值的反序列化器、消费者组 ID 等。创建生产者需要配置参数,包括 Kafka 集群的地址、消息的键和值的序列化器、事务ID 等。创建生产者需要配置参数,包括 Kafka 集群的地址、消息的键和值的序列化器、事务ID 等。消费者的正确配置和消息处理确保了消息的可靠性和一致性。在本节中,我们将详细讨论如何配置Kafka以支持事务性消息,包括生产者和消费者的设置。

2024-03-05 11:53:27 2087

原创 Kafka消息延迟和时序性详解(文末送书)

一、概括1.1 介绍 Kafka 消息延迟和时序性Kafka 消息延迟和时序性对于大多数实时数据流应用程序至关重要。本章将深入介绍这两个核心概念,它们是了解 Kafka 数据流处理的关键要素。1.1.1 什么是 Kafka 消息延迟?Kafka 消息延迟是指消息从生产者发送到消息被消费者接收之间的时间差。这是一个关键的概念,因为它直接影响到数据流应用程序的实时性和性能。在理想情况下,消息应该以最小的延迟被传递,但在实际情况中,延迟可能会受到多种因素的影响。1.1.2 为什么消息延迟很重要。

2024-03-05 11:40:19 761

原创 请说说MyBatis的工作原理?#{}和${}的区别?Mybatis如何执行批量操作?

基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在XML里,解除sql与程序代码的耦合,便于统一管理;Mybatis在处理时,是原值传入,就是把 {}时,是原值传入,就是把时,是原值传入,就是 把{}替换成变量的值,相当于JDBC中的Statement编译。是 mapper 级别的缓存,对于 mapper 级别的缓存不同的 sqlsession 是可以共享的。输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。

2024-03-05 11:23:29 681

原创 使用懒加载 + 零拷贝后,程序的秒开率提升至99.99%

BufferedReader 是一个缓冲字符输入流,可以对 FileRead 进行包装,提供了一个缓存数组,将数据按照一定规则读取到缓存区中,输入流每次读取文件数据时都需要将数据进行字符编码,而 BufferedReader 的出现,降低了输入流访问数据源的次数,将一定大小的数据一次读取到缓存区并进行字符编码,从而提高 IO 的效率。这是一个比较折中的方案,如果缓冲区太大的话,就会增加单次读写的时间,同样内存的大小也是有限制的,不可能都让你来干这个一件事。Java 的 NIO,用非阻塞的 IO 方式。

2024-03-05 11:02:46 976

原创 csv文件中的hi用特殊字符过滤

【代码】csv文件中的hi用特殊字符过滤。

2024-03-05 09:03:04 124

原创 Java学习笔记-stripTrailingZeros()和toPlainString()

stripTrailingZeros():返回一个BigDecimal,它在数值上等于这一个,但表示形式移除所有尾部零。BigDecimal 原生提供了stripTrailingZeros() 方法可以实现去掉末尾的 0。如果你在这里直接使用 然后使用 toString() 将会转换为科学计数法输出。,将会转换为科学计数法输出,如果你不希望用科学计数法输出的话,那么你可以使用。Java BigDecimal 如何去掉末尾多余的 0 呢?toPlainString():返回不带指数字段的此。

2024-03-04 19:33:28 877

原创 使用 Apache 的 commons-csv 实现 CSV 文件导出

CSV全称是:Comma Separated Values (逗号分隔值)或者 Character Separated Values(字符分隔值)。其文件以纯文本形式存储表格数据(数字和文本)。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。每一行记录位于一个单独的行上,用回车换行符CRLF(也就是\r\n)分割。对于excel来说默认使用 ,进行分割数据。每一行记录最后一个字段后不能跟逗号每一行一条记录。

2024-03-04 19:09:26 1978

原创 RedisTemplate使用最详解(五)--- opsForZSet()

增加key对应的集合中元素v1的score值,并返回增加后的值。向指定key中添加元素,按照score值由小到大进行排列。获取集合的大小,地层调用的还是 zCard(K key)集合中对应元素已存在,会被覆盖,包括score。获取key对应集合中o元素的score值。获取指定元素在集合中的索引,索引从0开始。获取指定score区间里的元素个数。v1不存在,直接新增一个元素。移除指定score区间内的值。获取指定score区间的值。(0,-1)就是获取全部。逆序获取对应下标的元素。获取指定下标之间的值。

2024-03-04 18:33:30 1356

原创 一文带你彻底搞懂Redis实现消息的订阅发布

频道的发布订阅实现原理Redis将所有频道的订阅关系都保存在服务器状态的 pubsub_channels 字典,字典的键是某个被订阅的频道,而对应值则是一个链表,链表里记录了所有订阅这个频道的客户端。2)该频道暂无订阅者该频道在 pubsub_channels 字典中不存在订阅者链表,**首先在字典中为频道创建一个键**,并将这个键的值设置为空链表,然后将客户端添加到链表,成为链表的第一个元素。是长连接,但并不可靠,订阅的时候就代表建立了一个长连接,客户端的订阅者想要接收消息,肯定也会维护长连接。

2024-03-04 14:56:37 1134

原创 索引下推,原来这么简单!

查询条件name LIKE “大%” 不是等值匹配,根据最左匹配原则,在(name, level)索引树上只用到name去匹配,查找到两条记录(id为1和4),拿到这两条记录的id分别回表查询,然后将结果返回给MySQL server,在MySQL server层进行level字段的判断。相比5.6以前的版本,多了索引下推的优化,在索引遍历过程中,对索引中的字段先做判断,过滤掉不符合条件的索引项,也就是判断level是否等于1,level不为1则直接跳过。先来看看MySQL5.6以前的版本。

2024-03-04 14:06:02 402

原创 一文拿捏 RestTemplate — 远程调用

restTemplate底层调用的是Execute方法,而Execute底层调用的是doExecute,它是基于http协议的,底层还是httpClient 的使用。

2024-03-04 11:49:07 1250

空空如也

空空如也

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

TA关注的人

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