Spring概念问题详解
一、Bean的生命周期
1.1 BeanDefinition
Spring容器在进行实例化时,会将xml配置的<bean>的信息封装成一个BeanDefinition对象,Spring根据BeanDefinition来创建Bean对象,里面有很多的属性用来描述Bean。
- beanClassName:bean 的类名
- initMethodName:初始化方法名称
- properryValues:bean 的属性值
- scope:作用域
- lazyInit:延迟初始化
1.2 Bean是如何创建的
- 首先通过BeanDefinition来获取bean的定义信息。
- Spring先调用无参构造方法进行反射,创建出一个对象bean。
- bean的依赖注入,通常情况是使用set方法注入、@Autowired。
- 处理Aware接口,包含(BeanNameAware、BeanFactoryAware、ApplicationContextAware),实现了这些接口,就可以重写里面的方法。
- Bean后置处理器BeanPostProcess,前置。
- 初始化方法。InitializingBean和自定义的init方法。
- Bean后置处理器BeanPostProcessor,后置。例如要增强某个类,就使用到了AOP,其原理是动态代理。
- 销毁bean。
package com.example.demo.demos.bean;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;@Component
public class UserController implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {/*** 2. 构造方法*/public UserController() {System.out.println("UserController的构造方法执行了...");}private String name;/*** 3. 依赖注入*/@Value("张三")public void setName() {System.out.println("setName方法执行了...");}/*** 4.1 实现了BeanNameAware获取beanName* @param s*/@Overridepublic void setBeanName(String s) {System.out.println("setBeanName方法执行了...");}/*** 4.2 实现了BeanFactoryAware获取beanFactory* @param beanFactory* @throws BeansException*/@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("setBeanFactory方法执行了...");}/*** 4.3 实现了ApplicationContextAware获取ApplicationContextAware* @param applicationContext* @throws BeansException*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("setApplicationContext方法执行了...");}/*** 6.1 自定义初始化方法*/@PostConstructpublic void init() {System.out.println("init方法执行了...");}/*** 6.2 实现了InitializingBean接口,实现了afterPropertiesSet初始化方法* @throws Exception*/@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet方法执行了...");}/*** 8. 销毁方法*/@PreDestroypublic void destory() {System.out.println("destory方法执行了...");}
}
package com.example.demo.demos.bean;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBeanPostProcessor implements BeanPostProcessor {/*** 5. 初始化前置后处理器* @param bean* @param beanName* @return* @throws BeansException*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (beanName.equals("User")) {System.out.println("postProcessBeforeInitialization方法执行了... -> User对象初始化方法前开始增强");}return bean;}/*** 7. 初始化后置后处理器* @param bean* @param beanName* @return* @throws BeansException*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (beanName.equals("User")) {System.out.println("postProcessAfterInitialization方法执行了... -> User对象初始化方法后开始增强");}return bean; }
}
package com.example.demo.demos.bean;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan("com.example.demo.demos.bean")
public class SpringConfig {
}
package com.example.demo;import com.example.demo.demos.bean.SpringConfig;
import com.example.demo.demos.bean.UserController;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;@SpringBootTest
class DemoApplicationTests {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);UserController bean = context.getBean(UserController.class);System.out.println(bean);}}
执行结果如下。
- “初始化”的时候,Spring会去扫描@PostConstruct注解,这个注解标记在一个方法上,就是自定义的初始化方法,意思是在进行参数初始化的时候,会调用这个方法,用这个方法写的逻辑,对某些参数进行赋值。
- 在“初始化”的时候,Spring会去判断此类是否实现了InitializingBean接口,用
instance of InitializingBean
来判断。
1.3 推断构造方法
当Spring启动时,会去扫描类上是否有Spring的注解,若有,则将创建这个类的对象,默认会去调用这个类的无参构造方法。
- 如果这个类中有多个构造方法,也并未指明选取哪个构造方法,Spring就默认选择无参构造方法。
- 如果这个类中只有一个有参构造方法,就会使用这个构造方法
- 如果这个类中有两个有参构造方法,会报错,因为不知道使用哪个构造方法
public UserService(OrderService orderService) {this.orderService = orderService;
}
在进行有参构造方式创建对象时,例如上面代码,首先Spring会去查看OrderService是否已经被实例成bean注入到Spring容器中了,若没有,会报错。如果已经注入了,则会去匹配OrderService类型的bean,如果只匹配到一个bean,则就使用这个bean,若匹配到多个bean,则又会根据name,即orderService去匹配唯一的bean。
1.3 依赖注入
@Autowired
private OrderService orderService;
在类中有一个属性,例如上面代码,用@Autowired注解标记后,Spring会先根据类型OrderService找到对应的bean,可能多个bean,再根据orderService这个名字去找唯一的bean。再将找到的这个值,赋值给orderService这个属性。
1.4 动态代理
// 代理类 --> 代理对象 --> 代理对象.target = 原始对象 --> 放到spring容器
class UserServiceProxy extends UserService {UserService target;public void test() {// 先执行切面逻辑(before)// 执行被代理的方法: target.test()target.test();}
}
Cglib动态代理:
- 首先会生成一个代理类,继承了要代理的类,这里是UserServiceProxy,继承UserService类。
- 假设UserService类中有test()方法,所以代理类也有一个test()方法。这个代理类中的test()中,会先执行切面逻辑,再去调用被代理的test()方法。
- 代理类会创建一个UserService对象,名字叫target,这个target的值就是原始UserService对象,这个对象是经过了依赖注入后的对象,属性都有值。
1.5 三级缓存解决循环依赖
1.5.1 什么是循环依赖
@Component
public class AService {@Autowiredprivate BService bService;public void test() {}
}
@Component
public class BService {@Autowiredprivate AService aService;public void test() {}
}
- 在实例化A的时候,首先在堆中开启内存空间,形成了一个半成品A(未注入属性)。
- 在初始化A的时候,设置B属性,需要在容器中找是否存在成品B。存在则直接赋值并返回,不存在则需要实例化B。
- 假设2中的B不存在,需要实例化B,此时也是在堆中开启内存空间,形成半成品B。
- 在初始化B的时候,设置A属性,需要到容器中查是否存在A对象。存在则直接赋值并返回,不存在则又回到了实例化A的地方。形成了循环依赖。
1.5.2 三级缓存
三级缓存解决的是在初始化步骤中产生的循环引用问题。Spring框架中提供的类,DefaultSingletonBeanRegistry
,此类中定义了三个集合,又称为三级缓存。
1.5.3 一二级缓存解决循环依赖问题
- 实例化A,得到的是半成品对象也就是原始对象A,将原始对象A存入二级缓存。
- 继续注入B,B不存在则实例化B,并初始化B,得到B的原始对象,将原始对象B存入二级缓存。
- 此时又需要注入A,就从二级缓存中取出原始对象A来给B的属性注入。以此B对象创建成功,放入单例池(一级缓存)中。
- 将B注入给A,A创建成功,也放入单例池中。清理了二级缓存中的半成品对象。
- 这种使用一、二级缓存来解决循环依赖的问题,只适用于一般的对象,不适用于代理对象。
1.5.4 代理对象需要三级缓存
- 实例化对象A,A是代理对象,对象A会生成一个ObjcetFactory对象,将工厂对象放入到三级缓存中。对象工厂可以生成代理对象或普通对象。
- A对象需要注入B,B不存在则实例化B,原始对象B生成一个ObjectFactory对象,将工厂对象放入三级缓存中。
- B需要注入A,则从三级缓存中获取A的对象工厂。对象工厂A会生成一个A对象,若A是代理对象则生成代理对象,若不是则生成普通对象。
- 把A产生的代理对象,存入二级缓存中。
- 把A的代理对象注入给B,B创建成功,放入单例池中。B创建成功了也将注入给A,A也创建成功。放入到单例池中。
1.5.5 构造方法中的循环依赖
三级缓存中,可以解决的是初始化过程中的循环依赖问题。但Bean的生命周期第一步,构造方法。这其中也会产生循环依赖问题。
加上@Lazy注解,什么时候用对象,什么时候再实例化对象。
二、Spring单例Bean是线程安全的吗
2.1 Spring中的Bean是单例的吗
Spring的Bean是单例的,如果加上@Scope(“prototype”)注解,他才是个多例的。否则他在每个Spring的IOC容器中只有一个实例。
2.2 Spring中的单例Bean是线程安全的吗
- 不是线程安全的。当多用户同时请求同一个服务的时候,容器会给每个请求分配一个线程,这些线程会并发执行业务逻辑,如果业务逻辑中对包含对单例状态的修改,比如修改单例的成员属性,就要考虑线程安全问题。
- Spring本身不对单例bean做线程安全封装,需要开发者自行处理。
- 一般在Spring的bean中都是注入无状态的对象,也就是不可被修改的对象,例如service、dao,这些是没有线程安全的。
- 但如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例和加锁来解决。
三、AOP
3.1 什么是AOP,是否使用过AOP
3.1.1 AOP的解释
AOP称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
3.1.2 AOP使用场景
1. 记录操作日志。
(1)自定义注解
package com.example.demo.demos.annotation;import java.lang.annotation.*;@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {public String name() default "";
}
(2)定义切面类。通过切点表达式,获取方法上加了Log注解的方法,并将进入环绕通知增强方法中执行方法,以此来实现AOP。
package com.example.demo.demos.aop;import com.example.demo.demos.annotation.Log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;@Component
@Aspect
public class SysAspect {/*** 切点表达式*/@Pointcut("@annotation(com.example.demo.demos.annotation.Log)")private void pointCut() {}/*** 环绕通知增强方法* @param joinPoint* @return*/@Around("pointCut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {// 需要验证token或session// 获取被增强的类对象和方法信息Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;// 获取被增强的方法对象Method method = methodSignature.getMethod();// 从方法中解析注解if (method != null) {Log annotation = method.getAnnotation(Log.class);System.out.println(annotation.name());}// 方法名字String name = method.getName();System.out.println(name);// 获取request请求对象RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();ServletRequestAttributes sra = (ServletRequestAttributes) requestAttributes;HttpServletRequest request = sra.getRequest();// urlString url = request.getRequestURI();System.out.println(url);// 请求方式String methodName = request.getMethod();System.out.println(methodName);return joinPoint.proceed();}
}
(3)接口上加上注解。
package com.example.demo.demos.web;import com.example.demo.demos.annotation.Log;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class BasicController {// http://127.0.0.1:8080/hello?name=lisi@RequestMapping("/hello")@ResponseBody@Log(name = "获取姓名")public String hello(@RequestParam(name = "name", defaultValue = "unknown user") String name) {return "Hello " + name;}
}
(4)访问后,可以获取到方法的一些信息。
2. 缓存处理。
3. Spring中内置事务处理。
3.2 Spring中事务是如何实现的
- Spring支持编程式事务管理和声明式事务管理两种方式。
- 编程式事务控制:需使用TransactionTemplate来进行实现,对业务代码有侵入性,项目中很少使用。
- 声明式事务管理:声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
3.3 事务失效的场景
3.3.1 异常捕获处理
- 事务通知只有捕捉到了目标抛出的异常才能进行后续的回滚处理,如果目标自己处理掉了异常,事务通知无法知悉,则造成了事务失效。
- 解决办法:在catch块中,throw new RuntimeException(e) 将异常抛出去即可。
3.3.2 抛出检查异常
- Spring默认只回滚非检查异常。下面抛出FileNotFoundException是检查异常。
- 配置rollbackFor属性:@Transactional(rollbackFor=Exception.class)。
3.3.3 非public方法
- Spring为方法创建代理、添加事务通知,前提条件都是该方法是public修饰的。
- 解决方法:添加public关键字。
四、SpringMVC执行流程
4.1 JSP
- 用户发送请求到前端控制器
DispatcherServlet
。 HandlerMapping
处理器映射器,处理器映射器中,保存的路径和Hanlder信息。key就是路径,value是类名#方法名。DispatcherServlet
调用HandlerMapping
去查询Hanlder信息。HandlerMapping
把处理器对象和拦截器(如果有),封装成HanlderExecutionChain
执行链。DispatcherServlet
调用HandlerAdapter
处理器适配器。其会适配并调用具体处理器,也就是Controller层的某一个方法。- 处理器适配器会去处理参数类型,处理返回值等等。当方法执行完,会返回ModelAndView对象。
HandlerAdapter
将ModelAndView返回给DispatcherServlet
。DispatcherServlet
传给ViewResolver
进行视图解析。ViewResolver
返回具体视图给DispatcherServlet
。DispatcherServlet
渲染视图并响应用户。
4.2 前后端分离
- 前4步骤同4.1的前4步。
- 在HandlerAdaptor处理器适配器中,会请求处理器,由于方法上添加了@ResponseBody注解,会通过
HttpMessageConverter
来返回结果转换为JSON并响应。 - 由于接口层级的开发,只需要响应JSON返回即可。
五、SpringBoot自动配置原理
- 在Spring Boot项目中的引导类上有一个注解
@SpringBootApplication
,这个注解是对三个注解进行了封装,分别是@SpringBootConfiguration
、@EnableAutoConfiguration
、@ComponentScan
。 - 其中
@EnableAutoConfiquration
是实现自动化配置的核心注解。 该注解通过@lmport
注解导入对应的配置选择器。内部就是读取了该项目和该项目引用的Jar包的的classpath路径下META-INF/spring.factories
文件中的所配置的类的全类名。 - 在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。
- 条件判断会有像
@ConditionalOnClass
这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的Bean放入spring容器中使用。
六、Spring相关注解
6.1 Spring注解
6.2 SpringMVC注解
6.3 SpringBoot注解
七、MyBatis
7.1 MyBatis执行流程
- 读取mybatis-config.xml文件,获取要连接的数据库ip端口等数据库连接信息,并加载映射文件。加载映射文件可以一个文件一个文件地加载,使用<Mapper resource=“xxx/UserMapper.xml>”;也可以加载某个包,使用<package name=“com.xx.mapper”/>。
- 构建SqlSessionFactory,会话工厂,全局唯一,生产sqlSession。
- SqlSessionFactory来创建SqlSession会话,他是项目与数据库的会话,包含了执行sql语句的所有方法,每次操作都会创建一个会话,存在多个SqlSession。
- Executor执行器,真正地数据库操作接口,也负责查询缓存的维护。它是 MyBatis 中负责执行 SQL 语句的组件。
- Executor它在执行SQL时会依赖MappedStatement中的信息。Executor会根据MappedStatement提供的SQL语句、参数映射和结果映射等信息,完成参数设置、SQL执行和结果处理等操作。
- 参数类型转换,将java中的map、list等参数,转换成sql中的类型。
- 返回结果类型转换,将sql数据库中的类型转换为Java的类型。
7.2 延迟加载
7.2.1 什么是延迟加载
- 当我们在selectById查询的一条数据的时候,这条数据的返回resultMap中,又根据id调用findByUid查询了订单信息。
- 当我们程序获取查询结果时,例如只使用user.getUserName()去获取了用户名信息,未获取订单信息,MyBatis如果开启延迟加载的话,就不会查询订单信息。
- 延迟加载就是用到了才加载,不需要则不加载。MyBaits支持一对一和一对多关联集合对象的延迟加载,可以通过配置lazyLoadingEnabled=true来开启。默认是关闭的。
7.2.2 延迟加载的原理
- 使用CGLIB创建目标对象的代理对象,主要使用代理对象完成的延迟加载。
- 当调用目标方法user.getOrderList()时,进入拦截器invoke方法,发现user.getOrderList()是null值,执行sql查询order列表。
- 把order查询到后,调用user.setOrderList(List| orderList),接着完成user.getOrderList()方法的调用。
7.3 MyBatis的一级、二级缓存
- MyBatis中有本地缓存,基于PrepetualCache,本质是HashMap。一级、二级缓存都是基于本地缓存来的。
- 一级缓存,作用域是session级别,主要是sqlSession。
- 二级缓存,作用域是namespace和mapper作用域,不依赖于session。
7.3.1 一级缓存
基于PerpetualCache的HashMap本地缓存,作用域为Session,默认开启。当Session进行flush或者close之后,该Session中所有的Cache就将清空。
- 上面代码中创建了一个sqlSession,其获取的Mapper接口的代理对象后,执行了同一个方法查询,当查询第一次的时候,MyBatis会将结果存放在缓存中。
- 当第二次又查询的时候不再sql查,而是直接读缓存。
7.3.2 二级缓存
二级缓存需要单独开启,作用域为Namespace或mapper,默认也是采用PerpetualCache,HashMap存储。
相关文章:
Spring概念问题详解
一、Bean的生命周期 1.1 BeanDefinition Spring容器在进行实例化时,会将xml配置的<bean>的信息封装成一个BeanDefinition对象,Spring根据BeanDefinition来创建Bean对象,里面有很多的属性用来描述Bean。 beanClassName:be…...
使用pm2 部署react+nextjs项目到服务器
记录一下 next.config.js中: output: standalone,package.json配置: "scripts": {"dev": "cross-env NODE_OPTIONS--inspect next dev","build": "next build","start": "cp -r .nex…...
JVM常量池(class文件常量池,运行时常量池,字符串常量池)
文章目录 问题JVM运行时数据区JVM中的常量池Class文件常量池运行时常量池字符串常量池创建了几个对象String的定义intern()问题 超过1W字深度剖析JVM常量池(全网最详细最有深度) - 跟着Mic学架构 - 博客园 问题 jdk1.8之后 元空间是独立存在的…...
Java 大视界 -- 基于 Java 的大数据分布式存储在视频会议系统海量视频数据存储与回放中的应用(263)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
光谱相机在地质勘测中的应用
一、矿物识别与蚀变带分析 光谱特征捕捉 通过可见光至近红外(400-1000nm)的高光谱分辨率(可达3.5nm),精确识别矿物的“光谱指纹”。例如: 铜矿:在400-500nm波段反射率显著低于围…...
深入解析Java泛型:从定义到实战应用
目录 🚀前言🤔泛型的定义🐧泛型类🌟泛型接口✍️泛型方法、通配符、上下限💯泛型方法💯 通配符与上下限⚙️通配符(Wildcard)⚙️泛型上下限⚙️应用场景 🦜泛型支持的类…...
数据结构:绪论之时间复杂度与空间复杂度
作者主页 失踪人口回归,陆续回三中。 开辟文章新专栏——数据结构,恳请各位大佬批评指正! 文章目录 作者主页 数据结构的基本知识数据:数据元素:数据对象:数据类型:数据结构:逻辑结…...
ARM Linux远程调试
准备 虚拟机既能ping通开发板,又能ping通外网,还要能ping通Windows主机(如果你有上位机通信(tftp、vsftp、ssh)的需求) VMware 添加网络适配器2用作桥接网卡,原有的网络适配器保持为NAT模式 打开虚拟网络编辑器,配置VMnet0为桥接模式,外部连接设置为Realtek PCIe G…...
PostgreSQL 14 pacemaker 高可用集群
核心架构原理 集群组成(典型三节点结构): [Node1] PostgreSQL Pacemaker Corosync pcsd [Node2] PostgreSQL Pacemaker Corosync pcsd [Node3] PostgreSQL Pacemaker Corosync pcsd ↕ ↕ ↕ ← Corosync 多…...
英语学习5.21
Far from sensible 表示“很不明智的”、“离明智相去甚远”。这是一个固定表达,结构是 far from adj.,意思是“根本不……”,常见例子: far from perfect(远非完美) far from acceptable(远…...
实现了TCP的单向通信
1. 客户端代码:Client.java package com.xie.javase.net1;import java.io.*; import java.net.*;public class Client {public static void main(String[] args) {Socket socket = null;BufferedWriter bw = null;try {// 1. 获取本机IP地址对象InetAddress localHost = Inet…...
华为云Flexus+DeepSeek征文 | 基于ModelArts Studio和Cherry Studio快速构建午餐管家助手
目录 一、前言 二、ModelArts Studio(MaaS)介绍与应用场景 2.1ModelArts Studio(MaaS)介绍 2.2 ModelArts Studio(MaaS)使用场景 2.3 开通MaaS服务 2.4 开通DeepSeek-V3商用服务 三、Cherry Studio简介和安…...
Spring AI 1.0 GA 正式发布
Spring AI 1.0 GA 正式发布 快速入门核心特性1. **增强型 LLM(大语言模型)**2. **MCP 协议支持**3. **RAG(检索增强生成)**4. **评估与监控**5. **智能代理(Agents)** 下一步计划 VMware Spring 团队 Mark …...
【计算机网络 第8版】谢希仁编著 第五章运输层 题型总结1 UDP和TCP报文格式
UDP报文 5.13 这一题可以先问AI: 但是问了AI,肯定想知道:这些知识点在书上哪里?怎么这么难找? 没错这题主要是靠IP地址,所以应该在第四章。 P136 P137 省流: 1.UDP的首部格式是8个字节&…...
华为云Flexus+DeepSeek征文 | 基于ModelArts Studio 的 DeepSeek API 实现行业深度搜索和分析
目录 一、前言 二、ModelArts Studio(MaaS)介绍与应用场景 2.1ModelArts Studio(MaaS)介绍 2.2 ModelArts Studio(MaaS)使用场景 2.3 开通MaaS服务 2.4 开通DeepSeek-V3商用服务 三、Deep Research简介和安…...
计算机网络——Session、Cookie 和 Token
在 Web 开发中,Session、Cookie 和 Token 是实现用户会话管理和身份验证的核心技术。它们既有联系,也有明显区别。以下从定义、原理、联系、区别和应用场景等方面详细解析。 一、基本定义与原理 1. Cookie 定义: 是浏览器存储在客户端的小…...
AAOS系列之----简介
一文讲透AAOS架构,点到为止不藏私 📌 AAOS是以一个系统APP的方式集成进安卓系统中,通过在SystemServer中启动其中的Service 📚 1. CarServcie 是如何被启动的? AAOS中的核心服务是CarService,其描述如下: 代码路径如下: android1…...
CTF签到题
1.题目:VmxkMFUxVXhTbkpOU0dSVVZrWktWRlpyVm5kU2JGSnlWbXhhYkdKRlduaFpWVlpoVkcxRmQwMUlhRlpXTTFKUVZXdFZlR05zWkZsaVJrcG9ZbGRvUmxaR1dsZFVhekZIVW14V1lWSlZOVkJVVlZaV1RVWldjbFZzVGxOTlJGWlhWa1pvZDFWdFJuTlRhMVpXVm14YVIxUlVSa2RPYkVweVYyeENWMVpVUlhwV1ZtUjNVMj…...
甲骨文云服务器适合做网站吗
甲骨文云服务器:建网站,它到底是不是“神队友”? 各位想在网上“立门户”的老板、个人创作者们,大家好!现在这年头,没个自己的网站,那感觉就像做生意没个店面、搞创作没个画廊一样,…...
性能测试场景题
题目 针对618,双十一活动的,一个电商系统,如何设计压力测试方案? 参考答案 针对618、双十一等高并发电商大促活动,压力测试方案需覆盖全链路性能瓶颈识别、容量评估和极端场景验证。以下为详细设计框架,…...
数智读书笔记系列033《软件设计的哲学(第2版)》:复杂性管理的艺术
《软件设计的哲学》(A Philosophy of Software Design)书籍简介 作者:约翰奥斯特豪特(John Ousterhout) 出版信息:第2版于2024年11月由人民邮电出版社出版,中文版由茹炳晟、王海鹏翻译。 作者背景 奥斯特豪特是斯坦福大学计算机科学教授、美国国家工程院院士,拥有丰…...
MySQL与Redis数据同步实践与优化
一、数据不一致的典型场景 写入顺序不一致 当业务逻辑需要同时更新数据库和缓存时,若出现"先删缓存后更新DB"或"先更新DB后删缓存"操作失败,会导致缓存与数据库数据版本不一致。 并发读写冲突 高并发场景下可能出现: …...
HarmonyOS 鸿蒙应用开发基础:EventHub,优雅解决跨组件通信难题
EventHub是鸿蒙开发中用于线程内通信的事件中心模块,基于发布订阅模式实现组件间的高效通信。它完美解决了传统回调方式在多层嵌套场景下的痛点,使得组件间的通信更加灵活和易于管理。 核心特性 事件中心机制:通过事件名进行通信,…...
如何解决鸿蒙应用闪退问题
如何解决鸿蒙应用闪退问题 本文是一份面向 ArkTS/JavaScript/C 多语言开发者的综合性排查与优化手册,覆盖 HarmonyOS/OpenHarmony 5.x 时代 常见闪退根因、诊断流程、调试技巧、CI 监控及线上防护方案,力争帮你把 Crash 数量降到 …...
人民日报社主管媒体深度聚焦珈和科技“遥感+AI”农险精准化突破:首创“四维数据贯通”模式 树行业转型新标杆
近日,由人民日报社主管的《中国城市报》对珈和科技与国寿财险湖南省分公司联合打造的农业保险数字化标杆项目进行了深度报道。 作为"遥感AI"技术在农业风险管理领域的创新实践者,珈和科技依托自主构建的覆盖“天-空-地-人”的全维度智慧农业技…...
(1)深度学习基础知识(八股)——常用名词解释
1. FC FC全称是Fully Connect全连接层,也被称为Linear Layer线性层。 它的核心是:每个输入神经元 与 每个输出神经元 都要通过权重连接,适用于将输入特征映射到高维或者低维空间。 数学表示 对于一个输入向量,FC的计算方式是: 是…...
深度学习零基础入门(2)-实战1:激活函数、前向传播和反向传播
一、激活函数 激活函数的作用 激活函数在神经网络中起着至关重要的作用,主要用于引入非线性因素,使得神经网络能够学习和模拟复杂的非线性关系。如果没有激活函数,无论神经网络有多少层,最终都只能表示线性变换,无法…...
LeRobot的机器人控制系统(下)
目的和范围 机器人控制系统是 LeRobot 框架的核心组件,提供用于操作、标定和记录物理机器人数据的接口。该系统支持远程操作、记录演示数据集、重放动作以及在真实机器人上运行已训练的策略。它充当用户、物理机器人硬件和训练流程之间的桥梁。本文介绍机器人控制系…...
Linux Docker安装【再探完美版教程】
Dokcer安装 文章目录 Dokcer安装安装前准备安装前设置yum网络镜像源【重要】查看服务器系统版本以及内核版本查看服务器内核版本安装依赖包:设置阿里云docker-ce镜像源 安装Dockerdocker-ce安装启动docker并设置开机自启配置阿里云镜像测试: Docker概念&…...
Java-根据路径获取JSON字符串的value值
实现内容 入参: 一串json的字符串,根据传入的字符串路径和想要获取此路径下的key值 出参: 此路径下的key的value值 实现原理 采用一层一层获取的方式,判断第一层并且获取第一层的数据,放入到数组中,将该数组放到下一次循环,再获取下一层的数据 实现方法 /*** 根据路径获取…...
【小呆的随机振动力学笔记】随机过程基础【一】
文章目录 1. 随机过程基础1.1 随机过程的概率分布1.2 随机过程的统计特征1.3 平稳随机过程1.4 遍历过程平稳随机过程 1. 随机过程基础 \quad\quad 上一节,我们主要回顾了概率论知识,接下来我们来回顾随机过程基础理论(或者叫随机场࿰…...
Java 内存模型中的读、写屏障
目录 1. 基本概念 1.1、读屏障 (Load Barrier) 1.2、写屏障 (Store Barrier) 1.3、咖啡店例子 2. 常见内存屏障 2.1、volatile 1、缓存可见性 2、指令重排序 3、内存屏障 2.2、final 2.3、synchronized关键字 2.4、手动内存屏障 3、不同屏障类型对比 4、实…...
AI 多 Agent 图形化开发深度解析:iVX IDE 与主流产品技术架构对比研究
随着人工智能技术的发展,软件开发正从手工编码向智能辅助开发演进。在 AI 多 Agent 图形化开发领域,iVX IDE 与 GitHub Copilot、Tabnine、CodeGeeX 等主流产品代表了不同的技术路线。本文从技术架构、功能实现、性能表现、生态建设等维度,对…...
微服务中的 AKF 拆分原则:构建可扩展系统的核心方法论
在数字化浪潮的推动下,互联网应用规模呈指数级增长,传统单体架构逐渐暴露出难以扩展、维护成本高等问题,微服务架构应运而生并成为企业应对复杂业务场景的主流选择。然而,随着业务的不断扩张和用户量的持续增加,如何确…...
MySQL迁移SSL报错
文章记录了之前tdsql迁移IDC过程中遇到的小问题 环境 xboss业务: tdsql未启用SSL, IDC-mysql启用了SSL: 原因分析 1, 迁移前: 因为tdsql未启用ssl, 且应用未显式配置ssl JDBC默认使用非SSL连接,因此可以正…...
Mysql的主从同步
一主一从 IP地址主机名master节点192.168.10.200mysql200slave节点192.168.10.201mysql201 master节点操作 配置文件增加两行参数 [rootmysql200 ~]# tail -n 2 /etc/my.cnf.d/mysql-server.cnf log-bin/mylog/mysql200 server-id200 [rootmysql200 ~]# systemctl restart …...
云原生微服务的前世今生
目录 Part1 时代背景 Part2 何为微服务? Part3 微服务出现的意义 Part4 企业应用 京东:国内电商领域的微服务实践 阿里:微服务在复杂业务场景中的应用 Part5 Istio:服务网格时代的微服务治理中枢 Istio 的技术定位…...
Python之虚拟环境
文章目录 Python之虚拟环境虚拟环境核心概念为什么需要虚拟环境?虚拟环境注意事项 创建虚拟环境使用 venv (Python 3.3 内置)使用 virtualenv (第三方工具,支持Python 2/3)与 venv创建方式的区别Python 版本支持功能与兼容性依赖关系和性能命令行工具创建…...
【Java高阶面经:数据库篇】15. 零停机数据迁移:从双写到一致性校验
一、迁移架构设计:双写+增量同步的三层防护模型 1.1 核心架构流程图 #mermaid-svg-MfnakvBNrtFScrMe {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-MfnakvBNrtFScrMe .error-icon{fill:#552222;}#mermaid-svg-Mf…...
车载以太网网络测试-27【SOME/IP-SD简述】
文章目录 1 摘要2 SOME/IP-SD协议介绍2.1 定义与作用2.2 SOMEIP/SD协议通俗易懂的理解2.2.1 SOMEIP/SD协议是什么?2.2.2 通信流程(简化)2.2.3 车载功能示例2.2.4 类比理解 2.3 SOME/IP-SD报文结构2.3.1 Flags2.3.1.1 REBOOT (Bit 7)2.3.1.2 U…...
Ubuntu 22.04上升级Node.js版本
在Ubuntu 22.04上升级Node.js版本有几种方法,推荐使用NVM(Node Version Manager),因为它可以让你轻松管理多个Node.js版本。 方法1: 使用NVM(推荐) 1. 安装NVM # 下载并安装NVM curl -o- https://raw.gi…...
软件设计师“面向对象设计”真题考点分析——求三连
一、考点分值占比与趋势分析 综合知识历年考察统计 年份考题数分值占比考察重点2018334%继承类型、设计原则2019445.3%多态实现、类关系2020556.7%设计模式应用、接口隔离2021334%消息通信、封装特性2022668%开闭原则、组合模式2023556.7%模板方法、适配器模式2024445.3%单一…...
flutter dart 函数语法
以下是 Dart 语言中函数语法的 详细实例说明,涵盖了所有常用写法 基本语法参数类型(必选、可选、命名、默认值)匿名函数、箭头函数高阶函数(函数作为参数/返回值)异步函数(async / await) 1. …...
鸿蒙Flutter实战:24-混合开发详解-4-初始化Flutter
概述 将 Flutter 模块添加至宿主鸿蒙项目中后,接下需要实现页面跳转、消息通信等功能,本文重点介绍如何初始化 Flutter。 项目配置 添加依赖 编辑 ohos_app/oh-package.json 文件 如果通过 Har 包方式引入 Flutter 模块,则需要添加如下内…...
微信小程序之Promise-Promise初始用
我们来尝试使用Promise。 1、需求,做个抽奖的按钮, 抽奖规则: 30%的几率中奖,中奖会提示恭喜恭喜,奖品为10万 RMB 劳斯莱斯优惠券,没中奖会提示再接再厉。 2、先搭界面: <view class&qu…...
工业 / 农业 / AR 场景怎么选?Stereolabs ZED 双目3D相机型号对比与选型建议
Stereolabs ZED 相机系列为视觉感知领域提供了多种创新解决方案,适用于不同应用场景。选择合适的 ZED 相机型号,需综合考虑分辨率、深度感知范围、接口类型等因素。 Stereolabs ZED 相机产品系列概览 ZED:首款立体视觉相机,专为高…...
(Git) 稀疏检出(Sparse Checkout) 拉取指定文件
文章目录 🏭作用🏭指令总览👷core.sparseCheckout👷sparse-checkout 文件 🏭实例演示⭐END🌟交流方式 🏭作用 类似于 .gitignore 进行文件的规则匹配。 一般在需要拉取大型项目指定的某些文件…...
Nginx 部署前端项目dist文件到局域网然后ngrok部署到公网
①项目里面 npm run build 生成的dist文件 ②下载nginx: download 将dist文件夹放入html文件夹中 ③conf修改配置 里面有nginx.conf 文本修改④在此目录下 打开cmd 输入 start nginx.exe 启动代理 ⑤http://localhost:90/index.html即可或者域名换成你的ip地址也可以 …...
【sylar-webserver】9 网络模块
目录 Address 类图 知识点 常用结构体 常用函数 Socket 类图 主要功能 初始化 socket 流程: ByteArray 知识点 zigzag 算法 TLV 编码结构 Stream 类图 Stream 流结构,提供字节流读写接口 SocketStream TcpServer 类图 主要功能 Address…...
野火鲁班猫(arrch64架构debian)从零实现用MobileFaceNet算法进行实时人脸识别(四)安装RKNN Toolkit2
RKNN Toolkit2是用来将onnx模型转成rknn专用模型,并可通过RKNN Toolkit Lite2或者RKNPU调用NPU进行加速计算的工具。 一开始我安装很多次都无法成功安装。后来跟售后技术对接,必须是PC平台的Linux环境才可以。我的电脑是windows,所以我需要用…...