自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 LeetCode热题100(最小栈)

利用两个栈实现,一个是正常存储数据,一个存储当前的栈中的最小值,每次push都需要更新。操作,并能在常数时间内检索到最小元素的栈。

2025-12-21 21:42:29 105

原创 在排序数组中查找元素的第一个和最后一个位置

这是最朴素的思想,二分查找,如果找到了再往两边拓展,处理边界条件,只可惜超时了。给你一个按照非递减顺序排列的整数数组。请你找出给定目标值在数组中的开始位置和结束位置。你必须设计并实现时间复杂度为。需要对二分法再进行二分查找。如果数组中不存在目标值。

2025-12-17 23:37:45 209

原创 LeetCode热题100(搜索插入位置)

1.二分法的思路,注意最后返回的是left,分析原因,此时left > right才会跳出循环,第一种情况left = temp+1之后导致的跳出循环,target大于left和right所在的位置的值,往后移一位便是插入的位置。第二种情况,right = temp - 1导致的,target小于left和right所在的位置,返回之前的right所在的位置,也就是left。给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。请必须使用时间复杂度为。

2025-12-15 23:25:39 180

原创 LeetCode热题100(单词搜索)

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。思路类似计算岛屿数量,同时要进行回溯。

2025-12-13 22:06:30 199

原创 LeetCode热题100(电话号码的字母组合)

可以对比之前子集的处理思路是类似,这里比较巧妙的是吧数字和字符串做了影射。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。的字符串,返回所有它能表示的字母组合。

2025-12-09 22:03:38 226

原创 LeetCode热题100(子集)

1.本题可以参考全排列的思路,记录路径,输出结果。但是需要注意的是控制起始的值。2.最好本地调试一下代码,回溯问题光看代码不好理解。返回该数组所有可能的子集(幂集)。

2025-12-08 22:12:44 192

原创 LeetCode热题100(全排列)

给定一个不含重复数字的数组。

2025-12-07 21:18:14 135

原创 LeetCode热题100(前缀树)

第一个属性,用来记录以当前类为节点存在的子节点,最多有26个。children数组的下标刚好对应着从当前节点到子类是什么字符。初始节点是root(每次调用方法把当前类作为初始的节点),如果子类是一个字符串遍历后的结束结点需要打上标记isEnd为true表示从root节点遍历到当前节点存在一个完整字符。是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。4.第一次看思路确实有点懵,多看几遍,妙不可言。2.本题的关键还是要明白插入字符的方法是怎么做的。(发音类似 "try")或者说。

2025-12-07 20:58:41 435

原创 LeetCode热题100(课程表)

要判断是否存在环,需要给每个课程一个标记,并且记录两个课程之间是否互相依赖,这个时候就要标记课程之间的访问状态,如果存在两个课程状态是相互访问,那么就是存在环的。虽然思路比较清晰,但代码实现起来还是需要一定的技巧。在选修某些课程之前需要一些先修课程。请你判断是否可能完成所有课程的学习?,表示如果要学习课程。

2025-12-05 21:56:11 235

原创 LeetCode热题100(腐烂的橘子)

2.题解巧妙的使用count计算新鲜橘子的数量,同时腐烂扩散的时候递减,如果最后有橘子没有,被扩散到,说明要返回-1,通过int[]数组记录腐烂橘子的横纵坐标,便于四个方向扩散。1.原本以为这题和岛屿数量类似的思路,但是不同的是,每次腐烂扩散需要考虑所有腐烂的橘子,如果不用队列辅助是做不出来的。直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。的新鲜橘子都会腐烂。

2025-12-04 21:35:22 437

原创 LeetCode热题100(岛屿数量)

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。3.本题特别巧妙的处理了为'1'的情况,遍历完之后赋值为'0'。1.对于本题没有思路,特别是图的深度优先遍历算法有点忘了。(水)组成的的二维网格,请你计算网格中岛屿的数量。此外,你可以假设该网格的四条边均被水包围。2.图的题目要特别注意边界值的处理。

2025-12-03 21:39:44 578

原创 LeetCode热题100(二叉树的最近公共祖先)

最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(2.二叉树的题目基本都可以用递归去实现,并且需要递归左右子树。最重要的是想明白怎么处理一次递归的边界条件。1.本题的卡点还是在于递归的处理,节点应该返回什么。后续怎么处理,怎么递归调用。3.题解从上往下找到p或q中的1个节点,确保公共祖先是最近的。给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

2025-12-02 21:18:42 201

原创 LeetCode热题(路径总和 III)

2.计算和的方式不对,官方题解巧妙的使用每遍历一个节点和的值减少,这样就不用再用一个变量记录当前和了。不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。4.使用递归如果数据量比较大的话,容易超时,本题还可以进一步优化。1.只考虑了以跟节点出发的情况,没有递归左子树和右子树。3.需要巧妙使用递归多次计算以不节点为起点的路径。给定一个二叉树的根节点。,求该二叉树里节点值之和等于。

2025-12-01 21:02:13 224

原创 git命令实操(比较文件)

由于我的本地仓库没有a.txt的提交记录,所以第一次使用git diff HEAD a.txt没有显示,先提交。然后再次修改a.txt文件,add到暂存区,使用git diff HEAD a.txt便可以看到差异。再次修改a.txt,通过git diff a.txt命令比较差异如图所示。把修改后的a.txt文件提交到本地仓库,然后再使用git diff a.txt命令并不能比较文件。3.git diff HEAD a.txt(工作区文件对比本地库文件)不指定文件名,工作区所有的文件与本地仓库历史版本比较。

2025-11-27 23:11:04 260

原创 git命令实操

3.git commit -m"commit a.txt 添加了验证二叉搜索的算法代码"先修改了a.txt文件,查看gIt,发现a.txt在工作区,并未加到缓存区。查看历史版本,显示的信息比较详细。文件为绿色表示加到了暂存区。前面索引显示更少的哈希值。

2025-11-26 22:28:58 185

原创 git常用命令总结

git status- 看看当前状态gitgit add .- 添加所有修改- 提交git pull- 先拉取更新git push- 再推送代码- 创建新分支- 合并分支上面演示了部分git命令的操作。希望这份清单对你有帮助!多加练习,才能熟练掌握git命令。虽然Idea已经集成了git命令,很多命令都可以以快捷键形式展示,但是还是有必要了解git命令,其中有些命令是idea不能解决的,通过命令行操作会对gIt有一个全新的认识。

2025-11-25 21:38:47 797

原创 Aop的动态通知调用

其中打印三个通知,最后一个是动态通知,InterceptorAndDynamicMethodMatcher。ReflectiveMethodInvocation需要使用匿名方式创建,因为它的构造方法是受保护的。Aop除了前面讲的静态通知调用外,还有动态通知调用,可以基于参数进行动态绑定。该通知不同于静态通知,里面有通知对象也有切点对象。对比两种通知得出以下结论。1)动态通知的特点是有参数绑定,而静态通知不需要参数绑定,而且有参数调用还需要切点。2)动态通知复杂度比较高,性能比无参数绑定的通知调用低。

2025-11-24 08:24:21 143

原创 Aop调用链执行原理

重写里面的方法,核心处理逻辑在proceed方法里面,通过递归调用通知实现增强。这里的处理逻辑使用了责任链模式,过滤器以及拦截器都是基于这个思想实现。Adice1的前置增强在前面,后置增强在其它通知后面。2)实现MethodInvocation类。1)准备目标类和两个切面。

2025-11-23 22:49:15 172

原创 Spring Aop调用链的执行

该对象用于后续执行方法调用及应用切面逻辑。由于该类的构造器是受保护的类型,所以需要和该类是同一个包下才可以使用。2.创建一个 ReflectiveMethodInvocation 对象,用于封装方法调用的上下文信息。Spring Aop调用链才是真正执行Aop增强的地方。下面是模拟框架的实现思路。这个通知必须在其它通知之前设置,否则执行会有问题。通过结果可以看到各个通知生效的顺序。1.设置Spring框架自带的advice。

2025-11-20 22:56:58 313

原创 Spring统一转换环绕通知

Before以及@AfterReturning注解的通知都被转换,转换后的接口实现了MethodInterceptor。在Spring底层,Aop中所有的通知最后都会转换为环绕通知。下面列举了多个通知,观察代理创建前后,通知的变化。变成了环绕通知,没有转换的本身就是环绕通知的类型,可以查看其实现的接口。

2025-11-20 00:07:00 217

原创 Spring高级切面转化为低级切面

以@Aspect注解实现的高级切面在框架中都会转换为低级切面的实现,以其中以@Before注解的通知为例,@Aspect里面还可以有环绕通知,后置通知等等。3)创建通知类,除了方法method和pointcut切点之外,还需要创建切点的实例工厂。2)解析切点,拿到切点表达式,这里以@Before为例。1)找到类Aspect以及类中直接声明的所有方法。打印了两个advisor切面。

2025-11-18 21:51:27 218

原创 Mysql数据类型转换

mysql底层有一套默认的转换机制,如果没有指定数据库字段到Java实体字段的映射,会有一套默认的转换机制。

2025-11-17 22:31:55 163

原创 Spring代理的创建时机

Bean1与Bean2产生了循环依赖,在Bean1依赖注入之前,Bean1的代理已经被创建。并且在Bean1依赖注入之前,Bean1的代理被Bean2使用了。spring代理的创建时机分为两种,第一个是初始化之后创建代理,第二种是依赖注入之前创建,这种情况是因为发生了循环依赖,代理被提前创建。Bean1需要Aop,其代理在初始化之后创建。上面日志并未打印代理的创建,可能由于spring版本问题。

2025-11-12 23:04:55 171

原创 AbstractAdvisorAutoProxyCreator

找到有资格的advisors,一部分是高级的切面转成的advisors,另一部分是低级的切面,可以通过编程编写。该类中有两个重要的方法去实现AOP的代理功能。该切面会转化成两个Advisor。

2025-11-11 21:02:30 137

原创 Advisor与@Aspect

AspectAdvisor其中advisor是一种比较低级的切面,@Aspect是一种高级切面,最后@Aspect的执行都会被转化为多个advisor低级切面。下面将要展示两种切面的使用方式。

2025-11-10 22:19:26 283

原创 @Transactional注解的切点匹配

前面切点表达式的匹配方法有一定的局限性,当注解在类或接口上的时候不能匹配。下面是另一种处理注解的切点匹配方式。使用StaticMethodMatcherPointcut进行注解的匹配。1)重写matches方法。该方法会搜索类上以及继承树上的类或接口。3)检查类上是否加了注解。2)检查方法上的注解。

2025-11-09 21:24:33 144

原创 Spring AoP的切点匹配

Spring AoP的切点匹配主要使用切点表达式进行匹配,下面是两种常用情况。设置表达式,execution()括号里面使用正则表达式匹配注解所在的方法。表达式的值为@annotation+注解所在的类路径。

2025-11-08 22:49:08 242

原创 Spring 代理的选择

Spring使用ProxyFactory用来创建代理类,用AopProxyFactory选择具体的代理实现,总共有两种实现,一个是JdkDynamicAopProxy,另一个是ObjenesisCglibProxy。具体可以分为以下三种情况。2.proxyTargetClass为false,目标没有实现接口,用cglib实现。1.proxyTargetClass为false,目标实现了接口,用jdk实现。3.proxyTargetClass为true,总是使用cglib实现。

2025-11-07 21:42:20 354

原创 Spring Aop实现

从输出结果可以看到,foo方法匹配了切点表达式并且进行了增强,从打印的代理类对象可以看出,通过代理工厂创建的代理是cglib代理。spring通过切点的方式可以实现对目标方法实现aop增强,下面是实现aop的四大步骤。

2025-11-06 22:32:45 485

原创 cglib动态代理之MethodProxy(三)

MethodProxy创建过程中使用到了两个FastClass对象进行辅助,它们调用目标方法避免反射的思路如下。先获取方法信息,找到对应的方法。再使用ProxyFastClass的invoke调用原始的saveSuper方法。先获取方法信息,再使用invoke调用原始的save方法。参数为int的情况。

2025-11-05 23:06:54 242

原创 cglib动态代理之MethodProxy(二)

最后回到主类的方法调用,methofProxy进行invoke调用的时候,会用到FastClass的invoke方法。通过传入的Target和args可以调用原始的目标方法。我们通过TargetFastClass(负责调用原始类的方法)模拟实现FastClass类,其中有两个重要的方法getIndex和invoke。MethodProxy创建的过程中,create方法传入了四个参数,在创建的过程中会调用FastClass的方法。获取方法签名,然后执行对应的目标方法。

2025-11-04 20:31:00 330

原创 cglib动态代理之MethodProxy

需要使用到四个参数,第一个是目标类,第二个是代理类,第三个是描述,()表示原始方法参数为空,V表示返回值为空,save是增强后的方法,saveSuper是原始的方法。相比之前的实现,新增三个原始的方法(调用父类的方法)。cglib动态代理的MethodProxy在优化方法调用的时候起了关键作用,下面是MethodProxy方法调用的实现,里面避免了使用反射调用,2) 使用methodProxy对象结合目标对象进行方法调用,里面也没有用到反射。

2025-11-03 22:10:14 182

原创 cglib动态代理实现原理

cglib动态代理实现原理如下,有与jdk动态代理类似的地方。但是cglib动态代理类是基于继承实现,目标类不用实现特定接口,并且cglib使用了MethodProxy优化性能。代理类是通过MethodInterceptor进行回调的,而jdk使用的是InvocationHandler进行回调。列举了三种不同情况的方法,后面会对这三种方法进行代理实现。

2025-11-02 16:58:29 175

原创 Jdk反射优化

通过结果可以知道,前16次jdk使用的是本地的MethodAccessor实现反射调用,后面一次进行了优化,使用的是GeneratedMethodAccessor2进行调用,通过Arthas工具可以看到该类的实现,里面是正常调用foo方法,没有使用反射,提高了性能。使用 JDK 的动态代理时,会使用反射调用方法。但相比于正常调用方法,利用反射的性能要低一些,通过测试,我们可以看到Jdk内部对反射调用进行了优化。如果jdk>=9的话,需添加下面的vm option参数。

2025-11-01 22:55:03 203

原创 Maven依赖冲突的解决

但是很多时候,我们并不知道会产生冲突,因为依赖的比较隐蔽,光从表面看不出来。通过看依赖数我们可以看到上面spring-context的依赖都来自哪,版本是否一致。如果产生了冲突,再通过exclusion进行排除。在maven项目开发中,由于引入了太多的Jar包,所以免不了会产生依赖冲突,同时存在几个不同版本的jar包。下面有两个解决办法。使用<dependencyManagement>可以使得mave强制使用固定版本的依赖,不用担心产生了依赖冲突。通过这种方式排查依赖传递,避免与我们定义的依赖产生冲突。

2025-10-31 21:31:34 258

原创 推荐开发必备的十二大IDEA插件

工欲善其事必先利其器,如果我们能合理使用插件,将极大提高我们的开发效率。下面推荐几个我开发中常用的IDEA插件。

2025-10-30 23:08:06 828

原创 IDEA开发常用快捷键总结

Alt + 鼠标点击。

2025-10-29 22:27:28 322

原创 jdk动态代理实现原理(二)

Foo接口的产生变化,bar方法返回值为int。InvocationHandler接口的invoke方法增加参数Object proxy,可以传入代理对象。下面对jdk动态代理实现进一步进行优化,考虑方法有返回值的情况,最终的实现类似于源码。把方法对象的获取抽象成静态代码块,同时进行更精确的异常捕获。重写bar方法要有返回值。

2025-10-28 23:07:55 166

原创 jdk动态代理的实现原理

下面的案例将一步步的模拟jdk源码思路实现jdk动态代理。

2025-10-27 23:04:36 150

原创 cglib动态代理实现

MethodInterceptor对象的创建需传入四个参数,第一个是代理对象,第二个是Method,第三个是args方法参数,第四个是MethodProxy代理对象,与第一个参数有所不同。这是一种通过反射的方式调用目标类的方法,除此之外还有别的方法可以使用,一般来说反射调用都会影响性能。代理类的创建是通过Enhancer对象创建,其中需要传入两个参数,一个是目标对象,另一个是MethodInterceptor对象。目标类是一个类而非对象,而且方法和类上都不能用final修饰。3.目标类的调用的三种方式。

2025-10-26 18:02:22 207

Spring IOC容器分享(PPT)

Spring IOC容器部分知识整理

2025-10-16

空空如也

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

TA关注的人

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