JAVA中高级工程师面试题库.docx
《JAVA中高级工程师面试题库.docx》由会员分享,可在线阅读,更多相关《JAVA中高级工程师面试题库.docx(52页珍藏版)》请在冰豆网上搜索。
JAVA中高级工程师面试题库
华坤集团
JAVA面试题库
【中高级开发工程师适用】
2020-7-28
IT流程部刊印
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五层网络协议
物理层:
为数据端设备提供传送数据的通路,数据通路可以是一个物理媒体,也可以是多个物理媒体连接而成。
数据链路层:
为网络层提供数据传送服务。
网络层:
路由选择和中继、激活,终止网络连接、在一条数据链路上复用多条网络连接,多采取分时复用技术、差错检测与恢复、排序,流量控制、服务选择、网络管理。
传输层:
传输层是两台计算机经过网络进行数据通信时,第一个端到端的层次,具有缓冲作用。
应用层:
应用层向应用程序提供服务
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。
(一般问会不会用,知道这些区别貌似也没卵用)
请写一段栈溢出、堆溢出的代码
递归调用可以导致栈溢出
不断创建对象可以导致堆溢出
代码如下:
publicclassTest{
publicvoidtestHeap(){
for(;;){
ArrayListlist=newArrayList(2000);
}
}
intnum=1;
publicvoidtestStack(){
num++;
this.testStack();
}
publicstaticvoidmain(String[]args){
Testt=newTest();
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让锁的粒度更精细一些,并发性能更好。
至于两者的底层实现,你如果想通过一篇文章就理解了,那就tooyoung了,好好找些博文+看源码去吧。
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面试题大全(2020版)
一、Java基础
1.JDK和JRE有什么区别?
JDK:
JavaDevelopmentKit的简称,java开发工具包,提供了java的开发环境和运行环境。
JRE:
JavaRuntimeEnvironment的简称,java运行环境,为java的运行提供了所需环境。
具体来说JDK其实包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具。
简单来说:
如果你需要运行java程序,只需安装JRE就可以了,如果你需要编写java程序,需要安装JDK。
2.==和equals的区别是什么?
==解读
对于基本类型和引用类型==的作用效果是不同的,如下所示:
基本类型:
比较的是值是否相同;
引用类型:
比较的是引用是否相同;
代码示例:
Stringx="string";
Stringy="string";
Stringz=newString("string");
System.out.println(x==y);//true
System.out.println(x==z);//false
System.out.println(x.equals(y));//true
System.out.println(x.equals(z));//true
代码解读:
因为x和y指向的是同一个引用,所以==也是true,而newString()方法则重写开辟了内存空间,所以==结果为false,而equals比较的一直是值,所以结果都为true。
equals解读
equals本质上就是==,只不过String和Integer等重写了equals方法,把它变成了值比较。
看下面的代码就明白了。
首先来看默认情况下equals比较一个有相同值的对象,代码如下:
classCat{
publicCat(Stringname){
this.name=name;
}
privateStringname;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
}
Catc1=newCat("王磊");
Catc2=newCat("王磊");
System.out.println(c1.equals(c2));//false
输出结果出乎我们的意料,竟然是false?
这是怎么回事,看了equals源码就知道了,源码如下:
publicbooleanequals(Objectobj){
return(this==obj);
}
原来equals本质上就是==。
那问题来了,两个相同值的String对象,为什么返回的是true?
代码如下:
Strings1=newString("老王");
Strings2=newString("老王");
System.out.println(s1.equals(s2));//true
同样的,当我们进入String的equals方法,找到了答案,代码如下:
publicbooleanequals(ObjectanObject){
if(this==anObject){
returntrue;
}
if(anObjectinstanceofString){
StringanotherString=(String)anObject;
intn=value.length;
if(n==anotherString.value.length){
charv1[]=value;
charv2[]=anotherString.value;
inti=0;
while(n--!
=0){
if(v1[i]!
=v2[i])
returnfalse;
i++;
}
returntrue;
}
}
returnfalse;
}
原来是String重写了Object的equals方法,把引用比较改成了值比较。
总结 :
==对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而equals默认情况下是引用比较,只是很多类重新了equals方法,比如String、Integer等把它变成了值比较,所以一般情况下equals比较的是值是否相等。
3.两个对象的hashCode()相同,则equals()也一定为true,对吗?
不对,两个对象的hashCode()相同,equals()不一定true。
代码示例:
Stringstr1="通话";
Stringstr2="重地";
System.out.println(String.format("str1:
%d|str2:
%d",str1.hashCode(),str2.hashCode()));
System.out.println(str1.equals(str2));
执行的结果:
str1:
1179395|str2:
1179395
false
代码解读:
很显然“通话”和“重地”的hashCode()相同,然而equals()则为false,因为在散列表中,hashCode()相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。
4.final在java中有什么作用?
final修饰的类叫最终类,该类不能被继承。
final修饰的方法不能被重写。
final修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
5.java中的Math.round(-1.5)等于多少?
等于-1,因为在数轴上取值时,中间值(0.5)向右取整,所以正0.5是往上取整,负0.5是直接舍弃。
6.String属于基础的数据类型吗?
String不属于基础类型,基础类型有8种:
byte、boolean、char、short、int、float、long、double,而String属于对象。
7.java中操作字符串都有哪些类?
它们之间有什么区别?
操作字符串的类有:
String、StringBuffer、StringBuilder。
String和StringBuffer、StringBuilder的区别在于String声明的是不可变的对象,每次操作都会生成新的String对象,然后将指针指向新的String对象,而StringBuffer、StringBuilder可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用String。
StringBuffer和StringBuilder最大的区别在于,StringBuffer是线程安全的,而StringBuilder是非线程安全的,但StringBuilder的性能却高于StringBuffer,所以在单线程环境下推荐使用StringBuilder,多线程环境下推荐使用StringBuffer。
8.Stringstr="i"与Stringstr=newString("i")一样吗?
不一样,因为内存的分配方式不一样。
Stringstr="i"的方式,java虚拟机会将其分配到常量池中;而Stringstr=newString("i")则会被分到堆内存中。
9.如何将字符串反转?
使用StringBuilder或者stringBuffer的reverse()方法。
示例代码:
//StringBufferreverse
StringBufferstringBuffer=newStringBuffer();
stringBuffer.append("abcdefg");
System.out.println(stringBuffer.reverse());//gfedcba
//StringBuilderreverse
StringBuilderstringBuilder=newStringBuilder();
stringBuilder.append("abcdefg");
System.out.println(stringBuilder.reverse());//gfedcba
10.String类的常用方法都有那些?
indexOf():
返回指定字符的索引。
charAt():
返回指定索引处的字符。
replace():
字符串替换。
trim():
去除字符串两端空白。
split():
分割字符串,返回一个分割后的字符串数组。
getBytes():
返回字符串的byte类型数组。
length():
返回字符串长度。
toLowerCase():
将字符串转成小写字母。
toUpperCase():
将字符串转成大写字符。
substring():
截取字符串。
equals():
字符串比较。
11.抽象类必须要有抽象方法吗?
不需要,抽象类不一定非要有抽象方法。
示例代码:
abstractclassCat{
publicstaticvoidsayHi(){
System.out.println("hi~");
}
}
上面代码,抽象类并没有抽象方法但完全可以正常运行。
12.普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法。
抽象类不能直接实例化,普通类可以直接实例化。
13.抽象类能使用final修饰吗?
不能,定义抽象类就是让其他类继承的,如果定义为final该类就不能被继承,这样彼此就会产生矛盾,所以final不能修饰抽象类,如下图所示,编辑器也会提示错误信息:
14.接口和抽象类有什么区别?
实现:
抽象类的子类使用extends来继承;接口必须使用implements来实现接口。
构造函数:
抽象类可以有构造函数;接口不能有。
main方法:
抽象类可以有main方法,并且我们能运行它;接口不能有main方法。
实现数量:
类可以实现很多个接口;但是只能继承一个抽象类。
访问修饰符:
接口中的方法默认使用public修饰;抽象类中的方法可以是任意访问修饰符。
15.java中IO流分为几种?
按功能来分:
输入流(input)、输出流(output)。
按类型来分:
字节流和字符流。
字节流和字符流的区别是:
字节流按8位传输以字节为单位输入输出数据,字符流按16位传输以字符为单位输入输出数据。
16.BIO、NIO、AIO有什么区别