public void clear() {
cache.clear();
}
@Override
public int size() {
return cache.size();
}
@Override
public String toString() {
return “DefaultCache{” +
“cache=” + cache.toString() +
‘}’;
}
public static void main(String[] args) {
Cache cache=new DefaultCache();
cache.putObject(“A”,100);
cache.putObject(“B”,200);
cache.putObject(“C”,300);
System.out.println(cache);
}
}
线程安全的Cache设计及实现,例如:
package com.jt.cache;
public class SynchronizedCache implements Cache {
private Cache cache;
public SynchronizedCache(Cache cache) {
this.cache = cache;
}
@Override
public synchronized void putObject(Object key, Object value) {
cache.putObject(key, value);
}
@Override
public synchronized Object getObject(Object key) {
return cache.getObject(key);
}
@Override
public synchronized Object removeObject(Object key) {
return cache.removeObject(key);
}
@Override
public void clear() {
cache.clear();
}
@Override
public int size() {
return cache.size();
}
@Override
public String toString() {
return “SynchronizedCache{” +
“cache=” + cache +
‘}’;
}
public static void main(String[] args) {
Cache cache = new SynchronizedCache(new DefaultCache());
cache.putObject(“A”, 100);
cache.putObject(“B”, 200);
System.out.println(cache);
}
}
实际工作中我们经常要分析和监控缓存的命中率,例如我们设计了缓存,但为什么还是查询了数据库,有多少请求数据来自缓存,多少请求查询了数据库等,此时需要一个基于日志进行分析的一个过程,因此LoggingCache对象诞生,例如:
package com.jt.cache;
/**
- 通过此对象记录Cache命中率
*/
public class LoggingCache implements Cache{
/*对这个cache进行命中率的记录/
private Cache cache;
/*请求次数/
private int requests;
/*命中的次数/
private int hints;
public LoggingCache(Cache cache){
this.cache=cache;
}
@Override
public void putObject(Object key, Object value) {
cache.putObject(key,value);
}
@Override
public Object getObject(Object key) {
//1.记录请求次数
requests++;
//2.从cache获取数据
Object object = cache.getObject(key);
if(object!=null){
//计算命中率
hints++;
System.out.println("hits/requests is "+hints*1.0/requests);
}
return object;
}
@Override
public Object removeObject(Object key) {
return cache.removeObject(key);
}
@Override
public void clear() {
cache.clear();
}
@Override
public int size() {
return cache.size();
}
public static void main(String[] args) {
LoggingCache loggingCache =
new LoggingCache(new DefaultCache());
loggingCache.putObject(“A”,100);
loggingCache.putObject(“B”,200);
loggingCache.putObject(“C”,300);
loggingCache.getObject(“D”);
loggingCache.getObject(“A”);
loggingCache.getObject(“A”);
}
}
缓存可以提供的内存空间是有限的,在缓存满的时候,我们要提供一些数据淘汰策略,接下来我们基于FIFO算法,对缓存进行设计,例如:
package com.jt.cache;
import java.util.Deque;
import java.util.LinkedList;
/**
- 有界缓存淘汰策略:FIFO(先进先出)算法
*/
public class FifoCache implements Cache{
/*存储数据的Cache/
private Cache cache;
/*Cache的最大容量/
private int maxCap;
/*双端队列(两头都可以操作),基于此队列记录key的顺序/
private Deque deque;
public FifoCache(Cache cache, int maxCap) {
this.cache = cache;
this.maxCap = maxCap;
this.deque=new LinkedList<>();
}
@Override
public void putObject(Object key, Object value) {
//1.记录key的顺序
deque.addLast(key);
//2.判定cache是否已满,满了则移除元素
//if(cache.size()==maxCap){} 方式1
if(deque.size()>maxCap){//方式2
//获取最先放入的元素key
Object eldestKey=deque.removeFirst();
//移除最先放进去的元素
cache.removeObject(eldestKey);
}
//3.添加新的元素
cache.putObject(key,value);
}
@Override
public Object getObject(Object key) {
return cache.getObject(key);
}
@Override
public Object removeObject(Object key) {
Object value=cache.removeObject(key);
deque.remove(key);
return value;
}
@Override
public void clear() {
cache.clear();
deque.clear();
}
@Override
public int size() {
return cache.size();
}
@Override
public String toString() {
return “FifoCache{” +
“cache=” + cache +
‘}’;
}
public static void main(String[] args) {
FifoCache cache = new FifoCache(new DefaultCache(), 3);
cache.putObject(“A”,100);
cache.putObject(“B”,200);
cache.putObject(“C”,300);
cache.putObject(“D”,400);
cache.putObject(“E”,500);
System.out.println(cache);
}
}
基于LRU算法(最近最少使用算法)对缓存进行数据淘汰设计,例如:
package com.cy.java.cache;
import java.util.LinkedHashMap;
import java.util.Map;
/** 缓存淘汰策略:LRU(最近最少使用算法)*/
public class LruCache implements Cache {
private Cache cache;
/*通过此属性记录要移除的数据对象/
private Object eldestKey;
/*通过此map记录key的访问顺序/
private Map<Object,Object> keyMap;
@SuppressWarnings(“serial”)
public LruCache(Cache cache,int maxCap) {
this.cache=cache;
//LinkedHashMap可以记录key的添加顺序或者访问顺序
this.keyMap=new LinkedHashMap<Object,Object>(maxCap, 0.75f, true)
{//accessOrder
//此方法每次执行keyMap的put操作时调用
@Override
protected boolean removeEldestEntry (java.util.Map.Entry<Object, Object> eldest) {
boolean isFull=size()>maxCap;
if(isFull)eldestKey=eldest.getKey();
return isFull;
}
};
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)
最后
分享一些系统的面试题,大家可以拿去刷一刷,准备面试涨薪。
这些面试题相对应的技术点:
- JVM
- MySQL
- Mybatis
- MongoDB
- Redis
- Spring
- Spring boot
- Spring cloud
- Kafka
- RabbitMQ
- Nginx
- …
大类就是:
- Java基础
- 数据结构与算法
- 并发编程
- 数据库
- 设计模式
- 微服务
- 消息中间件
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
- …
大类就是:
- Java基础
- 数据结构与算法
- 并发编程
- 数据库
- 设计模式
- 微服务
- 消息中间件
[外链图片转存中…(img-0FEgxN2C-1711531098985)]
[外链图片转存中…(img-xgXwXDmd-1711531098985)]
[外链图片转存中…(img-D15cIwQG-1711531098985)]
[外链图片转存中…(img-7CNZ1Xco-1711531098985)]
[外链图片转存中…(img-iCyUyy8y-1711531098986)]
[外链图片转存中…(img-yU8g4bRo-1711531098986)]
[外链图片转存中…(img-RRI1dVYg-1711531098986)]
[外链图片转存中…(img-do0N4exQ-1711531098986)]
[外链图片转存中…(img-aeXPMSPD-1711531098986)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!