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

2024 年 4 月 9 日
 sleepyfevniv

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

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

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

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

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

2749 次点击
所在节点    编程
29 条回复
agagega
2024 年 4 月 9 日
对面这人有点缺少心平气和沟通的能力
sleepyfevniv
2024 年 4 月 9 日
#1 不是缺少心平气和,是人家被代码搞的头大了,刚刚程序炸了,然后来群里面吐槽,所以毕竟带点情绪的
tool2d
2024 年 4 月 9 日
写 C++代码,一般恶性 BUG 会覆盖到别的地方内存,不一定马上会爆雷,确实不太好回溯。

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

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

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

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

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

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

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

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

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

他现在的假设其实是建立在 runtime 本身出现问题的情况下程序崩溃,如果 runtime 没有类似我说的这种方式来处理的话确实也可能出现他所说的什么信息都没有的情况,但我不太相信这些流行语言的 runtime 设计者会没有这类处理,所以在他以他的认知水平来看问题的情况下,任何语言都会出现崩溃但无信息的问题,而实际上是有办法规避的。
GeruzoniAnsasu
2024 年 4 月 9 日
拜托你俩都多写写其它的东西吧
Ayanokouji
2024 年 4 月 9 日
太钻牛角尖了,举个很常见的例子,容器被 oomkilled 怎么办,容器也算是个 runtime 了
chingyat
2024 年 4 月 9 日
你们在说啥?没用过 gdb ?
Rickkkkkkk
2024 年 4 月 9 日
@ivvei 启动失败也有报错的.
luckyrayyy
2024 年 4 月 9 日
我感觉他的理解是对的,总有 jvm 兜底兜不住的情况。如果你纯写 Java 业务代码,那可能确实没遇到过,我也没遇到过。之前写 JNA 调用 C 的 dll 遇到过一次 jvm 干崩了,有 dump 但是看起来毫不相关也看不懂。另外还有就是 jvm 外的问题,外部程序导致的 jvm 崩溃。 但是吧,话又说回来,你只写业务代码,不碰 unsafe 之类的东西,确实很难遇到 JVM 兜不住的,不像 C++那么容易搞破坏,这种心智负担和门槛的降低也是 Java 语言的优势之一了。
moudy
2024 年 4 月 9 日
你们都不在一个频道上。你在说买了房子装修该怎么弄。他在说怎么盖你那个房子。实际上他也不在底层,房子下面还有地基。地基下面还有岩层。
moudy
2024 年 4 月 9 日
@sunny352787 嵌入式程序员表示,较真起来没啥是不能崩的。曾经调试过一个应用崩溃,追下去是 runtime 崩溃,再查是 os 的 mutex 锁不住数据。接着追下去其实是两个 core 的同步没做对。最后是原因第三个 security core 的 firemware 中断权限调太高了....
KMpAn8Obw1QhPoEP
2024 年 4 月 9 日
@moudy 这就是应用开发跟系统开发的差距。。
Erroad
2024 年 4 月 9 日
大家都在刻意回避直接回答对方的问题罢了
adoal
2024 年 4 月 9 日
只做过本机原生可执行程序开发的,可能确实理解不了,在有 vm 的语言里,vm 在某种程度上相当于他那个技术栈里 hardware/os 的一部分功能。不过你如果遇到极端情况也有可能需要到 vm 层去调试。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1030932

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX