缓存三剑客:本质:导致大量请求直达数据库,数据库压力骤增(可理解为:redis:货架,数据库:仓库)
穿透:redis和数据库中都不存在(货架和仓库都没有),(有点类似攻击,请求查询不存在的信息,等于忙碌之后没有结果)
解决方案:
校验(先校验,在访问,在redis之前加一层过滤网)针对“格式 / 规则错误的请求”(驴头不对马嘴)
空值缓存(第一次发现没有,就设置空值(下次直接redis返回空值),并设置有效期(避免后续真的增加相应的数据)),
布隆过滤器(类似一个白名单,先查询白名单,有去访问redis)拦截:数据本身不存在的请求(合规)
击穿:主要针对热点数据,redis中没有,数据库中有(货架没有仓库有)
解决方案:锁(只放一个线程进行访问),永不过期(不设置过期时间)
雪崩:过期时间一致,或者redis宕机,
解决方案:随即过期(避免同时过期),集群(就是把redis在细分,解决的是rdis宕机),降级(丟车保帅,维持核心)
id自增实现
- 单库单表:优先用数据库自增(MySQL AUTO_INCREMENT),简单高效。
- 分布式系统:推荐雪花算法(性能好)或 Redis INCR(实现简单)。
- 特殊需求:若需自定义规则(如包含业务标识),可在自增基础上拼接前缀(如
ORDER_1001
)。
private RedisTemplate<Object, Object> redisTemplate;与private RedisTemplate redisTemplate;没有区别只是一个规定了泛型一个没有规定
spring事务和底层数据库的关系
spring事务相当于是个管理者,底层数据库更相当于是一个执行者
spring一般有
传播行为
事务失效
mysql有:
特性:ACID(原子性,持久性,隔离性,一致性)
事务的隔离机制:
读未提交
读已提交
可重复读
串行化
Spring 事务本身不直接实现 ACID,但它通过有效管理支持 ACID 的数据库事务,让开发者在使用时 “感知到 ACID 特性的存在”。ACID 的核心实现者始终是数据库。
针对配置类中的一些信息(yml)
- Spring Boot 会自动读取 yml 配置,无需手动加载。
- 简单配置用
@Value
更方便;复杂配置用配置类更规范。 - 配置类的核心作用是 “结构化管理配置”,而非 “让配置被读取”(读取本身是 Spring 自动完成的)。
@Service public class MyService { // 直接用@Value读取yml中的配置 @Value("${app.name}") private String appName; @Value("${app.port}") private Integer port; // 使用这些配置... } 方式二: yml文中的配置信息: user: name: "张三" age: 20 配置类 @Data @Configuration @ConfigurationProperties(prefix = "baidu") public class BaiduAIProperties { private String apikey; private String qianfanModel; } 通过配置类调用yml中的配置信息
定时任务有点类似于aop,单独调用(放在单独的job任务中)
@Component("contractJob") @Slf4j public class ContractJob { @Autowired private IContractService contractService; public void updateContractStatusJob() { contractService.updateContractStatus(); //需要设置定时任务的方法 log.info("定时更新合同状态成功!"); } }
建造者模式:
使用@build(lombok的注解),首先@NoArgsConstructor
和 @AllArgsConstructor
(只能生成全参和无参构造器,少参数的必须用空值替代)
import lombok.Builder; // @Builder: 自动生成建造者模式相关代码 @Builder public class User { // @NonNull: 标记为必选参数,会自动生成非空校验 可有可无 @NonNull private String id; // 必选:用户ID @NonNull private String username; // 必选:用户名 private int age; // 可选:年龄,默认0 private String email; // 可选:邮箱,默认null private String address; // 可选:地址,默认null } public class Main { public static void main(String[] args) { // 1. 创建包含所有属性的 User 对象 User user1 = User.builder() .id("1001") .username("张三") .age(25) .email("zhangsan@example.com") .address("北京市海淀区") .build(); // 2. 创建只包含必选属性的 User 对象(可选属性用默认值) User user2 = User.builder() .id("1002") .username("李四") // 不设置 age、email、address,使用默认值 .build(); } } 使用@NoArgsConstructor 和 @AllArgsConstructor则是要么全参要么是无参
JSONObject jsonObject = JSONUtil.parseObj(shadow.get(0).getReported().getProperties());理解下,一般在不知类型的话,可以使用转化为JSONObject,可以调用相应的方法进行操作,JSONObject是增强版map