业务方案总结
Q:Redis和数据库的缓存一致性保证A: 方案如下: 更新数据库之后删除缓存(旁路缓存模式) 并发情况下可采用延迟双删策略 或者实现canal客户端订阅数据变更,更新缓存 适合:商品详情页场景,读多写少的场景 先更新缓存再更新数据库(异步更新) 更新缓存成功采用消息队列更新数据(消费幂等性保证) 场景:秒杀 双写操作 同时更新Redis和数据库,可以使用事务保证(分布式事务方案,事务补偿机制) 场景:积分 数据回写 优先更新缓存,缓存数据定期更新到数据库(Redis集群和持久化机制) 场景:广告计费系统,点赞 Q:分布式锁实现方案A: 本地同步锁 分布式锁setNX 设置超时时间 redission看门狗机制,读写锁 redisssion redlock 解决锁的高一致性问题 Q:如何快速定位线上OOMA:出现的原因: 一次性申请的对象数量过多:如查询返回结果过大 内存资源耗尽未释放:如何jdbc连接、文件资源 本身资源不够:jmap -heap PID...
LeetCode算法题(二)更新中
二叉树1. 二叉树的中序遍历给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 提示: 树中节点数目在范围 [0, 100] 内 100 <= Node.val <= 100 示例:  12输入:root = [1,null,2,3]输出:[1,3,2] 代码: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) {...
LeetCode算法题(一)
哈希1. 两数之和给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 *target* 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 提示: 2 <= nums.length <= 104 109 <= nums[i] <= 109 109 <= target <= 109 只会存在一个有效答案 示例: 1234567输入:nums = [2,7,11,15], target = 9输出:[0,1]解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 输入:nums = [3,2,4], target = 6输出:[1,2]解释:因为 nums[1] + nums[2] == 6 , 返回[1, 2] 代码: 123456789101112131415161718192021/** * **进阶**:**时间复杂度小于 O(n2) 的算法解决此问题吗?** * 1....
责任链模式
基本概念责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。 核心思想:请求沿着处理者链传递,每个处理者决定是处理请求还是将其传递给下一个处理者,形成一个灵活的请求处理机制。 核心结构 Handler(处理者接口):定义处理请求的接口,包含设置下一个处理者和处理请求的方法 ConcreteHandler(具体处理者):实现处理者接口,决定是否处理请求,若不能处理则传递给下一个处理者 Client(客户端):创建处理链,并向链的起始端发送请求 示例说明场景:员工请假审批系统,不同级别领导处理不同天数的请假申请 组长:处理1天内的请假 部门经理:处理3天内的请假 总经理:处理7天内的请假 超过7天的请假不予批准 处理者接口 123456789101112public abstract class Approver { protected Approver nextApprover; // 下一个处理者 // 设置下一个处理者 ...
观察者模式
基本概念观察者模式:一种行为型设计模式,定义了对象之间的一对多依赖关系。当一个对象(主题)的状态发生改变时,所有依赖它的对象(观察者)都会自动收到通知并更新。 核心思想: 主题(Subject)维护观察者(Observer)列表 主题状态变化时,主动通知所有观察者 观察者无需知道其他观察者的存在,只关注主题更新 核心结构 主题(Subject):定义观察者注册/移除方法,维护观察者列表,状态变化时通知观察者。 观察者(Observer):定义更新接口,接收主题通知并作出响应。 具体主题(ConcreteSubject):实现主题接口,维护具体状态,状态变化时通知观察者。 具体观察者(ConcreteObserver):实现观察者接口,存储与主题相关的状态,响应通知。 示例说明场景:股票价格监控系统,当股票价格变化时,自动通知所有关注该股票的投资者 定义主题接口 123456789public interface Stock { void attach(Investor investor); // 注册观察者 void...
装饰者模式
基本概念装饰者模式:是一种结构型设计模式,动态地将额外责任附加到对象上。对于拓展功能,装饰者提供了子类化之外的弹性替代方案,提供了比子类化更灵活的拓展方案,允许在运行时动态添加或删除对象的行为。 核心思想是:使用装饰者包装原始对象,装饰者与原始对象实现相同接口,从而在不修改原始对象的前提下,为其添加新功能。 核心结构 Component(组件):定义对象接口,装饰者和被装饰者都实现此接口 ConcreteComponent(具体组件):接口的具体实现类,即被装饰的原始对象 Decorator(装饰者抽象类):持有组件引用,实现与组件相同的接口 ConcreteDecorator(具体装饰者):实现装饰逻辑,为组件添加新功能 示例说明 场景一:有一家咖啡连锁店,需要设计一个下单系统,其中需要设计一个拓展性强且耦合性低的咖啡设计结构,用户能够选择不同的调料,各种调教价格不一,同时存在后续新增的调料。 咖啡基类 12345678910// 咖啡基类public abstract class Beverage { String description =...
状态模式
基本概念状态模式:是一种行为型设计模式,允许对象在内部状态改变时改变它的行为,对象看起来似乎修改了它的类。 核心思想:将状态抽象为独立的类,上下文对象持有状态对象的引用,当状态改变时,只需更换状态对象,从而改变上下文的行为,避免使用大量条件判断语句。 核心结构 State(状态接口):定义所有具体状态必须实现的接口,声明状态相关的方法 ConcreteState(具体状态):实现状态接口,定义特定状态下的行为 Context(上下文):持有当前状态对象的引用,将状态相关的请求委托给当前状态对象处理 示例说明场景:设计一个手机播放器,具有”播放”、”暂停”、”停止”三种状态,不同状态下点击按钮会有不同行为。 状态接口 1234567public interface PlayerState { void clickPlay(); // 点击播放 void clickPause(); // 点击暂停 void clickStop(); //...
迭代器模式
基本概念迭代器模式:一种行为型设计模式,它提供一种顺序访问集合对象元素的方法,而无需暴露集合的内部表示。通过将遍历逻辑与集合本身解耦,使得不同遍历方式可以独立变化。 核心结构 迭代器接口(Iterator):定义遍历元素的方法(如hasNext()、next()、remove())。 具体迭代器(Concrete Iterator):实现迭代器接口,维护遍历的当前位置。 聚合接口(Aggregate):定义创建迭代器的方法(如createIterator())。 具体聚合(Concrete Aggregate):实现聚合接口,返回具体迭代器实例。 示例说明场景:自定义数组的迭代器 定义迭代器接口 12345678// 迭代器接口interface Iterator<T> { boolean hasNext(); // 是否有下一个元素 T next(); // 获取下一个元素 void remove(); // 删除当前元素(可选)} 定义聚合接口 12345//...
单件模式
基本概念单件模式:一种创建型设计模式,确保一个类在系统中只有一个实例,并提供全局访问点。主要用于解决全局资源共享的问题,常用于需要唯一控制的场景(如配置管理、日志记录、线程池等)。 核心结构: 类自身负责创建唯一实例 提供全局访问该实例的方法 确保实例只能被创建一次 示例说明场景:设计一个全局日志记录器,确保系统中只有一个日志实例 饿汉式单例(线程安全,立即加载) 123456789101112131415161718192021// 饿汉式单例(线程安全,类加载时创建实例)public class LoggerHungry { // 1. 私有静态成员变量,类加载时立即初始化 private static final LoggerHungry instance = new LoggerHungry(); // 2. 私有构造函数,防止外部实例化 private LoggerHungry() { System.out.println("日志记录器初始化"); } ...
代理模式
基本概念代理模式:是一种结构型设计模式,为其他对象提供一种代理以控制对这个对象的访问。代理对象作为客户端和目标对象之间的中介,允许在不修改目标对象的情况下,添加额外的控制逻辑(如访问权限、延迟加载、日志记录,事务管理等)。 核心结构: 抽象主题(Subject):定义代理和真实对象的共同接口 真实主题(Real Subject):实际需要被代理的对象 代理主题(Proxy):持有真实主题的引用,控制对真实主题的访问 示例说明场景:设计一个图片加载系统,需要对大尺寸图片实现延迟加载(只有在真正需要显示时才加载实际图片),避免初始加载时消耗过多资源。 图片显示接口 1234567代码实现// 抽象主题:定义图片显示接口public interface Image { void display();} 真实主题:实际图片对象(加载大尺寸图片资源) 12345678910111213141516171819public class RealImage implements Image { private String...