feat(interview): 添加面试题和解决方案

- 新增ByteDance类,包含三道面试题的解决方案。
- 在meituan810类中添加了解决方案和相关代码。
- 重构并优化了RateLimitingRequestSplitter类的代码。

fix(threadpool): 修正CvmResetHandler中线程池参数顺序

重新排列CvmResetHandler中线程池执行器的参数,以确保正确分配任务并防止在任务完成前服务中断。

refactor(code): 移除无用的变量和代码段

在多个类中清理无用的变量和未使用的代码段,以提高代码的可读性和维护性。
This commit is contained in:
whaifree 2024-08-19 00:50:26 +08:00
parent 30db149f1a
commit f5ac4f8829
7 changed files with 980 additions and 0 deletions

View File

@ -0,0 +1,224 @@
package cn.whaifree.interview.qiuzhao;
import java.util.HashMap;
import java.util.Scanner;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/18 18:55
* @注释
*/
public class ByteDance {
}
class ByteDancep1{
/**
* 字数组
* 4111 411 就是满足要求的
* 字数组特殊数组个数
* @param args
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int i = in.nextInt();
int[] nums = new int[i];
for (int j = 0; j < i; j++) {
nums[j] = in.nextInt();
}
nums = new int[]{2,2,3,2};
method(nums);
}
public static void method(int[] nums) {
int count = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = i + 2; j < nums.length; j++) {
count += display(nums, i, j);
}
}
System.out.println(count);
}
public static int display(int[] nums, int start, int end) {
if (end - start < 2) {
return 0;
}
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = start; i <= end; i++) {
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
if (map.keySet().size() >= 3) {
return 0;
}
}
return 1;
}
}
class ByteDance2{
/**
* n个事件最大钻石数量m 1 <= n,m<= 1000
*
* 每个事件有 xyz
* 有俩个选择
* 1 消耗 x钻石 获得 y金币
* 2 获得 z钻石
*
* 钻石数量超出m的部分会消失最多拥有m个钻石
*
* 事件结束后可以将钻石1比1换成金币
*
* 问最多能得到多少金币
*
* 作者Jovanko
* 链接https://www.nowcoder.com/feed/main/detail/e7e32ba86ff44c0aa40443c007991474?sourceSSR=search
* 来源牛客网
*
* 多重背包
* @param args
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int thing = in.nextInt();
int limit = in.nextInt();
int[][] events = new int[thing][3];
for (int i = 0; i < thing; i++) {
events[i][0] = in.nextInt();
events[i][1] = in.nextInt();
events[i][2] = in.nextInt();}
in.close();
int[][] dp = new int[thing + 1][limit + 1];
for (int i = 1; i <= thing; i++) {
int[] event = events[i - 1];
int x = event[0]; // 消耗x
int y = event[1]; // 获得y个金币
int z = event[2]; // 直接获取z个宝石
for (int j = 0; j <= limit; j++) {
dp[i][j] = dp[i - 1][j];
// 消耗宝石
if (j >= x) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - x] + y);
}
// 换宝石
if (j + z <= limit) {
dp[i][j + z] = Math.max(dp[i][j + z], dp[i - 1][j]);
}
}
}
int maxCoin = 0;
for (int i = 0; i <= limit; i++) {
maxCoin = Math.max(maxCoin, dp[thing][i]);
}
}
}
class ByteDancep3{
static int left = 0;
static int right = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int len = in.nextInt();
int num = in.nextInt();
int sum = 0;
int[] nums = new int[len];
for (int i = 0; i < len; i++) {
nums[i] = in.nextInt();
sum += nums[i];
}
right = nums.length - 1;
for (int i = 0; i < num; i++) {
String opr = in.next();
Integer oprLen = Integer.valueOf(in.next());
int value = 0;
if (oprLen > num) {
value += sum * (oprLen / len);
oprLen %= len;
}
if (opr.equals("L")) {
for (int j = 0; j < oprLen; j++) {
value += nums[left % len];
left++;
}
}else {
for (int j = 0; j < oprLen; j++) {
if (right < 0) {
right = right + len;
}
value += nums[right];
right--;
}
}
System.out.println(value);
}
}
public static int cut(int[] nums, String opr, int len) {
int res = 0;
if (opr.equals("L")) {
res += calLeft(nums, left, len);
left += len;
while (left > nums.length) {
left %= nums.length;
}
}else {
res += calRight(nums, right, len);
right -= len;
while (right < 0) {
right += nums.length;
}
}
System.out.println(res);
return res;
}
public static int calRight(int[] nums, int end, int count) {
int res = 0;
while (count > 0) {
res += nums[end];
end--;
count--;
if (end < 0) {
end += nums.length;
}
}
return res;
}
public static int calLeft(int[] nums, int start, int count) {
int res = 0;
while (count >= 0) {
res += nums[start];
start++;
count--;
if (start > nums.length) {
start -= nums.length;
}
}
return res;
}
}

View File

@ -0,0 +1,252 @@
package cn.whaifree.interview.qiuzhao;
import java.util.*;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/18 15:21
* @注释
*/
public class meituan810 {
}
// 注意类名必须为 Main, 不要有任何 package xxx 信息
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext hasNextLine 的区别
StringBuilder sb = new StringBuilder();
int t = in.nextInt();
for (int i = 0; i < t; i++) {
int n = in.nextInt();
long k = in.nextInt();
long x = in.nextInt();
// System.out.println("n:"+n+", k:"+k+", x:"+x);
HashSet<Integer> set = new HashSet<>();
int[] as = new int[n];
for (int j = 0; j < n; j++) {
as[j] = in.nextInt();
}
long min = x * n;
int cur = 0;
for (int j = n - 1; j >= 0; j--) {
set.add(as[j]);
while (set.contains(cur)) {
cur++;
}
min = Math.min(x * j + k * cur, min);
// System.out.println(set);
// System.out.println("min:"+min+", cur:"+cur);
}
sb.append(min);
sb.append("\n");
}
System.out.println(sb.toString());
}
}
/*作者逆风_前行
链接https://www.nowcoder.com/exam/test/82357235/submission?examPageSource=Company&pid=58084216&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fcompany%3FcurrentTab%3Drecommand%26jobId%3D100%26selectStatus%3D0%26tagIds%3D179&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源牛客网*/
class p3{
//小美有一个长度他可以对数组进行如下操作删除第一个元素a同时数组的长度减一花费为x
// 删除整个数组花费为k×MEX(a)其中MEX(a)表示a 中未出现过的最小非负整数例如[0,1,2,4][0,1,2,4] 的MEX为3
// 小美想知道将a数组全部清空的最小代价是多少请你帮帮他吧
static int allDelete;
static int oneDelete;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int numsCount = in.nextInt();
String[] split = in.next().split(" ");
int count = Integer.parseInt(split[0]);
allDelete = Integer.parseInt(split[1]);
oneDelete = Integer.parseInt(split[2]);
for (int i = 0; i < numsCount; i++) {
split = in.next().split(" ");
int[] ints = new int[split.length];
for (String s : split) {
ints[i] = Integer.parseInt(s);
}
}
}
/**
* 4 5 2 3 1 0
*
* 都删除
* 删除第一个
* @param ints
*/
public static void compute(int[] ints) {
int max = Arrays.stream(ints).max().getAsInt();
boolean[] booleans = new boolean[max]; // 表示是否出现
for (int i = 0; i < ints.length; i++) {
booleans[ints[i]] = true;
}
int[][] dp = new int[2][ints.length];
/**
* dp[0] 为删除第一个元素的最小代驾
* dp[1] 为全部删除的最小代驾
*/
for (int i = 0; i < booleans.length; i++) {
// 如果删除第一个元素
dp[0][i] = oneDelete;
}
}
}
class ArrayCostCalculator {
public static void main(String[] args) {
// 4 5 2 3 1 0
int[] array = {4, 5, 2, 3, 1, 0};
int x = 3; // 删除第一个元素的代价
int k = 3; // 删除整个数组的代价的系数
int result = findMinimumCost(array, x, k);
System.out.println("The minimum cost to clear the array is: " + result);
}
public static int findMinimumCost(int[] array, int x, int k) {
int n = array.length; // 数组长度
int mex = findMEX(array); // 计算MEX
int costIndividualDelete = n * x; // 逐个删除的代价
int costDeleteAll = k * mex; // 删除整个数组的代价
return Math.min(costIndividualDelete, costDeleteAll); // 返回较小的代价
}
private static int findMEX(int[] array) {
int maxElement = getMaxElement(array); // 数组中的最大元素
boolean[] 出现过 = new boolean[maxElement + 1]; // 用于跟踪数字是否出现过
// 标记数组中的每个元素
for (int num : array) {
出现过[num] = true;
}
// 找到MEX
for (int i = 0; i <= maxElement; i++) {
if (!出现过[i]) {
return i; // 未出现的最小非负整数
}
}
return maxElement + 1; // 如果数组包含所有数字则MEX是最大元素加1
}
private static int getMaxElement(int[] array) {
int max = array[0];
for (int num : array) {
if (num > max) {
max = num;
}
}
return max;
}
}
class p2{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
String right = in.next();
TreeMap<Integer, Set<String>> map = new TreeMap<>();
// map key为长度value为数量
for (int i = 0; i < num; i++) {
String next = in.next();
int length = next.length();
if (!map.containsKey(length)) {
map.put(length, new HashSet<>());
}
map.get(length).add(next);
}
ArrayList<Integer> keys = new ArrayList<>();
for (Integer i : map.keySet()) {
if (i < right.length()) {
keys.add(i);
}
}
// List<Integer> list = map.keySet().stream().filter(new Predicate<Integer>() {
// @Override
// public boolean test(Integer integer) {
// return integer < right.length();
// }
// }).toList();
int pre = 0;
for (Integer i : keys) {
pre += map.get(i).size();
}
System.out.println(pre + 1 + " " + (pre + map.get(right.length()).size()));
}
}
class p1{
public static void main(String[] args) {
System.out.println((int) 'z');
System.out.println((int) 'A');
Scanner in = new Scanner(System.in);
// 注意 hasNext hasNextLine 的区别
int num = in.nextInt();
for (int i = 0; i < num; i++) {
String next = in.next();
judge(next);
}
}
public static void judge(String s) {
char c = s.charAt(0);
if (isEn(c)) {
// 字母开头
boolean hasNum = false;
boolean hasEn = false;
for (int i = 1; i < s.length(); i++) {
boolean en = isEn(s.charAt(i));
boolean num = isNum(s.charAt(i));
if (!en && !num) {
System.out.println("invalid");
return;
}
hasEn = hasEn || en;
hasNum = num || hasNum;
}
if (hasNum && !hasEn) {
System.out.println("standard");
return;
} else if (!hasNum && hasEn) {
System.out.println("invalid");
return;
}
System.out.println("mix");
} else if (isNum(c)) {
// 数字开头
for (int i = 1; i < s.length(); i++) {
if (!isEn(s.charAt(i))) {
System.out.println("invalid");
return;
}
}
System.out.println("special");
}else {
System.out.println("invalid");
}
}
public static boolean isNum(char c) {
return c <= '9' && c >= '0';
}
public static boolean isEn(char c) {
return c >= 'A' && c <= 'z';
}
}

View File

@ -0,0 +1,72 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/17 22:32
* @注释
*/
public class LCR001 {
public static void main(String[] args) {
}
@Test
public void test() {
System.out.println(new Solution().divide(-2147483648, -1));
}
class Solution {
/**
* b<<1
*
* 让被除数不断翻倍去近似接近
*
* 17/3
* 3<<1 6<<1 12<<1 (17-12=5)
* 5/3
*
* @param a
* @param b
* @return
*/
public int divide(int a, int b) {
// 特殊情况2, b=-1
if (b == -1) {
return a == Integer.MIN_VALUE ? Integer.MAX_VALUE : -a;
}
long A = a;
long B = b;
// 确定符号
boolean positive = (A ^ B) >= 0;
// 为避免溢出, 转换为负数进行计算 -2^31 <= a, b <= 2^31 - 1
A = A < 0 ? -A : A;
B = B < 0 ? -B : B;
long tmpA = A;
long tmpB = B;
long mulSum = 0;
while (tmpA >= B) {
long mul = 1;
tmpB = B;
while (tmpB << 1 < tmpA) {
tmpB <<= 1;
mul <<= 1;
}
mulSum += mul;
tmpA -= tmpB;
}
return (int) (positive ? mulSum : -mulSum);
}
}
}

View File

@ -0,0 +1,118 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/17 21:33
* @注释
*/
public class LeetCode416 {
@Test
public void test()
{
int[] nums = {1,5,11,5};
System.out.println(canPartition(nums));
}
/**
*
* 背包容量 sum/2 11
* 物品 nums
*
* dp[i][j]表示从0-i中任意取放入容量为j的背包的最大价值
*
*
* dp
* 0 1 2 3 4 5 6 7 8 9 10 11
* 0 0 1 1 1 1 1 1 1 1 1 1 1
* 1 0 1 1 1 1 5 6 6 6 6 6 6
* 2 0 1 1 1 1 5 6 6 6 6 6 11
* 3 0 1 1 1 1 5 6 6 6 6 10 11
*
*
* if 能放进去
* 不放物品i的最大价值 dp[i-1][j]
* 放物品i的最大价值 dp[i-1][j-weight[i]] + value[i]
* else
* dp[i-1][j]
*
* @param nums
* @return
*/
public boolean canPartition(int[] nums)
{
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2 == 1) {
return false;
}
int half = sum / 2;
int[][] dp = new int[nums.length][half + 1];
for (int i = nums[0]; i <= half; i++) {
dp[0][i] = nums[0];
}
for (int i = 1; i < nums.length; i++) {
for (int j = 1; j <= half; j++) {
if (j < nums[i]) {
dp[i][j] = dp[i - 1][j];
}else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i]);
/**
* 不放 dp[i-1][j]
* 放i,在i-1中获取大价值基础上加 dp[i - 1][j - nums[i]] + nums[i]
*/
}
if (dp[i][j] == half) {
return true;
}
}
}
return false;
}
public boolean canPartition1(int[] nums)
{
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2 == 1) {
return false;
}
int half = sum / 2;
int[] dp = new int[half + 1];
for (int i = nums[0]; i <= half; i++) {
dp[i] = nums[0];
}
for (int i = 1; i < nums.length; i++) {
for (int j = half; j >= nums[i]; j--) {
/**
* https://www.programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-2.html#%E6%80%9D%E8%B7%AF
* 如果正序遍历
* dp[1] = dp[1 - weight[0]] + value[0] = 15
* dp[2] = dp[2 - weight[0]] + value[0] = 30
* 此时dp[2]就已经是30了意味着物品0被放入了两次所以不能正序遍历
*/
dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
if (dp[j] == half) {
return true;
}
}
}
return false;
}
}

View File

@ -0,0 +1,135 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/18 9:38
* @注释
*/
public class LeetCode5 {
@Test
public void test() {
System.out.println(new Solution1().longestPalindrome("cbbd"));
}
class Solution {
/**
* dp[i][j] 表示i-j是否是回文
*
* b a b a d
*
* 0 1 2 3 4
* 0 1 0 1
* 1 1 0
* 2 1
* 3 1
* 4 1
*
* if s[i]==s[j] && dp[i+1][j-1]
*
* @param s
* @return
*/
public String longestPalindrome(String s) {
char[] charArray = s.toCharArray();
int length = s.length();
boolean[][] dp = new boolean[length][length];
for (int i = 0; i < length; i++) {
dp[i][i] = true;
}
int first = 0;
int last = 0;
for (int i = length - 1; i >= 0; i--) {
for (int j = i + 1; j < length; j++) {
if (charArray[i] == charArray[j] && (dp[i + 1][j - 1] || j == i + 1)) {
dp[i][j] = true;
if (j - i > last - first) {
first = i;
last = j;
}
}
}
}
return s.substring(first, last + 1);
}
}
class Solution1{
public String longestPalindrome(String s) {
String maxLength = "";
for (int i = 0; i < s.length(); i++) {
String s1 = maxLengthHuiWen(s, i, i + 1);
String s2 = maxLengthHuiWen(s, i, i);
if (s1.length() > maxLength.length()) {
maxLength = s1;
}
if (s2.length() > maxLength.length()) {
maxLength = s2;
}
}
return maxLength;
}
/**
* 向外扩散的两个指针
*
* @param s
* @param start
* @param end
* @return
*/
public String maxLengthHuiWen(String s, int start, int end) {
int length = s.length();
while (start >= 0 && end < length) {
if (s.charAt(start) != s.charAt(end)) {
break;
}
start--;
end++;
}
return s.substring(start + 1, end);
}
}
}
class LeetCode647 {
public static void main(String[] args) {
System.out.println(new Solution().countSubstrings("aaa"));
}
static class Solution {
public int countSubstrings(String s) {
char[] charArray = s.toCharArray();
boolean[][] dp = new boolean[s.length()][s.length()];
for (int i = 0; i < s.length(); i++) {
dp[i][i] = true;
}
for (int i = s.length() - 1; i >= 0; i--) {
for (int j = i + 1; j < s.length(); j++) {
if (charArray[i] == charArray[j] && (j == 1 + i || dp[i + 1][j - 1])) {
dp[i][j] = true;
}
}
}
int count = 0;
for (boolean[] booleans : dp) {
for (boolean aBoolean : booleans) {
if (aBoolean) {
count++;
}
}
}
return count;
}
}
}

View File

@ -0,0 +1,58 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/18 23:36
* @注释
*/
public class LeetCode713 {
@Test
public void test(){
// 10,9,10,4,3,8,3,3,6,2,10,10,9,3
int[] nums = {10,9,10,4,3,8,3,3,6,2,10,10,9,3};
int k = 19;
System.out.println(new Solution1().numSubarrayProductLessThanK(nums, k));
}
class Solution {
public int numSubarrayProductLessThanK(int[] nums, int k) {
int res = 0;
for (int i = 0; i < nums.length; i++) {
int nowSum = 1;
for (int j = i; j < nums.length; j++) {
nowSum *= nums[j];
if (nowSum < k) {
res++;
}else {
break;
}
}
}
return res;
}
}
class Solution1 {
public int numSubarrayProductLessThanK(int[] nums, int k) {
int res = 0;
int left = 0;
int right = 0;
int tmpSum = 1;
while (right < nums.length) {
tmpSum *= nums[right];
while (tmpSum >= k && left <= right) {
tmpSum /= nums[left];
left++;
}
right++;
res += right - left;
}
return res;
}
}
}

View File

@ -0,0 +1,121 @@
package cn.whaifree.test;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class RateLimitingRequestSplitter {
private int rateLimit;
private BlockingQueue<String> requestQueue = new LinkedBlockingQueue<>();
public RateLimitingRequestSplitter(int rateLimit) {
this.rateLimit = rateLimit;
}
public void addRequest(String request) {
requestQueue.add(request);
}
public void processRequests() throws InterruptedException {
while (!requestQueue.isEmpty()) {
List<String> requests = new ArrayList<>();
for (int i = 0; i < rateLimit; i++) {
String poll = requestQueue.poll();
if (poll == null) {
break;
}
requests.add(poll);
}
System.out.println("send requests: " + requests);
simulateRequestAndResponse(requests);
Thread.sleep(1000);
}
}
private boolean simulateRequestAndResponse(List<String> requests) {
// 模拟请求处理和响应这里简单假设都成功
try {
Thread.sleep(500);
for (int i = 0; i < requests.size(); i++) {
System.out.println("Processed request: " + requests.get(i));
}
return true;
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) throws InterruptedException {
// 假设从配置中心获取的限频为 3
int rateLimitFromConfig = 3;
RateLimitingRequestSplitter splitter = new RateLimitingRequestSplitter(rateLimitFromConfig);
// 添加一些示例请求
for (int i = 0; i < 100; i++) {
splitter.addRequest("Request " + i);
}
splitter.processRequests();
}
}
class CvmResetHandler {
private static final int MAX_CONCURRENT_REQUESTS = 5; // 最大并发请求数
private static final int QUEUE_CAPACITY = 100; // 队列最大容量
private static final LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(QUEUE_CAPACITY);
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
MAX_CONCURRENT_REQUESTS, MAX_CONCURRENT_REQUESTS,
60L, TimeUnit.SECONDS, queue);
public void resetCvm(String serverId) {
Runnable task = () -> {
try {
System.out.println("Starting to reset CVM: " + serverId);
resetCvmServer(serverId);
System.out.println("Finished resetting CVM: " + serverId);
} catch (Exception e) {
System.err.println("Error resetting CVM: " + serverId);
e.printStackTrace();
}
};
// 提交任务到线程池
executor.submit(task);
}
private void resetCvmServer(String serverId) throws InterruptedException {
// 模拟重置操作
Thread.sleep(new Random().nextInt(5000)); // 模拟耗时操作
System.out.println("Resetting CVM: " + serverId);
}
public static void main(String[] args) {
CvmResetHandler handler = new CvmResetHandler();
// 创建多个重置请求
for (int i = 0; i < 50; i++) {
String serverId = "server-" + i;
handler.resetCvm(serverId);
}
// 等待所有任务完成
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
System.err.println("Some tasks did not complete in time.");
}
} catch (InterruptedException e) {
System.err.println("Interrupted while waiting for tasks to complete.");
}
}
}