虚拟机栈相关面试题

一 面试题

1 举例栈溢出的情况?

栈溢出:*Error。

main 函数递归调用 main 函数会出现栈溢出。

可以通过 -Xss 设置栈的大小。

2 调整栈大小,就能保证不出现溢出么?

不能保证不溢出,调大一些,只是出现得晚一些。比如:main 函数递归调用 main 函数,一定会出现栈溢出。

3 分配的栈内存越大越好么?

不是,一定时间内降低了 OOM 概率,但是会挤占其它的线程空间,因为整个空间是有限的。

4 垃圾回收是否涉及到虚拟机栈?

不会

5 方法中定义的局部变量是否线程安全?

具体问题具体分析。见实战中的代码分析。

6 运行时数据区,是否存在Error和GC?

虚拟机栈相关面试题

二 实战

1 代码分析

/**
* 面试题:
* 方法中定义的局部变量是否线程安全?具体情况具体分析
* 何为线程安全?
* 如果只有一个线程才可以操作此数据,则必是线程安全的。
* 如果有多个线程操作此数据,则此数据是共享数据。如果不考虑同步机制的话,会存在线程安全问题。
*/
public class StringBuilderTest {
    int num = 10;

    // s1的声明方式是线程安全的
    public static void method1() {
        // StringBuilder : 这个类是线程不安全
        // StringBuffer : 这个类是线程安全,两个类的区别是 StringBuffer 中的方法加了 synchronized
        StringBuilder s1 = new StringBuilder();
        s1.append("a");
        s1.append("b");
        //...
    }

    // sBuilder 的操作过程:是线程不安全的,因为 sBuilder 是从函数外传递进来的,成了共享数据
    public static void method2(StringBuilder sBuilder) {
        sBuilder.append("a");
        sBuilder.append("b");
        //...
    }

    // s1 的操作:是线程不安全的,因为 s1 传递到函数外了,成了共享数据
    public static StringBuilder method3() {
        StringBuilder s1 = new StringBuilder();
        s1.append("a");
        s1.append("b");
        return s1;
    }

    // s1 的操作:是线程安全的
    public static String method4() {
        StringBuilder s1 = new StringBuilder();
        s1.append("a");
        s1.append("b");
        return s1.toString();
    }

    public static void main(String[] args) {
        StringBuilder s = new StringBuilder();
        new Thread(() -> {
            s.append("a");
            s.append("b");
        }).start();
        method2(s);
    }
}

2 代码说明

总结一句话就是:如果对象是在内部产生,并在内部消亡,没有返回到外部,那么它就是线程安全的,反之则是线程不安全的。

上一篇:SQLServer2005+分页SQL


下一篇:OpenOffice的安装与启动