自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 线程池中execute和submit的区别?

submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。Worker实现了Runable接口,在调用start()方法候,实际执行的是run方法Worker实现了Runable接口,在调用start()方法候,实际执行的是run方法。execute在执行任务时,如果遇到异常会直接抛出,而submit不会直接抛出,只有在使用Future的get方法获取返回值时,才会抛出异常。

2025-06-12 09:00:00 519

原创 AI大模型入门知识

这段时间各种AI名词一波接一波的冲击着我的屏幕,Agent,MCP,FunctionCalling,RAG,它们都是什么东西有人说Agent是智能体,那智能体又是什么呢?有人说MCP是AI时代的USB协议,那么它可以接U盘吗?它们到底都是什么意思?

2025-06-10 09:00:00 832

原创 你了解Java线程池原理吗?

corePoolSize:当有新任务时,如果线程池中线程数没有达到核心线程池的大小corePoolSize,则会创建新的线程执行任务,否则将任务放入阻塞队列。当线程池中存活的线程数总是大于 corePoolSize 时,应该考虑调大 corePoolSize。maximumPoolSize:当阻塞队列填满时,如果线程池中线程数没有超过最大线程数maximumPoolSize,则会创建新的线程运行任务。如果线程池中线程数已经达到最大线程数maximumPoolSiz,则会根据拒绝策略处理新任务。

2025-06-09 09:00:00 610

原创 剑指offer-1、⼆维数组中的查找

在⼀个⼆维数组中(每个⼀维数组的⻓度相同),每⼀⾏都按照从左到右递增的顺序排序,每⼀列都按照从上到下递增的顺序排序。请完成⼀个函数,输⼊这样的⼀个⼆维数组和⼀个整数,判断数组中是否含有该整数。题目提示了,每⼀⾏都按照从左到右递增的顺序排序,每⼀列都按照从上到下递增的顺序排序,那我们其实就可以利用矩阵的排序特性可以从右上角或左下角开始查找,从而优化搜索效率。而如果是从左上角开始找,这种两个方向都更大, 如果从右下角开始找,两个方向都更小,显然无法完成搜索。- 如果当前元素大于目标值,向左移动一列。

2025-06-06 09:00:00 114

原创 算法题:数组中的第k个最大元素

很显然,nums[i] 最终所在的位置,也就是它排序后的具体位置。也就是说,如果实现的排序是降序排序,那么第k个位置的数据,也确定就是第k大的。而这样每经过一次 partition操作就能缩小搜索的范围,这样的思想叫做 “减而治之”(是 “分而治之” 思想的特例)。你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。但是,如果出了这道题,显然不是想让你调 API ,而是看你对快排的理解。个元素中最小的,有就是所有元素中第 k。请注意,你需要找的是数组排序后的第。

2025-06-05 09:00:00 369

原创 Synchronized是怎么实现的?

可重入锁是一种特殊的互斥锁,它允许同一个线程在持有锁的情况下再次获取该锁。也就是说,同一个线程可以多次获取同一个可重入锁,而不会发生死锁。在 Java 中,synchronized关键字就是一种可重入锁。当一个线程使用synchronized修饰的方法或代码块时,它会获得该对象的锁。如果该线程在持有锁的情况下再次调用同一个对象的synchronized方法或代码块,那么它会再次获得该对象的锁,而不会等待其他线程释放锁。可重入锁的好处是可以避免死锁的发生。

2025-06-04 09:00:00 721

原创 Linux常用命令介绍-系统管理

rpm命令来自英文词组redhat package manager的缩写,中文译为“红帽软件包管理器”,其功能是在Linux系统下对软件包进行安装、卸载、查询、验证、升级等工作,常见的主流系统(如RHEL、CentOS、Fedora等)都采用这种软件包管理器,推荐用固定搭配“rpm-ivh 软件包名”安装软件,而卸载软件则用固定搭配“rpm -evh 软件包名”,简单好记又好用。正数表示在指定的时间内修改或访问过的文件,负数表示在指定的时间之前修改或访问过的文件,零表示在当前时间点上修改或访问过的文件。

2025-06-03 09:00:00 737

原创 你了解ConcurrentHashMap吗?ConcurrentHashMap九连问

多线程环境下,使用Hashmap进行put操作会造成数据覆盖,应该使用支持多线程的 ConcurrentHashMap。

2025-05-30 09:00:00 677

原创 从尾到头打印链表

前⾯我们能想到栈,那么我们何必⾃⼰实现呢?先把元素⾥⾯的元素从头到尾遍历取出放在栈⾥⾯,然后再把栈的元素去出来放在ArraList ⾥⾯。主要利⽤了栈的先进后出的规则,这样就可以实现倒序的功能。遍历每⼀个节点,然后把它插⼊到头部,这样⼀直遍历到尾的时候,就相当于将整个链表都反转⼀遍了,然后再从头到尾遍历放到ArryList 即可。输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。0 <= 链表长度 <= 10000。返回一个数组为[3,2,1]

2025-05-29 09:00:00 468

原创 Linux常用命令介绍-文档编辑

echo命令的功能是在终端设备上输出指定字符串或变量提取后的值,能够给用户一些简单的提醒信息,亦可以将输出的指定字符串内容同管道符一起传递给后续命令作为标准输入信息进行二次处理,还可以同输出重定向符一起操作,将信息直接写入文件。rm也是一个很危险的命令,使用的时候要特别当心,尤其对于新手更要格外注意。是删除的意思,因为删除了 2-5 行,所以显示的数据就没有 2-5 行了, 另外,原本应该是要下达 sed -e 才对,但没有 -e 也是可以的,同时也要注意的是, sed 后面接的动作,请务必以。

2025-05-27 09:00:00 958

原创 Linux常用命令介绍-文件管理

文件或目录的权限位是由9个权限位来控制,每三位为一组,它们分别是文件所有者(User)的读、写、执行,用户组(Group)的读、写、执行以及其它用户(Other)的读、写、执行。cp命令是用于文件的复制操作,文件个数是增加的,而mv则为剪切操作,也就是对文件进行移动(搬家)操作,文件位置发生变化,但总个数并无增‍加。这两个参数尤为常用。设置权限时可以使用数字法,亦可使用字母表达式,对于目录文件,建议加入-R参数进行递归操作,这意味着不仅对于目录本身,而且也对目录内的子文件/目录进行新权限的设定。

2025-05-26 09:00:00 1464

原创 如果让你改造下 HashMap 的扩容实现,你会怎样优化?

假设有一个 1G 大的 HashMap,此时用户请求过来刚好触发它的扩容.那么当前用户请求会被阻塞,因为 HashMap的底层是基于数组+链表(红黑树)来实现的,一旦它发生扩容,就需要新增一个比之前大2倍的数组,然后将元素copy到新的数组上那么如何优化呢?

2025-05-23 09:00:00 885

原创 假设有一个 1G 大的 HashMap,此时用户请求过来刚好触发它的扩容,会怎样?

/ 容纳键值对的最大值// 负载因子int size;Node[] table的初始化长度length为16,默认的loadFactor是0.7。为什么默认负载因子是 0.75?官方答案如下:上面的意思,简单来说是默认负载因子为 0.75,是因为它提供了空间和时间复杂度之间的良好平衡。负载因子太低会导致大量的空桶浪费空间,负载因子太高会导致大量的碰撞,降低性能。0.75 的负载因子在这两个因素之间取得了良好的平衡。

2025-05-22 09:00:00 1207

原创 反转链表(花式反转)

最好的方式还是双指针解法;如果数据量较大,递归解法和借用栈的方式都有可能导致栈溢出的情况。

2025-05-21 09:00:00 785

原创 RocketMQ源码详解(消息存储、Consumer

消息存储流程消息存储入口:DefaultMessageStore#putMessage代码:CommitLog#putMessage代码:MappedFile#appendMessagesInner代码:CommitLog#doAppend代码:CommitLog#calMsgLength代码:CommitLog#doAppend代码:CommitLog#putMessage存储文件RocketMQ通过使用内存映射文件提高IO访问性能,无论是CommitLog、ConsumerQueue还

2025-05-20 09:00:00 996

原创 RocketMQ源码详解(NameServer、Producer)

消息中间件的设计思路一般是基于主题订阅发布的机制,消息生产者(Producer)发送某一个主题到消息服务器,消息服务器负责将消息持久化存储,消息消费者(Consumer)订阅该兴趣的主题,消息服务器根据订阅信息(路由信息)将消息推送到消费者(Push模式)或者消费者主动向消息服务器拉去(Pull模式),从而实现消息生产者与消息消费者解耦。那消息生产者如何知道消息要发送到哪台消息服务器呢?消息生产者的代码都在client模块中,相对于RocketMQ来讲,消息生产者就是客户端,也是消息的提供者。

2025-05-19 09:00:00 885

原创 讲讲深拷贝和浅拷贝?

在clone()后,克隆后的对象开始也是指向的原来引用地址值(刚克隆完检查a1.category == a2.category 为true),但是一旦String的值发生改变(String作为不可更改的类——immutable class,在新赋值的时候,会创建了一个新的对象)就改变了克隆后对象指向的地址,让它指向了一个新的String地址,不会影响原对象的指向和值,原来的String对象还是指向的它自己的的地址。当类中含有引用类型的属性时,新对象和旧对象的引⽤类型属性指向的是同⼀个对象,即为浅拷贝。

2025-05-16 09:15:00 665

原创 RocketMQ高级使用

分布式队列因为有高可靠性的要求,所以数据要进行持久化存储。Apache下开源的另外一款MQ—ActiveMQ(默认采用的KahaDB做消息存储)可选用JDBC的方式来做消息持久化,通过简单的xml配置信息即可实现JDBC消息存储。由于,普通关系型数据库(如Mysql)在单表数据量达到千万级别的情况下,其IO读写性能往往会出现瓶颈。在可靠性方面,该种方案非常依赖DB,如果一旦DB出现故障,则MQ的消息就无法落盘存储会导致线上故障文件系统目前业界较为常用的几款产品(RocketMQ/Kafka/RabbitMQ

2025-05-15 09:15:00 781

原创 手写生产者消费者模型

生产者-消费者模式是一个十分经典的多线程并发协作模式,弄懂生产者-消费者问题能够让我们对并发编程的理解加深。这也是校招常见面试手撕题所谓的生产者-消费者,实际上包含了两类线程,一种是生产者线程用于生产数据,另一种是消费者线程用于消费数据,为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库,生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为;而消费者只需要从共享数据区中获取数据,不需要关心生产者的行为。如果共享数据区已满的话,阻塞生产者继续生产数据;

2025-05-14 09:15:00 1024

原创 了解泛型擦除吗?知道类型擦除会造成多态的冲突吗?如何解决?

泛型的代码只存在于编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,称之为类型擦除。<T>

2025-05-13 09:15:00 543

原创 RabbitMQ高级使用

在支付场景中,支付成功后利用RabbitMQ通知交易服务,更新业务订单状态为已支付。但是大家思考一下,如果这里MQ通知失败,支付服务中支付流水显示支付成功,而交易服务中的订单状态却显示未支付,数据出现了不一致。此时前端发送请求查询支付状态时,肯定是查询交易服务状态,会发现业务订单未支付,而用户自己知道已经支付成功,这就导致用户体验不一致。因此,这里必须尽可能确保MQ消息的可靠性,即:消息应该至少被消费者处理1次该如何确保MQ消息的可靠性?如果真的发送失败,有没有其它的兜底方案?

2025-05-12 09:15:00 1177

原创 RabbitMQ基础入门

接下来,我们就学习它的基本概念和基础用法。多个消费者绑定到一个队列,同一条消息只会被一个消费者处理通过设置prefetch来控制消费者预取的消息数量交换机的作用是什么?接收publisher发送的消息将消息按照规则路由到与之绑定的队列不能缓存消息,路由失败,消息丢失FanoutExchange的会将消息路由到每个绑定的队列描述下Direct交换机与Fanout交换机的差异?Fanout交换机将消息路由给每一个与之绑定的队列。

2025-05-08 09:15:00 1117

原创 编写一段代码,使其必定产生死锁

编写一段代码,使得这段代码必定会产生死锁。

2025-05-07 09:15:00 387

原创 为什么重写equals一定也要重写hashCode方法?

==” 是运算符如果比较的对象是基本数据类型,则比较的是其存储的值是否相等;如果比较的是引用数据类型,则比较的是所指向对象的地址值是否相等(是否是同一个对象)。int a = 10;int b = 10;//true//显然不是同一个对象,false。

2025-05-06 08:15:00 1011

原创 缓存穿透的解决方式?—布隆过滤器

布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,查询时可以用来判断 “一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。布隆过滤器的空间效率O(m) 和查询时间O(k) 都很优秀,但是存在一定的误判率 (布隆过滤器认为不存在,则一定不存在;布隆过滤器认为存在,则只是可能存在)bit数组的位数m越大,hash函数的个数k越多,误判率就越低。

2025-04-30 08:15:00 974

原创 记录一次线上问题排查:JDK序列化问题

新加了个字段,然后发版,上线就发现了报错当时这个问题很简单,其实就是用的是 JDK序列化,当时这个类实现了 Serializable接口,但是没显示定义 serialVersionUID,这样一来序列化时会根据当前类的信息计算得到一个 serialVersionUID。

2025-04-29 08:15:00 739

原创 为什么不能用浮点型表示金额?

BigDecimal可以实现对浮点数的运算,不会造成精度丢失。通常情况下,大部分需要浮点数精确运算结果的业务场景(比如涉及到钱的场景)都是通过BigDecimal来做的。想要解决浮点数运算精度丢失这个问题,可以直接使用BigDecimal来定义浮点数的值,然后再进行浮点数的运算操作即可。// 0。

2025-04-28 08:15:00 1469

原创 如何统计不同电话号码的个数?—位图法

有人说遍历,使用HashSet或者int数组来存储,这里先不谈算法效率的问题,这100亿数据如何在能否在内存中放下也是一个问题。如果用int类型来存储这100亿个电话号码,那么就需要 100亿 * 4字节 = 37GB ≈ 40GB。所以这些方法行不通的根本原因实际上是内存不够。

2025-04-24 08:15:00 1683

原创 面试官:包装类型的缓存机制了解么?

当赋值100给Integer时,刚好在这个范围内,所以从cache中取对应的Integer并返回,所以a和b返回的是同一个对象,所以 比较是相等的,当赋值200给Integer时,不在cache 的范围内,所以会new Integer并返回,当然 比较的结果是不相等的。1、2、3都好理解,缓存范围是 [-128,127],1、2都在范围内,返回的是缓存中的对象,因此输出true,3不在范围内,返回的是新 new 的Integer,因此输出false。那为什么4输出的是true呢?

2025-04-23 08:15:00 368

原创 JDK的SPI有什么缺陷?dubbo做了什么改进?

在com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName)这个代码中,当然这个是有在具体的暴露服务或者引用远程服务才被调用执行的。到这一步就可以认为是dubbo的spi加载整个的过程完成了,整个链路有些长,需要好好的梳理一下。

2025-04-22 08:15:00 853

原创 面试官:SpringBoot 工程启动以后,希望将数据库中已有的固定内容提前加载到 Redis 缓存中,应该如何处理

这两个是Springboot中新增的扩展点,之所以将这两个扩展点放在一起,是因为它两个功能特性高度相似,不同的只是名字、扩展方法形参数类型、执行先后的一些小的不同。这两个接口触发时机为整个项目启动完毕后,自动执行。如果有多个,可以利用@Order来进行排序。CommandLineRunner和ApplicationRunner都有一个扩展方法run(),但是run()形参数类型不同;

2025-04-21 08:15:00 1925

原创 dubbo高级特性介绍

首先是支持事务的,但与关系型数据库的事务有区别。

2025-04-17 08:15:00 633

原创 ZooKeeper实现分布式锁

如果发现比自己小的那个节点被删除,则客户端的Watcher会收到相应通知,此时再次判断自己创建的节点是否是lock子节点中序号最小的,如果是则获取到了锁,如果不是则重复以上步骤继续获取到比自己小的一个节点并注册监听。当某个客户端释放锁时,需要触发所有等待的客户端获取锁,可能会导致较多的网络通信和监听事件。在整个分布式锁的竞争过程中,大量的「Watcher通知」和「子节点列表的获取」操作重复运行,并且大多数节点的运行结果都是判断出自己当前并不是编号最小的节点,继续等待下一次通知,而不是执行业务逻辑。

2025-04-15 08:15:00 1043

原创 Redis实现高并发场景下的计数器设计

大部分互联网公司都需要处理计数器场景,例如风控系统的请求频控、内容平台的播放量统计、电商系统的库存扣减等。传统方案一般会直接使用INCR 有,即当 Redis 检测到目标 key 不存在时,会,再执行递增操作。

2025-04-14 08:15:00 545

原创 深入理解请求限流算法的实现细节

在微服务架构中,服务与服务之间通过远程调用的方式进行通信,一旦某个被调用的服务发生了故障,其依赖服务也会发生故障,此时就会发生故障的蔓延,最终导致灾难性雪崩效应。。本文则着重介绍请求限流算法。

2025-04-11 08:15:00 592

原创 正则表达式规则详解

【代码】正则表达式规则详解。

2025-04-08 08:15:00 516

原创 电商平台中订单未支付过期如何实现自动关单?

日常开发中,我们经常遇到这种业务场景,如:外卖订单超 30 分钟未支付,则自动取订单;用户注册成功 15 分钟后,发短信息通知用户等等。这就是延时任务处理场景。在电商,支付等系统中,一设都是先创建订单(支付单),再给用户一定的时间进行支付,如果没有按时支付的话,就需要把之前的订单(支付单)取消掉。这种类以的场景有很多,还有比如到期自动收货,超时自动退款,下单后自动发送短信等等都是类似的业务问题。

2025-04-07 08:15:00 976

原创 【Guava】并发编程ListenableFuture&Service

AbstractExecutionThreadService可以把一个具体的异步操作封装成Service服务。说白了就是把之前在线程的实现逻辑封装成服务,把之前线程的具体实现逻辑搬到AbstractExecutionThreadService的实现方法run()方法去执行。

2025-04-04 08:15:00 1673

原创 【Guava】IO工具

其次,它还提供了更丰富的功能,比如对不同字符集的处理,还有资源的高效管理。在Java中,流(Streams)是处理数据的核心,不论是文件I/O还是网络通信,流都扮演着至关重要的角色。传统的Java I/O操作,虽然功能强大,但代码写起来往往既长又复杂,但是,有了Guava,这一切都变得轻松多了。在传统的Java I/O中,写文件也是一大堆代码,需要处理流的打开和关闭,还得小心处理异常。两个概念,指可以从中打开流的资源,比如 File、URL,同样也分别有字节和字符对应的源和汇,定义了一系列读写的方法。

2025-04-03 08:15:00 663

原创 【Guava】集合工具Collections2

如果是Collections2.FilteredCollection类,则直接转型到Collections2.FilteredCollection,然后返回这个类。如果不是Collections2.FilteredCollection,则new一个,将传入的容器和规则传入。传入一个带过滤的容器,和一个实现过滤规则的函数类,返回一个带有过滤动作的容器。私有构造器,也没有静态构造器,所以可以很明确它是一个纯工具类了。传入一个转型的类,再传入一个转型规则。

2025-04-02 08:15:00 205

空空如也

空空如也

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

TA关注的人

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