自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 【从零到Offer】MySQL最左匹配

​ 相信大家在日常开发时,也经常能听到“最左匹配”这个词,那么什么是最左匹配呢?本篇文章就带你一起探索“最左匹配”的神奇秘密。​ 最左匹配,通常指的是最左前缀匹配原则,即MySQL在检索数据时从联合索引的最左边开始匹配。​ 那么如何检验MySQL确实是按照最左匹配在查询数据呢?实践是检验真理的唯一标准。​ 这里新建一张数据表,并建立(a,b,c)三列的联合索引。建好表后,往表中添入数据。​ 如此一来初始数据就准备好了。但是下一个问题来了,如何检验当前查询是否走了对应的索引呢?

2024-02-13 21:05:51 1166

原创 【编程二三事】ES究竟是个啥?

在最近的项目中,总是或多或少接触到了搜索的能力。而在这些项目之中,或多或少都离不开一个中间件 - ElasticSearch。今天忙里偷闲,就来好好了解下这个中间件是用来干什么的。

2023-08-13 23:09:35 1764

原创 【编程二三事】SQL是如何执行的?

​ Mysql是我们日常接触最多的一个开发组件了。但是,一个SQL是如何从我们的应用程序里传递到数据库里去的呢?数据库又是如何解析并处理这些SQL语句的呢?别急,让我给你一一道来。那么最后回顾总结下来,执行一句SQL语句大致要经过如下的步骤:​ 第一层需经过客户层,建立客户端与Mysql数据库之间的连接。其中,Mysql会通过连接池、数据缓存等方式,减少连接的耗时、查询的耗时。​ 第二层会经过服务层,该层主要针对用户输入的语句信息进行翻译、解析、校验等逻辑。依次对应于解析器、优化器、执行器。

2023-08-06 23:10:36 263

原创 【从零到Offer】反射那些事

​ 反射简单来说,就是在代码运行期间,通过动态指定任意一个类,从而构建对象,并了解该类的成员变量和方法,甚至可以调用任意一个对象的属性和方法。//new 构造方法 String s = new String();//反射 Class

2023-07-15 23:13:12 557

原创 【从零到Offer】- HashMap与HashSet

​ HashMap与HashSet是我们日常最常使用的两个集合类。在实现上,两者也有很大的相似性。HashSet基本就是对HashMap的一个简单包装。​ 为了更好的理解Hash结构的实现原理,从而更好的指导我们的代码使用,本文就主要对HashMap的实现及设计做分析介绍。

2023-05-29 20:32:03 669

原创 一文带你理解SpringBean

​ Bean作为Spring框架面试中不可或缺的概念,其本质上是指代任何被Spring加载生成出来的对象。(本质上区别于Java Bean,Java Bean是对于Java类的一种规范定义。)Spring Bean代表着Spring中最小的执行单位,其加载、作用域、生命周期的管理都由Spring操作。可见Spring Bean在整个Spring框架中的重要地位。​ 本文从Bean的定义、设计目的入手,介绍了SpringBoot中Bean机制的重要地位。

2023-05-05 20:04:47 495 1

原创 一文告诉你如何用Bito AI提高开发效率

​ 理性中立客观的来说,虽然当前的BitoAI提供的功能还存在着一定的缺陷。比如部分生成的代码质量不高、解释的语言也更像是一些没用的话术。但是产品本身设计出来的功能和预期实现的目标确实是很诱人。试想一下,如果未来在编写代码的时候,能有一个无所不知的AI协助你,那么你的开发效率是不是可以得到几何倍数的提升呢?​。

2023-04-28 10:12:02 1091 1

原创 还不懂怎么设计超时关单?一文告诉你!

​ 提交订单,是交易领域避不开的一个话题。在提交订单设计时,会涉及到各种资源的预占:如商品库存、优惠券数量等等。但是,下单的流程并不能总是保证成功的,如商品库存异常的时候被拦截、优惠券数量不足的时候拦截等等。因此自然会涉及到需要将已被预占的资源回退。​ 以我现有负责的交易流程为例,一个基本的下单的逻辑大致如下所示:​ 正常的下单流程实现较为简单,但是要想处理好异常情况下的数据回滚却是件难事。为此,我大致总结了现有常见的回滚方案。定时任务扫描、延迟队列、时间轮算法、Redis键过期订阅和消息队列。

2023-04-17 09:54:30 253

原创 【从零到Offer】- 泛型

​ 文章从泛型的定义、用法和实现原理各方面介绍了泛型。通过更好的了解泛型,我们才能更合适的用好泛型,提高我们代码的优雅性和效率。

2023-04-12 10:18:58 256

原创 还苦于写接口文档?快试试javaDoc和Swagger

​ 上文内容中主要介绍了两种编写接口文档的方式:javaDoc和Swagger。其中javaDoc由于其提示方式,更适用于后端间的接口编写。通过合适的javaDoc标记,可以很简单的标记出相关的枚举类、额外的文档信息等。​ Swagger与javaDoc不同,其主要提供了一个在线的接口文档提供方式。在针对后端对前端提供文档的情况下,有较好的表现。通过简单的编写,就可以在项目启动后,提供一个完整的接口文档。​ 通过Swagger和javaDoc结合,我们就可以通过极少的代码,搭建出清晰易懂的接口文档。

2023-03-26 19:02:10 680

原创 从零到Offer -- List的那些事

​ 然而我们都知道,java下,一个数组的长度是固定的,是无法变化的。​ 为了尽早的避免这种情况发生(FailFast原则),ArrayList在设计上就采用一个modCount的变量来记录数组变更的次数,并通过判断迭代器生成时的modCount同循环进行时的modCount进行比较,从而达到目的。1、添加引发的扩充是很频繁的,因此需要更快的运算速度。2、从上述描述中,我们优先会考虑1.5和2,采用2倍空间进行扩容自然也是可以的,但是实际中2倍扩充会浪费比较多的空间,且数组的空间是无法被GC回收的。

2023-03-20 09:56:58 259

原创 SpringBoot异常处理?用这两个就够啦!

增强时机增强类型异同点@After后置增强目标方法执行之后调用增强方法@Before前置增强目标方法执行之前先调用增强方法返回增强目标方法执行return之后返回结果之前调用增强方法,如果出异常则不执行异常增强目标方法执行产生异常调用增强方法,需注意的是,处理后异常依旧会往上抛出,不会被catch。@Around环绕增强环绕增强包含前面四种增强,通过一定的try-catch处理,环绕类型可以替代上述的任意一种增强。

2023-03-12 12:55:03 324

原创 系统启动太慢,调优后我直呼Nice

问题背景 最近在负责一个订单系统的业务研发,本来不是件困难的事。但是服务的启动时间很慢,慢的令人发指。单次启动的时间约在10多分钟左右,基本一次迭代、开发,大部分的时间都花在了启动项目上。忍无可忍的我,终于决定找到启动慢的原因。方案探索 起初对于优化项目启动速度,是毫无头绪。也是傻傻的从百度上去搜解决的方案。一下子就搜到了Jprofiler这个软件,据说是能快速找到错误栈的位置。但是不得不说这软件真的很坑,不仅收费(MAC破解巨难找,找到了还打不开),而且实际因为很多Spring类都是采用动态代理加载的,

2023-02-26 13:53:55 876

原创 2022,我遭遇的那些小事

2022,总感觉一晃眼就过去了,不知不觉自己坚持更文已经一周年了。回顾这一周年,无论是在技术成长上还是职业发展上,都有了许多新的体会。回顾这2022年,我在写作上投入的东西不少,好在收获也很丰富。而且,写作给我带来的另外一个好处是:对于自己的晋升、调薪,我变得更加有自信了,我不在认为自己是德不配位,相反,我认为自己获得的这一切都是理所应当。焦虑的情绪不再蔓延。好好运营公众号,打造一点自己的个人IP提升发文数量,坚持周更。组织好自己的系列文章内容。工作上更加奋力迈进,争取明年再晋升一次。

2023-01-02 10:52:43 307

原创 哦,原来事务传播是这样

在事务嵌套的情况下,事务如何从调用者往被调用者传播的机制。​ 首先,需要清楚的是,根据场景的不同,所需要使用的事务传播机制往往是不同的。比如对于数据强一致性的情况,我们希望这两个嵌套事务保持一致。但是对一些数据不需要保持强一致性的场景,我们可能希望两个事务间互不干扰。事务传播级别代码中的传播级别级别描述REQUIREDREQUIRED级别是Spring的默认事务级别,在Spring注释中对于该等级的描述是:会自动加入当前的事务,如果不存在则新建事务。SUPPORTS。

2022-12-25 17:12:06 350

原创 【从零到Offer】- 拆箱装箱那点小事

装箱,指基础类型(int、double等)转换成包装类型(Integer、Double等)的过程拆箱,顾名思义同装箱相反,是从包装类型转换到基础类型的过程。在JDK1.5以前,还不存在装箱、拆箱的概念。因此,对于基本类型同包装类型的转换,基本只能通过代码手写实现。然而,懒惰是推动人类社会进步的动力。时间一长了,大家就发现:“明明这两个类型都是表达相似含义的东西,有没有什么办法把这两个的转换隐藏起来呢?这样我就不用写着么多代码了呀”​ 本文主要介绍了拆箱、装箱的实现原理及机制。

2022-12-11 11:18:45 128

原创 我悟了!Mysql事务隔离级别其实是这样!

​ 介绍了这么多有关事务隔离的内容,我们终于可以回归到我们的问题上来了。那么其实对于开头提到的问题,原因就是在异步线程中,会新开一个事务,这两个事务是并行的。由于mysql默认的事务隔离级别是可重复读,会导致事务A异步的情况下,数据可能未提交,事务B执行较快而获取到了旧数据,造成了同步数据错误的问题。​ 知道了问题,那么解决方案就比较简单了,可以不通过异步的方式发送,而是采用kafka消息的机制。这样就给事务A留足了事务提交的时间,从而确保数据的准确同步。

2022-11-22 20:53:57 339

原创 浅析Spring事务实现原理

​ 首先我们来了解下,最简单的事务是怎么实现的呢?以JDBC为例,当一个数据库Connection对象创建后,其会默认自动提交事务;每次执行SQL语句时,如果成功,就会向数据库自动提交,不能回滚。​ 通过调用setAutoCommit(false)方法可以取消自动提交事务。等到所有的SQL语句都执行成功后,调用commit()方法提交事务。如果其中某个操作失败或出现异常时,则调用rollback()方法回滚事务。

2022-11-08 18:24:31 654

原创 如何用IDEA提高你的开发效率

​ 作为一名java开发工程师,IDEA无疑是我日常接触最多的工具。因此,能否高效使用IDEA软件,一定程度上决定了我们的开发效率。本文将主要介绍IDEA中的四个便于提高开发效率的功能,常用快捷键、实时模版、后缀补全、文件和代码模版。相信一定会对你提升开发效率有所帮助。​ 期望通过对IDEA上述进阶功能的学习,我们未来可以更好的驾驭IDEA的功能,让IDEA不仅仅是完成开发的工具,更应该成为我们提高生产效率的真正利器。毕竟打工路漫漫,能早开发完成就代表我们能多努(mo)力(yu)一点。祝各位永不加班~

2022-10-30 17:07:02 1182

原创 一个Springboot配置顺序问题,让我直接回滚代码了

​ 为了找到问题发生的原因,首先需要了解配置是如何在SpringBoot项目中生效的。查阅资料后,我知道了在SpringBoot中,存在一个名为的变量,其中保存着Spring中启动的所有信息。在这所有的变量中,配置信息主要同变量相关,诸如JVM参数、环境变量、Apollo配置等配置用封装后,存放在里的。​ 除了存储配置以外,SpringBoot还设计了用于管控当前的配置信息,并负责对配置进行填充。​ 至于和的关系,形象点来说,就是一位翻译官,他会根据现有的词典。

2022-10-23 20:24:35 1010

原创 从一个主从延迟问题,学习Mysql主从复制原理

​ 主从架构作为最常见的集群搭建模式,通过将读写分离,来避免所有的请求都请求到同一个数据库上,从而减少单个数据库的压力。其次,通过对从库进行水平的扩展,也会使得系统的伸缩性及负载能力得到提升。​ 一主一从为最常见的主从架构模式,由一个主节点+一个从节点组合而成,当主节点宕机时,从节点可以快速接替主节点的工作。​ 该架构有一个主节点+多个从节点组成,适合读较多的场景,可以将读命令分摊到多个从节点。​ 在一主多从的基础上,为了减轻主库向从库同步数据的压力,还出现了树状主从/级连复制。

2022-09-25 07:19:38 435

原创 关于我加了一行日志搞崩了服务这件小事

周三的时候,组内出现了一个线上问题,影响到了若干个用户的下单、支付等操作。然而实际查询到问题的原因时,发现只是由于一行小小的日志打印导致的错误。以下的文章内容分为主要分为三部分:1、对案件的发生进行回顾;2、分析案件发生的原因;3、对案件总结与反思以三章内容来回顾出现的问题,以及提供未来的预防策略。​ 在经历了这次惨痛的教训之后,有哪些是值得我们深入关注去思考和反思的呢?1、在编写方法的时候尽量避免才用getXXX、isXXX的方法进行书写,这会导致部分框架的解析出现问题。

2022-08-22 09:51:00 250

原创 从0-1了解Spring是如何运行起来的(四):BeanFactory后处理初分析,了解如何加载BeanDefinition

​ 最深刻了解一个框架的思想的方式,莫过于看源码,本系列旨在于从Springboot底层源码(Version - 2.6.6)出发,一步步了解springboot是如何运行起来的。在前述的文章中,我们主要了解了SpringBoot是如何实现配置文件的加载、context的预处理.........

2022-07-03 17:15:28 251

原创 每天都在写Getter、Setter方法,我不耐烦了,于是用了神器MapperStruct,crud效率一下子提高了~

前言​ 相信绝大多数的业务开发同学,日常的工作都离不开写getter、setter方法。要么是将下游的RPC结果通过getter、setter方法进行获取组装。要么就是将自己系统内部的处理结果通过getter、setter方法处理成前端所需要的VO对象。public UserInfoVO originalCopyItem(UserDTO userDTO){ UserInfoVO userInfoVO = new UserInfoVO(); userInfoVO.setUserName(u

2022-05-29 20:33:30 696

原创 从0-1了解Spring是如何运行起来的(三):Context预处理,为加载容器做准备

前言最深刻了解一个框架的思想的方式,莫过于看源码,本系列旨在于从Springboot底层源码(Version - 2.6.6)出发,一步步了解springboot是如何运行起来的。从0-1了解SpringBoot如何运行(一):Environment环境装配从0-1了解SpringBoot是如何运行起来的(二):定制你的banner在前述的文章中,我们主要了解了SpringBoot是如何实现环境装配和banner打印的,这一期我们主要来了解SpringBoot是如何创建Context,并对conte

2022-05-24 16:11:21 361

原创 工厂模式:优雅地生成多种类型对象

​ 工厂模式是一种非常常用的创建型设计模式,其提供了创建对象的最佳方式。在创建对象时,不会对客户端暴露对象的创建逻辑,而是通过使用共同的接口来创建对象。通过使用工厂模式,在业务代码中可以灵活的操控生成的实例对象。​ 工厂模式主要包含以下三种实现:简单工厂、工厂方法及抽象工厂。下面我们来逐一了解这三种工厂方法的实现与异同。简单工厂​ 工厂模式中,最简单易懂的就是简单工厂方法。通俗点来说,简单工厂的核心思想就是:“你告诉我你需要什么,我就为你生产什么”。这里举一个游戏的简单例子。一个游戏中角色分别有战士、

2022-04-17 18:47:46 747

原创 从0-1了解SpringBoot是如何运行起来的(二):定制你的banner

​ 最深刻了解一个框架的思想的方式,莫过于看源码,本系列旨在于从Springboot底层源码(Version - 2.6.6)出发,一步步了解springboot是如何运行起来的。前言​ 上期我们聊了Spring是如何装配环境的。这期我们来接着往下看,一同来了解springBoot是如何加载出banner图片信息的。public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = ne

2022-04-10 17:20:26 589

原创 从0-1了解SpringBoot如何运行(一):Environment环境装配

前言最深刻了解一个框架的思想的方式,莫过于看源码,本系列旨在于从Springboot底层源码(Version - 2.6.6)出发,一步步了解springboot是如何运行起来的。public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args);}首先我们从run方法开始逐步深入其中。public ConfigurableApplicationContext run(St

2022-04-06 10:08:24 1242

原创 模版方法:优雅、灵活地拓展你的pipeline

模版方法,作为一种**行为型模式**,通过在抽象类或接口中定义一个操作中的算法骨架,而将一些步骤具体执行延迟到子类中实现,从而使得父类的方法执行可以获得不一样的结果。从而达到了代码复用、扩展性好、灵活度高的设计目的。

2022-03-27 15:14:44 333

原创 Spock框架初体验:更优雅地写好你的单元测试

随着情况的增多、if-else语句的增加,Junit带来的代码量会逐渐的增长,为后续的维护和情况的增加带来了一定的成本。针对这个痛点,Spock提出了自己的解决方案。其通过采用where语句的方式,简化了多if-else语句情况下的条件判断,进而简化了需编写的代码数量**。

2022-03-06 18:23:57 856

原创 多线程热知识(三):TransmittableThreadLocal,异步线程变量传递最优解

TTL通过将异步线程变量的传递时机由线程初始创建的时候,后移到了线程任务执行的时候。这样一来确保了线程变量即使在使用了线程池的时候也能够相应的传递下去。另外,采用了线程变量快照及重放的机制,避免了在高并发情况下可能出现的业务数据紊乱的问题,是很精妙的设计。

2022-02-24 10:39:14 1478

原创 多线程热知识(二):异步线程变量传递必知必会---InheritableThreadLocal及底层原理分析

在不依赖于线程池的场景下,ITL是一个很好的实现异步线程传递变量的工具。然而,在使用线程池的情况下,由于线程不会进行频繁地初始化和销毁等工作,ITL的变量值无法得到更新,因而有可能存在数据错误传递的问题。

2022-02-20 16:13:52 1234

原创 多线程热知识(一):ThreadLocal简介及底层原理

ThreadLocal作为一个多线程编程必不可少的元素,其通过对每个线程保存副本的方式,避免了互斥、同步等复杂操作。本文从底层源码逐步分析,为你揭开ThreadLocal的作用机理。同时探究引起ThreadLocal内存泄漏的本质原因,相信一定会让你受益良多。

2022-02-13 19:54:38 710

原创 初识分布式锁(三):Redis分布式锁原理及Redisson框架实战

前两篇文章咱们聊到了如何采用SQL数据库及Zookeeper实现相应的分布式锁。今天咱们再来聊聊如何采用redis实现相应的分布式锁,以及这种实现与前两种方式实现的差异性。

2022-02-09 11:15:20 1876

原创 初识分布式锁(二):ZooKeeper分布式锁原理浅析及实战案例

初识分布式锁(二):ZooKeeper分布式锁原理浅析及实战案例写作不易,点赞收藏关注以便下次再看,感谢爸爸们的支持~上回咱们说到,用Mysql数据库实现了分布式锁。实现起来相对简单。但是缺陷也相对比较明显,一方面是SQL锁没有过期机制,如果不保持高可用的情况下,线程没有释放掉锁就会出现死锁。另一方面是因为SQL本身性能并不高,因此采用SQL加锁的方式会极大拖累整个系统的性能。基于以上各点,本期咱们沿着Zookeeper展开,介绍如何使用Zookeeper实现相应的分布式锁。Zooke

2022-01-29 12:24:33 3032 2

原创 炉石营所思所想

期待炉石营是人生自己第一次参加职业培训(虽然预料到会很枯燥、洗脑),而且听往届同事的反馈,炉石营确实可以结交不少的伙伴,认识许多平日里认识不到的人,因此内心还是饱含期待的。然而,因为可恶的疫情原因,培训日期一拖再拖,从起初的7、8月份拖延到了9、10月份,又最终拖到了1月份,而且还是分批进行。属实是往头上浇了一盘冷水。相遇到了迎来炉石营的日子,悲伤地推去年会的排练,前往参加炉石营的开营仪式。不得不说,开营仪式没有我想象中的那么完美~~(毕竟没有五星级酒店的加持了)~~。但总体还是可以的,主持人

2022-01-25 16:27:26 994 2

原创 初识分布式锁(一):分布式锁原理浅析及Mysql实现案例

什么是分布式锁?普通锁要讲分布式锁,我们先来了解下普通锁是什么。在计算机科学中,锁(lock)是一种同步机制,用于在许多线程执行时对资源的限制。通过使用锁,确保多个线程在访问同一个共享变量时,都能保持正确的访问顺序,不至于因为线程的争抢执行导致脏数据等问题的产生。具体来说,锁依据实现又可以分成:悲观锁、乐观锁、自选锁等多种,这里我就不赘述了。分布式锁现在咱们已经有了基本的锁概念了,那么为什么还需要设计分布式锁呢?以上图为例子,设计分布式锁的主要原因在于,普通锁只是针对单个系统下的多个线程的

2022-01-25 15:34:22 1275

原创 异步线程间变量传递,价值两个 p0 case的代码深究

问题复现:项目内原本采用的是DemoContext作为一个线程的上下文context,用于存储从header头、入参数的一部分数据,实现跨业务代码复用及传递。public class DemoContext { ... //创建一个ThreadLocal private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>(); ...} @SneakyTh

2022-01-16 12:24:39 466

原创 策略模式:精妙替代你的if-else

何为策略模式?策略模式,作为一种常用的设计模式,其通过策略类、方法函数的方式封装不同场景的函数。从而对上层调用,可以屏蔽掉因为入参、场景的差异而导致的区别。对于内层逻辑,可以根据不同的场景执行不同的方法及类,同时易于增加新的策略,易于拓展。策略模式主要的组成框架图如下所示:何时应用策略模式?这里引用阿里大佬之叶对于什么时候应用策略模式的一段话:当if-else的代码块违反了单一职责原则、开闭原则,尤其是块中的代码量较大时,后续代码的扩展和维护就会变得非常困难且容易出错,使用卫语句也同样避免不了以

2022-01-05 18:03:37 8199 2

原创 AOP初识及实践

AOP初识及实践AOP是什么?AOP(Aspect Oriented Programming),即为面向切面编程。其作为一种新的编程思想,主要是将多数代码中共用的部分抽象出来,采用动态代理、静态代理等方式,自动添加到对应代码的首部或尾部。从而简化业务代码重复逻辑,提升开发效率。AOP常见概念增强/通知(advice),在特定连接点需要执行的动作。Spring下主要包括五种通知类型:前置通知(Before)后置通知(After)返回通知(After-returning)异常通知(Afte

2021-12-26 11:55:23 356

空空如也

空空如也

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

TA关注的人

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