Compare commits

..

2 Commits

Author SHA1 Message Date
1f2ef13c86 重构项目结构并添加新功能- 重命名多个文件和包,优化项目结构
- 新增SeleniumDemo模块,实现自动化测试功能
- 添加CopyAndWriteDemo和ExceptionDemo类,演示数据结构和异常处理
- 新增JUnitDemo类,准备添加单元测试- 实现Kama99_2类,解决特定算法问题- 添加MaiGuPiao类,包含多种股票买卖策略实现- 新增OOMTest类,模拟和测试内存溢出情况

AffinityThreadPoolTest.java
Alternate_printing.java
App.java
AppTest.java
chromedriver.exe
CopyAndWriteDemo.java
ExceptionDemo.java
FirstSeleniumDemo.java
FutureRelative.java
JUnitDemo.java
Kama99_2.java
MaiGuPiao.java
OOMTest.java
OOMTest.java
p1.java
pom.xml
pom.xml
QueryTask.java
SeleniumUtils.java
SelfDefiniteThreadPool.java
TestIntAndInteger.java
ThreadConnect.java
ThreadPoolInitSize.java
UserService.java
2024-10-19 23:18:38 +08:00
e6d23febec 新增Kama99和LeetCode797两个图形算法题解
- 添加Kama99类,实现了一个算法来计算二维数组中岛屿的数量
- 添加LeetCode797类,实现了寻找所有从源到目标的路径的算法
- 新增p1类,用于解决特定的字符串问题
- 在TestCacheThreadPool中添加了非公平锁的示例代码
- 在ThreadDemo1中添加了广度优先搜索的实现
2024-10-17 23:22:31 +08:00
28 changed files with 1524 additions and 7 deletions

View File

@ -0,0 +1,256 @@
package cn.whaifree.interview.hzyh;
import java.util.Arrays;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/17 18:23
* @注释
*/
public class p1 {
/**
* abcdefgihjklmnopqrstuvwxyz
*
* 中包含问号?
*
* 判断最少需要多少长可以涵盖这26个字符?是万能的
*
* @param args
*/
public static void main(String[] args) {
}
}
class p2{
public static void main(String[] args) {
p2 p2 = new p2();
System.out.println(p2.find_median(new float[]{1f, 3f, 7f}, new float[]{2f, 5, 10}));
}
/**
* 代码中的类名方法名参数名已经指定请勿修改直接返回方法规定的值即可
*
*
* @param array1 float浮点型一维数组 第一个有序数组
* @param array2 float浮点型一维数组 第二个有序数组
* @return float浮点型
*/
public float find_median (float[] array1, float[] array2) {
// 寻找两个数组中第k小的数
// 每次从数组中早到k/2
int n = array1.length;
int m = array2.length;
int left = (n + m + 1) / 2;
int right = (n + m + 2) / 2;
float res1 = kmin(0, n - 1, array1, 0, m - 1, array2, left);
float res2 = kmin(0, n - 1, array1, 0, m - 1, array2, right);
if ((n + m) % 2 == 0) {
return Math.min(res1, res2);
}
return (float) ((res1 + res2) * 0.5);
}
public static float kmin(int start1,int end1,float[] array1,int start2,int end2,float[] array2,int k){
int len1 = end1-start1+1;
int len2 = end2-start2+1;
if(len1>len2){
return kmin(start2,end2,array2,start1,end1,array1,k);
}
if(len1==0){
return array2[start2+k-1];
}
if(k==1){
return Math.min(array1[start1],array2[start2]);
}
int i = start1 + Math.min(len1, k / 2) - 1;
int j = start2 + Math.min(len2, k / 2) - 1;
if (array1[i]>array2[j]){
return kmin(start1, end1, array1, j + 1, end2, array2, k - j + start2 - 1);
}else {
return kmin(i + 1, end1, array1, start2, end2, array2, k - i + start1 - 1);
}
}
}
class p3{
public static void main(String[] args) {
p3 p3 = new p3();
System.out.println(p3.bitwiseComplement(5));
}
/**
* 代码中的类名方法名参数名已经指定请勿修改直接返回方法规定的值即可
*
*
* @param n int整型
* @return int整型
*/
public int bitwiseComplement (int n) {
// write code here
// 转二进制
// 转反
// 转十进制
String bin = Integer.toBinaryString(n);
StringBuilder stringBuilder = new StringBuilder();
for (char c : bin.toCharArray()) {
if (c == '0') {
stringBuilder.append('1');
}else {
stringBuilder.append('0');
}
}
return Integer.parseInt(stringBuilder.toString(), 2);
}
}
class p4{
public static void main(String[] args) {
p4 p4 = new p4();
int i = p4.giftExch(new int[]{2, 3, 7, 11, 13}, new int[]{1, 2, 3, 4, 5}, 30);
System.out.println(i);
}
/**
* 代码中的类名方法名参数名已经指定请勿修改直接返回方法规定的值即可
*
*
* @param points int整型一维数组 商品所需积分
* @param counts int整型一维数组 商品数量
* @param X int整型 用户拥有的积分
* @return int整型
*/
public int giftExch (int[] points, int[] counts, int X) {
// write code here
// 背包问题
int[] dp = new int[X + 1];
for (int i = 1; i <= X; i++) {
dp[i] = Integer.MAX_VALUE;
}
dp[0] = 0;
for (int i = 0; i < points.length; i++) {
int point = points[i];
int count = counts[i];
for (int j = X; j >= point; j--) {
for (int k = 1; k <= count && j >= k * point; k++) {
dp[j] = Math.min(dp[j], dp[j - k * point] + k);
}
}
}
return dp[X] == Integer.MAX_VALUE ? -1 : dp[X];
}
}
class DCBeiBao{
public static void main(String[] args) {
/**
* 重量 价值 数量
* 物品0 1 15 2
* 物品1 3 20 3
* 物品2 4 30 2
*/
int[] weights = {1, 3, 4};
int[] values = {15, 20, 30};
int[] sizes = {2, 3, 2};
int pkgSize = 7;
DCBeiBao dcBeiBao = new DCBeiBao();
int i = dcBeiBao.maxProfit1(weights, values, sizes, pkgSize);
System.out.println(i);
}
/**
*
* @param weights 重量
* @param values 价值
* @param sizes 物品数量
*/
public int maxProfit(int[] weights, int[] values, int[] sizes,int pkgSize) {
// 先写一个01背包
int[] dp = new int[pkgSize + 1];
for (int i = 0; i < weights.length; i++) {
int weight = weights[i];
int value = values[i];
int size = sizes[i];
for (int j = pkgSize; j >= weight; j--) {
dp[j] = Math.max(dp[j], dp[j - weights[i]] + value);
for (int k = 1; k <= size ; k++) {
// 遍历可以用的每个数量每个数量都做一次判断相当于k个物品
if (k * weight <= j) {
dp[j] = Math.max(dp[j], dp[j - k * weight] + k * value);
}else {
break;
}
}
}
}
return dp[pkgSize];
}
/**
*
* @param weights 重量
* @param values 价值
* @param sizes 物品数量
*/
public int maxProfit1(int[] weights, int[] values, int[] sizes,int pkgSize) {
int sum = Arrays.stream(sizes).sum();
int[] newWeights = new int[sum];
int[] newValues = new int[sum];
int index = 0;
for (int i = 0; i < weights.length; i++) {
for (int j = 0; j < sizes[i]; j++) {
newWeights[index] = weights[i];
newValues[index] = values[i];
index++;
}
}
weights = newWeights;
values = newValues;
// 先写一个01背包
int[] dp = new int[pkgSize + 1];
for (int i = 0; i < weights.length; i++) {
int weight = weights[i];
int value = values[i];
for (int j = pkgSize; j >= weight; j--) {
dp[j] = Math.max(dp[j], dp[j - weights[i]] + value);
}
}
return dp[pkgSize];
}
}

View File

@ -0,0 +1,65 @@
package cn.whaifree.leetCode.Graph;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/17 16:26
* @注释
*/
public class Kama99 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
int[][] input = new int[a][b];
boolean[][] visited = new boolean[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
input[i][j] = scanner.nextInt();
}
}
int res = 0;
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
if (!visited[i][j] && input[i][j] == 1) {
// 没有走过的节点+为陆地1
res++;
method(input, visited, i, j);
}
}
}
System.out.println(res);
}
public static int method(int[][] input, boolean[][] looking, int x, int y) {
int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; // 表示四个方向
int res = 0;
int[] item = new int[]{x, y};
looking[x][y] = true;
Deque<int[]> queue = new LinkedList<>();
queue.add(item);
while (!queue.isEmpty()) {
int[] pop = queue.pop();
int x1 = pop[0];
int y1 = pop[1];
for (int i = 0; i < 4; i++) {
int nextX = x1 + dir[i][0];
int nextY = y1 + dir[i][1];
if (nextX >= 0 && nextX < input.length && nextY >= 0 && nextY < input[0].length) {
if (!looking[nextX][nextY] && input[nextX][nextY] == 1) { // 只有1才遍历这样就可以保证只在小岛屿内
// 下一次的节点没有遍历过并且为1
queue.add(new int[]{nextX, nextY});
looking[nextX][nextY] = true; // 进入队列就标志看过了
}
}
}
}
return res;
}
}

View File

@ -0,0 +1,62 @@
package cn.whaifree.leetCode.Graph;
import java.util.Scanner;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/19 16:44
* @注释
*/
public class Kama99_2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[][] grid = new int[m][n];
boolean[][] visited = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
grid[i][j] = sc.nextInt();
}
}
int res = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!visited[i][j] && grid[i][j] == 1) {
res++;
visited[i][j] = true;
depth(grid, visited, i, j);
}
}
}
System.out.println(res);
}
static int[][] direct = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public static void depth(int[][] map, boolean[][] visited, int x, int y) {
// 深度优先
for (int i = 0; i < 4; i++) {
int[] ints = direct[i];
int nextX = x + ints[0];
int nextY = y + ints[1];
if (nextX < 0 || nextX >= map.length || nextY < 0 || nextY >= map[0].length) {
continue;
}
if (visited[nextX][nextY]) { // 访问过的不再访问
continue;
}
if (map[nextX][nextY] == 1) {
visited[nextX][nextY] = true;
depth(map, visited, nextX, nextY);
}
}
}
}

View File

@ -0,0 +1,47 @@
package cn.whaifree.leetCode.Graph;
import org.junit.Test;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/17 18:09
* @注释
*/
public class LeetCode797 {
@Test
public void test() {
int[][] graph = {{4,3,1},{3,2,4},{3},{4},{}};
List<List<Integer>> res = new Solution().allPathsSourceTarget(graph);
res.forEach(System.out::println);
}
class Solution {
List<List<Integer>> res = null;
List<Integer> path = null;
public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
res = new java.util.ArrayList<>();
path = new java.util.ArrayList<>();
path.add(0);
dfs(graph, 0);
return res;
}
public void dfs(int[][] graph, int cur) {
if (!path.isEmpty() && graph.length - 1 == path.get(path.size() - 1)) {
res.add(new java.util.ArrayList<>(path));
return;
}
int[] ints = graph[cur];
for (int i = 0; i < ints.length; i++) {
path.add(ints[i]);
dfs(graph, ints[i]); // 0-4
path.remove(path.size() - 1);
}
}
}
}

View File

@ -0,0 +1,394 @@
package cn.whaifree.redo.redo_all_241016;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/19 12:11
* @注释
*/
public class MaiGuPiao {
@Test
public void test() {
int[] prices = {7,1,5,3,6,4};
int max = new LeetCode121().new Solution1().maxProfit(prices);
System.out.println(max);
}
class LeetCode121{
public class Solution {
public int maxProfit(int[] prices) {
int max = 0;
int left = 0;
int right = 0;
while (right < prices.length) {
if (prices[left] > prices[right]) {
left = right;
}
max = Math.max(max, prices[right] - prices[left]);
right++;
}
return max;
}
}
public class Solution1 {
/**
* dp[i][0] 表示第i天手里咩有股票的最大利润
* dp[i][1] 表示手里有股票的最大利润
* - 前一天就有
* - 刚买入因为只能买卖一次所以 0利润-价格
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][2];
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = Math.max(dp[i - 1][1], -prices[i]); // 只能买入卖出一次
}
return dp[prices.length - 1][0];
}
}
public class Solution2 {
/**
* dp[i][0] 表示第i天手里咩有股票的最大利润
* dp[i][1] 表示手里有股票的最大利润
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int noHaveMaxProfit = 0;
int haveMaxProfit = -prices[0];
for (int i = 1; i < prices.length; i++) {
// 必须这个顺序因为需要前一天手里有股票的haveMaxProfit
noHaveMaxProfit = Math.max(noHaveMaxProfit, haveMaxProfit + prices[i]);
haveMaxProfit = Math.max(haveMaxProfit, -prices[i]);
}
return noHaveMaxProfit;
}
}
}
class LeetCode122{
public class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][2];
dp[0][0] = 0;
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return dp[prices.length - 1][0];
}
}
public class Solution1 {
public int maxProfit(int[] prices) {
int noHaveMaxProfit = 0;
int haveMaxProfit = -prices[0];
for (int i = 1; i < prices.length; i++) {
noHaveMaxProfit = Math.max(noHaveMaxProfit, haveMaxProfit + prices[i]);
haveMaxProfit = Math.max(haveMaxProfit, noHaveMaxProfit - prices[i]);
}
return noHaveMaxProfit;
}
}
// 只要上涨价
class Solution2 {
public int maxProfit(int[] prices) {
int res = 0;
for (int i = 1; i < prices.length; i++) {
int sub = prices[i] - prices[i - 1];
if (sub > 0) {
res += sub;
}
}
return res;
}
}
}
class LeetCode123{
public class Solution {
/**
*
* dp[i][1] 表示 第一次手里有股票
* - 前一天就有 dp[i-1][1]
* - 前一天没有今天刚刚买入第一只 dp[i-1][0] - prices[i]
* dp[i][2] 表示 第一次手里没有股票
* - 前一天就没有 dp[i-1][2]
* - 前一天有第一只今天刚刚卖出 dp[i-1][1] + prices[i]
* dp[i][3] 表示 第二次手里有股票
* - 前一天就有第二支股票 dp[i-1][3]
* - 前一天没有第二支股票即前一天没有第一支股票今天刚刚买入 dp[i-1][2] - prices[i]
* dp[i][4] 表示 第二次手里没股票
* - 前一天就没有第二支股票 dp[i-1][4]
* - 前一天有第二支股票今天刚刚卖出 dp[i-1][3] + prices[i]
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][5];
dp[0][1] = -prices[0];
dp[0][2] = 0;
dp[0][3] = -prices[0];
dp[0][4] = 0;
for (int i = 1; i < prices.length; i++) {
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
dp[i][4] = Math.max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
}
return dp[prices.length - 1][4];
}
}
}
@Test
public void test123() {
// [3,3,5,0,0,3,1,4]
int[] prices = {3, 3, 5, 0, 0, 3, 1, 4};
int max = new LeetCode188().new Solution().maxProfit(2, prices);
System.out.println(max);
}
class LeetCode188{
class Solution {
/**
* has[i][j] 表示有第j个股票的最大利润
* noHave[i][j] 表示 没有第j个股票的最大利润
* @param k
* @param prices
* @return
*/
public int maxProfit(int k, int[] prices) {
int[][] has = new int[prices.length][k + 1];
int[][] noHave = new int[prices.length][k + 1];
for (int j = 1; j <= k; j++) {
has[0][j] = -prices[0];
}
for (int i = 1; i < prices.length; i++) {
for (int j = 1; j <= k; j++) {
// 有第j个股票
// - 前一天就有第j个
// - 前一天没有刚刚买入刚刚买入要在前一个状态为手里没有第j-1个股票的情况 ;
has[i][j] = Math.max(has[i - 1][j], noHave[i - 1][j - 1] - prices[i]);
// 前一天就没有第j个股票有股票刚刚卖出
noHave[i][j] = Math.max(noHave[i - 1][j], has[i - 1][j] + prices[i]);
}
}
return noHave[prices.length - 1][k];
}
}
}
@Test
public void testchange() {
int N = 6; // 总天数
int k = 2; // 最多交易次数
double M = 10000; // 初始资金
double[] prices1 = {3, 2, 6, 5, 1, 3}; // 每天的股票价格
double res = new Change().new StockTrading().maxProfit(k, N, M, prices1);
System.out.println("最大利润:" + (res - M));
}
class Change {
public class StockTrading {
public static double maxProfit(int k, int N, double M, double[] prices) {
if (prices == null || prices.length == 0 || k == 0) {
return 0; // 没有交易或者没有股票价格
}
// dp[i][j][l]表示第i天交易了j次l=0表示不持有股票l=1表示持有股票
double[][][] dp = new double[N][k + 1][2];
// 初始化dp数组第一天不持有股票的利润是M持有股票的利润是M - prices[0]假设买入股票
for (int j = 0; j <= k; j++) {
dp[0][j][0] = M; // 第一天不持有股票
dp[0][j][1] = M / prices[0]; // 第一天买入股票
}
// 开始动态规划
for (int i = 1; i < N; i++) {
for (int j = 0; j <= k; j++) {
// 第i天不持有股票的情况
dp[i][j][0] = dp[i-1][j][0]; // 昨天也不持有
if (j > 0) {
dp[i][j][0] = Math.max(dp[i][j][0], dp[i-1][j][1] * prices[i]); // 今天卖出
}
// 第i天持有股票的情况
dp[i][j][1] = dp[i-1][j][1]; // 昨天也持有
if (j > 0) {
dp[i][j][1] = Math.max(dp[i][j][1], dp[i-1][j-1][0] / prices[i]); // 今天买入
}
}
}
// 返回最后一天最多交易k次且不持有股票的最大利润
return dp[N-1][k][0];
}
public static void main(String[] args) {
int N = 6; // 总天数
int k = 2; // 最多交易次数
double M = 10000; // 初始资金
double[] prices = {3, 2, 6, 5, 1, 3}; // 每天的股票价格
System.out.println("最大利润:" + (maxProfit(k, N, M, prices) - M));
}
}
public class StockTrading1 {
// 计算最大利润的方法
public static double maxProfit(double M, int K, double[] prices) {
int N = prices.length; // 获取天数
double[][][] dp = new double[N + 1][K + 1][2]; // 动态规划表
// 初始化基本情况
for (int i = 0; i <= N; i++) {
for (int k = 0; k <= K; k++) {
dp[i][k][0] = 0.0; // 手中没有股票
dp[i][k][1] = -Double.MAX_VALUE; // 不可能的状态
}
}
dp[0][0][0] = M; // 初始资金为M未进行任何交易
// 填充动态规划表
for (int i = 1; i <= N; i++) {
for (int k = 1; k <= K; k++) {
// 今天手中没有股票
dp[i][k][0] = Math.max(dp[i - 1][k][0], dp[i - 1][k][1] + prices[i - 1]);
// 今天手中持有股票
dp[i][k][1] = Math.max(dp[i - 1][k][1], dp[i - 1][k - 1][0] - prices[i - 1]);
}
}
// 返回在最多K次交易且手中没有股票时的最大利润
return dp[N][K][0];
}
}
}
@Test
public void testchange1() {
int N = 6; // 总天数
int k = 2; // 最多交易次数
double M = 10000; // 初始资金
double[] prices1 = {3, 2, 6, 5, 1, 3}; // 每天的股票价格
double res = new Change().new StockTrading1().maxProfit(M, k, prices1);
System.out.println("最大利润:" + (res - M));
}
@Test
public void test309() {
int[] prices = {1, 2, 3, 0, 2};
int max = new LeetCode309().new Solution().maxProfit(prices);
System.out.println(max);
}
class LeetCode309{
class Solution {
/**
* 冷冻
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
if (prices.length < 2) {
return 0;
}
int[][] dp = new int[prices.length][2];
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[1][0] = Math.max(0, prices[1] - prices[0]); // 第一天手里没有股票可能前一天买了今天卖了
dp[1][1] = Math.max(dp[0][1], -prices[1]);// 第1天手里有股票前一天有前一天没有今天买入
for (int i = 2; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
// 没有前一天就没有今天刚刚卖出
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 2][0] - prices[i]);
// 前一天就有今天刚刚买入前一天必须不能买
}
return dp[prices.length - 1][0];
}
}
}
class LeetCode714{
class Solution {
public int maxProfit(int[] prices, int fee) {
int[][] dp = new int[prices.length][2];
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee); // 每次卖出的手续费
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return dp[prices.length - 1][0];
}
}
class Solution1 {
public int maxProfit(int[] prices, int fee) {
// 注意买入的时候就付了手续费
int buy = prices[0] + fee; // 最低买入价钱
int profit = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] + fee < buy) {
// 更新更便宜的买入价钱
buy = prices[i] + fee;
} else if (prices[i] > buy) {
// 当天价格大于买入价格直接买入因为prices[i] + fee < buy存在所以这里一定是获利的
profit += (prices[i] - buy);
buy = prices[i]; // 更新买入价钱
}
}
return profit;
}
}
}
@Test
public void test714() {
int[] prices = {1, 3, 2, 8, 4, 9};
int fee = 2;
int max = new LeetCode714().new Solution().maxProfit(prices, fee);
System.out.println(max);
}
}

View File

@ -0,0 +1,16 @@
package cn.whaifree.tech.demo.dataStruct;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/18 23:42
* @注释
*/
public class CopyAndWriteDemo {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
}
}

View File

@ -0,0 +1,32 @@
package cn.whaifree.tech.demo.java;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/18 21:40
* @注释
*/
public class OOMTest {
// 如果起了 2 个线程当其中一个 OOM 另一个线程会受影响吗?
// -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
public static void main(String[] args) {
// 启动一个线程来模拟内存泄漏
Thread leakThread = new Thread(() -> {
try {
// 使用一个大数组来耗尽内存
while (true) {
// 创建一个大的对象数组
int[] largeArray = new int[10_000_000]; // 10M
Thread.sleep(100); // 暂停一段时间观察 GC
}
} catch (OutOfMemoryError e) {
System.out.println("OutOfMemoryError caught in leakThread.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
leakThread.start();
}
}

View File

@ -1,4 +1,4 @@
package cn.whaifree.tech.thread; package cn.whaifree.tech.demo.thread;
import com.github.phantomthief.pool.KeyAffinityExecutor; import com.github.phantomthief.pool.KeyAffinityExecutor;

View File

@ -1,4 +1,4 @@
package cn.whaifree.tech.thread; package cn.whaifree.tech.demo.thread;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.FileInputStream; import java.io.FileInputStream;

View File

@ -1,4 +1,4 @@
package cn.whaifree.tech.thread; package cn.whaifree.tech.demo.thread;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -1,4 +1,4 @@
package cn.whaifree.tech.thread; package cn.whaifree.tech.demo.thread;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;

View File

@ -1,4 +1,4 @@
package cn.whaifree.tech.thread; package cn.whaifree.tech.demo.thread;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;

View File

@ -1,4 +1,4 @@
package cn.whaifree.tech.thread; package cn.whaifree.tech.demo.thread;
import java.io.IOException; import java.io.IOException;
import java.io.PipedInputStream; import java.io.PipedInputStream;

View File

@ -0,0 +1,31 @@
package cn.whaifree.tech.demo.thread;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/18 22:37
* @注释
*/
public class ThreadPoolInitSize {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 6, 10,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3));
System.out.println(executor);
executor.submit(() -> System.out.println(1));
executor.submit(() -> System.out.println(1));
Thread.sleep(1000);
System.out.println(executor);
/**
* java.util.concurrent.ThreadPoolExecutor@1ddc4ec2[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
* 1 逐渐创建
* 1
* java.util.concurrent.ThreadPoolExecutor@1ddc4ec2[Running, pool size = 2, active threads = 0, queued tasks = 0, completed tasks = 2]
*/
}
}

View File

@ -271,4 +271,36 @@ public class TestCacheThreadPool {
} }
}
class NoFairLock {
public static void main(String[] args) {
// 公平锁和非公平锁的主要区别在于公平锁会检查是否有线程在等待有就直接封装成Node而非公平锁无论如何都会去试一下能不能获取锁
// 公平锁和非公平锁释放的过程是完全一样的都是通知CLH的后继节点
ReentrantLock lock = new ReentrantLock(false);
for (int i = 0; i < 15; i++) {
int finalI = i;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(finalI);
lock.lock();
System.out.println(Thread.currentThread().getName() + " acquired the lock");
// 模拟业务操作
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
System.out.println(Thread.currentThread().getName() + " released the lock");
lock.unlock();
}
}
}, "Thread-" + i).start();
}
}
} }

View File

@ -275,6 +275,37 @@ class mockException{
System.out.println(s); System.out.println(s);
} }
private int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; // 表示四个方向
/**
*
* @param grid 原地板
* @param visited 浏览的点
* @param x 起始位置
* @param y
*/
public void bfs(char[][] grid, boolean[][] visited, int x, int y) {
Queue<int[]> queue = new LinkedList<>(); // 定义队列
queue.offer(new int[]{x, y}); // 起始节点加入队列
visited[x][y] = true; // 只要加入队列立刻标记为访问过的节点
while (!queue.isEmpty()) { // 开始遍历队列里的元素
int[] cur = queue.poll(); // 从队列取元素
int curx = cur[0];
int cury = cur[1]; // 当前节点坐标
for (int i = 0; i < 4; i++) { // 开始想当前节点的四个方向左右上下去遍历
int nextx = curx + dir[i][0];
int nexty = cury + dir[i][1]; // 获取周边四个方向的坐标
if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) continue; // 坐标越界了直接跳过
if (!visited[nextx][nexty]) { // 如果节点没被访问过
queue.offer(new int[]{nextx, nexty}); // 队列添加该节点为下一轮要遍历的节点
visited[nextx][nexty] = true; // 只要加入队列立刻标记避免重复访问
}
}
}
}
} }

View File

@ -0,0 +1,46 @@
package cn.whaifree.tech.demo.java;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/19 22:42
* @注释
*/
public class ExceptionDemo {
@Test
public void testException() {
try {
int a = 1 / 0;
} catch (ArithmeticException e) {
System.out.println("ArithmeticException");
throw new RuntimeException();
} finally {
System.out.println("finally");
}
}
class CustomRuntimeException extends RuntimeException {
}
public void testRuntimeException() {
throw new CustomRuntimeException();
}
@Test
public void testCustomException() throws CustomCheckException {
method();
}
public void method() throws CustomCheckException {
throw new CustomCheckException("自定义异常");
}
class CustomCheckException extends Exception {
public CustomCheckException(String message) {
super(message);
}
}
}

View File

@ -0,0 +1,94 @@
package cn.whaifree.tech.demo.java;
import java.util.ArrayList;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/18 21:40
* @注释
*/
public class OOMTest {
// 如果起了 2 个线程当其中一个 OOM 另一个线程会受影响吗?
// -Xms10m -Xmx20m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
static List<int[]> list = new ArrayList<>();
public static void main(String[] args) {
// 启动一个线程来模拟内存泄漏
Thread leakThread = new Thread(() -> {
try {
// 使用一个大数组来耗尽内存
while (true) {
// 创建一个大的对象数组
int[] largeArray = new int[10_000_00]; // 5M
list.add(largeArray);
Thread.sleep(1000); // 暂停一段时间观察 GC
}
} catch (OutOfMemoryError e) {
e.printStackTrace();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
leakThread.start();
// 启动一个监控线程用于输出 GC 的信息
Thread monitorThread = new Thread(() -> {
while (true) {
try {
// 输出当前的内存使用情况
long totalMemory = Runtime.getRuntime().totalMemory();
long freeMemory = Runtime.getRuntime().freeMemory();
System.out.println("Total Memory: " + (totalMemory / (1024 * 1024)) + " MB");
System.out.println("Free Memory: " + (freeMemory / (1024 * 1024)) + " MB");
System.out.println("Used Memory: " + ((totalMemory - freeMemory) / (1024 * 1024)) + " MB");
// 暂停一段时间获取内存使用信息
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
monitorThread.start();
}
/**
* "C:\Program Files\Java\jdk1.8.0_202\bin\java.exe" -Xms10m -Xmx20m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Dhxl.spring.invoke.port=33333 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2022.3.3\lib\idea_rt.jar=61275:C:\Program Files\JetBrains\IntelliJ IDEA 2022.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_202\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\rt.jar;D:\project\LeetCode\ForJdk8\target\classes;D:\Program Files\apache-maven-3.9.2\repository\javax\persistence\javax.persistence-api\2.2\javax.persistence-api-2.2.jar;D:\Program Files\apache-maven-3.9.2\repository\com\github\phantomthief\simple-pool\0.1.17\simple-pool-0.1.17.jar;D:\Program Files\apache-maven-3.9.2\repository\org\slf4j\slf4j-api\1.7.21\slf4j-api-1.7.21.jar;D:\Program Files\apache-maven-3.9.2\repository\com\google\guava\guava\20.0\guava-20.0.jar;D:\Program Files\apache-maven-3.9.2\repository\com\github\phantomthief\more-lambdas\0.1.27\more-lambdas-0.1.27.jar;D:\Program Files\apache-maven-3.9.2\repository\org\springframework\spring-context\5.3.18\spring-context-5.3.18.jar;D:\Program Files\apache-maven-3.9.2\repository\org\springframework\spring-aop\5.3.18\spring-aop-5.3.18.jar;D:\Program Files\apache-maven-3.9.2\repository\org\springframework\spring-beans\5.3.18\spring-beans-5.3.18.jar;D:\Program Files\apache-maven-3.9.2\repository\org\springframework\spring-core\5.3.18\spring-core-5.3.18.jar;D:\Program Files\apache-maven-3.9.2\repository\org\springframework\spring-jcl\5.3.18\spring-jcl-5.3.18.jar;D:\Program Files\apache-maven-3.9.2\repository\org\springframework\spring-expression\5.3.18\spring-expression-5.3.18.jar;D:\Program Files\apache-maven-3.9.2\repository\cglib\cglib\3.3.0\cglib-3.3.0.jar;D:\Program Files\apache-maven-3.9.2\repository\org\ow2\asm\asm\7.1\asm-7.1.jar;D:\Program Files\apache-maven-3.9.2\repository\cn\hutool\hutool-http\5.8.18\hutool-http-5.8.18.jar;D:\Program Files\apache-maven-3.9.2\repository\cn\hutool\hutool-core\5.8.18\hutool-core-5.8.18.jar;D:\Program Files\apache-maven-3.9.2\repository\junit\junit\4.12\junit-4.12.jar;D:\Program Files\apache-maven-3.9.2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\wenhai\.config\.cool-request\request\lib\spring-invoke-starter.jar" cn.whaifree.tech.demo.java.OOMTest
* 0.117: [GC (Allocation Failure) [PSYoungGen: 2048K->504K(2560K)] 2048K->832K(9728K), 0.0010010 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
* 0.157: [GC (Allocation Failure) [PSYoungGen: 2552K->504K(2560K)] 2880K->1072K(9728K), 0.0008499 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
* Total Memory: 9 MB
* Free Memory: 4 MB
* Used Memory: 4 MB
* Total Memory: 13 MB
* Free Memory: 3 MB
* Used Memory: 9 MB
* 3.187: [GC (Allocation Failure) [PSYoungGen: 1647K->512K(2560K)] 13934K->13274K(16384K), 0.0007103 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
* 3.187: [GC (Allocation Failure) [PSYoungGen: 512K->512K(2560K)] 13274K->13386K(16384K), 0.0005327 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
* 3.188: [Full GC (Allocation Failure) [PSYoungGen: 512K->0K(2560K)] [ParOldGen: 12874K->12989K(13824K)] 13386K->12989K(16384K), [Metaspace: 4673K->4673K(1056768K)], 0.0115695 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
* 3.200: [GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] 12989K->12989K(16384K), 0.0010701 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
* 3.201: [Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 12989K->12899K(13824K)] 12989K->12899K(16384K), [Metaspace: 4673K->4666K(1056768K)], 0.0113301 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
* java.lang.OutOfMemoryError: Java heap space
* at cn.whaifree.tech.demo.java.OOMTest.lambda$main$0(OOMTest.java:25)
* at cn.whaifree.tech.demo.java.OOMTest$$Lambda$1/495053715.run(Unknown Source)
* at java.lang.Thread.run(Thread.java:748)
* Total Memory: 16 MB
* Free Memory: 3 MB
* Used Memory: 12 MB
* Total Memory: 16 MB
* Free Memory: 3 MB
* Used Memory: 12 MB
* Heap
* PSYoungGen total 2560K, used 96K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
* eden space 2048K, 4% used [0x00000000ff980000,0x00000000ff9982b8,0x00000000ffb80000)
* from space 512K, 0% used [0x00000000ffb80000,0x00000000ffb80000,0x00000000ffc00000)
* to space 1536K, 0% used [0x00000000ffe80000,0x00000000ffe80000,0x0000000100000000)
* ParOldGen total 13824K, used 12899K [0x00000000fec00000, 0x00000000ff980000, 0x00000000ff980000)
* object space 13824K, 93% used [0x00000000fec00000,0x00000000ff898f90,0x00000000ff980000)
* Metaspace used 4701K, capacity 4886K, committed 4992K, reserved 1056768K
* class space used 518K, capacity 561K, committed 640K, reserved 1048576K
*
* Process finished with exit code 130
*/
}

View File

@ -0,0 +1,30 @@
package cn.whaifree.tech.demo.java;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/19 22:49
* @注释
*/
public class TestIntAndInteger {
public static void main(String[] args) {
Integer a = new Integer(100);
Integer b = new Integer(100);
System.out.println(a == b);
Integer c = new Integer(100);
int d = 100;
System.out.println(c == d);
Integer e = new Integer(100);
Integer f = 100;
System.out.println(e == f);
Integer g = 100;
Integer h = 100;
System.out.println(g == h);
Integer j = 128;
Integer i = 128;
System.out.println(i == j);
Integer k = 1;
int l = 1;
System.out.println(k == l);
}
}

33
SeleniumDemo/pom.xml Normal file
View File

@ -0,0 +1,33 @@
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.example</groupId>
<artifactId>LeetCode</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>cn.whaifree.selenium</groupId>
<artifactId>SeleniumDemo</artifactId>
<packaging>jar</packaging>
<name>SeleniumDemo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,10 @@
package cn.whaifree.JUnit;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/19 21:06
* @注释
*/
public class JUnitDemo {
}

View File

@ -0,0 +1,13 @@
package cn.whaifree.selenium;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}

View File

@ -0,0 +1,116 @@
package cn.whaifree.selenium;
import cn.whaifree.utils.SeleniumUtils;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import java.util.concurrent.TimeUnit;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/19 20:06
* @注释
*/
public class FirstSeleniumDemo {
public static void main(String[] args) {
SeleniumUtils.init();
findElementDemo("https://www.baidu.com", SeleniumUtils.getWebDriver());
}
public static void findElementDemo(String url,WebDriver driver) {
driver.get(url);
// 通过id进行定位百度搜索框input的id为kw
driver.findElement(By.id("kw"));
// 通过name进行定位百度搜索框input的id为wd
driver.findElement(By.name("wd"));
// 通过class name进行定位百度搜索框input的class name为s_ipt
driver.findElement(By.className("s_ipt"));
// 通过tag name进行定位百度搜索框input的tag name为input
driver.findElement(By.tagName("input"));
// 通过xpath进行定位xpath定位有N种写法这里列几个常用写法
driver.findElement(By.xpath("//*[@id='kw']"));
driver.findElement(By.xpath("//*[@name='wd']"));
driver.findElement(By.xpath("//input[@class='s_ipt']"));
driver.findElement(By.xpath("//form[@id='form']/span/input"));
driver.findElement(By.xpath("//input[@id='kw' and @name='wd']"));
// 通过css进行定位css定位有N种写法这里列几个常用写法
driver.findElement(By.cssSelector("#kw"));
driver.findElement(By.cssSelector("[name=wd]"));
driver.findElement(By.cssSelector(".s_ipt"));
driver.findElement(By.cssSelector("form#form > span > input"));
// 通过link text进行定位定位新闻
driver.findElement(By.linkText("新闻"));
// 通过partialLink text进行定位定位新闻
driver.findElement(By.partialLinkText(""));
driver.close();
}
@Test
public void testControl() throws InterruptedException {
String url = "https://www.baidu.com";
WebDriver driver = SeleniumUtils.getWebDriver();
controlDemo(url,driver);
}
/**
* 控制浏览器操作
* @param url
* @param driver
*/
public static void controlDemo(String url,WebDriver driver) throws InterruptedException {
driver.get(url);
// 设置浏览器的窗口大小为500*300,
driver.manage().window().setSize(new Dimension(500,300));
// 设置浏览器显示位置
driver.manage().window().setPosition(new Point(200,300));
// 访问百度首页
driver.get("http://www.baidu.com");
// 延迟3s
TimeUnit.SECONDS.sleep(3L);
// 设置浏览器最大化
driver.manage().window().maximize();
// 获得输入框的尺寸大小
Dimension dimension = driver.findElement(By.id("kw")).getSize();
System.out.println("搜索框的宽高为:" + dimension.width + " * " + dimension.height);
// 新闻超链接的显示文本
System.out.println("新闻超链接的显示文本:" + driver.findElement(By.partialLinkText("")).getText());
// 搜索框是否用户可见
System.out.println("搜索框是否用户可见:" + driver.findElement(By.id("kw")).isDisplayed());
// 搜索框输入Selenium
driver.findElement(By.id("kw")).sendKeys("Selenium");
// 搜索框的name属性值为
System.out.println("搜索框的name属性值为" + driver.findElement(By.id("kw")).getAttribute("name"));
// 延迟3s
TimeUnit.SECONDS.sleep(3L);
// 清除输入框内容
driver.findElement(By.id("kw")).clear();
// 延迟3s
TimeUnit.SECONDS.sleep(3L);
// 搜索框输入Selenium
driver.findElement(By.id("kw")).sendKeys("Selenium");
// 延迟3s
TimeUnit.SECONDS.sleep(3L);
// 点击百度一下按钮
// driver.findElement(By.id("su")).click();
// 模拟提交
driver.findElement(By.id("kw")).submit();
// 延迟3s
TimeUnit.SECONDS.sleep(3L);
driver.close();
}
}

View File

@ -0,0 +1,36 @@
package cn.whaifree.utils;
import cn.hutool.core.io.FileUtil;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/19 20:14
* @注释
*/
public class SeleniumUtils {
static {
init();
}
public static void init() {
/**
* https://www.cnblogs.com/aiyablog/articles/17948703
*/
// resource 下的chromedriver.class
String property = System.getProperty("user.dir");
String parent = FileUtil.getParent(property, 1);
String chromedriver = parent + "/static/chromedriver.exe";
System.setProperty("webdriver.chrome.driver", chromedriver);
}
public static WebDriver getWebDriver() {
return new ChromeDriver();
}
}

View File

@ -0,0 +1,38 @@
package cn.whaifree.selenium;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}

10
pom.xml
View File

@ -11,8 +11,18 @@
<modules> <modules>
<module>ForJdk8</module> <module>ForJdk8</module>
<module>ForJdk17</module> <module>ForJdk17</module>
<module>SeleniumDemo</module>
</modules> <!--定义了 Maven 项目的打包方式(比如 jarwar...),默认使用 jar。--> </modules> <!--定义了 Maven 项目的打包方式(比如 jarwar...),默认使用 jar。-->
<dependencies>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.13</version>
</dependency>
</dependencies>
<build> <build>
<plugins> <plugins>

View File

@ -0,0 +1,125 @@
package cn.whaifree.springdemo.entity;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/19 22:12
* @注释
*/
@Configuration
@Order(-1)
class Config{
}
@Component("userService")
public class UserService implements InitializingBean, DisposableBean, BeanFactoryAware, ApplicationContextAware, BeanPostProcessor,AutoCloseable {
/**
* 执行 BeanFactoryAware.setBeanFactory
* 执行 ApplicationContextAware.setApplicationContext
* 执行 @PostConstruct
* UserService afterPropertiesSet
* 执行 BeanPostProcessor.postProcessBeforeInitialization
* 执行 BeanPostProcessor.postProcessAfterInitialization
* 执行 @PreDestroy
* UserService destroy
*
* @param args
*/
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("cn.whaifree.springdemo.entity");
UserService userService = context.getBean("userService", UserService.class);
// 执行 DisposableBean
context.close();
}
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行 BeanPostProcessor.postProcessBeforeInitialization");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行 BeanPostProcessor.postProcessAfterInitialization");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("UserService afterPropertiesSet");
}
@Override
public void destroy() throws Exception {
System.out.println("UserService destroy");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("执行 BeanFactoryAware.setBeanFactory");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("执行 ApplicationContextAware.setApplicationContext");
}
@PostConstruct
public void init(){
System.out.println("执行 @PostConstruct");
}
@PreDestroy
public void destroyMethod(){
System.out.println("执行 @PreDestroy");
}
@Override
public void close() throws Exception {
}
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods(java.lang.String, java.lang.Object)
*
* if (bean instanceof Aware) {
* if (bean instanceof BeanNameAware beanNameAware) {
* beanNameAware.setBeanName(beanName);
* }
* if (bean instanceof BeanClassLoaderAware beanClassLoaderAware) {
* ClassLoader bcl = getBeanClassLoader();
* if (bcl != null) {
* beanClassLoaderAware.setBeanClassLoader(bcl);
* }
* }
* if (bean instanceof BeanFactoryAware beanFactoryAware) {
* beanFactoryAware.setBeanFactory(AbstractAutowireCapableBeanFactory.this);
* } * }
*/
}

BIN
static/chromedriver.exe Normal file

Binary file not shown.