3年工作经验出去面试的面试问题:
1. mysql数据库的优化
1、表的设计要符合三范式。
2、添加适当的索引,索引对查询速度影响很大,必须添加索引。主键索引,唯一索引,普通索引,全文索引
3、添加适当存储过程,触发器,事务等。
4、读写分离(主从数据库)
5、对sql语句的一些优化,(查询执行速度比较慢的sql语句)
6、分表分区
分表:把一张大表分成多张表。分区:把一张表里面的分配到不同的区域存储,
7、对mysql服务器硬件的升级操作。
2. mysql数据库查询使用limit,两次查询结果会不会不一致,为什么?
MySQL的limit给分页带来了极大的方便,但数据量一大的时候,limit的性能就急剧下降。同样是取10条数据,下面两句就不是一个数量级别的。
1 |
select * from table limit 10000,10 |
2 |
select * from table limit 0,10 |
这个可能和咱们的数据库的数据有关!
3. 如何创建索引查询数据库?
http://jingyan.baidu.com/article/da1091fbd166ff027849d687.html
这个网页里面是数据库创建索引的步骤!自己理解一下,因为在面试过程中这个问题问的比较多!!
4、redis中的事务和mysql中的事务有什么区别?
1、Redis中的事务(transaction)是一组命令的集合。事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行。Redis事务的实现需要用到 MULTI 和 EXEC 两个命令,事务开始的时候先向Redis服务器发送 MULTI 命令,然后依次发送需要在本次事务中处理的命令,最后再发送 EXEC 命令表示事务命令结束。
2、mysql的事务特性,要求这组操作,要不全都成功,要不全都失败,这样就避免了某个操作成功某个操作失败。利于数据的安全
5、zookeeper为什么可以做注册中心?原理是什么?
首先我们要知道什么是zookeeper。zookeeper是一个为分布式应用提供一致性服务的软件,它是开源的Hadoop项目中的一个子项目!
(1)配置管理
集中式的配置管理在应用集群中是非常常见的,一般商业公司内部都会实现一套集中的配置管理中心,应对不同的应用集群对于共享各自配置的需求,并且在配置变更时能够通知到集群中的每一个机器。
Zookeeper很容易实现这种集中式的配置管理,比如将APP1的所有配置配置到/APP1 znode下,APP1所有机器一启动就对/APP1这个节点进行监控(zk.exist("/APP1",true)),并且实现回调方法Watcher,那么在zookeeper上/APP1 znode节点下数据发生变化的时候,每个机器都会收到通知,Watcher方法将会被执行,那么应用再取下数据即可(zk.getData("/APP1",false,null));
以上这个例子只是简单的粗颗粒度配置监控,细颗粒度的数据可以进行分层级监控,这一切都是可以设计和控制的。
(2)集群管理
应用集群中,我们常常需要让每一个机器知道集群中(或依赖的其他某一个集群)哪些机器是活着的,并且在集群机器因为宕机,网络断链等原因能够不在人工介入的情况下迅速通知到每一个机器。
Zookeeper同样很容易实现这个功能,比如我在zookeeper服务器端有一个znode叫/APP1SERVERS,那么集群中每一个机器启动的时候都去这个节点下创建一个EPHEMERAL类型的节点,比如server1创建/APP1SERVERS/SERVER1(可以使用ip,保证不重复),server2创建/APP1SERVERS/SERVER2,然后SERVER1和SERVER2都watch /APP1SERVERS这个父节点,那么也就是这个父节点下数据或者子节点变化都会通知对该节点进行watch的客户端。因为EPHEMERAL类型节点有一个很重要的特性,就是客户端和服务器端连接断掉或者session过期就会使节点消失,那么在某一个机器挂掉或者断链的时候,其对应的节点就会消失,然后集群中所有对/APP1SERVERS进行watch的客户端都会收到通知,然后取得最新列表即可。
另外有一个应用场景就是集群选master,一旦master挂掉能够马上能从slave中选出一个master,实现步骤和前者一样,只是机器在启动的时候在APP1SERVERS创建的节点类型变为EPHEMERAL_SEQUENTIAL类型,这样每个节点会自动被编号,
我们默认规定编号最小的为master,所以当我们对/APP1SERVERS节点做监控的时候,得到服务器列表,只要所有集群机器逻辑认为最小编号节点为master,那么master就被选出,而这个master宕机的时候,相应的znode会消失,然后新的服务器列表就被推送到客户端,然后每个节点逻辑认为最小编号节点为master,这样就做到动态master选举。
6、手写一个单例模式
Java的设计模式比较多,但是我们在面试前面至少有看好几个设计面试,
1.饿汉式单例类
//饿汉式单例类.在类初始化时,已经自行实例化 public class Singleton1 { //私有的默认构造子 private Singleton1() {} //已经自行实例化 private static final Singleton1 single = new Singleton1(); //静态工厂方法 public static Singleton1 getInstance() { return single; } } |
2.懒汉式单例类
//懒汉式单例类.在第一次调用的时候实例化 public class Singleton2 { //私有的默认构造子 private Singleton2() {} //注意,这里没有final private static Singleton2 single=null; //静态工厂方法 public synchronized static Singleton2 getInstance() { if (single == null) { single = new Singleton2(); } return single; } } |
3.登记式单例类
import java.util.HashMap; import java.util.Map; //登记式单例类. //类似Spring里面的方法,将类名注册,下次从里面直接获取。 public class Singleton3 { private static Map<String,Singleton3> map = new HashMap<String,Singleton3>(); static{ Singleton3 single = new Singleton3(); map.put(single.getClass().getName(), single); } //保护的默认构造子 protected Singleton3(){} //静态工厂方法,返还此类惟一的实例 public static Singleton3 getInstance(String name) { if(name == null) { name = Singleton3.class.getName(); System.out.println("name == null"+"--->name="+name); } if(map.get(name) == null) { try { map.put(name, (Singleton3) Class.forName(name).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return map.get(name); } //一个示意性的商业方法 public String about() { return "Hello, I am RegSingleton."; } public static void main(String[] args) { Singleton3 single3 = Singleton3.getInstance(null); System.out.println(single3.about()); } } |
7.maven的插件有哪些
Maven 提供以下两种类型插件:
类型 |
描述 |
构建插件 |
在生成过程中执行,并在 pom.xml 中的<build/> 元素进行配置 |
报告插件 |
在网站生成期间执行,在 pom.xml 中的 <reporting/> 元素进行配置 |
以下是一些常见的插件列表:
插件 |
描述 |
clean |
编译后的清理目标,删除目标目录 |
compiler |
编译 Java 源文件 |
surefile |
运行JUnit单元测试,创建测试报告 |
jar |
从当前项目构建 JAR 文件 |
war |
从当前项目构建 WAR 文件 |
javadoc |
产生用于该项目的 Javadoc |
antrun |
从构建所述的任何阶段运行一组 Ant 任务 |
8.maven如何处理依赖冲突的问题?
下面是maven的
解决maven传递依赖中的版本冲突
首先在pom.xml中添加: <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId> maven-project-info-reports-plugin </artifactId> </plugin> </plugins> </reporting> 如果用的是eclipse,那就用run as-build-在Goals那个框框里输入: project-info-reports:dependencies,如果实在dos环境下, 就mvn project-info-reports:dependencies。然后就会在target的文件夹下,生成一个site文件夹,里边有个dependency.html,进去就能看到详细的依赖的信息。 或者直接在eclipse中打开pom.xml文件 会看到打开的窗口中有一个dependency hie开头的选项卡。 这个选择卡页面左半部分显示了详细的jar包依赖树。右半部分则是maven将会下载的jar包。 比如我们看到右半部分有2个asm的jar,版本不同。 现在需要排除其中低版本的jar(比如xwork-core下的某个jar依赖的asm版本相对较低,不一定说是xwork-core依赖,而是它的依赖的依赖,即多重依赖的asm都是可以的) <dependency> <groupId>org.apache.struts.xwork</groupId> <artifactId>xwork-core</artifactId> <version>${struts.version}</version> <exclusions> <exclusion> <artifactId>asm</artifactId> <groupId>asm</groupId> </exclusion> </exclusions> </dependency> 当然我们也可以在dependency hie开头的选项卡中右半部分直接选中那个低版本的asm.jar。 然后右键exclude maven...点击确定会自动生成上面的。 |
如果你这个是步骤解决问题的步骤!在面试的时候咱们是可以用语言打动面试官的
maven引入依赖的时候,有的时候会发生循环依赖的情况,造成依赖失败,例如A依赖于B,B又依赖于C,C又依赖于A,造成一种环路,这样的话会失败。 假设依赖A依赖于B,D也依赖于B,B在pom中有2个版本B1,B2(有可能是直接依赖,也有可能是间接依赖),那么maven会通过以下机制引入依赖: |
这样面试官会认为你真正做过开发,并且自己遇到这样的问题!offer就在向你招手
9.电商项目中是如何解决高并发和高可用的?
1、尽量将请求的页面静态化 静态化的页面为.html(.htm等)不需要web服务器重新加载项解析,只需要生成一次,以后每次都直接下载到客户端,效率高很多。javaWeb静态化的技术有freemark和Velocity等。
2、fastDFS图片服务器:
将网站系统的web服务器、数据库服务器、图片和文件服务器分开,通过将服务器专业化分工,以提高网站访问速度。因为图片和文件在下载的时候无论是IIS、Apache等服务器都会有很大压力。
3、数据缓存服务器 redis
可以设置专门的数据缓存服务器,将大量数据放到缓存数据区,在访问量少得时候存入数据,减少连接直接操作数据库的开销。
4、数据库集群、库表散列(数据库的各种优化、数据库的拆分)
5、镜像(这个本人原理也是不是很明白)
镜像是大型网站常采用的提高性能和数据安全性的方式,镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异,比如ChinaNet和EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点,数据进行定时更新或者实时更新。在镜像的细节技术方面,这里不阐述太深,有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路,比如Linux上的rsync等工具。
6、负载均衡(nginx)
负载均衡将是大型网站解决高负荷访问和大量并发请求采用的高端解决办法。
7、最新:CDN加速技术(这个比镜像更好用)
什么是CDN? CDN的全称是内容分发网络。其目的是通过在现有的Internet中增加一层新的网络架构,将网站的内 容发布到最接近用户的网络“边缘”,使用户可以就近取得所需的内容,提高用户访问网站的响应速度。
10.nginx的作用?如何实现负载均衡的,原理是什么?
nginx的作用:1、http服务2、负载均衡3、解决高并发
这个在上课的时候老师是有文档的!
11.如果redis广告位节点中存入的大量数据(十万条),当添加新广告数据时,是否也要删掉十万广告对应的key?是否有其他解决方案保证能redis中数据是最新的?
Redis的作用: 1 、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
2 、Redis支持数据的备份,即master-slave模式的数据备份。
3 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
Redis常用数据类型
Redis最为常用的数据类型主要有以下:
String
Hash
List
Set
Sorted set
pub/sub
Transactions
12.activemq的事务管理?
在创建session时可以选择开启事务控制。所谓事务控制,即将消息生成发送,或接受,消费操作放入一个事务中。但不能同时控制发送与消费这一整个过程。因为事务都是基于一个session下的操作。 如下代码即开启了事务处理: ActiveMQSession session = connection.createSession(true,Session.CLIENT_ACKNOWLEDGE); 在事务状态下进行发送操作,消息并未真正投递到中间件,而只有进行session.commit操作之后,消息才会发送到中间件,再转发到适当的消费者进行处理。如果是调用rollback操作,则表明,当前事务期间内所发送的消息都取消掉。此时无论commit或rollback,会重新打开一个事务。 与此同时,在rollback之后,随着新的事务打开,一些持久化的消息会重新接收。原因在于当传送模式处于持久话的状态,产生的消息如若没有被及时签收确认,则消息会被中间件持久化。此时,当客户端重新连接或新的事务开启,消息会被再次发送到客户端。 为什么commit之后,不会有持久的消息重新传送呢? 原因在于commit操作会自动将为签收确认的消息进行签收确认,如果是当前接收但未签收确认的消息,都会被确认处理。因而在commit之后不会有持久化的消息出现。 |
13.“this is a dog”是如何添加到索引库中的?(solr)
索引 Solr/Lucene采用的是一种反向索引,所谓反向索引:就是从关键字到文档的映射过程,保存这种映射这种信息的索引称为反向索引
字段串列表和文档编号链表两者构成了一个字典。现在想搜索”lucene”,那么索引直接告诉我们,包含有”lucene”的文档有:2,3,10,35,92,而无需在整个文档库中逐个查找。如果是想搜既包含”lucene”又包含”solr”的文档,那么与之对应的两个倒排表去交集即可获得:3、10、35、92。 索引创建 假设有如下两个原始文档: 一:把原始文档交给分词组件(Tokenizer)
"Students","allowed","go","their","friends","allowed","drink","beer","My","friend","Jerry","went","school","see","his","students","found","them","drunk","allowed" 二:词汇单元(Token)传给语言处理组件(Linguistic Processor)
语言处理组件(linguistic processor)处理得到的结果称为词(Term),例子中经过语言处理后得到的词(Term)如下: "student","allow","go","their","friend","allow","drink","beer","my","friend","jerry","go","school","see","his","student","find","them","drink","allow"。 经过语言处理后,搜索drive时drove也能被搜索出来。Stemming 和 lemmatization的异同:
三:得到的词(Term)传递给索引组件(Indexer)
allow 2
them 2
对词(Term) “allow”来讲,总共有两篇文档包含此词(Term),词(Term)后面的文档链表总共有两个,第一个表示包含”allow”的第一篇文档,即1号文档,此文档中,”allow”出现了2次,第二个表示包含”allow”的第二个文档,是2号文档,此文档中,”allow”出现了1次 至此索引创建完成,搜索”drive”时,”driving”,”drove”,”driven”也能够被搜到。因为在索引中,”driving”,”drove”,”driven”都会经过语言处理而变成”drive”,在搜索时,如果您输入”driving”,输入的查询语句同样经过分词组件和语言处理组件处理的步骤,变为查询”drive”,从而可以搜索到想要的文档。 搜索步骤 搜索”microsoft job”,用户的目的是希望在微软找一份工作,如果搜出来的结果是:”Microsoft does a good job at software industry…”,这就与用户的期望偏离太远了。如何进行合理有效的搜索,搜索出用户最想要得结果呢?搜索主要有如下步骤: 一:对查询内容进行词法分析、语法分析、语言处理
二:搜索索引,得到符合语法树的文档集合 我们把查询语句也看作是一个文档,对文档与文档之间的相关性(relevance)进行打分(scoring),分数高比较越相关,排名就越靠前。当然还可以人工影响打分,比如百度搜索,就不一定完全按照相关性来排名的。 如何评判文档之间的相关性?一个文档由多个(或者一个)词(Term)组成,比如:”solr”, “toturial”,不同的词可能重要性不一样,比如solr就比toturial重要,如果一个文档出现了10次toturial,但只出现了一次solr,而另一文档solr出现了4次,toturial出现一次,那么后者很有可能就是我们想要的搜的结果。这就引申出权重(Term weight)的概念。 权重表示该词在文档中的重要程度,越重要的词当然权重越高,因此在计算文档相关性时影响力就更大。通过词之间的权重得到文档相关性的过程叫做空间向量模型算法(Vector Space Model) 影响一个词在文档中的重要性主要有两个方面:
空间向量模型 文档中词的权重看作一个向量 Document = {term1, term2, …… ,term N} Document Vector = {weight1, weight2, …… ,weight N} 把欲要查询的语句看作一个简单的文档,也用向量表示: Query = {term1, term 2, …… , term N} Query Vector = {weight1, weight2, …… , weight N} 把搜索出的文档向量及查询向量放入N维度的空间中,每个词表示一维: 夹角越小,表示越相似,相关性越大 |
补充:Lucene: 全文检索的基本原理
http://www.cnblogs.com/guochunguang/articles/3641008.html 这个里面有一些解释!lucene和solr的区别是在于:Solr是基于Lucene开发的全文检索服务器,而Lucene就是一套实现了全文检索的api,其本质就是一个全文检索的过程。全文检索就是把原始文档根据一定的规则拆分成若干个关键词,然后根据关键词创建索引,当查询时先查询索引找到对应的关键词,并根据关键词找到对应的文档,也就是查询结果,最终把查询结果展示给用户的过程。 |
14.http的三次握手?socket有几种状态?socket底层编程?
http的三次握手
TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急) Sequence number(顺序号码) Acknowledge number(确认号码) 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。 |
socket有几种状态
|
socket底层编程(这个可以不用了解)
http是网络上层协议。底层还是socket短连接是发送数据时进行联接。发送完关闭(我们做完电商项目之后这些有了解一下) |
15.你所知道的通讯协议?
在ip网络中,传输层主要协议是:tcp及udp。在web中,应用层也用http传输。 在网络io中,目前主要有:bio(阻塞)、nio(非阻塞)、aio(异步jdk7中新特性)。具体不作解析可以看相关文档。 在传输中应用层的协议及规范主要有: RMI(java原生的),用java自身的序列化技术。 xml-rpc 用xml+http Binary-RPC 用二进制+http soap,可以说是xml-rpc的一种封装 COBRA,加入了jdk中 jms,这个是一种规范,基于队列模型的 主要的实现框架,可以组合使用。 activeMQ:是jms的一种实现 mina:基本是包装了nio.Apache MINA is a network application framework which helps users develop high performance and high scalability network applications easily。It provides an abstract · event-driven · asynchronous API over various transports such as TCP/IP and UDP/IP via Java NIO. Hessian:Hessian是一个轻量级的remoting onhttp工具.采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据.自己实现序列化。 Burlap:和Hessian差不多,基于xml-RPC的实现 mule esb: 直接看官方文档http://www.mulesoft.org/ 基于总线模型 spring-Remoting 重量级的 Jboss-Remoting 重量及的 EJB3 |
16、redis集群中,某个节点宕机怎么办?你遇见过吗?你的解决思路是什么?
redis集群:一般的是至少是2台服务器,主从服务器!如果redis集群的主服务器挂了,没有关系还有备服务器
其他面试问题汇总:
1、hibernate 和mybetis的异同之处?
Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。
Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的缺点是学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。
2、用户在app订阅业务,使用什么设计模式实现?应用场景是什么?
观察者模式又叫做发布-订阅(Publish/Subscribe)模式。观察者模式定义了一种一对多地依赖模式,让多个观察者同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使它们能够自动更新自己。这里的主题对象就是指通知者,又叫做发布者。观察者又叫订阅者。
3、springmvc 如何声明一个controller? 注解
如果不基于注解: 该类需要继承 CommandController 或者 其他很多 参见 spring帮助
如果基于注解:在类名前 加上 @controller
补充:将类名前加上该注解,当spring启动 或者web服务启动 spring会自动扫描所有包(当然,这个可以设置)
作用: 就是告诉服务器 这个类是MVC中的C 这个类可以接收用户请求 处理用户请求
4、设计模式有哪些?单例,工厂,观察者.观察者模式的应用场景?
常见的设计模式:单例模式、工厂模式、观察者模式、装饰模式与适配器模式、桥接模式、代理模式
5、怎么声明事物?在spring配置文件中声明
spring支持编程式事务管理和声明式事务管理两种方式。
编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。
声明式事务管理也有两种常用的方式,一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。
6、编写匹配字符串(求质数)的程序
http://blog.csdn.net/xianfajushi/article/details/50133965
7、分词技术
一、 为什么要进行中文分词?
词是最小的能够独立活动的有意义的语言成分,英文单词之间是以空格作为自然分界符的,而汉语是以字为基本的书写单位,词语之间没有明显的区分标记,因此,中文词语分析是中文信息处理的基础与关键。
Lucene中对中文的处理是基于自动切分的单字切分,或者二元切分。除此之外,还有最大切分(包括向前、向后、以及前后相结合)、最少切分、全切分等等。
IK分析器的分词原理本质上是词典分词。现在内存中初始化一个词典,然后在分词过程中逐个读取字符,和字典中的字符相匹配,把文档中的所有的词语拆分出来的过程。
8、不开启服务,页面怎么实现热更新!
把项目打成war包发在服务器里面,直接运行
面试问题分类:
一、Java基础
1.String类为什么是final的。
2.HashMap的源码,实现原理,底层结构。
3.反射中,Class.forName和classloader的区别
4.session和cookie的区别和联系,session的生命周期,多个服务部署时session管理。
5.Java中的队列都有哪些,有什么区别。
6.Java的内存模型以及GC算法
7.Java7、Java8的新特性
8.Java数组和链表两种结构的操作效率,在哪些情况下(从开头开始,从结尾开始,从中间开始),哪些操作(插入,查找,删除)的效率高
9.Java内存泄露的问题调查定位:jmap,jstack的使用等等
二、框架
1.struts1和struts2的区别
Struts 1要求Action类要扩展自一个抽象基类。Struts 1的一个共有的问题是面向抽象类编程而不是面向接口编程。 |
2.struts2和springMVC的区别
①springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。 ②springmvc是基于方法开发,传递参数是通过方法形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。 ④ Struts2有漏洞,springmvc目前还没有漏洞出现。如果使用struts2,建议下载最新包。 |
3.spring框架中需要引用哪些jar包,以及这些jar包的用途
Spring3.X以后jar包进行了重构,取消了原来2.X版本中的总的spring.jar包,而是把总包中的功能全部分开打包。正在向osgi靠拢。
做Spring还必须依赖第三方包: ① Spring 工程依赖的公共包 ② 使用SpringAOP功能时依赖的包 ③ 使用SpringJDBC功能时依赖的包 |
4.srpingMVC的原理
1. 客户端请求提交到DispatcherServlet 2. 由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller 3. DispatcherServlet将请求提交到Controller 4. Controller调用业务逻辑处理后,返回ModelAndView 5. DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图 6. 视图负责将结果显示到客户端 DispatcherServlet是整个Spring MVC的核心。它负责接收HTTP请求组织协调Spring MVC的各个组成部分。其主要工作有以下三项: 1. 截获符合特定格式的URL请求。
|
5.springMVC注解的意思
|
6.spring中beanFactory和ApplicationContext的联系和区别
|
7.spring注入的几种方式
|
8.spring如何实现事物管理的
是通过AOP对配置的方法进行栏截,然后再调用事务管理器中的预设代码对事务进行管理,再委托被拦截方法完成原有的任务。
9.springIOC和AOP的原理
10.hibernate中的1级和2级缓存的使用方式以及区别原理
11.spring中循环注入的方式
什么是循环注入?举个列子我有一个类A,A有一个构造器里面的参数是类B,然后类B里面有个构造器参数是类C,类C里面有个构造器参数是类A,就是我们会发现其实引用循环了A 里面有B的引用,B里面有C的引用,C里面又有A的引用。
循环依赖又分为构造器循环依赖和set循环依赖: 首先讲一下构造器的循环依赖:
1:spring创建A首先去当前创建池中去查找当前A是否在创建,如果发明没有创建则准备其构造器需要的参数B,然后把创建A的标识放入当前创建池中。 2:spring创建B首先去当前创建池中去查找当前B是否在创建,如果发现没有创建则准备其构造器需要的参数C,然后把创建B的标识放入当前创建池中。 3:spring创建C首先去当前创建池中去查找当前C是否在创建,如果发现没有创建则准备其构造器需要的参数A,然后把创建C的标识放入当前创建池中。 4:spring创建C需要的A,这个时候会发现在当前创建池中已经有A的标识,A正在创建中则抛出BeanCurrentlyInCreationException。 构造器的循环注入是没有办法解决的,所以只能我们避免.
接下来看下set方式的循环注入: 先看第一种情况,还是拿上面的ABC3个类来说明问题,只不过这次不是构造器里面的参数,而是换成他们的成员变量,然后通过set方式类注入,这里代码就不写了直接讲下: 单列下set方式的注入流程是这样的: 1:spring创建A,首先根据其无参构造器创建一个对象A,然后提前暴露出创建出来的这个A对象,然后再当前的创建池中放入创建A的标识,然后进行set方法注入B。 2:spring创建B,首先根据其无参构造器创建一个对象B,然后提前暴露出创建出来的这个B对象,然后在当前的创建池中放入创建B的标识,然后进行set方法的注入C。 3:spring创建C,首先根据其无参构造器创建一个对象C,然后提前暴露出创建处理的这个C对象,然后在当前的创建池中放入创建C的标识,然后进行set方法的注入A。 4:在第三步注入A的时候由于提前暴露出来了创建出来的A对象所以不会报BeanCurrentlyInCreationException的错误。 多列下set方式的循环注入不能解决的原因是在多列的情况下,当创建对象的时候spring不会提前暴露创建处理的对象A,这样的话则会和构造器循环注入出现一样的情况最终导致报错 |
三、多线程
1.Java创建线程之后,直接调用start()方法和run()的区别
Thread类中run()和start()方法的区别如下: 当你调用start()方法时你将创建新的线程,并且执行在run()方法里的代码。但是如果你直接调用run()方法,它不会创建新的线程也不会执行调用线程的代码 |
2.常用的线程池模式以及不同线程池的使用场景
http://blog.163.com/wm_at163/blog/static/132173490201242984518354/
3.newFixedThreadPool此种线程池如果线程数达到最大值后会怎么办,底层原理。
4.多线程之间通信的同步问题,synchronized锁的是对象,衍伸出和synchronized相关很多的具体问题,例如同一个类不同方法都有synchronized锁,一个对象是否可以同时访问。或者一个类的static构造方法加上synchronized之后的锁的影响。
5.了解可重入锁的含义,以及ReentrantLock 和synchronized的区别
6.同步的数据结构,例如concurrentHashMap的源码理解以及内部实现原理,为什么他是同步的且效率高
7.atomicinteger和volatile等线程安全操作的关键字的理解和使用
8.线程间通信,wait和notify
9.定时线程的使用
10.场景:在一个主线程中,要求有大量(很多很多)子线程执行完之后,主线程才执行完成。多种方式,考虑效率。
四、网络通信
1.http是无状态通信,http的请求方式有哪些,可以自己定义新的请求方式么。
2.socket通信,以及长连接,分包,连接异常断开的处理。
3.socket通信模型的使用,AIO和NIO。
4.socket框架netty的使用,以及NIO的实现原理,为什么是异步非阻塞。
5.同步和异步,阻塞和非阻塞。
五、Linux
1.常用的linux下的命令
2.大的log文件中,统计异常出现的次数、排序,或者指定输出多少行多少列的内容。(主要考察awk)
3.linux下的调查问题思路:内存、CPU、句柄数、过滤、查找、模拟POST和GET请求等等场景
4.shell脚本中#!的作用
六、数据库MySql
1.MySql的存储引擎的不同
2.单个索引、联合索引、主键索引
3.Mysql怎么分表,以及分表后如果想按条件分页查询怎么办(如果不是按分表字段来查询的话,几乎效率低下,无解)
4.分表之后想让一个id多个表是自增的,效率实现
5.MySql的主从实时备份同步的配置,以及原理(从库读主库的binlog),读写分离
6.写SQL语句。。。
7.索引的数据结构,B+树
8.事物的四个特性,以及各自的特点(原子、隔离)等等,项目怎么解决这些问题
七、设计模式(写代码)
1.单例模式:饱汉、饿汉。以及饿汉中的延迟加载
2.工厂模式、装饰者模式、观察者模式。
八、算法
1.使用随机算法产生一个数,要求把1-1000W之间这些数全部生成。(考察高效率,解决产生冲突的问题)
2.两个有序数组的合并排序
3.一个数组的倒序
4.计算一个正整数的正平方根
5.说说常见的查找排序算法
九、缓存
1.为什么用缓存,用过哪些缓存,redis和memcache的区别
2.redis的数据结构
3.redis的持久化方式,以及项目中用的哪种,为什么
4.redis集群的理解,怎么动态增加或者删除一个节点,而保证数据不丢失。
赢在格局,不失风雅。