一、力扣
1、01背包-一和零
【题单】动态规划(入门/背包/状态机/划分/区间/状压/数位/树形/数据结构优化)
背包视频:0-1背包 完全背包【基础算法精讲 18】_哔哩哔哩_bilibili


java
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
int s = strs.length;
int[] count = new int[s];
for (int i = 0; i < s; i++) {
String temp = strs[i];
for (char e : temp.toCharArray()) {
if (e == '0') count[i]++;
}
}
int[][][] dp = new int[m + 1][n + 1][s + 1];
for (int i = 0; i < s; i++) {
int num0 = count[i];
int num1 = strs[i].length() - num0;
for (int j = 0; j <= m; j++) {
for (int k = 0; k <= n; k++) {
// 初始化为不选当前字符串的情况
dp[j][k][i + 1] = dp[j][k][i];
if (j >= num0 && k >= num1) {
// 选择当前字符串,取较大值
dp[j][k][i + 1] = Math.max(dp[j][k][i + 1], dp[j - num0][k - num1][i] + 1);
}
}
}
}
return dp[m][n][s];
}
}
2、完全背包-零钱兑换


java
class Solution {
public int coinChange(int[] coins, int amount) {
int n = coins.length;
int[][] f = new int[n + 1][amount + 1];
Arrays.fill(f[0], Integer.MAX_VALUE / 2); // 除 2 防止下面 + 1 溢出
f[0][0] = 0;
for (int i = 0; i < n; i++) {
for (int c = 0; c <= amount; c++) {
if (c < coins[i]) {
f[i + 1][c] = f[i][c];
} else {
f[i + 1][c] = Math.min(f[i][c], f[i + 1][c - coins[i]] + 1);
}
}
}
int ans = f[n][amount];
return ans < Integer.MAX_VALUE / 2 ? ans : -1;
}
}
3、完全背包-零钱兑换 II

java
class Solution {
public int change(int amount, int[] coins) {
int n = coins.length;
int[][] f = new int[n + 1][amount + 1];
f[0][0] = 1;
for (int i = 0; i < n; i++) {
for (int c = 0; c <= amount; c++) {
if (c < coins[i]) {
f[i + 1][c] = f[i][c];
} else {
f[i + 1][c] = f[i][c] + f[i + 1][c - coins[i]];
}
}
}
return f[n][amount];
}
}
4、最长公共子序列

java
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int m=text1.length(),n=text2.length();
int[][] dp=new int[m+1][n+1];
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(text1.charAt(i)==text2.charAt(j)){
dp[i+1][j+1]=dp[i][j]+1;
}else{
dp[i+1][j+1]=Math.max(dp[i][j+1],dp[i+1][j]);
}
}
}
return dp[m][n];
}
}
5、复原 IP 地址

java
class Solution {
List<String> res;
List<String> path;
String s;
public List<String> restoreIpAddresses(String s) {
res = new ArrayList<>();
path = new ArrayList<>();
this.s = s;
dfs(0);
return res;
}
public void dfs(int start) {
if (start > s.length())
return;
if (start == s.length() && path.size() == 4) {
StringBuilder temp = new StringBuilder();
for (int i = 0; i < path.size(); i++) {
temp.append(path.get(i));
if (i != path.size() - 1)
temp.append(".");
}
res.add(temp.toString());
}
for (int i = start; i < s.length(); i++) {
String temp = s.substring(start, i + 1);
if (check(temp) >= 0 && path.size() < 4) {
path.add(temp);
dfs(i + 1);
path.removeLast();
}
}
}
public int check(String ans) {
if (ans.length() > 1 && ans.charAt(0) == '0')
return -1;
int sum = 0;
for (int i = 0; i < ans.length(); i++) {
sum = sum * 10 + ans.charAt(i) - '0';
}
if (sum > 255)
return -1;
return sum;
}
}
6、删除排序链表中的重复元素 II

java
/**
* 删除链表中所有重复出现的元素,使每个元素只出现一次。
* 例如,给定链表 1->2->3->3->4,返回 1->2->4。
* 若链表为 1->1->1->2->3,返回 2->3。
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
// 创建虚拟头节点,简化删除头节点的逻辑
ListNode dummy = new ListNode(0);
dummy.next = head;
// pre 指针指向当前最后一个不重复的节点
ListNode pre = dummy;
// 外层循环:遍历链表,pre 总是指向已处理部分的末尾
while (pre.next != null && pre.next.next != null) {
int temp = pre.next.val; // 当前节点的值
// 检查是否存在重复:当前节点的下一个节点与下下个节点值相同
if (pre.next.next.val == temp) {
// 内层循环:跳过所有值等于 temp 的节点
while (pre.next != null && pre.next.val == temp) {
pre.next = pre.next.next; // 删除重复节点
}
} else {
// 无重复时,pre 前移到下一个节点
pre = pre.next;
}
}
return dummy.next;
}
}
7、寻找两个正序数组的中位数

java
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int tot = nums1.length + nums2.length; // 总元素个数
// 判断总数是偶数还是奇数
if (tot % 2 == 0) {
// 偶数情况:取中间两个数的平均值
int left = find(nums1, 0, nums2, 0, tot / 2); // 第tot/2小的元素
int right = find(nums1, 0, nums2, 0, tot / 2 + 1);// 第tot/2+1小的元素
return (left + right) / 2.0; // 返回平均值
} else {
// 奇数情况:直接取中间数
return find(nums1, 0, nums2, 0, tot / 2 + 1);
}
}
// 辅助递归方法:在两个数组中寻找第k小的元素(k从1开始计数)
int find(int[] n1, int i, int[] n2, int j, int k) {
// 确保n1是较短的数组,优化递归效率
if (n1.length - i > n2.length - j)
return find(n2, j, n1, i, k);
// 边界情况1:n1已遍历完,直接返回n2的第k小元素
if (i >= n1.length)
return n2[j + k - 1];
// 边界情况2:k=1时,返回两数组当前起始位置的最小值
if (k == 1)
return Math.min(n1[i], n2[j]);
// 正常情况:二分查找法缩小范围
// 计算两数组的中间位置(向下取整)
int si = Math.min(i + (k / 2), n1.length); // n1的参考切割点
int sj = j + k - (k / 2); // n2的参考切割点
// 比较两数组切割点前一个元素的值,排除较小部分
if (n1[si - 1] > n2[sj - 1]) {
// 排除n2的前(sj-j)个元素,继续在剩余部分找第(k - (sj-j))小的元素
return find(n1, i, n2, sj, k - (sj - j));
} else {
// 排除n1的前(si-i)个元素,继续在剩余部分找第(k - (si-i))小的元素
return find(n1, si, n2, j, k - (si - i));
}
}
}
8、二叉树的所有路径

java
class Solution {
List<String> res;
List<Integer> path;
public List<String> binaryTreePaths(TreeNode root) {
res=new ArrayList<>();
path=new ArrayList<>();
dfs(root);
return res;
}
public void dfs(TreeNode root){
if(root==null) return ;
path.add(root.val);
if(root.left==root.right){
StringBuilder ans=new StringBuilder();
for(int i=0;i<path.size();i++){
ans.append(path.get(i).toString());
if(i!=path.size()-1){
ans.append("->");
}
}
res.add(ans.toString());
}
dfs(root.left);
dfs(root.right);
path.removeLast();
}
}
二、语雀-场景题
1、秒杀场景下,怎么加库存?


2、5 分钟内最多允许用户尝试登录 3 次,如果错误次数超过限制,需要对该用户进行锁定。如何实现?
✅5 分钟内最多允许用户尝试登录 3 次,如果错误次数超过限制,需要对该用户进行锁定。如何实现?


3、两个不相关的网站A和B,如何实现A登录B也能自动登录
1. 基于token

2. 基于Session


4、MQ出现消息乱序了如何解决?

1. 顺序消息

2. 自己实现排序

5、MySQL千万级数据量,查询如何做优化?
1. 索引优化

2. 使用缓存

3. 数据归档

6、什么是数据归档,一般是怎么做的?


7、Redis、MySQL和MongoDB的区别是什么,各自适用场景呢?
✅Redis、MySQL和MongoDB的区别是什么,各自适用场景呢?


8、Redis实现分布式锁,加锁的时候,redis不可用了咋整?
✅Redis实现分布式锁,加锁的时候,redis不可用了咋整?

9、防止接口被恶意刷流量,除了限流还应在代码层面做哪些防护?

10、库存扣减、创建订单,如何拆成TCC?



11、Redis保存库存的时候,如何避免被Redis清理掉?
1. volatile

12、如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?
✅如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?


13、如何从 1TB 的搜索日志中找出搜索量最高的 10 个关键词
✅如何从 1TB 的搜索日志中找出搜索量最高的 10 个关键词?


14、用@Scheduled执行定时任务,如何避免集群的并发问题
✅用@Scheduled执行定时任务,如何避免集群的并发问题


15、下单支付过程,点击跳转支付,输入密码,支付完成后跳转到订单页,整个过程可能会有什么问题?架构方面做哪些设计?
✅下单支付过程,点击跳转支付,输入密码,支付完成后跳转到订单页,整个过程可能会有什么问题?架构方面做哪些设计?
1. 问题1:支付跳转失败

2. 问题2:支付状态未同步

3. 问题3:用户重复支付

4. 用户不支付,卡在支付中

16、有一张上百万条数据的单表,从前端页面、Java后台、数据库三个层面做查询优化
✅有一张上百万条数据的单表,从前端页面、Java后台、数据库三个层面做查询优化
1. 前端

2. Java代码

3. 数据库优化

17、假设还有很多内存,有什么情况还会频繁fullgc?


18、5亿条数据放到布隆过滤器中,大概需要多大内存?如何估算?

