最后
码字不易,觉得有帮助的可以帮忙点个赞,让更多有需要的人看到
又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考
以下是部分内容截图
属性值的加载顺序为:优先加载自定义的redis配置文件的redis.cluster.preloadSecondTime属性值,如果自定义的redis配置文件无相关的属性值;则从框架默认的redis配置文件redis-default.properties文件中加载;
3)当 @Cacheable 的Value配置缓存名称、失效时长和距离缓存失效的剩余时长,比如配置为:@Cacheable(value=“test#10#2”)
此时不会加载默认的expireTime和reloadTime,框架会直接使用@Cacheable注解中value属性配置的expireTime和reloadTime;
4)无论@Cacheable的Value属性是否配置了缓存时长信息,则都不会出现只配置reloadTime,没有配置expireTime的情况,框架规定的value属性格式为:缓存名称#expireTime#reloadTime
即只会出现的格式为:
-
缓存名称
-
缓存名称#expireTime
-
缓存名称#expireTime#reloadTime
不会存在单独出现reloadTime的情况,会出现配置了缓存名称#expireTime,reloadTime使用配置文件默认的时长配置的情况;
注意事项
1.mykit-cache-redis-spring-xml引用和mykit-cache-redis-spring-annotation引用是互斥的,即在一个工程中mykit-cache-redis-spring-xml和mykit-cache-redis-spring-annotation只能同时引用一个;
2.mykit-cache-redis-spring-xml和mykit-cache-redis-spring-annotation的功能是一样的,但是mykit-cache-redis-spring-annotation工程兼容Redis集群宕机或其他原因无法连接Redis集群时的情况;
3.如果Redis集群宕机或其他原因无法连接Redis集群时,则mykit-cache-redis-spring-xml会抛出异常,退出执行;而mykit-cache-redis-spring-annotation则会打印相关的异常信息,继续向下执行原来的方法。
4.如果你的项目中以XML配置的方式,配置了Spring容器和SpringMVC,而你想以兼容Redis集群宕机或其他原因连接不上Redis集群的方式配置缓存,可以经过如下配置:
1)在项目中添加如下配置类:
SpringContextConfig:配置Spring容器:
package io.mykit.cache.redis.spring.utils.config;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import io.mykit.cache.redis.spring.annotation.config.CacheRedisConfig;
/**
-
@ClassName SpringContextConfig
-
@Description Spring Java配置
-
@author binghe
*/
@Configuration
@EnableCaching
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(value = {“io.mykit.cache”})
@PropertySource(value = {“classpath:properties/redis-default.properties”, “classpath:properties/redis.properties”})
@ImportResource(“classpath:spring/applicationContext.xml”)
public class SpringContextConfig extends CacheRedisConfig{
}
SpringMVCConfig:配置SpringMVC:
package io.mykit.cache.redis.spring.utils.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
/**
-
@ClassName SpringMVCConfig
-
@Description SpringMVC Java配置
-
@author binghe
*/
@Configuration
@ImportResource(“classpath:spring/SpringMVC-servlet.xml”)
public class SpringMVCConfig {
}
2)web项目的web.xml修改如下:
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns=“http://java.sun.com/xml/ns/javaee” xmlns:web=“http://java.sun.com/xml/ns/javaee”
xsi:schemaLocation=“http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd”
version=“3.0”>
org.springframework.web.context.ContextLoaderListener
contextClass
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
contextConfigLocation
io.mykit.cache.redis.spring.utils.config.SpringContextConfig
org.springframework.web.util.IntrospectorCleanupListener
SpringMVC
org.springframework.web.servlet.DispatcherServlet
contextClass
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
contextConfigLocation
io.mykit.cache.redis.spring.utils.config.SpringMVCConfig
1
SpringMVC
/
1、需要在工程的pom.xml中引用
io.mykit.cache
mykit-cache-memcached-spring-simple-xml
1.0.0-SNAPSHOT
注意:框架的此模块不支持主动刷新缓存,底层核心使用的是simple-spring-memcached内核。
2、使用方法
1)在自身项目的classpath:properties目录下新建Memcached的配置文件,比如:memcached.properties文件,配置连接Memcached的属性;
属性配置如下:
#simple memcached config
simple.memcache.server=127.0.0.1:12000
simple.memcache.consistenthashing=true
simple.memcache.connectionpoolsize=1
simple.memcache.optimizeget=false
simple.memcache.optimizemergebuffer=false
simple.memcache.mergefactor=50
simple.memcache.usebinaryprotocol=true
simple.memcache.connectiontimeout=3000
simple.memcache.operationtimeout=2000
simple.memcache.enableheartbeat=true
simple.memcache.failureMode=false
注意:自定义的memcached文件的属性,必须和memcached-default.properties默认配置的属性key相同,也就是和上述配置的key相同,但可以不用覆盖上述完整的配置,
可以只配置:
simple.memcache.server=192.168.209.121:12000
来覆盖simple.memcache.server属性
2)在自身项目的classpath目录下新建spring配置文件,比如:spring-context.xml,配置内容如下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns:p=“http://www.springframework.org/schema/p”
xmlns:aop=“http://www.springframework.org/schema/aop”
xmlns:context=“http://www.springframework.org/schema/context”
xmlns:cache=“http://www.springframework.org/schema/cache”
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
<context:annotation-config />
aop:aspectj-autoproxy/
<context:component-scan base-package=“io.mykit.cache”/>
<context:property-placeholder location=“classpath*:properties/memcached-default.properties, classpath*:properties/memcached.properties” system-properties-mode=“FALLBACK”/>
<context:annotation-config />
<context:component-scan base-package=“io.mykit.cache” />
根据上述配置加载properties文件顺序,框架会用自定义的memcached.properties文件属性覆盖memcached-default.properties文件的属性。
如果memcached-default.properties文件中存在memcached.properties中不存在的属性,框架会用memcached-default.properties中默认的属性。
至此,就可以使用simple-spring-memcached提供的注解来配置使用缓存了。
3、simple-spring-memcached介绍
3-1、基本介绍
simple-spring-memcached本质上是采用了AOP的方式来实现缓存的调用和管理,其核心组件声明了一些Advice,当遇到相应的切入点时,会执行这些Advice来对memcached加以管理。
切入点是通过标签的方式来进行声明的,在项目开发时,通常在DAO的方法上加以相应的标签描述,来表示组件对该方法的拦截 组件所提供的切入点主要包括以下几种:
ReadThroughSingleCache、ReadThroughMultiCache、ReadThroughAssignCache
1)当遇到查询方法声明这些切入点时,组件首先会从缓存中读取数据,取到数据则跳过查询方法,直接返回。 取不到数据在执行查询方法,并将查询结果放入缓存,以便下一次获取。 InvalidateSingleCache、InvalidateMultiCache、InvalidateAssignCache
2)当遇到删除方法声明这些切入点时,组件会删除缓存中的对应实体,以便下次从缓存中读取出的数据状态是最新的 UpdateSingleCache、UpdateMultiCache、UpdateAssignCache
3-2、注解说明
各Annotation的详细说明
- ReadThroughSingleCache
作用:读取Cache中数据,如果不存在,则将读取的数据存入Cachekey生成规则:ParameterValueKeyProvider指定的参数,如果该参数对象中包含CacheKeyMethod注解的方法,则调用其方法,否则调用toString方法
@ReadThroughSingleCache(namespace = “Alpha”, expiration = 30)
public String getDateString(@ParameterValueKeyProvider final String key) {
final Date now = new Date();
try {
Thread.sleep(1500);
} catch (InterruptedException ex) {
}
return now.toString() + “:” + now.getTime();
}
- InvalidateSingleCache
作用:失效Cache中的数据
key生成规则:
1)使用 ParameterValueKeyProvider注解时,与ReadThroughSingleCache一致
2)使用 ReturnValueKeyProvider 注解时,key为返回的对象的CacheKeyMethod或toString方法生成
@InvalidateSingleCache(namespace = “Charlie”)
public void updateRandomString(@ParameterValueKeyProvider final Long key) {
// Nothing really to do here.
}
@InvalidateSingleCache(namespace = “Charlie”)
@ReturnValueKeyProvider
public Long updateRandomStringAgain(final Long key) {
return key;
}
- UpdateSingleCache
作用:更新Cache中的数据
key生成规则:ParameterValueKeyProvider指定
1)ParameterDataUpdateContent:方法参数中的数据,作为更新缓存的数据
2)ReturnDataUpdateContent:方法调用后生成的数据,作为更新缓存的数据
注:上述两个注解,必须与Update*系列的注解一起使用
@UpdateSingleCache(namespace = “Alpha”, expiration = 30)
public void overrideDateString(final int trash, @ParameterValueKeyProvider final String key,
@ParameterDataUpdateContent final String overrideData) {
}
@UpdateSingleCache(namespace = “Bravo”, expiration = 300)
@ReturnDataUpdateContent
public String updateTimestampValue(@ParameterValueKeyProvider final Long key) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
final Long now = new Date().getTime();
final String result = now.toString() + “-U-” + key.toString();
return result;
}
- ReadThroughAssignCache
作用:读取Cache中数据,如果不存在,则将读取的数据存入Cache
key生成规则: ReadThroughAssignCache 注解中的 assignedKey 字段指定
@ReadThroughAssignCache(assignedKey = “SomePhatKey”, namespace = “Echo”, expiration = 3000)
public List getAssignStrings() {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
final List results = new ArrayList();
final long extra = System.currentTimeMillis() % 20;
final String base = System.currentTimeMillis() + “”;
for (int ix = 0; ix < 20 + extra; ix++) {
results.add(ix + “-” + base);
}
return results;
}
- InvalidateAssignCache
作用:失效缓存中指定key的数据
key生成规则:assignedKey 字段指定
@InvalidateAssignCache(assignedKey = “SomePhatKey”, namespace = “Echo”)
public void invalidateAssignStrings() {
}
- UpdateAssignCache
作用:更新指定缓存
key生成规则:assignedKey 字段指定
@UpdateAssignCache(assignedKey = “SomePhatKey”, namespace = “Echo”, expiration = 3000)
public void updateAssignStrings(int bubpkus, @ParameterDataUpdateContent final List newData) {
}
框架此模块暂时不做实现,由于Spring与Ehcache的整合过于简单,可自行实现Spring与Ehcache的整合,这个不提供封装了。
spring4配置基于注解的ehcache缓存
1. ehcache配置文件ehcache.xml
<?xml version="1.0" encoding="UTF-8"?><defaultCache
maxElementsInMemory=“10000”
eternal=“false”
timeToIdleSeconds=“30”
timeToLiveSeconds=“30”
overflowToDisk=“true”>
<cache name=“statisticServiceCache”
maxElementsInMemory=“1000”
eternal=“false”
overflowToDisk=“true”
timeToIdleSeconds=“900”
timeToLiveSeconds=“1800”
diskPersistent=“false”
memoryStoreEvictionPolicy=“LFU” />
2.spring-cache注解及ehcache bean配置
<cache:annotation-driven cache-manager=“cacheManager”/>
3.确认开启了spring的aop支持
aop:aspectj-autoproxy/
4.Spring的cache注解的使用
(1)@Cacheable
@Cacheable 主要的参数
- value
缓存的名称,在 spring 配置文件中定义,必须指定至少一个
例如:
@Cacheable(value=”mycache”) 或者
@Cacheable(value={”cache1”,”cache2”}
- key
缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
例如:
@Cacheable(value=”testcache”,key=”#userName”)
- condition
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
例如:
@Cacheable(value=”testcache”,condition=”#userName.length()
如下示例:
@Cacheable(value = “statisticServiceCache”, key = “‘activityChartData_’ + #urlID”)
public ResultInfo getActivityChartData(String urlID, Date startMonth,Date endMonth) {
…
}
这个注解用于,在调用被注解的方法时,首先检查当前缓存系统中是否存在键值为key的缓存。如果存在,则直接返回缓存对象,不执行该方法。如果不存在,则调用该方法,并将得到的返回值写入缓存中。
(2)@CachePut
@CachePut 主要的参数
- value
缓存的名称,在 spring 配置文件中定义,必须指定至少一个
例如:
@Cacheable(value=”mycache”) 或者
@Cacheable(value={”cache1”,”cache2”}
- key
缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
例如:
@Cacheable(value=”testcache”,key=”#userName”)
- condition
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
例如:
@Cacheable(value=”testcache”,condition=”#userName.leng
@CachePut用于写入缓存,但是与@ Cacheable不同,@CachePut注解的方法始终执行,然后将方法的返回值写入缓存,此注解主要用于新增或更新缓存。
(3) @CacheEvict
@CacheEvict 主要的参数
- value
缓存的名称,在 spring 配置文件中定义,必须指定至少一个
例如:
@CachEvict(value=”mycache”) 或者
@CachEvict(value={”cache1”,”cache2”}
- key
缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
例如:
@CachEvict(value=”testcache”,key=”#userName”)
- condition
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存
例如:
@CachEvict(value=”testcache”, condition=”#userName.length()>2”)
- allEntries
是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
例如:
@CachEvict(value=”testcache”,allEntries=true)
- beforeInvocation
是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存
例如:
@CachEvict(value=”testcache”,beforeInvocation=true)
@CacheEvict用于删除缓存
无论使用哪种模块,需要在相关的项目中配置ApplicationContext到SpringContextWrapper中。
示例代码如下:
package io.mykit.cache.test.redis.spring.utils;
import io.mykit.cache.redis.spring.context.SpringContextWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import redis.clients.util.Hashing;
/**
-
@author binghe
-
@version 1.0.0
-
@description 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext.
*/
@Slf4j
@Component
public class SpringContext implements ApplicationContextAware {
private static ApplicationContext applicationContext;
/**
- 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContext.applicationContext = applicationContext; // NOSONAR
log.debug(SpringContext.class.getName() + " 类加载的路径:" + this.getClass().getResource(“/”).getPath() + “, hashcode:” + Hashing.MURMUR_HASH.hash(this.getClass().getResource(“/”).getPath()));
log.debug(SpringContext.class.getName() + " applicationContext===>>>" + applicationContext);
SpringContextWrapper.setApplicationContext(SpringContextWrapper.getContextKey(this.getClass()), applicationContext);
}
/**
-
取得存储在静态变量中的ApplicationContext.
-
@return ApplicationContext对象
*/
public static ApplicationContext getApplicationContext() {
checkApplicationContext();
return applicationContext;
}
/**
-
从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
-
@param name Spring中Bean的名称
-
@return 泛型对象
*/
@SuppressWarnings(“unchecked”)
public static T getBean(String name) {
checkApplicationContext();
return (T) applicationContext.getBean(name);
}
/**
-
从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
-
@param clazz 指定的clazz对象
-
@return 泛型对象
*/
public static T getBean(Class clazz) {
checkApplicationContext();
return (T) applicationContext.getBean(clazz);
}
/**
- 清除applicationContext静态变量.
*/
public static void cleanApplicationContext() {
applicationContext = null;
}
private static void checkApplicationContext() {
if (applicationContext == null) {
throw new IllegalStateException(“applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder”);
}
}
}
本项目还在开发中,目前未添加到Maven中央仓库,后续开发完成会添加到Maven中央仓库。
如果这个框架对大家有点帮助,还请小伙伴们打开Github和Gitee链接,给这个项目一个大大的Star,让更多的小伙伴收益。也可以为这篇文章点赞、在看和转发哦~~
如果你想进大厂,想升职加薪,或者对自己现有的工作比较迷茫,都可以私信我交流,希望我的一些经历能够帮助到大家~~
推荐阅读:
总结
面试难免让人焦虑不安。经历过的人都懂的。但是如果你提前预测面试官要问你的问题并想出得体的回答方式,就会容易很多。
此外,都说“面试造火箭,工作拧螺丝”,那对于准备面试的朋友,你只需懂一个字:刷!
给我刷刷刷刷,使劲儿刷刷刷刷刷!今天既是来谈面试的,那就必须得来整点面试真题,这不花了我整28天,做了份“Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法等”
且除了单纯的刷题,也得需准备一本【JAVA进阶核心知识手册】:JVM、JAVA集合、JAVA多线程并发、JAVA基础、Spring 原理、微服务、Netty与RPC、网络、日志、Zookeeper、Kafka、RabbitMQ、Hbase、MongoDB、Cassandra、设计模式、负载均衡、数据库、一致性算法、JAVA算法、数据结构、加密算法、分布式缓存、Hadoop、Spark、Storm、YARN、机器学习、云计算,用来查漏补缺最好不过。
如果这个框架对大家有点帮助,还请小伙伴们打开Github和Gitee链接,给这个项目一个大大的Star,让更多的小伙伴收益。也可以为这篇文章点赞、在看和转发哦~~**
如果你想进大厂,想升职加薪,或者对自己现有的工作比较迷茫,都可以私信我交流,希望我的一些经历能够帮助到大家~~
推荐阅读:
总结
面试难免让人焦虑不安。经历过的人都懂的。但是如果你提前预测面试官要问你的问题并想出得体的回答方式,就会容易很多。
此外,都说“面试造火箭,工作拧螺丝”,那对于准备面试的朋友,你只需懂一个字:刷!
给我刷刷刷刷,使劲儿刷刷刷刷刷!今天既是来谈面试的,那就必须得来整点面试真题,这不花了我整28天,做了份“Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法等”
[外链图片转存中…(img-tNx3Nt5u-1715546202395)]
且除了单纯的刷题,也得需准备一本【JAVA进阶核心知识手册】:JVM、JAVA集合、JAVA多线程并发、JAVA基础、Spring 原理、微服务、Netty与RPC、网络、日志、Zookeeper、Kafka、RabbitMQ、Hbase、MongoDB、Cassandra、设计模式、负载均衡、数据库、一致性算法、JAVA算法、数据结构、加密算法、分布式缓存、Hadoop、Spark、Storm、YARN、机器学习、云计算,用来查漏补缺最好不过。
[外链图片转存中…(img-kni7o0B7-1715546202395)]