早上一节软件工程课,我真不懂为什么这课能上的像文科一样,全是概念,什么软件开发的流程,照例写两道力扣。
写了两道多维动态规划的
第一道,在只能往下或往右走的二维矩阵从左上出发求到达右下的最小路径。之前讲过,动态规划一定要留意初始化,这道题就要对最左和最上初始化,因为只有一种路线,所以唯一值也是最小值。之后就可以从[1][1]开始计算了,昨天讲过,到达某个位置只有从左边或者上边到达,所以从两个之中选一个,加上本身就可以了。
第二道,求两个字符串的最长公共子序列,注意是按顺序的。这道题倒无需初始化,直接遍历就可以了。dp[i][j]表示的是,text1的前i个字符串和text2的前j个字符串的公共子序列的最大长度,不包括i和j本身。有点抽象,嵌套两个循环,保证每个字符都能遍历到,假如相等就用dp+1,因为dp指的是目前为止相等的,所以碰上相等的要在这基础上+1.假如不相等,就要把当前ij更新成之前最大的,通过max方法选出之前最大的。至于为什么不从i-1,j-1里找,因为i-1,j在其后面,其值一定大于等于i-1,j-1。
今天就先不看《深入理解JAVA虚拟机》了,昨天刚好看完第七章,明后两天给自己休假,今天就不开新坑了,简单讲一讲一些八股吧。
首先是SpringAOP,主要还是自己对这方面理解不够深,只在项目中用来做过日志,今天深入讲一下。这里简称AOP,AOP是基于动态代理实现的,那么就先讲一下代理。
代理(Proxy)是一种设计模式,它允许通过代理对象来控制对原始对象的访问。代理对象充当了原始对象的替代者,它可以拦截并处理对原始对象的方法调用。
代理模式的核心概念是将对原始对象的访问通过代理对象进行封装,从而实现对原始对象的间接访问和控制。代理对象和原始对象通常实现相同的接口,这样代理对象可以完全替代原始对象,并在必要时对原始对象的方法进行增强或限制。
代理又分为静态代理和动态代理
静态代理:在静态代理中,代理对象和原始对象是在编译时就确定的,主要有下面两种实现方式:
(1)手动编写代理类:通过手动编写代理类,实现对目标对象的代理。代理类需要实现与目标对象相同的接口,并在代理类中调用目标对象的方法,并可以在方法前后添加额外的逻辑。
(2)使用工具生成代理类:有一些工具可以根据指定的接口或类生成代理类的代码,如Java的Proxy类、CGLIB等。这些工具会根据指定的接口或类生成代理类的字节码,并在运行时动态加载和生成代理类。
动态代理:动态代理可以通过反射机制在运行时创建代理类,并将原始对象的方法调用转发给代理对象,主要有下面两种实现方式:
(1)基于接口的动态代理:基于接口的动态代理是通过实现原始对象的接口来创建代理对象。Java提供了一个Proxy类和一个InvocationHandler接口,通过这两个类可以实现基于接口的动态代理。代理对象的方法调用会被转发给InvocationHandler的invoke方法,从而实现对原始对象的增强。(昨天讲的RPC框架也是通过这种方法获得服务的动态代理对象的)
(2)基于类的动态代理:基于类的动态代理是通过继承原始对象的类来创建代理对象。Java提供了一个CGLIB库,它可以在运行时动态生成原始对象的子类作为代理对象。代理对象继承了原始对象的类,因此可以直接调用原始对象的方法,并在方法调用前后插入相应的增强逻辑。
代理模式
代理模式是一种结构型设计模式,它允许通过代理对象来控制对其他对象的访问。代理模式通过在代理对象和目标对象之间添加一层间接层,来实现对目标对象的间接访问和控制。
在代理模式中,有三个核心角色:
1. 目标对象(Subject):被代理的对象,它定义了代理对象所要代理的方法。
2. 代理对象(Proxy):代理目标对象,它持有对目标对象的引用,并在其自身的方法中调用目标对象的方法,可以在调用目标对象方法前后添加额外的逻辑。
3. 客户端(Client):使用代理对象的对象,它通过代理对象来访问目标对象。
代理模式可以实现以下功能和应用场景:
1. 访问控制:代理对象可以在调用目标对象的方法前后进行权限验证、安全检查等操作,从而对目标对象的访问进行控制。
2. 增强功能:代理对象可以在调用目标对象的方法前后添加额外的功能,如日志记录、性能监控、缓存等。
3. 远程代理:代理对象可以作为远程对象的代理,通过网络调用远程对象的方法。
4. 延迟加载:代理对象可以在需要时才创建和加载目标对象,从而实现延迟加载的效果。
5. AOP(面向切面编程):代理模式是AOP实现的基础,通过代理对象可以将横切逻辑(如事务管理、日志记录等)与业务逻辑分离,提高代码的可维护性和可重用性。
讲完代理,现在来说一下AOP
概念
Spring AOP(Aspect-Oriented Programming)是Spring框架的一个重要特性,它是一种面向切面编程的方式,用于在应用程序中实现横切关注点的分离。
在传统的面向对象编程中,我们将应用程序的功能逻辑组织在各个类中,这些类相互之间通过继承或接口实现来协作。然而,有些功能逻辑是横跨多个类的,比如日志记录、事务管理等。如果将这些功能逻辑直接编写在每个类中,会导致代码重复、维护困难等问题。
Spring AOP的工作原理是通过动态代理实现的。当目标对象被代理时,Spring会根据切面定义的通知和切点,在目标对象的方法执行前、后或抛出异常时,插入相应的切面逻辑。
Spring AOP通过将这些横切关注点(cross-cutting concerns)从业务逻辑中分离出来,实现了代码的复用和解耦。它通过在运行时动态地将切面(Aspect)织入到目标对象的方法中,从而实现了对目标对象的增强。
Spring AOP的核心概念包括:
1. 切面(Aspect):切面是一个模块化的单元,它包含了一组通知(advice)和切点(pointcut)。通知定义了在目标对象的方法执行前、后或抛出异常时要执行的逻辑,而切点定义了在哪些方法上应用这些通知。
2. 连接点(Join Point):连接点是在应用程序执行过程中能够插入切面的点,比如方法调用、异常抛出等。Spring AOP仅支持方法级别的连接点。
3. 通知(Advice):通知是在连接点上执行的代码,它定义了在何时、何地执行切面逻辑。Spring AOP提供了五种类型的通知:前置通知(Before)、后置通知(After)、返回通知(After-returning)、异常通知(After-throwing)和环绕通知(Around)。
4. 切点(Pointcut):切点是一个表达式,它定义了哪些连接点应用哪些通知。Spring AOP使用AspectJ切点表达式语言来定义切点。
5. 引入(Introduction):引入是一种为现有类添加新方法或字段的方式。它允许将新的方法或字段添加到目标对象中,从而扩展其功能。
作用
1、日志记录:通过在方法前后添加日志记录的逻辑,可以方便地记录方法的调用信息,用于调试和监控。
2、事务管理:通过在方法前后添加事务管理的逻辑,可以实现对方法的事务控制,保证数据的一致性和完整性。
3、性能监控:通过在方法前后添加性能监控的逻辑,可以实时监控方法的执行时间和资源消耗,用于性能优化。
4、异常处理:通过在方法前后添加异常处理的逻辑,可以统一处理方法的异常情况,提高代码的健壮性和可维护性。
5、前置/后置处理:通过在方法前后添加额外的处理逻辑,可以实现对方法的前置处理和后置处理,如参数校验、返回结果处理等。
AOP不依赖于Spring还能使用吗?
可以,基于Java原生态的动态代理是可以实现AOP的。这里主要依赖于两个核心类,一个是proxy,可以用new instance的api创建代理;另一个是InvocationHandler接口,然后再重写invoke方法,底层是通过反射实现的。
在Spring中的一个类,里面有一个方法A去调用同样在这个类里的方法B,能用到AOP吗?
不行,因为Spring AOP是基于代理的AOP实现,它通过在目标对象周围创建代理对象来实现增强。当方法A调用方法B时,实际上是通过目标对象来直接调用方法B,而不是通过代理对象。因此,代理对象无法介入并执行AOP增强逻辑。
另外,这样的做法也可能导致事务失效,因为用了this去调用,解决方法是自己注入自己,通过注入后的自己类来调用B方法;也可以通过手动生成代理对象来解决,我的项目就这样解决过。
Spring的自动配置原理(单纯有点忘了,补充一下)
Spring Boot的自动配置原理主要基于条件化配置和Spring框架的IoC容器。
1. 条件化配置:Spring Boot使用条件注解(@Conditional)来决定是否应该应用某个配置。条件注解可以根据类路径上的资源、环境变量、系统属性等进行判断。Spring Boot提供了许多内置的条件注解,如@ConditionalOnClass、@ConditionalOnBean、@ConditionalOnProperty等。开发者也可以自定义条件注解来扩展条件判断的逻辑。
2. 自动配置类:Spring Boot的自动配置类使用了条件化配置,根据条件判断是否应该应用某个配置。自动配置类使用了@Configuration注解,表示它是一个配置类。在配置类中,通过使用@Bean注解来定义需要自动配置的Bean。自动配置类通常使用了@ConfigurationProperties注解来注入配置属性,使用了@Conditional注解来控制条件。
3. Spring框架的IoC容器:Spring Boot的自动配置是建立在Spring框架的IoC容器基础上的。当应用启动时,Spring Boot会扫描classpath下的META-INF/spring.factories文件,该文件中定义了各个自动配置类的全限定名。Spring Boot会根据这些自动配置类的条件注解,决定是否应用某个自动配置类。如果应用了某个自动配置类,Spring Boot会将该类中定义的Bean注册到IoC容器中,以供应用程序使用。
4. 配置属性:Spring Boot使用配置属性(Configuration Properties)来管理配置信息。配置属性可以通过在application.properties或application.yml文件中配置属性,然后通过@Value注解或@ConfigurationProperties注解来注入配置属性。自动配置类也可以使用配置属性来进行自定义配置。