2020年你可能遇到的高频面试题,Java中高级面试题(含答案)!

2019很苦逼,我下定决心在今年的金三银四跳槽找个满意的工作。这也是我制定了一年的目标。通过不断的积累,把所遇到的面试题都整理一下。方便复习回顾。
在这里插入图片描述
Java中高级的面试

接口有什么用

1、通过接口可以实现不相关类的相同行为,而不需要了解对象所对应的类。
2、通过接口可以指明多个类需要实现的方法。
3、通过接口可以了解对象的交互界面,而不需了解对象所对应的类。
另:Java是单继承,接口可以使其实现多继承的功能

说说http,https协议

HTTP:
是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。

HTTPS:
是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。

区别:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

说说tcp/ip协议族

TCP/IP协议族是一个四层协议系统,自底而上分别是数据链路层、网络层、传输层和应用层。每一层完成不同的功能,且通过若干协议来实现,上层协议使用下层协议提供的服务。

1、数据链路层负责帧数据的传递。
2、网络层责数据怎样传递过去。
3、传输层负责传输数据的控制(准确性、安全性)
4、应用层负责数据的展示和获取。

tcp五层网络协议

物理层:
为数据端设备提供传送数据的通路,数据通路可以是一个物理媒体,也可以是多个物理媒体连接而成。

数据链路层:
为网络层提供数据传送服务。

网络层:
路由选择和中继、激活,终止网络连接、在一条数据链路上复用多条网络连接,多采取分时复用技术 、差错检测与恢复、排序,流量控制、服务选择、网络管理 。

传输层:
传输层是两台计算机经过网络进行数据通信时,第一个端到端的层次,具有缓冲作用。

扫描二维码关注公众号,回复: 11702781 查看本文章

应用层:
应用层向应用程序提供服务

TCP与UDP的区别

1、基于连接与无连接
2、TCP要求系统资源较多,UDP较少;
3、UDP程序结构较简单
4、流模式(TCP)与数据报模式(UDP);
5、TCP保证数据正确性,UDP可能丢包
6、TCP保证数据顺序,UDP不保证
在这里插入图片描述

cookie和session的区别,分布式环境怎么保存用户状态

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

分布式环境下的session(举例两种):

服务器session复制

原理:任何一个服务器上的session发生改变(增删改),该节点会把这个 session的所有内容序列化,然后广播给所有其它节点,不管其他服务器需不需要session,以此来保证Session同步。
优点:可容错,各个服务器间session能够实时响应。
缺点:会对网络负荷造成一定压力,如果session量大的话可能会造成网络堵塞,拖慢服务器性能。

session共享机制

使用分布式缓存方案比如memcached、redis,但是要求Memcached或Redis必须是集群。

GIT和SVN的区别

1、GIT是分布式的,SVN不是。
2、GIT把内容按元数据方式存储,而SVN是按文件。
3、GIT分支和SVN的分支不同。
4、GIT没有一个全局的版本号,而SVN有。
5、GIT的内容完整性要优于SVN。
(一般问会不会用,知道这些区别貌似也没卵用)

请写一段栈溢出、堆溢出的代码

递归调用可以导致栈溢出
不断创建对象可以导致堆溢出

代码如下:

public class Test {
    
      
 
   public void testHeap(){
    
      
       for(;;){
    
      
             ArrayList list = new ArrayList (2000);  
         }  
   }  
   int num=1;  
   public void testStack(){
    
      
       num++;  
       this.testStack();  
    }  
     
   public static void main(String[] args){
    
      
       Test  t  = new Test ();  
       t.testHeap();  
       t.testStack();     
   }  
}

在这里插入图片描述

springmvc的核心是什么,请求的流程是怎么处理的,控制反转怎么实现的

核心:
控制反转和面向切面

请求处理流程:
1、首先用户发送请求到前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;
2、页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);
3、前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;
4、前端控制器再次收回控制权,将响应返回给用户。

控制反转如何实现:
我们每次使用spring框架都要配置xml文件,这个xml配置了bean的id和class。
spring中默认的bean为单实例模式,通过bean的class引用反射机制可以创建这个实例。

因此,spring框架通过反射替我们创建好了实例并且替我们维护他们。
A需要引用B类,spring框架就会通过xml把B实例的引用传给了A的成员变量。

mybatis如何处理结果集

MyBatis的结果集是通过反射来实现的。并不是通过get/set方法。在实体类中无论是否定义get/set()方法,都是可以接收到的。

如果面试只是考你这个点的话就恭喜了。如果继续深问流程,那就需要自己找一些源码来阅读了。

java的多态表现在哪里

主要有两种表现形式:重载和重写

重载:
是发生在同一类中,具有相同的方法名,主要是看参数的个数,类型,顺序不同实现方法的重载的,返回值的类型可以不同。

重写:
是发生在两个类中(父类和子类),具有相同的方法名,主要看方法中参数,个数,类型必须相同,返回值的类型必须相同。

List和Set比较,各自的子类比较

对比一:Arraylist与LinkedList的比较

1、ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的)。

2、因为地址连续, ArrayList要移动数据,所以插入和删除操作效率比较低。

3、LinkedList基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址,对于新增和删除操作add和remove,LinedList比较占优势。

4、因为LinkedList要移动指针,所以查询操作性能比较低。

适用场景分析:

当需要对数据进行对此访问的情况下选用ArrayList,当需要对数据进行多次增加删除修改时采用LinkedList。

对比二:ArrayList与Vector的比较

1、Vector的方法都是同步的,是线程安全的,而ArrayList的方法不是,由于线程的同步必然要影响性能。因此,ArrayList的性能比Vector好。

2、当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样。ArrayList就有利于节约内存空间。

3、大多数情况不使用Vector,因为性能不好,但是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性。

4、Vector可以设置增长因子,而ArrayList不可以。

适用场景分析:

1、Vector是线程同步的,所以它也是线程安全的,而ArrayList是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用ArrayList效率比较高。

2、如果集合中的元素的数目大于目前集合数组的长度时,在集合中使用数据量比较大的数据,用Vector有一定的优势。

对比三:HashSet与TreeSet的比较

1.TreeSet 是二叉树实现的,Treeset中的数据是自动排好序的,不允许放入null值 。

2.HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束 。

3.HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例。

适用场景分析:

HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。
在这里插入图片描述

HashMap和ConcurrentHashMap的区别

1、HashMap不是线程安全的,而ConcurrentHashMap是线程安全的。
2、ConcurrentHashMap采用锁分段技术,将整个Hash桶进行了分段segment,也就是将这个大的数组分成了几个小的片段segment,而且每个小的片段segment上面都有锁存在,那么在插入元素的时候就需要先找到应该插入到哪一个片段segment,然后再在这个片段上面进行插入,而且这里还需要获取segment锁。

3、ConcurrentHashMap让锁的粒度更精细一些,并发性能更好。

至于两者的底层实现,你如果想通过一篇文章就理解了,那就too young了,好好找些博文+看源码去吧。

HashTable和ConcurrentHashMap的区别

它们都可以用于多线程的环境,但是当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。因为ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅需要锁定map的某个部分,而其它的线程不需要等到迭代完成才能访问map。简而言之,在迭代的过程中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。

String,StringBuffer和StringBuilder的区别

1、运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String。

2、线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的。

适用场景分析:

String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

wait和sleep的区别

1、sleep()方法是属于Thread类中的,而wait()方法,则是属于Object类中的。

2、sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线程,但是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。所以在调用sleep()方法的过程中,线程不会释放对象锁。

3、调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

这篇文章写了挺久,如果觉得有收获,点赞评论收藏三连击哦,也欢迎关注我的微信公众号『java耕耘者』哦。一大波算法文章向你走来。

看完有收获?那么希望老铁别吝啬你的三连击哦
1、点赞,可以让更多的人看到这篇文章
2、关注我的原创微信公众号『Java耕耘者』,第一时间阅读我的文章。公众号后台回复『Java』,还送你一份面试视频大礼包哦。
3、也欢迎关注我的博客哦。

猜你喜欢

转载自blog.csdn.net/a646705816/article/details/103945832