zookeeper的分布式锁的实现原理是什么
zk的分布式锁是基于zk的两个特性,第一是顺序节点的特性,第二是临时节点特性。顺序节点是假如多个客户端在某个目录下创建节点,zk会按照客户端发起创建请求的顺序来依次来创建节点,节点的末尾数字是递增的。序号的递增是由zk内部完成的。临时节点的意思是,当某个客户端断开链接时,其创建的节点就会被删除。根据这两个特性我们来模拟zk的分布式锁,比如在商品抢购场景中,一个客户端率先在这个商品id的目录下创建了临时顺序节点。后面的客户端再去这个商品id的目录下创建节点时跟据顺序节点的特性,其序号则会递增。多个客户端都创建了节点,客户端获取当前所有节点的列表,并判断自己的节点的序号是不是最小的,如果是最小的则获取到这个商品的锁。其余的节点则监听比自己小的节点是否存在,进入等待。等到前面的客户端不存在时,其会判断自己是不是最小节点,如果是则获取到了锁,如果不是继续监听比自己小的节点。
zookeeper和redis分布式锁的区别
·redis只保证最终一致性,就是说在redis集群中主从节点的复制是异步的。存在主从复制延迟的情况,比如说一个key set到了redis集群的主节点,然后其从主节点同步到从节点是有延迟时间的。主从切换之后可能有部分数据丢失,在分布式锁的应用场景下可能会丢失锁,所以在强一直性要求的业务中不推荐使用redis分布式锁,推荐使用zk。redis的另一个特点是集群各方法的响应时间均为最低,redis是基于内存io的数据库,所以其相应时间是很低的随着业务数据量的提升它的响应时间会有明显的上升,即使如此其也可以达到它的QPS的最大值。
zookeeper的分布式锁的实现原理是根据其临时顺序节点的特性。临时顺序节点的声明周期是客户端跟zk的连接,连接断开则节点失效。这样会有一种异常情况,当客户端没有主动与zk断开连接,而是因为网络状况导致的断连时,会导致节点失效,数据不一致。在这种情况下zk也无法保证数据的一致性。除此之外zk具有较好的稳定性,响应时间抖动小,但在业务数据量上升的情况下,zk为了保证数据一致性,其响应时间也会有明显的上升。
总结:zk涉及节点的创建同时又要保证数据的强一致性,响应时间相对较长。而redis分布式锁的操作相对简单,同时又不保证数据的强一致性,故其响应时间较短。
mysql如何做分布式锁
mysql做分布式锁是利用其主键唯一的这个特性,例如多个用户抢购同一件商品时,其分布式锁或者主键是商品的id,哪个客户端使用该id先在表中创建了数据,则表明哪个客户端获取到了锁。别的客户端再去创建就会报错,无法获取到锁。获得锁的客户端需要在使用完毕后删除该条数据,释放锁。
计数器算法是什么
计数器算法是在规定的时间周期内,其累计访问次数达到设置的阈值时就触发访问限制。下一个访问周期启动的时候其访问次数清零。
其实现原理是利用了redis的原子自增和设置过期时间的特性。但是其也存在问题,就是在前一个计时周期的后半段,和后一个计时周期的前半段个了超过设置阈值一半的请求。这其实是超过了系统的最大负载,但是因为两拨请求在相应的时间周期内都是符合要求的,从而导致无法拦截。
滑动时间窗口算法是什么
滑动时间窗口算法是为了解决计数器算法的临界值问题而发明的。滑动时间窗口是把时间周期切分成多个小的时间窗口,比如时间周期是一分钟,承载阈值是100,现把间周期划分成四个小块,那么每个小时间窗口也就是15秒的最大承载量就是25。在当前算法下时间临界点的最大访问量是50,明显是小于我们系统的承载阈值的。这样就解决了计数器算法的临界值问题。
漏桶限流算法是什么
就像漏斗一样,漏斗出水的速度取决于漏斗出水口的大小。在漏桶限流算法中,漏桶的容量等于消费速度乘以最大可接受的等待时间。比如消费速度是1,用户最大可接受等待时间是10,那么漏桶的容量就是10。如果超过最大容量,超过的部分就会被抛弃。当请求速度大于系统的处理速度且漏桶容量满时就会触发限流策略,当请求速度小于等于系统的处理速度时,则能正常执行。漏桶算法的缺点,当短时间内爆发大量请求时,漏桶无法处理会全被限流策略拦住。
令牌捅限流算法是什么
在系统中创建一个大小固定的容器也就是令牌桶,系统以恒定的速率向令牌桶中放入令牌。如果有客户端发起请求,就需要现在令牌桶中申请一个令牌,拿到令牌之后才能访问系统。在令牌桶满时,再向令牌桶存放令牌就会被抛弃。当请求速度大于令牌的生成速度,且令牌桶中的令牌被申请完了,就会触发限流策略。相对于漏桶算法而言,令牌桶的容量可以做的比较大,能处理较大的流量。
设计微服务是遵循的原则是什么
单一职责原则:就是让每个服务独立的有界限的进行工作,每个服务只关注自己的业务,做到高内聚。
服务自治原则:每个服务要能做到独立开发,独立测试,独立构建,独立部署,独立运行。与其它服务彻底解耦。
轻量级通信原则:在微服务系统中,一个业务功能的实现需要由多个服务之间的调用来完成。那么服务之间的调用最好采用轻量级的,比如restfull风格的接口,或者利用消息队列进行通信,这样可以发挥各个服务的特长。
粒度进化原则:对每个服务的设计其实没有统一的标准,需要根据业务情况具体分析不要为了设计而设计。服务粒度的发展根据用户量的发展而发展。
cap是什么
c:一致性,数据在多个系统中保持一致
a:可用性,系统对外提供服务需要保证可用
p:分区容错性,当网络发生分区时仍然要保证可用性
在实际应用场景中,拥有网络通信的不稳定性,所以分区时必然存在的。为了保证一致性就要牺牲掉可用性,为了保证可用性就要牺牲一致性。所以系统一般是保证cp或者ap。
base理论是什么
cap中一般只能保证ap或者cp。(基本可用,软状态,最终一致性)基本可用(不用保证系统中的全部功能可用,保证核心功能可用即可),软状态(弱状态)在保证整体系统可用性的前提下允许数据存在中间状态,允许系统不同节点至今进行通信时存在延时,要保证数据的最终一致性。
2PC提交协议是什么
两阶段提交协议是指在计算机网络或者数据库领域为了使在分布式系统中的所有节点在进行事务提交时保持一致性而设计的一种协议。通常在分布式系统的节点中,每个节点能知道自己的操作是成功还是失败,但却不知道其它节点的操作的执行情况。
当一个事务跨越多个节点时,由于各个节点执行情况的不可见型,为了保证事务的acid特性,就必须引入一个第三方的协调者来监控所有节点的执行情况。并最终指示所有的节点对操作要么提交要么回滚。
两阶段提交协议总体可以概括为,各个节点把执行结果告知协调者,再由协调者根据整体的操作结果做出决策,判断所有操作是提交还是终止。
两阶段提交的第一阶段是准备或者所投票阶段:在准备阶段,事务协调者向每个参与者发送prepare消息,参与者要么直接返回失败要么执行本地事务并且记录本地事务的redolog和undolog,此时事务并不提交并返会可以执行的结果。
第二阶段是提交执行阶段里面包括提交和回滚:事务协调者根据各个参与者的返回的结果判断整体的执行情况并决策下一步的操作。当参与制返回的结果是失败或者返回结果超时时,事务协调者认为执行失败下发回滚命令,否则就发送提交的命令。参与者根据协调者的命令进行提交或者回滚操作。执行完成之后释放资源,包括数据库或者锁。
两阶段提交协议的缺点
1.同步阻塞问题:在执行的过程中所有参与的节点都是事务阻塞性的。在准备阶段时所有的参与者获得了共享资源的锁,这时候其他的节点就处于阻塞等待状态
2.单点故障:协调者在整个流程中起到了至关重要的作用,当协调者出故障时,参与者无法获取后续执行,系统会进入瘫痪状态。
3.数据不一致:在第二阶段,协调者向所有的参与者发送提交命令时,可能会出现部分参与者接收不到命令的情况,导致数据不一致。
针对以上问题的解决方案是补偿机制,可以通过手动或者脚本的方式进行补偿。当脚本发现服务之间存在数据不一致的情况时,就会触发补偿机制使数据一致。
三阶段提交协议是什么
第一:can commit,协调者向参与者发送can commit请求,参与者如果可以提交就返回yes,否则就返回no
第二:pre commit,在上一阶段参与者都返回yes的情况下,协调者向参与者发送pre commit请求,参与者执行相应的处理,并记录redolog和undolog到本地事务,此时事务并不提交,如果一切正常就向协调者发送yes并等待协调者的do commit请求,假如超时未接到协调者的后续执行,参与者就会提交并且释放资源。
第三:do commit,在上一阶段的基础上,如果没有参与者返回异常或者超时,协调者向所有参与者发送do commit请求。参与者接到请求后提交事务,并释放资源。如果参与者有异常,协调者则向所有参与者发送终止命令,参与者回滚事务,并且释放资源。
两阶段请求和三阶段请求的区别
第一,三阶段比两阶段多了个can commit步骤,减少了不必要的资源浪费
第二,更完善的超时机制,在两阶段时只有协调者有超时机制,而在三阶段中协调者和参与者都有超时机制
tcc解决方案是什么
t:try,业务检查阶段,业务检查和校验,资源预留,也可以直接执行业务
c:confirm,确认阶段,若try阶段业务反馈正常,则进行提交操作,并释放资源
c:cancel,取消执行,若try阶段业务反馈异常,则全部取消回滚,并释放资源
tcc空回滚是为了解决什么问题
是解决try阶段执行者因为某种原因没有接到协调者的try请求,协调者当然也无法接到执行者的回复,进入超时cancel的场景。
这时候协调者向所有执行者发送中断回滚请求,而那个没有接到try请求的执行者没有执行任何业务,只能做空回滚操作。
如何解决tcc幂等的问题
幂等问题主要集中try阶段:加入执行者在try阶段执行成功之后要么执行confirm要么执行cancel,但是在执行confirm的时候失败了,try有个re try机制,这时候就有可能引起幂等问题cancel也是同样的道理。解决幂等问题的办法就是通过执行状态判断,在执行之前先判断执行状态,如果状态为true则不重复执行。同时也要使用分布式锁来控制业务执行的一致性。
如何解决tcc中的悬挂问题
悬挂问题是指在tcc的try阶段,由于执行者在处理其他业务逻辑没有来得及及时处理协调者的try请求,导致超时,这时候会进入到cancel阶段。正常来讲没有执行try操作的执行机是要执行空回滚的。执行了空回滚之后,再去处理try请求,申请并预留资源。这时候因为没有协调者的调度,资源得不到释放就会进入悬挂阶段。为了解决这个这个问题在执行try操作之前先做下判断,判断当前tcc的第二阶段是否已经执行完了,如果执行完了则不进行try操作。
可靠消息服务方案是什么
第一:可靠消息,发起方一定要把消息传递到消费方
第二:消息最终一致性
java面向对象的特征有哪些
封装:封装内部实现的机制,封装好的方法可以重复使用,增加了代码的复用性
继承:子类继承父类的属性和方法,增强代码的复用性
多态:分为编译时多态的运行时多态,重写是运行时多态,重载是编译时多态。运行时多态子类重写父类的方法,父类拥有子类的引用。增强了代码的灵活性,健壮性。
arraylist和linkedlist的区别是什么
arraylist底层数据结构是数组,数组的特性决定了其良好的随机访问的特性,所以ArrayList适合随机访问。
linkedlist的底层数据结构是双向链表,链表的特性决定了其对插入和删除的支持比较好,所以linkedlist适合随机插入和删除。
高并发下的集合有哪些问题
第一代集合比如vector和hashtable是线程安全的,其保证线程安全的方式是使用synchronized,使用这样的方式可以保证线程安全,但是执行效率比较低
第二代集合为了提高执行效率加了线程不安全的类,比如arraylist,hashmap,线程不安全但是性能比较好,在需要线程安全的场景下可以使用collections的synchronized方法把线程不安全的集合转化为线程安全的集合。转化为线程安全的方式仍然是使用synchronized,在当时执行效率依然不高。
第三代线程安全的集合做了升级,主要使用了自旋锁,提高执行效率。比如concruenthashmap
jdk1.8的新特性有哪些
接口支持default关键字,允许有默认方法
支持lambda表达式,简化编程
stream链式编程,map,filter,sort等
支持多重注解
java的接口和抽象类有哪些区别
抽象类:
抽象类可以有构造方法
可以有抽象方法和具体方法
抽象类可以定义成员变量
有抽象方法的类一定是抽象类,但抽象类不一定有抽象方法
抽象类中可以包裹静态方法
一个类只能继承一个抽象类
接口:
接口中不能定义构造方法
接口中定义的成员变量实际上都是常量
接口中的方法都是public
接口中不能有静态方法
一个类合一继承多个接口
抽象类更重要的是描述的是一个抽象的概念,例如动物,车,房子
而接口更倾向于描述的是行为,或者特征,比如飞,游泳等。
acid是靠什么来保证的
原子性:是由undolog来保证的,记录了要回滚的日志信息,事务回滚时撤销未提交的sql
一致性:由其他三大特性来保证
隔离性:事务之间彼此是隔离的,事务隔离级别有读未提交,读已提交,可重复度,序列化。事务隔离是由mvcc,多版本并发控制来保证。
持久化:redolog保证数据的持久化,即使是数据保存失败redolog日志保存成功数据也不会丢失。持久化表示事务执行成功之后数据是永久存储的。
binlog,两阶段提交–第一阶段准备阶段。
mvcc的工作原理
mvcc主要解决读写问题,读不阻塞写,写不阻塞读
读已提交rc,可重复读rr使用mvcc机制来保证
记录中隐藏字段:最近被修改的事务的编号,事务回滚指针,隐藏主键
undolog回滚日志,记录事务的历史数据
readview 读视图,活跃事务id列表,最小活跃事务id,当前已提交的事务id,快照读时未被使用的最小事务id
判断的逻辑是以最小活跃事务id和最小未被使用的事务id为上下边界(最小活跃id,最小未使用id)
当已提交事务id小于左边界,可以看得见,大于等于右边界 看不见
当已提交的事务id在上述区间内,则判断,已提交的事务id在不在活跃事务列表里面,在列表里面,看不见,不在看得见。
读已提交每次快照读都会创建readview
可重复度只有事务的第一次快照读的时候才会创建readview
beanfactory和applicationcontext的区别和联系
联系:
spring提供了两种不同的ioc容器,一种是beanfactory另一种是applicationcontext。beanfactory是bean工厂,而applicationcontext是应用程序上下文。他们都是接口,同时applicationcontext是beanfactory的子接口,它继承或者说实现自beanfactory。他们都可以用xml文件的方式来进行相关的配置,也支持属性的自动注入。beanfactory和applicationcontext都支持getbean方法获取bean对象,使用方式相同。
不同点:两者创建bean对象的时机不一样,beanfactory在调用getbean方法的时候才去实例化对象,而applicationcontext在启动容器的时候就是实例化单例bean,不会等到调用getbean的时候才去实例化。
beanfactory不支持国际化,而applicationcontext支持。
beanfactory不支持监听器,而applicationcontext支持
beanfactory的核心实现是xmlbeanfactory,而applicationcontext的核心实现是classpathxmlapplicationcontext
web容器的环境我们使用的是webapplicationcontext
总体来说applicationcontent比beanfactory提供了更加丰富的功能。
hashmap和hashtable的区别
hashmap是线程不安全,hashtable线程安全
hashmap适合单线程执行,执行效率高
hashtable是个多线程执行,执行效率较低
hashtable不允许键值有空置,而hashmap允许
hashtable的默认长度是11,扩容的长度是原长度乘2加一而hashmap的默认长度是16扩容的长度是2的指数倍
二者的父类不同,hashtable的父类是dictionary,而hashmap继承自abstractmap。二者同时又实现了map接口
hashmap有哪些线程安全的方式
第一种:collections.synchronizedmap(map),这种方式返回的不是hashmap而是一个Map的实现,这种方式实际上还是使用了synchronized方式加锁,执行效率不高
第二种:使用concurrenthashmap,而这种方法实际上是一种分段加锁的方法,执行效率较高
hashmap在扩容上有哪些优化
在jdk1.7版本时,每次扩容时都要对元素进行rehash操作来确定元素的新位置。这种方式在数据量比较大时运算量较大,执行效率比较低。
在jdk1.8后,借助了2倍扩容机制。更新了机制之后元素的位置要么在原位置,要么在原位置加上原数组长度的位置。在扩容是只需要判断当前位置跟hash值的与运算的结果的高位是0还是1,是0则保持原位,是1则新位置是原位置加原数组的长度。
mybatis插件运行原理及开发流程
暂时略,后续补充
mybatis的优缺点有哪些
简单易学,容易上手,基于sql编程
与jdbc相比,减少了百分之50以上的代码量,消除了jdbc大量的冗余代码,不需要手动开关连接
很好的与各种数据库兼容,因为mybatis使用jdbc与数据库连接,只要是jdbc支持的数据库,mybatis都支持,开发人员基本无序考虑数据库之间的差异性
提供了很多第三方插件,比如分页,逆向工程等
能够与spring很好的集成
mybatis相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,sql写在xml里,从程序代码中彻底分离。
提供xml标签,支持编写动态sql语句
提供映射标签,支持对象与数据的orm字段关系映射
提供对象关系映射标签
缺点:
sql语句编写工作量较大,尤其是字段多,关系表较多时更是如此,对开发人员的sql语句功底有一定的要求
sql语句依赖数据库,导致数据库移植性差,不能随意更换数据库。
mybatis和hibernate有什么区别
相同点:都是orm框架,两者都是可以通过sessionfactorybuilder由xml配置文件生成sessionfactory,然后由sessionfactory生成session,最后由session来开启执行事务和sql语句。
其中sessionfactorybuilder、sessionfactory和session的声明周期差不多。两者都支持jdbc和jta的事务处理。
不同点:hibernate是全自动的,mybatis是半自动的。hibernate完全可以通过对象关系模型来实现对数据库的操作,拥有完整的javabean对象和数据库的映射结构来自动生成sql。而mybatis仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写sql来实现和管理。
hibernate的数据库移植性远大于mybatis,hibernate通过他强大的映射结构和hql语言,大大降低了对象与数据库的耦合性。而mybatis需要手写sql,因此数据库的耦合性直接取决于程序员写sql的方法,如果sql不具有通用性,而用了许多某数据库特有的sql语句的话,移植性也会随之降低很多,移植成本很高。
hibernate具有完整的日志系统,mybatis则欠缺一些。hibeinate日志系统非常健全,涉及广泛包括sql记录、关系异常、优化警告、缓存提示、脏数据警告等;而mybatis在日志方面除了基本记录功能之外其他,则薄弱了许多,
mybatis相比hibernate需要多关心许多细节,hibernate相比mybatis来说配置复杂,学习成本高。正因为配置简单,所以在一些细节上可能就会有疏忽。忽略细节会导致项目前期bug比较多,因此开发出相对稳定的系统较慢,而开发出来软件却很快。
mybatis中的#{}和KaTeX parse error: Expected 'EOF', got '#' at position 7: {}的区别 #̲{}表示是预编译模式,{}是字符串替换
使用#{}可以有效的防止sql注入,提高系统的安全性
mysql的事务隔离级别
读未提交,导致脏读幻读不可重复度
读已提交,导致不可重复读
可重复读,幻读情况
序列化,事务串行执行,保证了数据的安全性,但是执行效率非常低
脏读:能看到别的事务没有提交的数据
幻读:当次事务修改的某个值被其他事务又修改了,仿佛有自己还没有修改这个数据的错觉
不可重复读:同一条sql两次执行的结果不一样
mysql的复制原理是什么
首先master服务器会将数据的改变记录到binarylog里面
slave服务器会在一定的时间间隔内探测master服务器的binarylog是否发生改变,如果有改变则开启i/o线程请求获取binarylog
madter服务器为每个slave服务器启动dump线程用于发送binarylog数据。slave服务器把master服务器发送过来的数据保存到中继日志里,启动一个sql线程读取数据,在本地重放sql操作。结束后线程进入休眠状态,等待下一次唤醒。
主从模式和主备模式的区别
主从模式是主从都可以访问,但是主节点负责写,从节点负责读。
主备模式中只有主节点可以访问,负责读写
mysql聚簇索引和非聚簇索引的区别
mysql的索引类型跟存储引擎是相关的,innodb存储引擎数据文件跟索引文件全部放在ibd文件中,而myisam的数据文件放在myd文件中,索引放在myi文件中。聚簇索引和非聚簇索引的区别就是索引是否跟数据文件放在一起。
innodb存储引擎在进行数据插入是,数据必须要跟索引放在一起。如果有主键就使用主键,没有主键就使用唯一键,没有唯一键就使用6字节的rowid,因此跟数据绑定在一起的就是聚簇索引,而为了避免数据冗余存储,其它索引的叶子节点存储的都是聚簇索引的key值,因此innodb中既有聚簇索引,又有非聚簇索引。而myisam中仅有非聚簇索引。
mysql的索引的基本原理
引入索引的原因:提高查询效率,加快数据访问的速度
什么是索引:索引在mysql中也是一种键,是存储引擎用于快速找到记录的一种数据结构。索引是优化查询速度最有效的手段。
索引的数据结构:mysql主要使用两种结构,B+tree索引和hash索引
innodb引擎默认使用的索引结构是B+tree
memory默认使用的是hash索引
两种的优缺点:
hash索引:单条查询快,范围查询慢
b+tree索引:单条查询速度不如hash但是其更适合排序等操作。
// 深入了解b+tree
mysql的索引结构有哪些,各自的优劣是什么
hash结构:单条快,范围慢
b+tree结构:单条慢,范围快
b+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差不超过一,而且同层级的两节点间有指针相关联。在b+tre上进行常规检索时,从根节点到叶子节点的搜索效率基本相当,不会出现大幅波动。而且基于索引的顺序扫描时,也可以利用双向指针快速左右移动,效率非常高。
哈希索引就是采用一定的hash算法,把键值换算成新的哈希值,检索时不需要类似b+树那样从根节点到叶子节点逐级查找,只需要一次哈希算法即可立即定位到相应的位置,速度非常快。
如果是等值查询,那么hash索引有着绝对的优势,只需要经过一次算法就可以找到相应的键值,前提是键值都是唯一如果键值不是唯一的,就需要根据键所在的位置,沿着链表往后扫描,直到找到相应的数据。
如果是范围查询,hash索引就没有优势了,因为hash索引是无序存放的。
hash索引也无法利用索引完成排序,以及like这样的部分模糊查询,不支持多列联合索引的最左匹配规则。
b+树的关键字检索比较平均,不向B树那样波动大,再有大量重复键值的情况下,哈希所有的效率也是极低的,因为存在hash碰撞的问题。
mysql锁的类型有哪些
基于锁的属性分类:共享锁,排他锁
基于锁的粒度分类:行级锁(innodb),表级锁(innodb,myisam),页级锁(innodb),记录锁,间隙锁,临建锁
共享锁(share lock):共享锁又称读锁,简称s锁。当一个事务为数据加上读锁之后,其他的事务只能对该数据加读锁,而不能加写锁。直到所有的读锁都释放之后其他事务才能加写锁。共享锁主要是为了支持并发的读取数据,读取数据的时候不支持修改,避免出现重复读的问题。
排他锁:排他锁,又称写锁,简称x锁。当一个事务为数据加上写锁时,其他的请求将不能再为数据加上任何锁,直到该锁释放之后,其他事务才能对相关数据加锁。排他锁的目的是修改数据的时候不允许其他事务读取和修改,避免出现脏读问题。
表锁:表锁是指上锁的时候锁住整个表,当下一个事务访问该表的时候必须等前一个事务释放了锁才能对表进行访问。特点是力度大,加锁简单,容易冲突
行锁:行锁是指上锁的时候锁住表的某一行或者多行记录,其他事务访问表的时候只有被锁住的几行不能被访问,其余的可以正常访问。特点:粒度小,加锁麻烦,不易长途,比表锁的并发高。
记录锁:记录锁是行锁的一种,只不过记录锁的范围知识表中的某一条记录,记录锁是说事务在加锁之后只锁住表中的某一条记录,加了记录锁之后可以避免数据在查询的时候被修改的不可重复读问题,也避免了在修改的事务未提交之前被其他事务读取脏数据。
页锁:页锁是数据库中粒度介于行锁和表锁之间的一种锁,表锁速度快但冲突多,行锁冲突少,但速度慢。所以有了折中的页锁,一次锁住相邻的一组数据。特点:开销和加锁时间介于表锁和行锁之间,会出现死锁。锁定粒度介于行锁和表锁之间,并发度一般。
间隙锁:也是行锁的一种,间隙锁是在事务加锁之后锁住表记录的某一区间,当表的相邻id之间出现间隙,则会形成一个区间,遵循左开右闭的原则。范围查询并且查询未命中记录,查询条件必须命中索引、间隙锁之后出现在可重复度的事务隔离级别中。
临键锁:也属于行锁的一种,并且他是innodb行锁默认算法。是记录锁和间隙锁的组合,临键锁会把查询出来的记录锁起来,同时也会把该查询范围内的所有间隙空间也锁住,再之它会把相邻下一个区间也锁住。
mysql为什么要需要主从同步
读写分离:主从模式
数据热备:主备模式
架构扩展:提高单机i/o性能,分库分表
mysql执行计划
explain:
关键字段
id:相同id,顺序执行,不同id,id越大,优先级越高
table:执行查询的表明:
type:表示sql的执行效率:执行效率system>range>index>all
key: 表示执行过程中用到的索引
rows:读取数据的预估值
数据库优化的方式
使用执行计划分析sql的执行情况
不要使用select * 查询
查询一条数据的时候使用limit 1
建立合适的1索引
避免在where字句中对字段进行表达式操作
对于联合索引来说遵守左前缀法则
哪些情况会导致sql索引失效
使用!=
左右类型不一致
使用运算符
模糊搜索
not null
spring spring mvc spring boot的区别是什么
spring是个轻量级的一站式java开发框架,核心是ioc和aop。
spring mvc是在spring的基础上的一个web框架,主要处理web开发时的路径映射和视图渲染,属于spring框架中web开发层的一部分。
spring boot是一个脚手架,其核心思想是约定大于配置,自动装配,使用spring boot工程可以省去大量的基于xml的配置,其着重于后端接口开发。
spring boot自动装配原理
自动装配简单来说就是spring工程自动注入第三方组件里面的bean到ioc容器中,在springboot工程开发过程中,我们只需要引入对应的starter spring boot就会帮我们把对应的bean自动注入到容器里面。spring boot工程自动装配的是入口是@SpringbootApplication这个这个,带有这个注解的类是整个工程的启动类。这个注解是个符合注解,其中最重要的是enableconfiguration这个注解,这个注解导入了autoconfigurationimportselector类,在这个类里面,有个selectimports方法,这个方法最终使用springfactoryloader获取spring支持的所有第三方组件的配置类,在springfactoryloader类中有个静态常量,factory.proterties。这里面定义了spring工程支持的所有第三方组件的配置类。配置类上有conditional注解,用于判断是否引入该组件。
springbootapplication-enableautoconfiguration-import(autoconfigurationimportselector)-selectimports-调用springfactoryloader类-静态常量-fatory.properties-定义了spring所有支持的配置类-conditional注解来判断工程是否引入了相应的组件,如果引入了则把相关的bean注入容器。
springmvc的工作流程是什么
浏览器-http请求-dispatchservelet-handdlermapping-handlleradapter-controller-serivice-返回modelandview-dispatchservelet-viewresolver-view解析-http响应-浏览器。
spring mvc的九大组件有哪些
handlermapper
handleradapter
handlerexceptionresolver:全局异常处理器
viewresolver
localeresolver:国际化
themeresolver:主题解析
multupartresolver:处理上传请求
requesttoviewnametranslator
flashmapmanager:用于在重定向中传递参数
spring的核心
ioc:控制反转
aop:面向切面编程
spring中的事务传播机制
7中传播机制:
required: 默认传播机制,如果没有事务则创建事务,有就加入
supports:有事务就加入,没有事务就以非事务的方式运行
mandatory:有事务就加入,没有事务则抛异常
required_new: 创建新的事务,有事务则挂起原事务
not_supported: 非事务的方式运行,有事务则挂起
never:不使用事务,有事务抛异常
nested: 如果当前事务存在,则在嵌套事务中执行,没有以required方式运行
spring框架中的单例bean是线程安全的吗
spring中的bean对象默认是单例的,框架没有对bean进行多线程的封装处理
如果bean是有状态的,那么就需要开发人员自己来保证线程安全,最简单的方法就是把单例模式改成原型模式,这样每次请求bean对象就相当于是创建新的对象来保证线程安全。
有状态就是有数据存储功能。
无状态就是不会存储数据,我们的controller,service,dao都不是线程安全的,只是调用里面的方法,而且多线程调用同一个实例的方法,会在内存中遍历复制;这是线程自己的工作内存,是最安全的。
因此在进行使用的时候不要在bean里面声明任何有状态的实力变量,或者类变量。如果必须如此,那应该使用threadlocal把变量变成线程私有,如果bean的实例变量或者类变量需要在多个线程之间共享,那么只能使用synchronized,lock,cas等这些实现线程同步的方法了。
spring框架中使用了哪些设计模式
单例模式:spring bean默认就是单例模式
代理模式:aop
工厂模式:beanfacory,
适配器模式:handleradapter
spring中事务的隔离级别有哪些
spring本身不提供事务的隔离级别,事务隔离级别取决于使用的数据库,比如使用mysql就支持,读未提交,读已提交,可重复读,序列化。
如果spring和数据库中设置的隔离级别不一致,以spring中配置的隔离级别为准。
spring中的事务的实现原理
在spring中有两种方式可以实现事务,一种是编程式事务,就是用代码逻辑来实现事务。另一种是声明式事务,通过@transactional注解来实现。一般不使用编程式事务,而是使用第二种。其实事务操作是spring aop的一个核心体现,当一个方法添加事务注解之后,spring会基于这个类生成一个代理对象。当业务逻辑没有出现问题时,代理逻辑就会提交事务,出现问题时,代理逻辑就会回滚事务,用户可以控制对哪些对象进行回滚操作。
spring事务什么时候失效
bean对象没有被spring容器管理
方法的修饰符不是public
自身调用问题(当前类的方法,调用当前类的方法,不能代理)
数据源没有配置事务管理器
数据库不支持事务
异常被捕获
异常类型错误,或者配置错误
spring是如何简化开发的
基于pojo的轻量级和最小侵入性编程
通过依赖注入和面向接口实现松耦合
基于切面和惯例进行声明式编程比如声明式事务
通过切面和模板减少样板式代码
spring bean的作用域有哪些
singleton单例模式,默认模式,ioc容器仅创建一个bean实例,每次返回的也是用一个
prototype原型模式,可以创建多个bean对象,ioc容器每次返回的都是新的实例
request:该属性仅会对http请求有效,使用该属性定义bean时,每次http请求都会创建一个新的bean,适用于webapplicationcontext环境
session:该属性仅用于http session,同一个session共享同一个bean实例,不同的session使用不同的
global-session:该属性仅用于http session,同session作用域不同的是,所有的session共享一个bean实例
myisqm数据库引擎和innodb的区别
innodb支持事务,行锁和外键,索引的形式包含聚簇索引和非聚簇索引,写效率高,读效率稍低
myisam不支持事务,行锁和外键,支持表锁和全文索引,索引是非聚簇索引,写效率稍低,读效率高
简述mysql索引类型有哪些,以及对数据库性能的影响
主键索引:特殊的唯一索引,一张表只能定义一个主键索引,主键索引里可以有多个列,不允许为空
唯一索引:可以保证数据记录的唯一性,允许为空
普通索引:允许重复值
全文索引:用于全文检索,用于检索值中是否包含某个关键字
联合索引:索引可以覆盖多个列
索引可以提高查询效率
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统性能
会降低插入,删除,更新的速度
索引需要占用物理空间,除了数据表占数据空间之外,每个索引还要占用一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大,如果非聚簇索引很多,一旦聚簇索引发生改变,那么所有的非聚簇索引也会跟着改变。
简述spring bean的声明周期
实例化bean对象
属性注入
检查aware相关接口并设置相关依赖:如果对象中需要引用容器内部的对象,那么需要aware接口的子类方法来进行统一设置
beanpostprocessor的前置处理:对生成的bean对象进行前置的处理工作
检查是否是initialiallizing的子类来决定是否调用afterpropertiesset方法:判断当前bean对象是否设置了initializingbean接口,然后进行属性的设置等基本工作。
检查是否有自定义的init-metthod方法
beanpostprocesssor后置处理:对生成的bean对象进行后置的处理工作
注册必要的desttrution相关回调接口:为了方便对象的销毁,在此处调用注销的回调接口,方便对象进行销毁工作。
怎么处理mysql慢查询
开启慢查询日志,精准定位到哪个sql语句出现了问题
分析sql语句,看是不是load了额外的数据,可能是查询了多余的行或者是多于的列,对sql语句进行分析和重写
分析语句的执行计划,然后获得其索引的使用情况,之后修改语句或者修改索引,是语句尽可能的命中索引
雨果语句的优化已经无法进行,可以考虑是不是表中的数据量过大,如果是的话可以进行横向或者纵向的分表
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数