百度面试题,大伙给点思路 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wangsunng
V2EX    Java

百度面试题,大伙给点思路

  •  
  •   wangsunng
    lenve 2024-08-07 11:57:30 +08:00 7340 次点击
    这是一个创建于 431 天前的主题,其中的信息可能已经有所发展或是发生改变。

    写一段 java 代码,稳定的触发两次 oungGC ,然后触发一次 fullGC ,然后又是两次 youngGC 。

    关键是稳定触发

    21 条回复    2024-08-07 18:29:18 +08:00
    xuld
        1
    xuld  
       2024-08-07 12:06:55 +08:00
    如果有人能回答:“如何强制触发一次 young GC”和“如何强制触发一次 full GC”。但不能回答上面的面试题。
    请问这个人面试通过还是不通过?
    expkzb
        2
    expkzb  
       2024-08-07 12:24:44 +08:00
    在 Java 中,垃圾收集器的行为通常是由 JVM 的垃圾收集策略和配置决定的,而不是由应用程序直接控制。然而,你可以使用`System.gc()`方法来建议 JVM 进行垃圾收集,但请注意,这个方法并不保证 JVM 一定会执行垃圾收集,也不保证垃圾收集的类型( Young GC 或 Full GC )。

    以下是一个 Java 代码示例,它尝试触发两次 Young GC 和一次 Full GC ,然后再触发两次 Young GC 。但请记住,这只是一种尝试,实际的行为将取决于 JVM 的实现和当前的内存使用情况。

    ```java
    public class GCTrigger {

    public static void main(String[] args) {
    // 尝试触发两次 Young GC
    for (int i = 0; i < 2; i++) {
    System.gc(); // 建议 JVM 进行垃圾收集
    System.runFinalization(); // 建议 JVM 执行可到达对象的终结方法
    try {
    // 等待一段时间,让 JVM 有机会执行垃圾收集
    Thread.sleep(100);
    } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    }
    }

    // 尝试触发一次 Full GC
    System.gc(); // 再次建议 JVM 进行垃圾收集

    try {
    // 等待一段时间,让 JVM 有机会执行垃圾收集
    Thread.sleep(100);
    } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    }

    // 尝试再次触发两次 Young GC
    for (int i = 0; i < 2; i++) {
    System.gc();
    System.runFinalization();
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    }
    }
    }
    }
    ```

    这段代码通过调用`System.gc()`和`System.runFinalization()`来建议 JVM 执行垃圾收集,并使用`Thread.sleep()`来等待一段时间,以便 JVM 有时间响应这些请求。然而,再次强调,这种方法不能保证垃圾收集的类型或次数。

    如果你需要更精确地控制垃圾收集的行为,你可能需要使用特定的 JVM 参数来配置垃圾收集器,或者使用更高级的 JVM 监控和诊断工具来分析和优化垃圾收集的性能。
    wpblank
        3
    wpblank  
       2024-08-07 12:26:30 +08:00 via Android
    应该是考察特定内存大小下,gc 触发时机吧,照着规则一直 new 特定大小的对象就行了吧
    wangsunng
        4
    wangsunng  
    OP
       2024-08-07 12:31:47 +08:00
    @expkzb 这个并不能稳定触发,因为无论是 System.gc(); 还是 System.runFinalization(); 都只是建议 GC ,并不能保证会发生 GC ,这个题目的难点就在这里。
    wangsunng
        5
    wangsunng  
    OP
       2024-08-07 12:34:38 +08:00
    @wpblank 我的思路也是这样,指定运行内存大小和新生代大小之后添加大对象,但是又有一个问题,比如新生代内存有 5M ,新创建的对象是 3M ,按理说不需要 GC ,但是有可能存在内存碎片,导致没有连续的 3M 内存,那么这个时候也可能会触发一次 YoungGC ,内存碎片这种事程序员又不可控
    quantal
        6
    quantal  
       2024-08-07 12:37:59 +08:00
    给一个 gpt4o 的回复
    要稳定地触发两次 Young GC 、一次 Full GC ,然后再触发两次 Young GC ,可以通过精确控制堆内存分配来实现。下面是一个示例代码,该代码通过分配和释放对象来控制垃圾回收的发生:
    public class GCDemo {

    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) throws InterruptedException {
    // 1. 分配足够的内存来触发两次 Young GC
    byte[] allocation1, allocation2, allocation3;
    allocation1 = new byte[2 * _1MB]; // 第一次分配
    allocation2 = new byte[2 * _1MB]; // 第二次分配
    allocation3 = new byte[2 * _1MB]; // 触发第一次 Young GC

    // 2. 再次分配内存,确保触发第二次 Young GC
    allocation1 = new byte[2 * _1MB];
    allocation2 = new byte[2 * _1MB];
    allocation3 = new byte[2 * _1MB]; // 触发第二次 Young GC

    // 3. 分配大对象,触发 Full GC
    allocation1 = new byte[4 * _1MB];
    allocation2 = new byte[4 * _1MB]; // 触发 Full GC

    // 4. 再次分配内存,确保触发两次 Young GC
    allocation1 = new byte[2 * _1MB];
    allocation2 = new byte[2 * _1MB];
    allocation3 = new byte[2 * _1MB]; // 触发第三次 Young GC

    allocation1 = new byte[2 * _1MB];
    allocation2 = new byte[2 * _1MB];
    allocation3 = new byte[2 * _1MB]; // 触发第四次 Young GC

    // 程序结束,等待手动触发 Full GC
    System.gc();
    }
    }
    为了确保该代码按预期运行,你需要使用适当的 JVM 参数来配置堆大小和垃圾收集器。例如:
    java -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:+UseSerialGC GCDemo
    yuankui
        7
    yuankui  
       2024-08-07 12:41:19 +08:00   8
    茴香豆雕花
    pangdundun996
        8
    pangdundun996  
       2024-08-07 12:53:57 +08:00
    问了一下 GPT ,大致思路是:
    1 )设置 jvm 参数:xms 、xmx 、新生代比例之类的
    2 )然后代码中分配对象,先填满新生代的一半,然后继续分配两次,触发两次 young gc
    3 )取消所有对象引用,触发 gull gc ,因为后续两次分配导致有对象晋升到 old gen
    4 )重复第二步,触发两次 young gc
    中间通过 sleep 来控制流程
    JasonLaw
        9
    JasonLaw  
       2024-08-07 13:04:35 +08:00 via iPhone
    这样的问题有什么意义?
    jixiangqd
        10
    jixiangqd  
       2024-08-07 14:12:05 +08:00
    @JasonLaw #9 意义还是有点,看你是否了解 jvm 的内存管理细节,而且有实践经验
    FreeWong
        11
    FreeWong  
       2024-08-07 14:21:37 +08:00   4
    这么在意垃圾回收,还用什么 java
    securityCoding
        12
    securityCoding  
       2024-08-07 14:23:42 +08:00
    @JasonLaw 没有任何意义...zgc 一把梭
    amon
        13
    amon  
       2024-08-07 14:39:13 +08:00
    哈面试官,你能回答这个问题吗:
    模拟掌管一个公司,
    先 miss 吴恩达,
    后 miss 陆奇,
    还 miss 了 Claude 创始人 Dario Amodei 。

    然后的百度 AI 还发展这个样的。
    cc666
        14
    cc666  
       2024-08-07 14:41:08 +08:00
    很久没写 java 了,但我认为这个问题的本意可能只是考察对 GC 的详细了解程度,设置各种代的大小,但是本质上来看个人认为是做不到的,只能写出来粗看之下正确的代码,并且这个代码里只能有基本数据类型和数组,因为只要你的代码中存在任何不是你自己写的引用对象,那么这段代码的内存占用就是你完全不可控的,你不可能知道所有被引入的包在类加载的时候生成的对象的数量,就一个 java 在运行时自动导入的 java.lang 包就够吃一壶的了,你让谁计算这些包在导入的时候生生了多少个,多大的内存对象,更不可能控制相关变量的 GC ,从而调参和精心构造你自己申请的内存大小就没有意义,并且 GC 本身就在一个线程里,你无法精确控制 GC 何时运行。

    就 java.lang 包就够想精确实现这个的人喝一壶的了,更别说真实的项目了,个人认为是傻逼面试题而已。
    xing7673
        15
    xing7673  
       2024-08-07 15:07:39 +08:00
    @quantal 还是强调一下,v 站禁止 ai 回复,用 ai 发言要慎重。
    wow0o
        16
    wow0o  
       2024-08-07 15:47:50 +08:00
    这个问题本身还挺有意思的。 可以让新老生代的实践不再那么镜花水月
    ZZ74
        17
    ZZ74  
       2024-08-07 16:13:25 +08:00
    代码不是重点,jvm 参数才是重点。
    首先要确定垃圾收集器用哪个,因为这决定了 Young Old 的比例,CMS 通常是 1:2 ,G1 是百分比。因为 G1 的百分比,以及 region 大小等可能直接导致直接分配到了 Old 。
    通过 6 楼 new byte[]来控制对象大小
    通过控制堆大小 Xms ,Xmx ,和新旧比例来控制 YGC
    通过控制直接分配到老年代的阈值 控制 full GC

    最关键的得对垃圾收集器的行为细节了如指掌才行,比如有大对象直接进老年代,但是没看过细节你怎么知道它不会顺手执行个 YGC
    109021017
        18
    109021017  
       2024-08-07 16:25:24 +08:00
    @amon 面试官: 关我屁事, 关你屁事
    feiyan35488
        19
    feiyan35488  
       2024-08-07 17:24:34 +08:00
    @JasonLaw 互联网八股文
    incubus
        20
    incubus  
       2024-08-07 18:26:43 +08:00
    @wangsunng 定时器?
    sagaxu
        21
    sagaxu  
       2024-08-07 18:29:18 +08:00
    .net 和 Go 就没这么多屁事
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2718 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 113ms UTC 08:53 PVG 16:53 LAX 01:53 JFK 04:53
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86