Java 笔记 2023
排序算法:https://mp.weixin.qq.com/s/UzshZ0jX7bCHOp5GtiyDqQ
https://www.techxiaofei.com/post/chatgpt/local/
Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据
获取token地址
http://chat.openai.com/api/auth/session
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9.eyJodHRwczovL2FwaS5vcGVuYWkuY29tL3Byb2ZpbGUiOnsiZW1haWwiOiJ4ZDIwMjFlbWFpbEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZX0sImh0dHBzOi8vYXBpLm9wZW5haS5jb20vYXV0aCI6eyJwb2lkIjoib3JnLW9VaXVXYWpHejdGd2dLVzZ0YUtUSVM1byIsInVzZXJfaWQiOiJ1c2VyLW5iTFpNd0RlWERZeGJkMVp0cGJlTXFmNSJ9LCJpc3MiOiJodHRwczovL2F1dGgwLm9wZW5haS5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMTUxMDI4NTEwMjY2MjE3NTU5NjIiLCJhdWQiOlsiaHR0cHM6Ly9hcGkub3BlbmFpLmNvbS92MSIsImh0dHBzOi8vb3BlbmFpLm9wZW5haS5hdXRoMGFwcC5jb20vdXNlcmluZm8iXSwiaWF0IjoxNjk5NTg2MTUzLCJleHAiOjE3MDA0NTAxNTMsImF6cCI6IlRkSkljYmUxNldvVEh0Tjk1bnl5d2g1RTR5T282SXRHIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCBtb2RlbC5yZWFkIG1vZGVsLnJlcXVlc3Qgb3JnYW5pemF0aW9uLnJlYWQgb3JnYW5pemF0aW9uLndyaXRlIG9mZmxpbmVfYWNjZXNzIn0.DDmL22-mcBbiW2ZTACxRCSmA1073y9RKZd4CNZDzCLxSVitWzpd3l3VCOL-npbsUDoiBis1LMs0chu6yYU2iiRcKTx5RKRkSp-X5GxhZT-TJRDlat7zcSoLDs5bzbLuV5a32ViOP3ADFGR9zKttyWbPTmGgLXe8vKcB2bQzvk3ltMFlHEqdSpsvY2f7FiEGmffvBTdUFnrA7cSpaW51GkZtVpkemwSSSPlQ_DMEaFZZVdCyo2MV2u1rd30Wn7wpKi2iT4Dg_Pf0xoYaOz7Fb_aGJIHSSoEgHsSRoPpdHie9BUByKTB5whbHNhUvS2l2544s3c2AC6NsGZC2yezPDPA
一、拦截器使用
HandlerInterceptor spring mvc 拦截请求
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 在请求处理之前被调用,可以进行一些预处理操作
return true; // 返回 true 表示继续执行后续的拦截器和处理器(Controller)
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// 在请求处理之后、视图渲染之前被调用,可以对数据进行处理或修改
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// 在整个请求完成(包括视图渲染完毕)之后被调用,
//可以进行一些清理工作 比如threadlocal.remove()
}
}
RequestInterceptor openfeign 拦截所有feign请求
public class MyFeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
// 在这里可以对 Feign 请求进行处理,比如添加请求头
template.header("Authorization", "Bearer YourAccessToken");
}
}
@Async 注解必须在非同类中使用
AQS 抽象队列同步器
AQS 核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是基于 CLH 锁 (Craig, Landin, and Hagersten locks) 实现的。
springboot没有类似Django的middleware的中间件概念,但是可以通过Spring提供的拦截器(Interceptor)和过滤器(Filter)来实现类似Django中的中间件功能。
(1)拦截器
@Component
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在请求进入Controller处理之前进行拦截,可以进行数据处理、验证登录等操作
// 返回true表示继续执行后续操作,返回false表示终止请求处理
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 在请求返回给客户端之前进行拦截,可以进行后处理操作
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 在请求完成后进行拦截,无论请求成功还是发生异常,都会执行该方法
}
}
(2)过滤器
@Component
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 过滤器初始化方法
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 在请求进入Servlet之前进行拦截,可以进行数据处理、验证登录等操作
chain.doFilter(request, response); // 继续执行后续操作
}
@Override
public void destroy() {
// 过滤器销毁方法
}
}
进程是对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发;
线程是进程的子任务,是CPU调度和分派的基本单位,用于保证程序的实时性,实现进程内部的并发;
堆中的每一个节点值都大于等于(或小于等于)子树中所有节点的值。或者说,任意一个节点的值都大于等于(或小于等于)所有子节点的值。
- 静态方法为什么不能调用非静态成员?
这个需要结合 JVM 的相关知识,主要原因如下:
静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,需要通过类的实例对象去访问。
在类的非静态成员不存在的时候静态方法就已经存在了,此时调用在内存中还不存在的非静态成员,属于非法操作。
- JDK 动态代理只能代理实现了接口的类或者直接代理接口,而 CGLIB 可以代理未实现任何接口的类
JDK 动态代理类使用步骤:
(1)定义一个接口及其实现类;
(2)自定义 InvocationHandler 并重写invoke方法,在 invoke 方法中我们会调用原生方法(被代理类的方法)并自定义一些处理逻辑;
(3)通过 Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 方法创建代理对象;
CGLIB 动态代理类使用步骤:
(1)定义一个类;
(2)自定义 MethodInterceptor 并重写 intercept 方法,intercept 用于拦截增强被代理类的方法,和 JDK 动态代理中的 invoke 方法类似;
(3)通过 Enhancer 类的 create()创建代理类;
- SpringApplication.run()这句话执行过程,完整解释一下?
SpringApplication.run()是Spring Boot应用启动的入口方法,用于启动Spring Boot应用。它的执行过程可以分为以下几个步骤:
(1)创建SpringApplication实例:首先会创建一个SpringApplication实例,该实例是用于启动Spring Boot应用的主要类。
(2)解析命令行参数:在创建SpringApplication实例时,会将命令行参数传递给它,用于配置应用的行为。例如,可以通过命令行参数来指定应用的配置文件、激活的Profile等。
(3)加载应用配置:SpringApplication会根据配置文件、注解等方式加载应用的配置信息,包括Bean定义、数据源配置、事务管理等。
(4)创建Spring容器:SpringApplication会根据加载的配置信息创建一个Spring容器(ApplicationContext),该容器负责管理应用中的所有Bean,并提供相应的依赖注入功能。
(5)启动Spring容器:一旦Spring容器创建完成,SpringApplication会调用refresh()方法启动Spring容器。在这个过程中,Spring容器会对所有的Bean进行初始化,并完成依赖注入。
(6)执行应用逻辑:Spring容器启动后,会根据配置信息自动扫描并加载应用中的所有组件,包括控制器、服务等。然后,根据URL映射来处理HTTP请求,执行相应的业务逻辑。
(7)监听端口:最后,SpringApplication会根据配置信息监听指定的端口,等待HTTP请求的到来。
总结:SpringApplication.run()方法的主要作用是启动Spring Boot应用,并完成Spring容器的初始化和HTTP请求的处理。它会在应用启动时执行一系列的步骤,包括加载配置、创建容器、执行业务逻辑等,最终使应用能够接收并处理HTTP请求。
注解
@ConditionalOnExpression 是 Spring Boot 中的一个条件注解,用于根据条件表达式来决定是否创建某个 Bean 或加载某个配置类。
@DependsOn 是 Spring Framework 中的注解之一,用于指定 Bean 之间的依赖关系。通过在一个 Bean 上添加 @DependsOn 注解,您可以告诉 Spring 容器,在初始化当前 Bean 之前,先初始化指定的依赖 Bean。
Mybatis
MyBatis通过SqlSession来处理事务, 默认情况下,它使用自动提交模式,但您也可以配置为使用手动提交模式。此外,您可以使用@Transactional注解或配置Spring的声明式事务来管理事务。
MyBatis的主要组件包括:
- SqlSessionFactory:它负责创建SqlSession实例,用于与数据库交互。
- /SqlSession:它是一个Java接口,提供执行SQL查询和管理事务的方法。
- Mappers:Mappers是XML或基于注解的接口,定义了SQL语句和Java对象的映射规则。