java面试-基础(一)

1.原始类型和引用类型
- 引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关,除了boolean的初始值是false以外,其他的都是0的一种表现方式(比如0,0.0f,0.0d)
- @Deprecated(since="9")
public Integer(int value) {
this.value = value;
}

推荐使用工厂模式Integer.valueOf()
- Intenger.MIN_VALUE没有对应的int正整数(因为补码)
- 对于基本类型的封装类的自动装箱,不要在循环中使用
- 对原始类型的赋值,会开辟新的内存,修改一个不会对另一个造成影响「1」
- 对象都是引用类型,创建时在堆内存中
- 多个变量被赋予同一个对象时,他们指向的是同一内存「2」

一段测试代码:(不要介意尾注释,这里只是为了方便)

import java.util.ArrayList;
import java.util.List;

/**
 * 

pakage: PACKAGE_NAME,descirption:

* * @author wanghai * @version V1.0 * @since
2018/6/18 下午10:39
*/
public class j { public static void main(String[] args) { Integer a = 120; // Integer a = Integer.valueOf(120); int b = 120; int k = b; Integer c = 120; Integer d = new Integer(120); Integer e = Integer.valueOf(120); System.out.println(a == b); // true System.out.println(a == c); // true System.out.println(a == d); // false System.out.println(b == d); // true System.out.println(k == d); // true System.out.println(a == e); // true System.out.println(b == e); // true System.out.println(b == k); // true // 修改基本类型的值,另一个值不改变 b = 100; System.out.println(b + "--" + k); Integer g = 128; Integer f = 128; Integer n = g; // 引用,指向同一地址 int h = 128; Integer l = -128; Integer m = -128; System.out.println(g == f); // false 超出-128~127 System.out.println(g == n); // true 引用,指向同一地址 System.out.println(f == h); // true 自动拆箱,依然true System.out.println(l == m); // true // 修改引用对象的值,导致另一个指向同一地址的对象的值也改变 n = 10000; System.out.println(g + "--" + n); // TODO:128--10000(按道理不是应该都变化?) // ------------------------------------------ List numbers1 = new ArrayList<>(10); numbers1.add(10); // numbers1------size: 1第一个数:10 System.out.println("numbers1------size: " + numbers1.size() + "第一个数:" + numbers1.get(0)); List numbers2 = numbers1; numbers2.add(99); // numbers2------size: 2第一个数:10 System.out.println("numbers2------size: " + numbers2.size() + "第一个数:" + numbers2.get(0)); // numbers1------size: 2第二个数:99 System.out.println("numbers1------size: " + numbers1.size() + "第二个数:" + numbers1.get(1)); } }
  • 在-128和127之间,jdk对-128~127之间的值做了缓存,对于-128~127之间的值会取缓存中的引用,所以除非显式调用new操作,该区间的值,Integer与Integer调用==方法返回true;
  • 无论如何,对于相同的值,int与Integer调用==方法,返回true。因为Integer调用了intValue()方法进行了自动拆箱操作
  • TODO:代码中System.out.println(g + "--" + n); // TODO:128--10000(按道理不是应该都变化?)
  • 原始类型不能使用泛型类型定义,也就是不能使用List< int>
  • 只要使用引用,就应该注意null问题。所以自动拆箱时,也是又可能发生空指针异常的。

2.静态方法和静态变量,为了避免混淆,便于区分,最好只通过类名来调用

3.Object类被继承时可以被重写的方法
非final的public、protected方法可以被重写,比如:
hashCode(),toString(),equals(),finalize(),clone(),wait(),notify()/notifyAll(),wait()
注意:

  • HashCode()返回的是int,所以,对于某一对象,其实例最多有2 32 32 次方个不同的hash值。
  • HashCode()和equals()应该:“捆绑重写“
  • 如果某一对象的所有实例(假设保存在HashMap中)都返回同一hash值,那么该HashMap的性能就相当于链表的性能了。
    TODO: hashCode(),equals()重写的深度实践

4.不可变对象是线程安全的,比如像String这样的对象,其一旦实例化,值永远不会变化。所有的数值的封装类,比如Integer、Double这些,都是线程安全的,但是int、long这些原始类型,不是线程安全的。可以参考这个例子以及stackoverflow的讨论

5.什么是驻留
String常量池(享元模式的应用)中的字面量,当被多次引用时,叫做驻留。
不仅是String字面量(一对引号之间的所有字符),任何实例化的String实例都可以使用inter()方法来将其添加到常量池之中去。
这些常量被放置于’Metaspace’中——一个JVM中占用内存的一等公民,不会被垃圾回收机制所回收(PermGen空间在Java8中被完全废除,取而代之的是metaspace直接使用本地内存),PermSize和MaxPermSize JVM参数将被忽略,OOM也会相对的减少一些。
部分参考自此文

@Test
    public void intEquality(){
        final Integer int1 = Integer.valueOf(new String("99"));
        final Integer int2 = Integer.valueOf("99");
        //assertTrue(int1 == int2);
        Assert.assertSame(int1,int2);
    }

6.类型协变体(covariance)
B是A的子类,但是List< B>不是List< A>的子类

7.描述异常层次结构中的核心类
java面试-基础(一)_第1张图片
图片引用自falkhausen,(未申请转载图片,侵删)

  • 所有的可以被抛出的类都是Throwable的子类。
  • Error: 程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。
  • Exception:又分为运行时异常——(RuntimeException, unchecked exception,非检查异常)和检查异常(checked exception,编译异常)。
  • 运行时异常,即RuntimeException:在运行时才能被发现,java编译器不要求必须进行异常捕获处理或者抛出声明,由程序员自行决定。 比如常见的NullPointerException、ArrayIndexOutOfBoundsException。
  • 检查异常: java编译器强制程序员必须进行捕获处理,比如常见的IOExeption和SQLException。对于非运行时异常如果不进行捕获或者抛出声明处理,编译都不会通过。
  • An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. (我们不不应该捕捉error)

8.原生函数
使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。这些函数的实现体在DLL中,JDK的源代码中并不包含

参考

[1] metaspace
[2] [原始类型的线程安全问题]
[3] 异常层次结构

你可能感兴趣的:(面试题-java)