JDK、JRE、JVM的区别
JDK是java开发工具包,包含了jre和jvm以及java基础类库。JRE是java运行环境,包含了jvm和java的核心类库。Jvm是java虚拟机,是java实现跨平台的基础,负责执行java字节码将其翻译为机器码。
重载和重写的区别
重载发生在同一个类中,方法名相同,形参列表不同,方法的返回类型可以不同。重写发生在不同的类中,方法名、新参列表、返回类型都相同。方法的访问修饰符要大于等于父类,是子类对父类中继承的方法进行重新定义。
==和equals的区别
==如果是比较基本类型,比较的就是值是否相同。如果比较的是引用类型,比较的就是地址值是否相同。equals默认情况下,与引用类型是一样的,比较的就是地址值是否相同。但很多情况下会被重写以实现内容的比较。
抽象类和接口的区别
首先二者的实现方式不同,抽象类使用extends来继承,接口使用implements来实现接口。然后一个类可以实现很多接口,但只能继承一个抽象类。以及抽象类的访问修饰符是可以任意的,但接口的访问修饰符只能是public。
什么是单例模式
单例模式是指某个类的实例在多线程环境下只会被创建一次。我知道的单例模式有饿汉式单例、懒汉式单例、双检锁单例模式三种。首先是饿汉式单例,是在类加载时就初始化实例,线程是安全的。而懒汉式单例只有在第一次使用时才会初始化,线程是非安全的。双检锁是在实现懒汉式的同时确保了线程安全。
Java中的异常体系是怎样的
Java中所有的异常都来自顶级父类Throwable。Throwable下有两个子类Exception和Error。Error表示非常严重的错误,出现这些错误时,仅仅想靠程序自己是解决不了的,所以通常不在代码中捕获这些Error,因为捕获的意义也不大。Exception表示异常,程序出现Exception是可以自己解决的,我们可以捕获这些异常来做特殊处理。
如果发生了缓存穿透该如何解决?
缓存穿透是指发送了一个缓存中没有的数据 ,由于Redis中没有对应的缓存,就会直接去找数据库,但是数据库也没有对应的数据,就查询不到,如果在同一时间内,这样的请求过多的话,到了一定的量,就会发生缓存穿透。
解决方案也很简单,缓存空数据,如果请求的数据在缓存中是null,那么就把null进行缓存,但是可能发生数据不一致的问题。因此还有一种更好的解决办法,布隆过滤器,当发送了一个缓存中没有的数据时,会先经过布隆过滤器,如果布隆过滤器中没有数据,就直接返回,连Reids都不会走,当然前提就是要在缓存预热的时候就把布隆过滤器初始化了,就是把热点数据先交给布隆过滤器,这就是我在华园快送项目中用到的解决办法。
布隆过滤器的原理是什么?
要想理解布隆过滤器的原理,就要先知道一个概念—bitmap,相当于是以一个bit位为单位的数组,数组中每个单元只能存储二进制数0或1,布隆过滤器正是依赖它实现的,主要原理是当进行缓存预热的时候,比如说id为1的数据,会先通过多个hash函数运算,获取hash值,将对应位置的值由0改为1,当后续查询数据经过布隆过滤器的时候,会将数据进行同样的hash函数运算,然后看hash值所对应位置的值是否与缓存的一致。当然也可能存在误判,比如缓存预热时,经过hash运算得到的值,与后面要查询的空值,hash运算得到的结果一致,就会发生误判。在华园快送项目中,我是通过Redisson来实现的布隆过滤器,设置了一个误判率,5%,以此来控制布隆过滤器误判。
如果发生了缓存击穿该如何解决?
缓存击穿是指给某一个key设置了过期时间,当某一个key过期了,与此同时有大量数据传入进来,但是这个时候已经没有缓存了,因此就会直接访问到数据库,可能会把数据库压垮。
解决方案有两种,第一种是添加互斥锁,互斥锁的实现原理是假设线程一查询缓存但没有命中,就会添加一个互斥锁,然后重新构建缓存数据,缓存构建成功后释放锁,在构建缓存的时候,如果有其他线程查询同样的缓存,由于没有缓存,并且由于线程一添加了互斥锁,就会获取到互斥锁,然后休眠,再重试,直到线程一构建完缓存然后释放互斥锁,最终命中缓存。还有一种办法就是逻辑过期,在写入缓存的时候多添加一个过期时间字段,当一个线程查询缓存时发现逻辑时间已经过期,就会获取一个互斥锁,然后开启一个新的线程去重建缓存,并且返回已经过期的数据,创建缓存的线程就只是用来创建缓存的,当缓存创建完成后就会释放互斥锁。在创建缓存的过程中如果有其他线程请求,就会直接返回已经过期的数据。两种方法是根据具体的业务来选择的。
如果发生了缓存雪崩该如何解决?
缓存雪崩是指在同一时间段有大量缓存key同时失效或者Redis服务宕机,导致大量请求直接到达数据库,带来巨大压力。如果是因为key同时过期很好解决,为不同的key添加不同的过期时间即可。而如果是因为Redis服务宕机的话,就利用 Redis 集群来提高服务的可用性。除去这两种方法还可以给缓存业务添加降级限流策略,比如在nginx,如果是微服务项目的话,就可以在网关来设置降级限流策略,最后也可以给业务增加多级缓存来防止缓存雪崩。
Redis作为缓存,MySQL的数据如何与Redis进行同步?
这个问题结合华园快送这个项目来说,项目中用户在查看店铺状态及菜品数据时,需要让数据库与Redis高度保持一致,因此使用的是Redisson实现的读写锁,当去读数据的时候添加共享锁,允许其它线程去读,但是不能写,当写数据的时候添加排他锁,阻塞其他线程的读写操作,这里面需要注意的是读方法和写方法上需要使用同一把锁才行。
此外,在后面学习到MQ之后,我又知道了一种同步数据的方式,就是异步通知,这个主要取决于MQ的可靠性。当写一条数据到数据库后,数据库就会发一条消息到MQ,缓存服务就监听着MQ最终更新缓存数据,这期间可能会有延迟,但是能保证数据最终是一致的。
Redis作为缓存,数据的持久化是怎么做的?
Redis持久化有两种方式:RDB、AOF
RDB:是Redis的数据快照,就是把内存中的所有数据都记录到磁盘中,当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。Redis内部是有默认的RDB触发机制的。RDB的缺点是数据可能会丢失。
AOF:是追加文件,Redis处理的每一个写命令都会记录在AOF文件,可以看作是日志命令文件。不过AOF默认是关闭的,需要去配置文件中开启AOF。AOF也是有缺点的,因为会存储每一条命令,重写时都会占用大量的资源。
如何定位慢查询?
MySQL自带慢日志查询,慢日志查询默认是关闭的,需要手动开启,开启的同
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/50423.html