目录
后端
JavaSE
-
反射
是什么:一种能力(在运行时检查、访问和修改类、方法、属性等信息)
作用:在运行时查看和操作 类的内部结构
有一个密封的玩具盲盒:
怎么用:
-
方法重载
是什么:一种现象,方法的名字相同。但参数列表不同,返回类型可以相同或不同
作用:让同一个方法能适配多种参数传递
怎么用:配合泛型,创建 统一返回结果 类
-
泛型
是什么:一种机制(Java中的类型参数化机制)
作用:允许在类、接口、方法中使用类型参数,例如:List<String> xx = new ArrayList<>();
怎么用:工具类中,接收任意类型的参数
-
种类
- 集合类泛型:
- 自定义泛型类:一种特殊的类定义方式,在定义类时不指定具体数据类型
public class Result<T> implements Serializable:①泛型类声明,Java中一种特殊的类定义方式,它允许在定义类时不指定具体数据类型,而是在使用时再确定类型。②表示这个类支持泛型,
T是一个占位符,使用时会被具体类型替换。③Serializable是 Java 中的一个标记接口(没有方法的接口),用于表示类的对象可以被序列化(对象转数据,就像把玩具拆成零件装进盒子。反序列化:把字节流 → Java对象)- 泛型接口:
-
泛型方法:
-
符号含义使用场景
TType(类型)最常用的泛型符号EElement(元素)集合中的元素KKey(键)Map中的键VValue(值)Map中的值RReturn(返回值)方法的返回类型IDIdentifier(标识符)ID类型
-
-
Lambda表达式
是什么:一个匿名函数(没名字的函数,能被当作参数传递)
作用:规定遍历的每一步操作
怎么用:例 -> 为每个口味设置菜品id,这里的菜品ID 由第一步中 插入的菜品得到(需要在mapperXML映射文件中配置返回主键,否则无法获取到id)
flavors.forEach(flavor -> {
flavor.setDishId(dish.getId());
});
“->”:箭头操作符/ Lambda 操作符,Java8 中引入了一个新的操作符 ,箭头操作符将 Lambda 表达式拆分成两部分 : 左侧 : Lambda 表达式的参数列表 右侧 : Lambda 表达式中所需执行的功能
-
数据类型
- Integer:整数
-
集合框架
-
Collection
-
List
-
Set
-
Map集合:键值对集合。Map是个接口,有如下三个实现类
-
HashMap<K,V>
-
基本特性:
- 基于哈希表实现
- 允许使用
null作为键和值 - 不保证元素的顺序
- 非线程安全
-
核心方法:
put(key, value)- 添加键值对get(key)- 获取指定键对应的值remove(key)- 删除指定键的映射containsKey(key)- 检查是否包含指定键
-
-
LinkedMap
-
TreeMap
-
-
-
三目运算:
条件 ? 表达式1 : 表达式2。
Spring全家桶
Spring vs SpringFramework vs SpringMVC vs SpringBoot
Spring指的是SpringFramework( 包含了Spring(提供核心功能:IoC容器、AOP、事务管理)和SpringMVC。
SpringMVC是SF的Web模块
SpringBoot 整合了 Spring Framework 和 Spring MVC
Web开发的三层架构
-> Controller:控制层,执行业务
-> Service:业务层,功能实现
-> DAO:数据访问层,操作数据库(Mapper层)
-
注解
一、核心与配置注解 (IoC容器):这些注解用于配置和组装Spring Bean,是IoC(控制反转)的核心。
二、Web MVC 注解:这些注解主要用于开发Web应用程序,处理HTTP请求和响应。
三、事务管理注解
四、AOP 注解
五、配置与属性注解
六、测试注解
-
Spring Cache
-
@EnableCaching:开启缓存功能,加在启动类
-
@Cacheable:在方法执行前,查缓→有数据→返回 否则 →调用方法→存入方法的返回值
-
@CachePut:方法的返回值放入缓存
-
@CacheEvict:从缓存中删除一条/n条数据
-
参数
-
allEntries=true:删除所有
-
cacheNames = “xxx”:缓存名
-
key = “#xxx”:设置存储键,存储值是Redis自动计算 方法的返回数据 得到的
- 比如:key = “#categoryId”
- 以分类ID作为缓存键
- 每个分类ID对应一个独立的缓存项
- 相同分类ID的请求会命中缓存
- 不同分类ID的请求会分别缓存
-
-
-
Spring
-
类+方法+接口
- @Transactional:事务管理
-
类注解
-
@RestController:
@Controller+@ResponseBody的组合 -
@ResponseBody:让方法返回数据而非html -
@RequestMapping:菜单
-
ConfigurationProperties:加载springboot配置文件中的数据。将配置文件中的属性值自动绑定到JavaBean。
-
@Component:将类交给spring管理- @Service:服务类
- @
Controller:控制类 @Configuration:数据访问层@Configuration:配置类
-
-
方法注解
-
@PostMapping: POST 请求的接口地址。Spring MVC 提供的一个组合注解,等价于@RequestMapping(method = RequestMethod.POST) -
@GetMapping:GET请求的接口地址。@RequestMapping(method = RequestMethod.GET)的简化形式。 -
@PutMapping
-
@Bean:加在方法上,将方法的返回值交给spring托管。
-
@RequestBody:获取请求体中的数据。将前端的请求(JSON)数据→对象,POST请求用(get请求没有请求体)
- 快递员(前端) 送来一个包裹(HTTP请求),包裹里装着商品(JSON数据)(后端)需要拆开包裹才能拿到商品
@RequestBody就是这个帮你自动拆包裹的工具
- 快递员(前端) 送来一个包裹(HTTP请求),包裹里装着商品(JSON数据)(后端)需要拆开包裹才能拿到商品
-
@PathVariable:获取路径参数,例如@PostMapping(“/status/{status}“)中的{status}
-
-
@ExceptionHandler :定义异常处理方法,专门处理控制器方法执行时抛出的异常。
-
-
MyBatis
- @Select:直接在接口方法上编写 SQL 选择语句。
- @Insert:直接在接口方法上编写 SQL 插入语句。
-
Lombok
-
-
Spring
-
AOP:面向切面编程,就是面向特定的方法编程(OOP:面向对象编程)
-
类注解
- @Aspect:标明这是一个AOP类
- @Conmponent:交给IOC容器管理
-
方法注解
- @Around:针对哪些方法生效
-
-
IOC,DI,Bean对象:控制反转(将对象创建的控制权交给容器)&依赖注入(容器为程序执行提供其所必须的资源)&容器中创建,管理的对象
这里有个神奇的容器,当一个类需要调用另一个类时,它可以直接提供
- @Component:将对象交给IOC容器
- @Autowired:自动依赖注入(DI)+自动装配Bean,在初始化对象时使用
-
事务管理:把小任务捆绑到一块,它们要么同时成功,要么同时失败→一错全错,全对才对。(应对多表联合时,一个表操作成功而其他表操作失败)
- @Transactional:只有运行异常(RuntimeException)才会回滚,如果错误是被抛出的则事务依然会提交。
- @Transactional(rollbackFor = {xxxxxx}):可以指定何种类型的异常会回滚
-
-
SpringMVC:(Model - View - Controller)模型-视图-控制器
-
Model:包含实体类(entity,与数据库字段一样)、数据传输对象(DTO,接收前端的数据,在后端代码中传输)、值对象/视图对象(VO,前端要的数据)、业务逻辑层(Service接口以及实现类ServiceImpl)。
-
DTO:一种pojo对象,全称数据传输对象(Data Transfer Object)
- 一个“快递包裹”,在不同的“地方”之间传递数据。DTO包含除了entity字段的其它字段,entity字段和数据库表中的字段完全一致。
- VO是后端→前端,DTO是前端→后端 或者 后端→后端
-
-
View:前端
-
Controller:处理前端请求,调用服务
-
-
Spring Task
一个框架,让程序能定时执行
-
Spring Cache
-
Spring AI
让Java调用大模型的框架
-
LangChain4j
专为Java设计的AI应用框架
让Java优雅地调用AI
核心组件:会话功能,RAG知识库,Tools工具
-
会话功能:用户和大模型聊天
-
AiServices工具类
- 引入依赖:LangChain4j-srpingbott-starter
- 配置yaml
- 创建接口
- 添加接口 @AiService:接口上,自动创建AI代理服务,可指定流式模型
-
流式调用:允许AI模型边生成边返回结果,而不是等待完整响应
- 导入依赖
- 配置yaml
- 返回值用 Flux<T> 接收
-
消息注解:接口的chat方法上,就是提示词,可规范ai的回答范围(只回答医疗相关)
- @SystemMessage(fromResource”xxx.txt”):指定txt文件
- @UserMessage(“xxx”)
-
会话记忆:大模型无记忆,只能把之前的聊天内容与新的提示词一起发过去,但上下文最多10w token
- 在config配置类中,定义会记忆对象
- 配置对象:在@AiService中添加属性:chatMemory=“配置的对象名字”
-
会话记忆隔离:解决所有用户共享一个记忆对象的问题
- 在config类中定义chatMemoryProvider对象
-
会话记忆持久化:
-
-
RAG:检索增强生成,就是让大模型 可以检索外部知识库。训练数据
-
引入依赖
-
文档加载器,可以传入指定的解析器
- FileSystemDocumentLoader, 根据本地磁盘绝对路径加载
- ClassPathDocumentLoader,相对于类路径加载
- UrlDocumentLoader,根据url路径加载
- 引入解析器依赖
- TextDocumentParser,解析纯文本格式的文件
- ApachePdfBoxDocumentParser,解析pdf格式文件
- ApachePoiDocumentParser,解析微软的office文件,例如DOC、PPT、XLS
- ApacheTikaDocumentParser(默认),几乎可以解析所有格式的文件
-
-
Tools:function calling,让ai能调用java中的方法
就是告诉ai能调用java的中的哪些方法
例如创建一个预约功能的工具类ReservationTool
然后就可以在接口中指定这个Tools,这样ai可以直接调用ReservationTool中的方法了
-
MyBatis
一个操作数据库的框架(JDBC的super-plus版)
你是个专注于写原生JDBC语句的佬儿,有天你突然看到一个后端小子建了个接口,又写了个方法,然后在方法上加上了@Select注解,短短三行就执行完了对数据库的操作
-
使用:①引入3个依赖(创建springboot时直接选,MySQL Driver+Mybatis Framework+Lombok)→②配置(在resources→application.properties)
-
配置
- 驱动
- 日志输出
-
注解
- @Mapper:加在接口上,标注是MyBatis接口(Mapper接口)
- @Delete:方法,删除
- @Select:方法,查询
-
#和:#{...},**占位符**,预编译SQL,传递参数用 And {…},拼接符,参数动态时使用,但会被SQL注入,慎用。
-
-
数据库连接池:一个容器,分配和管理数据库连接。项目自带,有HikariPool,Hikari和Druid(德鲁伊)连接池。
每次连接都要连了再断?干活累了回床上再出来,那直接原地休息,间断地工作不就好了。做到了连接复用+系统访问性能+避免连接遗漏
- 指定连接池:在上文配置文件中,添加spring.datasource.type=com.alibaba.druid.pool.DruidDataSource,需要添加依赖(pom.xml)
-
XML映射:不适用注解,直接在XML中配置SQL。在数据为动态时使用
-
标签
1、foreach
-
重要参数
1、separator=”;”
2、parameterType=(“xxxxxx”):告诉MyBatis传入参数的类型
3、useGeneratedKeys=“true”:告诉MyBatis使用数据库自动生成的主键值
4、keyProperty=“id”:配置返回主键:id,当插入成功后,将数据库自动生成的主键值设置到实体类的id属性中
-
示例
-
Redis
一种数据库,基于内存存储,很快。
存储键值对(key-value)结构的数据。用于大量访问的数据(新闻,咨询,商品)
-
存什么?

-
操作命令
-
字符串

-
哈希

-
列表

-
集合

-
有序集合
-
通用
-
-
Java操作
-
Jedis
-
Lettuce
-
Spring Data Redis:已封装前两者
- 导入依赖
- yml配置
- 编写配置类RedisConfiguration,创建RedisTemplate(Redis的模板对象)类型的方法
-
MySQL
硬盘(IO)存储,慢
-
索引
基于内存存储,很快。
登录校验
解决:“在没有登录时”,直接修改url地址进入到对应接口便可随意操作”的问题
是什么:本质是http协议基于请求响应模型,是无状态的协议,后一次请求并不会携带前一次的数据。因此需要解决数据不传递的问题→会话技术,以及拦截非法请求
-
会话技术:会话就像打电话,用户打开浏览器,建立通讯,直到有一方断开连接。会话跟踪,一种维护浏览器状态的方法,服务器识别多次请求是否来自同一人。
-
Cookie:是一种客户端会话跟踪技术,用户数据存储在浏览器(客户端)中。基于cookie的会话跟踪技术
-
设置与获取
-
优点:HTTP协议中支持的技术(像Set-Cookie 响应头的解析以及 Cookie 请求头数据的携带,都是浏览器自动进行的,无需手动操作)
-
缺点:
- 移动端APP(Android、IOS)中无法使用Cookie
- 不安全,用户可以自己删除或禁用Cookie
- Cookie不能跨域(协议,IP/域名,端口)三个有一个不同就无法生效
-
-
Session:
-
Token:令牌,一串字符串。常用JWT令牌,在登录成功后发放。
-
JWT令牌

-
使用
- 引入依赖
- 生成JWT:签名算法和密钥(base64转化的一段字符,自己定义)+自定义信息(claim)+过期时间
- 解析
-
-
-
拦截非法令牌
-
过滤器(Filter):
-
拦截器(Interceptor):动态拦截控制器方法执行
-
使用步骤:创建+注册(JWT令牌校验演示)
-
创建
- 拦截器方法的返回值代表是否放行,true放
-
注册
-
-
-
-
MP:MybatisPlus
MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变
https://baomidou.com/introduce/
1、使用步骤
①依赖
②定义Mapper接口,继承BaseMapper<?>,传入:你要操作的实体类
③分歧 -> a.就这样用,Service中需要手动引入Mapper接口,然后调用Mapper
-> b.让Service接口继承IService(传入:实体类),Service实现类继承ServiceImpl接口(传入:Mapper接口,实体类),无需再引入Mapper。
-
注解
数据库和实体类不一致才使用
@TableNmae:加载类上,指定表名
Doker
一种容器技术,让应用放在虚拟环境中运行,每个环境互不影响
-
安装
镜像:curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
检查 Docker镜像配置
cat /etc/docker/daemon.json
添加Docker镜像
清理未完成下载
docker system prune -a
运行并创建容器(本地没有会自动拉取SQL镜像)
docker run -d \ —name mysql \ -p 3306:3306 \ -e TZ=Asia/Shanghai \ -e MYSQL_ROOT_PASSWORD=123456 \ mysql
-
查看/启动镜像和容器
docker images
运行容器,run是创建
docker start xx
查看所有容器 docker ps -a —format “table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}”
# 查看运行中容器 docker ps —format “table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}”
-
打包与读取镜像
Docker sava —help
Docker sava -o nginx.tar nginx
Docker load -i xx.tar
-
开机自启
# Docker开机自启 systemctl enable docker # Docker容器开机自启 docker update —restart=always 容器名/容器id
-
数据卷与挂载:让主机可以修改容器内的文件
MQ:消息队列
一种异步通信方法(类似邮局,把业务请求存起来,发给相应的线程)
确保数据同步
核心术语
生产者(Producer) -> 发消息
代理(Broker) -> MQ的服务器,存储和转发消息
消费者(Consumer) -> 处理
- Kafuka:最高吞吐量
- RabbitMQ
- RocketMQ:阿里的
- Kafka:Apache公司的
微服务与分布式
分布式:就是指有多个系统,如A模块调用B模块的接口
微服务:一种软件架构风格,传统项目所有功能都写在一起,微服务就是把这些功能拆成若干个小项目,最后组装成一个大项目,比如支付功能就只实现支付,每个小项目都可以部署在不同的地方,互相调用
微服务常见框架如下
-
SpringCloud
核心组件如下
实际场景:A模块 调用 B模块
1、注册中心:Nacos
告诉系统你这服务叫啥,想用你的时候直接叫你名儿
2、负载均衡:Ribbon
现在B模块被部署在多个节点上,A到底请求哪一个节点
3、服务调用 Feign
封装请求,类似HttpClient
4、熔断:Hystrix
设定请求上限 -> B规定只接受100个,结果A发了105个,超过的会直接拒绝,类似保险丝
5、网关:Gateway
把请求转发到服务上
-
Dobbo
Redis与锁
分布式锁的实现有Redis和Zookeeper
其中Redis提供了Redisson框架,提供了很多锁的实现 黑马点评
高并发&多线程
进程之间内存空间独立,线程共享内存空间。
高并发:同一时间很多请求
K8S
一个容器编排工具
1、为服务器中的docker提供虚拟IP
2、核心组件
Netty
是什么:一个网络编程框架(基于Java NIO 事件驱动 异步)
异步:Netty 的所有 I/O 操作均为异步 -> 当调用一个方法时,它立即返回一个
ChannelFuture对象,而操作本身在后台执行。可以通过这个 Future 对象来获取操作完成的通知或等待其完成。事件驱动:“当数据来了通知我” Netty基于 事件模型 来处理网络事件 -> 当某个事件发生时(如连接建立、数据到达、异常抛出),Netty自动触发相应的事件,调用预先注册的处理器进行处理。这种模型非常高效,可以处理成千上万的并发连接。
责任链模式:
ChannelPipeline是责任链模式的完美体现。数据进出会像在一条流水线上一样,依次经过多个ChannelHandler的处理。每个 Handler 只关心自己负责的逻辑(如解码、日志、业务处理),实现了功能的解耦和高度可定制化。作用:让程序在高并发下依然又快又稳
怎么用:搭建Websokect连接
-
关键组件
-
EventLoopGroup和EventLoop:类似线程组和线程,
EventLoopGroup分配EventLoop来处理新的连接 和 已有的连接中的事件。一般会创建BossGroup和WorkerGroup两个EventLoopGroup。EventLoop:事件循环(I/O事件调度器) -> 一个不断循环的执行体,处理绑定的
Channel。BossGroup&WorkerGroup:一个负责接收客户端的连接。另一个处理已被接受的连接的 I/O 操作。
-
ServerBootstrap:服务器端的组装和启动类,负责将所有核心组件组合在一起并启动服务器。
-
Channel:通道,表示一个网络连接,负责数据的读写和网络操作。所有 I/O 操作都是通过 Channel 进行的。底层是抽象类,只能被子类实现
-
ChannelPipeline:管道。处理数据的责任链,包含一系列处理器 -> 为Channel提供处理器。类似Stream,拦截流经Channel的进出事件
-
ChannelHandler:管道的事件处理器。类似Filter处理 Channel 上各种事件。
常见处理器:
HttpServerCodec,HttpObjectAggregator用法:pipeline.addLast(new HttpServerCodec());
-
ChannelFuture:异步操作结果容器,代表一个尚未完成的异步操作。提供查询操作状态的方法
(isDone(), isSuccess())。I/O 操作都会立即返回一个
ChannelFuture -
-
实际应用
现在要用异步处理WebSoket连接
3.1 添加依赖
3.2 创建服务器启动类-通常在websoket-netty目录下
①设置属性
③创建启动方法,先开店(ServerBootstrap),再接客(Channel)。channel创建后才会执行serverBootstrap.channel
④关闭方法
⑤核心管道配置
⑥自定的拦截
⑦完整实现
3.3 创建另一个启动类,用于异步启动其它服务 -> 与启动类在同一目录,异步启动创建netty
部分信息可能已经过时






