JAVA面筋(20240406)

美团一面挂(到店后端)

面试时间:1小时10分钟

项目的难点

缓存雪崩、缓存穿透、缓存击穿

(1)缓存穿透(Cache Penetration):指查询一个不存在的数据,由于缓存中没有数据,
             所以这个查询请求会直接穿过缓存层,到达数据库层,造成了数据库的压力。
             攻击者可以通过构造恶意请求,使得缓存层无法命中任何数据,
             从而导致请求直接访问数据库,从而引起数据库压力过大。
 
(2)缓存击穿(Cache Breakdown):指缓存中某个热点数据失效,此时有大量并发请求同时访问
             这个失效的数据,导致这些请求直接访问数据库,造成数据库压力过大,
             甚至导致数据库崩溃。通常是由于缓存中某个热点数据过期失效,
             同时有大量并发请求访问该数据。
 
(3)缓存雪崩(Cache Avalanche):指缓存中大量的数据失效,导致大量请求直接访问数据库,
             造成数据库压力过大。通常是由于缓存中大量的数据在同一时间失效,
             导致大量请求直接访问数据库。

解决:

(1)缓存穿透:可以在查询缓存之前,先对请求的参数进行合法性检查,如过滤非法字符、
              判断参数范围等;或者使用BloomFilter等数据结构,对查询参数进行过滤,
              只有在BloomFilter中判断有可能存在的情况下才会去查询数据库。缓存空值
 
(2)缓存击穿:可以使用锁机制或者分布式锁机制,避免大量并发请求同时访问失效的热点数据。
      或者不设置TTL,设置逻辑上过期标识,需要过期的时候直接删除标识

热点数据永不过期
             
 
(3)缓存雪崩:可以采用多级缓存架构,减少缓存层的压力;
              或者设置热点数据的过期时间为随机时间,避免在同一时间大量数据同时失效。
              另外可以在缓存层和数据库层之间添加限流、熔断等措施,
              避免因突发流量导致系统崩溃。

布隆过滤器原理

布隆过滤器底层是bit数组,通过多个hash函数把key映射到数组中,布隆过滤器会出现误判

特点:存在不一定存在,不存在一定不存在

什么时候使用redis做缓存

热点数据(首页信息等)

缓存了哪些数据

String底层

1. 不可变性的优点

1. 只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现可以在运行时节约很多heap空间,因为不同的字符串引用都可以指向池中的同一个字符串。但如果字符串是可变的,如果一个引用变量改变了字符串的值,那么其它指向这个值的变量内容也会跟着一起改变。

2. 如果字符串是可变的,那么可能会引起很严重的安全问题。譬如,数据库的用户名、密码都是以字符串的形式传入数据库,以获得数据库的连接;或者在socket编程中,主机名和端口都是以字符串的形式传入。因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子,改变字符串指向的对象值,造成安全漏洞。

3. 因为字符串是不可变的,在物理上是绝对的线程安全,所以同一个字符串实例可以被多个线程共享。由于不可变对象不可能被修改,因此能够在多线程中被任意自由访问而不导致线程安全问题,不需要多余的同步操作。即在并发场景下,多个线程同时读一个资源,并不会引发竞态条件,只有对资源进行读写才有危险。不可变对象不能被写,所以线程安全。

4. 类加载器要用到字符串,不可变性也提供了安全性,以便正确的类可以被加载。譬如你想加载java.sql.Connection类,而这个值被改成了myhacked.Connection,那么会对你的数据库造成不可知的破坏。

5. 因为字符串是不可变的,所以在字符串对象创建的时候hashCode()就被执行并把执行结果缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,所以字符串的处理速度要快过其它的键对象,这就是HashMap中的键往往都使用字符串的原因,当我们需要频繁读取访问任意键值对时,能够节省很多的CPU计算开销。

6. Sting的不可变性会提高执行性能和效率,基于Sting不可变,我们就可以用缓存池将String对象缓存起来,同时把一个String对象的地址赋值给多个String引用,这样可以安全保证多个变量共享同一个对象。因此,构造一万个string s = "xyz",实际上得到都是同一个字符串对象,避免了很多不必要的空间开销。

2. 不可变性的缺点

● 丧失了部分灵活性。我们平时使用的大部分都是可变对象,比如内容变化时,只需要利用setValue()更新一下就可以了,不需要重新创建一个对象,但是String很难做到这一点。当然,我们完全可以使用StringBuilder来弥补这个缺点。
● 脆弱的不可变性,String其实可以利用JNI或反射来改变其不可变性。

Java基本数据类型

注意下包装类:-128-127能缓存,比较是true

StringBuilder和StringBuffer的区别,底层原理,为什么StringBuffer线程安全

  https://baijiahao.baidu.com/s?id=1764316709117920849&wfr=spider&for=pc

StringBuffer使用synchronized修饰

有哪些锁

乐观锁、悲观锁。问的时候具体说,synchronized和lock和reentrantlock

synchronized和lock的区别

 synchronizedLock两者区别:

  1:Lock是一个接口,而Synchronized是关键字。

  2:Synchronized会自动释放锁,而Lock必须手动释放锁。

  3:Lock可以让等待锁的线程响应中断,而Synchronized不会,线程会一直等待下去。

  4:通过Lock可以知道线程有没有拿到锁,而Synchronized不能。

  5:Lock能提高多个线程读操作的效率。

  6:Synchronized能锁住类、方法和代码块,而Lock是块范围内的

synchronized底层原理

锁升级过程是什么样的,重量级锁能降级吗

无锁-偏向锁-轻量化级锁-重量级锁

不能降级只能升级

synchronized能中断吗,能获取锁状态吗

可以中断,不能获取状态,会一直阻塞的获取不到的话

汇编语言学过吗(没学过)

MySQL的存储数据结构

B+树

为什么要使用B+树而不是B树

B+树只有叶子有数据,其他都是索引

b+树底层双向链表,支持范围查询

如何判断是否使用了索引

explain关键字

索引失效的情况有哪些

最左匹配、类型转换、左模糊、范围查询等

15分钟手撕算法,给一个字符串,返回所有可能的ip地址

回溯

总结:算法核心代码写出来了,但是那个编译器有问题没运行成功

Java基本数据类型byte一时间没答上来

字节流和字符流的区别

1. 数据类型:字节流处理的是字节数据,而字符流处理的是字符数据。字节流以字节为单位进行读取和写入,而字符流以字符为单位进行读取和写入。

2. 编码方式:字节流处理的是字节数据,而字符流处理的是字符数据。字符流需要指定字符集来进行字符编码和解码,而字节流则不需要。

3. 处理方式:字节流和字符流的处理方式也不同。字节流以字节为单位进行读取和写入,可以直接读取和写入二进制数据。字符流以字符为单位进行读取和写入,需要进行字符编码和解码。

4. 适用场景:字节流和字符流的适用场景也不同。字节流适用于处理二进制数据,例如图像、音频、视频等。字符流适用于处理文本数据,例如读取和写入文件、网络通信等
                      
原文链接:https://blog.csdn.net/2302_80648032/article/details/134643961

  • 21
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值