首页 课程 师资 教程 报名

史上最全的中高级JAVA工程师面试题及答案(三)

  • 2019-10-18 11:32:54
  • 2223次 动力节点

 

今天动力节点java培训机构小编为大家汇总了史上最全的中高级JAVA工程师面试题及答案(三),分别是java设计模式面试题、JDK源码面试题及java RPC面试题,希望能够帮助到正在找工作的中高级JAVA程序员,下面就随小编一起来看看吧。


timg.jpg

java设计模式面试题


  53、单例模式


  (1)懒汉模式-非安全 懒汉模式(线程不安全,可能出现多个Singleton 实例)


public class Singleton { 

    private static Singleton instance; 

    private Singleton (){} 


    public static Singleton getInstance() { 

            if (instance == null) { 

           instance = new Singleton(); 

            } 

            return instance; 

    } 

}


  (2)懒汉模式-安全 懒汉模式 (线程安全)


public class Singleton { 

    private static Singleton instance; 

private Singleton (){} 


    public static synchronized Singleton getInstance() { 

            if (instance == null) { 

             instance = new Singleton(); 

            } 

            return instance; 

    } 

}  


(3)饿汉模式


public class Singleton { 

    private static Singleton instance = new Singleton(); 

    private Singleton (){} 

    public static Singleton getInstance() { 

         return instance; 

    } 

}


  (4)饿汉模式(变种) 饿汉(变种,跟第三种差不多,都是在类初始化即实例化instance)


public class Singleton { 

    private Singleton instance = null; 

    static { 

            instance = new Singleton(); 

    } 

    private Singleton (){} 

    public static Singleton getInstance() { 

            return this.instance; 

    } 

}


   (5)静态内部类,跟三四有细微差别:Singleton类被装载instance不一定被初始化,因为内部类SingletonHolder没有被主动使用,只有显示调用getInstance才会显示装载SingletonHolder 类,从而实例化instance


public class Singleton { 

    private static class SingletonHolder { 

         private static final Singleton INSTANCE = new Singleton(); 

    } 

    private Singleton (){} 

    public static final Singleton getInstance() { 

         return SingletonHolder.INSTANCE; 

    } 

}   


  (6)枚举(既可以避免多线程同步问题,还可以防止被反序列化重建对象)


public enum Singleton { 

    INSTANCE;

public void whateverMethod() {



public static void main(String[] args) {

        Singleton s = Singleton.INSTANCE;

        Singleton s2 = Singleton.INSTANCE;

        System.out.println(s==s2);

}


}


  输出结果:true   


说明这种方式创建的对象是同一个,因为枚举类中的INSTANCE是static final类型的,只能被实例化一次。对于Enum中每一个枚举实例,都是相当于一个单独的Singleton实例。所以借用 《Effective Java》一书中的话, 单元素的枚举类型已经成为实现Singleton的最佳方法


  (7)懒汉升级版


public class Singleton { 

    private volatile static Singleton singleton; 

    private Singleton (){} 

    public static Singleton getSingleton() { 

            if (singleton == null) { 

                synchronized (Singleton.class) { 

                    if (singleton == null) { 

                            singleton = new Singleton(); 

                    } 

                } 

            } 

            return singleton; 

        } 

}


  策略模式


1571370099439812.jpg


  JDK源码面试题


  54、ThreadLocal的实现原理


  ThreadLocal的实现原理,有什么缺点?跟线程池结合使用要注意什么


1571370356269407.jpg


  原理:Current Thread当前线程中有一个ThreadLocalMap对象,它的key是ThreadLocal的弱引用,Value是ThreadLocal调用set方法设置的对象值。每一个线程维护一个各自的ThreadLocalMap,所以多个线程之间变量相互隔离,互不干扰。


  缺点:存在内存泄漏问题,因为当ThreadLocal设置为null后,ThreadLocalMap的key的弱引用指向了null,又没有任何的强引用指向threadlocal,所以threadlocal会被GC回收掉。但是,ThreadLocalMap的Value不会被回收,CurrentThread当前线程的强引用指向了ThreadLocalMap,进而指向了这个Entry,所以只有当currentThread结束强引用断开后,currentThread、ThreadLocalMap、Entry将全部被GC回收。 


所以结论是:只要currentThread被GC回收,就不会出现内存泄漏。但是在currentThread被GC回收之前,threadlocal设置为null之后的这段时间里,Value不会被回收,比如当使用线程池的时候,线程结束不会被GC回收,会被继续复用,那这个Value肯定还会继续存在。如果这个Value很大的情况下,可能就会内存泄漏。虽然threadlocal的set和get方法执行时会清除key为null的value,但是如果当前线程在使用中没有调用threadlocal的set或者get方法一样可能会内存泄漏。


  跟线程池结合使用的注意事项:因为线程池中线程复用的情况,本次的threadlocal中可能已经存在数据,所以上一次使用完threadlocal的变量后,要调用threadlocal的remove方法清除value。而且要注意调用完remove后应该保证不会再调用get方法。


  55、AQS实现公平锁和非公平锁


  基于AQS的锁(比如ReentrantLock)原理大体是这样:


  (1)有一个state变量,初始值为0,假设当前线程为A,每当A获取一次锁,status++. 释放一次,status--.锁会记录当前持有的线程。


  (2)当A线程拥有锁的时候,status>0. B线程尝试获取锁的时候会对这个status有一个CAS(0,1)的操作,尝试几次失败后就挂起线程,进入一个等待队列。


  (3)如果A线程恰好释放,--status==0, A线程会去唤醒等待队列中第一个线程,即刚刚进入等待队列的B线程,B线程被唤醒之后回去检查这个status的值,尝试CAS(0,1),而如果这时恰好C线程也尝试去争抢这把锁。


  非公平锁实现:C直接尝试对这个status CAS(0,1)操作,并成功改变了status的值,B线程获取锁失败,再次挂起,这就是非公平锁,B在C之前尝试获取锁,而最终是C抢到了锁。


 公平锁:C发现有线程在等待队列,直接将自己进入等待队列并挂起,B获取锁



  java RPC面试题


  56、RPC的序列化方式有哪些


  (1)Thrift---facebook ProtoBuf---google 


(2)Hessian 


(3)AVA原生的序列化接口 


(4)Json/xml


  57、服务熔断与服务降级概念


  服务熔断:


  一般指某个服务的下游服务出现问题时采用的手段,而服务降级一般是从整体层面考虑的。下游服务出现问题时可以进行服务熔断。


  对于目标服务的请求和调用大量超时或失败,这时应该熔断该服务的所有调用,并且对于后续调用应直接返回,从而快速释放资源,确保在目标服务不可用的这段时间内,所有对它的调用都是立即返回,不会阻塞的。再等到目标服务好转后进行接口恢复。


  服务降级:


  当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。



  58、JAVA线程执行中怎么kill掉


  (1)通过设置全局变量标志来控制线程的任务执行完成.进而销毁线程 


(2) 如果线程处于长久的阻塞状态,可以interrupt脱离线程阻塞状态跳出程序体


  59、HA主备怎么预防脑裂


  一般采用2个方法


  (1)仲裁 当两个节点出现分歧时,由第3方的仲裁者决定听谁的。这个仲裁者,可能是一个锁服务,一个共享盘或者其它什么东西。


  (2)fencing 当不能确定某个节点的状态时,通过fencing把对方干掉,确保共享资源被完全释放,前提是必须要有可靠的fence设备。


  60、性别字段是否需要加索引


1、聚集索引,叶子节点存储行记录,InnoDB索引和记录是存储在一起的。


2、普通索引,叶子节点存储了主键的值。在InnoDB引擎中每个表都会有一个聚集索引,如果表定义了主键,那主键就是聚集索引.一个表只有一个聚集索引,其余为普通索引.如果性别sex字段定义为普通的索引,那么在使用普通索引查询时,会先加载普通索引,通过普通索引查询到实际行的主键,用主键通过聚集索引去查询最终的行. 如果不对sex性别字段加索引,那么查找过程就是直接全表扫描查询到聚集索引定位到行,而不需要普通索引和聚集索引的切换,所以效率可能更高一点。

  

1.png

  61、Https的SSL握手过程


  Https协议由两部分组成:http+ssl,即在http协议的基础上增加了一层ssl的握手过程.


  (1)浏览器作为发起方,向网站发送一套浏览器自身支持的加密规则,比如客户端支持的加密算法,Hash算法,ssl版本,以及一个28字节的随机数client_random


  (2)网站选出一套加密算法和hash算法,生成一个服务端随机数server_random并以证书的形式返回给客户端浏览器,这个证书还包含网站地址、公钥public_key、证书的颁发机构CA以及证书过期时间。


  (3)浏览器解析证书是否有效,如果无效则浏览器弹出提示框告警。如果证书有效,则根据server_random生成一个preMaster_secret和Master_secret[会话密钥], master_secret 的生成需要 preMaster_key ,并需要 client_random 和 server_random 作为种子。浏览器向服务器发送经过public_key加密的preMaster_secret,以及对握手消息取hash值并使用master_secret进行加密发送给网站.[客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验]


  (4)服务器使用private_key 解密后得到preMaster_secret,再根据client_random 和 server_random 作为种子得到master_secret.然后使用master_secret解密握手消息并计算hash值,跟浏览器发送的hash值对比是否一致. 然后把握手消息通过master_secret进行对称加密后返回给浏览器.以及把握手消息进行hash且master_secret加密后发给浏览器.[服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。]


  (5)客户端同样可以使用master_secret进行解密得到握手消息.校验握手消息的hash值是否跟服务器发送过来的hash值一致,一致则握手结束.通信开始


  (6)以后的通信都是通过master_secret+对称加密算法的方式进行. 客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用"会话密钥"加密内容。SSL握手过程中如果有任何错误,都会使加密连接断开,从而阻止了隐私信息的传输


2_meitu_17.jpg


  非对称加密算法:RSA,DSA/DSS 对称加密算法:AES,RC4,3DES HASH算法:MD5,SHA1,SHA256 



  62、select和epoll的区别


  (1)select有最大并发数限制,默认最大文件句柄数1024,可修改。epoll没有最大文件句柄数限制,仅受系统中进程能打开的最大文件句柄限制。


(2)select效率低,每次都要线性扫描其维护的fd_set集合。epoll只在集合不为空才轮训 


(3)select存在内核空间和用户空间的内存拷贝问题。  


epoll中减少内存拷贝,mmap将用户空间的一块地址和内核空间的一块地址同时映射到相同的一块物理内存地址


  NIO使用的多路复用器是epoll


  63、Epoll导致的selector空轮询


  Java NIO Epoll 会导致 Selector 空轮询,最终导致 CPU 100%   


官方声称在 JDK 1.6 版本的 update18 修复了该问题,但是直到 JDK 1.7 版本该问题仍旧存在,只不过该 BUG 发生概率降低了一些而已,它并没有得到根本性解决 Netty的解决方案:


  对 Selector 的 select 操作周期进行统计,每完成一次空的 select 操作进行一次计数,若在某个周期内连续发生 N 次空轮询,则判断触发了 Epoll 死循环 Bug。


  然后,Netty 重建 Selector 来解决。判断是否是其他线程发起的重建请求,若不是则将原 SocketChannel 从旧的 Selector 上取消注册,然后重新注册到新的 Selector 上,最后将原来的 Selector 关闭。


  64、正排索引和倒排索引


  正排索引


  也叫正向索引,正排表是以document文档的ID为关键字,记录了document文档中所有的关键字keyword的信息,所以在查找某个keyword的时候,会扫描正排表中每个document文档,直到查出所有包含keyword的文档。图示:


2_meitu_18.jpg

 

  倒排索引


  也叫反向索引,倒排表示以keyword关键字建立索引,关键词keyword所对应的的表项记录了出现这个keyword的所有文档。表项包含了该文档的ID和在该文档中出现的位置情况。倒排表一次可以查出keyword关键字对应的所有文档,效率高于正排表。


  1_meitu_19.jpg


  正排索引是从文档到关键字的映射(已知文档求关键字) 倒排索引是从关键字到文档的映射(已知关键字求文档)


中高级JAVA工程师面试题及答案


以上就是动力节点java培训机构小编介绍的“史上最全的中高级JAVA工程师面试题及答案”的内容,希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为你服务。


由于“史上最全的中高级JAVA工程师面试题及答案”内容太多,本文已满,请看下文链接:


1~24道中高级JAVA工程师面试题及答案请看链接:http://www.bjpowernode.com/javazixun/2169.html


25~52道中高级JAVA工程师面试题及答案请看链接:http://www.bjpowernode.com/javazixun/2191.html


相关推荐


面试题总结—高级Java工程师面试题


Java高级开发工程师面试题


秋招中高级Java面试题,10道详解,死磕就对了


最新Java工程师面试题整理[社招篇]


大家都在收藏的中级常见Java工程师面试题


腾讯Java高级工程师高频面试题



选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交