1.switch空指针异常

Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "String.hashCode()" because "<local2>" is null
at Study5.Test03.main(Test03.java:6)
我们由此可以知道,switch语句部分情况下使用case做的判断在某种意义上其实就是获取字符串的hashCode的过程。
还有我认为写代码的时候最好在switch之前做空判断

2.Integer为null赋值给int变量会报空指针
Integer为null赋值给int变量会报java.lang.NullPointerException的思考_integer null赋值报错-优快云博客
其实是因为Interger类型值为null,默认调用了自己的自动拆箱方法null.intValue(),转为int
同理,Double 和double,Boolean和boolean 这种封装类和基本类型之间的转换都要注意这种情况

3. MapStruct LocalDate映射Date
我与数据库交互实体中的时间字段,用LocalDate接的
但是返回给前端的实体中相同时间字段,用Date接的
然后使用mapstruct进行convert的时候,他默认将两个类型进行转换的时候,时区用的utc


那就导致了我存入数据库的数据和返回给前端的数据,不一致
3.1 解决办法
解决办法有两个,要么就是两个时间字段设置为同一个类型,就是把返回给前端的时间字段也改为Date,要么就是在convert的时候设置expression
我最后选择了把两个字段类型改为一致了

4.java8多字段排序
这个以前就用过,只是很长时间没用,忘记了
使用java8排序,就可以省很多代码
list.sort(Comparator.comparing(User::getAge).thenComparing(User::getName));
5.泛型怎么用@Builder构建
把泛型写到.后边
RangeCompare<Float> compare = RangeCompare.<Float>builder()
.leftSymbol(leftSymbol).leftNum(minMid)
.relation(Constant.COMMA_SPLIT)
.rightNum(maxMid).rightSymbol(rightSymbol)
.build();
6.用long型接 防止过大变为负数
long iadd = 24L * 3600L * 1000L * 30;
7.转为数组然后排序或者取值
这是最近了解到的一种思想
8.日志打印
开始,我们拿到的开源项目有全局异常处理器,处理器只打印了e.message,但是没办法直接定位到具体哪一行报错,这样查问题很不方便
我就直接加了
e.printStackTrace();
把异常都输出出来了

但是注意到idea会报黄线
然后我就根据当前环境去识别是否要打印(但是我发现还报黄线,就看自己项目需求是啥吧,反正我觉得都给我打印出来,就算是生产环境,我查问题也好查。而且不用担心什么e.printStackTrace()浪费性能,都上了生产了,哪个接口能一天到晚报错啊)
log.isDebugEnabled()是根据 当前的日志级别 以及 当前的spring.profiles.active的配置
我目前bootstrap.yml中spring.profiles.active是dev
然后logback-spring.xml中对于dev的配置的debug
所以log.isDebugEnabled()是true
后来logback-spring.xml中对于dev的配置的INFO
那log.isDebugEnabled()就是false
这个是按照日志级别的 如果当前配置了debug 那isInfoEnable()也会返回true 因为info>debug

9.oracle授权用户
--oracle授权用户,解决无USER权限
alter user 用户 quota unlimited on users
10. 最近学到的关于多线程的知识点
1.get和thenCompose

get() 同步方法 等待所有线程执行完
thenCompose() 只等待被修饰的线程执行完
最后CompletableFuture.allOf(completableFutures).get() 等所有现成执行完再执行下一步
相似的还有CompletableFuture.anyOf(completableFutures).get() 任意一个执行完就执行下一步
2.interrupt方法不一定能中断线程

3.中断线程的几种方式
stop
设置标识
interrupt
百度安全验证
https://baijiahao.baidu.com/s?id=1771200491206091094&wfr=spider&for=pc
4.用线程削峰
在循环中请求rpc接口,但是rpc提供者说造成压力太大,服务挂了。
也没有mq,就用延时调用的方式削峰了
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors() << 1);
for (int i = 0; i <=10; i++) {
String msg = "第:" + i + ":页";
log.info(msg);
int finalI = i;
//隔几秒执行
executor.schedule(() -> {
try{
System.out.println(finalI);
}catch (Exception ex){
ex.printStackTrace();
throw AiIllegalException.supplier("执行分页失败").get();
}
}, i,TimeUnit.SECONDS);
}
//线程池使用完需要关闭 shutdown()是不接受新线程,执行完已有的再关
executor.shutdown();
log.info("collectSkipLimit-BiFunction");
try{
//强行关闭 不管线程是否执行完 直接关
if (!executor.awaitTermination(2*60*60L, TimeUnit.SECONDS)) {
log.error("线程等待超时,请检查!");
executor.shutdownNow();
}
}catch (InterruptedException e){
e.printStackTrace();
Thread.currentThread().interrupt();
throw new IllegalArgumentException(e.getMessage());
}
}
5.在事务中加快rpc调用速度
又是在循环中调用rpc
并且,如果调用失败,事务时需要回滚的
目标两个:1.加快速度 2.失败时回滚
思路 1.异步 2.向量,最后校验向量长度

Vector<?> pimApplyProjects = new Vector<>();
向量 最大的特点是:线程安全的 ,相当于线程安全的 ArrayList
在循环中通过异步的方式加快运行速度
用thenAccept让每个线程执行完都往向量里加东西
最后通过allof().join的方式等待所有异步线程运行完再执行下一步
最后断言比较预期长度和实际长度,不一致,说明异步中有线程报错,则抛出异常,使事务回滚

11.泛型
由于我本人使用泛型的几率没有那么频繁,所以看到带泛型的代码总要欣赏学习一下

11.1为啥要使用泛型
1.提升了程序的健壮性和规范性

2.编译时,检查添加元素的类型,提高了安全性
3.减少了类型转换的次数,提高效率
- 当不使用泛型时:

- 当使用泛型时

11.2 泛型定义类和方法
需要用<T> 或者<T extends Object>形式来定义泛型


java泛型类和泛型方法定义_千锋教育的技术博客_51CTO博客
1.泛型类
public class MyClass<T> {
private T value;
public MyClass(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
使用泛型类
MyClass<String> str = new MyClass<>("hello");
String s = str.getValue(); // "hello"
2.泛型方法
泛型方法: 泛型方法是指在定义方法时使用了泛型参数,这个泛型参数只能用于该方法中。泛型方法的定义方式如下:
public class MyClass {
public <T> T myMethod(T value) {
return value;
}
}
使用泛型方法
MyClass obj = new MyClass();
String s = obj.myMethod("hello"); // "hello"
Integer i = obj.myMethod(123); // 123
3.泛型可以定义多个
什么是 Java 泛型?怎样使用 Java 泛型?_java泛型类的定义和使用-优快云博客
public class Util {
// 静态泛型方法
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}
public class Pair<K, V> {
private K key;
private V value;
// 泛型构造函数
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
// 泛型方法
public void setKey(K key) { this.key = key; }
public void setValue(V value) { this.value = value; }
public K getKey() { return key; }
public V getValue() { return value; }
}
调用
Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
// boolean same = Util.<Integer, String>compare(p1, p2);
boolean same = Util.compare(p1, p2);
12.exe创建快捷方式
终于不用每次想打开dbever时候都去文件夹里边找了

13.Integer包装类不用==判断相等
【精选】java Interger包装类不能使用“==“判断值相等_包装类判断相等_咿呀&萨摩耶的博客-优快云博客
Interger是引用类,所以当我们使用’=='去判断i1与i2,i4与i5是否相等的时候实际上判断的是是否为同一引用对象即内存中指向的地址是否相同。
源码如下:在这个范围之间,地址相同,在这个范围之外,就new了一个
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
14.org.springframework.boot.autoconfigure.AutoConfiguration.imports
乍一看很陌生,但是看一下里边的配置,其实马上就联想到spring.factories
然后自己查了下,发现他俩确实一个作用

路径都一样


当然如果你两个都不想用,那只有在使用的时候用@Import把配置类引入进来,不然读不到,但是这种方式不推荐,作为jar包的提供者,最好还是自动配置

15.in/not in注意NULL
用in查,查询不到结果集为null的数据
用not int查,如果结果集中有为null的数据,那么最终结果集中啥都没有
第二点说的有点绕,我说下我今天踩坑的事


查了下原因
SQL避坑:当in,not in遇上null这种坑你避过吗?_not in null_莫叫石榴姐的博客-优快云博客
注:使用 not in 的时候,如果 not in 后面的选项中有 null,不会查询出来任何数据。
not in 相当于and条件,只要有一个false,那么所有的都为false。所以最终结果集中啥都没有
不等于NULL永远为false,所有整个条件判断都为false

in相当于or,对于null值得判断不是is null而是等于,因而对于NULL值得判断永远都是false
所以in的结果集中不会出现null,想要查Null得另外加上条件 is null
16.split需要转义,但是concat不需要
因为split后边跟着得是正则,所以你想把一个字符串通过点.分割得时候 需要\\.
比如
String[] split = "ss".split("\\.");
但是如果你想用点.拼接字符串,就不用转义了
比如
sourceDatabaseName.concat(".").concat(scheme);
17.show processlist ;
show processlist是显示用户正在运行的线程,需要注意的是,除了root用户能看到所有正在运行的线程外,其他用户都只能看到自己正在运行的线程,看不到其它用户正在运行的线程。除非单独个这个用户赋予了PROCESS权限。
kill 338687;
如果发现锁表,可以按照id给kill掉

18. trycatch放在for循环的里面还是外面好

4382

被折叠的 条评论
为什么被折叠?



