自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(22)
  • 收藏
  • 关注

原创 MySQL面试题:谈谈你对行锁、临键锁、间隙锁的理解?

而间隙锁就是某个事务对索引列加锁的时候默认锁定对应索引的左右开区间的一个范围。临键锁,它相当于行锁加间隙锁的一个组合,也就是说,它的锁定范围既包含了索引记录,也包含了索引的一个区间,它会锁定一个左开右闭的数据范围。所以总的来说,行锁、表锁、临键锁,它只是表示锁的数据的一个范围,最终的目的是为了去解决幻读问题,而临键锁,它相当于行锁加间隙锁的一个组合。因此我们当我们使用非唯一索引进行精准匹配的时候,会默认加一个临键锁,因为它需要去锁定匹配的这一行记录,还要去锁定这一行数据,对应的左开右闭区间。

2023-06-27 14:29:33 414

原创 MySQL面试题:mysql的事务实现原理?

如果数据库宕机就会导致数据丢失,也是说无法去满足持久化,所以在InnoDB里面,引入了Redo_LOG这样一个文件,那么这个文件存储了数据库变更之后的一个值,当我们通过事务进行数据更改的时候,除了修改内存缓冲区里面的数据以外,还会把本次修改的一个值,追加到REDO_LOG里面,当事务提交的时候,直接把REDO_LOG里面的日志,刷新到磁盘里面进行持久化,一旦服务器宕机,在Mysql重启以后,可以直接用REDO_LOG里面保存的重写日志,读取出来以后再去执行一遍,从而去保证数据的持久性。

2023-06-27 11:18:01 146

原创 MySQL面试题:update是行锁还是表锁?

来避免幻读的问题,比如针对主键索引的for update操作,Mysql会增加一个Next-key Lock来锁定id=10索引所在的区间,(select * from t where id =10 for update),而针对于索引区间的查询或者修改,Mysql会自动对索引加间隙锁,(select * from user where id between 1 and 100 for update)来解决幻读的问题。另外根据查询范围不同,Mysql也会选择不同粒度的锁,

2023-06-27 11:17:30 3564 1

原创 MySQL面试题:MyISAM和InnoDB引擎的区别?

第一个是数据存储方式不同,MyISAM里面的数据和索引是分开存储的,而InnoDB是把索引和数据存储在同一个文件里面。第三个对于锁的支持不同,MyISAM只支持表锁,而InnoDB可以根据不同的情况去支持行锁、表锁、间隙锁、临键锁。第二个对于事务的支持不同,MyISAM不支持事务,而InnoDB支持ACID特性的一个事务处理。比如如果需要支持事务则必须使用InnoDB,而如果大部分的表操作都是查询,可以选择MyISAM。因此可以根据这些特性,可以根据不同场景,去选择合适的存储引擎。

2023-06-27 11:17:08 136

原创 redis面试题:谈谈你对分布式锁的理解?

分布式锁是一种跨进程跨机器节点的一种互斥锁,它可以保证在多个机器节点对共享资源访问的排他性。线程锁的生命周期是单进程多线程,而分布式锁的生命周期是多进程多机器节点。在本质上,他们都需要满足锁的几个基本的重要特性,首先是排他性,也就是说在同一时刻,只能有一个节点去访问共享资源,其次就是可重入性,它允许一个已经获得锁的线程,在没有释放锁之前,重新去获得锁,第三个是锁的获取和释放的方法,第四个是锁的失效机制,也就是说避免死锁的一个问题,所有我认为只要能够去满足这些特性的技术组件,都能够去实现分布式锁。

2023-06-14 23:25:53 116

原创 redis面试题:redis主从复制原理?

全量复制:发生在初始化阶段。从节点点会主动主节点发起一个同步请求,主节点收到从节点请求以后会生成一份当前数据的快照发送给从节点,从节点收到数据进行加载之后,完成全量复制。增量复制是发生在每一次Master节点发生数据变更的一个场景里面,会把变化的增量数据同步给从节点,增量复制是通过维护offset这样一个复制偏移量来实现的。redis主从复制包括全量复制和增量复制。

2023-06-14 00:05:10 89

原创 redis面试题:请描述一下redis中AOF的重写过程?

最后为了避免子进程在重写的过程中,主进程的数据会发生变化,导致AOF文件里面的数据和redis内存中的数据不一致的问题,redis还做了优化,也就是说,子进程在重写的过程中,主进程的数据变更需要追加到AOF的重写缓冲区里面,等到AOF文件重写完成以后,再把AOF重写缓冲区里面的数据,追加到新的AOF文件里面,这样一来就可以保证新的AOF文件里面的数据和当前的redis内存数据是一致的。AOF是redis里面提供一种数据持久化的方式。它里面采用了指令追加的一个方式,去近乎实时的去实现数据指令的一个持久化。

2023-06-13 22:48:06 131

原创 redis面试题:redis的内存淘汰策略和原理是什么?

在redis里面它会维护一个大小为16的候选池,而候选池里面的数据会根据时间进行排序,然后每一次随机抽取5个key,放入到候选池里面,当候选池满了以后,访问的时间间隔最大的key,就会从候选池里面取出来淘汰掉。相比于LRU,LFU去增加了访问频率这样一个维度,来统计数据的热点情况,LFU的主要设计是使用了两个双向链表,去形成一个二维的双向链表,一个是用来保存频率,另一个是保存频率相同的所有元素,当添加元素的时候,访问频次默认为1,于是找到相同频次的节点,然后添加到相同的频率节点对应的双向链表的头部。

2023-06-13 22:17:41 155

原创 redis面试题:redis存在线程安全问题吗?

假设两个redis client同时去获取redis server上的key值,同时去进行修改和写入,因为多线程环境下的原子性无法被保障,以及多进程的情况下,共享资源访问的一个竞争问题,使得数据的安全性无法得到保障。对于指令的执行过程仍然是采用主线程来处理,所以说它不存在多个线程同时去执行操作指令的情况。从redis服务端层面,redis server本身是线程安全的key-value数据库,在redis server端执行指令的时候不需要任何的同步机制,它不会存在任何的线程安全的问题。

2023-06-12 18:45:00 811

原创 redis面试题:RDB和AOF的实现原理和优缺点

简单来说就是客户在执行一个数据变更的操作,redis就会把这样一个命令,追加到aof的缓冲区里面,然后再把缓冲区里面的数据写入到磁盘的aof文件里面,至于什么时候真正把数据持久化到磁盘的aof文件里面,是根据磁盘的刷盘策略来决定的。因为AOF这种指令追加的一个方式,会造成AOF文件过大,带来明显的IO性能问题,所以redis根据这样的情况,提供了AOF重写机制。RDB是通过快照的方式来实现持久化的,也就是说会根据快照的触发条件,把内存里面的数据快照写入到磁盘里面,以二进制的压缩文件的方式进行存储。

2023-06-12 18:30:00 105

原创 redis面试题:redis的哨兵机制和集群有什么区别?

一是redis的哨兵集群是基于主从复制来实现的,它可以实现读写分离,分担redis读操作的压力,而redis cluster里面的slaver节点,只是实现冷备的一个机制,它只有在master宕机之后才会工作。二是redis哨兵机制无法在线扩容,所以它的并发压力受限于单个服务器的资源的配置,redis cluster提供了一个基于slot槽的一个数据分片的一个机制,它可以实现在线扩容去提升读写的性能。因此,哨兵机制适用于单节点的高可用需求,而Redis集群适用于大规模、高并发的分布式应用场景。

2023-06-11 21:45:00 2976

原创 redis面试题:说说对缓存雪崩和缓存穿透的理解?

在一个成熟的系统里面,热点数据,必然会有一个专门的缓存系统来维护,同时它的过期时间的key必然要和其他业务的key有所区别。对于重要的场景,我们还是会设计多级缓存的一个实现。在这样的场景下有两个方法可以去解决,一是把无效的key保存到redis里面,并且设置为一个特殊的值,例如null字符串,这样下次再来访问的时候就不会再查数据库了。在系统启动的时候,我们可以把目标数据全部缓存到布隆过滤器里面,当攻击者不断使用不存在的key进行访问的时候,先到布隆过滤器里面去查询,如果不存在,就没有必要再去查询数据库了。

2023-06-11 21:00:00 46

原创 并发面试题:当任务数超过了线程池的核心线程数时,如何让它不进入队列?

在java的线程池里面,它的构造方法里面有一个参数,可以去修改阻塞队列的这样一个类型,其中有一个阻塞队列叫synchronousQueue,这个队列它是不能存储任何元素的阻塞队列,它的特性是每生产一个任务就必须指派一个消费者来处理这个任务,否则就会阻塞生产者。那么基于这个特性,我们只需要去把线程池的阻塞队列替换成synchronousQueue就好了,它就能够直接去避免任务进入到阻塞队列,而是直接去启动最大线程数量去处理这样一个任务。当我i们提交一个任务到线程池里面的时候,它的工作原理一共分为四个步骤。

2023-06-11 00:30:00 374

原创 并发面试题:怎么理解线程安全?

原子性就是一个线程在执行一系列程序指令操作的时候,它应该是不可中断的,因为一旦出现中断,站在多线程这样一个角度来看,这一系列的程序指令会出现前后不一致的一些问题,那么这个是跟数据库中的原子性是一样的。可见性就是说在多线程的操作下,由于读跟写是发生在不同线程里面的,有可能出现某个线程对共享变量的修改,对其他线程不是实时可见的,导致可见性问题有很多。而有序性说的是在程序编写的指令顺序和最终cpu运行的指令顺序可能会出现不一致的情况,这种现象,我们可以称为指令重排序。所以有序性他也会导致可见性问题。

2023-06-11 00:15:00 78

原创 并发面试题:线程池是如何实现线程复用的?

提交任务到线程池里面的一个线程称为生产者线程,它不断的去往线程池里面去传递任务。这些任务会保存到线程池的一个阻塞队列里面。然后线程池里面的工作线程,不断去重阻塞队列里面获取任务去执行。基于阻塞队列这样的一个特性,使得阻塞队列里面如果没有任何任务的时候,那么这些工作线程就会阻塞等待,直到有新任务进来的时候,这些工作线程又再次被唤醒,从而去达到线程的一个复用的目的。线程池里面采用了生产者/消费者模式来实现线程的复用,生产者消费者模型其实就是通过一个中间容器来去解耦生产者和消费者的一个任务处理的过程。

2023-06-10 21:45:00 133

原创 并发面试题:线程池的线程回收

因为工作线程都是从阻塞队列里面去获取执行任务的,所以只要在一定的时间内,阻塞队列没有任何可以处理的任务,那么这些线程就可以结束了,而这个功能是通过阻塞队列里面的poll()方法来完成的。这个方法里面提供了超时时间和超时时间单位这两个参数,当前线程在指定的时间内没有从阻塞队列里面获取任务的时候,那么poll()方法就会返回null,从而去终止线程,完成对线程的回收。核心线程和非核心线程的数量是在构造线程池的时候去设置的,也可以动态的进行更改,由于非核心线程是为了解决任务过多的情况下临时增加的。

2023-06-10 21:00:00 244

原创 并发面试题:ThreadLocal会出现内存泄漏吗?

不恰当的使用ThreadLocal会造成内存泄漏的问题。而弱引用的特性就是不管是否存在直接引用的关系,当成员变量ThreadLocal没有其他强引用关系的时候,这个时候对象就会被GC回收。从而导致key会变为null,造成这块内存永远无法被访问,出现内存泄漏的问题。第一种解决方案虽然不会造成key为null的现象,但是后续线程不在继续访问这个key,也就会导致这个内存一直占用不被释放,最后也会造成内存溢出的问题。所以说最好的解决方式,是在实际使用完以后,调用remove()方法去移除这个数据。

2023-06-10 20:30:00 2426

原创 并发面试题:现在有1、2、3三个线程,我想让线程1在执行的时候立马执行线程3,线程3执行的时候立马执行线程2?

可以在线程1中去调用线程3的join()方法,让线程1等待线程3执行完成后,继续执行。在线程3里面调用线程2的join()方法等待线程2执行完成后,再继续执行。在java中可以直接使用Thread类提供的join()方法来干预线程的执行顺序。join()方法可以让当前线程等待另一个线程执行完毕后再继续执行。

2023-06-09 21:00:00 89

原创 redis面试题:怎样防止缓存击穿?

3.使用分布式锁,当发现缓存失效的时候,不是先从数据库里加载,而是先获取分布式锁,获取分布式锁的线程从数据库里面查询数据并写回到缓存中,没有获取到锁的线程只需要进行等待或重试。这个方案牺牲了一些性能,但是保证了数据库避免被压垮。客户端恶意发起大量不存在的key的请求,由于访问的key本身在缓存中就不存在,所以每次必然会穿透到数据库,导致缓存成为摆设。另外,我们在整体的缓存架构设计中,除了尽可能避免缓存穿透问题,还要从全局的视角做整体考虑,比如业务隔离,多级缓存,部署隔离,安全性考虑等。

2023-06-09 16:06:07 69

原创 redis面试题:谈谈你对redis的理解?

针对不同的结构可以解决不同的场景问题,因此它可以用来覆盖应用开发里面的大部分的业务场景。最后,作为企业级开发来说,它又提供了主从复制+哨兵以及集群的方式实现高可用,在redis集群里面通过hash槽的方式去实现了数据的分片,进一步提升了整体的性能和拓展性。其次,redis本身是一个基于内存存储并且数据结构上做了大量的优化,所以IO性能会比较好。并且它是一个非关系型数据库的存储,它不存在表之间的关联查询的一些问题,所以它可以很好的去提升应用程序之间的数据IO效率。

2023-06-09 16:04:07 52

原创 并发面试题:如果一个线程两次调用start()方法会出现什么问题?

第一次调用start()方法时,线程的状态可能会处于终止状态或者非new状态下的其他状态,再调用一次start方法的时候,相当于是让正在运行的线程重新运行一遍。无论是从线程的安全性的角度来看,还是从线程本身执行的逻辑来看,它都是不合理的。因此为了避免这个问题,在线程运行的时候,会先去判断当前线程的一个运行状态。第二种runnable:这个状态下的线程可能是正在运行也可能是在就绪队列里面等待操作系统进行调度,分配CPU资源。一个线程本身是具备一定的生命周期的,在java中线程的状态一共分为六种。

2023-06-09 10:12:05 257

原创 并发面试题:volatile关键字有什么作用?

第二个方面是编译器层面的优化,编译器在编译过程中,在不改变单线程语义和程序正确性的前提下,对指令进行合理的重排序,从而去优化整体的一个性能。可见性:是指当一个线程对共享变量进行修改时,其他线程可以立刻看到修改后的值,其实可见性问题本质上是由几个方面造成的,第一方面是cpu里面的高速缓存,在cpu里面设计三级缓存去解决cpu运输效率和内存IO效率的问题,但是它所带来的就是缓存一致性问题,在多线程并行的条件下,缓存的一致性问题就会导致可见性问题。第二个是缓存锁,缓存锁是对总线锁的一个优化。

2023-06-09 10:09:34 57

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除