feat(leetcode): 添加多个 leetcode 问题的解决方案
- 新增了多个 leetcode 问题的 Java 解决方案,包括: - 问题 16: 最接近的三数之和 - 问题 43: 字符串相乘 - 问题 148: 排序链表 - 问题274: H 指数 - 问题 322: 零钱兑换 - 问题 377: 组合总和Ⅳ - 问题474: 一和零 - 问题 740: 删除并获得最大点数 - 更新了部分现有代码文件,优化了结构和注释 Default Changelist .gitignore AbstractClass.java AbstractFactoryPattern.java application.yaml AProviderController.java AService.java BProviderController.java BroomFilter.java BService.java CacheComparatorDemo.java CacheConfig.java CacheConstants.java CacheDecoratorController.java DynamicThreadPoolController.java EventController.java FactoryAndStrategy.java FilterConfig.java GlobalExceptionHandler.java HttpStatus.java IdempotenceController.java LeetCode002.java LeetCode16.java LeetCode33.java LeetCode43.java LeetCode84.java LeetCode148.java LeetCode274.java LeetCode322.java LeetCode377.java LeetCode474.java LeetCode740.java LimitType.java ListNode.java LoadBalanceConfig.java MinioController.java mvnw mvnw.cmd MyAutoConfiguration.java P1.java PersonProtocol.proto pom.xml protocolDemo.java RabbitMQController.java RateLimitAspect.java RateLimiter.java RedEnvelopeController.java RedisConfig.java RedisDataTest.java redisson.yaml RedissonConfig.java RestConfig.java ResVo.java RobEnvelope.lua SelfFilter.java spring.factories SpringDemoApplication.java SpringDemoApplicationTests.java SSEEmitter.java TestController.java UserService.java WhiteListController.java WxQrLoginController.java 工厂模式的几种类型,简单工厂、工厂方法、抽象工厂.md Unversioned Files D:\project\LeetCode\SpringCloud\ServiceA\src\main\resources\application.yaml D:\project\LeetCode\SpringCloud\ServiceB\src\main\resources\application.yaml D:\project\LeetCode\SpringCloud\ServiceA\pom.xml D:\project\LeetCode\SpringCloud\ServiceB\pom.xml D:\project\LeetCode\SpringCloud\pom.xml D:\project\LeetCode\SpringCloud\ServiceA\src\main\java\com\whai\springcloud\servicea\ServiceAApplication.java D:\project\LeetCode\SpringCloud\ServiceA\src\test\java\com\whai\springcloud\servicea\ServiceAApplicationTests.java D:\project\LeetCode\SpringCloud\ServiceB\src\main\java\com\whai\springcloud\serviceb\ServiceBApplication.java D:\project\LeetCode\SpringCloud\ServiceB\src\test\java\com\whai\springcloud\serviceb\ServiceBApplicationTests.java D:\project\LeetCode\SpringCloud\ServiceA\src\test\java\com\whai\springcloud\springcloud\SpringCloudApplicationTests.java D:\project\LeetCode\SpringCloud\ServiceB\src\test\java\com\whai\springcloud\springcloud\SpringCloudApplicationTests.java
This commit is contained in:
parent
7ea67e280f
commit
b6e5672f09
@ -54,5 +54,6 @@ public class FactoryAndStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,11 @@ package cn.whaifree.designPattern.kama.CreateType.AbstractFactoryPattern;
|
|||||||
|
|
||||||
|
|
||||||
public class AbstractFactoryPattern {
|
public class AbstractFactoryPattern {
|
||||||
|
/**
|
||||||
|
* AbstractFactory--> ModernFactory --|
|
||||||
|
* --> ClassicFactory --|-->Sofa OR Chair
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
|
||||||
// https://kamacoder.com/problempage.php?pid=1077
|
// https://kamacoder.com/problempage.php?pid=1077
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
### 简单工厂
|
||||||
|
|
||||||
|
一个工厂生产多种产品
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static Product createProduct(String type) {
|
||||||
|
if ("A".equalsIgnoreCase(type)) {
|
||||||
|
return new ProductA();
|
||||||
|
} else if ("B".equalsIgnoreCase(type)) {
|
||||||
|
return new ProductB();
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown product type");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 工厂方法
|
||||||
|
|
||||||
|
对工厂抽象
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 抽象工厂接口
|
||||||
|
interface Factory {
|
||||||
|
Product createProduct();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体工厂A
|
||||||
|
class FactoryA implements Factory {
|
||||||
|
@Override
|
||||||
|
public Product createProduct() {
|
||||||
|
return new ProductA();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Factory factory = new FactoryA();
|
||||||
|
Product product = factory.createProduct();
|
||||||
|
product.use(); // 输出: Using Product A
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 抽象工厂
|
||||||
|
|
||||||
|
对产品再次抽象出不同属性
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 产品族A接口
|
||||||
|
interface AbstractProductA {
|
||||||
|
void featureA();
|
||||||
|
}
|
||||||
|
// 具体产品A1
|
||||||
|
class ProductA1 implements AbstractProductA {
|
||||||
|
@Override
|
||||||
|
public void featureA() {
|
||||||
|
System.out.println("Feature A1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
79
ForJdk17/src/main/java/cn/whaifree/interview/PA/P1.java
Normal file
79
ForJdk17/src/main/java/cn/whaifree/interview/PA/P1.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package cn.whaifree.interview.PA;
|
||||||
|
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/30 17:38
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class P1 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Scanner in = new Scanner(System.in);
|
||||||
|
// 注意 hasNext 和 hasNextLine 的区别
|
||||||
|
while (in.hasNextInt()) { // 注意 while 处理多个 case
|
||||||
|
int n = in.nextInt();
|
||||||
|
int m = in.nextInt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0 1 2
|
||||||
|
* 0 0 0 0
|
||||||
|
* 1 1 1 1
|
||||||
|
* 2 1 2 3
|
||||||
|
* 3 1 3 6
|
||||||
|
*/
|
||||||
|
int[] dp = new int[m + 1];
|
||||||
|
dp[0] = 1;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = 1; j <= m; j++) {
|
||||||
|
dp[j] = dp[j] + dp[j - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(dp[m]);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class p2{
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
String str = scanner.next();
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
for (int right = 0; right <= str.length(); right++) {
|
||||||
|
for (int left = 0; left < right; left++) {
|
||||||
|
String leftStr = str.substring(0, left);
|
||||||
|
String rightStr = str.substring(right, str.length());
|
||||||
|
String concat = leftStr + rightStr;
|
||||||
|
if (!concat.isEmpty() && huiwen(concat)) {
|
||||||
|
System.out.println(concat);
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(res);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean huiwen(String str){
|
||||||
|
int left = 0;
|
||||||
|
int right = str.length() - 1;
|
||||||
|
while (left < right) {
|
||||||
|
if (str.charAt(left) != str.charAt(right)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
left++;
|
||||||
|
right--;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package cn.whaifree.leetCode;
|
package cn.whaifree.leetCode;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.ListNode;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,13 +111,13 @@ public class LeetCode002 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ListNode {
|
//class ListNode {
|
||||||
int val;
|
// int val;
|
||||||
ListNode next;
|
// ListNode next;
|
||||||
ListNode() {}
|
// ListNode() {}
|
||||||
ListNode(int val) { this.val = val; }
|
// ListNode(int val) { this.val = val; }
|
||||||
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
|
// ListNode(int val, ListNode next) { this.val = val; this.next = next; }
|
||||||
}
|
//}
|
||||||
|
|
||||||
class RefCountGC{
|
class RefCountGC{
|
||||||
// 这个成员属性的唯一作用就是占用一点内存
|
// 这个成员属性的唯一作用就是占用一点内存
|
||||||
|
116
ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode148.java
Normal file
116
ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode148.java
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package cn.whaifree.leetCode;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import cn.whaifree.leetCode.model.ListNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 14:35
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode148 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
ListNode listNode = ListNode.listNodeFromArray(new int[]{-1,5,3,4,0});
|
||||||
|
ListNode listNode1 = new Solution().sortList(listNode);
|
||||||
|
listNode1.printList();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
* 冒泡
|
||||||
|
* @param head
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ListNode sortList(ListNode head) {
|
||||||
|
ListNode resList = new ListNode(-1);
|
||||||
|
|
||||||
|
ListNode tmpHead = new ListNode(-1, head);
|
||||||
|
ListNode pre = tmpHead;
|
||||||
|
|
||||||
|
|
||||||
|
ListNode index = pre; // 用于对比index.next和index.next的指针
|
||||||
|
ListNode markMaxPre = pre; // 用于标记一次循环的最大值
|
||||||
|
while (index.next != null) {
|
||||||
|
// 一次循环找到最大的一个
|
||||||
|
while (index.next != null) {
|
||||||
|
if (markMaxPre.next.val < index.next.val) {
|
||||||
|
markMaxPre = index;
|
||||||
|
}
|
||||||
|
index = index.next;
|
||||||
|
}
|
||||||
|
ListNode thisMax = markMaxPre.next;
|
||||||
|
|
||||||
|
markMaxPre.next = markMaxPre.next.next;
|
||||||
|
addToHead(resList, thisMax);
|
||||||
|
index = pre;
|
||||||
|
markMaxPre = pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
return resList.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToHead(ListNode pre, ListNode newNode) {
|
||||||
|
if (newNode == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ListNode next = pre.next;
|
||||||
|
pre.next = newNode;
|
||||||
|
newNode.next = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
ListNode listNode = ListNode.listNodeFromArray(new int[]{4,2,1,3});
|
||||||
|
ListNode listNode1 = new Solution2().sortList(listNode);
|
||||||
|
listNode1.printList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 归并排序
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Solution2 {
|
||||||
|
// 我们使用 fast,slow 快慢双指针法,奇数个节点找到中点,偶数个节点找到中心左边的节点。
|
||||||
|
public ListNode sortList(ListNode head) {
|
||||||
|
if (head == null || head.next == null) {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
ListNode fast = head.next; // 注意不要一起开始
|
||||||
|
ListNode slow = head;
|
||||||
|
while (fast != null && fast.next != null) {
|
||||||
|
fast = fast.next.next;
|
||||||
|
slow = slow.next;
|
||||||
|
}
|
||||||
|
ListNode BHead = slow.next;
|
||||||
|
slow.next = null;
|
||||||
|
ListNode sortAfterA = sortList(head);
|
||||||
|
ListNode sortAfterB = sortList(BHead);
|
||||||
|
|
||||||
|
return merge(sortAfterA, sortAfterB);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListNode merge(ListNode A, ListNode B) {
|
||||||
|
ListNode dummy = new ListNode(-1);
|
||||||
|
ListNode cur = dummy;
|
||||||
|
while (A != null && B != null) {
|
||||||
|
if (A.val < B.val) {
|
||||||
|
cur.next = A;
|
||||||
|
A = A.next;
|
||||||
|
} else {
|
||||||
|
cur.next = B;
|
||||||
|
B = B.next;
|
||||||
|
}
|
||||||
|
cur = cur.next;
|
||||||
|
}
|
||||||
|
cur.next = A != null ? A : B;
|
||||||
|
return dummy.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
51
ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode16.java
Normal file
51
ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode16.java
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package cn.whaifree.leetCode;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/28 14:50
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode16 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] nums = {4, 0, 5, -5, 3, 3, 0, -4, -5};
|
||||||
|
System.out.println(new Solution().threeSumClosest(nums, -2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public int threeSumClosest(int[] nums, int target) {
|
||||||
|
Arrays.sort(nums);
|
||||||
|
int closeV = Integer.MAX_VALUE;
|
||||||
|
for (int left = 0; left < nums.length; left++) {
|
||||||
|
int mid = left + 1;
|
||||||
|
int right = nums.length - 1;
|
||||||
|
while (mid < right) {
|
||||||
|
int mv = nums[mid] + nums[left] + nums[right];
|
||||||
|
|
||||||
|
if (Math.abs(mv - target) < Math.abs(closeV - target)) {
|
||||||
|
closeV = mv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mv > target) {
|
||||||
|
right = right - 1;
|
||||||
|
} else if (mv < target) {
|
||||||
|
mid = mid + 1;
|
||||||
|
} else {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closeV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
65
ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode43.java
Normal file
65
ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode43.java
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package cn.whaifree.leetCode;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/28 15:23
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode43 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
String num1 = "12";
|
||||||
|
String num2 = "12";
|
||||||
|
Solution solution = new Solution();
|
||||||
|
String result = solution.multiply(num1, num2);
|
||||||
|
System.out.println(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
* 12345
|
||||||
|
* 678
|
||||||
|
*
|
||||||
|
* <img src="https://assets.leetcode-cn.com/solution-static/43/sol1.png">
|
||||||
|
* @param num1
|
||||||
|
* @param num2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String multiply(String num1, String num2) {
|
||||||
|
if (num1.equals("0") || num2.equals("0")) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
char[] char1 = num1.toCharArray();
|
||||||
|
char[] char2 = num2.toCharArray();
|
||||||
|
|
||||||
|
int[] ans = new int[char1.length + char2.length];
|
||||||
|
|
||||||
|
for (int i = char1.length - 1; i >= 0; i--) {
|
||||||
|
int V1 = char1[i] - '0';
|
||||||
|
for (int j = char2.length - 1; j >= 0; j--) {
|
||||||
|
int V2 = char2[j] - '0';
|
||||||
|
int product = V1 * V2;
|
||||||
|
int sum = ans[i + j + 1] + product;
|
||||||
|
int pre = sum / 10;
|
||||||
|
int retail = sum % 10;
|
||||||
|
ans[i + j + 1] = retail;
|
||||||
|
ans[i + j] = ans[i + j] + pre;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb=new StringBuilder();
|
||||||
|
for (int i = 0; i < ans.length; i++) {
|
||||||
|
if (i == 0 && ans[i] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sb.append(ans[i]);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
55
ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode740.java
Normal file
55
ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode740.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package cn.whaifree.leetCode;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/30 16:21
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode740 {
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] nums = new int[]{2, 2, 3, 3, 3, 4};
|
||||||
|
int res = new Solution().deleteAndEarn(nums);
|
||||||
|
System.out.println(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 打家劫舍
|
||||||
|
|
||||||
|
* @param nums
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int deleteAndEarn(int[] nums) {
|
||||||
|
|
||||||
|
int max = Arrays.stream(nums).max().getAsInt();
|
||||||
|
|
||||||
|
Map<Integer, Integer> map = new HashMap<>();
|
||||||
|
for (int num : nums) {
|
||||||
|
map.put(num, map.getOrDefault(num, 0) + 1);
|
||||||
|
}
|
||||||
|
int[] sum = new int[max + 1]; // sum[i]表示选择i进行打劫的收益
|
||||||
|
// 每个数字出现的总点数,能获取的总收益
|
||||||
|
map.forEach(
|
||||||
|
(k, v) -> sum[k] = v * k
|
||||||
|
);
|
||||||
|
|
||||||
|
int[] dp = new int[max + 1];
|
||||||
|
dp[0] = 0;
|
||||||
|
dp[1] = sum[1];
|
||||||
|
for (int i = 2; i <= max; i++) {
|
||||||
|
// dp[i-1] 不抢,抢 dp[i-2] + 本节点
|
||||||
|
dp[i] = Math.max(dp[i - 1], dp[i - 2] + sum[i]);
|
||||||
|
}
|
||||||
|
return dp[max];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -44,12 +44,15 @@ public class ListNode {
|
|||||||
System.out.println("null!");
|
System.out.println("null!");
|
||||||
}
|
}
|
||||||
ListNode curr = head;
|
ListNode curr = head;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
while (curr != null) {
|
while (curr != null) {
|
||||||
System.out.print(curr.val + " ");
|
sb.append(curr.val).append("->");
|
||||||
curr = curr.next;
|
curr = curr.next;
|
||||||
}
|
}
|
||||||
|
System.out.println(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void printList() {
|
public void printList() {
|
||||||
printList(this);
|
printList(this);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
package cn.whaifree.redo.redo_all_241016;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 12:25
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode274 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] citations = {2};
|
||||||
|
int res = new Solution().hIndex(citations);
|
||||||
|
System.out.println(res);
|
||||||
|
}
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
* 0 1 3 5 6
|
||||||
|
* @param citations
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int hIndex(int[] citations) {
|
||||||
|
|
||||||
|
Arrays.sort(citations);
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < citations.length; i++) {
|
||||||
|
if (citations[i] >= citations.length - i) {
|
||||||
|
return citations.length - i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package cn.whaifree.redo.redo_all_241016;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/30 15:12
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode322 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] coins = {2, 5};
|
||||||
|
int amount = 12;
|
||||||
|
Solution solution = new Solution();
|
||||||
|
int result = solution.coinChange(coins, amount);
|
||||||
|
System.out.println(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
* 无穷背包
|
||||||
|
* 0 1 2 3 4 5 6 7 8 9 10 11
|
||||||
|
* 1 1 1 2 3 4 5 6 7 8 9 10 11
|
||||||
|
* 2 1 1 1 2
|
||||||
|
* 5
|
||||||
|
*
|
||||||
|
* @param coins
|
||||||
|
* @param amount
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int coinChange(int[] coins, int amount) {
|
||||||
|
int[] dp = new int[amount + 1];
|
||||||
|
Arrays.fill(dp, Integer.MAX_VALUE);
|
||||||
|
dp[0] = 0;
|
||||||
|
for (int j = 1; j <= amount; j++) {
|
||||||
|
for (int i = 0; i < coins.length; i++) {
|
||||||
|
if (j >= coins[i] && dp[j - coins[i]] != Integer.MAX_VALUE) {
|
||||||
|
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[amount] == Integer.MAX_VALUE? -1 : dp[amount];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package cn.whaifree.redo.redo_all_241016;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/30 14:11
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode33 {
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param nums
|
||||||
|
* @param target
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int search(int[] nums, int target) {
|
||||||
|
int left = 0, right = nums.length - 1;
|
||||||
|
|
||||||
|
while (left <= right) {
|
||||||
|
int mid = (left + right) / 2;
|
||||||
|
if (nums[mid] == target) {
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
if (nums[left] <= nums[mid]) {
|
||||||
|
// |4 5 6 7 8 | 0 1
|
||||||
|
// 目标值在4-6,那么就右边指针mid-1 ,否则不在这个指针,去另一个乱序区间找
|
||||||
|
// 【 】mid【 k 】
|
||||||
|
if (target < nums[mid] && target >= nums[left]) {
|
||||||
|
right = mid - 1;
|
||||||
|
} else {
|
||||||
|
left = mid + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 4 5 |0 1 2 3|
|
||||||
|
if (target > nums[mid] && target <= nums[right]) {
|
||||||
|
left = mid + 1;
|
||||||
|
} else {
|
||||||
|
right = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Solution1 {
|
||||||
|
public int search(int[] nums, int target) {
|
||||||
|
int left = 0;
|
||||||
|
int right = nums.length - 1;
|
||||||
|
while (left < right) {
|
||||||
|
int mid = (left + right) / 2;
|
||||||
|
if (nums[mid] == target) {
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
if (nums[mid] >= nums[left]) {
|
||||||
|
// | mid k |
|
||||||
|
if (nums[left] <= target && target < nums[mid]) {
|
||||||
|
right = mid - 1;
|
||||||
|
}else {
|
||||||
|
left = mid + 1;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
// | k mid |
|
||||||
|
if (nums[right] >= target && target > nums[mid]) {
|
||||||
|
left = mid + 1;
|
||||||
|
}else {
|
||||||
|
right = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package cn.whaifree.redo.redo_all_241016;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 14:04
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode377 {
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] nums = {1, 2, 3, 4};
|
||||||
|
int target = 4;
|
||||||
|
int result = new Solution().combinationSum4(nums, target);
|
||||||
|
System.out.println(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
* 背包容量 target+1
|
||||||
|
* 无穷背包
|
||||||
|
*
|
||||||
|
* 0-i 中任选,装满背包的组合数
|
||||||
|
*
|
||||||
|
* 组合数,有排序
|
||||||
|
*
|
||||||
|
* 0 1 2 3 4 5
|
||||||
|
* 1 1 1 1 1 1 1
|
||||||
|
* 2 1 1 2 2 3 3 dp[j]+dp[j-nums[i]] // 没有排序
|
||||||
|
* 3 1 1 2 3 4 5
|
||||||
|
*
|
||||||
|
* @param nums
|
||||||
|
* @param target
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int combinationSum4(int[] nums, int target) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 先遍历背包,就可以让之前的背包都获得所有物品放入的可能性,
|
||||||
|
*
|
||||||
|
* 计算dp[4]的时候,结果集只有 {1,3} 这样的集合,忽略了{3,1}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int[] dp = new int[target + 1];
|
||||||
|
dp[0] = 1;
|
||||||
|
for (int j = 1 ; j <= target; j++) { // 有顺序,先遍历背包
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
if (nums[i] <= j) {
|
||||||
|
dp[j] = dp[j] + dp[j - nums[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[target];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package cn.whaifree.redo.redo_all_241016;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/30 15:42
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode474 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
String[] strs = {"10", "0001", "1", "0"};
|
||||||
|
int m = 5;
|
||||||
|
int n = 3;
|
||||||
|
Solution solution = new Solution();
|
||||||
|
int result = solution.findMaxForm(strs, m, n);
|
||||||
|
System.out.println(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 从str 0-i中任意取,满足j个0和k个1的最大长度
|
||||||
|
*
|
||||||
|
* @param strs
|
||||||
|
* @param m
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int findMaxForm(String[] strs, int m, int n) {
|
||||||
|
int[][] dp = new int[m + 1][n + 1];
|
||||||
|
for (int i = 0; i < strs.length; i++) {
|
||||||
|
String str = strs[i];
|
||||||
|
int zeroCount = countZero(str);
|
||||||
|
int oneCount = str.length() - zeroCount;
|
||||||
|
for (int j = m; j >= 0; j--) {
|
||||||
|
for (int k = n; k >= 0; k--) {
|
||||||
|
if (j >= zeroCount && k >= oneCount) {
|
||||||
|
dp[j][k] = Math.max(dp[j][k], dp[j - zeroCount][k - oneCount] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[m][n];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int countZero(String str) {
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
if (str.charAt(i) == '0') {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package cn.whaifree.redo.redo_all_241016;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 11:15
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode84 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] heights = {1,1};
|
||||||
|
Solution solution = new Solution();
|
||||||
|
int i = solution.largestRectangleArea(heights);
|
||||||
|
System.out.println(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
* 15
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param heights
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int largestRectangleArea(int[] heights) {
|
||||||
|
int[] left = new int[heights.length];
|
||||||
|
int[] right = new int[heights.length];
|
||||||
|
|
||||||
|
// 对每个元素找到左边第一个比他小的
|
||||||
|
left[0] = -1;
|
||||||
|
for (int i = 0; i < heights.length; i++) {
|
||||||
|
int index = i - 1;
|
||||||
|
while (index >= 0 && heights[index] >= heights[i]) {
|
||||||
|
index = left[index];
|
||||||
|
}
|
||||||
|
left[i] = index;
|
||||||
|
}
|
||||||
|
// 对每个元素找到右边第一个比他小的
|
||||||
|
right[heights.length - 1] = heights.length;
|
||||||
|
for (int i = heights.length - 1; i >= 0; i--) {
|
||||||
|
int index = i + 1;
|
||||||
|
while (index <= heights.length - 1 && heights[index] >= heights[i]) {
|
||||||
|
index = right[index];
|
||||||
|
}
|
||||||
|
right[i] = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxArea = 0;
|
||||||
|
for (int i = 0; i < right.length; i++) {
|
||||||
|
maxArea = Math.max(maxArea, heights[i] * (right[i] - left[i] - 1));
|
||||||
|
}
|
||||||
|
return maxArea;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution1 {
|
||||||
|
/**
|
||||||
|
* 29
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param heights
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int largestRectangleArea(int[] heights) {
|
||||||
|
int[] h = new int[heights.length + 2];
|
||||||
|
System.arraycopy(heights, 0, h, 1, heights.length);
|
||||||
|
heights = h;
|
||||||
|
|
||||||
|
Deque<Integer> stack = new LinkedList<>();
|
||||||
|
stack.push(0);
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 1; i < heights.length; i++) {
|
||||||
|
while (!stack.isEmpty() && heights[i] < heights[stack.peek()]) {
|
||||||
|
Integer pop = stack.pop();
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
int right = i;
|
||||||
|
int left = pop;
|
||||||
|
int region = (right - left - 1) * heights[pop];
|
||||||
|
res = Math.max(res, region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stack.push(i);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package cn.whaifree.tech.protocolDemo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/28 20:10
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class protocolDemo {
|
||||||
|
}
|
21
ForJdk17/src/main/resources/protocol/PersonProtocol.proto
Normal file
21
ForJdk17/src/main/resources/protocol/PersonProtocol.proto
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "com.example.protobufdemo";
|
||||||
|
option java_outer_classname = "PersonProto";
|
||||||
|
|
||||||
|
message Person {
|
||||||
|
int32 id = 1;
|
||||||
|
string name = 2;
|
||||||
|
string email = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
<!-- Protobuf runtime library -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.protobuf</groupId>
|
||||||
|
<artifactId>protobuf-java</artifactId>
|
||||||
|
<version>3.21.9</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
*/
|
54
SpringCloud/ServiceA/pom.xml
Normal file
54
SpringCloud/ServiceA/pom.xml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.whai.springcloud</groupId>
|
||||||
|
<artifactId>SpringCloud</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.whai.springcloud</groupId>
|
||||||
|
<artifactId>ServiceA</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>ServiceA</name>
|
||||||
|
<description>ServiceA</description>
|
||||||
|
<url/>
|
||||||
|
<licenses>
|
||||||
|
<license/>
|
||||||
|
</licenses>
|
||||||
|
<developers>
|
||||||
|
<developer/>
|
||||||
|
</developers>
|
||||||
|
<scm>
|
||||||
|
<connection/>
|
||||||
|
<developerConnection/>
|
||||||
|
<tag/>
|
||||||
|
<url/>
|
||||||
|
</scm>
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.whai.springcloud.servicea;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
@EnableFeignClients
|
||||||
|
public class ServiceAApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(ServiceAApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.whai.springcloud.servicea.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 18:31
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class LoadBalanceConfig {
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.whai.springcloud.servicea.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 18:29
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RestConfig {
|
||||||
|
@Bean
|
||||||
|
@LoadBalanced
|
||||||
|
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
|
||||||
|
return restTemplateBuilder.build();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.whai.springcloud.servicea.controller;
|
||||||
|
|
||||||
|
import com.whai.springcloud.servicea.service.BService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
|
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 17:58
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class AProviderController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BService bService;
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/hello")
|
||||||
|
public String hello(String msg) {
|
||||||
|
System.out.println("A---->B");
|
||||||
|
return bService.getB(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private DiscoveryClient discoveryClient;
|
||||||
|
@Resource
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
@GetMapping("/getBDiscovey")
|
||||||
|
public String getBDiscovey(){
|
||||||
|
List<ServiceInstance> instances = discoveryClient.getInstances("service-b");
|
||||||
|
ServiceInstance serviceInstance = instances.get(0);
|
||||||
|
return restTemplate.getForObject("http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/getB?msg=hello", String.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
|||||||
|
package com.whai.springcloud.servicea.controller;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
|
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 21:51
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class DynamicThreadPoolController {
|
||||||
|
|
||||||
|
static ThreadPoolExecutor executor ;
|
||||||
|
@Resource
|
||||||
|
private ConfigurableEnvironment environment;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
|
||||||
|
|
||||||
|
executor = new ThreadPoolExecutor(
|
||||||
|
Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().availableProcessors() * 4, 10, TimeUnit.SECONDS,
|
||||||
|
new ArrayBlockingQueue<>(100),
|
||||||
|
new ThreadFactory() {
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
Thread thread = new Thread(r);
|
||||||
|
thread.setName("DynamicThreadPoolController");
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new ThreadPoolExecutor.AbortPolicy()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/dynamicCoreSize")
|
||||||
|
public String dynamicCoreSize() {
|
||||||
|
return "Dynamic Core Size: " + executor.getCorePoolSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@RefreshScope
|
||||||
|
@EnableConfigurationProperties(ThreadConfigProperties.class) // 自动引入Properties,会自动加入Context
|
||||||
|
class DynamicThreadPoolConfig implements ApplicationListener<EnvironmentChangeEvent> {
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ThreadConfigProperties threadConfigProperties;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(EnvironmentChangeEvent event) {
|
||||||
|
if (event.getKeys().contains("dynamic.coreSize")) {
|
||||||
|
// 获取值
|
||||||
|
Integer coreSize = threadConfigProperties.getCoreSize();
|
||||||
|
// 更新线程池
|
||||||
|
DynamicThreadPoolController.executor.setCorePoolSize(coreSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "dynamic")
|
||||||
|
class ThreadConfigProperties {
|
||||||
|
int coreSize;
|
||||||
|
int maxSize;
|
||||||
|
public int getMaxSize() {
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
public void setMaxSize(int maxSize) {
|
||||||
|
this.maxSize = maxSize;
|
||||||
|
}
|
||||||
|
public int getCoreSize() {
|
||||||
|
return coreSize;
|
||||||
|
}
|
||||||
|
public void setCoreSize(int coreSize) {
|
||||||
|
this.coreSize = coreSize;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.whai.springcloud.servicea.service;
|
||||||
|
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 17:58
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@FeignClient("ServiceB")
|
||||||
|
public interface BService {
|
||||||
|
|
||||||
|
@GetMapping("/getB")
|
||||||
|
String getB(@RequestParam("msg") String msg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
40
SpringCloud/ServiceA/src/main/resources/application.yaml
Normal file
40
SpringCloud/ServiceA/src/main/resources/application.yaml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
server:
|
||||||
|
port: 12120
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: ServiceA
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
discovery:
|
||||||
|
namespace: 97ff159f-6177-4aab-b735-bd75458949d4
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
server-addr: localhost:8848
|
||||||
|
config:
|
||||||
|
# 配置所属命名空间的id,我们配置名称为dev的id,在命名空间列表查看id的值
|
||||||
|
namespace: 97ff159f-6177-4aab-b735-bd75458949d4
|
||||||
|
# 文件名,如果没有配置则默认为 ${spring.application.name}
|
||||||
|
prefix: springboot3-nacos
|
||||||
|
# 配置所属分组
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
# 后缀名,只支持 properties 和 yaml 类型
|
||||||
|
file-extension: yaml
|
||||||
|
# nacos服务器地址
|
||||||
|
server-addr: localhost:8848
|
||||||
|
# 配置自动刷新
|
||||||
|
refresh-enabled: true
|
||||||
|
|
||||||
|
# 启用远程同步配置
|
||||||
|
enable-remote-sync-config: true
|
||||||
|
config:
|
||||||
|
import:
|
||||||
|
- optional:nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
|
||||||
|
# Logger Config
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
com.hexadecimal: debug
|
||||||
|
|
||||||
|
hexadecimal:
|
||||||
|
name: whai
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.whai.springcloud.servicea;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ServiceAApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.whai.springcloud.springcloud;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class SpringCloudApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
54
SpringCloud/ServiceB/pom.xml
Normal file
54
SpringCloud/ServiceB/pom.xml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.whai.springcloud</groupId>
|
||||||
|
<artifactId>SpringCloud</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.whai.springcloud</groupId>
|
||||||
|
<artifactId>ServiceB</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>ServiceB</name>
|
||||||
|
<description>ServiceB</description>
|
||||||
|
<url/>
|
||||||
|
<licenses>
|
||||||
|
<license/>
|
||||||
|
</licenses>
|
||||||
|
<developers>
|
||||||
|
<developer/>
|
||||||
|
</developers>
|
||||||
|
<scm>
|
||||||
|
<connection/>
|
||||||
|
<developerConnection/>
|
||||||
|
<tag/>
|
||||||
|
<url/>
|
||||||
|
</scm>
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.whai.springcloud.serviceb;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
@EnableFeignClients
|
||||||
|
public class ServiceBApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(ServiceBApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.whai.springcloud.serviceb.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 17:58
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class BProviderController {
|
||||||
|
|
||||||
|
private final Environment environment;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public BProviderController(Environment environment) {
|
||||||
|
this.environment = environment;
|
||||||
|
}
|
||||||
|
// 提供服务
|
||||||
|
@RequestMapping("/getB")
|
||||||
|
public String getB(String msg) {
|
||||||
|
return StrUtil.format("BProviderController.getB, msg: {}, port: {}", msg, environment.getProperty("server.port"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.whai.springcloud.serviceb.service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/29 17:58
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public interface AService {
|
||||||
|
}
|
40
SpringCloud/ServiceB/src/main/resources/application.yaml
Normal file
40
SpringCloud/ServiceB/src/main/resources/application.yaml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
spring:
|
||||||
|
|
||||||
|
application:
|
||||||
|
name: ServiceB
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
discovery:
|
||||||
|
namespace: 97ff159f-6177-4aab-b735-bd75458949d4
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
server-addr: localhost:8848
|
||||||
|
config:
|
||||||
|
# ?????????id????????dev?id??????????id??
|
||||||
|
namespace: 97ff159f-6177-4aab-b735-bd75458949d4
|
||||||
|
# ?????????????? ${spring.application.name}
|
||||||
|
# prefix: springboot3-nacos
|
||||||
|
# ??????
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
# ??????? properties ? yaml ??
|
||||||
|
file-extension: yaml
|
||||||
|
# nacos?????
|
||||||
|
server-addr: localhost:8848
|
||||||
|
# ??????
|
||||||
|
refresh-enabled: true
|
||||||
|
# ????????
|
||||||
|
enable-remote-sync-config: true
|
||||||
|
config:
|
||||||
|
import:
|
||||||
|
- optional:nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
|
||||||
|
# Logger Config
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
com.hexadecimal: debug
|
||||||
|
|
||||||
|
hexadecimal:
|
||||||
|
name: whai
|
||||||
|
# --server.port=12139
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.whai.springcloud.serviceb;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ServiceBApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.whai.springcloud.springcloud;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class SpringCloudApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
103
SpringCloud/pom.xml
Normal file
103
SpringCloud/pom.xml
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.3.5</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.whai.springcloud</groupId>
|
||||||
|
<artifactId>SpringCloud</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>SpringCloud</name>
|
||||||
|
<description>SpringCloud</description>
|
||||||
|
<url/>
|
||||||
|
<licenses>
|
||||||
|
<license/>
|
||||||
|
</licenses>
|
||||||
|
<developers>
|
||||||
|
<developer/>
|
||||||
|
</developers>
|
||||||
|
<scm>
|
||||||
|
<connection/>
|
||||||
|
<developerConnection/>
|
||||||
|
<tag/>
|
||||||
|
<url/>
|
||||||
|
</scm>
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
<spring-cloud.version>2023.0.3</spring-cloud.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<!--hutool-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.8.14</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!--openfeign-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
<version>2023.0.1.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
<version>2023.0.1.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>org.springframework.cloud</groupId>-->
|
||||||
|
<!-- <artifactId>spring-cloud-starter-consul-config</artifactId>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>org.springframework.cloud</groupId>-->
|
||||||
|
<!-- <artifactId>spring-cloud-starter-consul-discovery</artifactId>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
0
springDemo/mvnw → SpringDemo/mvnw
vendored
0
springDemo/mvnw → SpringDemo/mvnw
vendored
@ -9,10 +9,10 @@
|
|||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>cn.whaifree</groupId>
|
<groupId>cn.whaifree</groupId>
|
||||||
<artifactId>springDemo</artifactId>
|
<artifactId>SpringDemo</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<name>springDemo</name>
|
<name>SpringDemo</name>
|
||||||
<description>springDemo</description>
|
<description>SpringDemo</description>
|
||||||
<url/>
|
<url/>
|
||||||
<licenses>
|
<licenses>
|
||||||
<license/>
|
<license/>
|
@ -0,0 +1,44 @@
|
|||||||
|
//package cn.whaifree.springdemo.config;
|
||||||
|
//
|
||||||
|
//import org.springframework.cache.Cache;
|
||||||
|
//import org.springframework.cache.CacheManager;
|
||||||
|
//import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
//import org.springframework.cache.concurrent.ConcurrentMapCache;
|
||||||
|
//import org.springframework.cache.transaction.TransactionAwareCacheDecorator;
|
||||||
|
//import org.springframework.context.annotation.Bean;
|
||||||
|
//import org.springframework.context.annotation.Configuration;
|
||||||
|
//import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
//
|
||||||
|
//import java.util.Arrays;
|
||||||
|
//import java.util.Collection;
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * @version 1.0
|
||||||
|
// * @Author whai文海
|
||||||
|
// * @Date 2024/10/25 22:44
|
||||||
|
// * @注释
|
||||||
|
// */
|
||||||
|
//@Configuration
|
||||||
|
//@EnableCaching()
|
||||||
|
//@EnableTransactionManagement()
|
||||||
|
//public class CacheConfig {
|
||||||
|
// @Bean
|
||||||
|
// public CacheManager cacheManager() {
|
||||||
|
// return new CustomCacheManager();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 自定义的 CacheManager,装饰每个缓存为 TransactionAwareCacheDecorator
|
||||||
|
// static class CustomCacheManager implements CacheManager {
|
||||||
|
// @Override
|
||||||
|
// public Cache getCache(String name) {
|
||||||
|
// Cache cache = new ConcurrentMapCache(name); // 使用 ConcurrentMapCache 实现缓存
|
||||||
|
// return new TransactionAwareCacheDecorator(cache); // 包装为 TransactionAwareCacheDecorator
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public Collection<String> getCacheNames() {
|
||||||
|
// return Arrays.asList("myCache"); // 设定缓存的名称
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
@ -0,0 +1,67 @@
|
|||||||
|
//package cn.whaifree.springdemo.controller.CacheDecoratorDemo;
|
||||||
|
//
|
||||||
|
//import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
//import jakarta.annotation.Resource;
|
||||||
|
//import org.springframework.cache.Cache;
|
||||||
|
//import org.springframework.cache.annotation.CachePut;
|
||||||
|
//import org.springframework.cache.annotation.Cacheable;
|
||||||
|
//import org.springframework.data.redis.cache.RedisCacheManager;
|
||||||
|
//import org.springframework.transaction.annotation.Transactional;
|
||||||
|
//import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
//import org.springframework.web.bind.annotation.RestController;
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * @version 1.0
|
||||||
|
// * @Author whai文海
|
||||||
|
// * @Date 2024/10/25 22:43
|
||||||
|
// * @注释
|
||||||
|
// */
|
||||||
|
//@RestController
|
||||||
|
//public class CacheDecoratorController {
|
||||||
|
//
|
||||||
|
// @Resource
|
||||||
|
// private final RedisCacheManager cacheManager;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// public CacheDecoratorController(RedisCacheManager cacheManager) {
|
||||||
|
// this.cacheManager = cacheManager;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @RequestMapping("/getData")
|
||||||
|
// public String getData(Long id) {
|
||||||
|
// // 先从缓存中获取数据
|
||||||
|
// String data = SpringUtil.getBean(CacheDecoratorController.class).getDataById(id);
|
||||||
|
// return data;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @RequestMapping("/update")
|
||||||
|
// public void update(Long id, String newValue) {
|
||||||
|
// // 更新数据
|
||||||
|
// SpringUtil.getBean(CacheDecoratorController.class).updateData(id, newValue);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Cacheable(value = "myCache", key = "#id")
|
||||||
|
// public String getDataById(Long id) {
|
||||||
|
// // 模拟获取数据操作
|
||||||
|
// return "Data for ID " + id;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Transactional
|
||||||
|
// @CachePut(value = "myCache", key = "#id", condition = "#result != null")
|
||||||
|
// public String updateData(Long id, String newValue) {
|
||||||
|
// // 更新数据库操作
|
||||||
|
// // ...
|
||||||
|
// // 返回的新值会在事务提交后自动更新到缓存中
|
||||||
|
// // return newValue;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// // 或者手动操作缓存
|
||||||
|
// Cache myCache = cacheManager.getCache("myCache");
|
||||||
|
// if (myCache != null) {
|
||||||
|
// myCache.put(id, newValue);
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
@ -0,0 +1,57 @@
|
|||||||
|
package cn.whaifree.springdemo.utils.BroomFilter;
|
||||||
|
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/30 21:01
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class BroomFilter{
|
||||||
|
RedisTemplate redisTemplate = SpringUtil.getBean("redisTemplate", RedisTemplate.class);
|
||||||
|
|
||||||
|
private int hashCount; // 哈希函数数量
|
||||||
|
private int size; // 位图大小
|
||||||
|
private String key; // Redis 中的 Bitmap 键
|
||||||
|
|
||||||
|
public BroomFilter() {
|
||||||
|
this.hashCount = 10;
|
||||||
|
this.size = 1000000;
|
||||||
|
this.key = "broomFilter";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
// 计算Hashcode
|
||||||
|
int[] hash = getHash(o);
|
||||||
|
for (int i : hash) {
|
||||||
|
// 检查位图中对应位置是否为true
|
||||||
|
if (!redisTemplate.opsForValue().getBit(key, i)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToBroom(Object o) {
|
||||||
|
|
||||||
|
// 计算Hashcode
|
||||||
|
int[] hash = getHash(o);
|
||||||
|
for (int i : hash) {
|
||||||
|
// 设置位图中对应位置为true
|
||||||
|
redisTemplate.opsForValue().setBit(key, i, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成哈希值
|
||||||
|
private int[] getHash(Object value) {
|
||||||
|
int[] result = new int[hashCount];
|
||||||
|
for (int i = 0; i < hashCount; i++) {
|
||||||
|
result[i] = Math.abs(value.hashCode() + i * 123456) % size;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,11 @@
|
|||||||
package cn.whaifree.springdemo.RedisData;
|
package cn.whaifree.springdemo.RedisData;
|
||||||
|
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import cn.whaifree.springdemo.utils.BroomFilter.BroomFilter;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.data.geo.*;
|
import org.springframework.data.geo.*;
|
||||||
import org.springframework.data.redis.connection.BitFieldSubCommands;
|
import org.springframework.data.redis.connection.BitFieldSubCommands;
|
||||||
@ -23,6 +26,8 @@ public class RedisDataTest {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private SpringUtil springUtil;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHyperloglog() {
|
public void testHyperloglog() {
|
||||||
@ -68,8 +73,6 @@ public class RedisDataTest {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 创建BitFieldSubCommands对象,用于执行更复杂的位图操作
|
// 创建BitFieldSubCommands对象,用于执行更复杂的位图操作
|
||||||
BitFieldSubCommands subCommands = BitFieldSubCommands.create();
|
BitFieldSubCommands subCommands = BitFieldSubCommands.create();
|
||||||
// 添加一个指令到subCommands中,获取第11个位(从0开始计数)的64位整型值
|
// 添加一个指令到subCommands中,获取第11个位(从0开始计数)的64位整型值
|
||||||
@ -114,4 +117,30 @@ public class RedisDataTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testbitMap2() {
|
||||||
|
|
||||||
|
BroomFilter broomFilter = new BroomFilter();
|
||||||
|
broomFilter.addToBroom("obj1");
|
||||||
|
broomFilter.addToBroom("obj2");
|
||||||
|
broomFilter.addToBroom("obj3");
|
||||||
|
broomFilter.addToBroom("obj4");
|
||||||
|
broomFilter.addToBroom("obj5");
|
||||||
|
broomFilter.addToBroom("obj6");
|
||||||
|
broomFilter.addToBroom("obj7");
|
||||||
|
broomFilter.addToBroom("obj8");
|
||||||
|
broomFilter.addToBroom("obj9");
|
||||||
|
broomFilter.addToBroom("obj10");
|
||||||
|
broomFilter.addToBroom("obj11");
|
||||||
|
broomFilter.addToBroom("obj12");
|
||||||
|
broomFilter.addToBroom("obj13");
|
||||||
|
broomFilter.addToBroom("obj14");
|
||||||
|
broomFilter.addToBroom("obj15");
|
||||||
|
System.out.println(broomFilter.contains("obj1"));
|
||||||
|
System.out.println(broomFilter.contains("obj16"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
package cn.whaifree.springdemo.config;
|
|
||||||
|
|
||||||
import org.springframework.cache.Cache;
|
|
||||||
import org.springframework.cache.CacheManager;
|
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
|
||||||
import org.springframework.cache.concurrent.ConcurrentMapCache;
|
|
||||||
import org.springframework.cache.transaction.TransactionAwareCacheDecorator;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @version 1.0
|
|
||||||
* @Author whai文海
|
|
||||||
* @Date 2024/10/25 22:44
|
|
||||||
* @注释
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
@EnableCaching()
|
|
||||||
@EnableTransactionManagement()
|
|
||||||
public class CacheConfig {
|
|
||||||
@Bean
|
|
||||||
public CacheManager cacheManager() {
|
|
||||||
return new CustomCacheManager();
|
|
||||||
}
|
|
||||||
// 自定义的 CacheManager,装饰每个缓存为 TransactionAwareCacheDecorator
|
|
||||||
static class CustomCacheManager implements CacheManager {
|
|
||||||
@Override
|
|
||||||
public Cache getCache(String name) {
|
|
||||||
Cache cache = new ConcurrentMapCache(name); // 使用 ConcurrentMapCache 实现缓存
|
|
||||||
return new TransactionAwareCacheDecorator(cache); // 包装为 TransactionAwareCacheDecorator
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<String> getCacheNames() {
|
|
||||||
return Arrays.asList("myCache"); // 设定缓存的名称
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
package cn.whaifree.springdemo.controller.CacheDecoratorDemo;
|
|
||||||
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
|
||||||
import org.springframework.cache.Cache;
|
|
||||||
import org.springframework.cache.annotation.CachePut;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @version 1.0
|
|
||||||
* @Author whai文海
|
|
||||||
* @Date 2024/10/25 22:43
|
|
||||||
* @注释
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
public class CacheDecoratorController {
|
|
||||||
|
|
||||||
private final SpringUtil springUtil;
|
|
||||||
private final RedisCacheManager cacheManager;
|
|
||||||
|
|
||||||
public CacheDecoratorController(SpringUtil springUtil, RedisCacheManager cacheManager) {
|
|
||||||
this.springUtil = springUtil;
|
|
||||||
this.cacheManager = cacheManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping("/getData")
|
|
||||||
public String getData(Long id) {
|
|
||||||
// 先从缓存中获取数据
|
|
||||||
String data = SpringUtil.getBean(CacheDecoratorController.class).getDataById(id);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping("/update")
|
|
||||||
public void update(Long id, String newValue) {
|
|
||||||
// 更新数据
|
|
||||||
SpringUtil.getBean(CacheDecoratorController.class).updateData(id, newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable(value = "myCache", key = "#id")
|
|
||||||
public String getDataById(Long id) {
|
|
||||||
// 模拟获取数据操作
|
|
||||||
return "Data for ID " + id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@CachePut(value = "myCache", key = "#id", condition = "#result != null")
|
|
||||||
public String updateData(Long id, String newValue) {
|
|
||||||
// 更新数据库操作
|
|
||||||
// ...
|
|
||||||
// 返回的新值会在事务提交后自动更新到缓存中
|
|
||||||
// return newValue;
|
|
||||||
|
|
||||||
|
|
||||||
// 或者手动操作缓存
|
|
||||||
Cache myCache = cacheManager.getCache("myCache");
|
|
||||||
if (myCache != null) {
|
|
||||||
myCache.put(id, newValue);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user