当前位置:首页 » 硬盘大全 » 缓存架构面试
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

缓存架构面试

发布时间: 2022-02-01 16:07:06

‘壹’ Java软件工程师的具体职责是什么

Java软件工程师运用Java开发工具去完成软件产品的软件程序设计、开发、测试、维护升级等工作。具体职责是:

1、按产品或项目要求进行技术开发,能独立完成模块分析设计。

2、根据开发规范与流程独立完成详细设计,编码,测试及相关文档。

3、负责信息系统(如OA、CRM等)持续优化,以及微信企业平台端的开发。

4、负责信息系统的推广应用,数据管理及日常维护管理。

5、配合信息安全主任做好信息安全保密工作。



任职要求

1、计算机专业本科以上学历,从事后台系统开发1年以上工作经验;

2、熟练使用Java/.NET语言开发Web应用,熟悉主流技术框架;

3、熟悉数据库理论,熟练掌握主流数据库MySQL、SQL Server等的应用;

4、熟悉HTML、XML、JavaScprit、ajax、Web Servrice等WEB技术;

5、熟悉Linux操作系统者优先;有大型网站/系统开发经验者优先。

‘贰’ 马上就java面试了,不会介绍项目,咋办我没做过实际项目,是自学出来的,为了好找工作,我照别人的

没实际开发过项目,你都敢写上4,5个,我java干两年大项目也就做过两个, 通常干过4,5个的话那就可以面试高工,厉害的就是架构师了

‘叁’ 面试之mybatis和hibernate的区别

第一章Hibernate与MyBatis

Hibernate是当前最流行的O/R mapping框架,它出身于sf.net,现在已经成为Jboss的一部分。Mybatis是另外一种优秀的O/R mapping框架。目前属于apache的一个子项目。

MyBatis参考资料官网:http://www.mybatis.org/core/zh/index.html

Hibernate参考资料:http://docs.jboss.org/hibernate/core/3.6/reference/zh-CN/html_single/

1.1 Hibernate简介

Hibernate对数据库结构提供了较为完整的封装,Hibernate的O/R Mapping实现了POJO和数据库表之间的映射,以及SQL的自动生成和执行。程序员往往只需定义好了POJO到数据库表的映射关系,即可通过Hibernate提供的方法完成持久层操作。程序员甚至不需要对SQL的熟练掌握,Hibernate/OJB会根据制定的存储逻辑,自动生成对应的SQL并调用JDBC接口加以执行。

1.2 MyBatis简介

iBATIS的着力点,则在于POJO与SQL之间的映射关系。然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定POJO。 相对Hibernate“O/R”而言,iBATIS是一种“Sql Mapping”的ORM实现。

第二章 开发对比

开发速度

Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。

开发社区

Hibernate与Mybatis都是流行的持久层开发框架,但Hibernate开发社区相对多热闹些,支持的工具也多,更新也快,当前最高版本4.1.8。而Mybatis相对平静,工具较少,当前最高版本3.2。

开发工作量

Hibernate和MyBatis都有相应的代码生成工具。可以生成简单基本的DAO层方法。

针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。

第三章 系统调优对比

Hibernate的调优方案

  • 制定合理的缓存策略;

  • 尽量使用延迟加载特性;

  • 采用合理的Session管理机制;

  • 使用批量抓取,设定合理的批处理参数(batch_size);

  • 进行合理的O/R映射设计

  • Mybatis调优方案

    MyBatis在Session方面和Hibernate的Session生命周期是一致的,同样需要合理的Session管理机制。MyBatis同样具有二级缓存机制。MyBatis可以进行详细的SQL优化设计。

    SQL优化方面

    Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。而Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。

    Hibernate HQL语句的调优需要将SQL打印出来,而Hibernate的SQL被很多人嫌弃因为太丑了。MyBatis的SQL是自己手动写的所以调整方便。但Hibernate具有自己的日志统计。Mybatis本身不带日志统计,使用Log4j进行日志记录。

    扩展性方面

    Hibernate与具体数据库的关联只需在XML文件中配置即可,所有的HQL语句与具体使用的数据库无关,移植性很好。MyBatis项目中所有的SQL语句都是依赖所用的数据库的,所以不同数据库类型的支持不好。

    第四章 对象管理与抓取策略

    对象管理

    Hibernate是完整的对象/关系映射解决方案,它提供了对象状态管理(state management)的功能,使开发者不再需要理会底层数据库系统的细节。也就是说,相对于常见的JDBC/SQL持久层方案中需要管理SQL语句,Hibernate采用了更自然的面向对象的视角来持久化Java应用中的数据。

    换句话说,使用Hibernate的开发者应该总是关注对象的状态(state),不必考虑SQL语句的执行。这部分细节已经由Hibernate掌管妥当,只有开发者在进行系统性能调优的时候才需要进行了解。

    而MyBatis在这一块没有文档说明,用户需要对对象自己进行详细的管理。

    抓取策略

    Hibernate对实体关联对象的抓取有着良好的机制。对于每一个关联关系都可以详细地设置是否延迟加载,并且提供关联抓取、查询抓取、子查询抓取、批量抓取四种模式。 它是详细配置和处理的。

    而Mybatis的延迟加载是全局配置的。

    第五章 缓存机制对比

    Hibernate缓存

    Hibernate一级缓存是Session缓存,利用好一级缓存就需要对Session的生命周期进行管理好。建议在一个Action操作中使用一个Session。一级缓存需要对Session进行严格管理。

    Hibernate二级缓存是SessionFactory级的缓存。SessionFactory的缓存分为内置缓存和外置缓存。内置缓存中存放的是SessionFactory对象的一些集合属性包含的数据(映射元素据及预定SQL语句等),对于应用程序来说,它是只读的。外置缓存中存放的是数据库数据的副本,其作用和一级缓存类似.二级缓存除了以内存作为存储介质外,还可以选用硬盘等外部存储设备。二级缓存称为进程级缓存或SessionFactory级缓存,它可以被所有session共享,它的生命周期伴随着SessionFactory的生命周期存在和消亡。

    MyBatis缓存

    MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。

    默认情况下是没有开启缓存的,除了局部的session缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的SQL映射文件中添加一行: <cache/>

    字面上看就是这样。这个简单语句的效果如下:

  • 映射语句文件中的所有select语句将会被缓存。

  • 映射语句文件中的所有insert,update和delete语句会刷新缓存。

  • 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。

  • 根据时间表(比如no Flush Interval,没有刷新间隔),缓存不会以任何时间顺序 来刷新。

  • 缓存会存储列表集合或对象(无论查询方法返回什么)的1024个引用。

  • 缓存会被视为是read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

  • 所有的这些属性都可以通过缓存元素的属性来修改。

    比如: <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

    这个更高级的配置创建了一个FIFO缓存,并每隔60秒刷新,存数结果对象或列表的512个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。可用的收回策略有,默认的是LRU:

  • LRU–最近最少使用的:移除最长时间不被使用的对象。

  • FIFO–先进先出:按对象进入缓存的顺序来移除它们。

  • SOFT–软引用:移除基于垃圾回收器状态和软引用规则的对象。

  • WEAK–弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

  • flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

    size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是1024。

    readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。

    相同点

    Hibernate和Mybatis的二级缓存除了采用系统默认的缓存机制外,都可以通过实现你自己的缓存或为其他第三方缓存方案,创建适配器来完全覆盖缓存行为。

    不同点

    Hibernate的二级缓存配置在SessionFactory生成的配置文件中进行详细配置,然后再在具体的表-对象映射中配置是那种缓存。

    MyBatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现。

    两者比较

    因为Hibernate对查询对象有着良好的管理机制,用户无需关心SQL。所以在使用二级缓存时如果出现脏数据,系统会报出错误并提示。

    而MyBatis在这一方面,使用二级缓存时需要特别小心。如果不能完全确定数据更新操作的波及范围,避免Cache的盲目使用。否则,脏数据的出现会给系统的正常运行带来很大的隐患。

    第六章Hibernate与Mybatis对比总结

    两者相同点

  • Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory生成Session,最后由Session来开启执行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。

  • Hibernate和MyBatis都支持JDBC和JTA事务处理。

  • Mybatis优势

  • MyBatis可以进行更为细致的SQL优化,可以减少查询字段。

  • MyBatis容易掌握,而Hibernate门槛较高。

  • Hibernate优势

  • Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。

  • Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。

  • Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。

  • Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。

  • 他人总结

  • Hibernate功能强大,数据库无关性好,O/R映射能力强,如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。

  • Hibernate的缺点就是学习门槛不低,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate方面需要你的经验和能力都很强才行。

  • iBATIS入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。

  • iBATIS的缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。

‘肆’ 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只能过温饱的生化,但是我想我足够了,比起以前的工资好了些,以后可以多寄些钱回家。我想只要我继续努力。我工资一定会翻倍的。 把本文写出来,希望能让和我一样的没有基础的朋友有信心,其实我们没有自卑,我们不比别人笨,只有我们肯努力,我们一样会成功。

‘伍’ php面试题 memcache和redis的区别

Redis与Memcached的区别传统MySQL+ Memcached架构遇到的问题实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:1.MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。2.Memcached与MySQL数据库数据一致性问题。3.Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。4.跨机房cache同步问题。众多NoSQL百花齐放,如何选择最近几年,业界不断涌现出很多各种各样的NoSQL产品,那么如何才能正确地使用好这些产品,最大化地发挥其长处,是我们需要深入研究和思考的问题,实际归根结底最重要的是了解这些产品的定位,并且了解到每款产品的tradeoffs,在实际应用中做到扬长避短,总体上这些NoSQL主要用于解决以下几种问题1.少量数据存储,高速读写访问。此类产品通过数据全部in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。2.海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。3.这方面最具代表性的是dynamo和bigtable 2篇论文所阐述的思路。前者是一个完全无中心的设计,节点之间通过gossip方式传递集群信息,数据保证最终一致性,后者是一个中心化的方案设计,通过类似一个分布式锁服务来保证强一致性,数据写入先写内存和redo log,然后定期compat归并到磁盘上,将随机写优化为顺序写,提高写入性能。4.Schema free,auto-sharding等。比如目前常见的一些文档数据库都是支持schema-free的,直接存储json格式数据,并且支持auto-sharding等功能,比如mongodb。面对这些不同类型的NoSQL产品,我们需要根据我们的业务场景选择最合适的产品。Redis适用场景,如何正确的使用前面已经分析过,Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。2 Redis支持数据的备份,即master-slave模式的数据备份。3 Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。抛开这些,可以深入到Redis内部构造去观察更加本质的区别,理解Redis的设计。在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。Redis只会缓存所有的 key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计 算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以 保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap操作的。同时由于Redis将内存 中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这个 操作,直到子线程完成swap操作后才可以进行修改。使用Redis特有内存模型前后的情况对比:VM off: 300k keys, 4096 bytes values: 1.3G usedVM on: 300k keys, 4096 bytes values: 73M usedVM off: 1 million keys, 256 bytes values: 430.12M usedVM on: 1 million keys, 256 bytes values: 160.09M usedVM on: 1 million keys, values as large as you want, still: 160.09M used当 从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方。 这里就存在一个I/O线程池的问题。在默认的情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会相应。这种策略在客户端的数量较小,进行 批量操作的时候比较合适。但是如果将Redis应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。所以Redis运行我们设置I/O线程 池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。如果希望在海量数据的环境中使用好Redis,我相信理解Redis的内存设计和阻塞的情况是不可缺少的。补充的知识点:memcached和redis的比较1 网络IO模型Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe 传递给worker线程,进行读写IO, 网络层使用libevent封装的事件库,多线程模型可以发挥多核作用,但是引入了cache coherency和锁的问题,比如,Memcached最常用的stats 命令,实际Memcached所有操作都要对这个全局变量加锁,进行计数等工作,带来了性能损耗。(Memcached网络IO模型)Redis使用单线程的IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll、kqueue和select,对于单纯只有IO操作来说,单线程可以将速度优势发挥到最大,但是Redis也提供了一些简单的计算功能,比如排序、聚合等,对于这些操作,单线程模型实际会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞住的。2.内存管理方面Memcached使用预分配的内存池的方式,使用slab和大小不同的chunk来管理内存,Item根据大小选择合适的chunk存储,内存池的方式可以省去申请/释放内存的开销,并且能减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数据也可能会被剔除,原因可以参考Timyang的文章:/memcached/)。Memcached的客户端软件实现非常多,包括C/C++, PHP, Java, Python, Ruby, Perl, Erlang, Lua等。当前Memcached使用广泛,除了LiveJournal以外还有Wikipedia、Flickr、Twitter、Youtube和WordPress等。在Window系统下,Memcached的安装非常方便,只需从以上给出的地址下载可执行软件然后运行memcached.exe –d install即可完成安装。在Linux等系统下,我们首先需要安装libevent,然后从获取源码,make && make install即可。默认情况下,Memcached的服务器启动程序会安装到/usr/local/bin目录下。在启动Memcached时,我们可以为其配置不同的启动参数。1.1 Memcache配置Memcached服务器在启动时需要对关键的参数进行配置,下面我们就看一看Memcached在启动时需要设定哪些关键参数以及这些参数的作用。1)-p Memcached的TCP监听端口,缺省配置为11211;2)-U Memcached的UDP监听端口,缺省配置为11211,为0时表示关闭UDP监听;3)-s Memcached监听的UNIX套接字路径;4)-a 访问UNIX套接字的八进制掩码,缺省配置为0700;5)-l 监听的服务器IP地址,默认为所有网卡;6)-d 为Memcached服务器启动守护进程;7)-r 最大core文件大小;8)-u 运行Memcached的用户,如果当前为root的话需要使用此参数指定用户;9)-m 分配给Memcached使用的内存数量,单位是MB;10)-M 指示Memcached在内存用光的时候返回错误而不是使用LRU算法移除数据记录;11)-c 最大并发连数,缺省配置为1024;12)-v –vv –vvv 设定服务器端打印的消息的详细程度,其中-v仅打印错误和警告信息,-vv在-v的基础上还会打印客户端的命令和相应,-vvv在-vv的基础上还会打印内存状态转换信息;13)-f 用于设置chunk大小的递增因子;14)-n 最小的chunk大小,缺省配置为48个字节;15)-t Memcached服务器使用的线程数,缺省配置为4个;16)-L 尝试使用大内存页;17)-R 每个事件的最大请求数,缺省配置为20个;18)-C 禁用CAS,CAS模式会带来8个字节的冗余;2. Redis简介Redis是一个开源的key-value存储系统。与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:字符串、哈希表、链表、集合、有序集合以及基于这些数据类型的相关操作。Redis使用C语言开发,在大多数像Linux、BSD和Solaris等POSIX系统上无需任何外部依赖就可以使用。Redis支持的客户端语言也非常丰富,常用的计算机语言如C、C#、C++、Object-C、PHP、Python、Java、Perl、Lua、Erlang等均有可用的客户端来访问Redis服务器。当前Redis的应用已经非常广泛,国内像新浪、淘宝,国外像Flickr、Github等均在使用Redis的缓存服务。Redis的安装非常方便,只需从bin目录下。在启动Redis服务器时,我们需要为其指定一个配置文件,缺省情况下配置文件在Redis的源码目录下,文件名为redis.conf。php面试题 memcache和redis的区别

‘陆’ java三大框架面试题

你只要去弄明白Struts控制页面跳转、spring管理映射、hibernate简化数据库操作,另外再背一下SSH的基本配置流程就行了,他真要问你深层的缓存之类的东西,你自己说不会就行,面试的家伙其实很多都是被面试题问参加面试的人的,很多面试官都是虚张声势的。
有时我也觉得很有趣,面试官和参加面试的背面试题,这真要看缘分,如果都背一份面试题就好了..

‘柒’ voliate怎么保证可见性

上次我们学习了volatile是如何解决多线程环境下共享变量的内存可见性问题,并且简单介绍了基于多核CPU并发缓存架构模型的Java内存模型。
详情见文章:

volatile很难?由浅入深怼到CPU汇编,彻底搞清楚它的底层原理

在并发编程中,有三个重要的特性:

内存可见性
原子性
有序性
volatile解决了并发编程中的可见性和有序性,解决不了原子性的问题,原子性的问题需要依赖synchronized关键字来解决。

关于并发编程三大特性的详细介绍,大家可以点击下方卡片搜索查看:

搜更多精彩内容

并发编程三大特性

内存可见性在上一篇文章中已经验证,本文我们继续通过代码学习如下内容:1、volatile为什么解决不了原子性问题?2、缓存行、缓存行填充3、CPU优化导致的乱序执行4、经典面试题:DCL必须要有volatile关键字吗?5、valatile关键字是如何禁止指令重排序的?

以上每一步都会有一段代码来验证,话不多说,开始输出干货!

1、volatile为什么解决不了原子性问题?

如果你对volatile了解的还可以,那么咱们继续往下看,如果不是太熟悉,请先行阅读上一篇文章。

老规矩,先来一段代码:

volatile原子性问题代码验证

这段代码的输出结果是多少?10000?大于10000?小于10000?

程序执行10次输出的结果如下:

join:10000
join:10000
join:10000
join:9819
join:10000
join:10000
join:10000
join:9898
join:10000
join:10000
会有小几率的出现小于10000的情况,因此volatile是无法保证原子性的,那么到底在什么地方出问题了呢?
还是用上篇文章的图来说明一下程序的整体流程:

当线程1从内存读取num的值到工作内存,同时线程2也从内存读取num的值到工作内存了,他俩各自操作自己的num++操作,但是关键点来了:

当线程1、2都执行完num++,线程1执行第五步store操作,通过总线将新的num值写回内存,刷新了内存中的num值,同时触发了总线嗅探机制,告知线程2其工作内存中的num不可用,因此线程2的num++得到的值被抛弃了,但是线程2的num++操作却是执行了。

2、CPU缓存行

写上篇文章的时候,有朋友问到了CPU的三级缓存以及缓存行相关的问题,然后我就找了一些资料学习,形成了下面的一张图:

CPU缓存行

CPU和主内存RAM之间会有三级缓存,因为CPU的速度要比内存的速度要快的多,大概是100:1,也就是CPU的速度比内存要快100倍,因此有了CPU三级缓存,那为什么是三级缓存呢?不是四级、五级呢?四个大字送给你:工业实践!相关概念:

ALU:CPU计算单元,加减乘除都在这里算
PC:寄存器,ALU从寄存器读取一次数据为一个周期,需要时间小于1ns
L1:1级缓存,当ALU从寄存器拿不到数据的时候,会从L1缓存去拿,耗时约1ns
L2:2级缓存,当L1缓存里没有数据的时候,会从L2缓存去拿,耗时约3ns
L3:3级缓存,一颗CPU里的双核共用,L2没有,则去L3去拿,耗时约15ns
RAM内存:当缓存都没有数据的时候,会从内存读取数据
缓存行:CPU从内存读取数据到缓存行的时候,是一行一行的缓存,每行是64字节(现代处理器)
问题来了:

1、缓存行存在的意义?好处是什么?

空间的考虑:一个地址被访问,相连的地址很大可能也被访问;

时间的考虑:最近访问的会被频繁访问好处:比如相连的地址,典型的就是数组,连续内存访问,很快!

2、缓存行会带来什么问题?

缓存行会导致缓存失效的问题,从而导致程序运行效率低下。例如下图:

当x,y两个变量在一个缓存行的时候:

1、线程1执行x++操作,将x和y所在的缓存行缓存到cpu core1里面去,

2、线程2执行y++操作,也将x和y所在的缓存行缓存到cpu core2里面去,

3、线程1执行了x++操作,写入到内存,同时为了保证cpu的缓存一致性协议,需要使其他内核x,y所在的缓存行失效,意味着线程2去执行y++操作的时候,无法从自己的cpu缓存拿到数据,必须从内存获取。

这就是缓存行失效!

一段代码来验证缓存行失效的问题:

缓存行失效例程

耗时:2079ms
这个时候我们做一个程序的改动,在x变量的前面和后面各加上7个long类型变量,如下:

再次运行,看耗时输出:

耗时:671ms
大约三倍的速度差距!

关于缓存行的更多概念,大家也可以点击下方卡片直接搜索更多信息:

搜更多精彩内容

缓存行

3、CPU优化导致的乱序执行

上文在说缓存行的时候,主要是因为CPU的速度大约是内存的速度的100倍,因此CPU在执行指令的时候,为了不等待内存数据的读取,会存在CPU指令优化而导致乱序执行的情况。

看下面这段代码:

cpu乱序执行例程

执行后输出(我执行了900多万次才遇到x=0,y=0的情况,可以试试你的运气哦~):

因为CPU的速度比内存要快100倍,所以当有两行不相关的代码在执行的时候,CPU为了优化执行速度,是会乱序执行的,所以上面的程序会输出:x=0,y=0的情况,也就是两个线程的执行顺序变成了:

x = b;
y = a;
a = 1;
b = 1;
这个时候我们就需要加volatile关键字了,来禁止CPU的指令重排序!

4、DCL单例模式需要加volatile吗?

一道经典的面试题:DCL单例模式需要加volatile字段吗?先来看DCL单例模式的一段代码:

DCL单例模式

DCL全称叫做Double Check Lock,就是双重检查锁来保证一个对象是单例的。

核心的问题就是这个INSTANCE变量是否需要加volatile关键字修饰?答案肯定是需要的。

首先我们来看new一个对象的字节码指令:

查看其字节码指令:

NEW java/lang/Object
DUP
INVOKESPECIAL java/lang/Object.<init> ()V
ASTORE 1
即:

1、创建并默认初始化Object对象;

2、复制操作数栈对该对象的引用;

3、调用Object对象的初始化方法;

4、将变量Object o指向创建的这个对象,此时变量o不再为null;

根据上文描述我们知道因为CPU和内存速度不匹配的问题,CPU在执行命令的时候是乱序执行的,即CPU在执行第3步初始化方法时候如果需要很长的时间,CPU是不会等待第3步执行完了才去执行第4步,所以执行顺序可能是1、2、4、3。

那么继续看DCL单例程序,当线程1执行new DCLStudy()的顺序是先astore再invokespecial,但是invokespecial方法还没有执行的时候,线程2进来了,这个时候线程2拿到的就是一个半初始化的对象。

因此,DCL单例模式需要加volatile关键字,来禁止上述new对象的过程的指令重排序!

valatile关键字是如何禁止指令重排序的

JVM规范中规定:凡是被volatile修饰的变量,在进行其操作时候,需要加内存屏障!

JVM规范中定义的JSR内存屏障定义:

LoadLoad屏障:
对于语句Load1;LoadLoad;Load2;Load1和Load2语句不允许重排序。
StoreStore屏障:
对于语句Store1;StoreStore;Store2;Store1和Store2语句不允许重排序。
LoadStore屏障:
对于语句Load1;StoreStore;Store2;Load1和Store2语句不允许重排序。
StoreLoad屏障:
对于语句Store1;StoreStore;Load2;Store1和Load2语句不允许重排序。
JVM层面volatile的实现要求:

如果对一个volatile修饰的变量进行写操作:

前面加StoreStoreBarrier屏障,保证前面所有的store操作都执行完了才能对当前volatile修饰的变量进行写操作;

后面要加StoreLoadBarrier,保证后面所有的Load操作必须等volatile修饰的变量写操作完成。

如果对一个volatile修饰的变量进行读操作:

后面的读操作LoadLoadBarrier必须等当前volatile修饰变量读操作完成才能读;

后面的写操作LoadStoreBarrier必须等当前的volatile修饰变量读操作完成才能写。

上篇文章我们通过一定的方式看到了程序执行的volatile修饰的变量底层汇编码:

0x000000010d3f3203: lock addl $0x0,(%rsp) ;*putstatic flag
; - com.java.study.VolatileStudy::lambda$main$1@9 (line 31)
也就是到CPU的底层执行的命令其实就是这个lock,这个lock指令既完成了变量的可见性还保证了禁止指令充排序:

LOCK用于在多处理器中执行指令时对共享内存的独占使用。它的作用是能够将当前处理器对应缓存的内容刷新到内存,并使其他处理器对应的缓存失效;另外还提供了有序的指令无法越过这个内存屏障的作用。
end

至此,对volatile的学习就到这里了,通过两篇文章来对volatile这个关键字有了一个系统的学习。

学无止境,对volatile的学习还只是一个基础学习,还有更多的知识等待我们去探索学习,例如:

什么是as-if-serial?什么是happens-before?
Java的哪些指令可以重排序呢?重排序的规则是什么?
我们下期再见!

1372阅读
搜索
java自学一般要学多久
volatile底层原理
汇编111条指令详解
java必背100源代码
volatile架构图
嵌入式volatile详解

‘捌’ 面试官要求我研究一个Java缓存框架,哪个比较好

缓存框架有ehcache、redis、memcached
现在大公司用的比较多的是memcached和redis,这也是分布式系统开发中常用的缓存中间件
个人比较推荐用redis,因为redis对于可支持的数据类型比memcached要多,而且redis是一个可持久化的缓存框架,在使用的时候还可以尝试搭建redis集群环境。
如果你对redis深入研究,相信你的面试官会很乐意要你的。

‘玖’ 阿里巴巴资深java工程师什么水平

你好,如阿里网络腾讯等互联网大厂的工程师,资深(架构师水平)工程师是非常有实力的。

以阿里为例:

1、阿里工程师岗位职级

阿里巴巴集团采用双序列职业发展体系:

一套体系是专家路线【P序列=技术岗】,程序员、工程师,某一个专业领域的人才,一共分为14级,从P1到P14,目前校招最低从P4开始。

一套体系是M路线,即管理者路线【M序列=管理岗】,从M1到M10。

考核因素是上一年的绩效分数+直属领导的打分+晋升委员会打分,这里的委员会一般由直属领导+合作方的高管+懂业务的HRG组成。HRG:HR多面手,base在业务下面,在阿里话语权比别的互联网HR高。

晋升标准:绩效满足3.75、主管提名、技术答辩通过。


P8架构师作为阿里“IT架构灵魂人物”的角色,他们不仅做着架构师的本职工作,还同时做程序开发,写核心代码的工作。另外,架构师依旧是技术高手,编程能力依然是一流的。

但根据当前的市场需求,互联网大厂们对于普通Java开发人才需求逐年锐减,而对互联网架构师人才的需求招聘量已经上升到50%,因此薪资更是不可同日而语。

对于想学习互联网架构师的同学来说,北大青鸟、课工场等优秀品牌都是不错的选择。课程根据招聘需求制定,包含全部分布式微服务技术,对标阿里P8级别架构师。



希望我的回答对你有所帮助!