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

topcode【随机算法题】【2026.5.24打卡-java版本】

最长有效括号

要点:栈,push下标

class Solution { public int longestValidParentheses(String s) { //栈 //放前哨-1 Deque<Integer> stack = new ArrayDeque<>(); stack.push(-1); int ans = 0; for(int i = 0; i < s.length(); i++){ char c = s.charAt(i); if(c =='('){ stack.push(i); }else{ stack.pop(); if(stack.isEmpty()){ stack.push(i); }else{ ans = Math.max(ans, i - stack.peek()); } } } return ans; } }

下一个排列

要点:从后往前找第一个小的数,再找比这个数大一点的数,换位置,旋转

class Solution { public void nextPermutation(int[] nums) { //找下降点 int i = nums.length - 1; while((i-1)>=0 && nums[i]<=nums[i-1] ){ i--; } if(i-1>= 0){ int j = nums.length -1; while(nums[j]<=nums[i-1] && j>=0){ j--; } swap(nums,i-1,j); } reverse(nums, i); } private void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } private void reverse(int[] nums, int start) { int end = nums.length - 1; while (start < end) { swap(nums, start, end); start++; end--; } } }

数据流的中位数

要点:大顶堆,小盯堆分成两边

class MedianFinder { // leftMaxHeap: 存放较小的一半数,堆顶是这一半中的最大值(大顶堆) private PriorityQueue<Integer> leftMaxHeap; // rightMinHeap: 存放较大的一半数,堆顶是这一半中的最小值(小顶堆) private PriorityQueue<Integer> rightMinHeap; public MedianFinder() { // 大顶堆:使用 lambda 表达式 (a, b) -> b - a,让大的元素在堆顶 leftMaxHeap = new PriorityQueue<>((a, b) -> b - a); // 小顶堆:默认排序,小的元素在堆顶 rightMinHeap = new PriorityQueue<>(); } public void addNum(int num) { // 情况1:左半边为空,或者 num 小于等于左半边的最大值 // 说明 num 应该放在左半边(较小的一半) if (leftMaxHeap.isEmpty() || num <= leftMaxHeap.peek()) { leftMaxHeap.offer(num); // 平衡:左半边最多只能比右半边多1个元素 // 如果左半边比右半边多了2个以上,就把左半边的最大值移到右半边 if (leftMaxHeap.size() > rightMinHeap.size() + 1) { rightMinHeap.offer(leftMaxHeap.poll()); } } // 情况2:num 大于左半边的最大值 // 说明 num 应该放在右半边(较大的一半) else { rightMinHeap.offer(num); // 平衡:右半边的大小不能超过左半边 // 如果右半边比左半边还大,就把右半边的最小值移到左半边 if (rightMinHeap.size() > leftMaxHeap.size()) { leftMaxHeap.offer(rightMinHeap.poll()); } } } public double findMedian() { // 如果左半边多一个元素(总数为奇数),中位数就是左半边的最大值 if (leftMaxHeap.size() > rightMinHeap.size()) { return leftMaxHeap.peek(); } // 如果两边数量相等(总数为偶数),中位数是(左最大 + 右最小)/ 2 return (leftMaxHeap.peek() + rightMinHeap.peek()) / 2.0; } }

柱状图中最大的矩形

要点:栈,哨兵,高度*宽度

import java.util.*; class Solution { public int largestRectangleArea(int[] heights) { if (heights == null || heights.length == 0) { return 0; } int n = heights.length; // 创建一个新数组,在原数组前后各添加一个0,方便处理边界 int[] newHeights = new int[n + 2]; for (int i = 0; i < n; i++) { newHeights[i + 1] = heights[i]; } // 前后哨兵为0 newHeights[0] = 0; newHeights[n + 1] = 0; Stack<Integer> stack = new Stack<>(); int maxArea = 0; for (int i = 0; i < newHeights.length; i++) { // 当当前柱子高度小于栈顶柱子高度时 while (!stack.isEmpty() && newHeights[i] < newHeights[stack.peek()]) { // 弹出栈顶柱子 int height = newHeights[stack.pop()]; // 计算宽度:右边界i,左边界是新的栈顶元素 int left = stack.isEmpty() ? -1 : stack.peek(); int width = i - left - 1; maxArea = Math.max(maxArea, height * width); } // 将当前索引入栈 stack.push(i); } return maxArea; } }

寻找两个正序数组的中位数

要点:最笨的方法

class Solution { public double findMedianSortedArrays(int[] a, int[] b) { int m = a.length; int n = b.length; int[] merged = new int[m + n]; System.arraycopy(a, 0, merged, 0, m); System.arraycopy(b, 0, merged, m, n); Arrays.sort(merged); int s = m + n; int k = (s - 1) / 2; return s % 2 > 0 ? merged[k] : (merged[k] + merged[k + 1]) / 2.0; } }

随机知识

二、分布式系统理论(概念级,加分项)

核心题:什么是 CAP 定理?BASE 理论是什么?分布式事务了解吗?

面试官为什么这么问:现在很少有系统真单机,实习生至少要知道 CAP 和 BASE,证明你有分布式意识。

希望听到的回答

  • CAP
    • C(一致性):所有节点同一时间看到同一数据
    • A(可用性):每个请求都能得到非错误的响应
    • P(分区容错性):网络分区时系统仍能工作
    • 分布式系统只能同时满足两个,P 是必须的,所以要么 CP(ZooKeeper)要么 AP(Eureka)
  • BASE
    • Basically Available(基本可用)
    • Soft state(软状态)
    • Eventually consistent(最终一致性)
    • 是和 ACID 的对照,用于 NoSQL 和分布式缓存场景
  • 分布式事务概念:2PC、TCC、本地消息表、RocketMQ 事务消息,知道名字和大概思路就行,不要求细节。

结合项目说的话:“我们用 RabbitMQ 做异步处理,保证投递可靠,就是基于 BASE 思想实现最终一致性,不强求强一致。”

候选人:
好的。这三个概念是分布式系统的基石,CAP是理论约束,BASE是工程妥协,分布式事务是具体实践。我从CAP讲起,再说明BASE如何放宽约束,最后介绍几种常见的分布式事务方案。

第一,CAP定理——分布式系统的“不可能三角”。

CAP定理告诉我们:一个分布式系统最多只能同时满足以下三个特性中的两个。

C是一致性。所有节点在同一时刻看到的数据完全相同。客户端向节点A写入数据后,立即去节点B读取,节点B必须返回最新写入的值。对于客户端来说,系统表现得就像只有一个节点一样,这是最理想但也最难实现的状态。

A是可用性。每个请求都能得到非错误的响应,但不保证返回的数据是最新的。系统可能返回旧数据,但必须响应。

P是分区容错性。当网络发生分区时,也就是部分节点之间无法通信,系统仍然能继续工作。网络分区在分布式系统中是不可避免的,交换机故障、光缆被挖断、网络抖动都可能导致分区。所以P是分布式系统的“生存底线”,任何跨网络的节点通信都必须考虑P。

为什么只能三选二?

关键是:当网络分区发生时,系统必须在C和A之间做选择。

假设系统有节点A和节点B,它们之间网络断了。客户端向A发送写请求。如果系统选择保证一致性,A必须拒绝这次写入,因为它无法把数据同步给B,于是牺牲了可用性——这就是CP系统

如果系统选择保证可用性,A接受写入并返回成功,但B此时无法同步到新数据。客户端访问A看到新数据,访问B看到旧数据,两个节点不一致——这就是AP系统

没有网络分区的时候,系统可以同时满足C和A。一旦分区发生,就必须在两者之间取舍。

典型产品的选择

ZooKeeper是典型的CP系统。当Leader节点故障时,集群会暂停服务进行重新选举,期间拒绝所有请求,保证数据一致性。这适合配置管理、分布式锁这类对一致性要求严格的场景。

Eureka是典型的AP系统。服务之间有过期检查,但网络分区时优先保证服务可用,允许各节点数据短暂不一致,适合服务注册发现的场景,宁可让调用方拿到可能过期的服务列表,也不能停止服务。

Redis本身设计偏向AP。主从复制是异步的,主节点故障切换时可能有短暂的数据丢失窗口。Redis Cluster也是去中心化设计,优先保证分片可用,不保证多节点间强一致性。

第二,BASE理论——对CAP的工程妥协。

CAP定理要求我们在C和A之间做选择,但现实业务往往不需要绝对的强一致性。BASE理论就是针对AP系统的一种实践指导,它是对ACID(原子性、一致性、隔离性、持久性)严格事务模型的放松。

BA是基本可用。系统出现故障时允许损失部分可用性,但核心功能仍可用。比如双十一高峰时,阿里会关闭退款、账单明细等非核心功能,保证下单和支付链路正常。用户虽然不能查去年的订单,但能完成购买。

S是软状态。允许系统中的数据存在中间状态,不要求所有节点数据时刻一致。比如订单支付成功后,订单状态从“待支付”变成“支付成功”,但积分系统可能还没有加上积分。这个中间状态窗口可以接受。

E是最终一致性。不强求实时一致,但保证经过一段时间后,所有副本最终达到一致状态。比如用户用积分兑换了优惠券,几分钟后积分才被冻结,最终结果正确就行。

BASE和ACID不是对立关系,而是不同场景的选择。金融转账、账户余额必须是ACID强一致;社交帖子、点赞数、商品库存展示这些场景,BASE的最终一致性完全可接受。CAP告诉我们“没有完美的分布式系统”,BASE则回答了“在不完美的系统中,如何让业务还能正常运转”。

第三,分布式事务——如何跨服务保证最终一致性。

单体应用用数据库自带的事务保证ACID。微服务架构下,一笔业务跨越多个服务实例和多个数据库,就需要分布式事务方案。我对以下几种方案各有理解:

2PC两阶段提交。协调者先问所有参与者“能提交吗”(准备阶段),所有参与者都回复可以,再通知“正式提交”(提交阶段)。问题是协调者单点故障、参与者同步阻塞时间长、性能最差。XA协议是2PC的标准实现,但生产环境很少用在核心链路上。

TCC补偿事务。把操作拆成Try(预留资源)、Confirm(确认执行)、Cancel(取消回滚)三个阶段。每个参与方都要提供对业务的三段接口。比2PC灵活,但代码侵入性强,每个业务接口都要按TCC规范设计,开发成本高。

本地消息表。服务的本地事务里同时写业务数据和消息表,用定时任务扫描未发送消息投递到MQ,消费方处理并回调确认。完全依赖本地事务保证原子性,不要求跨服务的实时协调,但需要消费方接口做成幂等。比较适合单体拆分或简单链路。

RocketMQ事务消息。生产者先向MQ发一条半消息,然后执行本地事务。本地事务成功则提交半消息,失败则回滚半消息。MQ会定期反查生产者的本地事务状态来确认未知状态的消息。这是最佳生产实践,不需要消费者额外开发确认接口,RocketMQ自身承担事务反查的职责。

项目中的实际选择

我的项目用RabbitMQ实现最终一致性。核心链路是先写数据库确认业务成功,然后发消息到MQ。消费方从队列取出消息处理。需要考虑两种异常:发消息失败时,把待发送记录写入重试表,定时任务扫描补偿;消费处理失败时,重试几次仍失败转死信队列,人工介入处理。同时消费者做好幂等,用唯一业务键加数据库唯一索引来防止重复处理。

这就是典型的BASE思想实践——不强求跨服务的实时强一致,但通过消息重试、死信兜底、幂等设计保证最终数据对齐。

总结:CAP告诉我们分布式系统必须在一致性和可用性之间做取舍,P是必须满足的底线。BASE告诉我们大多数互联网业务可以接受最终一致性,用软状态换可用性和性能。分布式事务方案从强一致的2PC到弱一致的本地消息表再到事务消息,选择什么方案取决于业务对一致性的要求和对复杂性的容忍度。基本规律是:大部分场景用MQ加幂等实现最终一致性就够了,只有极少数的资金交易才需要强一致性的分布式事务框架介入。

碎碎念:后续会更新每天学习的八股和算法 题,开始准备秋招的第14天。努力连续更新100天!以后每天就按,秋招项目【java+agent】,科研,必做项目,算法,八股,锻炼身体来总结。今天又是啥也没干的一天,一放假就啥也不想干,项目还出了好多问题,唉。

总结:不要放弃呀,

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

2.秋招项目【java可能ok?】【agent继续加油】,这周一定要搞完背面试八股了

3.科研要跑一下

4.必搞项目也得总结文档

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

6.背八股

7.锻炼身体

【最后最后,请相信自己可以的!!!!!】
————————————————

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

相关文章:

  • 神经网络与深度学习课程总结二
  • 基于CNN的食双星参数快速预测:ebop_maven模型原理与应用
  • 基于伊辛机与机器学习的无线网络TDMA调度优化实践
  • Java 入门实验:手把手实现 Tank 坦克类(面向对象基础实战)
  • 中医馆升级|结合瑞式养老模式的医养结合完整落地方案
  • ArchPilot:基于多智能体与代理评估的高效神经网络架构搜索框架
  • 因果增强XGBoost框架:破解北极降水预测难题
  • RL-ARM CAN迁移至CMSIS-RTOS的实践指南
  • 机器学习记忆化:平衡隐私、鲁棒性与公平性的核心技术挑战
  • 3步解锁游戏语言障碍:XUnity自动翻译工具完全指南
  • 苏州石膏板难题终结者:苏州聚亿鑫装饰的全方位解决方案,全屋定制/石膏板/欧松板/家装设计/生态板,石膏板公司哪个好 - 品牌推荐师
  • 华硕笔记本终极优化指南:如何用G-Helper轻量级工具全面提升使用体验
  • 差分隐私公平性:基于群体自适应裁剪的DP-SGD改进算法
  • Python 3 模块详解
  • Burp Suite Professional实战卡点解析:HTTPS抓包、代理拦截与Intruder失效根因
  • 《道德经》第二十章
  • sudo高危漏洞CVE-2023-27350原理与1.9.5p2修复实战
  • 机器学习发现物理守恒量:从数据中挖掘对称性与不变性
  • 基于Transformer的行星大气辐射传输仿真器:百倍加速与1%精度
  • AssetRipper深度解析:Unity资源静态解析原理与工程化实践
  • 如何突破百度网盘限速:终极免费解析工具使用指南
  • JMeter分布式测试:突破单机性能瓶颈的实战指南
  • 如何快速掌握BepInEx插件框架:新手的完整避坑指南
  • Charles断点调试:HTTP/HTTPS流量精准控制与实战避坑
  • 5分钟上手:用LeaguePrank打造专属英雄联盟客户端
  • Linux服务器报错libgcc_s.so.1找不到?别慌,这份应急恢复指南帮你搞定
  • 告别‘找茬’游戏:用Python复现ALCNet,让红外小目标检测又快又准
  • Unity Library文件夹不是缓存,而是项目运行时核心枢纽
  • 5分钟解放双手!碧蓝航线智能助手Alas终极使用指南
  • Wi-Fi链路质量预测:基于EMA组合的轻量级模型原理与工程实践