1. == 比较的是什么?
“ == ” 对比两个对象基于内存引用,如果两个对象的引用完全相同(指向同一个对象)时,“ == ”返回的是true,否则返回false 。而如果两边是基本类型的话 “ == ” 就是比较的他们之间的数值是否是相等的 。
2. 若对一个类不重写, 它的 equals () 方法是如何比较的 ?
比较的是内存的地址。
3. 一个十进制数在内存中是怎么存的 ?
以补码的方式进行存储。
4. 为什么有时会出现 4.0-3.6 = 0.400000001的这种情况?
由第三问, 2进制的小数无法精确的表达十进制的小鼠,计算机在计算十进制小数的过程中要先转换为2进制 进行计算,这个过程中出现了误差。
5. 什么是值传递和引用传递 ?
值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量;
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本,并不是对原对象本身。所以对引用对象进行操作会同时改变原对象。 通常我们认为 在 Java中 的传递 都是 值传递。
6.数组(Array) 和列表 (ArrayList)有什么区别? 我们应该如何选择 ?
- Arry 和 ArrayList 的 不同点:
- Array可以包含基本类型和对象类型,ArrayList 只能包含对象类型。
- Array大小是固定的,ArrayList 的大小是动态变化的。
- ArrayList 提供了更多的方法和特性,比如:addAll () ,removeAll( ) , iterator () 等等 。
- 对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当固定大小的基本数据类型的时候,这种方式相对比较慢。
7、String 和 StringBuffer 的区别 ?
Java 平台提供两个类:String 和 StringBuffer , 他们可以存储和操作字符串,即包含多个字符的字符数据。这个String类 提供了数值不可改变的字符串。而这个StringBuffer 类提供的字符串进行修改。当你知道字符数据要改变时你就可以使用StringBuffer。典型的 , 你可以使用StringBuffer 来动态构造字符数据。
8、& 和 && 的区别 ?
&运算符有两种用法 : (1)按位与; (2)逻辑与。 && 运算符时短路与运算。
逻辑与 跟 短路与 的差别时非常巨大的,虽然二者都要求运算符左右两端的布尔值都市true 整个表达式的值才是 true 。
&& 之所以称为短路运算是因为,如果&&左边的表达式的值 是 false , 右边的表达式会被直接短路掉,不会进行运算。
很多时候我们可能都需要使用&& 而不是 & ,例如在验证用户登录时判定用户名不是 null 而且不是空字符串,应当选为:username != null && !username.equals(" ") , 二者的顺序不能交换,更不能用& 运算符,因为第一个条件如果不成立,根本不能进行字符串的equals 比较,否则会产生NullPointException 异常。
9. 介绍一下 volatile ?
volatile 关键字是用来保证有序性和可见性。这跟Java内存模型有关。比如我们所写的代码,不一定是按照我们自己书写的顺序来执行的,编译器会重新排序,CPU 也会做重排序的,这样的重排序是为了减少流水线的阻塞的,引起流水阻塞,比如数据相关性,提高CPU 的执行效率。需要有一定的顺序和规则来保证,不然程序员自己写的代码都不知道对不对了,所以有happens-before 规则,其中有条就是volatile 变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作;
有序性实现的是通过插入内存屏蔽来保证的。
可见性:首先Java 内存模型分为,主内存,工作内存。比如线程A重主内存把变量重主内存读到了自己的工作内存种,做了加1的操作,但是此时没有将 i 的最新值刷新到主内存种,线程B读到的还是 i 的旧值。 加了 volatile 关键字的代码生成的汇编代码发现,会多出一个 lock 前缀指令 Intel 平台的CPU ,早期是线总锁 ,这样的代价太高了 ,后面提出了一个缓存一致性的协议 , MESI , 来保证了多核之间数据不一致的问题。