diff --git "a/Java\345\237\272\347\241\200.md" "b/Java\345\237\272\347\241\200.md" index 94766a8..4ce55ca 100644 --- "a/Java\345\237\272\347\241\200.md" +++ "b/Java\345\237\272\347\241\200.md" @@ -525,10 +525,15 @@ hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重 #### 51.HashMap有时候会死循环,你知道是什么原因吗? 详见:https://www.cnblogs.com/williamjie/p/11089522.html +1.7版本 +并发后的rehash头插,倒置链表。导致死循环 +1.8之后转为尾插法 #### 52.ConcurrentHashMap是怎么实现的? 详见:https://www.infoq.cn/article/ConcurrentHashMap/ +锁分段技术,将数据一段段存储,然后每一段都分配一把锁,当一个线程占用锁访问这组数据的时候,其余的线程不能访问,达到线程安全的目的。同时不会影响其余分组的线程查询。 +两次hash算法,减少hash冲突,使元素均匀的分布在每个segment,提高容器的存取效率。 #### 53.静态代理和动态代理的区别 diff --git "a/Java\350\231\232\346\213\237\346\234\272.md" "b/Java\350\231\232\346\213\237\346\234\272.md" index 57b9567..d611f8a 100644 --- "a/Java\350\231\232\346\213\237\346\234\272.md" +++ "b/Java\350\231\232\346\213\237\346\234\272.md" @@ -93,7 +93,7 @@ #### 7.JVM怎么判断一个对象是不是要回收? -引用计数法(缺点是对于相互引用的对象,无法进行清除) +引用计数法(缺点是对于相互引用的对象,无法进行清除) 可达性分析 #### 8.GC Roots 有哪些? @@ -210,6 +210,10 @@ App ClassLoader(应用类加载器) 双亲委派机制的意思是除了顶层的启动类加载器以外,其余的类加载器,在加载之前,都会委派给它的父加载器进行加载。这样一层层向上传递,直到祖先们都无法胜任,它才会真正的加载。 +向上查找缓存,向下查找加载路径 + +安全性 + #### 19.双亲委派机制可以被违背吗?请举例说明。 可以被违背。 diff --git a/Mybatis.md b/Mybatis.md index 95aaf0c..ee6b177 100644 --- a/Mybatis.md +++ b/Mybatis.md @@ -176,3 +176,26 @@ https://zhuanlan.zhihu.com/p/60257737 https://www.cnblogs.com/qmillet/p/12523636.html https://blog.csdn.net/a745233700/article/details/80977133 + +Object Relational Mapping + +数据库的执行流程: +1.注册数据库驱动类,指定数据库地址,其中包括 DB 的用户名、密码及其他连接信息; +2.调用 DriverManager.getConnection() 方法创建 Connection 连接到数据库; +3.调用 Connection 的 createStatement() 或 prepareStatement() 方法,创建 Statement 对象,此时会指定 SQL(或是 SQL 语句模板 + SQL 参数); +4.通过 Statement 对象执行 SQL 语句,得到 ResultSet 对象,也就是查询结果集; +5.遍历 ResultSet,从结果集中读取数据,并将每一行数据库记录转换成一个 JavaBean 对象; +6.关闭 ResultSet 结果集、Statement 对象及数据库 Connection,从而释放这些对象占用的底层资源 + + +mybatis 三层架构: +1.基础支撑层 + 类型转化模块,日志模块(适配器模块),反射工具模块,binding模块,数据源模块,缓存模块,解析器模块,事务管理模块 +2.核心处理层 + 配置解析,sql解析与scripting模块,sql执行,插件 +3.接口层 + 接口层是mybatis暴露给调用的接口集合,包括sqlSession,sqlSessionFactory + +Reflector 是 MyBatis 反射模块的基础 + + \ No newline at end of file diff --git a/Redis.md b/Redis.md index 0f915da..b935398 100644 --- a/Redis.md +++ b/Redis.md @@ -75,7 +75,7 @@ Remote Dictionary Server。 1、内存操作; 2、单线程,省去线程切换、锁竞争的开销; -3、非阻塞IO模型,epoll。 +3、非阻塞IO模型,epoll。 epoll 多路复用器,不负责数据的读写,负责读写事件的管理 #### 8.Redis如何实现分布式锁? @@ -83,8 +83,11 @@ Remote Dictionary Server。 #### 9.Redis是单线程还是多线程? +执行命令的一直都是单线程 + Redis6.0采用多线程IO,不过命令的执行还是单线程的。 Redis6.0之前,IO线程和执行线程都是单线程的。 +io模型编程 #### 10.Redis 官方为什么不提供 Windows 版本? @@ -111,10 +114,15 @@ Redis集群目前无法做数据库选择,默认在0数据库。 #### 14.缓存失效?缓存穿透?缓存雪崩?缓存并发? 1. 缓存失效 - 缓存失效指的是大量的缓存在同一时间失效,到时DB的瞬间压力飙升。造成这种现象的原因是,key的过期时间都设置成一样了。解决方案是,key的过期时间引入随机因素,比如5分钟+随机秒这种方式。 + 缓存失效指的是大量的缓存在同一时间失效,到时DB的瞬间压力飙升。造成这种现象的原因是,key的过期时间都设置成一样了。 + + 解决方案: + key的过期时间引入随机因素,比如5分钟+随机秒这种方式。 2. 缓存穿透 缓存穿透是指查询一条数据库和缓存都没有的一条数据,就会一直查询数据库,对数据库的访问压力就会增大,缓存穿透的解决方案,有以下2种: + + 解决方案: 缓存空对象:代码维护较简单,但是效果不好。 布隆过滤器:代码维护复杂,效果很好。 @@ -123,13 +131,16 @@ Redis集群目前无法做数据库选择,默认在0数据库。 造成缓存雪崩的原因,有以下2种: reids宕机。 大部分数据失效。 + + 解决方案: + 对于缓存雪崩的解决方案有以下2种: + 搭建高可用的集群,防止单机的redis宕机。 + 设置不同的过期时间,防止同意之间内大量的key失效。 -对于缓存雪崩的解决方案有以下2种: -搭建高可用的集群,防止单机的redis宕机。 -设置不同的过期时间,防止同意之间内大量的key失效。 - -4. 缓存并发 +4. 缓存并发(缓存击穿) 有时候如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。 + + 解决方案: 一般处理方案是在查DB的时候进行加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后再查缓存或者进入DB查询。 #### 15.Redis中的热key怎么处理? @@ -176,6 +187,22 @@ unwatch : 取消watch对所有key的监控 8种:noeviction,volatile-lru,volatile-lfu,volatile-ttl,volatile-random,allkey-lru,allkeys-lfu,allkeys-random +1. noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键 + +2. allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键 + +3. volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键 + +4. allkeys-random:加入键的时候如果过限,从所有key随机删除 + +5. volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐 + +6. volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键 + +7. volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键 + +8. allkeys-lfu:从所有键中驱逐使用频率最少的键 + #### 20.Redis在什么情况下会触发key的回收? 2种情况:1、定时(抽样)清理;2、执行命令时,判断内存是否超过maxmemory。 @@ -288,5 +315,5 @@ Redisson是一个高级的分布式协调Redis客服端,能帮助用户在分 #### 参考链接 http://blog.itpub.net/31545684/viewspace-2213990/ - -https://blog.csdn.net/weixin_34081595/article/details/92420220 + +https://blog.csdn.net/weixin_34081595/article/details/92420220 diff --git a/RocketMQ.md b/RocketMQ.md index ba989eb..5e1fb4b 100644 --- a/RocketMQ.md +++ b/RocketMQ.md @@ -109,7 +109,7 @@ SelectMessageQueueByMachineRoom 没有实现 #### 8.如何让RocketMQ保证消息的顺序消费? -首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,天然顺序。多个queue同时消费是无法绝对保证消息的有序性的。所以总结如下: +首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,天然顺序。多个queue 同时消费是无法绝对保证消息的有序性的。所以总结如下: 同一topic,同一个QUEUE,发消息的时候一个线程去发送消息,消费的时候 一个线程去消费一个queue里的消息。 diff --git a/demo/eight/Demo.java b/demo/eight/Demo.java new file mode 100644 index 0000000..91fed8a --- /dev/null +++ b/demo/eight/Demo.java @@ -0,0 +1,19 @@ +package eight; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class Demo { + + public static void main(String[] args) { + List list = new ArrayList<>(); + list.add("ceshi"); + + HashMap map = new HashMap(); + map.put("ceshi","ceshi"); + + System.out.println(list.toString()); + System.out.println(map.toString()); + } +} diff --git a/demo/eight/GuessSize.java b/demo/eight/GuessSize.java new file mode 100644 index 0000000..4319e19 --- /dev/null +++ b/demo/eight/GuessSize.java @@ -0,0 +1,47 @@ +package eight; + +/** + * @author aday + * @date 2022/9/21 10:25 + * description : + */ +public class GuessSize { + + static int bet = 10000; + + public static void main(String[] args) { + int money = 1000000; + int num = 0; + int last = money; + while (last > 0) { + num ++ ; + System.out.println("赌博次数:" + num); + last = start(last); + } + } + + //赌博 + public static int start(int money) { + Boolean b = guess(); + if (b) { + money = money + bet; + bet = 10000; + System.out.println(" 结果 赢了," + " 剩余本金:" + money + "下次赌注:" + bet); + } else { + money = money - bet; + bet = bet * 2; + System.out.println(" 结果 输了," + " 剩余本金:" + money + "下次赌注:" + bet); + } + return money; + } + + //猜大小 + public static Boolean guess() { + double result = Math.random(); + if (result <= 0.5) { + return false; + } else { + return true; + } + } +} diff --git a/demo/eight/HashMapDemo.java b/demo/eight/HashMapDemo.java new file mode 100644 index 0000000..64ba7ff --- /dev/null +++ b/demo/eight/HashMapDemo.java @@ -0,0 +1,23 @@ +package eight; + +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; + +public class HashMapDemo { + public static void main(String[] args) { + HashMap hashMap = new HashMap(); + + new Thread(()->{hashMap.put("测试1","测试");}).start(); + new Thread(()->{hashMap.put("测试2","测试");}).start(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(hashMap.keySet().toString()); + + ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap(); + concurrentHashMap.put("线程安全","a"); + concurrentHashMap.get("线程安全"); + } +} diff --git a/demo/eight/LockDemo.java b/demo/eight/LockDemo.java new file mode 100644 index 0000000..0aa2671 --- /dev/null +++ b/demo/eight/LockDemo.java @@ -0,0 +1,15 @@ +package eight; + +/** + * @author Lenovo + * 轻量级锁 自旋 cap 占用 cpu 资源 + * 重量级锁 进入队列不用占用cpu资源 + */ +public class LockDemo { + + /** + * 轮询,优先级,cfs complate + */ + + +} diff --git a/demo/eight/ObjectDemo.java b/demo/eight/ObjectDemo.java new file mode 100644 index 0000000..0bf4fb9 --- /dev/null +++ b/demo/eight/ObjectDemo.java @@ -0,0 +1,48 @@ +package eight; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author aday + * @date 2022/9/22 15:12 + * description : + */ +public class ObjectDemo { + + public static void main(String[] args) { + A a = new A(); + List list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + a.setName("测试:" + i); + list.add(a); + } + for (A a1 : list) { + System.out.println(a1); + } + + } + +} + +class A { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public A() { + } + + @Override + public String toString() { + return "A{" + + "name='" + name + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/demo/eleven/MyThread.java b/demo/eleven/MyThread.java new file mode 100644 index 0000000..508c08a --- /dev/null +++ b/demo/eleven/MyThread.java @@ -0,0 +1,29 @@ +package eleven; + +/** + * @author Lenovo + */ +public class MyThread extends Thread { + + private volatile boolean flag = false; + + @Override + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // 修改变量值 + flag = true; + System.out.println("flag = " + flag); + } + + public boolean isFlag() { + return flag; + } + + public void setFlag(boolean flag) { + this.flag = flag; + } +} diff --git a/demo/eleven/StreamTest.java b/demo/eleven/StreamTest.java new file mode 100644 index 0000000..09627c1 --- /dev/null +++ b/demo/eleven/StreamTest.java @@ -0,0 +1,19 @@ +package eleven; + +import java.util.Optional; +import java.util.stream.Stream; + +public class StreamTest { + + public static void main(String[] args) { + // 找出最长的单词 + Stream stream = Stream.of("I", "love", "you", "too"); + Optional longest = stream.reduce((s1, s2) -> s1.length() >= s2.length() ? s1 : s2); + //Optional longest = stream.max((s1, s2) -> s1.length()-s2.length()); + System.out.println(longest.get()); + // 求单词长度之和 + Stream stream1 = Stream.of("I", "love", "you", "too"); + Integer lengthSum = stream1.reduce(0, (sum, str) -> sum + str.length(), (a, b) -> a + b); + System.out.println(lengthSum); + } +} diff --git a/demo/eleven/VolatileExample.java b/demo/eleven/VolatileExample.java new file mode 100644 index 0000000..d16227c --- /dev/null +++ b/demo/eleven/VolatileExample.java @@ -0,0 +1,25 @@ +package eleven; + +/** + * @author Lenovo + */ +public class VolatileExample { + + /** + * main 方法作为一个主线程 + */ + public static void main(String[] args) { + MyThread myThread = new MyThread(); + // 开启线程 + myThread.start(); + + // 主线程执行 + for (; ; ) { + if (myThread.isFlag()) { + System.out.println("主线程访问到 flag 变量"); + } + } + } + +} + diff --git a/demo/eleven/pdf.java b/demo/eleven/pdf.java new file mode 100644 index 0000000..eb2c740 --- /dev/null +++ b/demo/eleven/pdf.java @@ -0,0 +1,11 @@ +package eleven; + +/** + * @author aday + * @date 2022/9/22 16:31 + * description : pdf识别 + */ +public class pdf { + + +} diff --git a/demo/five/DoubleTest.java b/demo/five/DoubleTest.java new file mode 100644 index 0000000..60f9bd8 --- /dev/null +++ b/demo/five/DoubleTest.java @@ -0,0 +1,18 @@ +package five; + +public class DoubleTest { + + + public static void main(String[] args) { + float a = 3.0f; + float c = 2.96f; + double e = 3.0000000000000000000000000000000; + float d = a - c; //0.040000000000000036 0.03999996 + float d2 = 0.04f - 0.039f; + System.out.println(d); // 输出 0.3999999999999999 + System.out.println(d2); // 输出 1.1102230246251565E-16 + System.out.println(d2 > 0); // 输出true + } + + +} diff --git a/demo/five/Solution001.java b/demo/five/Solution001.java new file mode 100644 index 0000000..984b2d9 --- /dev/null +++ b/demo/five/Solution001.java @@ -0,0 +1,28 @@ +package five; + +/** + * 给定一个二叉树,检查它是否是镜像对称的。 + * @author Lenovo + */ +public class Solution001 { + public static void main(String[] args) { + + } + + public boolean isSymmetric(TreeNode root) { + if (root == null) { + return false; + } + return isSymmetricHelper(root.getLeft(), root.getRight()); + } + + public boolean isSymmetricHelper(TreeNode left, TreeNode right) { + if (right == null && left == null) { + return true; + } + if (right == null || left == null || left.getVal() != right.getVal()) { + return false; + } + return isSymmetricHelper( left.getLeft(),right.getRight()) && isSymmetricHelper(left.getRight(), right.getLeft()); + } +} diff --git a/demo/five/Solution002.java b/demo/five/Solution002.java new file mode 100644 index 0000000..28745ce --- /dev/null +++ b/demo/five/Solution002.java @@ -0,0 +1,17 @@ +package five; + +/** + * @author Lenovo + */ +public class Solution002 { + + static int a = 100; + + public static void main(String[] args) { + a = ~a; + int b = 128; + b = b >> 1; + System.out.println(a); + System.out.println(b); + } +} diff --git a/demo/five/Solution003.java b/demo/five/Solution003.java new file mode 100644 index 0000000..5c10e4a --- /dev/null +++ b/demo/five/Solution003.java @@ -0,0 +1,42 @@ +package five; + +import java.util.HashSet; + +/** + * 请你判断一个9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 + * + * 数字1-9在每一行只能出现一次。 + * 数字1-9在每一列只能出现一次。 + * 数字1-9在每一个以粗实线分隔的3x3宫内只能出现一次。(请参考示例图) + * 数独部分空格内已填入了数字,空白格用'.'表示。 + * + */ +public class Solution003 { + + public static void main(String[] args) { + + } + + public boolean isValidSudoku(char[][] board) { + for(int i = 0;i < 9;i++){ + HashSet setLine = new HashSet(); + HashSet setCol = new HashSet(); + HashSet setBox = new HashSet(); + for (int j = 0; j < 9; j++) { + if(board[i][j] != '.' &&!setLine.add(board[i][j])){ + return false; + } + if(board[j][i] != '.' && !setCol.add(board[j][i])){ + return false; + } + int a = (i/3)*3 + j/3; + int b = (i%3)*3 + j%3; + if(board[a][b] != '.' && !setBox.add(board[a][b])){ + return false; + } + } + } + return true; + } + +} diff --git a/demo/five/Solution004.java b/demo/five/Solution004.java new file mode 100644 index 0000000..5334427 --- /dev/null +++ b/demo/five/Solution004.java @@ -0,0 +1,25 @@ +package five; + +/** + * @author Lenovo + */ +public class Solution004 { + + public static void main(String[] args) { + //0000 0000 0000 0000 0000 0000 0000 1010 + int a = 10; + //0000 0000 0000 0000 0000 0000 0000 1111 + int b = 15; + //1111 1111 1111 1111 1111 1111 1111 0101 反码 + //1111 1111 1111 1111 1111 1111 1111 0110 补码 + //取反 + // + System.out.println(~a); + System.out.println(a^b); + System.out.println(b|a); + System.out.println(a&b); + System.out.println(10+(-10)); + + } + +} diff --git a/demo/five/Test.java b/demo/five/Test.java new file mode 100644 index 0000000..897b091 --- /dev/null +++ b/demo/five/Test.java @@ -0,0 +1,24 @@ +package five; + +import java.util.Hashtable; + +/** + * @author Lenovo + */ +public class Test { + + public static void main(String[] args) { + String a = "a"; + String b = "b"; + String ab = "ab"; + String sbtemp = a + b ; + final String m = new String("a"); + Hashtable hashtable = new Hashtable(); + + System.out.println(sbtemp); + } + +} + + + diff --git a/demo/five/TreeNode.java b/demo/five/TreeNode.java new file mode 100644 index 0000000..33321ad --- /dev/null +++ b/demo/five/TreeNode.java @@ -0,0 +1,38 @@ +package five; + +/** + * @author Lenovo + */ +public class TreeNode { + + private Object val; + private TreeNode left; + private TreeNode right; + + public TreeNode() { + } + + public Object getVal() { + return val; + } + + public void setVal(Object val) { + this.val = val; + } + + public TreeNode getLeft() { + return left; + } + + public void setLeft(TreeNode left) { + this.left = left; + } + + public TreeNode getRight() { + return right; + } + + public void setRight(TreeNode right) { + this.right = right; + } +} diff --git a/demo/four/ListNode.java b/demo/four/ListNode.java new file mode 100644 index 0000000..bc77ee6 --- /dev/null +++ b/demo/four/ListNode.java @@ -0,0 +1,20 @@ +package four; + +/** + * @author Lenovo + */ +public class ListNode { + + int val; + + ListNode next; + + ListNode(int val) { + this.val = val; + } + + ListNode(int val, ListNode next) { + this.val = val; + this.next = next; + } +} \ No newline at end of file diff --git a/demo/four/Solution.java b/demo/four/Solution.java new file mode 100644 index 0000000..c99b135 --- /dev/null +++ b/demo/four/Solution.java @@ -0,0 +1,16 @@ +package four; + +public class Solution { + + public static void main(String[] args) { + + } +/* +* 给你一个整数数组 nums 。你可以选定任意的 正数 startValue 作为初始值。 + +你需要从左到右遍历 nums 数组,并将 startValue 依次累加上 nums 数组中的值。 + +请你在确保累加和始终大于等于 1 的前提下,选出一个最小的 正数 作为 startValue 。 +*/ + +} \ No newline at end of file diff --git a/demo/four/Solution001.java b/demo/four/Solution001.java new file mode 100644 index 0000000..0a3aa87 --- /dev/null +++ b/demo/four/Solution001.java @@ -0,0 +1,31 @@ +package four; + +/** + * 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。 + * + * 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 + * + */ +public class Solution001 { + + static int removeDuplicates(int[] nums) { + int left = nums[0]; + int right = nums[0]; + int temp = 1; + for (int a = 0; a < nums.length; a++) { + right = nums[a]; + if (left < right) { + left = right; + nums[temp] = left; + temp ++; + } + + } + return temp; + } + + public static void main(String[] args) { + int[] temp = {1,1,2}; + System.out.println(removeDuplicates(temp)); + } +} diff --git a/demo/four/Solution002.java b/demo/four/Solution002.java new file mode 100644 index 0000000..76381c2 --- /dev/null +++ b/demo/four/Solution002.java @@ -0,0 +1,47 @@ +package four; + +/** + * 给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。 + * + * 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 + * + * 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 + * + */ +public class Solution002 { + + + public static void main(String[] args) { + int[] prices = {7,6,4,3,1}; + System.out.println(maxProfit(prices)); + } + + static int maxProfit(int[] prices) { + if (prices.length <= 0) { + return 0; + } + int left = prices[0]; + int maxRight = 0; + int max = 0; + int temp = 0; + int right; + for (int i = 0; i <= prices.length; i++) { + if (i == prices.length) { + right = 0; + } else { + right = prices[i]; + } + if (right > left && right > maxRight) { + maxRight = right; + temp = right - left; + } else { + max = max + temp; + left = right; + maxRight = right; + } + } + return max; + } + + +} \ No newline at end of file diff --git a/demo/four/Solution003.java b/demo/four/Solution003.java new file mode 100644 index 0000000..a5aff29 --- /dev/null +++ b/demo/four/Solution003.java @@ -0,0 +1,49 @@ +package four; + +/** + * @author Lenovo + */ +public class Solution003 { + + public static void main(String[] args) { + int[] ints = {1,2,3,4,5,6,7,8}; + System.out.println(rotate(ints,3)); + //System.out.println(rotate1(ints,3)); + System.out.println(8%7); + } + + static int[] rotate(int[] nums, int k) { + int lengthOld = nums.length; + for (;;){ + if (k > lengthOld){ + k = k-lengthOld; + }else { + break; + } + } + int tempArray[] = new int[lengthOld]; + for(int a = 0 ;a T getProxyObject(Class clazz){ + JdkProxy proxy = null; + try { + proxy = new JdkProxy(clazz.getDeclaredConstructor().newInstance()); + //jdk dynamic proxy 只能针对实现了接口的类进行代理, newProxyInstance 函数需要的参数就可以看出 + T proxied = (T) Proxy.newProxyInstance(JdkDynamicObjectFactory.class.getClassLoader(), + clazz.getInterfaces(),proxy + ); + return proxied; + }catch (Exception e){ + e.printStackTrace(); + } + return null; + } + + public static void main(String[] args) { + InterfaceDemo interfaceImpl = JdkDynamicObjectFactory.getProxyObject(InterfaceImpl.class); + interfaceImpl.getName(); + } + +} diff --git a/demo/nine/JdkProxy.java b/demo/nine/JdkProxy.java new file mode 100644 index 0000000..9fc8d4b --- /dev/null +++ b/demo/nine/JdkProxy.java @@ -0,0 +1,33 @@ +package nine; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * @author Lenovo + */ +public class JdkProxy implements InvocationHandler { + + Object target; + + public JdkProxy(Object target) { + this.target = target; + } + + /** + * 核心 + * @param proxy + * @param method + * @param args + * @return + * @throws Throwable + */ + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + System.out.println("jdk dynamic before ..."); + Object object = method.invoke(target,args); + System.out.println("jdk dynamic after ..."); + return object; + } + +} diff --git a/demo/nine/UUIDTest.java b/demo/nine/UUIDTest.java new file mode 100644 index 0000000..1185552 --- /dev/null +++ b/demo/nine/UUIDTest.java @@ -0,0 +1,60 @@ +package nine; + +import java.util.UUID; + +/** + * @author Lenovo + */ +public class UUIDTest { + + public static void main(String[] args) { + /** + * 优点: + * 生产足够简单,本地生产无网络消耗,具有唯一性 + * 缺点: + * 无序的字符串,不具备趋势自增性 + * 没有具体的业务含义 + * 长度过长,存储mysql 对数据库的性能消耗比较大 + */ + String uuid = UUID.randomUUID().toString().replace("-",""); + System.out.println(uuid); + + /** + * 基于数据库自增的id + * 优点:实现简单,id单调自增,数值类型查询速度快 + * 缺点:DB单点存储存在宕机风险,无法扛住高并发场景 + */ + + /** + * 基于数据库集群模式 + * 优点:解决DB单点的问题 + * 缺点:不利于后续扩充 + */ + + /** + * 基于数据库的号段模式 + * 采用版本号乐观锁的方式更新,这种分布式id生产方式不强依赖于数据库,不会频繁的访问数据库,对数据库压力小很多 + */ + + /** + * 基于redis模式: + * 受redis 持久化影响 aof 和 rdb + * 优点: + * 缺点: + */ + + /** + * 基于雪花算法: + * + */ + + /** + * 百度 + */ + + /** + * 美团 + */ + + } +} diff --git a/demo/one/Demo.java b/demo/one/Demo.java new file mode 100644 index 0000000..883a3c0 --- /dev/null +++ b/demo/one/Demo.java @@ -0,0 +1,41 @@ +package one; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Demo { + + public static void main(String[] args) { + String oldString = "adfaadfa3156464.1316adsfa卧.槽dfa4adf1af32as1df32a1sd56fa1sd32f1a321fdsf2a31"; + String[] test = oldString.split("[^0-9|.]"); + List list = new ArrayList<>(); + for (String s :test){ + if (s!=null && !s.isEmpty() && !".".equals(s)){ + BigDecimal temp = new BigDecimal(s); + list.add(temp); + } + } + System.out.println(list); + + + String regin="\\d+(?:\\.\\d+)?"; + Matcher m=Pattern.compile(regin, Pattern.MULTILINE).matcher(oldString); + List result=new ArrayList<>(); + while (m.find()){ + result.add(m.group()); + } + System.out.println(result); + + String regin1="[^0-9|.]"; + Matcher m1=Pattern.compile(regin1, Pattern.MULTILINE).matcher(oldString); + List result1=new ArrayList<>(); + while (m1.find()){ + result.add(m1.group()); + } + System.out.println(result1); + + } +} diff --git a/demo/one/JsonCore.java b/demo/one/JsonCore.java new file mode 100644 index 0000000..6317947 --- /dev/null +++ b/demo/one/JsonCore.java @@ -0,0 +1,16 @@ +package one; + +import com.alibaba.fastjson.JSON; + +/** + * @author Lenovo + */ +public class JsonCore { + + public static void main(String[] args) { + Cat cat = new Cat(); + cat.name = "张三"; + String jsonOutput= JSON.toJSONString(cat); + System.out.println(cat); + } +} diff --git a/demo/one/Sort.java b/demo/one/Sort.java new file mode 100644 index 0000000..7334ccb --- /dev/null +++ b/demo/one/Sort.java @@ -0,0 +1,38 @@ +package one; + +/** + * @author Lenovo + */ +public class Sort { + + public static Integer[] a = new Integer[]{1, 10, 3, 6, 2, 7, 5, 4}; + + /** + * 快速排序 + * @return + */ + private static Integer[] sort1() { + return a; + } + + private static Integer[] sort2() { + return a; + } + + private static Integer[] sort3() { + return a; + } + + public static void main(String[] args) { + Integer[] temp = sort1(); + print(temp); + } + + private static void print(Integer[] temp) { + System.out.print("开始排序:"); + for (Integer c : temp) { + System.out.print(c); + System.out.print("__"); + } + } +} diff --git a/demo/one/StreamTest.java b/demo/one/StreamTest.java new file mode 100644 index 0000000..a9ec820 --- /dev/null +++ b/demo/one/StreamTest.java @@ -0,0 +1,60 @@ +package one; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class StreamTest { + + public static void main(String[] args) { + System.out.println("empty:" + Stream.empty().collect(Collectors.toList())); + System.out.println("ofInteger:" + Stream.of(new Integer[]{1, 2, 3}).max(Comparable::compareTo).get()); + System.out.print("ofString:"); + Stream.of("2", "3", "2", "1", "1").distinct().sorted().forEach(System.out::print); + System.out.println(); + System.out.println(Stream.generate(() -> "" + Math.random()).limit(2).collect(Collectors.joining())); + System.out.println(Stream.iterate(BigInteger.valueOf(0L), x -> x.add(BigInteger.valueOf(1L))) + //注意,这里的skip和limit的顺序调换后的结果是不同的 + .skip(3).limit(10) + .filter(x -> x.longValue() > 6 && x.longValue() < 14) + .collect(Collectors.toList()) + ); + System.out.println(Arrays.stream(new String[]{"a", "b", "c"}).collect(Collectors.joining())); + System.out.println(Arrays.stream(new Integer[]{1, 2, 4, 6, 7}, 1, 4).count()); + + //map + System.out.println(Stream.of(1, 2, 3, 4).map(x -> x * 2).collect(Collectors.toList())); + IntStream intStream = Stream.of("1", "2", "3").mapToInt(Integer::parseInt); + System.out.println(intStream.toArray()[2]); + System.out.println(Stream.of(new String[]{"1", "2"}, new String[]{"2", "4"}, new String[]{"3"}).flatMap(x -> Stream.of(x)).collect(Collectors.toSet())); + + + int f = 201; + int b = 10; + System.out.println(Math.ceil(f/b)); + + List result = new ArrayList<>(); + for (int i = 1 ;i <500; i ++){ + result.add("ceshi"+ i); + } + if (result.size()>0){ + //一次500条 + int applyIdSelectSize = 100; + int limit = (result.size() + applyIdSelectSize - 1) / applyIdSelectSize; + //分成limit次发请求到数据库,in()操作时 可以把多条数据分割成多组请求 + Stream.iterate(0, n -> n + 1).limit(limit).forEach(a -> { + //获取后面1000条中的前500条 + // 拿到这个参数的流的 (a * applyIdSelectSize)后面的数据 .limit(applyIdSelectSize)->后面数据的500条 .collect(Collectors.toList()->组成一个toList + List paperEntityList = result.stream().skip(a * applyIdSelectSize).limit(applyIdSelectSize).collect(Collectors.toList()); + System.out.println(paperEntityList.size()); + }); + System.out.println("数据解析入库成功!!"); + } + + + } +} diff --git a/demo/one/Symbol.java b/demo/one/Symbol.java new file mode 100644 index 0000000..e3060c0 --- /dev/null +++ b/demo/one/Symbol.java @@ -0,0 +1,16 @@ +package one; + +public class Symbol { + + public static void main(String[] args) { + String temp = "中国人"; + char[] src = temp.toCharArray(); + char[] result = new char[temp.length()]; + for (int a = 0 ; a { + int count = 1; + for (int i = 0; i < 1000; i++) { + ++count; + System.out.println(count); + } + System.out.println(count); + }).start();*/ + + AtomicInteger au = new AtomicInteger(0); + for (int i = 1; i < 1000; i++) { + new Thread(() -> { + au.getAndAdd(1); + }).start(); + } + try { + Thread.sleep(1000); + System.out.println("auto 数据 :" + au); + }catch (Exception e){ + e.printStackTrace(); + } + } +} diff --git a/demo/seven/SonAndFather.java b/demo/seven/SonAndFather.java new file mode 100644 index 0000000..1aff6e7 --- /dev/null +++ b/demo/seven/SonAndFather.java @@ -0,0 +1,37 @@ +package seven; + +public class SonAndFather { + public static void main(String[] args) { + Son a = new Son(); + a.setName("儿子"); + System.out.println(a.getName()); + } + +} + +class Father { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + +class Son extends Father { + + private String name; + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } +} diff --git a/demo/seven/SubList.java b/demo/seven/SubList.java new file mode 100644 index 0000000..203bca2 --- /dev/null +++ b/demo/seven/SubList.java @@ -0,0 +1,18 @@ +package seven; + +import java.util.ArrayList; +import java.util.List; + +public class SubList { + public static void main(String[] args) { + List list = new ArrayList<>(); + list.add("1"); + list.add("2"); + list.add("3"); + list.add("4"); + list.add("5"); + list.add("6"); + list = list.subList(0,5); + System.out.println(list.toString()); + } +} diff --git a/demo/six/Atomic.java b/demo/six/Atomic.java new file mode 100644 index 0000000..581b077 --- /dev/null +++ b/demo/six/Atomic.java @@ -0,0 +1,55 @@ +package six; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author Lenovo + */ +public class Atomic { + static int num = 1; + + public static void main(String[] args) { + AtomicInteger a = new AtomicInteger(1); + Object o1 = new Object(); + boolean b = true; + new Thread(new Runnable() { + @Override + public void run() { + for (int i = 0; i < 50; i++) { + synchronized (o1) { + try { + ++num; + System.out.println(Thread.currentThread().getName() + " :" + num); + o1.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + }, "a线程").start(); + + new Thread(new Runnable() { + @Override + public void run() { + for (int i = 0; i < 50; i++) { + synchronized (o1) { + num++; + System.out.println(Thread.currentThread().getName() + " :" + num); + o1.notify(); + } + try { + //让出 cpu 执行权限 + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + } + }, "b线程").start(); + } + + + +} diff --git a/demo/six/Client.java b/demo/six/Client.java new file mode 100644 index 0000000..4dc0d39 --- /dev/null +++ b/demo/six/Client.java @@ -0,0 +1,25 @@ +package six; + +/** + * @author Lenovo + */ +public class Client { + + /** + * 这是一个异步方法,返回的Data接口是一个Future + */ + public Data request(String queryStr) { + final FutureData future = new FutureData(); + new Thread() { + @Override + public void run() { + // RealData的构建很慢,所以在单独的线程中进行 + RealData realdata = new RealData(queryStr); + //setRealData()的时候会notify()等待在这个future上的对象 + future.setRealData(realdata); + } + }.start(); + // FutureData会被立即返回,不会等待RealData被构造完 + return future; + } +} diff --git a/demo/six/CompletableDemo.java b/demo/six/CompletableDemo.java new file mode 100644 index 0000000..9ac7156 --- /dev/null +++ b/demo/six/CompletableDemo.java @@ -0,0 +1,82 @@ +package six; + +import java.util.concurrent.CompletableFuture; + +/** + * @author Lenovo + */ +public class CompletableDemo { + + private static Object object = new Object(); + + public static void main(String[] args) throws Exception { + String talk1 = "小王"; + String talk2 = "小李"; + + long start = System.currentTimeMillis(); + CompletableFuture.supplyAsync(CompletableDemo::input) + .thenAccept( + result -> { + System.out.println(result); + synchronized (object) { + object.notifyAll(); + } + } + ) + .exceptionally(throwable -> { + throwable.printStackTrace(); + return null; + }); + synchronized (object) { + object.wait(); + } + + new Thread(new Runnable() { + @Override + public void run() { + try { + synchronized (object) { + /** + * 线程进入等待队列 + */ + object.wait(); + } + Thread.sleep(1000); + System.out.println("是谁在说话:" + talk1); + } catch (Exception e) { + e.printStackTrace(); + } + } + }).start(); + + new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(2000); + synchronized (object) { + object.notify(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("是谁在说话:" + talk2); + } + }).start(); + + Thread.sleep(4000); + System.out.println("程序执行完成,耗时:" + (System.currentTimeMillis() - start)); + } + + public static String input() { + try { + Thread.sleep(5000); + } catch (Exception e) { + e.printStackTrace(); + } + String result = "这个人说了五秒钟"; + return result; + } + + +} diff --git a/demo/six/CountDownLuntchTest.java b/demo/six/CountDownLuntchTest.java new file mode 100644 index 0000000..aca46a3 --- /dev/null +++ b/demo/six/CountDownLuntchTest.java @@ -0,0 +1,46 @@ +package six; + +import java.util.concurrent.CountDownLatch; + +public class CountDownLuntchTest { + + public static void main(String[] args) { + Long start = System.currentTimeMillis(); + CountDownLatch downLatch = new CountDownLatch(2); + new Thread(new Runnable() { + @Override + public void run() { + // 逻辑执行五秒 + System.out.println("开始a任务。。。"); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("a任务结束。。。"); + downLatch.countDown(); + } + }).start(); + new Thread(new Runnable() { + @Override + public void run() { + // 逻辑执行八秒 + System.out.println("开始b任务。。。"); + try { + Thread.sleep(8000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("b任务结束。。。"); + downLatch.countDown(); + } + }).start(); + try { + downLatch.await(); + System.out.println("任务执行完毕。耗时:" + (System.currentTimeMillis() - start)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } +} diff --git a/demo/six/Data.java b/demo/six/Data.java new file mode 100644 index 0000000..7787ca7 --- /dev/null +++ b/demo/six/Data.java @@ -0,0 +1,12 @@ +package six; + +/** + * @author Lenovo + */ +public interface Data { + /** + * 获取数据 + * @return + */ + public String getResult (); +} diff --git a/demo/six/Float.java b/demo/six/Float.java new file mode 100644 index 0000000..9a7a6aa --- /dev/null +++ b/demo/six/Float.java @@ -0,0 +1,10 @@ +package six; + +public class Float { + public static void main(String[] args) { + float a = 4.0F; + System.out.println(a); + float b = java.lang.Float.MAX_VALUE; + System.out.println(b); + } +} diff --git a/demo/six/Future.java b/demo/six/Future.java new file mode 100644 index 0000000..08a2a7e --- /dev/null +++ b/demo/six/Future.java @@ -0,0 +1,25 @@ +package six; + +/** + * @author Lenovo + */ +public class Future { + + public static void main(String[] args) { + Client client = new Client(); + //这里会立即返回,因为得到的是FutureData而不是RealData + Data data = client.request("对线"); + long time = System.currentTimeMillis(); + System.out.println("请求完毕:" + (System.currentTimeMillis() - time)); + try { + //这里可以用一个sleep代替了对其他业务逻辑的处理 + //在处理这些业务逻辑的过程中,RealData被创建,从而充分利用了等待时间 + Thread.sleep(5000); + } catch (InterruptedException e) { + } + System.out.println("业务执行完毕" + (System.currentTimeMillis() - time)); + //使用真实的数据,如果到这里数据还没有准备好,getResult()会等待数据准备完,再返回 + System.out.println("数据 = " + data.getResult() + " 耗时:" + (System.currentTimeMillis() - time)); + } + +} diff --git a/demo/six/FutureData.java b/demo/six/FutureData.java new file mode 100644 index 0000000..0f01727 --- /dev/null +++ b/demo/six/FutureData.java @@ -0,0 +1,40 @@ +package six; + +/** + * @author Lenovo + */ +public class FutureData implements Data { + + /** + * 内部需要维护RealData + */ + protected RealData realdata = null; + + protected boolean isReady = false; + + public synchronized void setRealData(RealData realdata) { + if (isReady) { + return; + } + this.realdata = realdata; + isReady = true; + //RealData已经被注入,通知getResult() + notifyAll(); + } + + /** + * 会等待RealData构造完成 + */ + @Override + public synchronized String getResult() { + while (!isReady) { + try { + //一直等待,直到RealData被注入 线程进入锁的等待队列 + wait(); + } catch (InterruptedException e) { + } + } + //真正需要的数据从RealData获取 + return realdata.result; + } +} \ No newline at end of file diff --git a/demo/six/LongStringTest.java b/demo/six/LongStringTest.java new file mode 100644 index 0000000..f7b5741 --- /dev/null +++ b/demo/six/LongStringTest.java @@ -0,0 +1,19 @@ +package six; + +import java.util.ArrayList; +import java.util.List; + +public class LongStringTest { + + + public static void main(String[] args) { + + List longs = new ArrayList<>(); + longs.add(1L); + longs.add(222L); + longs.add(2222L); + String temp = longs.toString(); + System.out.println(temp); + + } +} diff --git a/demo/six/RealData.java b/demo/six/RealData.java new file mode 100644 index 0000000..5a8a29f --- /dev/null +++ b/demo/six/RealData.java @@ -0,0 +1,21 @@ +package six; + +public class RealData implements Data { + protected final String result; + + public RealData(String para) { + StringBuffer sb = new StringBuffer(para); + //假设这里很慢很慢,构造RealData不是一个容易的事 + try { + Thread.sleep(8000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + result = sb.toString(); + } + + @Override + public String getResult() { + return result; + } +} diff --git a/demo/six/ReentrantlockDemo.java b/demo/six/ReentrantlockDemo.java new file mode 100644 index 0000000..babdc61 --- /dev/null +++ b/demo/six/ReentrantlockDemo.java @@ -0,0 +1,36 @@ +package six; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author Lenovo + */ +public class ReentrantlockDemo { + + public static void main(String[] args) { + ReentrantLock reentrantLock = new ReentrantLock(true); + new Thread(new Runnable() { + @Override + public void run() { + + for (int i = 1 ; i <100 ; i ++ ){ + reentrantLock.lock(); + System.out.println("数数:" + i); + reentrantLock.unlock(); + } + } + }).start(); + + new Thread(new Runnable() { + @Override + public void run() { + + for (int i = -1 ; i > -100 ; i -- ){ + reentrantLock.lock(); + System.out.println("数数:" + i); + reentrantLock.unlock(); + } + } + }).start(); + } +} diff --git a/demo/six/StringTest.java b/demo/six/StringTest.java new file mode 100644 index 0000000..5ea5100 --- /dev/null +++ b/demo/six/StringTest.java @@ -0,0 +1,17 @@ +package six; + +public class StringTest { + public static void main(String[] args) { + String st = "123456"; + char[] ch = st.toCharArray(); + String result = ""; + for (int a = 0 ; a < ch.length ;a++ ){ + result = result + ch[ch.length - a -1]; + } + System.out.println(result); + String ct = "@潘宜天"; + char c = ct.charAt(0); + System.out.println(c); + + } +} diff --git a/demo/six/Test.java b/demo/six/Test.java new file mode 100644 index 0000000..c909bee --- /dev/null +++ b/demo/six/Test.java @@ -0,0 +1,45 @@ +package six; + +import java.util.concurrent.CountDownLatch; + +public class Test { + + private static int x = 0, y = 0, a = 0, b = 0; + + public static void main(String[] args) throws Exception { + + for (int i = 0; i < Long.MAX_VALUE; i++) { + x = 0; + y = 0; + a = 0; + b = 0; + CountDownLatch countDownLatch = new CountDownLatch(2); + + Thread one = new Thread(new Runnable() { + @Override + public void run() { + a = 1; + x = b; + countDownLatch.countDown(); + } + }); + + Thread two = new Thread(new Runnable() { + @Override + public void run() { + b = 1; + y = b; + countDownLatch.countDown(); + } + }); + + one.start(); + two.start(); + countDownLatch.await(); + if (x == 0 && y == 0) { + System.err.println("第 " + i + "次执行,数据执行错误:" + "x 为 " + x + " y 为 " + y); + break; + } + } + } +} diff --git a/demo/ten/Solution1.java b/demo/ten/Solution1.java new file mode 100644 index 0000000..2c5ca26 --- /dev/null +++ b/demo/ten/Solution1.java @@ -0,0 +1,42 @@ +package ten; + +import five.TreeNode; + +import java.util.ArrayList; + +/** + * 检查是否是平衡二叉树 + * @author Lenovo + */ +public class Solution1 { + public static boolean flag = true; + + public static void main(String[] args) { + TreeNode treeNode = new TreeNode(); + Solution1 solution1 = new Solution1(); + solution1.depth(treeNode); + ArrayList arrayList = new ArrayList(); + arrayList.addAll(new ArrayList()); + arrayList.add(new ArrayList()); + } + + public int depth(TreeNode root){ + if (root == null){ + return 0; + } + int l = depth(root.getLeft()); + if (l == -1){ + return -1; + } + int r = depth(root.getLeft()); + if (r == -1){ + return -1; + } + if (Math.abs(l-r)>1){ + flag = false; + return -1; + } + return Math.max(l,r) + 1; + } + +} diff --git a/demo/ten/Solution2.java b/demo/ten/Solution2.java new file mode 100644 index 0000000..922311f --- /dev/null +++ b/demo/ten/Solution2.java @@ -0,0 +1,50 @@ +package ten; + +/** + * @author Lenovo + */ +public class Solution2 { + public static void main(String[] args) { + //第一次只有三个人 + System.out.println(threePeople(1)); + //第二次只有三个人 + System.out.println(threePeople(2)); + //第三次只有三个人 + System.out.println(threePeople(3)); + //第一千次只有三个人 + System.out.println(threePeople(1000)); + } + + /** + * 3、4、5、6、7 + * 求第三次 只三个人的做核酸的一天 + */ + public static Integer threePeople(int day) { + int a = 1; + while (true) { + int num = 0; + a++; + if (a % 3 == 0) { + num++; + } + if (a % 4 == 0) { + num++; + } + if (a % 5 == 0) { + num++; + } + if (a % 6 == 0) { + num++; + } + if (a % 7 == 0) { + num++; + } + if (num == 3) { + day--; + } + if (day <= 0) { + return a; + } + } + } +} diff --git a/demo/ten/SyncDemo.java b/demo/ten/SyncDemo.java new file mode 100644 index 0000000..b657275 --- /dev/null +++ b/demo/ten/SyncDemo.java @@ -0,0 +1,17 @@ +package ten; + +public class SyncDemo { + + public static void main(String[] args) { + SyncDemo syncDemo = new SyncDemo(); + } + + public SyncDemo(){ + synchronized (this){ + System.out.println("1"); + System.out.println("同步代码块"); + System.out.println("0"); + } + + } +} diff --git a/demo/ten/Test.java b/demo/ten/Test.java new file mode 100644 index 0000000..27da80b --- /dev/null +++ b/demo/ten/Test.java @@ -0,0 +1,35 @@ +package ten; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +public class Test { + public static void main(String[] args) { + int N = 4; + CyclicBarrier barrier = new CyclicBarrier(N); + for(int i=0;i longs = new ArrayList<>(); + longs.add(1L); + System.out.println(longs.toString()); + } +} diff --git a/demo/three/MyBloomFilter.java b/demo/three/MyBloomFilter.java new file mode 100644 index 0000000..27224e7 --- /dev/null +++ b/demo/three/MyBloomFilter.java @@ -0,0 +1,65 @@ +package three; + +import java.util.BitSet; + +/** + * @author Lenovo + */ +public class MyBloomFilter { + /** + * 2 << 26表示32亿个比特位 + */ + private static final int DEFAULT_SIZE = 2 << 29; + private static final int[] seeds = new int[]{3, 5, 7, 11, 13, 19, 23, 37}; + /** + * 这么大存储在BitSet + */ + private BitSet bits = new BitSet(DEFAULT_SIZE); + private SimpleHash[] func = new SimpleHash[seeds.length]; + + public static void main(String[] args) { + //可疑网站 + String value = "www.baidu.com"; + MyBloomFilter filter = new MyBloomFilter(); + //加入之前判断一下 + System.out.println(filter.contains(value)); + filter.add(value); + //加入之后判断一下 + System.out.println(filter.contains(value)); + } + + /** + * 构造函数 + */ + public MyBloomFilter() { + for (int i = 0; i < seeds.length; i++) { + func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]); + } + } + + /** + * 添加网站 + * + * @param value + */ + public void add(String value) { + for (SimpleHash f : func) { + bits.set(f.hash(value), true); + } + } + + /** + * 判断可疑网站是否存在 + */ + public boolean contains(String value) { + if (value == null) { + return false; + } + boolean ret = true; + for (SimpleHash f : func) { + //核心就是通过“与”的操作 + ret = ret && bits.get(f.hash(value)); + } + return ret; + } +} diff --git a/demo/three/SimpleHash.java b/demo/three/SimpleHash.java new file mode 100644 index 0000000..ae59b75 --- /dev/null +++ b/demo/three/SimpleHash.java @@ -0,0 +1,22 @@ +package three; + +/** + * @author Lenovo + */ +public class SimpleHash { + private int cap; + private int seed; + + public SimpleHash( int cap, int seed) { + this .cap = cap; + this .seed = seed; + } + public int hash(String value) { + int result = 0 ; + int len = value.length(); + for ( int i = 0 ; i < len; i ++ ) { + result = seed * result + value.charAt(i); + } + return (cap - 1 ) & result; + } +} diff --git a/demo/three/Test.java b/demo/three/Test.java new file mode 100644 index 0000000..e05eadd --- /dev/null +++ b/demo/three/Test.java @@ -0,0 +1,224 @@ +package three; + +/** + * 最长回文字串 + * @author Lenovo + */ +public class Test { + + public static void main(String[] args) { + String temp = "dsfsdhadhfkdsdsfsdhadhdsfsdhadhfkddsfsdhadhfkdsahfksadhdsfsd" + + "hadhfkdsahfksadhfksddsfsdhadhfkdsahfksadhfksdhfusdihfksjadfhksadjkdsa" + + "hfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdsfsdhadhfkds" + + "ahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuonc" + + "sdbfzmbfkhfioaewncfhskhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihw" + + "eiyrtiuoncsdbfzmbfkhfioaewncf啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊hskdsfsdhadhfkdsahfksadhfksdhfusdihfksjadfhk" + + "sadjkdsahfdsjkhfksdasdfasfffffffffffdfasdfhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdsfsdha" + + "sadjkdsahfdsjkhfksdasdfasffffdfasdfhffhiafffffffwoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdsfsdha" + + "dhfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrt" + + "iuoncsdbfzmbfkhfioaewncfhskdsfsdhadhfkdsahfksadhfksdhfusdihfksjadsfsdhadhf" + + "iuoncsdbfzmbfkhfioaewncfhskdsfsdhadhfkdsahfksadhfksdhfusdihfksjadsfsdhadhf" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfk水水水水水水水水水水水水水水水水水水水sjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "kdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuon" + + "csdbfzmbfkhfioaewncfhskdsfsdhadhfkfasdfadsfaefqwewefasddcvaSawedsahfksadhfksdhfusdihfksjadfhksadjkdsahf" + + "dsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdfhksadjkdsahfdsjkh" + + "fksdhffhiawoeuruihweiyrtiuoncasdfasfdasdfasfdaasfsdbfzmbfkhfioaewncfhskfdsfsdhadhfkdsahfksadhfk" + + "sdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioa" + + "ewncfhskksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzm" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "bfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeurui" + + "hweiyrtiuoncsdbfzmbfkhfioaewncfhskfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfd" + + "sjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskahfksadhfksdhfusdihfksj" + + "adfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhsk"; + String tempA = "aaa"; + System.out.println(getStr(temp)); + System.out.println(longestPalindrome(temp)); + System.out.println(longestPalindrome1(temp)); + + } + + static String getStr(String s){ + Long start = System.currentTimeMillis(); + char[] a = s.toCharArray(); + if (a.length<2){ + return ""; + } + //最优子结构 + if (a.length == 2 && a[0] == a[1]){ + return s; + } + String result = ""; + for (int i = 0 ; i < a.length-2;i++){ + char m = a[i]; + char n = a[i+1]; + char o = a[i+2]; + String temp = ""; + if (m == n){ + for (int b = 0 ; b < i; b++){ + if (i+1+b>=a.length){ + break; + } + if (a[i-b] == a[i+1+b]){ + temp = a[i-b] + temp + a[i+1+b]; + }else { + break; + } + } + } + if (m == o){ + temp = n+""; + for (int b = 0 ; b < i+1; b++){ + if (i+2+b>=a.length){ + break; + } + if (a[i-b] == a[i+2+b]){ + temp = a[i-b] + temp + a[i+2+b]; + }else { + break; + } + } + } + if(temp.length()>result.length()){ + result = temp; + } + } + Long end = System.currentTimeMillis(); + System.out.println(end-start); + return result; + } + + + public static String longestPalindrome(String s) { + Long start = System.currentTimeMillis(); + if (s.isEmpty()) { + return s; + } + int n = s.length(); + boolean[][] dp = new boolean[n][n]; + int left = 0; + int right = 0; + for (int i = n - 2; i >= 0; i--) { + dp[i][i] = true; + for (int j = i + 1; j < n; j++) { + dp[i][j] = s.charAt(i) == s.charAt(j) &&( j-i<3||dp[i+1][j-1]);//小于3是因为aba一定是回文 + if(dp[i][j]&&right-left