Java面试记要,不要错过

Posted 程序员食堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java面试记要,不要错过相关的知识,希望对你有一定的参考价值。

程序员食堂与你同在

Java面试记要,不要错过


Java面试记要,不要错过


note

1

解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法

通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在静态区中。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,理论上整个内存没有被其他进程使用的空间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。

String str = new String("hello");

上面的语句中变量str放在栈上,用new创建出来的字符串对象放在堆上,而”hello”这个字面量放在静态区。

补充:较新版本的Java(从Java 6的某个更新开始)中使用了一项叫”逃逸分析”的技术,可以将一些局部对象放在栈上以提升对象的操作性能

note

2

请写一段栈溢出、堆溢出的代码

首先分析:为什么会出现栈溢出:

1. 就是请求的栈深度>jvm'所允许的栈深度。

2.Jvm在扩展栈深度时无法获取到足够的内存。

Java面试记要,不要错过

下来就是:为什么会出现堆溢出:

因为:给对象分配内存时,没有足够的空间供使用了

Java面试记要,不要错过

note

3

ThreadLocal可以用来共享数据吗

可以,他是线程级别的变量,他的底层是一个自定义的hashmap,早期的版本,在hashmap中的key保存线程的id,value保存的是对共享数据的一份拷贝,这样就可以实现变量在不同的线程之前共享。在1.8中,每一个线程都维护一个hashmap表,其中的key就是threadLocal,value是真正要存得值。

这样改变的好处就是:

1)这样设计之后每个Map存储的Entry数量就会变小,因为之前的存储数量由Thread的数量决定,现在是由ThreadLocal的数量决定。

2)当Thread销毁之后,对应的ThreadLocalMap也会随之销毁,生命周期与线程相同,能减少内存的使用。

note

4

Java 中会存在内存泄漏吗

理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致内存泄露的发生。例如hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)或清空(flush)一级缓存就可能导致内存泄露。下面例子中的代码也会导致内存泄露。

import java.util.Arrays;

import java.util.EmptyStackException;

 

public class MyStack<T> {

    private T[] elements;

    private int size = 0;

 

    private static final int INIT_CAPACITY = 16;

 

    public MyStack() {

        elements = (T[]) new Object[INIT_CAPACITY];

    }

 

    public void push(T elem) {

        ensureCapacity();

        elements[size++] = elem;

    }

 

    public T pop() {

        if(size == 0)

            throw new EmptyStackException();

        return elements[--size];

    }

 

    private void ensureCapacity() {

        if(elements.length == size) {

            elements = Arrays.copyOf(elements, 2 * size + 1);

        }

    }

}

上面的代码实现了一个栈(先进后出(FILO))结构,乍看之下似乎没有什么明显的问题,它甚至可以通过你编写的各种单元测试。然而其中的pop方法却存在内存泄露的问题,当我们用pop方法弹出栈中的对象时,该对象不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,因为栈内部维护着对这些对象的过期引用(obsolete reference)。在支持垃圾回收的语言中,内存泄露是很隐蔽的,这种内存泄露其实就是无意识的对象保持。如果一个对象引用被无意识的保留起来了,那么垃圾回收器不会处理这个对象,也不会处理该对象引用的其他对象,即使这样的对象只有少数几个,也可能会导致很多的对象被排除在垃圾回收之外,从而对性能造成重大影响,极端情况下会引发Disk Paging(物理内存与硬盘的虚拟内存交换数据),甚至造成OutOfMemoryError。



以上是关于Java面试记要,不要错过的主要内容,如果未能解决你的问题,请参考以下文章

一些Java面试技巧分享,你不能错过!

面试技巧2018年 Java 面试题汇总(含答案),错过了血亏!

想搞定Java面试?你不该错过这些

Python面试题分享,不要错过哟!

JAVA面试技巧,不容错过!

关于Web前端面试的小技巧,千万不要错过!