在线运行的代码报错怎么看?六种语言的读法
跑一段代码报错了,难点往往不是改错,而是先判断错在哪一层 —— 编译、运行、还是环境本身。这六种语言在浏览器里的失败方式差别很大,读法也不一样。
- Python 由 Pyodide 在浏览器本地运行、代码不上传,报错是标准 traceback,但它没有标准输入,input() 会直接抛错
- C++、Java、Go、Shell 走远端网关执行,编译错误与运行错误分开呈现,编译失败时不会有任何程序输出
- 退出码非零才是失败信号,Shell 脚本不会因为某条命令失败就整体中断,除非显式写了 set -e
- 状态栏的耗时是从发请求到拿到结果的往返时间,包含远端排队与编译,它不代表你的代码慢
- 网关不可用时会自动回退到备份服务,两条错误信息拼在一起出现,说明两层都失败了
#先分清错误来自哪一层
在线运行环境里的失败分三层:编译错误、运行错误、环境限制。三层的原因和改法完全不同,混在一起读只会越改越乱。
这六种语言的分层方式还不一样:编译型语言有独立的编译阶段,Python 和 Shell 直接进入运行,而 Python 又是唯一在浏览器本地跑的。
| 层 | 表现 | 该做什么 |
|---|---|---|
| 编译期 | 没有任何程序输出,只有编译器报错 | 修语法,暂时别管逻辑 |
| 运行期 | 有输出后中断,或退出码非零 | 读 traceback / 异常类型 |
| 环境限制 | 缺包、无输入、超时、沙箱限制 | 换写法或换工具,不是改代码 |
看到「没有任何输出」先别怀疑代码逻辑。编译型语言编译失败时程序根本没启动过,输出当然是空的 —— 这时候的输出栏里显示的是编译器的话,不是你的程序的话。
#Python:本地运行,报错最接近你熟悉的样子
Python 在这套工具里由 Pyodide(编译成 WebAssembly 的 CPython)跑在浏览器里,代码不上传,所以报错就是标准的 Python traceback。 首次要下载十几 MB 的运行时,之后走缓存。
它有两个和本地环境不同、但很容易被当成 bug 的差异:
- 没有标准输入:Pyodide 没有绑定 stdin,
input()会直接抛错。要演示交互式程序,把输入写成代码里的常量 - 第三方包有限:只支持 Pyodide 预编译过的那部分,标准库完整,
numpy这类常见库多半可用。报ModuleNotFoundError基本都是这一类,不是你写错了
因为执行用的是 runPythonAsync,顶层可以直接写 await,不需要自己套事件循环。标准输出与标准错误合并按顺序显示,不会像本地终端那样分成两股。
用 Python 在线运行 时如果确实需要 stdin,换 C++、Java、Go 或 Shell 那几个工具 —— 它们有输入框。
#编译型语言:编译不过就没有运行输出
C++、Java、Go 的执行都要先编译,编译失败时你看到的是编译器的话,程序一次都没跑过。 这条听起来 trivial,但它是「为什么什么都没输出」最常见的答案。
这几个工具走的是本站自建的执行网关 run.dsjson.com,网关不可用时自动回退到备份服务。代码会离开浏览器,所以不要放密码、密钥或内部地址。
一个容易误判的地方是耗时:状态栏显示的是从发请求到拿到结果的往返时间,包含远端排队与编译,所以几百毫秒到几秒都正常,不代表代码慢。
// 编译错误示例:这类问题不会有任何程序输出
#include <iostream>
int main() {
std::cout << "hi" << std::endl // 缺分号
return 0;
}用 C++ 在线运行、Java 在线运行、Go 在线运行 时,「标准输入」框里的内容会作为 stdin 传给程序,cin、scanf、Scanner、bufio.Reader 都能正常读。
网关和备份服务都失败时,两条错误信息会拼在一起给出。看到两段报错不用担心,那是设计如此 —— 它是让你判断「是网络问题还是服务问题」的唯一线索。
#Shell:只看退出码
Shell 脚本没有编译阶段,出错就是运行错误,最可靠的判据是退出码。 脚本非零退出时退出码会显示出来,标准错误与标准输出分开呈现。
但要注意一个行为差异:bash 默认不会因为某条命令失败就中断脚本,它会继续往下跑,最后一条命令的退出码才是整体退出码。要严格失败即停,必须在开头写 set -e。
脚本在一次性沙箱里执行,所以下面这几件事不会按预期工作:
- 读不到你的文件系统,本地路径全部无效
- 读不到你的环境变量,密钥和配置都是空的
- 访问不到内网,
curl内网地址只会超时
那不是语法错,是环境限制 —— 换个环境才能验证。
用 Shell 在线运行 验证语法、字符串处理、循环和管道组合都合适,read 也能从「标准输入」框读到内容。
#JavaScript:语法提示会误报模块代码
JS 在这套工具里是本地执行、即时报错,但语法提示有一类固定误报:顶层 import / export。 因为它用 new Function 试编译,把你的代码当函数体看。
- 顶层的
import/export会报语法提示(ESM 模块语法本来就不能出现在函数体里) - 顶层的
return反而不报(函数体里合法)
看到这类提示,先判断是不是模块语法,别急着改代码。它不是 linter,逻辑错误、未定义变量都不会报。
用 JavaScript 在线运行 可以快速验证一段算法,配合 文本差异对比 还能对比两个版本的输出差异。
#什么时候该用哪个工具
| 你想做的事 | 用哪个 | 关键差异 |
|---|---|---|
| 跑 Python 脚本、验证算法 | Python 在线运行 | 本地运行不上传,但没有 stdin |
| 验证一段 JS 逻辑 | JavaScript 在线运行 | 本地执行,模块语法会误报 |
| 交作业、验证编译是否通过 | C++ 在线运行 | GCC 13.2.0,有 stdin |
| 练习 Java 类与集合 | Java 在线运行 | 远端编译,编译错误优先修 |
| 验证并发或标准库用法 | Go 在线运行 | 远端执行,代码会上传 |
| 处理文本、验证管道组合 | Shell 在线运行 | 一次性沙箱,看退出码 |
选择顺序建议是:能本地跑的就别上传(Python、JS),需要真实编译器的再用远端那几个。这与 在线运行代码怎么用 里讲的沙箱限制是一套逻辑,那篇讲边界,这篇讲怎么读报错。
#常见问题
#为什么点了运行什么都没输出?
先看有没有编译错误。编译型语言(C++、Java、Go)编译失败时程序一次都没启动,输出栏里显示的是编译器的话。如果没有报错也没输出,检查程序是否真的打印了内容 —— 有些语言输出有缓冲,直到程序结束才刷新。
#Python 报 ModuleNotFoundError,是我写错了吗?
大概率不是。Pyodide 只能加载预编译过的包,标准库完整,numpy、pandas 这类常见库多半可用,冷门包和需要自编译 C 扩展的包装不上。确实要用某个包,就换成远端执行的方案。
#Segmentation fault 是什么意思?
程序访问了不属于它的内存,通常是指针没初始化、数组越界、或者递归太深。它和 Python 的 traceback 不同:段错误不会有任何「哪一行出错」的提示,只能靠自己在可疑位置打印日志定位。
#退出码 0 但结果不对,算什么错?
算逻辑错误。退出码只表示程序有没有正常结束,不表示结果对不对 —— 一个算错的程序完全可以正常退出。这类问题要看输出内容本身,必要时用 文本差异对比 把期望输出与实际输出比一遍。
#为什么同样的代码在本地能跑,在线就报错?
三类原因:缺少依赖库(在线环境只装了一部分)、缺少标准输入(本地你用键盘输入了)、以及环境差异(工作目录、环境变量、行尾换行)。先在报错里找这三条线索,比改代码快。
本文提到的工具
Python 在线运行工具,基于 Pyodide 在浏览器本地运行 Python 3 代码,无需安装环…
立即使用 →JavaScript 在线运行浏览器本地执行 JavaScript 代码,支持 console 输出与 async/await
立即使用 →Java 在线运行JDK 21 在线编译执行,支持标准输入与类方法示例
立即使用 →Go 在线运行Go 1.22 在线编译执行,支持标准输入与切片/结构体示例,浏览器直接查看编译与运行输出
立即使用 →C++ 在线运行GCC 13 在线编译执行,支持标准输入与多组示例代码,浏览器直接查看编译错误与运行结果
立即使用 →Shell 在线运行Bash 脚本在线执行,支持变量、循环、函数与管道,可填写标准输入,浏览器直接查看命令输出
立即使用 →