| 优先级 | 运算符 | 结合性 |
|---|---|---|
| 1 | ()、[]、 . |
从左到右 |
| 2 | ! 、+(正)、 -(负)、 ~、 ++ 、— |
从右向左 |
| 3 | * 、/ 、% |
从左向右 |
| 4 | +(加) 、-(减) |
从左向右 |
| 5 | << 、>>、 >>> |
从左向右 |
| 6 | < 、<= 、> 、>= 、 instanceof |
从左向右 |
| 7 | == 、!= |
从左向右 |
| 8 | & |
从左向右 |
| 9 | ^ |
从左向右 |
| 10 | | |
从左向右 |
| 11 | && |
从左向右 |
| 12 | || |
从左向右 |
| 13 | ?: |
从右向左 |
| 14 | = 、+=、-=、*=、/=、%=、&=、|=、^=、~=、<<=、>>=、>>>= |
从右向左 |
- Java12
- 多线程11
- SpringCloud8
- 设计模式8
- MQ7
- Mybatis7
- SpringBoot7
- mysql7
- Jvm6
- Redis6
- zookeeper6
- 工具6
- Spring5
- 工作流4
- Docker3
- Nginx2
- SpringMvc2
- Dubbo1
- Netty1
一,日志架构历史

1.1log4j
很多年前,一个叫 Ceki Gülcü 的大佬在一个项目中开发跟踪 API,这套跟踪 API 逐步演变成 log4j, 大概1999年,log4j 成为 Apache 的一员。
一,结论
| 修饰符 | 当前类(案例1) | 同一包内(案例2) | 子孙类(案例3) | 子孙类(不同包)(案例4) | 其他包(案例5) |
|---|---|---|---|---|---|
| public | Y | Y | Y | Y | Y |
| protected | Y | Y | Y | Y/N(案例4.1) | N |
| default | Y | Y | Y | N | N |
| private | Y | N | N | N | N |
一,FastJson反序列化和lombock注解
1,报错信息:
com.alibaba.fastjson.JSONException: default constructor not found
2,问题描述:
lombock的@Builder注解会自动生成全参构造,从而导致默认的无参数构造丢失,如果此时结合JSON的反序列化JSON.parseObject(jsonString,calss);方法就会报错。
3,解决方式:
使用@Builder注解时,同时添加无参和有参构造
假设两个人A、B两个情报员,需要通过书信交流情报。AB双方想要真正交流情报,首先需要建立交流渠道、需要确保自己能发(SYN)且别人能收(ACK):
二次握手:
A:“你能收到我写的信吗?”(A:SYN)
B:“我能收到你写的信!你能收到我写的信吗?”(B:ACK-B:SYN)
三次握手:
A:“你能收到我写的信吗?”(A:SYN)
B:“我能收到你写的信!你能收到我写的信吗?”(B:ACK-B:SYN)
A:“我也能收到!”(A:ACK)
四次握手:
A:“你能收到我写的信吗?”(A:SYN)
B:“我能收到你写的信!”(B:ACK)
B:“你能收到我写的信吗?”(B:SYN)
A:“我也能收到!”(A:ACK)
好的,我们现在解释一下常见的问题。
问题1:为什么TCP二次握手不可以?
根据二次握手中A和B的交流、可以发现A可以确定自己能发(SYN)、B能收(ACK),但是B只能确定自己能发(SYN),A能不能收(ACK)到这就不确定了。试想一下你和你朋友写信,一直没收到朋友的回信,你还会继续写下去吗,你会怀疑自己是不是发的地址不对,或者朋友没有收到信,再说写下去也是白写,平白浪费时间。
问题2:为什么不是四次握手?
根据四次握手中A和B的交流、可以发现A可以确定自己能发(SYN)、B能收(ACK),B也能确定自己能发(SYN),A能收(ACK)到。那为什么不采用四次握手?因为B家没钱,为了节省钱,就写了一封信做了两件事,回答朋友的问题并问出自己的问题。
一,java异常
1.1 定义
异常就是有异于常态,和正常情况不一样,有错误出现。在java中,阻止当前方法或作用域的情况,称之为异常。
1.2 异常的分类
- 运行时异常:
RuntimeException类极其子类表示JVM在运行期间可能出现的错误。编译器不会检查此类异常,并且不要求处理异常,比如用空值对象的引用(NullPointerException)、数组下标越界(ArrayIndexOutBoundException)。此类异常属于不可查异常,一般是由程序逻辑错误引起的,在程序中可以选择捕获处理,也可以不处理。 - 非运行时异常:Exception中除
RuntimeException极其子类之外的异常。编译器会检查此类异常,如果程序中出现此类异常,比如说IOException,必须对该异常进行处理,要么使用try-catch捕获,要么使用throws语句抛出,否则编译不通过。(不能只使用throw并没有处理异常) - 错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
一,java对象的拷贝
将一个对象的引用复制给另一个对象,一共有三种方式。第一种是直接赋值,第二种方式是浅拷贝,第三种是深拷贝,这三种方式实际上都是为了拷贝对象。
1.1 直接赋值
直接赋值是通过=进行赋值操作的,直接赋值对于不可变类而言相当于深拷贝,常见的不可变类八个基本类型的包装类和String类都属于不可变类。
案例1,不可变类的赋值操作:
public static void main(String[] args) {
Integer a = 1;
String b = "1";
Integer c = a;
String d = b;
System.out.println("修改前c:"+b); // 输出 1
System.out.println("修改前d:"+bb);// 输出 1
a = 2;
b = "2";
System.out.println("修改前c:"+b);// 输出 2
System.out.println("修改前d:"+bb);// 输出 2
}
一,String字符串常量池
1.1 字符串常量池的设计思想
- 字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建 字符串,极大程度地影响程序的性能
- JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化 为字符串开辟一个字符串常量池,类似于缓存区创建字符串常量时,首先查询字符串常量池是否存在该字符串存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中
1.2 三种字符串操作
①,直接赋值字符串
String s = "zyh"; // s指向常量池中的引用
一,HashMap原理
1.1 数据结构
从结构实现来讲,HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,如下如所示:
从源码可知,HashMap类中有一个非常重要的字段,就是 Node<K,V>[] table,即哈希桶数组
transient Node<K,V>[] table;
一,背景介绍
由阿里的电商业务规则、表达式(布尔组合)、特殊数学公式计算(高精度)、语法分析、脚本二次定制等强需求而设计的一门动态脚本引擎解析工具。
在阿里集团有很强的影响力,同时为了自身不断优化、发扬开源贡献精神,于2012年开源。
QLExpress脚本引擎被广泛应用在阿里的电商业务场景,具有以下的一些特性:
- 线程安全,引擎运算过程中的产生的临时变量都是threadlocal类型。
- 高效执行,比较耗时的脚本编译过程可以缓存在本地机器,运行时的临时变量创建采用了缓冲池的技术,和groovy性能相当。
- 弱类型脚本语言,和groovy,javascript语法类似,虽然比强类型脚本语言要慢一些,但是使业务的灵活度大大增强。
- 安全控制,可以通过设置相关运行参数,预防死循环、高危系统api调用等情况。
- 代码精简,依赖最小,250k的jar包适合所有java的运行环境,在android系统的低端pos机也得到广泛运用。