延时队列的实现方式
延时队列,是一种有定时器的队列。比如商品订单支付失效,电影票锁座时间等,订单需要经过一段时间没有支付时要变为失效状态。延时队列的实现各种各样,比如JDK自带的DelayQueue,Redis、消息队列等,以下详细描述。
实现DelayQueue接口实现java.util.concurrent.Delayed接口中的getDelay方法和compareTo方法,前者为了获取剩余失效时间,后者用来比较谁先超时。例子:
12345678910111213141516171819202122232425262728293031323334353637@Datapublic class Order implements Delayed { private String id; private String name; /** 创建时间*/ private Long createTime; /** 持续时间*/ private Long time; /** 结束时间*/ private Long endTime; public ...
自定义starter
我们常常将一些通用的功能封装成Jar包,供不同的项目使用。同样在SpringBoot的开发中,也可以将一些通用的功能封装,根据SpringBoot的自动装配的约定,可以封装自己的starter,然后在Spring Boot环境中完成一些通用功能的注入。
原理哪些Bean可以自动装配首先,会寻找@Configuration注解标注的类,添加@Conditional条件注解约束什么时候可以被装配,通常会用@ConditionalOnClass和@ConditionalOnMissingBean,相关的类能找到,并且没有声明的时候注入。
如何定位要装配的Bean检查Jar包META-INF/spring.factories下的文件,是否有声明:
123org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\com.mycorp.libx.autoconfigure.LibXWebAutoConfigur ...
Git操作命令备忘
常用的Git命令拾遗。
同步一个fork场景:A同学fork了B同学的一个仓库,A在本地进行了修改,同时B也进行了修改。A这是想向B提交一个PR,那么需要先拉取B的更改,并合并到自己的仓库,然后再发起PR,那么如何同步呢。
1.将本地仓库关联到远程fork的那个仓库使用命令:git remote -v查看远程,可以看到你只有自己仓库的地址:
123$ git remote -vorigin git@github.com:abumaster/hello-world.git (fetch)origin git@github.com:abumaster/hello-world.git (push)
那么要做的是,关联你foke的那个仓库地址,即设置上游地址:
123456git remote add upstream https://github.com/ckatgit/hello-world.git$ git remote -vorigin git@github.com:abumaster/hello-world.git (fetch)origin git@github.co ...
http状态码
http的请求方法已经状态码的规范,转自,http接口设计指北。
请求方法
如果请求头中存在 X-HTTP-Method-Override 或参数中存在 _method(拥有更高权重),且值为 GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD 之一,则视作相应的请求方式进行处理
GET, DELETE, HEAD 方法,参数风格为标准的 GET 风格的参数,如 url?a=1&b=2
POST, PUT, PATCH, OPTIONS 方法
默认情况下请求实体会被视作标准 json 字符串进行处理,当然,依旧推荐设置头信息的 Content-Type 为 application/json
在一些特殊接口中(会在文档中说明),可能允许 Content-Type 为 application/x-www-form-urlencoded 或者 multipart/form-data ,此时请求实体会被视作标准 POST 风格的参数进行处理
关于方法语义的说明:
OPTIONS 用于获取资源支持的所有 HTTP 方法
HEAD 用于只获取 ...
分布式锁的三种实现方式
分布式系统中,操作共享资源的时候,需要用到分布式锁,来保证数据的一致性。常用的分布式锁有三种实现方式:
基于数据库实现;
基于Redis的实现;
基于Zookeeper实现。
基于数据库实现分布式锁共享资源大部分情况下是数据库中的数据,比如商品的增减,账户金额的增减。因此,可以在sql层面上,利用数据库的锁来实现分布式锁。
悲观锁悲观锁,认为任何一条操作都可能存在冲突,例如MySQL提供了sql语句 + for update手动加上排它锁,避免了多个服务对数据库的更新。sql语句中的条件加上索引,否则会锁整个表。
乐观锁类似Java并发中的CAS操作,在数据库表中添加也给额外的version字段,每次更新操作,version字段加一,更新的时候会比对数据库中version与查出的version是否一致,不一致则不能更新。
基于Redis实现分布式锁简单的API方式Jedis中提供了一个setnx的API,当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。expire设置key的过期时间,del删除指定的key。所以操作资源前获 ...
work
工作的时候总会有这么一种感觉:重复、简单、没有技术含量,学习了这么多年,却在办公室每天做这么没有技术含量的工作,没错,这就是dirty work了。刚入职时却是在做这些,这些并不可怕,可怕的是,工作了几年,看什么工作都是dirty work,怎么看都是没有技术含量的垃圾工作,永没有特别牛逼的项目来做。一直这种念头,你觉得你是最聪明的,那是因为你进错了房间。哪怕是简单的工作,总有人能做出彩,追本溯源。让人看到,不觉让人直呼卧槽,牛逼。交给我,我估计又会抱怨,这是什么垃圾啊,烦死了。这不是能力的问题了,是态度的问题,往往最怕的就是态度出问题。思想建设决定上层建筑,以此为戒。做就做好。
几种树对比
树结构,是一种常用的数据结构。数据库中的索引,Map中的底层存储,极大提升了数据的检索效率。比如常见的B树、红黑树,都具有不同的特性,优缺点,应用于不同的场景,以下介绍常用的树的特点及其应用。
平衡二叉树概念平衡二叉树(Balanced BinaryTree)又被称为AVL树,是一棵空树,或它的左右两个子树的高度差的绝对值不超过1,并且左右子树都是一棵平衡二叉树。
特点针对普通的二叉树添加了平衡因子的限制,即左右子树的高度差为1。如果不满足,则要通过一定的策略进行调整。增加这个策略的原因是为了通过二分法提升数据检索的效率,避免极端情况下树往一个方向偏,查询变成线性查找。特点如下:
非叶子节点最多拥有两个子节点;
非叶子节点值大于左子节点,小于右子节点;
树左右两边的高度差不会大于1;
如果不满足平衡需要通过左旋或者右旋来保证平衡。
B-Tree概念B树是一棵多路平衡查找树,假设树M阶,代表树为M个分叉,树高M。具有如下特点:
按照节点中的关键字递增排序,左小右大;
非叶子节点数>1并且<=M;
关键字数:节点的关键字>=ceil(M/2)-1,并且<= ...
事务隔离级别
事务具有原子性、一致性、隔离性、持久性四大特性,而隔离性顾名思义指的就是事务彼此之间隔离开,多个事务在同时处理一个数据时彼此之间互相不影响,如如果隔离的不够好就有可能会产生脏读、不可重复度、幻读等读现象,为此,隔离性总共分为四种级别:由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题。
概念介绍
脏读:读取到其他事务未提交的数据,未提交意味着这些数据可能会回滚,可能删除,读取到的不是最终的数据;
可重复读:在同一个事务中,最开始和结束的任意时刻读取到同样的数据是一致的;
不可重复读:同一事务的不同时刻读到的数据不一致,往往是由于其他事务对这数据进行了更新操作;
幻读:针对插入操作,A事务对某些内容进行了更改,未提交,B事务插入了与事务A更改前的记录相同的记录行,并在A之前提交,事务A发现刚刚的更改对某些数据没有起作用,但其实是B刚刚插入的数据。
事务隔离级别SQL定义了四种事务隔离级别:
读未提交
读提交
可重复度
串行 ...
Spring事务传播机制
Spring中提供了事务的增强功能,即事务的传播,不属于数据库,是Spring框架提供的,不同的事务传播行为,带来不同的事务特性,Spring提供了其中事务传播行为,在Propagation枚举中进行了定义。
事务传播行为七种事务传播行为:
事务传播行为类型
说明
Propagation.REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。默认的。
Propagation.SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
Propagation.MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
Propagation.REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
Propagation.NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
Propagation.NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
Propagation.NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前 ...
Spring事务失效的情况
在使用Spring事务的过程中,有时会遇到事务失效的情况,那么什么情况下会出现事务失效,遇见这种情况又该如何定位解决呢。
事务失效的原因及解决方法数据库不支持事务这种情况很少出现,一般在一开始就能定位到的。比如Mysql的MyIsam存储引擎就不支持事务,因此如果使用MySQL要确保存储引擎是Innodb的。
Spring中未配置事务管理器如果是springboot项目,可以加上注解@EnableTransactionManagement开启。如果SpringMVC项目可以通过xml配置
123<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"><property ref="you_datasource" name="dataSource"/></bean>
方法不是public类型的事务注解@Transaction ...