Skip to content

Commit

Permalink
new update for learning note
Browse files Browse the repository at this point in the history
  • Loading branch information
rbmonster committed Jan 17, 2021
1 parent 56a71ab commit 05a439a
Show file tree
Hide file tree
Showing 25 changed files with 1,530 additions and 387 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
- [计算机网络](https://github.com/rbmonster/learning-note/blob/master/src/main/java/com/toc/NETWORK.md)
- [Elasticsearch 基本知识](https://github.com/rbmonster/learning-note/blob/master/src/main/java/com/design/ES.md)
- [Linux相关](https://github.com/rbmonster/learning-note/blob/master/src/main/java/com/toc/LINUX.md)
- [Netty](https://github.com/rbmonster/learning-note/blob/master/src/main/java/com/toc/NETTY.md)

## 系统设计
- [接口设计](https://github.com/rbmonster/learning-note/blob/master/src/main/java/com/toc/INTERFACE_DESIGN.md)
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/com/four/SOURCECODE.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,38 @@ public final TransactionStatus getTransaction(@Nullable TransactionDefinition de
- Spring 事务处理 中,可以通过设计一个 TransactionProxyFactoryBean 来使用 AOP 功能,通过这个 TransactionProxyFactoryBean 可以生成 Proxy 代理对象
### 事务隔离实现
spring 事务隔离主要通过`DataSourceTransactionManager` 在开启事务的时候,设置对应的隔离级别到数据库连接中。
> 本质上事务的实现是通过设置数据库连接的隔离级别。即类似于 `mysql> set global transaction_isolation ='read-committed';` 因此数据库的实现依赖于数据库支持的隔离级别
```
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;

try {
if (!txObject.hasConnectionHolder() ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
Connection newCon = obtainDataSource().getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}

txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection();

Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
...
}
}
```
### @Transactional失效场景
1. 注解导致的事务失效:
1. @Transactional 注解属性 propagation 设置错误,设置了以非事务的状态运行
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
throws Exception {
log.info("[preHandle][" + request + "]" + "[" + request.getMethod()
+ "]" + request.getRequestURI() + request.getParameterMap());

return HandlerInterceptor.super.preHandle(request, response, handler);
throw new RuntimeException("sdfasdf");
// return HandlerInterceptor.super.preHandle(request, response, handler);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.four.filterinterceptor.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
* <pre>
* @Description:
*
* </pre>
*
* @version v1.0
* @ClassName: TestControllerAdvicer
* @Author: sanwu
* @Date: 2021/1/12 14:53
*/
@Slf4j
@RestControllerAdvice(basePackages = "com.four.filterinterceptor.interceptor")
public class TestControllerAdvicer {

@ExceptionHandler(RuntimeException.class)
public String handler(RuntimeException e) {
log.info("this is handler exception process");
return e.getMessage();
}
}
68 changes: 63 additions & 5 deletions src/main/java/com/learning/algorithm/ALGORITHM.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,19 @@ map.put(1, count.getOrDefault(1, 0) + 1);
### 字符串
公共前缀问题
- 最长公共前缀:https://leetcode-cn.com/problems/longest-common-prefix/
- 分治法、二分法

回文问题(包含子串与子序列问题)
- 最长回文子串:https://leetcode-cn.com/problems/longest-palindromic-substring/

双指针问题
- 反转字符串
- 反转字符串https://leetcode-cn.com/problems/reverse-string/
- 两数之和 II - 输入有序数组(最基础问题) :https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/
- 快慢指针:
- 移除数组
- 移动零


- 反转单词顺序:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/

## 链表
链表双指针:
Expand Down Expand Up @@ -270,10 +272,15 @@ private int maximum_depth(TreeNode root) {
- 二叉树的最近公共祖先:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

### 二叉搜索树
二叉搜索树相关问题基本思想:
1. 中序遍历
2. 递归利用二叉搜索树属性进行处理。

基本操作:
- 验证二叉搜索树:https://leetcode-cn.com/problems/validate-binary-search-tree/
- 二叉搜索树中的搜索:https://leetcode-cn.com/problems/search-in-a-binary-search-tree/
- 二叉搜索树中的插入操作:https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/
- 把二叉搜索树转换为累加树(review):https://leetcode-cn.com/problems/convert-bst-to-greater-tree/
- 删除二叉搜索树中的节点
- 如果目标节点没有子节点,我们可以直接移除该目标节点。
- 如果目标节只有一个子节点,我们可以用其子节点作为替换。
Expand Down Expand Up @@ -319,8 +326,7 @@ private int maximum_depth(TreeNode root) {
二叉搜索树构建:
- 将有序数组转换为二叉搜索树:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/
## 算法归类
Expand All @@ -343,7 +349,6 @@ private int maximum_depth(TreeNode root) {
- 修剪二叉搜索树(review):https://leetcode-cn.com/problems/trim-a-binary-search-tree/
- 左叶子之和(review):https://leetcode-cn.com/problems/sum-of-left-leaves/
- 二叉树的右视图(review):https://leetcode-cn.com/problems/binary-tree-right-side-view/
- 把二叉搜索树转换为累加树(review):https://leetcode-cn.com/problems/convert-bst-to-greater-tree/
- 找树左下角的值(review):https://leetcode-cn.com/problems/find-bottom-left-tree-value/
- 寻找重复的子树(review):https://leetcode-cn.com/problems/find-duplicate-subtrees/solution/
- 二叉搜索树中的众数:https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/
Expand Down Expand Up @@ -505,7 +510,60 @@ class UnionFindSet {
## 单调栈
单调栈: 单调栈实际上就是栈, 只是利⽤了⼀些巧妙的逻辑, 使得每次新元素⼊栈后, 栈内的元素都保持有序(单调递增或单调递减) 。
- 每日温度:https://leetcode-cn.com/problems/daily-temperatures/
- 下一个更大元素 I: https://leetcode-cn.com/problems/next-greater-element-i/
```
public int[] dailyTemperatures(int[] T) {
Deque<Integer> stack = new LinkedList<>();
int len = T.length;
int[] res = new int[len];
// 从尾到头遍历
for(int i = len-1; i>=0 ;i--) {
while(!stack.isEmpty() && T[stack.peek()] <= T[i]) {
stack.pop();
}
// 判断位置差值
res[i] = stack.isEmpty() ? 0 : stack.peek() - i;
stack.push(i);
}
return res;
}
```
## 单调队列
- 剑指 Offer 59 - I. 滑动窗口的最大值: https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/
```
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length == 0 || k == 0) return new int[0];
Deque<Integer> deque = new LinkedList<>();
int len = nums.length;
int[] res= new int[len -k +1];
for(int i =0;i<k ;i++) {
// 新元素入队,比较队尾元素,小的元素全部移除,保证队列的单调性
while(!deque.isEmpty()&& deque.peekLast() <nums[i]) {
deque.removeLast();
}
deque.addLast(nums[i]);
}
res[0] = deque.peekFirst();
for(int i =k;i<len;i++) {
// 滑动窗口的比较
if(nums[i-k] == deque.peekFirst()) {
deque.removeFirst();
}
while(!deque.isEmpty()&& deque.peekLast() <nums[i]) {
deque.removeLast();
}
deque.addLast(nums[i]);
res[i-k+1] = deque.peekFirst();
}
return res;
}
```
## 前缀树
前缀树又名字典树,单词查找树,Trie树,是一种多路树形结构,是哈希树的变种,和hash效率有一拼,是一种用于快速检索的多叉树结构。
Expand Down
94 changes: 47 additions & 47 deletions src/main/java/com/learning/algorithm/Demo.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,53 +24,53 @@ public class Demo {

public static void main(String[] args) {
String ad = "";
// Demo main = new Demo();
// int[][] matrix = {
// {1, 2, 2, 3, 5},
// {3, 2, 3, 4, 4},
// {2, 4, 5, 3, 1},
// {6, 7, 1, 4, 5},
// {5, 1, 1, 2, 4}
// };
// int[][] xx = {{0, 1, 0, 0, 1, 1, 0}, {1, 0, 0, 0, 0, 0, 0}, {1, 0, 0, 1, 1, 1, 1}, {0, 1, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0, 1}, {1, 0, 0, 1, 0, 0, 0}, {1, 0, 1, 0, 0, 1, 0}};
//// System.out.println(main.shortestPathBinaryMatrix(xx));
// Map<Integer, Integer> map = new HashMap<>();
// map.put(1, 2);
// System.out.println(map);
// map.putIfAbsent(1, 4);
// map.putIfAbsent(2, 4);
// System.out.println(map);
// int mer = map.merge(1, 6, (v1, v2) -> v1 + v2);
// System.out.println(map);
// int value = 123123;
// int key2 = map.computeIfAbsent(2, k -> value);
// int key3 = map.computeIfAbsent(3, k -> value);
// System.out.println(map);
// int res = map.computeIfPresent(3, (key, oldVal) -> oldVal - 1);
// System.out.println(map);
// int result1 = map.compute(3, (key, oldValue) -> oldValue - 10);
// int[][] example = new int[][]{{1,1,0}, {1,1,0},{0,0,1}};
//// System.out.println(main.findCircleNum(example));
//// System.out.println(main.findDuplicate(new int[] {1,2,3,3,4}));
//// System.out.println(main.hammingDistance(1,4));
// String[] A = new String[] {"123"};

Map<Integer,Integer> map = new HashMap<>(4,1);

Set<Integer> set = new LinkedHashSet<>();
Map<String, String > map1 = new HashMap<>();
Scanner scanner = new Scanner(System.in);
Demo demo = new Demo();
demo.canCompleteCircuit(new int[]{1,2,3,4,5}, new int[]{3,4,5,1,2});
List<Integer> result = new ArrayList<>();
Integer[] re = new Integer[123];
result.toArray(re);
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(1);
treeSet.add(2);
treeSet.add(3);
treeSet.add(4);
System.out.println(treeSet.last());
Demo main = new Demo();
int[][] matrix = {
{1, 2, 2, 3, 5},
{3, 2, 3, 4, 4},
{2, 4, 5, 3, 1},
{6, 7, 1, 4, 5},
{5, 1, 1, 2, 4}
};
int[][] xx = {{0, 1, 0, 0, 1, 1, 0}, {1, 0, 0, 0, 0, 0, 0}, {1, 0, 0, 1, 1, 1, 1}, {0, 1, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0, 1}, {1, 0, 0, 1, 0, 0, 0}, {1, 0, 1, 0, 0, 1, 0}};
// System.out.println(main.shortestPathBinaryMatrix(xx));
Map<Integer, Integer> map = new HashMap<>();
map.put(1, 2);
System.out.println(map);
map.putIfAbsent(1, 4);
map.putIfAbsent(2, 4);
System.out.println(map);
int mer = map.merge(1, 6, (v1, v2) -> v1 + v2);
System.out.println(map);
int value = 123123;
int key2 = map.computeIfAbsent(2, k -> value);
int key3 = map.computeIfAbsent(3, k -> value);
System.out.println(map);
int res = map.computeIfPresent(3, (key, oldVal) -> oldVal - 1);
System.out.println(map);
int result1 = map.compute(3, (key, oldValue) -> oldValue - 10);
int[][] example = new int[][]{{1,1,0}, {1,1,0},{0,0,1}};
// System.out.println(main.findCircleNum(example));
// System.out.println(main.findDuplicate(new int[] {1,2,3,3,4}));
// System.out.println(main.hammingDistance(1,4));
String[] A = new String[] {"123"};

// Map<Integer,Integer> map = new HashMap<>(4,1);
//
// Set<Integer> set = new LinkedHashSet<>();
// Map<String, String > map1 = new HashMap<>();
// Scanner scanner = new Scanner(System.in);
// Demo demo = new Demo();
// demo.canCompleteCircuit(new int[]{1,2,3,4,5}, new int[]{3,4,5,1,2});
// List<Integer> result = new ArrayList<>();
// Integer[] re = new Integer[123];
// result.toArray(re);
// TreeSet<Integer> treeSet = new TreeSet<>();
// treeSet.add(1);
// treeSet.add(2);
// treeSet.add(3);
// treeSet.add(4);
// System.out.println(treeSet.last());
}
Map<String, Integer> note = new HashMap<>();

Expand Down
26 changes: 24 additions & 2 deletions src/main/java/com/learning/algorithm/Demo2.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,35 @@
*/
public class Demo2 {
public static void main(String[] args) {
new Demo2().translateNum(18580);
new Demo2().reverseWords("the sky is blue");

PriorityQueue<Integer> queue = new PriorityQueue<>((o1,o2) -> o2-o1);

}

int res = 0;
public String reverseWords(String s) {
if (s == null || s.trim().length() == 0) return "";
StringBuilder sb = new StringBuilder();
int len = s.length();
int index = 0;
for (int i = 0; i < len; i++) {
char ch = s.charAt(i);
if (ch == ' ') {
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != ' ') {
sb.append(' ');
}
continue;
}
if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ' ') {
index = sb.length();
}
sb.insert(index, ch);
}
return sb.reverse().toString();
}


int res = 0;

public int translateNum(int num) {
String str = String.valueOf(num);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/learning/basic/COLLECTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- 添加元素时使用 ensureCapacityInternal() 方法来保证容量足够,如果不够时,需要使用 grow() 方法进行扩容,新容量的大小为 oldCapacity + (oldCapacity >> 1),也就是旧容量的 1.5 倍。
- 主要一个超精度负数判断,如果经度过长,则默认使用当前长度
- 数据复制使用Arrays.copyOf(elementData, newCapacity);
- 因为为一步操作因此用于快速失败的modCount+1
```
// size为当前的list长度
Expand Down Expand Up @@ -66,6 +67,9 @@ private void grow(int minCapacity) {
elementData = Arrays.copyOf(elementData, newCapacity);
}
```
思考:arrayList 为啥1.5倍扩容?
##### 删除元素
- 调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,该操作的时间复杂度为 O(N),可以看到 ArrayList 删除元素的代价是非常高的。
- System.arraycopy(elementData, index+1, elementData, index, numMoved);
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/com/learning/basic/CONCURRENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ public class SynchronizedDemo2 {
- 如果不再需要这个锁对象,那么将锁对象设置为无锁状态,重新进行偏向锁竞争。

第一次获取替换对象头TheadID:
1. 当一个线程访问同步块并获取锁时, 会在锁对象的对象头和栈帧中的锁记录里存储锁偏向的线程ID, 以后该线程进入和退出同步块时不需要进行CAS操作来加锁和解锁。
2. 需要简单的测试一下锁对象的对象头的MarkWord里是否存储着指向当前线程的偏向锁(线程ID是当前线程)。
- 如果测试成功, 表示线程已经获得了锁;
- 如果测试失败, 则需要再测试一下MarkWord中偏向锁的标识是否设置成1(表示当前是偏向锁)
- 如果没有设置, 则使用CAS竞争锁。
1. 当一个线程访问同步块并获取锁时, 会在锁对象的对象头和栈帧中的锁记录里存储锁偏向的线程ID, 以后该线程进入和退出同步块时不需要进行CAS操作来加锁和解锁。
2. 需要简单的测试一下锁对象的对象头的MarkWord里是否存储着指向当前线程的偏向锁(线程ID是当前线程)。
- 如果测试成功, 表示线程已经获得了锁;
- 如果测试失败, 则需要再测试一下MarkWord中偏向锁的标识是否设置成1(表示当前是偏向锁)
- 如果没有设置, 则使用CAS竞争锁。
- 如果设置了, 则尝试使用CAS将锁对象的对象头的偏向锁指向当前线程.

偏向锁的撤销
Expand Down
Loading

0 comments on commit 05a439a

Please sign in to comment.