龙空技术网

【面试篇】Java面试中xx与xx之间有什么区别,本文汇总详解

笑小枫 46

前言:

而今小伙伴们对“java两个对象比较”大体比较珍视,姐妹们都需要学习一些“java两个对象比较”的相关知识。那么小编在网摘上收集了一些关于“java两个对象比较””的相关资讯,希望姐妹们能喜欢,兄弟们快快来学习一下吧!

前言/背景

据说今年面试压力特别大,不知真假~

不管面试压力大不大,复习好,该掌握的技术点都熟练掌握,珍惜每一次面试机会

今天给大家分享一篇基础的面试题,不要输在这些基础且又常见的问题上

image-20230315192849401

资料总结/刷题指南

image-20230315193002814

这里先自荐一个面试刷题的小程序吧,大家可以免费去刷题,希望可以帮助到你。

大家可以扫码前往,也可以微信搜索**【Java面试 | 笑小枫】**小程序。持续更新中,后续会上一些资源、简历模板、面试分享内容

applet-tg

面试流程

image-20230315193356436

老面:&和&&有什么区别?

笑小枫:&可用于位运算,当左右两边的条件不是布尔型,而是数字时,它会进行位运算;

当&运算符两侧是是布尔型,且表达式的结果均为真时,整个运算结果才为真;当&&操作符第一个表达式为 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以及配合操作系统来实现,是一个关键字reentrantLockjdk1.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不支持跨域。

image-20230315193758765

寄语

本文到此就结束了,希望本文可以帮助到你,希望你可以找到一个满意的工作

如果需要简历模板或者进行面试指导,可以关注【笑小枫】公众号私聊我哈

image-20230315193421391

标签: #java两个对象比较