几个面试题

沙子 2015-05-08 08:43:29
最近面试遇到几个问题挺有意思:

1、int类型在Java堆里分配多大的内存
这个题不是int是多少个字节,也不是it在需虚拟机栈里的空间。

2、wait()和sleep()方法从cpu角度来说哪个利用率高?问什么?

3、Java除了通过构造方法外,还有哪些方法可以生成实例?

4、Java有几种唤醒线程的方式?分别有什么优缺点?

5、ConcurrentHashMap与Hashtable比有什么优点?又有什么缺点?

6、有一个方法最多只允许2个线程同时访问,如何处理?

...全文
1099 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
kiyoki 2015-05-13
  • 打赏
  • 举报
回复
引用 6 楼 Chengyajie521 的回复:
[quote=引用 4 楼 ice_ice_cream 的回复:] [quote=引用 1 楼 kiyoki 的回复:] 我呆了一下,想来想去int类型始终是4字节的内存
回来查了很多资料,也没找到答案。反正我当初说4字节,那个面试官撇撇嘴不任何。 比较不好的事,既然哥不知道,你作为面试官就不能告诉哥答案![/quote] 基础类型和引用是在栈中存储,不是堆[/quote] 你所有的类都没有int型的成员变量的?
鸣鸣Amadues 2015-05-13
  • 打赏
  • 举报
回复
第一个问题:一般int就是4个字节,分配多少内存跟占用几个字节有区别? 第六个问题:首先想了解下是静态方法还是实例方法,是在一个进程里最多两个线程访问还是在多个进程里最多两个线程访问。 我的思路就是设置一个计数器变量,在方法的开头判断一下,如果不到0的话就-1,已经是0的话就跳过,在方法的结尾+1 这个计数器必须是线程共享的,如果线程在不同进程里可能比较麻烦。 我不确定这种方法是不是你需要的,因为我毕竟还是多次访问了,只不过超过两次的话跳过方法里的逻辑。
qingchange 2015-05-13
  • 打赏
  • 举报
回复
引用 20 楼 Chengyajie521 的回复:
[quote=引用 18 楼 qinchange 的回复:] [quote=引用 6 楼 Chengyajie521 的回复:] [quote=引用 4 楼 ice_ice_cream 的回复:] [quote=引用 1 楼 kiyoki 的回复:] 我呆了一下,想来想去int类型始终是4字节的内存
回来查了很多资料,也没找到答案。反正我当初说4字节,那个面试官撇撇嘴不任何。 比较不好的事,既然哥不知道,你作为面试官就不能告诉哥答案![/quote] 基础类型和引用是在栈中存储,不是堆[/quote] 我记得Integer 类型如果小于127是在常量池分配不再堆,大于等于128才在对分配内存。。 [/quote] 本来我都懒得回这帖子了,反正也没分,不过你说讲出来大家学学,好吧 首先,他说的是int,不是Integer。你用integer来做这个实验是想向我们证明有常量池这个东西对么?常量池是在方法区中的,可以算是堆的一个分支,但它恰恰又叫非堆(Non-Heap)。常量池是放什么的呢?Class文件中的类描述信息,编译期生成的字面量和符号引用。这么说可能不太清晰,我截个图吧。 在Const pool里你找到了什么?类描述信息还有字符串的字面量以及我声明为final的基本变量(40和50)。这是常量池的作用。 至于那个你的例子结果为什么不是都为true呢?下面是Integer的代码:

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

明白了么?里面是有一个缓存池的,其实如果你愿意,改改源码,大可以存比127大的数。缓存池cache是final的,好吧,有兴趣你可以写一个final类型的数组然后javap一下看看是否他在常量池中。至于下面那个问题,我不明确说为什么信号量可以而CountDownLatch不行,只是因为太长了,多线程的东西不是三行两行就讲清了的,多写写爬虫多线程抓取,用用生产者消费者,还有线程池自然就明白了,只讲是没有用的[/quote] 学习了。。
Chengyajie521 2015-05-13
  • 打赏
  • 举报
回复
引用 26 楼 kiyoki 的回复:
[quote=引用 6 楼 Chengyajie521 的回复:]
[quote=引用 4 楼 ice_ice_cream 的回复:]
[quote=引用 1 楼 kiyoki 的回复:]
我呆了一下,想来想去int类型始终是4字节的内存

回来查了很多资料,也没找到答案。反正我当初说4字节,那个面试官撇撇嘴不任何。
比较不好的事,既然哥不知道,你作为面试官就不能告诉哥答案![/quote]
基础类型和引用是在栈中存储,不是堆[/quote]

你所有的类都没有int型的成员变量的?[/quote]
你说的没错,对象中的int 类型是分配在堆中的,但是面试官为什么会撇嘴呢?或许他想听到的不是4个字节的答案。但堆中的int也确实是4个字节,可以通过调整堆的大小和打印gc记录来证明:

第一次运行程序生成1M个byte的数组(不用int是因为前几次用int和double做了,这个用byte做验证,可以换成int自己去测试),运行打印gc记录,记录新生代的大小,然后换成2M个byte的数组,记录新生代的大小,两次的差就是1M个byte在堆中的实际大小,右侧小框是计算一个byte的大小的,得出结论byte在堆中的大小是1个byte的,似乎等于没证明,同理int。
为什么面试官认为这个答案不满意?
songjy3 2015-05-13
  • 打赏
  • 举报
回复
某人确实吊,掉到没朋友!你还不是站在前人的肩膀上来的?有本事自己生产自己的东西,用自己的东西啊,别碰任何别人的东西,楼主加油
沙子 2015-05-12
  • 打赏
  • 举报
回复
引用 17 楼 darcy_yuan 的回复:
第一题,int类型的数据不是存放在堆中的,而是存放在常量池中,而如果是Integer, 则是存放在堆中,简单来说对象的内存布局包括对象头,实例数据,对齐填充,很难计算出来,所以还是建议写个程序测试一下。 第六题,用个原子类的计数器或者Semaphore应该可以实现,CountDownLatch不能,应为计数不能被重置。
如果是想一个出来后,就允许再进一个,这样CountDownLatch就不能满足了。
沙子 2015-05-12
  • 打赏
  • 举报
回复
引用 20 楼 Chengyajie521 的回复:
[quote=引用 18 楼 qinchange 的回复:] [quote=引用 6 楼 Chengyajie521 的回复:] [quote=引用 4 楼 ice_ice_cream 的回复:] [quote=引用 1 楼 kiyoki 的回复:] 我呆了一下,想来想去int类型始终是4字节的内存
回来查了很多资料,也没找到答案。反正我当初说4字节,那个面试官撇撇嘴不任何。 比较不好的事,既然哥不知道,你作为面试官就不能告诉哥答案![/quote] 基础类型和引用是在栈中存储,不是堆[/quote] 我记得Integer 类型如果小于127是在常量池分配不再堆,大于等于128才在对分配内存。。 [/quote] 本来我都懒得回这帖子了,反正也没分,不过你说讲出来大家学学,好吧 首先,他说的是int,不是Integer。你用integer来做这个实验是想向我们证明有常量池这个东西对么?常量池是在方法区中的,可以算是堆的一个分支,但它恰恰又叫非堆(Non-Heap)。常量池是放什么的呢?Class文件中的类描述信息,编译期生成的字面量和符号引用。这么说可能不太清晰,我截个图吧。 在Const pool里你找到了什么?类描述信息还有字符串的字面量以及我声明为final的基本变量(40和50)。这是常量池的作用。 至于那个你的例子结果为什么不是都为true呢?下面是Integer的代码:

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

明白了么?里面是有一个缓存池的,其实如果你愿意,改改源码,大可以存比127大的数。缓存池cache是final的,好吧,有兴趣你可以写一个final类型的数组然后javap一下看看是否他在常量池中。至于下面那个问题,我不明确说为什么信号量可以而CountDownLatch不行,只是因为太长了,多线程的东西不是三行两行就讲清了的,多写写爬虫多线程抓取,用用生产者消费者,还有线程池自然就明白了,只讲是没有用的[/quote] 真不明白,有人欠你钱了吗? 现在的社会不会是一个人能玩的转的,无论你技术的高地。 谦逊是为人之本。从一个团队来讲,我同样不会要那种拽的二五八万似的人物。 贴这几个问题,只是面试的时候还记得的题目,知道答案又愿意回答可以说,不愿意可以不写,没必要去说教。
沙子 2015-05-12
  • 打赏
  • 举报
回复
引用 22 楼 kk_124 的回复:
楼主答的不错了,我补充一下第5个,ConcurrentHashMap适用于高并发场景,其内部主要采用分段锁技术,使操作其中一段key不影响其他key操作(较hashtable锁细粒度话),当然还包括不可变final、volatile先行发生原则等知识。
兄弟,上面是有着好几个花的11楼回答的。不是楼主答的。 ConcurrentHashMap分段,每个段都是一个锁。某些情况下可能会比hashtable更慢,比如对key进行遍历,就会有可能需要获取所有的锁,这种情况下就比获取一把锁慢很多了。
Chengyajie521 2015-05-11
  • 打赏
  • 举报
回复
引用 18 楼 qinchange 的回复:
[quote=引用 6 楼 Chengyajie521 的回复:]
[quote=引用 4 楼 ice_ice_cream 的回复:]
[quote=引用 1 楼 kiyoki 的回复:]
我呆了一下,想来想去int类型始终是4字节的内存

回来查了很多资料,也没找到答案。反正我当初说4字节,那个面试官撇撇嘴不任何。
比较不好的事,既然哥不知道,你作为面试官就不能告诉哥答案![/quote]
基础类型和引用是在栈中存储,不是堆[/quote]

我记得Integer 类型如果小于127是在常量池分配不再堆,大于等于128才在对分配内存。。
[/quote]
本来我都懒得回这帖子了,反正也没分,不过你说讲出来大家学学,好吧
首先,他说的是int,不是Integer。你用integer来做这个实验是想向我们证明有常量池这个东西对么?常量池是在方法区中的,可以算是堆的一个分支,但它恰恰又叫非堆(Non-Heap)。常量池是放什么的呢?Class文件中的类描述信息,编译期生成的字面量和符号引用。这么说可能不太清晰,我截个图吧。

在Const pool里你找到了什么?类描述信息还有字符串的字面量以及我声明为final的基本变量(40和50)。这是常量池的作用。
至于那个你的例子结果为什么不是都为true呢?下面是Integer的代码:

private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];

static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
high = h;

cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}

public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}


明白了么?里面是有一个缓存池的,其实如果你愿意,改改源码,大可以存比127大的数。缓存池cache是final的,好吧,有兴趣你可以写一个final类型的数组然后javap一下看看是否他在常量池中。至于下面那个问题,我不明确说为什么信号量可以而CountDownLatch不行,只是因为太长了,多线程的东西不是三行两行就讲清了的,多写写爬虫多线程抓取,用用生产者消费者,还有线程池自然就明白了,只讲是没有用的
普凡 2015-05-11
  • 打赏
  • 举报
回复
引用 11 楼 qq118194716 的回复:
试着答一下,基础薄弱... 1、int不是在栈中分配么,堆中为0? 2、wait()效率高吧,同是让出cpu,sleep()持有线程锁,不让持有同一把锁的其他线程运行不是浪费cpu资源么 3、反射、对象克隆、对象反序列化 4、notify(),notifyAll(),notify()单独唤醒线程并赋予其对象上的锁,但是如果唤醒的线程没有继续notify其他线程就死翘翘了 notifyAll()唤醒所有线程,都去等待锁对象并竞争 5、这个不晓得,没用过... 6、查了下资料学习了下,计数是必须的,让出锁对象是必须的(代码不是我写的....)

Object lock = new Object();  
int count = 0;  
  
public void fun(Thread t) {  
    // 访问计数判断与更新  
    synchronized (lock) {  
        while (count >= 2) {  
            try {  
                lock.wait();  
            } catch (InterruptedException e) {  
                // ignore  
            }  
        }  
        count++;  
    }  
    // 方法实际操作部分。。。。  
    System.out.println(t.getName());// 测试时打印  
  
    // 更新访问计数并唤醒等待的线程  
    count--;  
    lock.notifyAll();  
}  
楼主答的不错了,我补充一下第5个,ConcurrentHashMap适用于高并发场景,其内部主要采用分段锁技术,使操作其中一段key不影响其他key操作(较hashtable锁细粒度话),当然还包括不可变final、volatile先行发生原则等知识。
风吹过夏天 2015-05-11
  • 打赏
  • 举报
回复
楼主你好,这是大概几K的面试题。。。
qingchange 2015-05-10
  • 打赏
  • 举报
回复
引用 12 楼 Chengyajie521 的回复:
[quote=引用 10 楼 ice_ice_cream 的回复:] [quote=引用 9 楼 Chengyajie521 的回复:] 最后一题用信号量
这个Java并发包里有提供一个类CountDownLatch,可以解决[/quote] 建议你好好补一补多线程,看看CountDownLatch到底是做什么的,再试着搜一搜信号量是做什么的[/quote] 就算说得不对也说一下,大家学习学习。
qingchange 2015-05-10
  • 打赏
  • 举报
回复
引用 6 楼 Chengyajie521 的回复:
[quote=引用 4 楼 ice_ice_cream 的回复:]
[quote=引用 1 楼 kiyoki 的回复:]
我呆了一下,想来想去int类型始终是4字节的内存

回来查了很多资料,也没找到答案。反正我当初说4字节,那个面试官撇撇嘴不任何。
比较不好的事,既然哥不知道,你作为面试官就不能告诉哥答案![/quote]
基础类型和引用是在栈中存储,不是堆[/quote]

我记得Integer 类型如果小于127是在常量池分配不再堆,大于等于128才在对分配内存。。
沙子 2015-05-09
  • 打赏
  • 举报
回复
引用 15 楼 Chengyajie521 的回复:
呵呵,我是面试官也不会要你
自己知道点信号量、临界区。就想当然以为别人都不会。 你这种人只能呵呵
Chengyajie521 2015-05-09
  • 打赏
  • 举报
回复
呵呵,我是面试官也不会要你
沙子 2015-05-09
  • 打赏
  • 举报
回复
引用 12 楼 Chengyajie521 的回复:
[quote=引用 10 楼 ice_ice_cream 的回复:] [quote=引用 9 楼 Chengyajie521 的回复:] 最后一题用信号量
这个Java并发包里有提供一个类CountDownLatch,可以解决[/quote] 建议你好好补一补多线程,看看CountDownLatch到底是做什么的,再试着搜一搜信号量是做什么的[/quote] 你在说什么,不要太想当然好吗?
沙子 2015-05-09
  • 打赏
  • 举报
回复
引用 11 楼 qq118194716 的回复:
4、notify(),notifyAll(),notify()单独唤醒线程并赋予其对象上的锁,但是如果唤醒的线程没有继续notify其他线程就死翘翘了 notifyAll()唤醒所有线程,都去等待锁对象并竞争
notify()和notifyAll()必须在wait()之后调用。Java并发包里提供了另外一种方式park()和unpark()方式。相较于wait和notify更灵活
步景 2015-05-09
  • 打赏
  • 举报
回复
第一题,int类型的数据不是存放在堆中的,而是存放在常量池中,而如果是Integer, 则是存放在堆中,简单来说对象的内存布局包括对象头,实例数据,对齐填充,很难计算出来,所以还是建议写个程序测试一下。 第六题,用个原子类的计数器或者Semaphore应该可以实现,CountDownLatch不能,应为计数不能被重置。
Chengyajie521 2015-05-08
  • 打赏
  • 举报
回复
引用 10 楼 ice_ice_cream 的回复:
[quote=引用 9 楼 Chengyajie521 的回复:] 最后一题用信号量
这个Java并发包里有提供一个类CountDownLatch,可以解决[/quote] 建议你好好补一补多线程,看看CountDownLatch到底是做什么的,再试着搜一搜信号量是做什么的
飏飏一蝶 2015-05-08
  • 打赏
  • 举报
回复
试着答一下,基础薄弱... 1、int不是在栈中分配么,堆中为0? 2、wait()效率高吧,同是让出cpu,sleep()持有线程锁,不让持有同一把锁的其他线程运行不是浪费cpu资源么 3、反射、对象克隆、对象反序列化 4、notify(),notifyAll(),notify()单独唤醒线程并赋予其对象上的锁,但是如果唤醒的线程没有继续notify其他线程就死翘翘了 notifyAll()唤醒所有线程,都去等待锁对象并竞争 5、这个不晓得,没用过... 6、查了下资料学习了下,计数是必须的,让出锁对象是必须的(代码不是我写的....)

Object lock = new Object();  
int count = 0;  
  
public void fun(Thread t) {  
    // 访问计数判断与更新  
    synchronized (lock) {  
        while (count >= 2) {  
            try {  
                lock.wait();  
            } catch (InterruptedException e) {  
                // ignore  
            }  
        }  
        count++;  
    }  
    // 方法实际操作部分。。。。  
    System.out.println(t.getName());// 测试时打印  
  
    // 更新访问计数并唤醒等待的线程  
    count--;  
    lock.notifyAll();  
}  
加载更多回复(10)
作者:July、阿财。 时间:二零一一年十月十三日。 ------------------------------ 无私分享造就开源的辉煌。 今是二零一一年十月十三日,明日14日即是本人刚好开博一周年。在一周年之际,特此分享出微软面试 全部100题答案的完整版,以作为对本博客所有读者的回馈。 一年之前的10月14日,一个名叫July 的人在一个叫csdn 的论坛上开帖分享微软等公司数据结构+算法 面试100题,自此,与上千网友一起做,一起思考,一起解答这些面试题目,最终成就了一个名为:结构之法 算法之道的编程面试与算法研究并重的博客,如今,此博客影响力逐步渗透到海外,及至到整个互联网。 在此之前,由于本人笨拙,这微软面试100题的答案只整理到了前60题(第1-60题答案可到本人资源下 载处下载:http://v_july_v.download.csdn.net/),故此,常有朋友留言或来信询问后面40题的答案。只是 因个人认为:一、答案只是作为一个参考,不可太过依赖;二、常常因一些事情耽搁(如在整理最新的今年 九月、十月份的面试题:九月腾讯,创新工场,淘宝等公司最新面试十三题、十月百度,阿里巴巴,迅雷搜狗 最新面试十一题);三、个人正在针对那100题一题一题的写文章,多种思路,不断优化,即成程序员编程 艺术系列。自此,后面40题的答案迟迟未得整理。且个人已经整理的前60题的答案,在我看来,是有诸多问 题与弊端的,甚至很多答案都是错误的。 互联网总是能给人带来惊喜。前几日,一位现居美国加州的名叫阿财的朋友发来一封邮件,并把他自己 做的全部100题的答案一并发予给我,自此,便似遇见了知己。十分感谢。 任何东西只有分享出来才更显其价值。本只需贴出后面40题的答案,因为前60题的答案本人早已整理上 传至网上,但多一种思路多一种参考亦未尝不可。特此,把阿财的答案再稍加整理番,然后把全部100题的答 案现今都贴出来。若有任何问题,欢迎不吝指正。谢谢。 上千上万的人都关注过此100题,且大都都各自贡献了自己的思路,或回复于微软100题维护地址上,或 回复于本博客内,人数众多,无法一一标明,特此向他们诸位表示敬意和感谢。谢谢大家,诸君的努力足以影 响整个互联网,咱们已经迎来一个分享互利的新时代。 感谢诸君,请享用.....

62,610

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧