最最最常见的Java面试题总结-第一周
这里会分享一些出现频率极其极其高的面试题,初定周更一篇,什么时候更完什么时候停止。
Github地址:https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/最最最常见的Java面试题总结/第一周(2018-8-7).md
一 Java中的值传递和引用传递(非常重要)
首先要明确的是:“对象传递(数组、类、接口)是引用传递,原始类型数据(整型、浮点型、字符型、布尔型)传递是值传递。”
那么什么是值传递和应用传递呢?
值传递是指对象被值传递,意味着传递了对象的一个副本,即使副本被改变,也不会影响源对象。(因为值传递的时候,实际上是将实参的值复制一份给形参。)
引用传递是指对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象的改变会反映到所有的对象上。(因为引用传递的时候,实际上是将实参的地址值复制一份给形参。)
有时候面试官不是单纯问你“Java中是值传递还是引用传递”是什么啊,骚年?而是给出一个例子,然后让你写出答案,这种也常见在笔试题目中!所以,非常重要了,请看下面的例子:
值传递和应用传递实例
1. 值传递
public static void main(String[] args) { int num1 = 10; int num2 = 20; swap(num1, num2); System.out.println("num1 = " + num1); System.out.println("num2 = " + num2); } public static void swap(int a, int b) { int temp = a; a = b; b = temp; System.out.println("a = " + a); System.out.println("b = " + b); }
结果:
a = 20 b = 10 num1 = 10 num2 = 20
解析:
在swap方法中,a、b的值进行交换,并不会影响到num1、num2。因为,a、b中的值,只是从num1、num2的复制过来的。
也就是说,a、b相当于num1、num2的副本,副本的内容无论怎么修改,都不会影响到原件本身。
2. 引用传递
public static void main(String[] args) { int[] arr = {1,2,3,4,5}; change(arr); System.out.println(arr[0]); } public static void change(int[] array) { //将数组的第一个元素变为0 array[0] = 0; }
结果:
1 0
解析:
无论是主函数,还是change方法,操作的都是同一个地址值对应的数组。 。因此,外部对引用对象的改变会反映到所有的对象上。
一些特殊的例子
1. StringBuffer类型传递
// 测试引用传递:StringBuffer @org.junit.Test public void method1() { StringBuffer str = new StringBuffer("公众号:Java面试通关手册"); System.out.println(str); change1(str); System.out.println(str); } public static void change1(StringBuffer str) { str = new StringBuffer("abc");//输出:“公众号:Java面试通关手册” //str.append("欢迎大家关注");//输出:公众号:Java面试通关手册欢迎大家关注 //str.insert(3, "(编程)");//输出:公众号(编程):Java面试通关手册 }
结果:
公众号:Java面试通关手册 公众号:Java面试通关手册
解析:
很多要这个时候要问了:StringBuffer创建的明明也是对象,那为什么输出结果依然是原来的值呢?
因为在change1
方法内部我们是新建了一个StringBuffer对象,所以str
指向了另外一个地址,相应的操作也同样是指向另外的地址的。
那么,如果将change1
方法改成如下图所示,想必大家应该知道输出什么了,如果你还不知道,那可能就是我讲的有问题了,我反思(开个玩笑,上面程序中已经给出答案):
public static void change1(StringBuffer str) { str.append("欢迎大家关注"); str.insert(3, "(编程)"); }
2. String类型传递
// 测试引用传递:Sring @org.junit.Test public void method2() { String str = new String("公众号:Java面试通关手册"); System.out.println(str); change2(str); System.out.println(str); } public static void change2(String str) { // str="abc"; //输出:公众号:Java面试通关手册 str = new String("abc"); //输出:公众号:Java面试通关手册 }
结果:
公众号:Java面试通关手册 公众号:Java面试通关手册
可以看到不论是执行str="abc;"
还是str = new String("abc");
str的输出的值都不变。
按照我们上面讲“StringBuffer类型传递”的时候说的,str="abc;"
应该会让str的输出的值都不变。为什么呢?因为String在创建之后是不可变的。
3. 一道类似的题目
下面的程序输出是什么?
public class Demo { public static void main(String[] args) { Person p = new Person("张三"); change(p); System.out.println(p.name); } public static void change(Person p) { Person person = new Person("李四"); p = person; } } class Person { String name; public Person(String name) { this.name = name; } }
很明显仍然会输出张三
。因为change
方法中重新创建了一个Person
对象。
那么,如果把 change
方法改为下图所示,输出结果又是什么呢?
public static void change(Person p) { p.name="李四"; }
答案我就不说了,我觉得大家如果认真看完上面的内容之后应该很很清楚了。
二 ==与equals(重要)
== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型==比较的是值,引用数据类型==比较的是内存地址)
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
- 情况1:类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。
- 情况2:类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。
举个例子:
public class test1 { public static void main(String[] args) { String a = new String("ab"); // a 为一个引用 String b = new String("ab"); // b为另一个引用,对象的内容一样 String aa = "ab"; // 放在常量池中 String bb = "ab"; // 从常量池中查找 if (aa == bb) // true System.out.println("aa==bb"); if (a == b) // false,非同一对象 System.out.println("a==b"); if (a.equals(b)) // true System.out.println("aEQb"); if (42 == 42.0) { // true System.out.println("true"); } } }
说明:
- String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,而String的equals方法比较的是对象的值。
- 当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象。
三 hashCode与equals(重要)
面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?”
hashCode()介绍
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)
为什么要有hashCode
我们以“HashSet如何检查重复”为例子来说明为什么要有hashCode:
当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head fist java》第二版)。这样我们就大大减少了equals的次数,相应就大大提高了执行速度。
hashCode()与equals()的相关规定
- 如果两个对象相等,则hashcode一定也是相同的
- 两个对象相等,对两个对象分别调用equals方法都返回true
- 两个对象有相同的hashcode值,它们也不一定是相等的
- 因此,equals方法被覆盖过,则hashCode方法也必须被覆盖
- hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
写在最后
推荐一个自己的开源的后端文档
Java-Guide: Java面试通关手册(Java学习指南)Java Interview Customs Manual (Java Study Guide)。star:1.4k。
Github地址:https://github.com/Snailclimb/Java-Guide
文档定位:一个专门为Java后端工程师准备的开源文档,相信不论你是Java新手还是已经成为一名Java工程师都能从这份文档中收获到一些东西。
面试相关资源免费分享
Java最新17年面试笔试题+Java面试宝典+简历模版就业指导笔记视频+
Java校招面试 Google面试官亲授+Java[BAT]面试必备+2017Google面试官亲授 java校招面试
关注微信公众号“Java面试通关手册”回复“面试”即可免费领取!
参考:
https://blog.csdn.net/zhzhao999/article/details/53449504
https://www.cnblogs.com/skywang12345/p/3324958.html
https://www.cnblogs.com/skywang12345/p/3324958.html
https://www.cnblogs.com/Eason-S/p/5524837.html
如果想要获取更多我的原创文章以及优质学习资源,欢迎关注我的微信公众号:"Java面试通关手册" 。无套路,希望能与您共同进步,互相学习。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JavaScript中的堆和栈
1. 堆heap和栈stack的区别 在计算机领域中,堆栈是两种数据结构,它们只能在一端(称为栈顶(top))对数据项进行插入和删除。 堆:队列优先,先进先出;由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 栈:先进后出;动态分配的空间 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。 以上都属于计算机基础部分,在此都不详细赘述了,下面我们联系JavaScript来剖析一下堆栈。 2. JavaScript变量类型 JavaScript变量可以用来保存两种类型的值:基本类型值和引用类型值 JavaScript的数据类型有六种,包括5种基本类型和1种引用类型: 基本类型 Undefined Null Boolean Number String 引用类型 Object 基本类型值和引用类型值具有以下特点: 基本类型值在内存中占据固定大小的空间,因此被保存在栈(stack)内存 从一个变量向另外一个变量复制基本类型的值,会创建这个值的一个副本; 引用类型的值是对象关于typeof与instanceof的区...
- 下一篇
百度架构师是怎样搭建MySQL分布式集群?
1、什么是MySQL集群 MySQL集群是一个无共享的(shared-nothing)、分布式节点架构的存储方案,其目的是提供容错性和高性能。 数据更新使用读已提交隔离级别(read-committedisolation)来保证所有节点数据的一致性,使用两阶段提交机制(two-phasedcommit)保证所有节点都有相同的数据(如果任何一个写操作失败,则更新失败)。 无共享的对等节点使得某台服务器上的更新操作在其他服务器上立即可见。传播更新使用一种复杂的通信机制,这一机制专用来提供跨网络的高吞吐量。 通过多个MySQL服务器分配负载,从而最大程序地达到高性能,通过在不同位置存储数据保证高可用性和冗余。 需要更多MySQL集群知识的可以订阅我哦 2、名称概念 MySQL集群有如下三层: 应用程序层:负责与mysql服务器通信的各种应用程序。 Mysql服务器层:处理SQL命令,并与NDB存储引擎通信和Mysql服务器。 NDB集群组件层:NDB集群组件有时也称数据节点,负责处理查询,然后将结果返回给mysql服务器。 其中MySQL数据库集群主要包括如下三部分: 1) SQL节点(S...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2全家桶,快速入门学习开发网站教程
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- MySQL8.0.19开启GTID主从同步CentOS8
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程