Memcached 在 Spring 里怎么用
本文将对在Java环境下Memcached应用进行详细介绍。Memcached主要是集群环境下的缓存解决方案,可以运行在Java或者.NET平台上,这里我们主要讲的是Windows下的Memcached应用。
这些天在设计SNA的架构,接触了一些远程缓存、集群、session复制等的东西,以前做企业应用的时候感觉作用不大,现在设计面对internet的系统架构时就非常有用了,而且在调试后看到压力测试的情况还是比较好的。
在缓存的选择上有过很多的思考,虽然说memcached结合java在序列化上性能不怎么样,不过也没有更好的集群环境下的缓存解决方案了,就选择了memcached。本来计划等公司买的服务器到位装个linux再来研究memcached,但这两天在找到了一个windows下的Memcached版本,就动手开始调整现有的框架了。
Windows下的Server端很简单,不用安装,双击运行后默认服务端口是11211,没有试着去更改端口,因为反正以后会用Unix版本,到时再记录安装步骤。下载客户端的JavaAPI包,接口非常简单,参考API手册上就有现成的例子。
目标,对旧框架缓存部分进行改造:
1、缓存工具类
2、hibernate的provider
3、用缓存实现session机制
今天先研究研究缓存工具类的改造,在旧框架中部分函数用了ehcache对执行结果进行了缓存处理,现在目标是提供一个缓存工具类,在配置文件中配置使用哪种缓存(memcached或ehcached),使其它程序对具体的缓存不依赖,同时使用AOP方式来对方法执行结果进行缓存。
首先是工具类的实现:
在Spring中配置
Java代码
bean id=”cacheManager”
class=”org.springframework.cache.ehcache.EhCacheManagerFactoryBean”
property name=”configLocation”
valueclasspath:ehcache.xmlvalue
property
bean
bean id=”localCache”
class=”org.springframework.cache.ehcache.EhCacheFactoryBean”
property name=”cacheManager” ref=”cacheManager” /
property name=”cacheName”
value=”×××.cache.LOCAL_CACHE” /
bean
bean id=”cacheService”
class=”×××.core.cache.CacheService” init-method=”init” destroy-method=”destory”
property name=”cacheServerList” value=”${cache.servers}”/
property name=”cacheServerWeights” value=”${cache.cacheServerWeights}”/
property name=”cacheCluster” value=”${cache.cluster}”/
property name=”localCache” ref=”localCache”/
bean
bean id=”cacheManager”
class=”org.springframework.cache.ehcache.EhCacheManagerFactoryBean”
property name=”configLocation”
valueclasspath:ehcache.xmlvalue
property
bean
bean id=”localCache”
class=”org.springframework.cache.ehcache.EhCacheFactoryBean”
property name=”cacheManager” ref=”cacheManager” /
property name=”cacheName”
value=”×××.cache.LOCAL_CACHE” /
bean
bean id=”cacheService”
class=”×××.core.cache.CacheService” init-method=”init” destroy-method=”destory”
property name=”cacheServerList” value=”${cache.servers}”/
property name=”cacheServerWeights” value=”${cache.cacheServerWeights}”/
property name=”cacheCluster” value=”${cache.cluster}”/
property name=”localCache” ref=”localCache”/
bean
在properties文件中配置${cache.servers} ${cache.cacheServerWeights} ${cache.cluster}
具体工具类的代码
Java代码
/**
* @author Marc
*
*/
public class CacheService {
private Log logger = LogFactory.getLog(getClass());
private Cache localCache;
String cacheServerList;
String cacheServerWeights;
boolean cacheCluster = false;
int initialConnections = 10;
int minSpareConnections = 5;
int maxSpareConnections = 50;
long maxIdleTime = 1000 * 60 * 30; // 30 minutes
long maxBusyTime = 1000 * 60 * 5; // 5 minutes
long maintThreadSleep = 1000 * 5; // 5 seconds
int socketTimeOut = 1000 * 3; // 3 seconds to block on reads
int socketConnectTO = 1000 * 3; // 3 seconds to block on initial
// connections. If 0, then will use blocking
// connect (default)
boolean failover = false; // turn off auto-failover in event of server
// down
boolean nagleAlg = false; // turn off Nagle’s algorithm on all sockets in
// pool
MemCachedClient mc;
public CacheService(){
mc = new MemCachedClient();
mc.setCompressEnable(false);
}
/**
* 放入
*
*/
public void put(String key, Object obj) {
Assert.hasText(key);
Assert.notNull(obj);
Assert.notNull(localCache);
if (this.cacheCluster) {
mc.set(key, obj);
} else {
Element element = new Element(key, (Serializable) obj);
localCache.put(element);
}
}
/**
* 删除
*/
public void remove(String key){
Assert.hasText(key);
Assert.notNull(localCache);
if (this.cacheCluster) {
mc.delete(key);
}else{
localCache.remove(key);
}
}
/**
* 得到
*/
public Object get(String key) {
Assert.hasText(key);
Assert.notNull(localCache);
Object rt = null;
if (this.cacheCluster) {
rt = mc.get(key);
} else {
Element element = null;
try {
element = localCache.get(key);
} catch (CacheException cacheException) {
throw new DataRetrievalFailureException(“Cache failure: “
+ cacheException.getMessage());
}
if(element != null)
rt = element.getValue();
}
return rt;
}
/**
* 判断是否存在
*
*/
public boolean exist(String key){
Assert.hasText(key);
Assert.notNull(localCache);
if (this.cacheCluster) {
return mc.keyExists(key);
}else{
return this.localCache.isKeyInCache(key);
}
}
private void init() {
if (this.cacheCluster) {
String[] serverlist = cacheServerList.split(“,”);
Integer[] weights = this.split(cacheServerWeights);
// initialize the pool for memcache servers
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(serverlist);
pool.setWeights(weights);
pool.setInitConn(initialConnections);
pool.setMinConn(minSpareConnections);
pool.setMaxConn(maxSpareConnections);
pool.setMaxIdle(maxIdleTime);
pool.setMaxBusyTime(maxBusyTime);
pool.setMaintSleep(maintThreadSleep);
pool.setSocketTO(socketTimeOut);
pool.setSocketConnectTO(socketConnectTO);
pool.setNagle(nagleAlg);
pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);
pool.initialize();
logger.info(“初始化memcached pool!”);
}
}
private void destory() {
if (this.cacheCluster) {
SockIOPool.getInstance().shutDown();
}
}
}
/**
* @author Marc
*
*/
public class CacheService {
private Log logger = LogFactory.getLog(getClass());
private Cache localCache;
String cacheServerList;
String cacheServerWeights;
boolean cacheCluster = false;
int initialConnections = 10;
int minSpareConnections = 5;
int maxSpareConnections = 50;
long maxIdleTime = 1000 * 60 * 30; // 30 minutes
long maxBusyTime = 1000 * 60 * 5; // 5 minutes
long maintThreadSleep = 1000 * 5; // 5 seconds
int socketTimeOut = 1000 * 3; // 3 seconds to block on reads
int socketConnectTO = 1000 * 3; // 3 seconds to block on initial
// connections. If 0, then will use blocking
// connect (default)
boolean failover = false; // turn off auto-failover in event of server
// down
boolean nagleAlg = false; // turn off Nagle’s algorithm on all sockets in
// pool
MemCachedClient mc;
public CacheService(){
mc = new MemCachedClient();
mc.setCompressEnable(false);
}
/**
* 放入
*
*/
public void put(String key, Object obj) {
Assert.hasText(key);
Assert.notNull(obj);
Assert.notNull(localCache);
if (this.cacheCluster) {
mc.set(key, obj);
} else {
Element element = new Element(key, (Serializable) obj);
localCache.put(element);
}
}
/**
* 删除
*/
public void remove(String key){
Assert.hasText(key);
Assert.notNull(localCache);
if (this.cacheCluster) {
mc.delete(key);
}else{
localCache.remove(key);
}
}
/**
* 得到
*/
public Object get(String key) {
Assert.hasText(key);
Assert.notNull(localCache);
Object rt = null;
if (this.cacheCluster) {
rt = mc.get(key);
} else {
Element element = null;
try {
element = localCache.get(key);
} catch (CacheException cacheException) {
throw new DataRetrievalFailureException(“Cache failure: “
+ cacheException.getMessage());
}
if(element != null)
rt = element.getValue();
}
return rt;
}
/**
* 判断是否存在
*
*/
public boolean exist(String key){
Assert.hasText(key);
Assert.notNull(localCache);
if (this.cacheCluster) {
return mc.keyExists(key);
}else{
return this.localCache.isKeyInCache(key);
}
}
private void init() {
if (this.cacheCluster) {
String[] serverlist = cacheServerList.split(“,”);
Integer[] weights = this.split(cacheServerWeights);
// initialize the pool for memcache servers
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(serverlist);
pool.setWeights(weights);
pool.setInitConn(initialConnections);
pool.setMinConn(minSpareConnections);
pool.setMaxConn(maxSpareConnections);
pool.setMaxIdle(maxIdleTime);
pool.setMaxBusyTime(maxBusyTime);
pool.setMaintSleep(maintThreadSleep);
pool.setSocketTO(socketTimeOut);
pool.setSocketConnectTO(socketConnectTO);
pool.setNagle(nagleAlg);
pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);
pool.initialize();
logger.info(“初始化memcachedpool!”);
}
}
private void destory() {
if (this.cacheCluster) {
SockIOPool.getInstance().shutDown();
}
}
}
然后实现函数的AOP拦截类,用来在函数执行前返回缓存内容
Java代码
public class CachingInterceptor implements MethodInterceptor {
private CacheService cacheService;
private String cacheKey;
public void setCacheKey(String cacheKey) {
this.cacheKey = cacheKey;
}
public void setCacheService(CacheService cacheService) {
this.cacheService = cacheService;
}
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = cacheService.get(cacheKey);
//如果函数返回结果不在Cache中,执行函数并将结果放入Cache
if (result == null) {
result = invocation.proceed();
cacheService.put(cacheKey,result);
}
return result;
}
}
public class CachingInterceptor implements MethodInterceptor {
private CacheService cacheService;
private String cacheKey;
public void setCacheKey(String cacheKey) {
this.cacheKey = cacheKey;
}
public void setCacheService(CacheService cacheService) {
this.cacheService = cacheService;
}
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = cacheService.get(cacheKey);
//如果函数返回结果不在Cache中,执行函数并将结果放入Cache
if (result == null) {
result = invocation.proceed();
cacheService.put(cacheKey,result);
}
return result;
}
}
Spring的AOP配置如下:
Java代码
aop:config proxy-target-class=”true”
aop:advisor
pointcut=”execution(* ×××.PoiService.getOne(..))”
advice-ref=”PoiServiceCachingAdvice” /
aop:config
bean id=”BasPoiServiceCachingAdvice”
class=”×××.core.cache.CachingInterceptor”
property name=”cacheKey” value=”PoiService” /
property name=”cacheService” ref=”cacheService” /
bean
转载
java开发工程师必须要学的技术有哪些?
学习内容:
初级部分
Java 程序设计基础,包括 J2sdk基础、Java面向对象基础、Java API使用、数据结构及算法基础、Java AWT图形界面程序开发;
J2SE平台Java程序设计,包括Swing图形程序设计, Socket网络应用程序设计,对象序列化,Java 常用数据结构,Applet,流和文件,多线程程序设计;
Java桌面系统项目开发,4~5人组成一个项目组,项目大小为(15人*工作日);
Linux的基本操作,Linux下的Java程序开发,Linux系统的简单管理;
Oracle数据库,包括SQL/PLSQL;数据库和数据库设计;简单掌握ORACLE9i 数据库的管理;[2]
中级部分
Java Web应用编程,包括 Java Oracle 编程,即JDBC;JavaWeb编程,包括JSP、Servlet,JavaBean;Java应用编程,包括Weblogic、Websphere、Tomcat;以及利用Jbuilder开发Java程序;
MVC与Struts,学习业界通用的MVC设计模式和Struts架构;
Java B/S商务项目开发,4~5人一个项目组,项目大小为(25人*工作日左右)
高级部分
J2ME程序设计,包括J2EE程序、J2ME;Java高级程序设计(J2EE),包括J2EE体系结构和J2EE技术、EJB;Weblogic使用、 JBuilder开发;
Java和XML,包括Java Web Service,JavaXML, 业界主流XML解析器程序设计;
软件企业规范和软件工程,包括UML系统建模型和设计(Rational Rose 200x)软件工程和业界开发规范;CVS版本控制、Java Code书写规范;
J2EE商务应用系统项目开发,4~5人一个项目组,项目大小为(25人*工作日左右)。
………………………………………………………………………………………………
看你问的问题,应该是对java很感兴趣,其实你可以自学java。关于如何学习java,我刚才看到一篇很不错的文章,是一个农民工介绍自己如何自学java,并找到Java的工作,里面介绍了他的学习方法和学习过程,希望对你有帮助。
我是一名地地道道的农民工,生活在经济落后的农村,有一个哥哥和一个弟弟,父母都是地道的农民,日出而作,日落而息,我从小到大学习一直很好,从小学到高一都,成绩在全级一直名列前茅,这样我也顺利了考上省的重点高中,然而,每个学期开学是家里最为难的时候,每次交学费都让父母发愁许久,家里为了给我筹钱读书,都借了不少钱,才让我读上高中。我知道我读到高中家里已经欠了好多债,为了减轻家里的负担,我选择了退学。
2009年我高一退学,为了给家里还债,干过建筑工地的小工,搞过塑料制品加工,送水工等等。很工资都很低,一个月也就1000多,加上加班费一个月能拿2000多一点,我每个月都向家里寄回800-1000元,到了2011年末,一次偶然的机会我接触了Java,听说Java的前景挺不错,工资相对于我一个农民工来说简直是天文数字,于是我在新华书店买了几本Java的书,尽管白天辛苦工作,晚上回来还是坚持看书,但有于基础太差很多都很不明白,但还是坚持看,一有看1-2个小时Java的书,看着看着许多基础都慢慢的学会了,但那些比较难的还是看不懂,后来还买了有些关于框架的书,还是看不懂,这样断断续续的持续了半年多,觉得自己Java的基础都差不多懂了,但框架还是看不懂,还有最缺的项目经验,看了很多招聘Java程序员的简介都要项目经验,相对我一个农民工来连框架都弄不明白,想找一份Java工作对我来说简直是奢侈。我只想学Java,并不敢想以后能从事Java的工作。
有一次,在百度上看到一篇让我很鼓舞的文章,是一个Java高手介绍在没有基础的朋友怎么自学入门Java,文章写的很好,包含了如何学习,该怎么学习,他提到一个方法就是看视频,因为看书实在太枯燥和费解的,不少是我们也看不懂,这点我真的很认同,我自己看书都看了很久才学会基础。曾经有想过参加培训,但是上万元的培训费让我望而却步,我工资这么低,每个月还有向家里汇钱,加上城市消费比较高,虽然每个月只有几百剩下,但是相对于上万万学费和四个月的吃住费用逼我连想不敢想。 于是我决定看视频,我就去搜索Java的视频,虽然我零星的找到一些Java的视频,但是都不系统。最重要连项目都没有。后来我找到一份很好的视频,是IT学习联盟这个网站一套视频叫零基础Java就业班的教程还不错,很完整。还赠送11个顶级企业项目。价格很合理,于是我买下来。
于是开始了我的自学Java的路,收到光盘后,我就开始学习,刚开始学习还不错,是从零基础教起,老师幽默风趣而又轻松的课堂教课,使我发现原来学习JAVA并不是一件很难的事情。因为我本来基础还不错,前面的基础看一篇我就过去了,到了框架,我觉不又不是很难,可能老师太牛了,他能把复杂的问题讲的比较通俗易懂,有些难点的地方我还是连续看了五六次,把他弄懂。每天下午6点下班后,吃了饭,马上跑回家。看视频,买了几本笔记本。当时,为了编程还花几百元了台二手的台式电脑,配置一般,但编程是足够的。一边看视频,一边记笔记,把重点都记下来,还一边跟着老师敲代码,为了能尽早学会Java。每天都坚持学5-6个小时。经常学到晚上一点多才睡觉。星期六,日不用上班,每天7点多起床,学到晚上11,12点。那段时间特别辛苦,特别累。在学习Java的三个多月里,除了吃饭睡觉工作,剩余的时间都在学习,因为我知道自己的计算机基础不是很好,也没有学过什么计算机,只是学了些Java基础,相对于那些科班的人来说我要比他们付出更多的努力。我只能咬紧牙关,坚持下去,我不能放弃,我要完成我的梦想,我要让我的家人过上好日子。终于三个多月后我把Java教程里的内容和项目都学完了,在学项目的过程中我发现项目特别重要,他能把你学过的知识全部联系起来,能更好的理解你所学的知识。还有学习过程中,动手很重要,要经常跟着老师动手敲,动手吧,跟着做,一行一行的跟着敲,再试着加一些自己的功能,按照自己的思路敲一些代码,收获远比干听大的多。 如果遇到暂时对于一些思路不能理解的,动手写,先写代码,慢慢你就会懂了。这套视频还赠送了11个顶级企业项目,对于我没有任何经验的人来说,这个太重要了,还有在学习项目是提升能力最快的方法。项目能把所有的知识点全都连到一起了,不再是分散的,而是形成一个整体了。那种感觉是仅仅深入钻研知识点而不写真实项目的人所不能体会的。一个项目就是一根绳子可以把大片的知识串到一起。 就这样,我用了两个月也把项目给学完了。其实学完教程差不错就达到就业水平,但是我可能觉得自己学历低还是把那11个顶级企业项目才去找工作。
接着我就到51job疯狂的投简历,因为我的学历问题,初中毕业,说真的,大公司没有人会要我。所以我头的都是民营的小公司,我希望自己的努力有所回报。没有想过几天后,就有面试了,但是第一次面试我失败了,虽然我自认为笔试很好,因为我之前做了准备,但是他们的要求比价严格,需要有一年的项目经验,所以我没有被选中。 后来陆续面试了几加公司,终于功夫不负有心人,我终于面试上了一家民营的企业。公司规模比较小,我的职务是Java程序员。我想我比较幸运,经理看中我的努力,就决定吕勇我,开的工资是3500一个月,虽然我知道在北京3500只能过温饱的生化,但是我想我足够了,比起以前的工资好了些,以后可以多寄些钱回家。我想只要我继续努力。我工资一定会翻倍的。 把本文写出来,希望能让和我一样的没有基础的朋友有信心,其实我们没有自卑,我们不比别人笨,只有我们肯努力,我们一样会成功。
java一面和二面什么区别
下面列出了一面问到的问题:
synchronized与lock的区别,使用场景。看过synchronized的源码没
JVM自动内存管理,Minor GC与Full GC的触发机制
了解过JVM调优没,基本思路是什么
如何设计存储海量数据的存储系统
缓存的实现原理,设计缓存要注意什么
淘宝热门商品信息在JVM哪个内存区域
操作系统的页式存储
volatile关键字的如何保证内存可见性
happen-before原则
Lucene全文搜索的原理
阿里二面
下面是面试过程中的问题:
自我介绍下自己,不超过3分钟(我的自我介绍仍然不超过1分钟)
你说你熟悉并发编程,那么你说说Java锁有哪些种类,以及区别(果然深度不一样)
如何保证内存可见性
Http请求的过程与原理
TCP连接的特点
TCP连接如何保证安全可靠的
为什么TCP连接需要三次握手,两次不可以吗,为什么
AOP的原理
动态代理与cglib实现的区别(这个,醉得很厉害)
那么你说说代理的实现原理呗
看过Spring源码没,说说Ioc容器的加载过程吧
阿里三面(总监面)
先问项目,从项目问起
了解什么分布式数据一致性算法,具体说说
MySQL事务隔离级别以及MVCC机制
Redis缓存雪崩、缓存穿透以及如何解决?
问了设计秒杀系统
说说同步和异步,什么时候用同步,什么时候用异步
mysql的innodb索引数据结构为什么是b+树,用hash来实现可以吗?
分布式事务的实现?
如何解决redis和mysql数据一致性?
常见的MySQL主从同步方案有哪些?优劣势比较过?
阿里四面(总监面)
自我介绍
手画自己项目架构图,然后针对架构和中间件提问
四面总结
一面和二面总结
一面大概面了50多分钟,可以看出一面的问题不是很难,但是要得到面试官比较高的评价,还是需要一-定的表达能力和对技术比较本质的认识的,如果在回答问题的时候能够做一些适当的扩展,自然会让面试官对你有不一样的评价。
二面面试官问的问题都比较直接,答案也是知道就知道,不知道就不知道。这些问题-部分是基础,一部分是根据你的专业技能的来提问的。面完后面试官对我的评价是:中规中矩,有机会下次面试。虽说是中规中矩,但听到面试官说有机会下次面试就感觉这次面试应该过了。
三面总结
三面是交叉面,没想到是阿里的总监面试。由于具体的技术问题在前两轮面试中已经问过了,所以三面后不会有具体的技术问题,总结来看,对自己做过的项目一定要深入,包括使用使用到的技术原理、为什么要使用这些技术。
针对项目,面试官关注的无非以下几点:
1.项目中某个比较重要的点是如何实现的(需要深入技术的原理)
2.遇到的最大困难是什么(有哪些),你怎么解决的?
3.如果需要扩展某个功能,如何降低系统的耦合度
4.如果针对某个功能进行优化,你会怎么设计和优化
四面总结
虽然这面比较轻松,也没有什么具体的技术问题,但对项目仍然是面试官关注的,后面了解到总监面除了看你的基础,主要看你的潜力(就是有没有培养的价值),这个东西看起来挺虚的,但是从你平时的学习中仍然是可以看得出来的。所以,作为一名开发人员。平时对技术的研究也是很重要的
最后
其实一步一步走过来,不单单只靠面试之前刷题那么简单,更多的还是平时的积累。小编整理出一篇Java进阶架构师之路的核心知识,同时也是面试时面试官必问的知识点,篇章也是包括了很多知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日志、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等
想要免费获取这份完整版文档的朋友,点赞、关注、转发之后,私信【学习】即可免费获取
最后是总重要的技能环节,分享给大家一份核心面试文档
JavaOOP
Java集合/泛型
由于篇幅限制,无法全部展现出来,文末有完整版获取方式
Java异常
Java中的IO与NIO
Java反射
Java序列化
什么是java序列化,如何实现java序列化?
保存(持久化)对象及其状态到内存或者磁盘
序列化对象以字节数组保持-静态成员不保存
序列化用户远程对象传输
Serializable 实现序列化
writeObject 和 readObject 自定义序列化策略
序列化 ID
序列化并不保存静态变量
Transient 关键字阻止该变量被序列化到文件中
序列化(深 clone 一中实现)
多线程并发
JAVA 并发知识库
Java中实现多线程有几种方法
继承 Thread 类
实现 Runnable 接口。
ExecutorService、 Callable、 Future 有返回值线程
基于线程池的方式
4 种线程池
如何停止一个正在运行的线程
notify()和notifyAll()有什么区别?
sleep()和wait() 有什么区别?
volatile 是什么?可以保证有序性吗?
JVM
java中会存在内存泄漏吗,请简单描述。
64 位 JVM 中,int 的长度是多数?
Serial 与 Parallel GC 之间的不同之处?
32 位和 64 位的 JVM,int 类型变量的长度是多数?
Java 中 WeakReference 与 SoftReference 的区别?
JVM 选项 -XX:+UseCompressedOops 有什么作用?为什么要使用
怎样通过 Java 程序来判断 JVM 是 32 位 还是 64位?
32 位 JVM 和 64 位 JVM 的最大堆内存分别是多数?
JRE、JDK、JVM 及 JIT 之间有什么不同?
解释 Java 堆空间及 GC?
Mysql
数据库存储引擎
InnoDB(B+树)
TokuDB( Fractal Tree-节点带数据)
Memory
数据库引擎有哪些
InnoDB与MyISAM的区别
索引
常见索引原则有
数据库的三范式是什么
第一范式(1st NF - 列都是不可再分)
Redis
什么是 Redis?
Redis 与其他 key-value 存储有什么不同?
Redis 的数据类型?
使用 Redis 有哪些好处?
Redis 相比 Memcached 有哪些优势?
Memcache 与 Redis 的区别都有哪些?
Redis 是单进程单线程的?
一个字符串类型的智能存储最大容量是多少?
Redis持久化机制
缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题
Memcached
Memcached 是什么,有什么作用?
memcached 服务在企业集群架构中有哪些应用场景?
Memcached 服务分布式集群如何实现?
Memcached 服务特点及工作原理是什么?
简述 Memcached 内存管理机制原理?
memcached 是怎么工作的?
memcached 最大的优势是什么?
memcached 和 MySQL 的 query
memcached 和服务器的 local cache(比如 PHP 的 APC、mmap 文件等)相比,有什么优缺点?
memcached 的 cache 机制是怎样的?
memcached 如何实现冗余机制?
MongoDB
mongodb是什么?
mongodb有哪些特点?
你说的NoSQL数据库是什么意思?NoSQL与RDBMS直接有什么区别?为什么要使用和不使用NoSQL数据库?说一说NoSQL数据库的几个优点?
NoSQL数据库有哪些类型?
MySQL与MongoDB之间最基本的差别是什么?
你怎么比较MongoDB、CouchDB及CouchBase?
MongoDB成为最好NoSQL数据库的原因是什么?
journal回放在条目(entry)不完整时(比如恰巧有一个中途故障了)会遇到问题吗?
分析器在MongoDB中的作用是什么?
名字空间(namespace)是什么?
Spring
不同版本的 Spring Framework 有哪些主要功能?
什么是 Spring Framework?
列举 Spring Framework 的优点。
Spring Framework 有哪些不同的功能?
Spring Framework 中有多少个模块,它们分别是什么?
什么是 Spring 配置文件?
Spring 应用程序有哪些不同组件?
使用 Spring 有哪些方式?
什么是 Spring IOC 容器?
什么是依赖注入?
Spring Boot
什么是 Spring Boot?
为什么要用SpringBoot
Spring Boot 有哪些优点?
Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?
运行Spring Boot有哪几种方式
如何理解 Spring Boot 中的 Starters?
如何在Spring Boot启动的时候运行一些特定的代码?
Spring Boot 需要独立的容器运行吗?
Spring Boot中的监视器是什么?
如何使用Spring Boot实现异常处理?
Spring Cloud
什么是 Spring Cloud?
使用 Spring Cloud 有什么优势?
服务注册和发现是什么意思?Spring Cloud 如何实现?
负载平衡的意义什么?
什么是 Hystrix?它如何实现容错?
什么是 Hystrix 断路器?我们需要它吗?
什么是 Netflix Feign?它的优点是什么?
什么是 Spring Cloud Bus?我们需要它吗?
什么是微服务
什么是服务熔断?什么是服务降级
RabbitMQ
什么是 rabbitmq
为什么要使用 rabbitmq
使用 rabbitmq 的场景
如何确保消息正确地发送至 RabbitMQ? 如何确保消息接收方消费了消息?
如何避免消息重复投递或重复消费?
消息基于什么传输?
消息如何分发?
消息怎么路由?
如何确保消息不丢失?
使用 RabbitMQ 有什么好处?
Dubbo
为什么要用 Dubbo?
Dubbo 的整体架构设计有哪些分层?
默认使用的是什么通信框架,还有别的选择吗?
服务调用是阻塞的吗?
一般使用什么注册中心?还有别的选择吗?
默认使用什么序列化框架,你知道的还有哪些?
服务提供者能实现失效提出是什么原理?
服务上线怎么不影响旧版本?
如何解决服务调用链过长的问题?
说说核心的配置有哪些?
MyBatis
什么是 Mybatis?
Mybaits 的优点
MyBatis 框架的缺点
MyBatis 框架适用场合
MyBatis 与 Hibernate 有哪些不同?
#{}和${}的区别是什么?
当实体类中的属性名和表中的字段名不一样 ,怎么办 ?
模糊查询 like 语句该怎么写?
通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?
如何获取自动生成的(主)键值?
ZooKeeper
什么是Zookeeper?
Zookeeper 如何保证了分布式一致性特性?
ZooKeeper 提供了什么?
Zookeeper 文件系统
ZAB 协议?
四种类型的数据节点 Znode
Zookeeper Watcher 机制 — 数据变更通知
客户端注册 Watcher 实现
服务端处理 Watcher 实现
客户端回调 Watcher
数据结构
栈(stack)
队列(queue)
链表(Link)
散列表(Hash Table)
排序二叉树
前缀树
红黑树
B-TREE
位图
Elasticsearch
elasticsearch 了解多少,说说你们公司 es 的集群架构,索引数据大小,分片有多少,以及一些调优手段 。
elasticsearch 的倒排索引是什么
elasticsearch 索引数据多了怎么办,如何调优,部署
elasticsearch 是如何实现 master 选举的
详细描述一下 Elasticsearch 索引文档的过程
详细描述一下 Elasticsearch 搜索的过程?
Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法
lucence 内部结构是什么?
Elasticsearch 是如何实现 Master 选举的?
Elasticsearch 中的节点(比如共 20 个),其中的 10 个选了一个 master,另外 10 个选了另一个 master,怎么办?
Kafka
Kafka 是什么
partition 的数据文件(offset, MessageSize, data)
数据文件分段 segment(顺序读写、分段命令、二分查找)
负载均衡(partition 会均衡分布到不同 broker 上)
批量发送
压缩(GZIP 或 Snappy)
消费者设计
Consumer Group
如何获取 topic 主题的列表
生产者和消费者的命令行是什么?
微服务
微服务架构有哪些优势?
微服务有哪些特点?
设计微服务的最佳时间是什么?
微服务架构如何运作?
微服务架构的优缺点是什么?
单片,SOA 和微服务架构有什么区别?
在使用微服务架构时,您面临哪些挑战?
SOA 和微服务架构之间的主要区别是什么?
微服务有什么特点?
Linux
绝对路径用什么符号表示?当前目录、上层目录用什么表示?主目录用什么表示? 切换目录用什么命令?
怎么查看当前进程?怎么执行退出?怎么查看当前路径?
怎么清屏?怎么退出当前命令?怎么执行睡眠?怎么查看当
Ls 命令执行什么功能? 可以带哪些参数,有什么区别?
查看文件有哪些命令
列举几个常用的Linux命令
你平时是怎么查看日志的?
建立软链接(快捷方式),以及硬链接的命令
目录创建用什么命令?创建文件用什么命令?复制文件用什么命令?
查看文件内容有哪些命令可以使用?
面试,难还是不难?最终结果好还是不好?取决于面试者的底蕴(气场+技能)、心态和认知以及沟通技巧。而一些主流的大型互联网公司面试(阿里巴巴、京东、美团、滴滴)更是需要你在面试时展现出自己的能力,从而获得面试官的欣赏和肯定。
而程序员在应聘时更是需要经历层层面试。俗话说,磨刀不误砍柴工,做好面试前的准备工作可以帮助大家更好的应对面试官的问题以及面试中的突发情况。
不用出国也能买到60多万的真皮腰带!机会难得,快来试试
精选推荐
广告

面试题2
104阅读·0评论·0点赞
2020年11月25日
66个求职应聘技巧性问答(三)
955阅读·0评论·0点赞
2015年5月26日
凯捷Java二面问题总结
84阅读·1评论·0点赞
2022年10月24日
程序员面试中一面、二面、三面有什么区别?
2697阅读·1评论·3点赞
2023年1月5日
纯干货分享!百度Java一、二、三面面经总结,本人已成功拿到offer!
5987阅读·7评论·8点赞
2021年4月11日
Java 虚拟机系列一:一文搞懂 JVM 架构和运行时数据区
460阅读·2评论·0点赞
2020年1月23日
阿里后端开发Java面经,附上我的面试真题复盘,希望对大家有帮助!
1429阅读·0评论·0点赞
2021年4月22日
华为OD(外包)社招技术二面,总结复盘
1.4W阅读·4评论·7点赞
2020年9月28日
java二面技术面试经验_网易java开发面试:一面+二面+三面以及 面试经验总结
280阅读·0评论·0点赞
2021年3月1日
java一面和二面_钉钉面经,Java面试题,一面二面整理
268阅读·0评论·0点赞
2021年3月10日
阿里Java研发2面,都会问什么?斩获阿里P6+的“他”告诉你答案
200阅读·2评论·0点赞
2021年5月19日
网易java程序员面试_网易Java程序员两轮面试 请问你能答对几个?
106阅读·0评论·0点赞
2021年3月8日
java二面问什么_java面试题,拼多多面试题分享(java二面)
2792阅读·0评论·1点赞
2021年3月11日
阿里高级Java面试题(首发,70道,带详细答案)
408阅读·0评论·0点赞
2022年8月19日
四年开发,待业半年本想放弃Java,抱着试试的心态面试某C轮金融科技公司居然过了!
1866阅读·18评论·6点赞
2020年11月21日
阿里第2面,都会问什么?
1426阅读·0评论·0点赞
2019年11月15日
阿里二面(主问项目和开发性问题)
875阅读·0评论·0点赞
2018年7月28日
阿里java研发岗五面(HR面+技术四面),附面试路线分享!
372阅读·0评论·1点赞
2021年7月26日
华为技术支持面试
7450阅读·1评论·3点赞
2011年11月18日
去首页
看看更多热门内容
评论1

jiasiyan

赞
请问大佬,校招不会问得这么难吧
如何配置Memcached服务器
Windows下的Memcache安装
1. 下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached
2. 在终端(也即cmd命令界面)下输入 c:\memcached\memcached.exe -d install --安装memcached成为服务,这样才能正常运行,否则运行失败!
3. 再输入: c:\memcached\memcached.exe -d start --启动memcached的。
以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。
Linux下的安装:
1.下载memcached和libevent,放到 /tmp 目录下
# cd /tmp
# wget
# wget
2.先安装libevent:
# tar zxvf libevent-1.2.tar.gz
# cd libevent-1.2
# ./configure –prefix=/usr
# make
# make install
3.测试libevent是否安装成功:
# ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent-1.2.so.1 – libevent-1.2.so.1.0.3
-rwxr-xr-x 1 root root 263546 11?? 12 17:38 libevent-1.2.so.1.0.3
-rw-r–r– 1 root root 454156 11?? 12 17:38 libevent.a
-rwxr-xr-x 1 root root 811 11?? 12 17:38 libevent.la
lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent.so – libevent-1.2.so.1.0.3
4.安装memcached,同时需要安装中指定libevent的安装位置:
# cd /tmp
# tar zxvf memcached-1.2.0.tar.gz
# cd memcached-1.2.0
# ./configure –with-libevent=/usr
# make
# make install
如果中间出现报错,请仔细检查错误信息,按照错误信息来配置或者增加相应的库或者路径。
安装完成后会把memcached放到 /usr/local/bin/memcached ,
5.测试是否成功安装memcached:
# ls -al /usr/local/bin/mem*
-rwxr-xr-x 1 root root 137986 11?? 12 17:39 /usr/local/bin/memcached
-rwxr-xr-x 1 root root 140179 11?? 12 17:39 /usr/local/bin/memcached-debug
memcached的基本设置:
1.启动Memcache的服务器端:
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid
-d选项是启动一个守护进程,
-m是分配给Memcache使用的内存数量,单位是MB,这里是10MB,
-u是运行Memcache的用户,这里是root,
-l是监听的服务器IP地址,如果有多个地址的话,这里指定了服务器的IP地址192.168.0.200,
-p是设置Memcache监听的端口,这里设置了12000,最好是1024以上的端口,
-c选项是最大运行的并发连接数,默认是1024,这里设置了256,按照你服务器的负载量来设定,
-P是设置保存Memcache的pid文件,这里是保存在 /tmp/memcached.pid,
2.如果要结束Memcache进程,执行:
# kill `cat /tmp/memcached.pid`
也可以启动多个守护进程,不过端口不能重复。
3.重启apache,service httpd restart
java的客户端连接程序:
将java_memcached-release_1.6.zip解压后的目录中的java_memcached-release_2.0.jar文件复制到java项目的lib目录下。
package utils.cache;
import java.util.Date;
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
/**
* 使用memcached的缓存实用类.
*/
public class MemCached
{
// 创建全局的唯一实例
protected static MemCachedClient mcc = new MemCachedClient();
protected static MemCached memCached = new MemCached();
// 设置与缓存服务器的连接池
static {
// 服务器列表和其权重
String[] servers = {“127.0.0.1:11211”};
Integer[] weights = {3};
// 获取socke连接池的实例对象
SockIOPool sockIOPool = SockIOPool.getInstance();
// 设置服务器信息
sockIOPool.setServers( servers );
sockIOPool.setWeights( weights );
// 设置初始连接数、最小和最大连接数以及最大处理时间
sockIOPool.setInitConn( 5 );
sockIOPool.setMinConn( 5 );
sockIOPool.setMaxConn( 250 );
sockIOPool.setMaxIdle( 1000 * 60 * 60 * 6 );
// 设置主线程的睡眠时间
sockIOPool.setMaintSleep( 30 );
// 设置TCP的参数,连接超时等
sockIOPool.setNagle( false );
sockIOPool.setSocketTO( 3000 );
sockIOPool.setSocketConnectTO( 0 );
//sockIOPool.setFailover(bFailover);
//sockIOPool.setAliveCheck(bAliveCheck);
// 初始化连接池
sockIOPool.initialize();
// 压缩设置,超过指定大小(单位为K)的数据都会被压缩
if (memCachedClient == null)
{
mcc = new MemCachedClient(sPoolName);
mcc.setCompressEnable(true);
mcc.setCompressThreshold(4096);
mcc.setPrimitiveAsString(true);
}
}
/*
h3基于Spring的配置,如下:/h3
pre
bean id=”memCachedService” class=”com.ms.memcached.MemCachedServiceImpl”
constructor-arg index=”0″ value=”${memcached.pool.name}” /
constructor-arg index=”1″ value=”${memcached.pool.servers}” /
constructor-arg index=”2″ value=”${memcached.pool.initConn}” /
constructor-arg index=”3″ value=”${memcached.pool.maxConn}” /
constructor-arg index=”4″ value=”${memcached.pool.minConn}” /
constructor-arg index=”5″ value=”${memcached.pool.socketTO}” /
constructor-arg index=”6″ value=”${memcached.pool.maintSleep}” /
constructor-arg index=”7″ value=”${memcached.pool.nagle}” /
constructor-arg index=”8″ value=”${memcached.pool.failover}” /
constructor-arg index=”9″ value=”${memcached.pool.aliveCheck}” /
/bean
/pre
h3利用com.MS.cache.properties来设置参数,如下:/h3
pre
memcached.pool.name = MS
memcached.pool.servers = 192.168.9.132:12000,192.168.9.133:12000
memcached.pool.initConn = 128
memcached.pool.maxConn = 1024
memcached.pool.minConn = 20
memcached.pool.socketTO = 3000
memcached.pool.maintSleep = 30
memcached.pool.nagle = false
memcached.pool.failover = true
memcached.pool.aliveCheck = true
/pre
*/
/**
* 保护型构造方法,不允许实例化!
*/
protected MemCached()
{
}
/**
* 获取唯一实例.
*/
public static MemCached getInstance()
{
return memCached;
}
/**
* 添加一个指定的值到缓存中.
* @param key
* @param value
*/
//新增指定key的缓存内容,但不覆盖已存在的内容。
public boolean add(String key, Object value)
{
return mcc.add(key, value);
}
//expiry过期时间
public boolean add(String key, Object value, Date expiry)
{
return mcc.add(key, value, expiry);
}
//新增或覆盖指定Key的缓存内容
public boolean set(String key, Object value)
{
return mcc.set(key, value);
}
//lExpiry过期时间
public boolean set(String key, Object value, long lExpiry)
{
return mcc.set(key, value, new Date(lExpiry));
}
//根据指定的Key获取缓存内容
public boolean get(String key)
{
return mcc.get(key);
}
//根据指定Key更新缓存内容
public boolean replace(String key, Object value)
{
return mcc.replace(key, value);
}
//lExpiry 指定的时间
public boolean replace(String key, Object value, long lExpiry)
{
return mcc.replace(key, value, new Date(lExpiry));
}
//根据指定Key删除缓存内容
public boolean delete(String key, Object value)
{
return mcc.delete(key, value);
}
//根据指定Key在指定时间后删除缓存内容
public boolean delete(String key, Object value, long lExpiry)
{
return mcc.delete(key, value, new Date(lExpiry));
}
//检测Cache中当前Key是否存在
public boolean exists(String key)
{
return mcc.exists(key);
}
//根据指定一批Key批量获取缓存内容。
/*
* @param sKeys 指定的一批Key。
* @return Object[oValue]
*/
public Object[] getMultiArray(String[] sKeys) throws ServiceException
{
return memCachedClient.getMultiArray(sKeys);
}
/**
* 根据指定一批Key批量获取缓存内容。
*
* @param sKeys 指定的一批Key。
* @return MapsKey, oValue
*/
public MapString, Object getMulti(String[] sKeys) throws ServiceException
{
return memCachedClient.getMulti(sKeys);
}
public static void main(String[] args)
{
MemCached memCached= MemCached.getInstance();
memCached.add(“hello”, 234);
System.out.print(“get value : ” + memCached.get(“hello”));
}
}
那么我们就可以通过简单的像main方法中操作的一样存入一个变量,然后再取出进行查看,我们可以看到先调用了add,然后再进行get,我们运行一次 后,234这个值已经被我们存入了memcached的缓存中的了,我们将main方法中红色的那一行注释掉后,我们再运行还是可以看到get到的 value也是234,即缓存中我们已经存在了数据了。
对基本的数据我们可以操作,对于普通的POJO而言,如果要进行存储的话,那么比如让其实现java.io.Serializable接口,因为 memcached是一个分布式的缓存服务器,多台服务器间进行数据共享需要将对象序列化的,所以必须实现该接口,否则会报错的。
Entity
/**
* 获取当前实体的缓存Id
*
* @return
*/
public String getCacheId()
{
return getCacheId(this.getClass(), sBreedId);
}
get
public Breed getBreedById(String sBreedId) throws ServiceException
{
Breed breed = (Breed)memCachedService.get(getCacheId(Breed.class, sBreedId));
if(breed == null)
{
breed = service.get(“breed.getBreedById”, sBreedId);
if(breed != null)
{
memCachedService.set(breed.getBreedId(), breed);
}
}
return breed;
}
save
memCachedService.set(spider.getCacheId(), breed);
update
memCachedService.replace(spider.getCacheId(), breed);
remove
memCachedService.delete(getCacheId(Spider.class, IbreedId));
或
memCachedService.delete(breed.getCacheId());
listAll
public List listAll() throws ServiceException
{
List breeds = new ArrayList ();
List breedIds = (List)memCachedService.get(getKeyByMap(“Breed”, null));
if(ObjectUtils.isEmpty(breedIds))
{
breeds = service.list(“breed.getAllBreed”, null);
if (!ObjectUtils.isEmpty(breeds))
{
breedIds = new ArrayList();
for (Breed breed : breeds)
{
breedIds.add(breed.getBreedId());
}
memCachedService.set(getKeyByMap(“Breed”, null), breedIds);
}
}
else
{
for (String sBreedId : breedIds)
{
Breed breed = getBreedById(sBreedId);
if (breed != null)
{
breeds.add(breed);
}
}
}
return breeds;
}
redis可以多key对应一个value吗
redis可以多key对应一个value,设置方法为:
1、打开HBuilderX工具,新建web项目并在js文件夹中,创建一个js文件map.js。
2、进入到map.js,定义一个map变量(Map类型),然后调用set方法设置key-value。
3、调用for…of语句,遍历map变量的值,使用entries()方法,打印对应的key和value。
4、接着新建一个HTML5页面,并将map.js引入到页面中。
5、修改map.js,调用window.onload,并定义showKeys方法。
java不用数据库怎样保存数据
比较常用的就是保存到XML文件,我的博客(百度搜索“图显IP”,第一位就是我的网站)就是用种方式,这样就可以不用受数据库的限制,轻量级,方便部署,哪怕是虚拟主机,不用单独购买数据库