使用idea的模版项目,模版项目,use this template,clone到自己的仓库中,会生成一个干净的模版,默认使用kotlin生成的,src.main.kotlin 是kotlin代码,如果要使用java,要src.main.javam目录。
模版项目重要是plugin.xml,里面可以定义applicationService 实现类,projectService实现类和applicationListeners实现类。
用默认kotlin看起来都是好的,切换到java,弹出框不太行,找了一圈也没找到原因。放弃了。

本来想是不是学学kotlin更好写,发现例子都是java的,还是java吧,理解插件机制,晚点再学习新语法。都一起学很慢。

本来想一个周末搞出来了大概,但我自信了,不会的东西还是很多的。今年junt5是重点,而且经过反复查看,感觉已经快了,继续专攻一处,这个写插件急不得。

题目

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例 2:

输入:head = [], val = 1
输出:[]
示例 3:

输入:head = [7,7,7,7], val = 7
输出:[]

提示:

列表中的节点数目在范围 [0, 104] 内
1 <= Node.val <= 50
0 <= val <= 50

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-linked-list-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

自己没解出来,想起来虚拟头节点解决头部的处理,但只用一个指针,怎么都没处理明白,最后看解答,2个指针很简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head == null){
return head;
}
ListNode dummy = new ListNode(-1, head);
ListNode pre = dummy;
ListNode cur = head;

while(cur != null){
if(cur.val == val){
pre.next = cur.next;
}else{
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}

Assertions

JUnit Jupiter 从Junit4 集成很多断言方法,还有新增一些java 8 lambda使用的。断言在静态方法 org.junit.jupiter.api.Assertions 类下面

测试用例分为几种情况
标准断言

1
2
3
4
5
6
7
8
@Test
void standardAssertions() {
assertEquals(2, calculator.add(1, 1));
assertEquals(4, calculator.multiply(2, 2),
"The optional failure message is now the last parameter");
assertTrue('a' < 'b', () -> "Assertion messages can be lazily evaluated -- "
+ "to avoid constructing complex messages unnecessarily.");
}

分组断言,所有断言都执行,所有失败一起报告,assertAll

1
2
3
4
5
6
7
8
9
@Test
void groupedAssertions() {
// In a grouped assertion all assertions are executed, and all
// failures will be reported together.
assertAll("person",
() -> assertEquals("Jane", person.getFirstName()),
() -> assertEquals("Doe", person.getLastName())
);
}

依赖断言,一个断言失败了,子代码被跳过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Test
void dependentAssertions() {
// Within a code block, if an assertion fails the
// subsequent code in the same block will be skipped.
assertAll("properties",
() -> {
String firstName = person.getFirstName();
assertNotNull(firstName);

// Executed only if the previous assertion is valid.
assertAll("first name",
() -> assertTrue(firstName.startsWith("J")),
() -> assertTrue(firstName.endsWith("e"))
);
},
() -> {
// Grouped assertion, so processed independently
// of results of first name assertions.
String lastName = person.getLastName();
assertNotNull(lastName);

// Executed only if the previous assertion is valid.
assertAll("last name",
() -> assertTrue(lastName.startsWith("D")),
() -> assertTrue(lastName.endsWith("e"))
);
}
);
}

assertThrows 异常断言

1
2
3
4
5
6
@Test
void exceptionTesting() {
Exception exception = assertThrows(ArithmeticException.class, () ->
calculator.divide(1, 0));
assertEquals("/ by zero", exception.getMessage());
}

超时断言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

@Test
void timeoutNotExceeded() {
// The following assertion succeeds.
assertTimeout(ofMinutes(2), () -> {
// Perform task that takes less than 2 minutes.
});
}

@Test
void timeoutNotExceededWithResult() {
// The following assertion succeeds, and returns the supplied object.
String actualResult = assertTimeout(ofMinutes(2), () -> {
return "a result";
});
assertEquals("a result", actualResult);
}

@Test
void timeoutNotExceededWithMethod() {
// The following assertion invokes a method reference and returns an object.
String actualGreeting = assertTimeout(ofMinutes(2), AssertionsDemo::greeting);
assertEquals("Hello, World!", actualGreeting);
}

@Test
void timeoutExceeded() {
// The following assertion fails with an error message similar to:
// execution exceeded timeout of 10 ms by 91 ms
assertTimeout(ofMillis(10), () -> {
// Simulate task that takes more than 10 ms.
Thread.sleep(100);
});
}

@Test
void timeoutExceededWithPreemptiveTermination() {
// The following assertion fails with an error message similar to:
// execution timed out after 10 ms
assertTimeoutPreemptively(ofMillis(10), () -> {
// Simulate task that takes more than 10 ms.
new CountDownLatch(1).await();
});
}

assertTimeoutPreemptively() 在不同的线程中计时,如果依赖ThreadLocal可能导致不可预期的副作用。

Assumptions

JUnit Jupiter 从Junit4 集成很多断言方法,还有新增一些java 8 lambda使用的。断言在静态方法 org.junit.jupiter.api.Assertions 类下面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class AssumptionsDemo {

private final Calculator calculator = new Calculator();

@Test
void testOnlyOnCiServer() {
assumeTrue("CI".equals(System.getenv("ENV")));
// remainder of test
}

@Test
void testOnlyOnDeveloperWorkstation() {
assumeTrue("DEV".equals(System.getenv("ENV")),
() -> "Aborting test: not on developer workstation");
// remainder of test
}

@Test
void testInAllEnvironments() {
assumingThat("CI".equals(System.getenv("ENV")),
() -> {
// perform these assertions only on the CI server
assertEquals(2, calculator.divide(4, 2));
});

// perform these assertions in all environments
assertEquals(42, calculator.multiply(6, 7));
}

}

最近新领导开始搞人力检查,看起来多的人力都会被一个个问询。我们只能一个个编对应理由,很无聊。
我经历过的几个新领导到来,所谓新官上任三把火,总会弄的你难受。
领导来的第一步都是整顿流程,这个也很好理解,我自己也这样,如果下属干的不好,那就给他们设立一个流程,你们不用动脑子,按照我们的流程走就好了。人懒惰的,习惯性少做无用的事情,或省略其他。领导的精力是有限的,最好是能定一套流程, 下属自动完成,我不需要再耗费什么精力去管理,那流程就是最好的东西,完善一次就能节省很多精力,这也是大部分领导到来首先整顿流程。
然后就是人力,雇佣你就是要用你的时间换公司的收益,如果能用更少的复出,收获更多的收益,那是最好的,所以这一块,一定要在合理的范围内。
最后就是加班,如果没有法律的限制,当然是越剥削你越好了,花更少钱,收获更多的收益,为什么不这么做的呢?
每个领导,应该都是比你能力更强,经历更多,为什么都选择这样的方法,一种就是这种方法确实有效。另外一种就是我正受着不公正的待遇,我想偷懒,所以我觉得领导sb。领导看到我,每天清闲不干活,所以想出各种办法,让我加班,觉得我sb。

到了30岁,发现自己离传统的去大公司往上走,可能性越来越低。留在上海,高额的房价,买了房子一辈子都套牢,以及父母的老去,都感觉自己被工作地点限制,可能未来越来越难。突然想一种能不受空间限制的工作,远离大城市高额的消费,也能有还可以的收入,能照顾老去的家人,不用为了钱一直为别人打工。
想到几种可能的方式。
一种是外企外包,相对轻松,生活工作平衡,但需要外语水平高。
一种就是独立开发者,自己开发东西自己有收入。
暂时我还没能力自己创建团队,开发的东西肯定也做不过大公司,只能找一些细分领域,做一些大公司看不上的,支撑不起一个团队的收入,但对一个人足够的收入。
跟着别人做,早晚有一天,你会被替代,不管多么不可替代,自己能摸索市场,看准需求,自己能挣钱,而不是负债,你才能不用担心被裁员。
独立开发者在中国可能还没有那么好的待遇,所以要先工作着,有着主要收入,再去探索哪种模式,这条路也可能失败,而且也不好走。
我搜索到的几种,
1.chrome插件开发赚钱
2.wordpress插件或主题
3.小程序、微信公众号
4.自己做网站

但同时也看到很多悲观论调,广告收入很少,没有流量引入,没有知道要流量就要花钱。相对来说,国外的环境好一点,大家付费的情绪高一点。
我昨晚看了一下最常用的idea的插件,也有收费的,而且下载量很高的,一个6美元,100多万的采摘量,但这是最高的,其他的都很少了,付费下载量超过万的不多。
我想试试这条路,先从各种插件入手看看,开发一些成熟软件的插件,看试试能不能有一些收入。
因为最近想到部门再抓首移质量, 好多人提交代码前,一些基本的运行都不做,提交的代码都编译报错,想能不能本地开发个idea 插件,可以本地方便的执行这些操作,同时还可以开发了规范的检查,提交前先检查,这样提交代码的质量会提高很多。
用自己的手艺吃饭,不断增加自己手艺的数量,加大手艺融合碰撞。
这条路暂时没看到现成的道路,需要自己探索,更难,但可能竞争者更少。

测试类:任何顶层类,静态成员类或@Nested 类,至少包含一个测试方法。必须不是抽象类,有单一的构造器

测试方法:被@Test,@RepeatedTest,@ParameterizedTest,@TestFactory,@TestTemplate 直接注解或元注解的实例方法

生命周期方法:被@BeforeAll,@AfterAll,@BeforeEach,@AfterEach 注解或元注解的实例方法。

测试方法和生命周期方法可能在当前类定义,或从超类继承,或从接口继承。另外测试方法和生命周期方法不能是抽象,并且不能返回值(除了@TestFactory要求返回值)

题目

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

| 1 | 2 | 3 |
| 8 | 9 | 4 |
| 7 | 6 | 5 |

示例 1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:

输入:n = 1
输出:[[1]]

提示:

1 <= n <= 20

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/spiral-matrix-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题

自己没想出来,看着别人的做的,循环不变量原则
模拟顺时针画矩阵的过程:

填充上行从左到右
填充右列从上到下
填充下行从右到左
填充左列从下到上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public int[][] generateMatrix(int n) {
int loop = 0;
int start = 0;
int[][] res = new int[n][n];
int count = 1;
int i, j;
while(loop++ < n/2){
for(j = start; j < n - loop; j++){
res[start][j] = count++;
}
for(i = start; i < n - loop; i++){
res[i][j] = count++;
}
for(; j > start; j--){
res[i][j] = count++;
}
for(; i > start; i--){
res[i][j] = count++;
}
start++;
}
if(n % 2 == 1){
res[start][start] = count;
}
return res;

}
}

题目

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:

输入:target = 4, nums = [1,4,4]
输出:1
示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

提示:

1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105

进阶:

如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-size-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法

解题:滑动窗口法
看别人的解法,自己写的超过时间限制

1
2
3
4
5
6
7
8
9
10
11
12
13
public int minSubArrayLen(int target, int[] nums) {
int i = 0;
int result = Integer.MAX_VALUE;
int sum = 0;
for(int j = 0; j < nums.length ; j++){
sum += nums[j];
while(sum >= target){
result = Math.min(result, j - i + 1);
sum -= nums[i++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}

最近在给spring cloud gateway 添加header信息,想解析token 然后再塞到header传到后面微服务组件。但有的时候不起效,就研究为啥。

通过继承 WebFilter,实现filter(ServerWebExchange exchage,WebFilterChain chain)
通过exchange.getRequest().mutate() 来构建ServerHttpRequest.Builder 正常这个应该是建造者模式,流式创建一个新的request对象,但其中有一个比较特别的就是header属性,headers方法,可以传入一个cunsumer对象,可以覆盖或删除对象,而且会直接影响到原来的request的header。这个可以理解为特意这么设计,可能为了改变header而不用每次都创建新的对象,其他属性的修改都符合建造者模式是复制一个对象,而不是直接修改原来对象。
这个比较特殊,允许header修改,且影响原来的对象。但不调用mutate方法却不能修改,因为原来对象是只读对象。

自己既干过员工,也当过一点小领导,脑海里出现过两个完全对立的观点,但貌似都有道理。
当自己是员工的时候,碰到一些麻烦,自己做了一些,但没做好。先跑了,把工作一半留给领导,想领导挣得多,自然干得多,没毛病。我就挣这点,就这样不错了。
当自己是领导,把任务分给下级,下级做的磕磕绊绊,最后留一个烂摊子给你,下级还觉得不错,你就想我招你们来是分担工作的,结果你们一个个都比我轻松,我是给你们服务的,请了大爷来。
两种对立的想法,在不同场景内看起来都是合理的。上级工作做不过来,需要招人来帮忙分担,而且觉得手下人都是给自己干活的,自然自己要比其他人权力更大,想让你们干什么就干什么,不然我要你有什么用,我自己都干了得了。下级如果只看薪水工作,那上级比我赚钱多,自然干的多,很正常。从单一角度看都没问题,但现实是多维度了,员工要看到自己的工作的内容和报酬的关系,更要看雇佣你的人,对你的期望,评价,以及目的。而且人容易看不清自己的评价,然后自我解释自我满足。
领导也不能只把员工看成给自己分担工作,不能有权力高于别人的错觉,你要别人帮你分担,你就需要更高维度去管理,我不是简单理解别人都会明白。上级明白下级容易,下级明白上级难。如果你不跟别人讲,明天听过你的想法,也就没人理解你,你不能只按自己想法去和别人合作。
之前我就明白要多维度,但没有什么途径去了解,就拿自己工作去揣测上下级,看看如果能使用多维度思考。