zoukankan      html  css  js  c++  java
  • Java面试题目汇总

    3年工作经验出去面试的面试问题:

    1. mysql数据库的优化

    1、表的设计要符合三范式。

    2、添加适当的索引,索引对查询速度影响很大,必须添加索引。主键索引,唯一索引,普通索引,全文索引

    3、添加适当存储过程,触发器,事务等。

    4、读写分离(主从数据库)

    5、对sql语句的一些优化,(查询执行速度比较慢的sql语句)

    6、分表分区

    分表:把一张大表分成多张表。分区:把一张表里面的分配到不同的区域存储,

    7、对mysql服务器硬件的升级操作。

    2. mysql数据库查询使用limit,两次查询结果会不会不一致,为什么?

    MySQLlimit给分页带来了极大的方便,但数据量一大的时候,limit的性能就急剧下降。同样是取10条数据,下面两句就不是一个数量级别的。

     

    1

    select * from table limit 10000,10

    2

    select * from table limit 0,10

    这个可能和咱们的数据库的数据有关

     

    3. 如何创建索引查询数据库?

    http://jingyan.baidu.com/article/da1091fbd166ff027849d687.html

    这个网页里面是数据库创建索引的步骤!自己理解一下,因为在面试过程中这个问题问的比较多

    4redis中的事务和mysql中的事务有什么区别?

    1Redis中的事务(transaction)是一组命令的集合。事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行。Redis事务的实现需要用到 MULTI  EXEC 两个命令,事务开始的时候先向Redis服务器发送 MULTI 命令,然后依次发送需要在本次事务中处理的命令,最后再发送 EXEC 命令表示事务命令结束。

    2mysql的事务特性,要求这组操作,要不全都成功,要不全都失败,这样就避免了某个操作成功某个操作失败。利于数据的安全

     

    5zookeeper为什么可以做注册中心?原理是什么?

    首先我们要知道什么是zookeeperzookeeper是一个为分布式应用提供一致性服务的软件,它是开源的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包。

    比如我们看到右半部分有2asmjar,版本不同。

    现在需要排除其中低版本的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依赖于BB又依赖于CC又依赖于A,造成一种环路,这样的话会失败。

    假设依赖A依赖于B,D也依赖于BBpom中有2个版本B1B2(有可能是直接依赖,也有可能是间接依赖),那么maven会通过以下机制引入依赖: 
    如果A直接依赖于B1A-B1D间接依赖于B2,例如D-C-B2,那么maven会有优先选择依赖路径短的那个版本,即依赖B1,而不依赖B2。假设B1B2都是间接依赖,例如A-C-B1D-C-B2,那么在选择B的依赖版本的时候,谁在pom文件中优先声明依赖了,那么就依赖哪个,假设A-C-B1pom文件中优先D-C-B2声明了,那么将引入B1.

    这样面试官会认为你真正做过开发,并且自己遇到这样的问题!offer就在向你招手

    9.电商项目中是如何解决高并发和高可用的?

    1、尽量将请求的页面静态化 静态化的页面为.html(.htm)不需要web服务器重新加载项解析,只需要生成一次,以后每次都直接下载到客户端,效率高很多。javaWeb静态化的技术有freemarkVelocity等。

    2fastDFS图片服务器:

    将网站系统的web服务器、数据库服务器、图片和文件服务器分开,通过将服务器专业化分工,以提高网站访问速度。因为图片和文件在下载的时候无论是IISApache等服务器都会有很大压力。

    3数据缓存服务器 redis

    可以设置专门的数据缓存服务器,将大量数据放到缓存数据区,在访问量少得时候存入数据,减少连接直接操作数据库的开销。

    4、数据库集群、库表散列数据库的各种优化、数据库的拆分)

    5、镜像(这个本人原理也是不是明白)    

    镜像是大型网站常采用的提高性能和数据安全性的方式,镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异,比如ChinaNetEduNet之间的差异就促使了很多网站在教育网内搭建镜像站点,数据进行定时更新或者实时更新。在镜像的细节技术方面,这里不阐述太深,有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路,比如Linux上的rsync等工具。

    6、负载均衡nginx

    负载均衡将是大型网站解决高负荷访问和大量并发请求采用的高端解决办法。

    7、最新:CDN加速技术(这个镜像好用

    什么是CDN?    CDN的全称是内容分发网络。其目的是通过在现有的Internet中增加一层新的网络架构,将网站的内    容发布到最接近用户的网络边缘,使用户可以就近取得所需的内容,提高用户访问网站的响应速度。

    10.nginx的作用?如何实现负载均衡的,原理是什么?

    nginx的作用:1http服务2负载均衡3解决高并

    这个在上课的时候老师是有文档的!

    11.如果redis广告位节点中存入的大量数据(十万条),当添加新广告数据时,是否也要删掉十万广告对应的key?是否有其他解决方案保证能redis中数据是最新的?

    Redis作用   1 Redis不仅仅支持简单的k/v类型的数据,同时还提供listsetzsethash等数据结构的存储。 

    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采用的是一种反向索引,所谓反向索引:就是从关键字到文档的映射过程,保存这种映射这种信息的索引称为反向索引

     

    • 左边保存的是字符串序列
    • 右边是字符串的文档(Document)编号链表,称为倒排表(Posting List)

    字段串列表和文档编号链表两者构成了一个字典。现在想搜索”lucene”,那么索引直接告诉我们,包含有”lucene”的文档有:2,3,10,35,92,而无需在整个文档库中逐个查找。如果是想搜既包含”lucene”又包含”solr”的文档,那么与之对应的两个倒排表去交集即可获得:3、10、35、92。

    索引创建

    假设有如下两个原始文档:
    文档一:Students should be allowed to go out with their friends, but not allowed to drink beer.
    文档二:My friend Jerry went to school to see his students but found them drunk which is not allowed.
    创建过程大概分为如下步骤:

    一:把原始文档交给分词组件(Tokenizer)
    分词组件(Tokenizer)会做以下几件事情(这个过程称为:Tokenize),处理得到的结果是词汇单元(Token)

    1. 将文档分成一个一个单独的单词
    2. 去除标点符号
    3. 去除停词(stop word)
    • 所谓停词(Stop word)就是一种语言中没有具体含义,因而大多数情况下不会作为搜索的关键词,这样一来创建索引时能减少索引的大小。英语中停词(Stop word)如:”the”、”a”、”this”,中文有:”的,得”等。不同语种的分词组件(Tokenizer),都有自己的停词(stop word)集合。经过分词(Tokenizer)后得到的结果称为词汇单元(Token)。上例子中,便得到以下词汇单元(Token)

    "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)主要是对得到的词元(Token)做一些语言相关的处理。对于英语,语言处理组件(Linguistic Processor)一般做以下几点:

    1. 变为小写(Lowercase)。
    2. 将单词缩减为词根形式,如”cars”到”car”等。这种操作称为:stemming。
    3. 将单词转变为词根形式,如”drove”到”drive”等。这种操作称为:lemmatization。

    语言处理组件(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的异同:

    • 相同之处:
    1. Stemming和lemmatization都要使词汇成为词根形式。
    • 两者的方式不同:
    1. Stemming采用的是”缩减”的方式:”cars”到”car”,”driving”到”drive”。
    2. Lemmatization采用的是”转变”的方式:”drove”到”drove”,”driving”到”drive”。
    • 两者的算法不同:
    1. Stemming主要是采取某种固定的算法来做这种缩减,如去除”s”,去除”ing”加”e”,将”ational”变为”ate”,将”tional”变为”tion”。
    2. Lemmatization主要是采用事先约定的格式保存某种字典中。比如字典中有”driving”到”drive”,”drove”到”drive”,”am, is, are”到”be”的映射,做转变时,按照字典中约定的方式转换就可以了。
    3. Stemming和lemmatization不是互斥关系,是有交集的,有的词利用这两种方式都能达到相同的转换。

    三:得到的词(Term)传递给索引组件(Indexer)

    1. 利用得到的词(Term)创建一个字典
    2. Term    Document ID
    3. student     1
    4. allow       1
    5. go          1
    6. their       1
    7. friend      1
    8. allow       1
    9. drink       1
    10. beer        1
    11. my          2
    12. friend      2
    13. jerry       2
    14. go          2
    15. school      2
    16. see         2
    17. his         2
    18. student     2
    19. find        2
    20. them        2
    21. drink       2

    allow       2

    1. 对字典按字母顺序排序:
    2. Term    Document ID
    3. allow       1
    4. allow       1
    5. allow       2
    6. beer        1
    7. drink       1
    8. drink       2
    9. find        2
    10. friend      1
    11. friend      2
    12. go          1
    13. go          2
    14. his         2
    15. jerry       2
    16. my          2
    17. school      2
    18. see         2
    19. student     1
    20. student     2
    21. their       1

    them        2

    1. 合并相同的词(Term)成为文档倒排(Posting List)链表
    • Document Frequency:文档频次,表示多少文档出现过此词(Term)
    • Frequency:词频,表示某个文档中该词(Term)出现过几次

    对词(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…”,这就与用户的期望偏离太远了。如何进行合理有效的搜索,搜索出用户最想要得结果呢?搜索主要有如下步骤:

    一:对查询内容进行词法分析、语法分析、语言处理

    1. 词法分析:区分查询内容中单词和关键字,比如:english and janpan,”and”就是关键字,”english”和”janpan”是普通单词。
    2. 根据查询语法的语法规则形成一棵树
    3. 语言处理,和创建索引时处理方式是一样的。比如:leaned–>lean,driven–>drive

    二:搜索索引,得到符合语法树的文档集合
    三:根据查询语句与文档的相关性,对结果进行排序

    我们把查询语句也看作是一个文档,对文档与文档之间的相关性(relevance)进行打分(scoring),分数高比较越相关,排名就越靠前。当然还可以人工影响打分,比如百度搜索,就不一定完全按照相关性来排名的。

    如何评判文档之间的相关性?一个文档由多个(或者一个)词(Term)组成,比如:”solr”, “toturial”,不同的词可能重要性不一样,比如solr就比toturial重要,如果一个文档出现了10次toturial,但只出现了一次solr,而另一文档solr出现了4次,toturial出现一次,那么后者很有可能就是我们想要的搜的结果。这就引申出权重(Term weight)的概念。

    权重表示该词在文档中的重要程度,越重要的词当然权重越高,因此在计算文档相关性时影响力就更大。通过词之间的权重得到文档相关性的过程叫做空间向量模型算法(Vector Space Model)

    影响一个词在文档中的重要性主要有两个方面:

    • Term Frequencey(tf),Term在此文档中出现的频率,ft越大表示越重要
    • Document Frequency(df),表示有多少文档中出现过这个Trem,df越大表示越不重要
      物以希为贵,大家都有的东西,自然就不那么贵重了,只有你专有的东西表示这个东西很珍贵,权重的公式:

    空间向量模型

    文档中词的权重看作一个向量

    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 这个里面有一些解释!lucenesolr的区别是在于: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协议提供可靠的连接服务,采用三次握手建立一个连接。 
    第一次握手:建立连接时,客户端发送syn(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; 
    第二次握手:服务器收到syn包,必须确认客户的SYNack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYNACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。 完成三次握手,客户端与服务器开始传送数据.

    socket有几种状态

    CLOSED

    没有使用这个套接字

    LISTEN

    套接字正在监听入境连接

    SYN_SENT

    套接字正在试图主动建立连接

    SYN_RECEIVED

    正在处于连接的初始同步状态

    ESTABLISHED

    连接已建立

    CLOSE_WAIT

    远程套接字已经关闭:正在等待关闭这个套接字

    FIN_WAIT_1

    套接字已关闭,正在关闭连接

    CLOSING

    套接字已关闭,远程套接字正在关闭,暂时挂起关闭确认

    LAST_ACK

    远程套接字已关闭,正在等待本地套接字的关闭确认

    FIN_WAIT_2

    套接字已关闭,正在等待远程套接字关闭

    TIME_WAIT

    这个套接字已经关闭,正在等待远程套接字的关闭传送

    socket底层编程(这个可以不用了解)

    http是网络上层协议。底层还是socket短连接是发送数据时进行联接。发送完关闭(我们做完电商项目之后这些有了解一下)

    15.你所知道的通讯协议?

    ip网络中,传输层主要协议是:tcpudp。在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 easilyIt 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

    16redis集群中,某个节点宕机怎么办?你遇见过吗?你的解决思路是什么?

    redis集群:一般的是至少是2服务器,主从服务器如果redis集群的服务器挂没有关系还有备服务器

    其他面试问题汇总:

    1hibernate mybetis的异同之处?

     Mybatishibernate不同,它不完全是一个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)模式。观察者模式定义了一种一对多地依赖模式,让多个观察者同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使它们能够自动更新自己。这里的主题对象就是指通知者,又叫做发布者。观察者又叫订阅者。

    3springmvc 如何声明一个controller? 注解

    如果不基于注解:   该类需要继承  CommandController   或者 其他很多 参见  spring帮助

                如果基于注解:在类名前  加上         @controller   

          补充:将类名前加上该注解,当spring启动  或者web服务启动  spring会自动扫描所有包(当然,这个可以设置)

             作用就是告诉服务器  这个类是MVC中的C    这个类可以接收用户请求    处理用户请求

    4、设计模式有哪些?单例,工厂,观察者.观察者模式的应用场景?

    常见的设计模式:单例模式、工厂模式、观察者模式、装饰模式与适配器模式桥接模式代理模式

    5、怎么声明事物?spring配置文件中声明

    spring支持编程式事务管理和声明式事务管理两种方式。

            编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate

            声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

           显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。

             声明式事务管理也有两种常用的方式,一种是基于txaop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。

    6、编写匹配字符串(求质数)的程序

    http://blog.csdn.net/xianfajushi/article/details/50133965

    7、分词技术

    一、       为什么要进行中文分词?

    词是最小的能够独立活动的有意义的语言成分,英文单词之间是以空格作为自然分界符的,而汉语是以字为基本的书写单位,词语之间没有明显的区分标记,因此,中文词语分析是中文信息处理的基础与关键。

    Lucene中对中文的处理是基于自动切分的单字切分,或者二元切分。除此之外,还有最大切分(包括向前、向后、以及前后相结合)、最少切分、全切分等等。

    IK分析器的分词原理本质上是词典分词。现在内存中初始化一个词典,然后在分词过程中逐个读取字符,和字典中的字符相匹配,把文档中的所有的词语拆分出来的过程。

    8、不开启服务,页面怎么实现热更新!

    项目打成war包发在服务器里面,直接运行

    面试问题分类:

    一、Java基础
    1.String类为什么是final的。


    2.HashMap的源码,实现原理,底层结构。
    3.反射中,Class.forNameclassloader的区别
    4.sessioncookie的区别和联系,session的生命周期,多个服务部署时session管理。
    5.Java中的队列都有哪些,有什么区别。
    6.Java的内存模型以及GC算法
    7.Java7Java8的新特性
    8.Java数组和链表两种结构的操作效率,在哪些情况下(从开头开始,从结尾开始,从中间开始),哪些操作(插入,查找,删除)的效率高
    9.Java内存泄露的问题调查定位:jmapjstack的使用等等

    二、框架
    1.struts1struts2的区别

    Struts 1要求Action类要扩展自一个抽象基类。Struts 1的一个共有的问题是面向抽象类编程而不是面向接口编程。
    Struts 2Action类实现了一个Action接口,连同其他接口一起实现可选择和自定义的服务。Struts 2提供一个名叫ActionSupport的基类实现一般使用的接口。虽然,Action接口不是必须的。任何使用execute方法的POJO对象可以 被当作Struts 2Action对象使用。 
    程模型
    Struts 1 Action类是单例类,因只有一个示例控制所有的请求。单例类策略造成了一定的限制且给开发带来了额外的烦恼。Action资源必须是程安全或者同步 的。
    Struts 2 Action对象每一个请求都实例化对象,所以没有程安全的问题。(实践中,servlet容器生许多丢的对象对于每一个请求,多于一个的对象并不影响垃 圾收集)
    Servlet 依赖
    Struts 1Action类依赖于servlet APIHttpServletRequestHttpServletResponse作参数传给execute方法当Action被调用时。
    Struts 2Action不和容器有关。Servlet上下文被表现简单的Maps,允许Action被独立的测试。Struts 2Action可以访问最初的请求和相应,如果需要的话。然而,其他的架构元素少或者排除直接访问HttpServletRequest或者 HttpServletResponse的需要。 
    易测性
    测试Struts 1的主要障碍是execute方法暴露了Servlet API。第三方的扩展,Struts测试用例,提供Struts 1的集合对象。
    Struts 2Action可以通过实例化Action测试,设置属性,然后调用方法。依赖注入的支持也是测试变得更简单。
    接受输入
    Struts 1使用ActionForm对象捕获输入。象Action一样,所有的ActionForm必须扩展基类。因其他的JavaBean不能作 ActionForm使用,开发者经常创建多余的类捕获输入。DynaBeans可以被用来作替代ActionForm的类创建。但是开发者可以重新描述 已经存在的JavaBean
    Struts 2 Action属性作输入属性,排除第二个输入对象的需要。输入属性可能有丰富的对象类型这些类型有他们自己的属性。Action的属性可以通过标签库访 问。Struts 2也支持ActionForm形式。丰富的对象类型,包含业务或者域对象,可以被当作输入或者输出对象使用。馍型驱动特性简化标签对POJO输入对象的引 用。
    表达式语言
    Struts 1整和JSTL,所以它使用JSTL的表达式语言。表达式语言有基本的图形对象移动,但是相对很弱的集合和被索引的属性支持。
    Struts 2使用JSTL,但是框架也支持更大和更灵活的表达式,叫做对象图形符号语言OGNL)。
    将值绑定要视图上
    Struts 1使用标准JSP机制来绑定对象到页面上下文。
    Struts 2使用“ValueStack”技术了标签库可以不用链接你的视图到对象的表现类型访问值。ValueStack策略允许重用视图。
    类型转换
    Struts 1ActionForm属性经常都是String的。Struts 1使用Commons-Beanutils类型转换。转换每一个类,不是每一个实例配置。
    Struts 2使用OGNL类型转换。框架包含转换器基本的和共同的对象类型和原始类型。
    验证
    Struts 1支持手动验证凭借ActionFormvalidate方法,或者通过扩展的公用验证器。类可以有不同的验证上下文未相同的类,但是不能不能包括验证 子对象。
    Struts 2支持手动验证凭借validate方法和XWork验证框架。Xwork验证框架支持一连串的验证子属性使用的验证了属性类的类型和严正上下文而定义。
    Action执行的控制
    Struts 1支持独立的请求处理器对于每一个模型,但是所有在模型中的Action必须共享同一个生命周期。
    Struts 2支持在每一个Action基础上凭借拦截栈创建不同的生命周期。自定义栈可以被创建且使用不同的所需 的Action


    2.struts2springMVC的区别

    ①springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。

    ②springmvc是基于方法开发,传递参数是通过方法形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
    ③Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request对象内容进行解析成方法形参,将响应数据和页面封装成ModelAndView对象,最后又将模型数据通过request对象传输到页面。 Jsp视图解析器默认使用jstl。

    ④ Struts2有漏洞,springmvc目前还没有漏洞出现。如果使用struts2,建议下载最新包。


    3.spring框架中需要引用哪些jar包,以及这些jar包的用途

    Spring3.X以后jar包进行了重构,取消了原来2.X版本中的总的spring.jar包,而是把总包中的功能全部分开打包。正在向osgi靠拢。
    Spring官网提供了共20个包,各个包的作用如下:

    org.springframework.aop-3.0.6.RELEASE

    Spring的面向切面编程,提供AOP(面向切面编程)实现

    org.springframework.asm- 3.0.6.RELEASE

    Spring独立的asm程序,Spring2.5.6的时候需要asmJar 包3.0.6开始提供他自己独立的asmJar

    org.springframework.aspects- 3.0.6.RELEASE

    Spring提供对AspectJ框架的整合

    org.springframework.beans-3.0.6.RELEASE

    SpringIoC(依赖注入)的基础实现

    org.springframework.context.support-3.0.6.RELEASE

    Spring-context的扩展支持,用于MVC方面

    org.springframework.context-3.0.6.RELEASE

    Spring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等

    org.springframework.core-3.0.6.RELEASE

    Spring3.0.6的核心工具

    org.springframework.expression-3.0.6.RELEASE

    Spring表达式语言

    org.springframework.instrument.tomcat-3.0.6.RELEASE

    Spring3.0.6对Tomcat的连接池的集成

    org.springframework.instrument-3.0.6.RELEASE

    Spring3.0.6对服务器的代理接口

    org.springframework.jdbc-3.0.6.RELEASE

    对JDBC的简单封装

    org.springframework.jms-3.0.6.RELEASE

    为简化JMS API的使用而作的简单封装

    org.springframework.orm-3.0.6.RELEASE

    整合第三方的ORM框架,如hibernate,ibatis,jdo,以及 spring的JPA实现

    org.springframework.oxm-3.0.6.RELEASE

    Spring 对Object/XMl的映射支持,可以让Java与XML之间来回切换

    org.springframework.test-3.0.6.RELEASE

    对Junit等测试框架的简单封装

    org.springframework.transaction-3.0.6.RELEASE

    为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理

    org.springframework.web.portlet-3.0.6.RELEASE

    基于protlet的MVC实现

    org.springframework.web.servlet-3.0.6.RELEASE

    基于servlet的MVC实现

    org.springframework.web.struts-3.0.6.RELEASE

    整合Struts的时候的支持

    org.springframework.web-3.0.6.RELEASE

    SpringWeb下的工具包

    做Spring还必须依赖第三方包:

    ① Spring 工程依赖的公共包
    commons-logging-1[1].0.4.jar(只要是做Spring都需要这个包,否则工程起不来)

    ② 使用SpringAOP功能时依赖的包
     aspectjweaver-1[1].5.3.jar
    aopalliance-1.0.jar  (下载:http://mirrors.ibiblio.org/maven2/aopalliance/aopalliance/1.0/)

    ③ 使用SpringJDBC功能时依赖的包
    commons-dbcp.jar (下载:http://commons.apache.org/dbcp/download_dbcp.cgi)
    commons-pool.jar (下载:http://mirrors.ibiblio.org/maven2/commons-pool/commons-pool/)
    commons-collections-2.1.1.jar


    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请求。
           2. 初始化DispatcherServlet上下文对应的WebApplicationContext,并将其与业务层、持久化层的WebApplicationContext建立关联。
           3. 初始化Spring MVC的各个组成组件,并装配到DispatcherServlet中。

     

     


    5.springMVC注解的意思


    @Controller 
    @Controller 负责注册一个bean spring 上下文中,bean ID 默认为

    类名称开头字母小写,你也可以自己指定,如下 
    方法一: 
    @Controller 
    public class TestController {} 
     
    方法二:            
    @Controller("tmpController") 
    public class TestController {} 
     
    @RequestMapping 
     
    1.@RequestMapping用来定义访问的URL,你可以为整个类定义一个

    @RequestMapping,或者为每个方法指定一个。 
    @RequestMapping放在类级别上,这可令它与方法级别上的

    @RequestMapping注解协同工作,取得缩小选择范围的效果。 
    例如: 
    @RequestMapping("/test") 
    public class TestController {} 
    则,该类下的所有访问路径都在/test之下。 
     
    2.@RequestMapping用于整个类不是必须的,如果没有配置,所有的方法

    的访问路径配置将是完全独立的,没有任何关联。 
     
    3.完整的参数项为:@RequestMapping(value="",method =

    {"",""},headers={},params={"",""}),各参数说明如下:
    value :String[] 设置访问地址 
    method: RequestMethod[]设置访问方式,字符数组,查看RequestMethod

    类,包括GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE,常用

    RequestMethod.GETRequestMethod.POST 
    headers:String[] headers一般结合method = RequestMethod.POST使用 
    params: String[] 访问参数设置,字符数组 例如:userId=id 
     
    4.value的配置还可以采用模版变量的形式 ,例如:@RequestMapping

    (value="/owners/{ownerId}", method=RequestMethod.GET),这点将在介

    @PathVariable中详细说明。 
     
    5.@RequestMapping params的补充说明,你可以通过设置参数条件来限制

    访问地址,例如params="myParam=myValue"表达式,访问地址中参数只有

    包含了该规定的值"myParam=myValue"才能匹配得上,类似"myParam"之类

    的表达式也是支持的,表示当前请求的地址必须有该参数(参数的值可以是

    任意)"!myParam"之类的表达式表明当前请求的地址不能包含具体指定的

    参数"myParam" 
     
    6.有一点需要注意的,如果为类定义了访问地址为*.do,*.html之类的,则

    在方法级的@RequestMapping,不能再定义value值,否则会报错,例如 
    Java代码  
    @RequestMapping("/bbs.do")  
    public class BbsController {  
        @RequestMapping(params = "method=getList")  
        public String getList() {  
         return "list";  
        }  
    @RequestMapping(value= "/spList")  
    public String getSpecialList() {  
         return "splist";  
        }  
    }  
     
    如上例:/bbs.do?method=getList 可以访问到方法getList() ;而访

    /bbs.do/spList则会报错. 
     
    @PathVariable 
    1.@PathVariable用于方法中的参数,表示方法参数绑定到地址URL的模板

    变量。 
    例如: 
    Java代码  
    @RequestMapping(value="/owners/{ownerId}", 

    method=RequestMethod.GET)  
    public String findOwner(@PathVariable String ownerId, Model 

    model) {  
      Owner owner = ownerService.findOwner(ownerId);    
      model.addAttribute("owner", owner);    
      return "displayOwner";  
    }  
     
    2.@PathVariable用于地址栏使用{xxx}模版变量时使用。 
    如果@RequestMapping没有定义类似"/{ownerId}" ,这种变量,则使用在

    方法中@PathVariable会报错。 
     
     
    @ModelAttribute 
    1.应用于方法参数,参数可以在页面直接获取,相当于

    request.setAttribute(,) 
    2.应用于方法,将任何一个拥有返回值的方法标注上 @ModelAttribute,使

    其返回值将会进入到模型对象的属性列表中. 
    3.应用于方法参数时@ModelAttribute("xx"),须关联到Object的数据类型

    ,基本数据类型 如:int,String不起作用 
    例如: 
    Java代码  
    @ModelAttribute("items")//<——①向模型对象中添加一个名为items

    属性  
    public List<String> populateItems() {  
            List<String> lists = new ArrayList<String>();  
            lists.add("item1");  
            lists.add("item2");  
            return lists;  
    }  
    @RequestMapping(params = "method=listAllBoard")  
    public String listAllBoard(@ModelAttribute("currUser")User user, 

    ModelMap model) {  
            bbtForumService.getAllBoard();  
            //<——②在此访问模型中的items属性  
            System.out.println("model.items:" + ((List<String>)

    model.get("items")).size());  
            return "listBoard";  
    }  
     
    在 ① 处,通过使用 @ModelAttribute 注解,populateItem() 方法将在

    任何请求处理方法执行前调用,Spring MVC 会将该方法返回值以“items

    为名放入到隐含的模型对象属性列表中。 
    所以在 ② 处,我们就可以通过 ModelMap 入参访问到 items 属性,当执

    listAllBoard() 请求处理方法时,② 处将在控制台打印

    “model.items:2”的信息。当然我们也可以在请求的视图中访问到模型

    对象中的 items 属性。 
     
     
    @ResponseBody 
    这个注解可以直接放在方法上,表示返回类型将会直接作为HTTP响应字节

    流输出(不被放置在Model,也不被拦截为视图页面名称)。可以用于ajax 
     
    @RequestParam 
    @RequestParam是一个可选参数,例如:@RequestParam("id") 注解,所以

    它将和URL所带参数 id进行绑定 
    如果入参是基本数据类型(如 intlongfloat 等),URL 请求参数中

    一定要有对应的参数,否则将抛出 

    org.springframework.web.util.NestedServletException 异常,提示无

    法将 null 转换为基本数据类型. 
     
    @RequestParam包含3个配置 @RequestParam(required = ,value="", 

    defaultValue = "") 
    required :参数是否必须,boolean类型,可选项,默认为true 
    value: 传递的参数名称,String类型,可选项,如果有值,对应到设置方

    法的参数 
    defaultValue:String类型,参数没有传递时为参数默认指定的值 
     
    @SessionAttributes session管理 
    Spring 允许我们有选择地指定 ModelMap 中的哪些属性需要转存到 

    session 中,以便下一个请求属对应的 ModelMap 的属性列表中还能访问

    到这些属性。这一功能是通过类定义处标注 @SessionAttributes 注解来

    实现的。@SessionAttributes 只能声明在类上,而不能声明在方法上。 
     
    例如 
     
    @SessionAttributes("currUser") // ModelMap 中属性名为currUser 的属性 


    @SessionAttributes({"attr1","attr2"}) 
    @SessionAttributes(types = User.class) 
    @SessionAttributes(types = {User.class,Dept.class}) 
    @SessionAttributes(types = {User.class,Dept.class},value={"attr1","attr2"}) 

     
    @CookieValue 获取cookie信息 
    @RequestHeader 获取请求的头部信息


    6.springbeanFactoryApplicationContext的联系和区别

    BeanFacotryspring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。 
      ApplicationContext接口,它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能。ApplicationContext以一种更向面向框架的方式工作以及对上下文进行分层和实现继承,ApplicationContext包还提供了以下的功能: 
      • MessageSource, 提供国际化的消息访问  
      • 资源访问,如URL和文件  
      • 事件传播  
      • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web  


    7.spring注入的几种方式

    • 接口注入
    • Setter方法注入
    • 构造方法注入
    • spring4可以注解注入@Autowired


    8.spring如何实现事物管理的

    是通过AOP对配置的方法进行栏截,然后再调用事务管理器中的预设代码对事务进行管理,再委托被拦截方法完成原有的任务。


    9.springIOCAOP的原理
    10.hibernate中的1级和2级缓存的使用方式以及区别原理
    11.spring中循环注入的方式

    什么是循环注入?举个列子我有一个类AA有一个构造器里面的参数是类B,然后类B里面有个构造器参数是类C,类C里面有个构造器参数是类A,就是我们会发现其实引用循环了A 里面有B的引用,B里面有C的引用,C里面又有A的引用。

    循环依赖又分为构造器循环依赖和set循环依赖:

    首先讲一下构造器的循环依赖:

    1. public class A  
    2. {  
    3. public A(B b)  
    4. {  
    5. }  
    6. }  

     

    1. public class B  
    2. {  
    3. public B(C c)  
    4. {  
    5. }  
    6. }  
    1. public class C  
    2. {  
    3. public C(A a)  
    4. {  
    5. }  
    6. }  


    当我们用spring来加载A的时候spring的流程是这样的:

    1spring创建A首先去当前创建池中去查找当前A是否在创建,如果发明没有创建则准备其构造器需要的参数B,然后把创建A的标识放入当前创建池中。

    2spring创建B首先去当前创建池中去查找当前B是否在创建,如果发现没有创建则准备其构造器需要的参数C,然后把创建B的标识放入当前创建池中。

    3spring创建C首先去当前创建池中去查找当前C是否在创建,如果发现没有创建则准备其构造器需要的参数A,然后把创建C的标识放入当前创建池中。

    4spring创建C需要的A,这个时候会发现在当前创建池中已经有A的标识,A正在创建中则抛出BeanCurrentlyInCreationException

    构造器的循环注入是没有办法解决的,所以只能我们避免.

     

    接下来看下set方式的循环注入:
    set方式的循环注入分2种情况,第一种情况是可以解决的循环注入就是单列情况下。第二种情况就是无法解决的循环注入就是多列情况下,下面分析一下原因:

    先看第一种情况,还是拿上面的ABC3个类来说明问题,只不过这次不是构造器里面的参数,而是换成他们的成员变量,然后通过set方式类注入,这里代码就不写了直接讲下:

    单列下set方式的注入流程是这样的:

    1spring创建A,首先根据其无参构造器创建一个对象A,然后提前暴露出创建出来的这个A对象,然后再当前的创建池中放入创建A的标识,然后进行set方法注入B

    2spring创建B,首先根据其无参构造器创建一个对象B,然后提前暴露出创建出来的这个B对象,然后在当前的创建池中放入创建B的标识,然后进行set方法的注入C

    3spring创建C,首先根据其无参构造器创建一个对象C,然后提前暴露出创建处理的这个C对象,然后在当前的创建池中放入创建C的标识,然后进行set方法的注入A

    4:在第三步注入A的时候由于提前暴露出来了创建出来的A对象所以不会报BeanCurrentlyInCreationException的错误。

    多列下set方式的循环注入不能解决的原因是在多列的情况下,当创建对象的时候spring不会提前暴露创建处理的对象A,这样的话则会和构造器循环注入出现一样的情况最终导致报错



    三、多线程
    1.Java创建线程之后,直接调用start()方法和run()的区别

    Thread类中run()start()方法的区别如下:
    run()方法:在本线程内调用该Runnable对象的run()方法,可以重复多次调用;
    start()方法:启动一个线程,调用该Runnable对象的run()方法,不能多次启动一个线程;

    当你调用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.atomicintegervolatile等线程安全操作的关键字的理解和使用
    8.线程间通信,waitnotify
    9.定时线程的使用
    10.场景:在一个主线程中,要求有大量(很多很多)子线程执行完之后,主线程才执行完成。多种方式,考虑效率。

    四、网络通信
    1.http是无状态通信,http的请求方式有哪些,可以自己定义新的请求方式么。
    2.socket通信,以及长连接,分包,连接异常断开的处理。
    3.socket通信模型的使用,AIONIO
    4.socket框架netty的使用,以及NIO的实现原理,为什么是异步非阻塞。
    5.同步和异步,阻塞和非阻塞。

    五、Linux
    1.常用的linux下的命令
    2.大的log文件中,统计异常出现的次数、排序,或者指定输出多少行多少列的内容。(主要考察awk)
    3.linux下的调查问题思路:内存、CPU、句柄数、过滤、查找、模拟POSTGET请求等等场景
    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.为什么用缓存,用过哪些缓存,redismemcache的区别
    2.redis的数据结构
    3.redis的持久化方式,以及项目中用的哪种,为什么
    4.redis集群的理解,怎么动态增加或者删除一个节点,而保证数据不丢失。

     赢在格局,不失风雅。

  • 相关阅读:
    noip不知道哪年 货车运输
    bzoj1002轮状病毒
    bzoj1001狼抓兔子
    20171002模拟赛
    20171001模拟赛
    异常
    springmvc-servlet.xml 第二种选择
    springmvc入门
    springmvc-servlet.xml(springmvc-servlet.xml 配置 增强配置)
    777
  • 原文地址:https://www.cnblogs.com/Joey-zy1024/p/9266414.html
Copyright © 2011-2022 走看看