一、第一天:装个环境,心态先崩了
我教过不少人写代码,每次都说“Hello World很简单,几分钟就搞定”。直到我自己换新电脑重新配环境,才发现这句话有多离谱。
第一天装Python。官网下载安装包,一路Next,装完兴冲冲打开CMD敲python hello.py,结果给我弹了个'python' 不是内部或外部命令-。我愣了三秒才反应过来——安装的时候没勾那个“Add Python to PATH”-。卸载重装,勾上,再试,还是不行。重启CMD,终于通了。就这一个勾,浪费了我二十分钟。
接着装Java。JDK装好了,java -version能显示版本,但javac HelloWorld.java报错找不到或无法加载主类-。环境变量又没配。去系统设置里新建JAVA_HOME,Path里加%JAVA_HOME%\bin-,改完重启CMD-。配完了编译通过,但运行时又报错错误: 找不到或无法加载主类 HelloWorld-。查了半天发现是我文件名大小写写错了——helloworld.java和HelloWorld.java在Windows下没问题,但类名是HelloWorld,编译出来的class文件就叫HelloWorld.class,我运行时敲的是java helloworld,大小写对不上。改过来终于跑通了。
第一天总结:装了两个环境,踩了四个坑,花了快两个小时。就这还只是“能跑”,离“熟练”差得远。
二、第二天:标点符号,新手的噩梦
第二天我开始教一个朋友写Python。我让他照着我的屏幕敲:print("Hello, World!")。他敲完运行,报错SyntaxError: invalid syntax-。
我凑过去一看——print("Hello,World!")。括号是中文的,逗号是中文的,感叹号也是中文的-。我让他对比一下我的代码和他的代码有什么区别,他看了五分钟才发现“括号长得不一样”。改完英文括号,又报错,因为引号还是中文的。全改完终于通了,他长舒一口气说:“写代码怎么跟打仗似的。”
第二天最离谱的事发生在晚上。我让他自己写一个Java的Hello World,他自信满满地敲完,编译报错一堆非法字符: \uff1b-。我一看,分号是中文全角的。他说他明明切换了输入法,但Windows的中英文切换他还没熟练掌握,以为按了Shift就行,结果半角全角还是没切对-。
第二天总结:标点符号问题至少出现了七八次。对新手来说,肉眼区分中文括号()和英文括号()比想象中难得多。
三、第三天:缩进和括号,一对看不见的杀手
第三天他写Python的时候遇到了一个新问题——代码看起来完全一样,但运行报错IndentationError: expected an indented block-。原来他在if后面直接写了print,没有缩进。Python用缩进来区分代码块,而他之前写C和Java习惯了用花括号,完全没意识到缩进在Python里是语法的一部分-。
更搞笑的是他后来写了一段带if的代码,缩进用了空格和Tab混着来,Python直接报错TabError: inconsistent use of tabs and spaces in indentation。我帮他设置编辑器“将Tab转换为空格”之后才消停。
晚上他写C语言,printf("Hello World")忘了加分号-,编译报错expected ';' before '}'。他盯着代码看了十分钟没发现少了什么,最后我指给他看,他拍了一下桌子说:“就一个分号?”我说对,就一个分号,C语言里分号是语句的结束符-。
第三天总结:缩进和括号这类“看不见”的规则,比标点符号更隐蔽,因为它们不出现在屏幕上,新手很难自己发现。
四、第四天:文件名和类名,Java特有的折磨
第四天他开始正式学Java。我让他写一个HelloWorld.java,内容如下:
java
复制
public class hello {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
编译通过了,但运行时java hello报错错误: 找不到或无法加载主类 hello-。他一脸茫然。我说你文件名是HelloWorld.java,但类名叫hello,Java要求类名和文件名必须一致-。他改类名为HelloWorld,重新编译,运行,终于通了。
他松了一口气,然后我让他改一下文件名试试。他把HelloWorld.java改成了hello.java,类名还是HelloWorld,编译报错类HelloWorld是公共的,应在名为HelloWorld.java的文件中声明。他崩溃了:“文件名改一下都不行?”我说不行,Java就这么严格-。
晚上他又遇到了一个新问题——代码里String写成了string-,System写成了system-。Java是大小写敏感的,这些拼写错误编译时全报错。他抱怨说:“C语言里printf小写就行,Java怎么这么多规矩。”
第四天总结:Java的严格对新手来说是一道坎,但跨过去之后,你对“规范”的理解会深很多。
五、第五天:Go语言的模块,把我自己都绕进去了
第五天我换了个语言教他——Go。我以为Go比Java简单,结果自己先翻车了。我让他写一个hello.go:
go
复制
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
直接go run hello.go没问题。但我想教他编译成二进制,就让他执行go build,结果报错cannot find package-。我一看,他没有初始化go module。在Go 1.16之后,默认开启了module模式,不在module里的代码go build会报错-。我让他执行go mod init hello,再go build,终于生成了二进制文件。
然后我又踩了一个坑。我把hello.go挪到了桌面上,执行go build,报错说main.go找不到——因为go.mod里记录的模块路径还是原来的。我忘了在移动文件后重新初始化module。折腾了十分钟才想起来。
第五天总结:连我这个写过Go的人都翻车了,新手遇到这些问题只会更懵。Go的module机制虽然好,但对刚入门的人来说又是一个额外的认知负担。
六、第六天:Docker的Hello World,网络不配和
第六天我突发奇想,让他试试Docker的Hello World——docker run hello-world。我以为这是最简单的,结果直接卡住了。执行命令后,终端显示Unable to find image 'hello-world:latest' locally-,然后开始拉取镜像,接着报错Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: lookup registry-1.docker.io-——网络不通,DNS解析失败。
我帮他换了国内镜像源,改了/etc/docker/daemon.json,重启Docker服务,再试,终于拉下来了。但整个过程花了快四十分钟,就为了打印一行“Hello from Docker!”。
他问我:“这个比Python那个难在哪?”我说难在它的依赖不在你电脑上,在别人服务器上。网络不通,你就什么都干不了。
第六天总结:Hello World一旦涉及网络,复杂度就指数级上升。你以为只是打印一行字,实际上要跟镜像仓库、DNS、防火墙打一圈交道。
七、第七天:我把所有踩过的坑列了个清单
七天下来,我让他把踩过的坑整理成了一张表:
| 序号 | 问题 | 表现 | 解决方式 |
|---|---|---|---|
| 1 | Python没加PATH | 'python' 不是内部命令 | 重装勾选Add to PATH |
| 2 | 中文括号/引号 | SyntaxError: invalid syntax | 切换英文输入法 |
| 3 | 中文分号 | 非法字符: \uff1b | 切换半角标点 |
| 4 | 忘记引号 | SyntaxError: invalid syntax | 补上引号- |
| 5 | 括号不匹配 | SyntaxError: unexpected EOF | 补全右括号- |
| 6 | Python缩进错误 | IndentationError | 统一用空格缩进- |
| 7 | Tab和空格混用 | TabError | 设置编辑器自动转换 |
| 8 | C语言忘加分号 | expected ';' before '}' | 补分号- |
| 9 | Java类名和文件名不一致 | 找不到或无法加载主类 | 保持类名=文件名- |
| 10 | Java大小写拼错 | 找不到符号 | 注意String/System大写- |
| 11 | Go未初始化module | cannot find package | go mod init– |
| 12 | Docker网络不通 | dial tcp: lookup failed | 换国内镜像源- |
他盯着这张表看了半天,说了一句让我印象特别深的话:“原来‘Hello World很简单’这句话,是骗人的。”
八、最后说几句实在话
这七天我最大的感受是:我们这些老程序员已经忘了第一次有多难。你习惯了英文标点、习惯了大小写、习惯了环境变量、习惯了缩进规则,但这些对新手来说全是陌生的。你随口说一句“很简单”,他可能要在屏幕前坐半个小时,面对一堆看不懂的红色报错。
如果你正在教别人编程,请做好两件事:第一,坐在他旁边看着他敲,而不是丢一个教程链接就完事;第二,他报错的时候别急着告诉他答案,让他自己读一遍报错信息——哪怕读不懂,这个过程本身就在训练他“如何跟计算机对话”。
至于我自己,以后再也不会说“Hello World很简单”这句话了。七天二十个坑,哪一个都不简单。
