当前位置: 首页 > news >正文

Spring题集 - Spring AOP相关面试题总结

文章目录

      • 01. Spring AOP 的理解?
      • 02. Spring AOP 思想的代码实现
      • 03. Spring AOP 的相关术语有哪些?
      • 04. Spring AOP 基于注解的切面实现?
      • 05. Spring AOP 的通知有哪些类型?
      • 06. AOP 有哪些实现方式?
      • 07. Spring AOP 和 AspectJ AOP 有什么区别?
      • 08. JDK动态代理和CGLIB动态代理的区别?
      • 09. 如何理解 Spring 中的代理?
      • 10. Spring在运行时通知对象?
      • 11. Spring 只支持方法级别的连接点?
      • 12. Spring AOP 中 Weaving 是什么?

01. Spring AOP 的理解?

Spring AOP(Aspect-Oriented Programming,面向切面编程)提供了一种在程序运行期间动态地将代码切入到方法调用前、调用后或抛出异常时等不同执行点上的能力,可以在不修改原有代码的情况下,对系统进行横切关注点的处理,如日志记录、性能统计、安全控制等。

在这里插入图片描述

02. Spring AOP 思想的代码实现

在BeanPostProcessor的after方法中使用动态代理对Bean进行增强,实际存储到单例池singleObjects中的不是当前目标对象本身,而是当前目标对象的代理对象Proxy,这样在调用目标对象方法时,实际调用的是代理对象Proxy的同名方法,起到了目标方法前后都进行增强的功能。

将增强的方法提取出去到一个增强类中,且只对com.hh.service.impl包下的任何类的任何方法进行增强。

① 增强的方法:

@Component
public class MyAdvice1 {public void beforeAdvice(){System.out.println("前置的增强....");}public void afterAdvice(){System.out.println("最终的增强....");}
}

② 在BeanPostProcessor的after方法中对bean进行增强:

@Component
public class MockAopBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {private ApplicationContext applicationContext;@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {//目的:对UserServiceImpl中的show1和show2方法进行增强,增强方法存在与MyAdvice1中if(bean.getClass().getPackage().getName().equals("com.hh.service.impl")){//生成当前Bean的Proxy对象Object beanProxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(),bean.getClass().getInterfaces(),(Object proxy, Method method, Object[] args) -> {// 从Spring容器中获取增强类对象MyAdvice1 myAdvice1 = applicationContext.getBean(MyAdvice1.class);// 执行增强对象的before方法myAdvice1.beforeAdvice();// 执行目标对象的目标方法Object result = method.invoke(bean, args);// 执行增强对象的after方法myAdvice1.afterAdvice();return result;});return beanProxy;}return bean;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}

③ UserServiceImpl中的show1和show2方法:

@Service
public class UserServiceImpl implements UserService {@Overridepublic void show1() {System.out.println("show1....");}@Overridepublic void show2() {System.out.println("show2....");}
}

④ 配置类:

@Configuration
@ComponentScan("com.hh")   
public class SpringConfig {
}

④ 测试:

public class ApplicationContextTest {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);UserService userServiceImpl = (UserService)context.getBean("userServiceImpl");userServiceImpl.show1();}
}

环绕前的增强…
show1…
环绕后的增强…

03. Spring AOP 的相关术语有哪些?

在这里插入图片描述

在Spring AOP中,有几个重要的名词需要理解:

① Aspect:切面包含了一组通知和切点。

② Advice:通知是切面的具体实现,它定义了在何时、何地、如何执行切面的逻辑。

③ Pointcut:切点是一个表达式,它定义了哪些方法需要被切入。

④ Joinpoint:连接点是程序执行过程中能够被切入的点。

⑤ Weaving:织入是将切面应用到目标对象中的过程,它可以在编译时、类加载时或运行时进行。

04. Spring AOP 基于注解的切面实现?

在 Spring AOP 中,基于注解的切面实现主要包括以下几个步骤:

  • 定义切面类:在切面类上使用 @Aspect 注解来标识该类为切面类,同时在该类中定义切点和通知等信息。
  • 定义切点:在切面类中使用 @Pointcut 注解来定义切点,切点是一个表达式,用于描述哪些连接点应该被拦截。
  • 定义通知:在切面类中定义通知方法,通知方法使用 @Before、@After、@AfterReturning、@AfterThrowing 或 @Around 等注解来标识通知类型,同时可以使用 JoinPoint 参数来获取连接点的信息。
  • 在Spring配置类中开启AOP支持。

① 定义切面类:

@Component
@Aspect
public class MyAspect {// 定义切点@Pointcut("execution(* com.hh.service.*.*(..))")public void myPointcut() {}// 定义前置通知@Before("myPointcut()")public void myBeforeAdvice(JoinPoint joinPoint) {System.out.println("Before method " + joinPoint.getSignature().getName());}// 定义后置通知@AfterReturning(pointcut = "myPointcut()", returning = "result")public void myAfterReturningAdvice(JoinPoint joinPoint, Object result) {System.out.println("After returning method " + joinPoint.getSignature().getName() + ", return value is " + result);}
}

② 在Spring配置类中开启AOP支持:

@Configuration
@ComponentScan("com.hh")   
@EnableAspectJAutoProxy  
public class SpringConfig {
}

③ 需要应用切面的Bean:

@Service
public class MyServiceImpl implements MyService {@Overridepublic void doSomething() {System.out.println("Doing something...");}
}

④ 测试:

public class ApplicationContextTest {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);UserService userServiceImpl = (UserService)context.getBean("userServiceImpl");userServiceImpl.show1();}
}

执行结果:

Before method show1
show1…
After returning method show1, return value is null

通过以上步骤,就可以配置一个切面,并将其应用到需要增强的Bean上。在执行目标方法时,切面中定义的通知会根据切点的匹配规则在目标方法的前后执行,从而实现对目标方法的增强。

05. Spring AOP 的通知有哪些类型?

在Spring AOP中,通知(Advice)是在切点(Pointcut)上执行的一段代码,用于实现横切关注点的具体逻辑。通知可以分为以下几种类型:

在这里插入图片描述

① 在切面类中定义5种通知:

@Component
@Aspect
public class MyAspect {/*** 前置通知* @param joinPoint 连接点*/@Before("execution(* com.hh.service.*.*(..))")public void myBeforeAdvice(JoinPoint joinPoint) {System.out.println("Before method " + joinPoint.getSignature().getName());}/*** 后置通知* @param joinPoint 连接点*/@After("execution(* com.hh.service.*.*(..))")public void myAfterAdvice(JoinPoint joinPoint) {System.out.println("After method " + joinPoint.getSignature().getName());}/*** 返回通知* @param joinPoint 连接点*/@AfterReturning(pointcut = "execution(* com.hh.service.*.*(..))", returning = "result")public void myAfterReturningAdvice(JoinPoint joinPoint, Object result) {System.out.println("After returning method " + joinPoint.getSignature().getName() + ", return value is " + result);}/** * 异常通知 * @param joinPoint 连接点* @param ex 异常*/@AfterThrowing(pointcut = "execution(* com.hh.service.*.*(..))", throwing = "ex")public void myAfterThrowingAdvice(JoinPoint joinPoint, Exception ex) {System.out.println("After throwing method " + joinPoint.getSignature().getName() + ", exception is " + ex.getMessage());}/*** 环绕通知* @param proceedingJoinPoint 连接点* @return Object* @throws Throwable 异常*/@Around("execution(* com.hh.service.*.*(..))")public Object myAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {// 在目标方法执行前执行的逻辑System.out.println("Around Before method " + proceedingJoinPoint.getSignature().getName());// 调用目标方法Object result = proceedingJoinPoint.proceed();// 在目标方法执行后执行的逻辑System.out.println("Around After method " + proceedingJoinPoint.getSignature().getName());return result;}
}

② 在配置类上开启 Spring AOP:

@Configuration
@ComponentScan("com.hh")   
@EnableAspectJAutoProxy 
public class SpringConfig {
}

③ 需要增强的目标对象和目标方法:

@Service
public class UserServiceImpl implements UserService {@Overridepublic void show1() {System.out.println("show1....");}
}

④ 测试:

public class ApplicationContextTest {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);UserService userServiceImpl = (UserService)context.getBean("userServiceImpl");userServiceImpl.show1();}
}

执行结果:

Around Before method show1
Before method show1
show1…
After returning method show1, return value is null
After method show1
Around After method show1

06. AOP 有哪些实现方式?

AOP(Aspect-Oriented Programming,面向切面编程)有多种实现方式,其中比较常见的包括以下几种:

① 基于代理的 AOP:基于代理的 AOP 是 Spring AOP 的实现方式,它通过创建代理对象来实现对目标对象方法的拦截和增强。基于代理的 AOP 又分为 JDK 动态代理和 CGLIB 代理两种方式,其中 JDK 动态代理只能代理实现了接口的类,而 CGLIB 代理可以代理任意类。

② 基于字节码增强的 AOP:基于字节码增强的 AOP 是 AspectJ 的实现方式,它通过在编译期或类加载期间修改字节码来实现对目标对象方法的拦截和增强。基于字节码增强的 AOP 可以拦截更多的操作,例如类的初始化、静态方法调用等。

③ 基于注解的 AOP:基于注解的 AOP 是一种简化 AOP 配置的方式,它通过在切面类和目标类的方法上添加注解来实现对目标对象方法的拦截和增强。基于注解的 AOP 可以减少配置文件的编写,提高开发效率。

需要注意的是,不同的 AOP 实现方式有各自的优缺点,选择合适的实现方式需要根据具体的业务需求和技术场景进行评估。

07. Spring AOP 和 AspectJ AOP 有什么区别?

Spring AOP 和 AspectJ AOP 都是 AOP 的实现方式,它们有以下几点区别:

① 实现方式:Spring AOP 是基于代理的 AOP,它通过创建代理对象来实现对目标对象方法的拦截和增强;而 AspectJ AOP 是基于字节码增强的 AOP,它通过在编译期或类加载期间修改字节码来实现对目标对象方法的拦截和增强。

② 功能支持:AspectJ AOP 支持更多的 AOP 功能,例如拦截类的初始化、静态方法调用等操作,而 Spring AOP 只能拦截方法调用。

③ 配置方式:Spring AOP 的配置方式比较简单,可以通过 XML 配置文件或注解来实现;而 AspectJ AOP 的配置方式比较复杂,需要使用 AspectJ 的专用语言来编写切面。

④ 性能:由于 Spring AOP 是基于代理的 AOP,它的性能相对较低;而 AspectJ AOP 是基于字节码增强的 AOP,它的性能相对较高。

需要注意的是,Spring AOP 和 AspectJ AOP 都是 AOP 的实现方式,它们可以互相补充,例如可以使用 Spring AOP 来拦截方法调用,使用 AspectJ AOP 来拦截类的初始化等操作。选择合适的 AOP 实现方式需要根据具体的业务需求和技术场景进行评估。

08. JDK动态代理和CGLIB动态代理的区别?

JDK 动态代理和 CGLIB 动态代理都是基于代理模式实现的 AOP 技术,它们的主要区别如下:

① 实现方式:JDK 动态代理是基于接口的代理,它只能代理实现了接口的类;而 CGLIB 动态代理是基于继承的代理,它可以代理任意类,包括没有实现接口的类。

② 性能:JDK 动态代理的性能相对较低,因为它是基于反射实现的;而 CGLIB 动态代理的性能相对较高,因为它是基于字节码增强实现的。

③ 代理对象:JDK 动态代理创建的代理对象是目标对象实现的接口,而 CGLIB 动态代理创建的代理对象是目标对象的子类。

④ 依赖关系:JDK 动态代理依赖于 JDK 的接口和反射机制;而 CGLIB 动态代理依赖于 CGLIB 库。

需要注意的是,JDK 动态代理和 CGLIB 动态代理都有各自的优缺点,选择合适的代理方式需要根据具体的业务需求和技术场景进行评估。如果目标对象实现了接口,可以考虑使用 JDK 动态代理;如果目标对象没有实现接口,可以考虑使用 CGLIB 动态代理。

09. 如何理解 Spring 中的代理?

在 Spring 中,代理是一种常用的设计模式,它可以在不改变原有代码的情况下,为对象提供额外的功能。Spring 中的代理主要用于实现 AOP(Aspect-Oriented Programming,面向切面编程)功能,通过代理对象来拦截方法调用,并在方法调用前后执行一些额外的操作,例如日志记录、权限控制、事务管理等。

Spring 中的代理主要分为两种类型:JDK 动态代理和 CGLIB 动态代理。JDK 动态代理是基于接口的代理,它只能代理实现了接口的类,通过反射机制来实现代理;而 CGLIB 动态代理是基于继承的代理,它可以代理任意类,通过修改字节码来实现代理。

在 Spring 中,代理对象是通过 AOP 框架创建的,它包含了目标对象和切面,用于在目标对象方法执行前后执行通知。代理对象可以通过 Spring 容器来获取,也可以通过编程方式创建。在使用代理对象时,需要注意代理对象和目标对象的类型,以及代理对象的生命周期等问题。

需要注意的是,代理是一种常用的设计模式,不仅在 Spring 中有应用,在其他框架和系统中也有广泛的应用。理解代理的概念和原理,可以帮助我们更好地理解和使用代理模式。

10. Spring在运行时通知对象?

在 Spring 中,运行时通知对象是指在程序运行期间,通过 AOP(Aspect-Oriented Programming,面向切面编程)技术来拦截方法调用,并在方法调用前后执行一些额外的操作,例如日志记录、权限控制、事务管理等。Spring 中的 AOP 框架提供了一种方便的方式来实现运行时通知对象,它可以通过代理对象来拦截方法调用,并在方法调用前后执行通知。

在 Spring 中,运行时通知对象的实现主要分为以下几个步骤:

定义切面:切面是一个横跨多个核心关注点的模块化功能单元,它包含了一组切点和一组通知,用于描述在哪些切点上执行哪些通知。

配置切面:在 Spring 配置文件中,通过 aop:config 元素来配置切面,包括切点和通知等信息。

创建代理对象:在 Spring 容器中,通过 aop:proxy 元素来创建代理对象,代理对象包含了目标对象和切面,用于在目标对象方法执行前后执行通知。

使用代理对象:在程序中,通过 Spring 容器来获取代理对象,并使用代理对象来调用目标对象的方法。代理对象会拦截方法调用,并在方法调用前后执行通知。

需要注意的是,运行时通知对象是通过 AOP 技术实现的,它可以在不改变原有代码的情况下,为对象提供额外的功能。在使用 AOP 技术时,需要注意切面的定义和配置,以及代理对象的创建和使用等问题

11. Spring 只支持方法级别的连接点?

在 Spring AOP 中,连接点(Join Point)是指程序执行过程中能够插入切面的点,例如方法调用、异常抛出等。Spring AOP 只支持方法级别的连接点,也就是说,只能拦截方法调用,而不能拦截类的初始化、静态方法调用等操作。

这是因为 Spring AOP 是基于代理的 AOP 实现方式,它只能拦截方法调用,而不能拦截类的初始化、静态方法调用等操作。在 JDK 动态代理中,代理对象只能实现接口,而接口中只有方法定义,因此只能拦截方法调用。在 CGLIB 动态代理中,代理对象是目标对象的子类,因此也只能拦截方法调用。

需要注意的是,虽然 Spring AOP 只支持方法级别的连接点,但是它可以通过切点表达式(Pointcut Expression)来选择特定的方法进行拦截,从而实现对程序行为的统一管理和控制。如果需要拦截类的初始化、静态方法调用等操作,可以考虑使用 AspectJ 等其他 AOP 框架。

12. Spring AOP 中 Weaving 是什么?

在 Spring AOP 中,Weaving(织入)是指将切面代码插入到目标对象的字节码中,从而实现对目标对象方法调用的拦截和增强。Weaving 是 AOP 的核心概念之一,它是实现 AOP 的关键技术之一。

Spring AOP 中的织入方式主要有两种:编译时织入和运行时织入。

编译时织入:编译时织入是指在编译期间将切面代码织入到目标对象的字节码中,从而生成新的字节码文件。编译时织入需要使用特定的编译器和插件,例如 AspectJ 编译器和 Maven 插件等。

运行时织入:运行时织入是指在程序运行期间将切面代码织入到目标对象的字节码中,从而实现对目标对象方法调用的拦截和增强。运行时织入需要使用 AOP 框架提供的代理对象来实现,例如 Spring AOP 中的 JDK 动态代理和 CGLIB 动态代理。

需要注意的是,Weaving 是 AOP 的核心概念之一,它是实现 AOP 的关键技术之一。在使用 AOP 技术时,需要了解织入的原理和方式,以及织入对程序性能和可维护性等方面的影响。

① 前置通知(Before):在目标方法执行之前执行通知逻辑。

public class MyBeforeAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {// 在目标方法执行前执行的逻辑System.out.println("Before method " + method.getName());}
}

② 后置通知(After):在目标方法执行之后执行通知逻辑。

public class MyAfterAdvice implements AfterReturningAdvice {@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {// 在目标方法执行后执行的逻辑System.out.println("After method " + method.getName());}
}

③ 返回通知(AfterReturning):在目标方法执行之后执行通知逻辑,只有在目标方法成功返回时才会执行。

public class MyAfterReturningAdvice implements AfterReturningAdvice {@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {// 在目标方法成功返回后执行的逻辑System.out.println("After returning method " + method.getName() + ", return value is " + returnValue);}
}

④ 异常通知(AfterThrowing):在目标方法抛出异常时执行通知逻辑。

public class MyAfterThrowingAdvice implements ThrowsAdvice {public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {// 在目标方法抛出异常后执行的逻辑System.out.println("After throwing method " + method.getName() + ", exception is " + ex.getMessage());}
}

⑤ 环绕通知(Around):在目标方法执行之前和之后都可以执行通知逻辑,可以控制目标方法的执行过程,例如可以在目标方法执行前进行一些准备工作,执行后进行一些清理工作。

public class MyAroundAdvice implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {// 在目标方法执行前执行的逻辑System.out.println("Before method " + invocation.getMethod().getName());// 调用目标方法Object result = invocation.proceed();// 在目标方法执行后执行的逻辑System.out.println("After method " + invocation.getMethod().getName());return result;}
}

这些通知类型可以根据具体的需求进行选择和组合,从而实现对目标对象的增强。例如,可以使用前置通知记录日志,使用后置通知进行资源释放,使用返回通知进行结果处理,使用异常通知进行异常处理,使用环绕通知控制目标方法的执行过程。

相关文章:

Spring题集 - Spring AOP相关面试题总结

文章目录01. Spring AOP 的理解?02. Spring AOP 思想的代码实现03. Spring AOP 的相关术语有哪些?04. Spring AOP 基于注解的切面实现?05. Spring AOP 的通知有哪些类型?06. AOP 有哪些实现方式?07. Spring AOP 和 AspectJ AOP 有…...

分考场

[蓝桥杯 2017 国 C] 分考场(假题&#xff1a;最小色数) 题目描述 nnn 个人参加某项特殊考试。 为了公平&#xff0c;要求任何两个认识的人不能分在同一个考场。 求最少需要分几个考场才能满足条件。 输入格式 第一行&#xff0c;一个整数 n(1<n<100)n(1<n<100…...

BI技巧丨DAX Studio

DAX Studio DAX Studio&#xff0c;作为PowerBI外部插件使用率排名第一的插件&#xff0c;相信各位小伙伴或多或少都听说过&#xff0c;那么DAX Studio具体有哪些功能呢&#xff1f; PS&#xff1a;DAX Studio的下载链接&#xff0c;小伙伴们可以自行搜索&#xff0c;这里就不…...

Java 8常用时间 API

Date: 你不爱我了吗? &#x1f6a1;本地时间时区相关格式化在Java 8中&#xff0c;Instant类用于表示时间戳&#xff0c;相当于旧的Date类&#xff1b;LocalDateTime类用于表示日期和时间&#xff0c;相当于旧的Calendar类&#xff1b;DateTimeFormatter类用于格式化日期和时间…...

C++运算符

C运算符 运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 内置了丰富的运算符&#xff0c;并提供了以下类型的运算符&#xff1a; 算术运算符关系运算符逻辑运算符位运算符赋值运算符杂项运算符 1. 算术运算符 运算符描述实例把两个操作数相加A B 将得到 30-从第…...

低/无代码赋能企业,IT与业务的角色正在悄然改变

现在这个社会&#xff0c;年轻人的压力是真的大&#xff0c;需要会的技能多到数不清。想学习多点技能也不知道去哪学&#xff0c;主要是网络资源太丰富&#xff0c;很难找到一个适合自己的。那接下来推荐4个大神级别的资源网站你可一定得码住&#xff0c;都是年轻人特别 …...

SpringCloud学习2(Spring Cloud Netflix)负载均衡Ribbon、Feign负载均衡、Hystix服务熔断

文章目录负载均衡RibbonRibbon的作用代码实现生产者cloud1_provider实现配置文件在HiController中编写以下代码启动集群消费者cloud1_consumer实现引入依赖编写配置文件编写启动类&#xff0c;并给RestTemplate配置LoadBalanced注解编写RestController来测试Feign负载均衡简介F…...

Spring 源码解析 - @Async 注解下的循环依赖问题原理

一、Async 注解下的循环依赖问题 我们都知道 Spring IOC 单例模式下可以帮助我们解决循环依赖问题&#xff0c;比如下面自己依赖自己循环依赖的场景&#xff1a; Component public class TestAsync {ResourceTestAsync async;public void test() {System.out.println("t…...

8个全球性编程比赛,天才程序员的梦想舞台

很多编程爱好者在学习之初&#xff0c;都渴望与全球的程序员一较高下&#xff0c;以证明自己的实力。 一些全球性的编程竞赛为他们提供了这样的机会&#xff0c;不仅可以与全世界的顶尖程序员们交流&#xff0c;还有机会获得丰厚的奖金和进入顶级公司的机会&#xff0c;更重要…...

2023年中国海洋大学计算机及电子信息考研分析

考研时间跨度&#xff1a; 初试时间&#xff1a; 2022年8月23 海大推免及创新人才计划接收通知。 2022年9月13 海大专业目录及人数&#xff0c;包含推免。 2022年10月18 2022年硕士研究生计划 &#xff0c;不含推免。 海大2022年硕士研究生计划 网上第一次时间为2022年9月24日…...

【C++笔试强训】第六天

选择题 1. 解析&#xff1a;十进制转换为八进制就是不断的除8&#xff0c;取余数。十进制转换成其他进制的数就是除以进制&#xff0c;取余。 解析&#xff1a;注意printf的转换&#xff0c;%%只会打印一个%&#xff0c;所以选A。 解析&#xff1a;由于()的原因p先和*结合&…...

Redission 中的 RedLock 原理实现, springboot 你造吗?

分布锁之RedLock 锁住你的心我的爱 &#x1f682;为什么需要使用 RedLock锁被误释放时钟不一致问题锁的“延迟释放”而不是死锁Redlock是啥redlock 存在什么问题惊群效应时钟漂移Redisson 实现 RedLock在 Redisson 中, RedLock的实现类是哪一个类?这一招叫抛砖引玉springboot …...

【沐风老师】3dMax一键房屋创建者插件使用方法详解

3dmax一键房屋创建者&#xff0c;一键生成墙体、窗洞和门洞的插件&#xff01;这个脚本主要用于创建或捕获一些架构项目所代表的平面&#xff0c;这是通过导入它们并在每个所需的层添加值来实现的。传统方法&#xff0c;但是省事儿多了&#xff01; 【版本要求】 3dMax 2015及…...

C/C++ 变量详解

文章目录前言一、静态变量与动态变量1. 概念2. 区别3. 使用方法和注意事项3.1 静态变量3.2 动态变量4. 结论二、全局变量与局部变量1. 区别2. 全局变量的使用方法和注意事项3. 局部变量的使用方法和注意事项4. 总结前言 对C学习感兴趣的可以看看这篇文章哦&#xff1a;C/C教程…...

新SSD盘安装操作系统启动不了

今天打算给电脑升级下装备&#xff0c;加装一块固态硬盘。 电脑原本自带两块硬盘&#xff08;SSD128GSATA1T&#xff09;&#xff0c;SSD清理了许久还是没空间&#xff0c;于是就买了块1TSSD&#xff0c;打算扩容下。 打开电脑后盖傻眼了&#xff0c;没有备用插槽&#xff0c…...

基于Spring、SpringMVC、MyBatis的病历管理系统

文章目录 项目介绍主要功能截图:登录首页医院公告管理用户管理科室信息管理医生管理出诊信息管理预约时间段管理预约挂号管理门诊病历管理就诊评价管理轮播图管理功能架构图部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历…...

QT编程从入门到精通之三十四:“第五章:Qt GUI应用程序设计”之“5.5 Qt Creator使用技巧”

目录 第五章:Qt GUI应用程序设计 5.5 Qt Creator使用技巧 第五章:Qt GUI应用程序设计 在“Qt 程序创建基础”上,本章将继续深入地介绍Qt Creator设计GUI应用程序的方法,包括Qt创建的应用程序项目的基本组织结构,可视化设计的UI界面文件的原理和运行机制,信号与槽的使用…...

网络工程方向有哪些SCI期刊推荐? - 易智编译EaseEditing

以下是网络工程领域的一些SCI期刊推荐&#xff1a; IEEE Transactions on Network and Service Management: 这是一个IEEE旗下的期刊&#xff0c;涵盖了网络与服务管理方面的研究。主要关注网络管理、服务管理和其它相关领域的创新和最新研究。 Computer Networks: 这是一本著…...

netty入门(二十六)任务加入异步线程池源码剖析

1.handler中加入线程池和Context添加线程池 1.1 源码剖析目的 &#xff08;1&#xff09;在 Netty 中做耗时的&#xff0c;不可预料的操作&#xff0c;比如&#xff1a;数据库、网络请求、会严重影响 Netty 对 Socket 的处理速度。 &#xff08;2&#xff09;而解决方法就是…...

神经网络算法入门和代码

文章内容 感知机&#xff08;Perceptron&#xff09;反向传播算法&#xff08;Back Propagation algorithm&#xff09;RBF(Radial Basis Function&#xff0c;径向基函数) 网络&#xff1a;单一层前馈网络&#xff0c;它使用径向基作为隐层神经元激活函数ART(Adaptive Resona…...

如何用一个端口同时暴露 HTTP1/2、gRPC、Dubbo 协议?

作者&#xff1a;华钟明 本文我们将介绍 Apache Dubbo 灵活的多协议设计原则&#xff0c;基于这一设计&#xff0c;在 Dubbo 框架底层可灵活的选用 HTTP/2、HTTP/REST、TCP、gRPC、JsonRPC、Hessian2 等任一 RPC 通信协议&#xff0c;同时享用统一的 API 与对等的服务治理能力。…...

ToBeWritten之杂项2

也许每个人出生的时候都以为这世界都是为他一个人而存在的&#xff0c;当他发现自己错的时候&#xff0c;他便开始长大 少走了弯路&#xff0c;也就错过了风景&#xff0c;无论如何&#xff0c;感谢经历 转移发布平台通知&#xff1a;将不再在CSDN博客发布新文章&#xff0c;敬…...

Linux三剑客之awk命令详解

1、概述 Linux三剑客&#xff1a;grep、sed、awk。grep主打查找功能&#xff0c;sed主要是编辑行&#xff0c;awk主要是分割列处理。本篇文章我们详细介绍awk命令。 awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。awk是一种编…...

C++异常处理:掌握高效、健壮代码的秘密武器

C异常处理全面解析&#xff1a;底层原理、编译器技巧与实用场景C异常机制&#xff1a;让我们迈向更安全、更可靠的代码C异常处理&#xff1a;掌握基本概念什么是异常&#xff1f;异常处理的重要性C异常处理的组成部分&#xff1a;try、catch、throw探索C异常处理的核心&#xf…...

Jetpack Compose基础组件之按钮组件

概述 按钮组件Button是用户和系统交互的重要组件之一&#xff0c;它按照Material Design风格实现&#xff0c;我们先看下Button的参数列表&#xff0c;通过参数列表了解下Button的整体功能 Composable fun Button(onClick: () -> Unit, // 点击按钮时的回调modifier: Modi…...

利用json-server快速在本地搭建一个JSON服务

1&#xff0c;json-server介绍 一个在前端本地运行&#xff0c;可以存储json数据的server。 通俗来说&#xff0c;就是模拟服务端接口数据&#xff0c;一般用在前后端分离后&#xff0c;前端人员可以不依赖API开发&#xff0c;而在本地搭建一个JSON服务&#xff0c;自己产生测…...

可重入函数与线程安全

指令乱序和线程安全 先来看什么是指令乱序问题以及为什么有指令乱序。程序的代码执行顺序有可能被编译器或CPU根据某种策略打乱指令执行顺序&#xff0c;目的是提升程序的执行性能&#xff0c;让程序的执行尽可能并行&#xff0c;这就是所谓指令乱序问题。理解指令乱序的策略是…...

一文彻底读懂异地多活

文章目录 系统可用性单机架构主从副本风险不可控同城灾备同城双活两地三中心伪异地双活真正的异地双活如何实施异地双活1、按业务类型分片2、直接哈希分片3、按地理位置分片异地多活总结系统可用性 要想理解异地多活,我们需要从架构设计的原则说起。 现如今,我们开发一个软件…...

孕酮PEG偶联物:mPEG Progestrone,PEG Progestrone,甲氧基聚乙二醇孕酮

中文名称&#xff1a;甲氧基聚乙二醇孕酮 英文名称&#xff1a;mPEG Progestrone&#xff0c;PEG Progestrone 一、反应机理&#xff1a; 孕酮-PEG衍生物是一类具有生物活性的类固醇-PEG偶联物&#xff0c;可用于药物发现或生物测定开发。孕酮是一种女性性激素&#xff0c;负…...

网络系统集成实验(一)| 网络系统集成基础

目录 一、前言 二、实验目的 三、实验需求 四、实验步骤与现象 &#xff08;1&#xff09;网络设置、网络命令的使用 ① 在华为设备中&#xff0c;常用指令的使用 ② 在思科设备中&#xff0c;常用指令的使用 ③ 在Windows设备中&#xff0c;常用网络指令的使用 &#xf…...