当前位置: 首页 > news >正文

leecodecode【双指针题2】【2026.5.26打卡-java版本】

盛最多水的容器

要点:right-left, 移动小的那边

class Solution { public int maxArea(int[] height) { //双指针 int left = 0; int right = height.length -1; int ans = 0; while(left < right){ int area = (right - left) * Math.min(height[left], height[right]); ans = Math.max(ans, area); if(height[left] < height[right]){ left++; }else{ right--; } } return ans; } }

接雨水

要点: 双指针找到短的那边 ,记录leftmax, rightmax

class Solution { public int trap(int[] height) { int maxleft = height[0]; int maxright = height[height.length -1]; int left = 1; int right = height.length - 2; int ans = 0; while(left <= right){ if(maxleft < maxright){ if(maxleft <= height[left]){ maxleft = height[left]; }else{ ans += maxleft - height[left]; } left++; }else{ if(maxright <= height[right]){ maxright = height[right]; }else{ ans += maxright - height[right]; } right--; } } return ans; } }

判断子序列

要点: s一个指针i, t一个指针j

class Solution { public boolean isSubsequence(String s, String t) { //双指针 int i = 0; int j = 0; while(j < t.length() ){ char c = t.charAt(j); if(i < s.length()&& s.charAt(i) == c){ i++; } j++; } return i == s.length(); } }

随机知识

业务

1.登录业务

(1)双token机制

token是什么?

(2)切面限流

1. 什么是 Token?为什么要用 Token?

问:你能解释一下 Token 是什么吗?与 Session 有什么区别?

答:
Token 可以理解为服务器颁发给客户端的临时凭证,客户端每次请求时带上它,证明“我是合法登录的用户”。它类似一张有时效、有权限的门禁卡

与 Session 的主要区别:

  • Session:服务器存储用户信息(有状态),需要共享存储(如 Redis)才能多机共用。
  • Token:客户端存储 Token(通常用 JWT),服务器只负责签发和验证(无状态),天然适合分布式系统。

2. 双 Token(Access Token + Refresh Token)的流程

问:你们项目里是怎么做登录态管理的?为什么需要双 Token?

答:
我们使用的是双 Token 方案

  • Access Token:有效期短(15分钟),用于调用业务接口(加购物车、下单等)。
  • Refresh Token:有效期长(7天),不参与业务,唯一的职责是去换取新的 Access Token。

流程:

  1. 登录成功后,服务端返回一对 Token。
  2. 客户端将 Access Token 放在请求头中调用业务接口。
  3. 若 Access Token 过期(返回 401),客户端拿 Refresh Token 调用/refresh接口。
  4. 服务端验证 Refresh Token 有效后,颁发新的 Access Token(有时也刷新 Refresh Token)。
  5. 客户端用新 Token 重试原来的请求。

好处:

  • 用短期 Access Token 降低泄露风险。
  • 用长期 Refresh Token 实现无感续期,提升体验。
  • 修改密码或异常时,仅吊销 Refresh Token 即可强制下线。

3. 注解和切面是如何联系上的?

问:我看到一个限流注解@AccessLimit,但它只是一个注解,没有任何执行逻辑。请问它怎么起到限流作用的?注解和切面之间是怎么联系起来的?

答:
注解本身只是元数据,真正执行逻辑的是AOP 切面。它们的联系是通过Spring AOP 的切入点表达式建立的,步骤如下:

  1. 定义注解@AccessLimit,包含limittime等属性。

  2. 编写切面类AccessLimitAspect,并标注@Aspect@Component

  3. 在切面中写一个@Around方法,切入点表达式为@annotation(accessLimit)

    java

    @Around("@annotation(accessLimit)")
    public Object limit(ProceedingJoinPoint joinPoint, AccessLimit accessLimit) {
    // 读取注解参数,进行限流检查...
    }

  4. Spring 启动时,解析该表达式,自动为所有标注了@AccessLimit的方法创建代理对象

  5. 运行时调用该方法,会先执行切面中的限流逻辑。若通过,再通过joinPoint.proceed()调用原始方法;若超限则直接返回错误,原始方法不再执行。

关键点:不是注解主动找到切面,而是切面主动声明“我要处理所有带有这个注解的方法”。没有切面,注解就是单纯的注释。


4. 双 Token 的常见追问(展示深度)

追问1:Refresh Token 存储在哪里?有什么安全要求?

Refresh Token 必须放在HttpOnly Cookie或移动端安全存储中,绝不能放在 localStorage,否则易被 XSS 窃取。Access Token 可以放在内存或短时 Cookie 中。

追问2:如果 Refresh Token 也被偷了怎么办?

可以使用Refresh Token 轮换:每次续签时颁发新的 Refresh Token,旧的一个立即失效。这样攻击者只能使用一次,且服务端可检测异常(如一个 Refresh Token 被用了两次)。此外,还可以绑定设备指纹或 IP 来增强安全性。

追问3:为什么 Access Token 通常用 JWT,而 Refresh Token 有时要存数据库?

Access Token 需要高频验证,用无状态的 JWT 性能好;Refresh Token 需要支持吊销、轮换、次数记录等,通常用数据库或 Redis 存储状态,便于精细控制。

缓存

缓存到底存的是什么?

你打开商城首页,看到"全部商品"那一页,这一页数据在 Redis 里存的样子是:

key: "product:list::1:12" value: [商品A, 商品B, 商品C ... 一共12个商品]

这就是缓存:把一整个页面内容存起来,下次再来就直接拿,不用查数据库。


为什么不同条件要拆开存?

假设你是老板,商场里有三个货架,每个货架摆法完全不一样

货架摆法
默认排序最新商品摆最前面
价格升序最便宜的摆最前面
价格降序最贵的摆最前面

这三个货架的顺序完全不同,必须分开记。

同样道理:

product:list:手机::1:12 → [华为新品, iPhone15, ...] 按最新时间排 product:list:手机:price_asc:1:12 → [红米, iPhoneSE, iPhone15, ...] 按最便宜排

这两份数据长得不一样,不能放同一个格子里,否则会乱套。


为什么 page 也要存?

因为每个货架有 10 页。你是老板,你不能把所有商品全写在同一张纸上——纸太长了。你分 10 页写:

内容
第 1 页商品 A, B, C ... L
第 2 页商品 M, N, O ... X
第 3 页商品 Y, Z ...

如果你把第 1 页和第 2 页的东西混在一起存,那当用户想看第 1 页时,你会分不清哪些是该给他看的。

总结成一句话

每个不同组合(不同分类 + 不同排序 + 不同页)都是不同的"页面",每个页面单独存一份缓存。这就像给 150 张不同的照片各拍了一张拍立得,哪张被看到了就拿出来用,不用重新拍。

用户有多少种玩法,就有多少种缓存

Key 就是"地址标签"

CacheConstants.PRODUCT_LIST = "product:list:" ← 固定前缀,告诉"这是商品列表" "手机" ← 分类 ":" ← 分隔符 "price_asc" ← 排序方式 ":" ← 分隔符 "1" ← 第几页 ":" ← 分隔符 "12" ← 每页几条

最终 Key =product:list:手机:price_asc:1:12

Value 就是那个页面的数据

[红米, ¥999, 库存200件], [iPhone SE, ¥3499, 库存50件], ... 共12条

(实际存的是 JSON 字符串,就是这 12 个商品的完整信息)

回答你最后的问题

用户不管怎么排序,我都有对应的缓存是吗?

不是一开始就有的,是"谁先点,谁触发创建":

用户操作Key状态
第一个人打开首页product:list::1:12没有缓存→ 查 DB → 写缓存
第二个人打开首页product:list::1:12缓存命中→ 直接返回
有人点"价格升序"product:list::price_asc:1:12没有缓存→ 查 DB → 写缓存
后来又有个人点"价格升序"product:list::price_asc:1:12缓存命中→ 直接返回

只要有一个用户选过这个组合,这个组合就会被缓存,后面来的人全走缓存。如果永远没人选"价格降序第 3 页",它也不会被创建,不占内存。

这种方法叫做惰性缓存(lazy caching)——按需生成,按需缓存。

碎碎念:后续会更新每天学习的八股和算法 题,开始准备秋招的第16天。努力连续更新100天!以后每天就按,秋招项目【java+agent】,科研,必做项目,算法,八股,锻炼身体来总结。今天效率一般。明天加油!!!

总结:不要放弃呀,

1.算法要系统过一遍【灵神】2/27

2.秋招项目,【java】开始实际看业务,2/10;【agent】还在学,决定把helloagent看一遍,3/16

3.科研要跑一下,无

4.检测项目也得总结文档,无,

5.训练项目看看先选择好,无

6.背八股,无

7.锻炼身体,1h

昨天玩手机三点才睡觉欸嘿嘿,今天状态不好,明天再接再厉!

【要吃好喝好睡好!!!保持心情愉悦】

http://www.jsqmd.com/news/904775/

相关文章:

  • AbMole 小讲堂丨Artemisinin:青蒿素在氧化应激与铁代谢研究中的应用
  • 为团队开发环境统一配置Taotoken CLI工具的方法
  • LeetCode 3120.统计特殊字母的数量 I:(手写)哈希表
  • Claude + LangChain集成测试失效真相:Token截断、上下文漂移与状态同步漏洞(附可复用的断言校验DSL)
  • Silicon Graphics 030-8123-016/B I/O 背板组件
  • 蒙皮(Skinning):让 3D 角色的皮肤跟着骨头动的神奇魔法
  • 导师严选!2026年刚需首选的专业AI论文写作软件
  • 【Sora 2作品集交付标准】:影视级分辨率/帧率/连贯性三重校验清单(附2024最新Luma+Runway交叉验证协议)
  • 马能否走遍棋盘的可达性证明
  • Arduino线性霍尔磁力传感器模块应用指南:从原理到转速测量实战
  • 知行合一:为什么懂了很多道理,还是很难做到?
  • 基于Arduino与超声波传感器的低成本智能跟随小车全攻略
  • OBS Studio 安装 Zoominator 插件
  • 为什么92%的Sora 2预告片被平台限流?深度溯源Meta/Adobe联合内容指纹协议,附3种合规性绕过验证路径
  • 基于树莓派Pico的模块化教育机器人平台设计与实践
  • Arduino与L298N实现线性执行器平滑位置控制
  • 魔术贴采购指南——采购经理们关注哪些供应商特质? - 变量人生001
  • 干货合集:盘点2026年全网顶尖的的降AIGC平台
  • 2026 杭州西装定制工艺 / 预算匹配指南|高定西装口碑排名前十名推荐 - 天天生活分享日志
  • 3分钟解锁网易云音乐:ncmdump解密工具完全指南
  • 番茄小说下载器:3种方式打造个人离线图书馆,告别网络限制
  • 2026 大连卖大牌包包必看!90% 人踩坑套路,添价收包包回收全拆解 - 薛定谔的梨花猫
  • Taotoken 的审计日志功能如何助力企业 API 访问管理
  • 3分钟找出Windows热键冲突元凶:Hotkey Detective让你重掌键盘控制权
  • Windows 11任务栏自定义终极指南:用Taskbar11解锁隐藏功能
  • 科创板新股长进光子首日涨1510%,早期投资者最高获567倍回报
  • 告别论文焦虑:6款2026年优质AI论文网站深度横评
  • 为ClaudeCode编程助手配置稳定可靠的API后端
  • PortSwigger SQL注入LAB10
  • Topit:Mac窗口置顶神器,彻底提升你的多任务效率