消息队列小专题
LeetCode 138 随机数组的复制 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。 例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。 返回复制链表的头节点。 用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示: val:一个表示 Node.val 的整数。 random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。 你的代码 只 接受原链表的头节点 head...
消息队列小专题
今天详细学习了一下消息队列的幂等性与重复消费问题,其实是在AI的模拟面试的时候被狠狠diss了 😥 😥 我在实习的时候,这一条链路的业务大致是这样的,我们拿到模型实例返回的计费数据和日志数据,我们要把他们持久化进Mongo中,持久化操作肯定还是异步比较舒服,而且我们肯定不能在本地直接开启那么多线程直接去异步调用Mongo,这样性能会被浪费,我实习的项目选择的是kafka进行业务解耦,通过consumer去调用Mongo,我们本地只需要发消息就行了。 那么使用消息队列就必须面对几个经典问题,如何保证消息不丢失,如何解决幂等性问题,怎样监控消息堆积量(吓哭了 😰 😰 我们先简单了解一下消息队列的组成和原理(以kafka为例): 要理解 Kafka,必须先掌握这几个核心概念: Producer (生产者): 往记事本上写数据的人(比如你的 MaaS 计费服务)。 Consumer (消费者): 从记事本上读数据的人(比如你的 MongoDB 写入服务)。 Broker (代理/服务器): 存放记事本的服务器节点。 Topic (主题):...
CI/CD
主播最近也是get到一个新的爱好就是健身,可能最近会专门开一篇健身专题吧hahahh 😚 😚 博客荒废了好久,主要是主播实习结束完后给自己放了一个月的假,最近要收收心自律起来了...
m1kasaz的Netty笔记
BIO模型和NIO模型 两个模型都是很常见的Java网络模型 BIO模型:同步阻塞模型,一个线程专门负责一个连接,数据以流的形式传输 NIO模型:同步非阻塞模型,一个线程负责多个连接,其功能被多个组件分摊,Channel为双方提供双向的通信通道,读写数据都要通过Buffer,Selector可以实现高效的多路复用器 两个模型就好比不同餐厅的招待方式,BIO的餐厅就像一位服务员专门负责一桌客人,而且会一直等待客人的命令;NIO餐厅则是一位服务员负责多桌客人,而且只要你不点餐(数据没准备好),我就不会在你的桌前停留 BIO策略只适合连接数量不多,且连接时间较长的情况,过多的连接将导致线程数量过多导致OOM NIO策略下,一个线程被赋予处理多个请求的能力,并发量大大提高 NIO性能很高,为什么我们不直接使用它呢? 答:开发效率不高,使用NIO直接进行开发,开发者需要应付这些问题: Selector 的复杂性:Selector 是 NIO 的核心,但其使用方式反直觉。你需要在一个循环中轮询(select())事件,然后遍历 selected keys,并针对每个 key...
EXPLAIN关键字
前言 距离上次更新过去了差不多一个月,主要一直在忙八股和项目,然后就是投简历改简历,我觉得这是一个瓶颈期,因为一直没有正反馈,迷茫、焦虑,尤其是面对这样的环境,我希望好好沉下心,打好基础,没有机会就先沉淀,不知道过些日子,再回头看看自己写下的这段话,会有什么感想。 欲渡黄河冰塞川,将登太行雪满山:李白在《行路难·其一》中用此句,以渡河被冰堵塞、登山被雪阻挡,象征人生道路上仕途受阻,充满艰难险阻。 EXPLAIN Q:我们为什么要使用explain? A:帮助我们分析sql语句的执行过程 我们想要知道一条sql语句的执行时间可以这样操作: 1234567891011121314-- 1. 首先检查 profiling 功能是否开启,默认可能是关闭的SELECT @@profiling;-- 2. 如果为 0,则开启它SET profiling = 1;-- 3. 执行你的 SQL 语句SELECT * FROM your_table WHERE ...;-- 4. 查看所有已记录查询的列表及其总耗时SHOW PROFILES;-- 5. 查看上面列表中某个特定查询(比如...
MySQL索引优化
前言 我们知道MySQL的数据都存储在磁盘中,在执行SQL语句时需要对进行大量磁盘IO,这使得磁盘性能可能成为性能的瓶颈,这是我们不希望出现,或者说希望优化的。 索引基础知识 什么是索引 索引其实在我们的生活中普遍存在,比如查字典,我们知道先从目录开始查而不是去一页一页的找,字典里的目录就是索引的一种实现。 索引是数据库中有序存储特定列值的数据结构(如B+树、哈希表),通过缩小扫描范围实现高效查询。 索引有什么用 根据索引的本质其实也不难理解,使用索引在大部分情况下都能提高数据库的性能,包括但不限于提高查询速度,减少磁盘IO,减少分组和排序时间等等。为啥用索引就能"快"?...
业务功能--优惠券秒杀(优化)
前言 在优化之前我们完成了基于redis分布式锁的优惠券秒杀功能,但是这个功能并不完善,虽然能用但在高并发的情况下处理速度是很慢的。为什么呢? 我们回顾一遍业务流程:用户下单-判断库存-尝试加锁-添加订单-返回订单,这样我们业务流程是单线程的,这样每次用户下单都会执行这一整套流程,速度是很慢的。如何优化呢? 我们何不将添加订单的过程交给另一些线程去完成,将判断用户是否有权添加订单的同时,为另外一些用户添加订单,判断和添加过程异步执行,这样效率明显更高。 利用lua脚本保证业务的原子性 为了保证判断业务的原子性,我们使用lua脚本编写判断业务的代码。 12345678910111213141516171819202122232425262728-- 1.参数列表-- 1.1.优惠券idlocal voucherId = ARGV[1];-- 1.2.用户idlocal userId = ARGV[2];-- 1.3.订单idlocal orderId = ARGV[3];-- 2.数据key-- 2.1.库存keylocal storeKey =...
业务功能--优惠券秒杀(基础)
前言 最近学习了利用redis解决许多业务问题的方法,优惠券秒杀是其中一个综合性较强的业务问题。 全局唯一id 雪花算法:雪花算法的原理就是生成一个的 64 位比特位的 long 类型的唯一 id。id组成为符号位(1bit)、时间戳(41bits)、工作机器ID(10bits)、序列号(12bits)。雪花算法能基于时间戳生成自增的id,但正是因为基于时间戳,雪花算法有可能出现时间(时钟)回拨的问题。 组成: 1:最高 1 位是符号位,固定值 0,表示id 是正整数 41:接下来 41 位存储毫秒级时间戳,2^41/(1000606024365)=69,大概可以使用 69 年。 10:再接下 10 位存储机器码,包括 5 位 datacenterId 和 5 位 workerId。最多可以部署 2^10=1024 台机器。 12:最后 12 位存储序列号。同一毫秒时间戳时,通过这个递增的序列号来区分。即对于同一台机器而言,同一毫秒时间戳下,可以生成 2^12=4096 个不重复...
线程变量、全局异常处理器
...
Token令牌技术+Interceptor过滤器
前言 简单了解一下原理,重点知道怎么用 Token:简单来说就是一个用户在一段时间内的标识,只有登录成功才能获得Token,一般情况下只有携带Token的请求才能被Interceptor放行。 Interceptor:这是一个过滤器技术,可以将Interceptor理解为一个筛子,在请求到达控制层前进行拦截,根据具体的业务需求,可以对请求进行一定操作,比如拦截、放行等等。 Jwt快速入门 JwtToken的组成 Header 标头,一般用来标识令牌类型和所使用的签名算法。 1234{ "alg": "HS256", "typ": "JWT"} Payload 有效载荷,保存自定义信息。 123456{ "sub": "1234567890", "name": "John Doe", "admin": true, "iat":...









