前言/背景
据说往年面试压力特地大,不知真假~
不论面试压力大不大,温习好,该把握的技术点都熟练掌握,珍惜每一次面试机会
明天给大家分享一篇根底的面试题,不要输在这些根底且又常见的问题上
材料总结/刷题指南
这里先自荐一个面试刷题的小程序吧,大家能够收费去刷题,心愿能够帮忙到你。
大家能够扫码返回,也能够微信搜寻【Java面试 | 笑小枫】小程序。继续更新中,后续会上一些资源、简历模板、面试分享内容
面试流程
老面:&和&&有什么区别?
笑小枫:&可用于位运算,当左右两边的条件不是布尔型,而是数字时,它会进行位运算;
当&运算符两侧是是布尔型,且表达式的后果均为真时,整个运算后果才为真;当&&操作符第一个表达式为 false时,后果为 false,并且不再计算第二个表达式,具备短路性能。
老面:||、&&、! 有什么区别?
笑小枫:‘||’是 逻辑或的意思,就是或者,有一个对的就是对的。a||b,示意a表达式或b表达式有一个返回true,则a||b整个表达式返回true。
例:
1==1 || 1==1 //返回true1==1 || 1==2 //返回true1==2 || 1==2 //返回false
‘&&’是逻辑且的意思,就是并且,有一个是错的就是错的。a&&b,示意a表达式或b表达式有一个返回false ,则a&&b整个表达式返回false。如果a表达式为false,则间接返回false,不会再判断b表达式。
例:
1==1 && 1==1 //返回true1==1 && 1==2 //返回false1==2 && 1==2 //返回false
‘!’是逻辑非的意思,就是反转,原来是的对的,加上!后,就变成错的,原来是错的,加上!后,就变成了对的。
!true 返回false
!false 返回true
例:
! (1==1) //返回false! (1==2) //返回true
老面:== 与 equals有什么区别?
笑小枫:能够从性能、定义和运行速度上来说:
- 性能不同
== 既能够比拟根本类型也能够比拟援用类型;对于根本类型,== 比拟的是值;对于援用类型,== 比拟的是地址;
equals不能用于根本类型的比拟;如果没有重写equals,equals就相当于==;如果重写了equals办法,equals比拟的是对象的内容。
留神:重写equals办法的同时,也要重写hashCode,不然同一个对象比拟,可能会呈现hashCode不同,equals比拟的时候先判断hashCode是否雷同,而后再比拟值,如果hashCode不同,则间接认为这两个对象不同。
- 定义不同
equals在JAVA中是一个办法;== 在JAVA中只是一个运算合乎。 - 运行速度不同
== 比equals运行速度快,因为 == 只是比拟援用。
老面:String、StringBuffer 和 StringBuilder 有什么区别?
笑小枫:能够从可变性、线程安全性、性能三方面来说:
- 可变性
String 类中应用 final 关键字字符数组保留字符串,所以 String 对象是不可变的。而 StringBuilder 与StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是应用字符数组保留字符串 char[]value 然而没有用 final 关键字润饰,所以这两种对象都是可变的。
- 线程安全性
String 中的对象是不可变的,也就能够了解为常量,线程平安。StringBuffer 对办法加了同步锁或者对调用的办法加了同步锁,所以是线程平安的。StringBuilder 并没有对办法进行加同步锁,所以是非线程平安的。
- 性能
每次对 String 类型进行扭转的时候,都会生成一个新的 String 对象,而后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象自身进行操作,而不是生成新的对象并扭转对象援用。雷同状况下应用StringBuilder 相比应用 StringBuffer 仅能取得 10%~15% 左右的性能晋升,但却要冒多线程不平安的危险。
对于三者应用的总结:
- 操作大量的数据 = String
- 单线程操作字符串缓冲区下操作大量数据 = StringBuilder
- 多线程操作字符串缓冲区下操作大量数据 = StringBuffer
老面:final、finally、finalize 有什么区别?
笑小枫:final能够润饰类,变量,办法,润饰的类不能被继承,润饰的变量不能从新赋值,润饰的办法不能被重写
finally用于抛异样,finally代码块内语句无论是否产生异样,都会在执行finally,罕用于一些流的敞开。
finalize办法用于垃圾回收。
个别状况下不须要咱们实现finalize,当对象被回收的时候须要开释一些资源,比方socket链接,在对象初始化时创立,整个生命周期内无效,那么须要实现finalize办法,敞开这个链接。
然而当调用finalize办法后,并不意味着gc会立刻回收该对象,所以有可能真正调用的时候,对象又不须要回收了,而后到了真正要回收的时候,因为之前调用过一次,这次又不会调用了,产生问题。所以,不举荐应用finalize办法。
老面:throw 和 throws 有什么区别?
笑小枫:
throw作用在办法内,示意抛出具体异样,由办法体内的语句解决; 肯定抛出异样;
throws作用在办法的申明上,示意抛出异样,由调用者来进行异样解决; 可能出现异常,不肯定会产生异样。
老面:Error 和 Exception 有什么区别?
笑小枫:
Error示意零碎级的谬误和程序不用解决的异样;比方内存溢出、线程死锁、虚拟机谬误等;
Exception示意须要捕获或者须要程序进行解决的异样,是一种设计或实现问题;也就是说,它示意如果程序运行失常,从不会产生的状况;比方IO异样、Sql异样、运行时异样等。
老面:BIO、NIO、AIO 有什么区别?
笑小枫:
BIO:Block IO同步阻塞式IO,就是咱们平时应用的传统IO,它的特点是模式简略使用方便,并发解决能力低。
NIO:Non IO同步非阻塞IO,是传统IO的降级,客户端和服务器端通过Channel(通道)通信,实现了多路复用。
AIO:Asynchronous IO是NIO的降级,也叫NIO2,实现了异步非梗塞IO,异步IO的操作基于事件和回调机制。
BIO是一个连贯一个线程。
NIO是一个申请一个线程。
AIO是一个无效申请一个线程。
BIO:同步并阻塞,服务器实现模式为一个连贯一个线程,即客户端有连贯申请时服务器端就须要启动一个线程进行解决,如果这个连贯不做任何事件会造成不必要的线程开销,当然能够通过线程池机制改善。
NIO:同步非阻塞,服务器实现模式为一个申请一个线程,即客户端发送的连贯申请都会注册到多路复用器上,多路复用器轮询到连贯有I/O申请时才启动一个线程进行解决。
AIO:异步非阻塞,服务器实现模式为一个无效申请一个线程,客户端的I/O申请都是由OS先实现了再告诉服务器利用去启动线程进行解决。
老面:重载(Overload)和重写(Override)有什么区别?
笑小枫:
重载: 产生在同一个类中,办法名必须雷同,参数类型不同、个数不同、程序不同,办法返回值和拜访修饰符能够不同,产生在编译时。
重写: 产生在父子类中,办法名、参数列表必须雷同,返回值范畴小于等于父类,抛出的异样范畴小于等于父类,拜访修饰符范畴大于等于父类;如果父类办法拜访修饰符为 private 则子类就不能重写该办法。
PS:留神这里是类,如果是接口,比方咱们罕用的serviceImpl实现service接口,而后办法上会用@Override
注解,但这并不是重写,而是实现的一种形式。重写是类之间的继承extends
。
老面:成员变量与局部变量有什么区别?
笑小枫:
- 从语法模式上,成员变量是属于类的,局部变量是在办法中定义的变量或是办法的参数;成员变量能够被 public,private,static 等修饰符所润饰,而局部变量不能被访问控制修饰符及 static 润饰;
- 从变量在内存中的存储形式来看,成员变量是对象的一部分,而对象存在于堆内存,局部变量存在于栈内存;
- 从变量在内存中的生存工夫上看,成员变量是对象的一部分,它随着对象的创立而存在,而局部变量随着办法的调用而主动隐没;
- 成员变量如果没有被赋初值,则会主动以类型的默认值而赋值(一种状况例外被 final 润饰的成员变量必须显示地赋值);而局部变量则不会主动赋值。
老面:静态方法和实例办法有什么区别?
笑小枫:
- 在内部调用静态方法时,能够应用"类名.办法名"的形式,也能够应用"对象名.办法名"的形式。而实例办法只有前面这种形式。也就是说,调用静态方法能够无需创建对象。
- 静态方法在拜访本类的成员时,只容许拜访动态成员(即动态成员变量和静态方法),而不容许拜访实例成员变量和实例办法;实例办法则无此限度。
老面:#{}和${}的区别是什么?
笑小枫:
#{}是预编译解决,${}是字符串替换;应用#{}能够无效的避免SQL注入。
Mybatis在解决#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set办法来赋值;
Mybatis在解决${}时,就是把${}替换成变量的值。例如传入表名、SQL片段,排序字段等场景。存在sql注入问题,请审慎应用!
老面:线程的run()和start()有什么区别?
笑小枫:
start() 办法用于启动线程,run() 办法用于执行线程的运行时代码。run() 能够反复调用,而 start() 只能调用一次。
start()办法来启动一个线程,真正实现了多线程运行。调用start()办法无需期待run办法体代码执行结束,能够间接继续执行其余的代码; 此时线程是处于就绪状态,并没有运行。 而后通过此Thread类调用办法run()来实现其运行状态, run()办法运行完结, 此线程终止。而后CPU再调度其它线程。
run()办法是在本线程里的,只是线程里的一个函数,而不是多线程的。 如果间接调用run(),其实就相当于是调用了一个一般函数而已,间接待用run()办法必须期待run()办法执行结束能力执行上面的代码,所以执行门路还是只有一条,基本就没有线程的特色,所以在多线程执行时要应用start()办法而不是run()办法。
老面:Synchronized 和 ReentrantLock 区别是什么?
笑小枫:
- 实现原理上
synchronized
是依附jvm
以及配合操作系统来实现,是一个关键字。 reentrantLock
是jdk1.5
之后提供的API层面的互斥锁。
- 应用便利性上
synchronized
只须要增加上相干关键字即可,加锁与开释过程由操作系统实现。 reentrantLock
则须要手动加锁与开释锁。
- 锁粒度与灵便度
reentrantLock
要强于synchronized
reentrantLock
提供了三个高级性能:
- 期待可中断,持有锁的线程长期不开释的时候,正在期待的线程能够抉择放弃期待,这相当于Synchronized来说能够避免出现死锁的状况。通过
lock.lockInterruptibly()
来实现这个机制。 - 多个线程期待同一个锁时,必须依照申请锁的工夫程序取得锁,Synchronized锁非偏心锁,
ReentrantLock
默认的构造函数是创立的非偏心锁,能够通过参数true设为偏心锁,但偏心锁体现的性能不是很好。 - 一个
ReentrantLock
对象能够同时绑定对个对象。ReenTrantLock
提供了一个Condition(条件)类,用来实现分组唤醒须要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全副线程。
- 性能区别
synchronized
优化之后性能与reentrantLock
曾经并驾齐驱了,官网甚至更倡议应用synchronized
关键字。
老面:get 和 post 申请有哪些区别?
笑小枫:
- get申请参数是连贯在url前面的,而post申请参数是寄存在request body内的;
- get申请因为浏览器对url长度有限度,所以参数个数有限度,而post申请参数个数没有限度;
- 因为get申请参数裸露在url上,所以平安方面post比get更加平安;
- get申请只能进行url编码,而post申请能够反对多种编码方式;
- get申请参数会保留在浏览器历史记录内,post申请并不会;
- get申请浏览器会被动cache,post并不会,除非被动设置;
- get申请产生1个tcp数据包,post申请产生2个tcp数据包;
- 在浏览器进行回退操作时,get申请是有害的,而post申请则会从新申请一次;
- 浏览器在发送get申请时会将header和data一起发送给服务器,服务器返回200状态码,而在发送post申请时,会先将header发送给服务器,服务器返回100,之后再将data发送给服务器,服务器返回200 OK。
老面:forward 和 redirect 的区别?
笑小枫:
- forward是间接申请转发;redirect是间接申请转发,又叫重定向。
- forward,客户端和浏览器执行一次申请;redirect,客户端和浏览器执行两次申请。
- forward,经典的MVC模式就是forward;redirect,用于防止用户的非正常拜访。(例如用户非正常拜访,servlet就能够将HTTP申请重定向到登录页面)。
- forward,地址不变;redirect,地址扭转。
- forward罕用办法:RequestDispatcher类的forward()办法;redirect罕用办法:HttpServletRequest类的sendRedirect()办法。
老面:session 和 cookie 有什么区别?
笑小枫:
- 存储地位不同
- cookie在客户端浏览器;
- session在服务器;
- 存储容量不同
- cookie<=4K,一个站点最多保留20个cookie;
- session没有上线,出于对服务器的爱护,session内不可存过多货色,并且要设置session删除机制;
- 存储形式不同
- cookie只能保留ASCII字符串,并须要通过编码方式存储为Unicode字符或者二进制数据;
- session中能存储任何类型的数据,包含并不局限于String、integer、list、map等;
- 隐衷策略不同
- cookie对客户端是可见的,不平安;
- session存储在服务器上,平安;
- 有效期不同
- 开发能够通过设置cookie的属性,达到使cookie长期有效的成果;
- session依赖于名为JESSIONID的cookie,而cookie JSESSIONID的过期工夫默认为-1,只需敞开窗口该session就会生效,因此session达不到长期有效的成果;
- 跨域反对上不同
- cookie反对跨域;
- session不反对跨域。
寄语
本文到此就完结了,心愿本文能够帮忙到你,心愿你能够找到一个称心的工作
如果须要简历模板或者进行面试领导,能够关注【笑小枫】公众号私聊我哈