常见面试题

1:hashmap的原理:http://www.javashuo.com/article/p-wccjhppe-ck.htmlhtml

HashMap是基于hashing的原理,咱们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当咱们给put()方法传递键和值时,咱们先对键调用hashCode()方法,返回的hashCode用于找到bucket位置来储存Entry对象。”这里关键点在于指出,HashMap是在bucket中储存键对象和值对象,做为Map.Entry。java

当hashcode相同时:mysql

回答“由于hashcode相同,因此它们的bucket位置相同,‘碰撞’会发生。由于HashMap使用链表存储对象,这个Entry(包含有键值对的Map.Entry对象)会存储在链表中。”这个答案很是的合理,虽然有不少种处理碰撞的方法,这种方法是最简单的,也正是HashMap的处理方法。linux

 

为何默认初始化桶数组大小为16,为何加载因子的大小为0.75,这两个值的选取有什么特色。

经过看上面的代码咱们能够知道这两个值主要影响的threshold的大小,这个值的数值是当前桶数组需不须要扩容的边界大小, threshold=initialCapacity*loadFactor,桶中的键值对超过这个界限就把桶的容量变大。git

咱们都知道桶数组若是扩容,会申请内存空间,而后把原桶中的元素复制进新的桶数组中,这是一个比较耗时的过程。既然这样,那为什么不把这两个值都设置大一些呢,threshold是两个数的乘积,设置大一些就不那么容易会进行扩容了啊。github

缘由是这样的,若是桶初始化桶数组设置太大,就会浪费内存空间,16是一个折中的大小,既不会像1,2,3那样放几个元素就扩容,也不会像几千几万那样能够只会利用一点点空间从而形成大量的浪费。web

加载因子设置为0.75而不是1,是由于设置过大,桶中键值对碰撞的概率就会越大,同一个桶位置可能会存放好几个value值,这样就会增长搜索的时间,性能降低,设置太小也不合适,若是是0.1,那么10个桶,threshold为1,你放两个键值对就要扩容,太浪费空间了。redis

 

在扩容的时候, 也是直接乘以2进行扩容, 保证仍是2的n次方 .算法

扩容时,当hashmap的长度为length = 2^n时,不一样的hash值发生碰撞的几率比较小,这样就会使得数据在table数组中分布较均匀,查询速度也较快。spring

由于相同位数数字与11111111111进行与运算都不一样。

咱们回到indexFor方法,该方法仅有一条语句:h&(length - 1),由于求在hashmap中的位置时就是hashcode%length 而 h & (length - 1) == h % length”这句话除了上面的取模运算外还有一个很是重要的责任:均匀分布table数据和充分利用空间。

      这里咱们假设length为16(2^n)和15,h为五、六、7。

(这里的h表示的根据key算的hash值,这个indexFor方法是要在数组上给当前数据找个落脚点,好存放当前数据。)

table1_thumb[3]

 当length=15时,6和7的结果同样,这样表示他们在table存储的位置是相同的,也就是产生了碰撞,六、7就会在一个位置造成链表,这样就会致使查询速度下降。诚然这里只分析三个数字不是不少,那么咱们就看0-15。

table2_thumb[16]

      从上面的图表中咱们看到总共发生了8次碰撞,同时发现浪费的空间很是大,有一、三、五、七、九、十一、1三、15处没有记录,也就是没有存放数据。这是由于他们在与14进行&运算时,获得的结果最后一位永远都是0,即000一、00十一、010一、01十一、100一、10十一、110一、1111位置处是不可能存储数据的,空间减小,进一步增长碰撞概率,这样就会致使查询速度慢。而当length = 16时,length – 1 = 15 即1111,那么进行低位&运算时,值老是与原来hash值相同,而进行高位运算时,其值等于其低位值。

因此说当length = 2^n时,不一样的hash值发生碰撞的几率比较小,这样就会使得数据在table数组中分布较均匀,查询速度也较快。

 

为何hashmap最大设置为2^31,由于考虑到32为操做系统内存最大为2^32,当对2^31进行扩容时,首先要建立一个更大的map出来,内存不够用了

4GB= 2^32 Byte啊

 

ConcurrentHashMap  使用锁分段技术,  分红16个段,修改哪一个段,就获取哪一个段的锁。

 

2:从浏览器输入url到加载出页面,都经历了什么,例如输入www.baidu.com     https://segmentfault.com/a/1190000003925803

      假设本身的主机已经联网,省略了广播到dhcp肯定本机ip和本地dns服务器ip的步骤 

       输入url,  首先要解析域名为对应的ip地址,若是2.2失败就进行2.3....

     2.1:查询浏览器dns缓存

     2.2: 查询操做系统的dns缓存

      2.3:搜索操做系统的hosts文件,维护了一张域名与ip的对应表

       2.4:向本地dns服务器发出请求,查询本地dns服务器缓存,成功率为80%

       2.5    向跟dns服务器查询,   跟dns服务器返回返com 域的顶级域名服务器的地址。

       2.6   向com域的顶级域名服务器发出查询请求,返回baidu.com的dns服务器地址

       2.7:向baidu.com发送查询请求,返回www.baidu.com  的ip地址

    知道了服务器的 IP 地址,下面便开始与服务器建立链接了

       2.8   与服务器  简历tcp链接,三次握手,可靠数据链接 (检验和,定时,序号,窗口流水线,确定确认,否认确认)

                2.8.1   客户端向服务器发起请求链接信号,带有标致为SYN=1,客户端序号

                2.8.2   服务器接收到信号,向客户端返回确认信号,  标致位SYN=1 ,服务端确认号=客户端序号+1, 服务端序号

               2.8.3      客户端接收到服务器的确认信号,     向服务器发送确认信号能够带有数据,标致位改变,SYN=0  客户端确认号=服务端序号+1, 客户端序号=服务端确认号

 

当服务器与主机创建了链接以后,下面主机便与服务器进行通讯。网页请求是一个单向请求的过程,便是一个主机向服务器请求数据,服务器返回相应的数据的过程。

            2.9浏览器根据 URL 内容生成 HTTP 请求,请求中包含请求文件的位置、请求文件的方式等等;

             2.10服务器接到请求后,会根据 HTTP 请求中的内容来决定如何获取相应的 HTML 文件;

             2.11服务器将获得的 HTML 文件发送给浏览器;

             2.12在浏览器尚未彻底接收 HTML 文件时便开始渲染、显示网页;

             2.13在执行 HTML 中代码时,根据须要,浏览器会继续请求图片、CSS、JavsScript等文件,过程同请求 HTML ;

              2.14   断开链接--四次挥手

               2.14.1主机向服务器发送一个断开链接的请求不早了,我该走了);

               2.14.2服务器接到请求后发送确认收到请求的信号(知道了);尚未断开链接

               2.14.3服务器向主机发送断开通知我也该走了);

               2.14.4主机接到断开通知后断开链接并反馈一个确认信号(嗯,好的),服务器收到确认信号后断开链接;

              经历的协议过程:dhcp>dns>tcp链接>http>tcp断开

       

3:Rpc远程调用    http://www.javashuo.com/article/p-ggjyumtm-cn.html

        Rpc服务器提供一个接口,让客户端调用,服务器的具体实现类方法能够修改。  比较灵活

4:设计模式 http://www.cnblogs.com/foryang/p/5849402.html

     4.1: 责任链,一个接口handle,  为每个handle的实现类设置后继,当没有后继时,就结束

     4.2:建造者: 一个统领,  将构建产品的步骤分步进行。   统领者指导建造者一步一步构建产品对象。

      4.3:分红产品族,当一个对象中的部件相互依赖时,例如  宝马的轮胎和宝马的轮廓才能适配,使用奔驰的轮廓就不行,那么宝马分为一个产品族。这个工厂专门生产宝马。

5:spring aop  和ioc    http://www.javashuo.com/article/p-rmjdpvxu-ce.html

 http://jinnianshilongnian.iteye.com/blog/1413846

http://www.javashuo.com/article/p-xzmpncuh-n.html

      5.1 :spring ioc 是一个容器,管理各个bean对象。管理的时候是经过描述建立对象,经过配置管理,修改对象。

      5.2 最主要是完成了对象的建立和依赖的管理注入等等

       5.3 SpringIOC容器管理了咱们定义的各类Bean对象及其相互的关系

      5.4 IoC容器的初始化包括BeanDefinition的Resource定位、载入和注册这三个基本的过程。     

 

//向IoC容器注册BeanDefinition 
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());   //将解析xml事后的bean对象注册近容器
//若是解析的BeanDefinition有别名,向容器为其注册别名  String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String aliase : aliases) { registry.registerAlias(beanName, aliase); } } 

 

最后,Bean定义资源文件中配置的Bean被解析事后,已经注册到IoC容器中,被容器管理起来,真正完成了IoC容器初始化所作的所有工做。现  在IoC容器中已经创建了整个Bean的配置信息,这些BeanDefinition信息已经可使用,而且能够被检索,IoC容器的做用就是对这些注册的Bean定义信息进行处理和维护。这些的注册的Bean定义信息是IoC容器控制反转的基础,正是有了这些注册的数据,容器才能够进行依赖注入。Spring Bean是单例的:http://www.javashuo.com/article/p-cudrgzdh-hn.html

   5.5:控制反转是一种经过描述(在java中能够是XML或者注解)并经过第三方去产生或获取特定对象的方式。

            潜意识里以为对象须要本身建立,事实上这并非你真正的须要,由于也许你对某一领域并不精通,这个时候能够把建立对象的主动权交给别人,这就是控制反转

Spring Ioc容器能够容纳咱们所开发的各类Bean, 而且咱们能够从中获取各类发布在Spring Ioc容器里的Bean,  而且经过描述能够获得它。

 例子:假如如今是共产主义社会,本身是觉得蛋糕师,那么社会上的各类东西咱们均可以得到, 这些东西就做为Bean注入到了Spring Ioc容器中, 本身生产的各类蛋糕Bean也注入到了Spring Ioc容器中 ,  若是咱们想要一辆奔驰车,  咱们只须要经过描述想要的奔驰车配置(例如四个轮,2.0T),就能够获得一辆奔驰车,咱们并不须要关注制造奔驰车的细节(例如螺丝怎么拧的)。一样,别人也能够经过描述拿到本身作的蛋糕bean

            

 IOC和DI  就是讲对象的建立,控制,依赖管理交给IOC容器。

5.2:spring aop  管理切面上某些对象之间的协做,  当多个对象,在某一点相互影响时,须要定义一个切面,来协调这几个对象在这一点的操做。

AOP 1: 对多个对象产生影响的行为进行封装成一个切面(不少方法(切入点)),2: 对方法进行加强

https://www.cnblogs.com/zhaozihan/p/5953063.html             

http://www.javashuo.com/article/p-dxbtymsz-hh.html

Spring AOP 经常使用于数据库事务的编程

      spring aop  将业务代码(一个方法,service层,包含多个对象的相互协做)经过动态代理 织入到相应的位置 ,动态代理中invoke方法中 method.invoke(obj, objects)处; 业务先后的逻辑由拦截器(或固定的实现,例如数据库链接,异常处理)实现。 https://github.com/1367356/GradleTestUseSubModule/tree/master/SpringAOPTheory/src/main/java/com/li

6: innodb和imysam数据库引擎

Innodb引擎

Innodb引擎提供了对数据库ACID事务的支持,而且实现了SQL标准的四种隔离级别。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它自己其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中创建缓冲池,用于缓冲数据和索引。可是该引擎不支持FULLTEXT类型的索引,并且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时须要扫描全表。当须要使用数据库事务时,该引擎固然是首选。因为锁的粒度更小,写操做不会锁定全表,因此在并发较高时,使用Innodb引擎会提高效率。可是使用行级锁也不是绝对的,若是在执行一个SQL语句时MySQL不能肯定要扫描的范围,InnoDB表一样会锁全表。

 

MyIASM引擎

 

MyIASM是MySQL默认的引擎,可是它没有提供对数据库事务的支持,也不支持行级锁和外键,所以当INSERT(插入)或UPDATE(更新)数据时即写操做须要锁定整个表,效率便会低一些。不过和Innodb不一样,MyIASM中存储了表的行数,因而SELECT COUNT(*) FROM TABLE时只须要直接读取已经保存好的值而不须要进行全表扫描。若是表的读操做远远多于写操做且不须要数据库事务的支持,那么MyIASM也是很好的选择

主要区别:

一、MyIASM是非事务安全的,而InnoDB是事务安全的

二、MyIASM锁的粒度是表级的,而InnoDB支持行级锁

三、MyIASM支持全文类型索引,而InnoDB不支持全文索引

四、MyIASM相对简单,效率上要优于InnoDB,小型应用能够考虑使用MyIASM

五、MyIASM表保存成文件形式,跨平台使用更加方便

应用场景:

一、MyIASM管理非事务表,提供高速存储和检索以及全文搜索能力,若是再应用中执行大量select操做,应该选择MyIASM
二、InnoDB用于事务处理,具备ACID事务支持等特性,若是在应用中执行大量insert和update操做,应该选择InnoDB
 
       mybatis执行过程, 
      1:首先读取配置文件  XMLConfigBuilder(建造者模式,一个统领)   对配置文件进行解析,生成Configuraiton对象(单例)。
  2:经过Configuration 对象生成SqlSessionFactory,
      3:SqlSessionFactory  用于生成SqlSession.
      4:生成SqlSession以后,使用SqlSession生成一个UserMapper的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);  //建立UserMapper的代理对象
//建立过程当中判断UserMapper是否是一个类,若是不是,须要用MapperMethod.excute(SqlSession sqlsession,Object[] obj) 去建立动态代理对象。
//建立过程当中将sqlSession的方法加入到了invoke中。
//那么调用代理对象mapper方法的时候,就调用sqlSession中的方法,也就是sql语句。 SqlSession至关于一个UserMapper的实现类,用户本身去写sqlSession(sql语句)里面的业务
//SqlSession 包含了执行sql所须要的全部方法,能够经过SqlSession实例直接运行映射的sql语句,完成对数据的正删改查和事务的提交等,用完以后关闭SqlSession
8:redis   缓存数据库,以key-value形式结构进行存储
     优势:数据结构丰富(字符串,列表,hash,集合,有序集合), 可持久化,都是原子操做
 
9: 乐观锁,悲观锁
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操做。[1]
乐观锁:假设不会发生并发冲突,只在提交操做时检查是否违反数据完整性。[1] 乐观锁不能解决脏读的问题。
 
10:linux下mysql备份命令:

一,数据库的备份与导入

1),数据库的备份

1.导出整个数据库
mysqldump -u 用户名 -p 数据库名 > 导出的文件名
例:mysqldump -u dbadmin -p myblog > /home/zhangy/blog/database_bak/myblog.sql

2.导出一个表
mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名
例:mysqldump -u dbadmin -p myblog wp_users> /home/zhangy/blog/database_bak/blog_users.sql

3.导出一个数据库结构
mysqldump -u dbadmin -p -d --add-drop-table myblog > /home/zhangy/blog/database_bak/blog_struc.sql
说明:-d 没有数据 --add-drop-table 在每一个create语句以前增长一个drop table

4.导出数据库一个表结构
mysqldump -u dbadmin -p -d --add-drop-table myblog  wp_users> /home/zhangy/blog/database_bak/blog_users_struc.sql
说明:-d 没有数据 --add-drop-table 在每一个create语句以前增长一个drop table

 

2),数据库的导入

1,用 mysqldump 备份出来的文件是一个能够直接倒入的 SQL 脚本,有两种方法能够将数据导入。
例如:
#/usr/local/mysql/bin/mysql -u root -p *****  myblog   < /home/zhangy/blog/database_bak/myblog.sql

这种方法,我之前常常如今不多用了,由于很容易产生乱码,由于:

a,导出数据库时,你若是忘了设置导出字符集的话,在导入的时候,就有可能会出问题.

b,假如,你导出时设置导出时设置了utf8的编码,可是你又把你的数据库如今的字符集改为了gb2312的.这样又会乱码。

2,用 source 语句
例如:

mysql -u dbadmin -p

use myblog;

set names utf8;  #这里的字符集根你的将要导入的数据库的字符集一至。

source /home/zhangy/blog/database_bak/myblog.sql;

 

11:  socket编程

   两个程序(进程)运行时,它们经过从套接字读出和写入数据彼此之间进行通讯。

  网络应用程序,经过socket进行通讯。   socket将发送方的数据经过socket通讯(指定IP,  端口,协议)传递到接收方。

网络层的“ip地址”能够惟一标识网络中的主机,而传输层的“协议+端口”能够惟一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就能够标识网络的进程了,网络中的进程通讯就能够利用这个标志与其它进程进行交互。

网络中的进程是经过socket来通讯的

        https://blog.csdn.net/m0_37947204/article/details/80489431

       http://www.javashuo.com/article/p-drqmpbyr-gs.html

     https://www.cnblogs.com/wangcq/p/3520400.html

12:为何有进程了,还要有线程

      由于进程是系统分配资源的最小单位,进程切换开销大。

线程容许在同一个进程中同时存在多个程序控制流,线程会共享进程范围内的资源。

    缘由: 线程是比进程更轻量级的调度执行单位。线程的引入,能够把一个进程的资源分配和执行调度分开,各个线程便可以共享进程资源(内存地址,文件I/O等),又能够独立调度(线程是CPU调度的基本单位)。

 

13:多路复用和多路分解

    多路复用:将多个进程的套接字的数据取出,为各个数据添加上协议(ip,端口号), 组成分组,发送出去。

   多路分解: 将套接字中的数据分解,发给各个进程,叫作多路分解。

 

 IO多路复用:就是多个客户端线程发送过来IO请求,来的都放进来,而不是每一个链接为其开启一个服务端进程。服务端将其放到一个队列中,而后服务端一个线程对这个队列进行处理。处理完返回。至关于一个事件循环Event loop.  

      后台就一个线程,避免了线程切换和后天线程抢夺资源,  可能单cpu

 

14:校验和

        一个十六进制数,

       0x8732ACD87

        前4为和后四位化成二进制,相加获得一个和,若是最高位有进位,就和的最后+1。 而后取反

15: 创建两个列的索引,复合查询  。符合索引的有效索引为最长前缀匹配。 例如 index(A,B,C)  那么有效索引为:(A),(A,B),(A,B,C)

16:String intern的用法

http://www.javashuo.com/article/p-xwueyuaf-eo.html

上面是jdk源码中对intern方法的详细解释。简单来讲就是intern用来返回常量池中的某字符串,若是常量池中已经存在该字符串,则直接返回常量池中该对象的引用。不然,在常量池中加入该对象,而后 返回引用。下面的一个例子详细的解释了intern的做用过程:

       例如:   jdk 1.7以后,将会在堆上建立对象,在常量池中保存符号引用,  String.intern()返回字符串的首次出现的实例引用。

String st2=new StringBuilder("计算机").append("软件").toString();
System.out.println(st2.intern()==st2);

String st3=new StringBuilder("计算机").append("软件").toString();
System.out.println(st3.intern()==st3);
System.out.println(st3.intern()==st2);
/**结果
 true
 false
 true
 */

 st3.intern()是首次计算机软件出现的实例引用(在常量池中)。

17:String 的equals 和==的区别

==是对象引用的比较

equals是逻辑一致性比较,对象覆盖了该方法,将会按照对象设定的比较方式进行比较。

String 覆盖了equals方法

public final class String implements Serializable, Comparable<String>, CharSequence {
    public boolean equals(Object var1) {
        if (this == var1) {
            return true;
        } else {
            if (var1 instanceof String) {
                String var2 = (String)var1;
                int var3 = this.value.length;
                if (var3 == var2.value.length) {
                    char[] var4 = this.value;
                    char[] var5 = var2.value;

                    for(int var6 = 0; var3-- != 0; ++var6) {
                        if (var4[var6] != var5[var6]) {
                            return false;
                        }
                    }

                    return true;
                }
            }

            return false;
        }
    }
}

 

        String s1 = new String("abc");
        String s2 = new String("abc");

        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));

        /**结果
         false
         true
         */

 18:Java 中的编译期常量是什么?使用它又什么风险?

风险:使用了一个其它Jar包的编译器常量,jar包的发布者有可能会改变它的值。而你不知道,还在使用,解决方法,当更新Jar依赖时,要从新编译。

公共静态不可变(public static final )变量也就是咱们所说的编译期常量,这里的 public 可选的。实际上这些变量在编译时会被替换掉,由于编译器知道这些变量的值,而且知道这些变量在运行时不能改变。这种方式存在的一个问题是你使用了一个内部的或第三方库中的公有编译时常量,可是这个值后面被其余人改变了,可是你的客户端仍然在使用老的值,甚至你已经部署了一个新的jar。为了不这种状况,当你在更新依赖 JAR 文件时,确保从新编译你的程序。

 

19:运行时常量池

     运行时常量池是方法区的一部分,存放编译器生成的各类字面量和符号引用,   字面量和符号引用 是Class文件的一部分。

    方法区用于存放类信息,常量,静态变量,编译后的代码。

 20: BIO,NIO,AIO. Selector 

http://www.javashuo.com/article/p-sqmzvpaz-nh.html

http://www.javashuo.com/article/p-qkkfaxit-kk.html

 

BIO同步阻塞:BIO 每一个链接须要服务器建立一个线程。

NIO 同步非阻塞:NIO的最重要的地方是当一个链接建立后,不须要对应一个线程,这个链接会被注册到多路复用器上面,因此全部的链接只须要一个线程就能够搞定,当这个线程中的多路复用器进行轮询的时候,发现链接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。

   非阻塞:须要while轮询

AIO 异步阻塞:经过read,write异步操做来完成, 

 与NIO不一样,当进行读写操做时,只须直接调用API的read或write方法便可。这两种方法均为异步的,对于读操做而言,当有流可读取时,操做系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操做而言,当操做系统将write方法传递的流写入完毕时,操做系统主动通知应用程序。  便可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。

同步和异步:

同步和异步是针对应用程序和内核的交互而言的,同步指的是用户进程触发IO操做并等待或者轮询的去查看IO操做是否就绪,而异步是指用户进程触发IO操做之后便开始作本身的事情,而当IO操做已经完成的时候会获得IO完成的通知。

 

Selector 是一个选择器,轮询器。  用于NIO同步非阻塞。   

http://www.importnew.com/26258.html

se
lect将会采用轮询的方式对队列中的全部链接进行查询,获取有效的链接。可是,当链接特别多时,例如1000000个链接,可是有效请求特别少时,例如100个,那么将会形成极大的浪费。
epoll将活跃链接保存在一个红黑树中,每次只查询活跃链接。 已经取代了select/poll.

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package java.nio.channels;

import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.spi.SelectorProvider;
import java.util.Set;

public abstract class Selector implements Closeable {
    protected Selector() {
    }

    public static Selector open() throws IOException {
        return SelectorProvider.provider().openSelector();
    }

    public abstract boolean isOpen();

    public abstract SelectorProvider provider();

    public abstract Set<SelectionKey> keys();

    public abstract Set<SelectionKey> selectedKeys();

    public abstract int selectNow() throws IOException;

    public abstract int select(long var1) throws IOException;

    public abstract int select() throws IOException;

    public abstract Selector wakeup();

    public abstract void close() throws IOException;
}

 

 21:  了解的设计模式

         a:工厂模式

      http://www.cnblogs.com/java-my-life/archive/2012/03/28/2418836.html

        b:   建造者模式    https://github.com/1367356/GradleTestUseSubModule/tree/master/DesignPattern/src/main/java/com/li/MyBuilderPattern

        http://www.cnblogs.com/java-my-life/archive/2012/04/07/2433939.html

       c: 适配器模式:

         http://www.cnblogs.com/java-my-life/archive/2012/04/13/2442795.html

      d:  观察者模式 

     http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html

    e:  策略模式 

    http://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html

    f:  代理模式

    http://www.cnblogs.com/java-my-life/archive/2012/04/23/2466712.html

 

解释:

状态模式:状态决定行为,  状态是一个接口,状态(子类对象不一样)不一样,行为不一样。

策略模式:客户端选择不一样的策略,选择不一样的计算方法

工厂模式:各个零部件(产品零部件)的工厂,工程师组装

抽象工厂模式:每个产品,构成一个产品族,有产品工厂生成

建造者模式:一个统领,指挥建造者一步一步构建产品对象。  统领,建造者,产品(part1,part2).

适配器模式:适配类(ada.method1)没有须要的目标对象(target.method1,target.method2)中的方法,就建造一个适配器(method1(){ada.method1},method2),继承适配类和目标对象,将目标对象的方法用适配类方法重写.  

观察者模式:为主题添加观察者对象(继承自抽象观察者),当主题变化时,通知观察者。   有推模式和拉模式,推模式是将主题变化的状态推给观察者,拉模式是将主题对象直接给观察者,由观察者本身从主题对象中获取内容。

代理模式:为一个类建立一个代理类,其中,代理类和被代理的类(目标类)实现了相同的接口,代理类也实现了InvocationHandler。 生成的代理类中有目标类的方法和hashCode,equals,toString方法,当调用这几个方法时>会调用super(invocaitonHandler)>会调用invoke方法>调用method.invoke(target)>调用了目标类了的方法。

 

22:缓存策略

http://www.javashuo.com/article/p-firrwpbx-gv.html

23:redis

       redis底层是用字典(dict)数据结构存储的。

      dict里面有两个哈希表,每一个哈希表的桶里面存储dictEntry链表,dictEntry存储具体的key和value。

     redis支持的数据类型hashtable是用开链表的形式(和hashMap差很少)。

Redis也是惰性删除,即要用到数据时,先检查key是否过时,过时则删除,而后返回错误。单纯的靠惰性删除,上面说过可能会致使内存浪费,因此Redis也有补充方案,Redis里面有个定时执行的函数,叫servercron,它是维护服务器的函数,在它里面,会对过时数据进行删除,注意不是全删,而是在必定的时间内,对每一个数据库的expire dict里面的数据随机选取出来,若是过时,则删除,不然再选,直到规定的时间到。即随机选取过时的数据删除,这个操做的时间分两种,一种较长,一种较短,通常执行短期的删除,每隔必定的时间,执行一次长时间的删除。这样能够有效的缓解光采用惰性删除而致使的内存浪费问题。

 

redis持久化

 1:保存redis数据库文件   RDB  ,后台线程执行bgsave

2:   保存redis命令

     2.1 根据aof_buf   向aof文件中输入命令

     2.2  aof_rewrite命令能够根据数据库生成操做命令(逆向),将生成的命令存入aof

 

 aof命令载入的时候,redis生成一个假的客户端,去执行这些命令,最后将原来 的数据恢复出来。

 

Redis是单event loop的,主线程是单线程的。

 

24:  epoll

http://www.javashuo.com/article/p-wsiwtuxy-m.html

http://www.javashuo.com/article/p-bfjmamzc-mt.html

https://www.jianshu.com/p/36197dac65d9

      select 使用扫描全表的形式找出活跃的链接,有最大fd限制,1024。  10万个fd至少须要100个进程

    epoll首先create是建立对象的epoll对象(事件)的,ctl操做为红黑树添加,更新事件。当有有效事件发生时,经过事件的回调函数callback事件添加到了双向链表rlist中。

await查询双向链表中有无事件便可,有的话处理,没有等待。

25:复合索引的匹配策略,左向最长匹配

     例如一个索引index(a,b,c),  那么可使用索引的选择项为:

    select * from table a=''

    select * from table a='' and b='';

    select * from table a='' and b='' and c='';

26:  修饰符的做用范围从大到小  public - protected- default-private

27:进程间通讯方式: http://www.javashuo.com/article/p-vifdlolq-bd.html

近日想总结下进程间,线程间的通讯方式,在网上搜索了下,感受写的很好,照搬过来,当作加深记忆。

几种进程间的通讯方式

(1) 管道(pipe):管道是一种半双工的通讯方式,数据只能单向流动,并且只能在具备血缘关系的进程间使用。进程的血缘关系一般指父子进程关系。

(2)有名管道(named pipe):有名管道也是半双工的通讯方式,可是它容许无亲缘关系进程间通讯。

(3)信号量(semophore):信号量是一个计数器,能够用来控制多个进程对共享资源的访问。它一般做为一种锁机制,防止某进程正在访问共享资源时,其余进程也访问该资源。所以,主要做为进程间以及同一进程内不一样线程之间的同步手段。

(4)消息队列(message queue):消息队列是由消息组成的链表,存放在内核中 并由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。

(5)信号(signal):信号是一种比较复杂的通讯方式,用于通知接收进程某一事件已经发生。

(6)共享内存(shared memory):共享内存就是映射一段能被其余进程所访问的内存,这段共享内存由一个进程建立,但多个进程均可以访问,共享内存是最快的IPC方式,它是针对其余进程间的通讯方式运行效率低而专门设计的。它每每与其余通讯机制,如信号量配合使用,来实现进程间的同步和通讯。

(7)套接字(socket):套接口也是一种进程间的通讯机制,与其余通讯机制不一样的是它能够用于不一样及其间的进程通讯。

几种线程间的通讯机制

一、锁机制

     1.1 互斥锁:提供了以排它方式阻止数据结构被并发修改的方法。

     1.2 读写锁:容许多个线程同时读共享数据,而对写操做互斥。

     1.3 条件变量:能够以原子的方式阻塞进程,直到某个特定条件为真为止。对条件测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一块儿使用。

二、信号量机制:包括无名线程信号量与有名线程信号量

三、信号机制:相似于进程间的信号处理。

线程间通讯的主要目的是用于线程同步,因此线程没有象进程通讯中用于数据交换的通讯机制。

 

28:求一个环形链表的长度,

    能够取一个节点做为头节点,而后将该节点赋值为head,  再一次向下取节点,并判断是否等于头节点,直到等于头结点,结束。

29:死锁产生的条件和预防

      http://www.javashuo.com/article/p-byvlpsof-gq.html

30:深复制与浅复制  https://www.jianshu.com/p/aa6d493603d3

   浅复制:仅仅复制一个对象的引用,clone就是浅复制。 克隆对象和原对象指向相同的位置。改变浅复制的引用的值,也将改变原对象的值。

  深复制:经过序列化将对象写到流里面,而后经过反序列化复原原对象。  改变深复制对象的值,不会改变原对象的值。

31:TCP的状态

http://blog.51cto.com/jinlong/2065461

32:悲观锁和乐观锁   http://www.javashuo.com/article/p-qpuqpsfi-gk.html

首先介绍一些乐观锁与悲观锁:

  悲观锁:老是假设最坏的状况,每次去拿数据的时候都认为别人会修改,因此每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了不少这种锁机制,好比行锁,表锁等,读锁,写锁等,都是在作操做以前先上锁。再好比Java里面的同步原语synchronized关键字的实现也是悲观锁。

  乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,因此不会上锁,可是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可使用版本号等机制。乐观锁适用于多读的应用类型,这样能够提升吞吐量,像数据库提供的相似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

33:装态码

 200 OK

请求已成功,请求所但愿的响应头或数据体将随此响应返回。出现此状态码是表示正常状态。
 
 
34: 为何TCP 4次挥手期间要等待2MSL

问题

主动发起关闭链接的操做的一方将达到TIME_WAIT状态,并且这个状态要保持Maximum Segment Lifetime的两倍时间。为何要这样作而不是直接进入CLOSED状态?

缘由:

  1. 保证TCP协议的全双工链接可以可靠关闭
  2. 保证此次链接的重复数据段从网络中消失

解释

  1. 若是Client直接CLOSED了,那么因为IP协议的不可靠性或者是其它网络缘由,致使Server没有收到Client最后回复的ACK。那么Server就会在超时以后继续发送FIN,此时因为Client已经CLOSED了,就找不到与重发的FIN对应的链接,最后Server就会收到RST而不是ACK,Server就会觉得是链接错误把问题报告给高层。这样的状况虽然不会形成数据丢失,可是却致使TCP协议不符合可靠链接的要求。因此,Client不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,可以保证对方收到ACK,最后正确的关闭链接。
  2. 若是Client直接CLOSED,而后又再向Server发起一个新链接,咱们不能保证这个新链接与刚关闭的链接的端口号是不一样的。也就是说有可能新链接和老链接的端口号是相同的。通常来讲不会发生什么问题,可是仍是有特殊状况出现:假设新链接和已经关闭的老链接端口号是同样的,若是前一次链接的某些数据仍然滞留在网络中,这些延迟数据在创建新链接以后才到达Server,因为新链接和老链接的端口号是同样的,又由于TCP协议判断不一样链接的依据是socket pair,因而,TCP协议就认为那个延迟的数据是属于新链接的,这样就和真正的新链接的数据包发生混淆了。因此TCP链接还要在TIME_WAIT状态等待2倍MSL,这样能够保证本次链接的全部数据都从网络中消失。

 35: 判断一个链表中是否有环, http://www.javashuo.com/article/p-hmasbovi-ex.html

36: String ,StringBuffer,StringBuilder http://www.javashuo.com/article/p-pzzvfptq-mr.html

 37: jvm何时会进行full gc.

         a:当老年代的最大可用的连续空间大于新生代全部对象的总空间时。 容许minor gc

         b:  当老年代的最大可用的连续空间S小于新生代全部对象的总空间时, 可是开启了HandlePromotionFailure=true设置容许担保失败时,而且S大于历次晋升到老年代对象的平均大小。容许发生minor gc

          c:  jdk1.6以后,HandlePromotionFailure已经再也不使用,只要老年代的最大可用的连续空间大于新生代全部对象的总空间 或者  大于历次晋升到老年代对象的平均大小。容许发生minor gc

         何时会进行full gc.

         d:   老年代的最大可用的连续空间小于历次晋升到老年代对象的平均大小,进行full  gc。

               当老年代的最大可用的连续空间小于新生代全部对象的总空间时,开启了HandlePromotionFailure=false不容许担保失败时,将进行full gc。

38:Spring Boot 启动流程,启动解析

http://www.javashuo.com/article/p-yytkatbe-ew.html

       http://www.javashuo.com/article/p-flhyhcgb-dz.html

Spring 事务原理

http://www.javashuo.com/article/p-pqkcmraz-ce.html

Spring 事务传播机制:http://www.javashuo.com/article/p-fhpapdbr-dg.html

39:elasticsearch 原理

     http://www.javashuo.com/article/p-zksoblfe-bo.html

      倒排索引:http://www.javashuo.com/article/p-dampwjyp-by.html

     倒排索引,和MyISAM的全文检索同样,用单词找文档。单词作键,文档列表做为值。

       单词1:【记录1,记录2】

       单词2:【记录1,记录3,记录5】

       

40:iPv4 和ipv6所包含的字段

        ipv4:  版本号,首部长度,服务类型(将要求低时延,高吞吐量,或可靠性的数据报区别开来),数据报长度,标签,标识,片偏移,寿命,上层协议,校验和,选项,源ip,目的ip,数据。

       ipv6: 版本号,流量类型,流标签,有效载荷长度,跳限制,下一个首部,源ip,目的ip,数据。

     

        tcp:   源端口号,目的端口号,序列号,确认号,校验和,窗口,数据,选项 等。

       udp:源端口号,目的端口号,长度,校验和,数据。

       

41:经常使用linux命令

       http://www.javashuo.com/article/p-gvkrzyvd-m.html

       http://man.linuxde.net/

 42:项目中设置的jvm大小   871.12MB

43: Integer  详解

https://www.jianshu.com/p/9cb9c61b0986

44:  Compable 和Compartor

http://www.javashuo.com/article/p-ofkjiiep-bm.html

 

45:  不使用第三方变量的交换,+-法,异或^

a = a + b;

b = a - b;

a = a - b;

 

46: 方法重载和重写的区别

方法重写(overriding):

  一、也叫子类的方法覆盖父类的方法,要求返回值、方法名和参数都相同。

  二、子类抛出的异常不能超过父类相应方法抛出的异常。(子类异常不能超出父类异常)

  三、子类方法的的访问级别不能低于父类相应方法的访问级别(子类访问级别不能低于父类访问级别)

方法重载(overloading):重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,可是参数却不相同,方法体也不相同,最多见的重载的例子就是类的构造函数,能够参考API帮助文档看看类的构造方法

 

47:线程池

http://www.cnblogs.com/dolphin0520/p/3932921.html

https://blog.csdn.net/cjh94520/article/details/70545202/

为何要有线程池:1:由于线程的建立和销毁cpu开销比较大,2:由于无限制的建立线程池,资源消耗比较大。3:建立线程不是越多越好,必定程度便可。超过必定限度,性能反而会下降  4:稳定性,建立线程的数量受到多个因素的制约,例如JVM启动参数,Thread请求参数中请求的栈大小以及操做系统的支持。若是破坏了这些限制,极可能抛出OutOfMemoryError 。

线程池的好处:

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);

1:maximumPoolSize线程池能建立的最大线程数量>稳定性增强。

2:corePoolSize  核心线程数量,这些线程一直在一个while死循环中运行(从workQueue总获取任务,执行), 其他的线程 (maximumPoolSize-corePoolSize) 个线程,当超过必定时间时,会销毁。这样可以保证资源开销不会太大。

3:long keepAliveTime,TimeUnit unit,  活跃时间和时间单位

4:workQueue  任务队列,当执行exec.execute(task)时,将会将task添加到workQueue中。  而后while循环中的线程,取出任务,最后仍是执行了Runnable.run()。

5:ThreadFactory  线程工厂,用来建立线程

6: handle ,当执行出现错误时,选择的处理策略,a:抛出异常,b:丢弃任务等。

 

线程池的大小http://www.javashuo.com/article/p-qmesfdwy-gh.html

48:spring boot特性,启动流程   http://www.javashuo.com/article/p-yytkatbe-ew.html

Spring 启动流程:http://www.javashuo.com/article/p-kikedxkm-cn.html

http://www.javashuo.com/article/p-flhyhcgb-dz.html

AOP,  DI, IOC

49:Spring 如何保证线程安全的

由于Spring中的Bean实例是单例的, 每一个线程获取的时候,会用一个ThreadLocal为每一个线程建立一个Bean副本进行操做,保证了线程安全。

 50:系统性能瓶颈

http://www.javashuo.com/article/p-yauekoey-cw.html

https://blog.csdn.net/smooth00/article/details/63680191

51:  Spring Boot启动方式

Runner

 

52:  类加载器:

http://www.javashuo.com/article/p-zoasinon-cr.html

 53: 测试工具:JEMTER

 http://www.javashuo.com/article/p-fkdouhnu-nq.html

http://www.javashuo.com/article/p-tvwoymlh-dg.html

测试结果:

首次查询:500次请求须要6秒

第二次查询:500次请求须要3秒

54:高并发写入:

https://segmentfault.com/q/1010000005931313

55: 将某个字段不可持久化修饰符

transient

56:什么是微服务

https://blog.csdn.net/wuxiaobingandbob/article/details/78642020?locationNum=1&fps=1

https://www.oschina.net/news/70121/microservice

57:如何保证线程安全

https://blog.csdn.net/jinggod/article/details/78275763?utm_source=blogxgwz0

https://blog.csdn.net/zhouzhaoxiong1227/article/details/74932180/

58:elasticsearch 优化

 https://yq.aliyun.com/articles/38285

http://www.javashuo.com/article/p-nkkxdaqt-no.html

59:CAS  适合读多写少的场景,例如秒杀活动。

        java.util.concurrent包中的类都是用CAS原理完成的。

60:反射原理:http://www.javashuo.com/article/p-ourbsjow-dz.html

所以咱们就能够经过Class对象去得到成员变量的值,也就是咱们想要获得的变量名、修饰符列表、方法名等等,这就是反射的基本原理

61:分析进程状态的linux命令,查询哪个进程消耗资源过多等

ps  

top

java中的命令jps

 

62:对象锁和类锁的做用范围

http://www.javashuo.com/article/p-kfirwuti-ex.html

63:为何3次握手:

http://blog.51cto.com/zhangxinbei/1829125

64:如何保证多人同时安全修改数据库

      a:   在业务层使用框架自带的事务, 

     b:  在业务层使用锁,防止并发修改

     c:   在数据层(数据库层sql语句)使用事务

      d:   在数据层(数据库层sql语句)使用版本控制

https://bbs.csdn.net/topics/390466595?page=1

https://blog.csdn.net/baimin7657/article/details/8062939

65:先后端交互原理

https://blog.csdn.net/SoftwareTester_zys/article/details/79989956

 http://www.javashuo.com/article/p-vtfefylr-g.html

http://www.cnblogs.com/nalanshawn/p/9351782.html

66:无状态和有状态

http://www.javashuo.com/article/p-dcwrgfzk-gc.html

67:post和put的区别

http://www.javashuo.com/article/p-ywputvlx-gk.html

68: restful和web service 的区别

http://www.javashuo.com/article/p-tepbeyuy-w.html

https://www.zhihu.com/question/28570307

https://blog.csdn.net/angus_17/article/details/80693165

http://www.javashuo.com/article/p-enjuqfer-cb.html

https://blog.csdn.net/angus_17/article/details/80693165

 69:如何防止网站被爬虫

http://www.javashuo.com/article/p-dsjjegga-gv.html

https://bbs.csdn.net/topics/392070282

70:微服务:

微服务就是把不相关的服务构成一个独立单元。服务之间相互调用。

71:形成内存泄漏的缘由.

https://blog.csdn.net/u011479990/article/details/78480091

相关文章
相关标签/搜索