Quartz
1. 入门
核心组件
Scheduler
:调度器Job
:接口,特定任务需要实现该接口,并实现execute
方法。JobDetail
:对某个Job
实例的封装Trigger
:Job
的触发器,即指定某个任务在什么情况下执行。JobBuilder
:使用build
方法返回一个JobDetail
对象。使用了设计模式中的建造者模式。TriggerBuilder
TCP的三次握手是基于可用性、安全性、高效性来设计的。
首先我们假设A是请求建立连接端,即客户端;B为服务端。
讨论为什么不是两次。两次的话有以下缺点:
对于二次握手,服务器无法验证客户端真伪,容易造成dDOS攻击。
前两次连接就客户端的初始序列号达成了一致(A发送SYN包,seq=0;B收到,ACK=1,SYN=1,ack=1,seq=0),即客户端知道了自己应该发送第几个序列号给服务端,但服务端无法知道客户端是否接收到了自己发的同步包,即服务端不知道该发第几个序列号给客户端。
防止旧的重复链接造成混乱,比如旧的syn比新的syn先到达服务端。
Java中共有8种基本数据类型,每一个基本类型都有对应的类。由基本数据类型封装成类的过程叫装箱,反过来叫拆箱。比如Integer->int
和int ->Integer
。在Integer这个类中,类加载的时候会在内存中创建一个-128-127的Integer数组,当自动装箱时就会调用Integer.valueOf
这个方法,首先会判断数值是否在这个缓存范围内,不在的话会调用new Integer
方法在内存中创建对象。
1 | public class Test{ |
官方文档地址:https://docs.spring.io/spring-framework/docs/2.0.x/reference/beans.html#beans-constructor-injection
依赖注入(Dependency Injection)指的是某个类中使用到其他类时,我们不直接new,而是可以通过构造器或者setter方法等手段将需要的类作为参数传给使用的类,在合适的时候实现注入。如果没有容器,就需要我们手动去实现何时注入,有了Spring容器之后,容器就会自动帮我们去管理并注入这些依赖项,这就叫控制反转(Inversion of Control),即将bean的控制权交给容器。
Spring中依赖注入主要有两种方式:
1 | public class SimpleMovieLister { |
1 | public class SimpleMovieLister { |
Spring中Bean的作用域可分为:
singleton时容器在启动过程中就会自动创建bean,prototype时,容器会在使用时才会去创建。
Java中实现等待唤醒机制共有三种方法:
synchronized
配合wait
与notify
实现等待唤醒await
,signal
实现等待唤醒LockSupport
类中的静态方法park
、unpark
。前两种方法的缺点:
IllegalMonitorStateException
notify
、后wait
,则等待的线程会无限期等待LockSupport
的优点:
Unsafe
类,通过设置凭证(permit)来实现,permit初始为0,unpark
会使permit数量加一(最多为1),因此重复调用unpark
的效果与调用一次相同;park
方法会使permit数量减一,多次调用可能会造成阻塞。unpark
后park
,则park
不会阻塞线程为什么等待通知要配合锁来使用?
如果没有锁的加入,可能会由于线程调度导致wait的线程错过notify,从而造成该线程无限期阻塞。
1 | import java.util.concurrent.*; |
将重复冗余的代码抽取出来,通过动态代理的方式在程序运行时对程序进行增强和扩展。是面向函数编程的衍生,能够解耦合。
@Aspect
申明这是一个切面类。当一个对象不想引用或不能直接引用另一个对象时就可以通过动态代理来实现。
@Before
前置通知,在切入点方法执行前通知@AfterReturning
@AfterThrowing
@After
后置最终(finally)通知,@Around
环绕通知Around -> Before -> proceed(目标方法执行) -> AfterReturning/AfterThrowing -> After -> Around
1 | Around beginning... |
B树又成多路平衡查找树,B树中所有节点的孩子节点数的最大值成为B树的阶(order)。
一棵m阶B树的组成:根节点、内部节点、叶子节点
一棵m阶B树,或为空树,或为满足如下特性的m叉树:
树中每个节点至多有m个孩子,即最多含有m+1个key,每个节点的key以非降序存放。根节点至少有两个孩子;
除根节点外的所有非叶子节点至少含有ceil(m/2)
个孩子
所有的叶子节点位于同一层,不包含孩子
m的阶数越高,树的高度越小
B+树的叶子节点包含了所有的key。
B+树的内部节点仅存储数据对应的key不存储具体的数据,而完整数据存储于叶子节点中(或者说叶子节点存储了指向完整数据的具体地址),而B树内部节点和叶子节点存储了数据的key和完整的数据,当数据量特别大可能会很占内存
B+树的叶子节点包含了是有序的且用链表进行串联。
B树的key值在树中是唯一的,而B+树允许重复。
在添加、删除节点上。B+树更加高效;在B树中搜索时,可能到不了叶子节点,即在中间节点就找到了目标,而B+树中一定会搜索到叶子节点。
MySQL为何选择B+树而不是B树作为索引?
总的来说hashmap中用到了链表、数组、红黑树这三种数据结构。不同hash值的key放在对应的数组中,当存在hash冲突时,将相同hash值的key用链表保存起来,当链表长度以及所有k-v对的个数达到阈值时,链表就会“树化”为红黑树,以提高查找效率。
区分两个概念:capacity
、size
size
:指的是map中不同key-value键值对的总个数,这个字段会暴露给我们。capacity
:指的是map中buckets的个数,即table数组的长度当我们在初始化一个map的时候,默认负载因子为0.75f
,当size达到0.75 * capacity
时,就会进行扩容,map的扩容是2倍扩容。
table的长度始终都是2的指数次幂,当我们指定的初始化长度不是2的次幂时,会调用tableSizeFor
方法自动找到刚好大于该长度的2的次幂的数。默认初始化时table的长度是16。
缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
3、在根目录_config.yml里添加配置:
jsonContent: meta: false pages: false posts: title: true date: true path: true text: false raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true