V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sleepybear1113
V2EX  ›  编程

写 Java 的和写 Cpp 的理念和观点争论,各位看看我的理解哪里有问题

  •  
  •   sleepybear1113 · 20 天前 · 1544 次点击

    我是写 Java 的,基本就是写业务 crud 的;人家是写 C++ 的,游戏后端,室友。在讨论今天的屎山代码的时候,聊到了这个话题。

    话题主要是,一个程序异常退出了,怎么定位问题。他的理解是,不管什么语言,总会有程序/虚拟机捕捉不到的情况,找不到堆栈、日志,怎么去排查问题。我的理解是,我目前就写 Java ,也就谈论 Java ,jvm 接管,都是在写业务,很少遇到程序炸了的情况,即使炸了 jvm 也会接手给出 dump 或者打印堆栈,或者框架在崩溃之前有相关的日志,而且一般 Java 的应该都是 oom 炸的比较多,别的暂时没怎么接触。

    后面是四张微信截图。在我看来,应该是两个人对于语言的理解不一样,所以导致开发的过程中对于异常的处理也不一样。所以麻烦大家看看,我的想法是不是也有不对的地方,或者双方的理解都有什么问题。

    叠甲,双方都是友好讨论,关系不错,就瞎扯扯到这个的。不要说谁杠就是谁对,仅探讨内容和理解方面的问题,指出一下比如我的哪块理解或者知识储备有问题。

    下面是图片,可能有点长,一共四张(另外,哪些图床可以贴图,带缩放的,不然图片尺寸有点大,太刷屏了)

    000201

    000202

    000203

    000204

    29 条回复    2024-04-10 13:59:25 +08:00
    agagega
        1
    agagega  
       20 天前 via iPhone   ❤️ 3
    对面这人有点缺少心平气和沟通的能力
    sleepybear1113
        2
    sleepybear1113  
    OP
       20 天前
    #1 不是缺少心平气和,是人家被代码搞的头大了,刚刚程序炸了,然后来群里面吐槽,所以毕竟带点情绪的
    tool2d
        3
    tool2d  
       20 天前
    写 C++代码,一般恶性 BUG 会覆盖到别的地方内存,不一定马上会爆雷,确实不太好回溯。

    JAVA 这方便,是要好那么一点的。
    geelaw
        4
    geelaw  
       20 天前   ❤️ 1
    在调试器下启动需要调试的进程不就行了?这样刚启动就崩溃的时候调试器就可以用来查看状态。

    感觉对方和你说的是两回事儿。你说的是 JVM 已经控制进程的状态,对方说的是没有合适的 runtime 管理进程的状态。
    me1onsoda
        5
    me1onsoda  
       20 天前
    都是 runtime 能有什么区别
    看到这就不想聊了,既不懂 Java 也不懂 go
    ivvei
        6
    ivvei  
       20 天前
    jvm 启动失败的时候呢
    zsl199512101234
        7
    zsl199512101234  
       20 天前
    C++编译器的报错,神仙都看不懂(现在要好很多了
    sleepybear1113
        8
    sleepybear1113  
    OP
       20 天前
    @ivvei #6 正常一个能跑的 Java ,改两下,应该是不会连 jvm 都起不来的,至少我没遇到过
    Mithril
        9
    Mithril  
       20 天前   ❤️ 2
    他说的是没错的。

    虽然有 runtime 罩着你,但你也总会有把 runtime 炸掉的情况。那么这些时候 runtime 不一定会有什么有意义的输出,而且你直接炸 runtime 也不会有 log 。甚至缓冲里的 Log 也不一定输出出来。

    而 Debug 是一个成本和概率问题。正确的做法是:
    1. 基于现有情况,猜一下概率最高的问题,选个成本最低的定位方法,尝试一下
    2. 如果能定位到这个问题,那么就解决了
    3. 如果定位不到,那就再尝试成本次低的下一个方法
    4. 如果排除这个问题,那么尝试概率第二高的可能问题

    对于 C++来说,很多未捕捉到的异常都可能导致它那种情况,所以你都已经出了问题了,再去加日志并不是一个“成本可接受”的方法。而他这种情况,最简单的,就是去查一下返回码。

    对于 Java 来说,有 JVM 托管,有 Spring 框架,绝大多数情况都有 log ,而且大部分异常顶多炸个请求,也不会炸掉你整个 app ,自然去查 log 是最简单的方法。

    但当你没法靠这么简单的办法定位问题的时候,只能去找更复杂的办法,去尝试可能性更低的问题了。

    不是啥对错的问题,你自己 Java 和 C++都做点项目就能理解了。
    sunny352787
        10
    sunny352787  
       20 天前
    他有点钻牛角尖了,带 runtime 和不带 runtime 的语言其实区别很大

    我之前写 C++的时候也碰到过这种啥都没有直接崩没了的情况,我们的解决方式是程序启动直接分配一块内存预留 dump ,这样即使程序 oom 了也有一块内存能保存错误信息,再极端点可以在磁盘也预分配一块儿,所以这些其实都不是什么问题。

    他现在的假设其实是建立在 runtime 本身出现问题的情况下程序崩溃,如果 runtime 没有类似我说的这种方式来处理的话确实也可能出现他所说的什么信息都没有的情况,但我不太相信这些流行语言的 runtime 设计者会没有这类处理,所以在他以他的认知水平来看问题的情况下,任何语言都会出现崩溃但无信息的问题,而实际上是有办法规避的。
    GeruzoniAnsasu
        11
    GeruzoniAnsasu  
       20 天前
    拜托你俩都多写写其它的东西吧
    Ayanokouji
        12
    Ayanokouji  
       20 天前
    太钻牛角尖了,举个很常见的例子,容器被 oomkilled 怎么办,容器也算是个 runtime 了
    chingyat
        13
    chingyat  
       20 天前   ❤️ 1
    你们在说啥?没用过 gdb ?
    Rickkkkkkk
        14
    Rickkkkkkk  
       20 天前
    @ivvei 启动失败也有报错的.
    luckyrayyy
        15
    luckyrayyy  
       20 天前
    我感觉他的理解是对的,总有 jvm 兜底兜不住的情况。如果你纯写 Java 业务代码,那可能确实没遇到过,我也没遇到过。之前写 JNA 调用 C 的 dll 遇到过一次 jvm 干崩了,有 dump 但是看起来毫不相关也看不懂。另外还有就是 jvm 外的问题,外部程序导致的 jvm 崩溃。 但是吧,话又说回来,你只写业务代码,不碰 unsafe 之类的东西,确实很难遇到 JVM 兜不住的,不像 C++那么容易搞破坏,这种心智负担和门槛的降低也是 Java 语言的优势之一了。
    moudy
        16
    moudy  
       20 天前   ❤️ 3
    你们都不在一个频道上。你在说买了房子装修该怎么弄。他在说怎么盖你那个房子。实际上他也不在底层,房子下面还有地基。地基下面还有岩层。
    moudy
        17
    moudy  
       20 天前   ❤️ 8
    @sunny352787 嵌入式程序员表示,较真起来没啥是不能崩的。曾经调试过一个应用崩溃,追下去是 runtime 崩溃,再查是 os 的 mutex 锁不住数据。接着追下去其实是两个 core 的同步没做对。最后是原因第三个 security core 的 firemware 中断权限调太高了....
    enchilada2020
        18
    enchilada2020  
       20 天前 via Android
    @moudy 这就是应用开发跟系统开发的差距。。
    Erroad
        19
    Erroad  
       20 天前
    大家都在刻意回避直接回答对方的问题罢了
    adoal
        20
    adoal  
       20 天前
    只做过本机原生可执行程序开发的,可能确实理解不了,在有 vm 的语言里,vm 在某种程度上相当于他那个技术栈里 hardware/os 的一部分功能。不过你如果遇到极端情况也有可能需要到 vm 层去调试。
    barrysj
        21
    barrysj  
       20 天前
    你们的这个争论本身,还没到讨论具体“没堆栈日志的情况下怎么排查”,是在争论有没有“没堆栈日志的这个情况”。
    c 发生 core 的场景肯定比 jvm 挂掉的场景多得多,所以写 c 的去考虑这个问题是有意义的,java 不去考虑也行。
    不过对面这个哥们其实是有点 der 的。。。。倒数第二张图你说“发现虚拟机的好处了”,这哥们以为你说的 cvm 。。
    还提到 strace ,程序挂了的时候 strace 又用不了
    sleepybear1113
        22
    sleepybear1113  
    OP
       20 天前
    @Mithril #9 看起来我们两个应该不在一条线上

    @GeruzoniAnsasu #11 工作已经很累了,怎么多写呢。不是那么容易的。

    @Ayanokouji #12 容器炸了相当于系统炸了,这个东西从来没考虑过,要么加硬件要么限制内部。

    @chingyat #13 对方有用过,对 Java 来说,这个应该基本接触不到的,你可能不写 Java 吧。

    @Erroad 不是刻意回避的情况,现在的了解应该是不在一条频道了。
    woodfizky
        23
    woodfizky  
       20 天前   ❤️ 1
    感觉是语言特性/生态特性/异常处理风格不同 导致的一般情况下职责划分和系统层面的不同。

    写 Java 的一般不用处理 JVM 或者框架跑不起来的情况。

    写 C/CPP 的,程序炸了还要看是在哪个层面炸了,调查深度可以很深,一层一层向底层调查的感觉。

    所以你俩确实没聊到一起去。
    ruooooooli
        24
    ruooooooli  
       20 天前
    我是写 Go 的,正好今天线上偶现了一个问题,服务像是暂停了,没有任何日志,进程也在,就是没法响应,定位不了问题,没有头绪。
    hefish
        25
    hefish  
       20 天前
    一个说英文的,吐槽时态语法太复杂了, 然后一个说中文的反驳,说时态语法有啥复杂的。。。
    然后两个人相互吵啊。。。吵啊。。。。然后其中一个人把微信截图发到论坛上来了。。。
    然后我就跟帖了。。。
    yannxia
        26
    yannxia  
       20 天前
    @ruooooooli #24 goroutine trace ,把 go pprof 打开,多半哪里有个无超时的地方 Hang 了,go 还是挺好排查问题的……
    ruooooooli
        27
    ruooooooli  
       19 天前
    @yannxia 看了 pprof 的,进程没法响应,也抓不到😂
    skull
        28
    skull  
       19 天前 via iPhone
    java 不就是 springboot ,这句无力吐槽
    sleepybear1113
        29
    sleepybear1113  
    OP
       19 天前
    @skull #28 对于上图场景下,Java 就是 Spring Boot 我觉得没啥问题。互联网场景有哪几个不用 Spring Boot ?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1080 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:45 · PVG 02:45 · LAX 11:45 · JFK 14:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.