前言 / 背景
据说往年面试压力特地大,不知真假~
不论面试压力大不大,温习好,该把握的技术点都熟练掌握,珍惜每一次面试机会
明天给大家分享一篇根底的面试题,不要输在这些根底且又常见的问题上
材料总结 / 刷题指南
这里先自荐一个面试刷题的小程序吧,大家能够收费去刷题,心愿能够帮忙到你。
大家能够扫码返回,也能够微信搜寻 【Java 面试 | 笑小枫】 小程序。继续更新中,后续会上一些资源、简历模板、面试分享内容
面试流程
老面👴:& 和 && 有什么区别?
笑小枫🍁:& 可用于位运算,当左右两边的条件不是布尔型,而是数字时,它会进行位运算;
当 & 运算符两侧是是布尔型,且表达式的后果均为真时,整个运算后果才为真;当 && 操作符第一个表达式为 false 时,后果为 false,并且不再计算第二个表达式,具备短路性能。
老面👴:||、&&、! 有什么区别?
笑小枫🍁:‘||’是 逻辑或的意思,就是或者,有一个对的就是对的。a||b, 示意 a 表达式或 b 表达式有一个返回 true, 则 a || b 整个表达式返回 true。
例:
1==1 || 1==1 // 返回 true
1==1 || 1==2 // 返回 true
1==2 || 1==2 // 返回 false
‘&&’是逻辑且的意思,就是并且,有一个是错的就是错的。a&&b, 示意 a 表达式或 b 表达式有一个返回 false , 则 a &&b 整个表达式返回 false。如果 a 表达式为 false,则间接返回 false,不会再判断 b 表达式。
例:
1==1 && 1==1 // 返回 true
1==1 && 1==2 // 返回 false
1==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 不反对跨域。
寄语
本文到此就完结了,心愿本文能够帮忙到你,心愿你能够找到一个称心的工作
如果须要 简历模板 或者进行 面试领导,能够关注【笑小枫】公众号私聊我哈