简介:面向大数据入门读者的实验一配套文档,系统讲解Linux操作与Hadoop操作的基础训练。内容围绕三个核心目标展开:掌握Linux虚拟机安装、熟悉常用Linux命令、完成Hadoop伪分布式安装,适合正在准备大数据课程实验或需要搭建单机实验环境的在校学生与自学者。压缩包内包含1个docx文件,大小289KB,文档结构清晰,覆盖实验目的、平台选择、操作命令详解与知识点总结,可直接打印或者对照步骤上机练习。目前已有974人学习下载,是同类入门实验中较常被参考的一份。文件重点演示cd、ls、mkdir、rmdir、cp、mv、rm、cat、tac等常用命令,并结合Hadoop 3.1.3给出伪分布式安装及基础Shell操作说明,包含WordCount实例验证思路;同时补充Java环境变量配置、tar压缩解压、find与grep检索等实用操作,帮助读者快速打通大数据实验的起步环节。
1. 听到 Hadoop 就头大:它到底是什么,这门实验到底在带你做什么
第一次接触大数据实操课,很多人都会在同一个地方懵住:课还没怎么开始,老师先让你把 Linux 虚拟机装起来,接着在里面敲一堆看不懂的命令,最后再装一个叫 Hadoop 的东西。这里的关键词其实只有两个——大数据和 Linux。Hadoop 是目前大数据处理绕不开的基础框架,它能用一堆普通电脑组成集群,一起处理海量数据;而 Hadoop 在 Linux 上运行最稳定、生态工具也最全。所以这堂入门实验的本质,就是带你做三件事:装出你的第一台 Linux 虚拟机、练熟最常用的 Linux 命令、再在单机上把 Hadoop 的伪分布式环境跑起来,亲手完成几个文件操作。如果你现在连“终端”在哪里都还不知道,完全不用慌,这篇就是给你准备的。读完你就能明白每一步在干什么,也能照着自己动手做一遍。
2. 先把地基打好:为什么 Windows 上必须装一台 Linux 虚拟机
很多新手拿到实验指导书的第一反应是:“我电脑就是 Windows,直接在 Windows 上装 Hadoop 不行吗?” 行,但你会把自己坑得很惨。这一章就把虚拟机这件事讲透,顺便给你一条能走通的安装路径。
2.1 为什么非要在 Linux 上跑 Hadoop
Hadoop 的设计目标、测试环境和主流生产部署,几乎全部围绕 Linux 展开。它的启动脚本是 Shell 脚本,它管理文件依赖 Linux 的用户权限体系,它生态里的大多数配套工具默认只发布 Linux 版本。你可以把 Hadoop 想象成一位在特定厨房里练了十年手艺的厨师,换一间厨房也能做菜,但处处不对劲。
在 Windows 上硬装 Hadoop 不是不可能,但你会遇到很多“别人没遇到过”的问题。比如教程里写的路径是 /usr/local/hadoop,Windows 上要改成盘符;教程里说用 chown 改文件归属,Windows 上没有这个概念。对一个零基础新手来说,跟着主流走就是少踩坑。
那虚拟机是什么?简单说,就是用软件在你现有电脑里“模拟出另一台完整电脑”。这台虚拟电脑有自己的硬盘、内存、网卡,你可以在里面安装 Ubuntu 系统。对你来说它只是个窗口里的桌面;对 Ubuntu 来说,它以为自己独占了一台机器。凡是教程里说 Linux 能做到的事,在虚拟机里都能做。
我第一次学的时候也觉得多此一举,后来才发现 Hadoop 的启动脚本全是 .sh 文件,这些脚本在 Linux 里就是原生应用,双击不行、要在终端里跑,这条路走通之后,后面所有实验都顺畅了。
2.2 用 VirtualBox 装 Ubuntu:可视化步骤清单
实验平台推荐使用 VirtualBox 和 Ubuntu 18.04(或 16.04)。这两个都是免费资源,下载渠道在各自官网就能找到。整个安装过程大概半小时,核心步骤是这么几条:
- 在 Windows 上安装 VirtualBox。一路“下一步”即可,安装完成后建议重启一次电脑,让驱动生效。
- 下载 Ubuntu 18.04 的桌面版镜像文件(后缀是 .iso)。镜像就是一张“虚拟光盘”,虚拟机要依靠它来安装系统。
- 打开 VirtualBox,点击“新建”,给虚拟机起个名字,类型选 Linux,版本选 Ubuntu 64-bit。
- 分配内存。建议给 2GB 到 4GB。如果你电脑内存总共只有 8GB,给虚拟机 2GB 也能跑,只是慢一点;低于 2GB 会非常吃力。
- 创建虚拟硬盘。建议 20GB 起步,类型选默认的 VDI 就行。
- 设置里加载 Ubuntu 镜像:在“存储”里把刚才下载的 .iso 挂载到光驱位置,然后启动虚拟机。
- 虚拟机屏幕里会进入 Ubuntu 安装界面,选“Install Ubuntu”,按提示选语言、时区、键盘布局,设置一个用户名和密码。
- 安装完成后重启,进入 Ubuntu 桌面,整个流程就走完了。
提示:安装过程中如果虚拟窗口很小,先别管,装完系统后装“增强功能”就能全屏使用。
装完系统先别急着开始,还有三件小事要处理,见下一节。
2.3 装完系统先做三件小事
第一件是更新软件源。终端里执行 sudo apt update,作用是让系统拿到最新的软件清单,后面的安装才不会找不到包。
第二件是安装 SSH 服务。这一步和本实验强相关:Hadoop 的各个角色之间通信要用 SSH,伪分布式虽然在一台机器上跑,但 NameNode 连接 DataNode 时会用它。所以我们要装 openssh-server,并配置免密登录。听起来很玄,其实就是“办一张门禁卡”,让 Hadoop 进程自己进门不用输密码。
# 安裝 SSH 服务端 sudo apt install -y openssh-server # 生成一张“门禁卡”(密钥),按三次回车即可 ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa # 把公钥写进授权列表 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 测试免密登录,如果能直接进到 shell 说明成功(退出用 exit) ssh localhost第三件是确认 Java 环境。Hadoop 跑在 Java 之上,实验要求配置 JAVA_HOME,前提是系统里已经装了 JDK。在终端执行 java -version,如果提示找不到命令,先去装一个 JDK,记住你安装的路径,后面配置环境变量要用。
2.4 初次登录需要建立的两个直觉
第一次进 Ubuntu 桌面,大部分人都会有点迷。你需要建立两个直觉:
第一,终端是一个“和电脑对话的输入框”。图形界面里点鼠标能做的事,在终端里敲命令也能做,而且更适合批量操作。终端通常在左侧任务栏里,或者按 Ctrl+Alt+T 打开。
第二,sudo 的意思是“以管理员权限执行这条命令”。类比 Windows 里的“以管理员身份运行”,它不改变你的身份,只是让一条命令拥有更高权限。所以看到 sudo 开头,就是在做系统级操作。
3. 命令练熟再进下一步:Linux 常用的 17 个命令一次讲明白
实验要求掌握的 Linux 命令一共有十几条,听起来很多,但它们其实分成了清晰的几组。你不需要背,跟着下面的场景过一遍,重点感受“每条命令解决什么问题”,做完实验自然就记住了。
3.1 先学会认路:cd、ls、pwd
Linux 里所有的文件都放在一个以 / 开头的目录树里。cd 是切换目录,ls 是列出目录内容,pwd 是告诉你现在在哪。这三条命令就像手机地图里的“定位 + 浏览”。
# 切换到 /usr/local 目录 cd /usr/local # 返回当前目录的上一级 cd .. # 回到当前登录用户的主文件夹(也就是家目录) cd ~ # 查看 /usr 目录下有哪些文件和目录 ls /usr # 显示当前完整路径 pwd这里有个新手很容易迷糊的点:~/usr/local 和 /usr/local 不是一回事。~ 是当前用户的主目录,/ 是系统根目录。一条命令带不带斜杠开头,含义可能完全不同。遇到路径不确定时,先 pwd 确认自己站在哪里。
3.2 新建和删除目录:mkdir、rmdir、touch
mkdir 是新建目录,rmdir 是删除空目录,touch 是创建空文件。实验里有个经典练习,在 /tmp 下创建 a1/a2/a3/a4 这种多级目录,用 mkdir -p 一步到位。
# 进入 /tmp,创建目录 a cd /tmp mkdir a # 创建多级目录 a1/a2/a3/a4 mkdir -p a1/a2/a3/a4 # 删除空目录 a rmdir a # 删除多级空目录 a1/a2/a3/a4(会从最内层开始删) rmdir -p a1/a2/a3/a4 # 在 /tmp 下创建一个空文件 hello,ls -l 可以查看它的时间 touch hellormdir 只能删空目录,如果里面有文件就会报错。这是 Linux 的一个保护机制,防止你误删有内容的目录。想删非空目录,要等下文的 rm -r 出场。
3.3 文件的复制、移动、改名、删除:cp、mv、rm
这四条是日常用得最频繁的命令。cp 负责复制,mv 负责移动和改名,rm 负责删除。实验中还涉及 chown 这个命令,用来修改文件所有者,也是文件操作的重要一环。
# 把家目录下的 .bashrc 复制到 /usr 下,并重命名为 bashrc1 cp ~/.bashrc /usr/bashrc1 # 在 /tmp 下新建目录 test,再复制到 /usr 下 mkdir /tmp/test cp -r /tmp/test /usr/ # 把 /usr/bashrc1 移动到 /usr/test 目录里 mv /usr/bashrc1 /usr/test/ # 把 /usr/test 重命名为 test2 mv /usr/test /usr/test2 # 删除 /usr/test2 里的 bashrc1 rm /usr/test2/bashrc1 # 删除整个 test2 目录(-r 表示递归删除) rm -r /usr/test2 # 把 hello 文件所有者改成 root(需要管理员权限) sudo chown root /tmp/hello特别注意 rm -r 和 rm -rf。Linux 删除文件没有回收站,删了就真的没了。r 表示递归删除目录里的所有内容,f 表示强制删除不询问。新手对这两个参数一定要保持敬畏,不确定自己在删什么的时候,先 ls 看清楚再动手。
3.4 查看文件内容:cat、tac、more、head、tail
这五个命令都是“打开文件看内容”,但视角不同。实验里反复拿家目录的 .bashrc 做练习,你跟着过一遍就有感觉了。
| 命令 | 行为 | 适合场景 |
|---|---|---|
| cat | 从头到尾一口气输出全部内容 | 文件短的时候 |
| tac | 从最后一行开始反向输出 | 偶尔想倒着看 |
| more | 一页一页翻动,按空格翻页 | 文件很长、想慢慢看 |
| head | 只看开头,默认 10 行 | 快速确认格式 |
| tail | 只看结尾,默认 10 行 | 看日志最新输出 |
# 正着看 .bashrc 全部内容 cat ~/.bashrc # 反着看 .bashrc tac ~/.bashrc # 分页查看,按 q 退出 more ~/.bashrc # 查看前 20 行 head -n 20 ~/.bashrc # 查看最后 20 行 tail -n 20 ~/.bashrchead 和 tail 的 -n 参数表示“几行”,这是最常见的用法。等你以后接触了 Hadoop 日志,会经常用 tail 看日志尾部的最新报错信息,那时你就知道这会比打开整个文件高效多少。
3.5 查找、打包、搜字符串:find、grep、tar
find 按名字找文件,grep 在文件内容里找字符串,tar 负责打包和解压。这三个都是“检索类”命令,方向不同:find 管文件位置,grep 管内容匹配,tar 管归档搬运。
# 在家目录下找文件名为 .bashrc 的文件 find ~ -name ".bashrc" # 在 .bashrc 里查找字符串 examples,带行号显示 grep -n "examples" ~/.bashrc # 在根目录 / 下新建文件夹 test,然后打包成 test.tar.gz cd / tar -zcvf test.tar.gz test # 把 /test.tar.gz 解压到 /tmp 目录 tar -zxvf /test.tar.gz -C /tmptar 的参数看起来吓人,其实拆开记就行:z 表示用 gzip 压缩,c 表示创建打包文件,v 表示显示过程,f 表示后面跟的是文件名;解压时把 c 换成 x,再补一个 -C 指定解压目标目录。这套记法能覆盖你 90% 的使用场景。
3.6 配置环境变量:让命令“永久认识自己”
实验的最后一步不是命令,而是配置环境变量。它解决一个实际问题:每次打开终端,系统怎么知道你的 Java 装在哪个路径?答案是提前把答案写进一个叫 ~/.bashrc 的文件里,终端一启动就会自动读它。
# 用 vim 打开 .bashrc vim ~/.bashrc # 在文件末尾加两行(把路径替换成你实际的 JDK 安装路径) export JAVA_HOME=/usr/lib/jvm/你的JDK路径 export PATH=$PATH:$JAVA_HOME/bin # 保存退出:先按 Esc,输入 :wq 再回车 # 让配置立刻生效 source ~/.bashrc # 验证:输出 JAVA_HOME 的值 echo $JAVA_HOME这里最容易翻车的点是忘记 source。改了 .bashrc 之后,当前终端不会自动更新,必须执行 source ~/.bashrc,改动才算真正生效。如果你发现 echo $JAVA_HOME 输出是空的,十有八九就是漏了这一步。
4. Hadoop 伪分布式安装:让一台电脑假装一个集群
Linux 命令练完,接下来就是重头戏:装 Hadoop。这一章先讲清“伪分布式”到底是个什么原理,再带你走一遍从下载到验证的完整流程。
4.1 伪分布式是什么:一个人分饰多角
真实的大数据集群,是很多台服务器各司其职:有的节点专门管“文件目录和档案索引”,叫 NameNode;有的节点专门存“实际文件内容”,叫 DataNode;还有节点负责任务调度,叫 ResourceManager。每台机器独立运行,通过网络通信。
伪分布式的意思是:没有多台机器,只有你这一台虚拟机,但要模拟出整个集群的逻辑。怎么办?同时启动多个进程,每个进程扮演一个角色。你的电脑既当 NameNode 又当 DataNode,还当 ResourceManager。看起来是集群,实际上都是同一台机器的进程。
这个“伪”字很重要。它能让你把集群的目录结构、文件上传下载、启动停止这些操作完整跑一遍,等以后接触真集群,命令几乎一模一样,只是机器数和配置项更多。对入门者来说,这是性价比最高的环境。
4.2 下载、解压、准备环境
Hadoop 官网提供编译好的压缩包,本实验使用的是 3.1.3 版本。下载后得到一个 hadoop-3.1.3.tar.gz 文件,我们需要把它解压到 /usr/local/hadoop,这个路径是实验里反复会用到的地方。
# 先确保你已进入下载文件所在目录,然后解压到 /usr/local sudo tar -zxvf hadoop-3.1.3.tar.gz -C /usr/local # 改目录归属,避免每次操作都要 sudo(把“你的用户名”换成实际登录名) sudo chown -R 你的用户名 /usr/local/hadoop # 验证版本,看到版本号说明解压和环境变量都到位了 hadoop version如果 hadoop version 提示找不到命令,回到第 3 章最后一步,检查 JAVA_HOME 是否配置并 source 生效。这一步不过,后面所有操作都不必开始。
4.3 核心配置文件到底改什么
Hadoop 的配置分散在 /usr/local/hadoop/etc/hadoop/ 目录下的多个 XML 文件里。新手最容易犯的错是想一口气搞懂所有配置。不用急,这次实验只动两个文件。
core-site.xml 是全局核心配置。我们需要告诉 Hadoop:默认文件系统地址是什么、临时数据放在哪里。
<configuration> <!-- 默认文件系统,端口 9000 是 NameNode 的通信端口 --> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <!-- 临时数据目录,NameNode 和 DataNode 的元数据都存在这里 --> <property> <name>hadoop.tmp.dir</name> <value>/usr/local/hadoop/tmp</value> </property> </configuration>hdfs-site.xml 是 HDFS 的专属配置。最关键的一项是把副本数设为 1。默认副本数是 3,意思是同一份数据要复制到三台机器;你只有一台机器,不改成 1,系统会一直想复制却找不到地方,日志里各种报错。
<configuration> <!-- 副本数设为 1,因为伪分布式只有一台机器 --> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration>提示:以后跑 WordCount 等任务时,通常还要配置 yarn-site.xml。到那一步再按实验指导书补,今天先把 HDFS 跑通。
4.4 格式化、启动、验证
配置改完后,启动流程分三步:格式化、启动 HDFS、启动 YARN。格式化这个动作容易让人紧张,我用白话解释一下:
NameNode 启动前要先建立一个“档案索引”,记录整个文件系统有哪些目录和文件。hdfs namenode -format 就是初始化这个索引,类似于新硬盘买回来先分区格式化。它只会清空 HDFS 的元数据,不会删除你的安装文件。
# 第一步:初始化 NameNode 的元数据 hdfs namenode -format # 第二步:启动 HDFS(启动 NameNode、DataNode、SecondaryNameNode) start-dfs.sh # 第三步:启动 YARN(启动 ResourceManager、NodeManager) start-yarn.sh # 第四步:用 jps 查看当前 Java 进程,验证各角色是否都起来了 jps执行完 jps 后,如果一切正常,你应该看到 5 个进程:NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager。少一个就要回到第 5 章排查。
最后是浏览器验证。打开浏览器访问 http://localhost:9870,这是 Hadoop 3.x 的 HDFS 管理界面。能看到页面,并且首页显示 Live Nodes 为 1,你的伪分布式集群就算真正跑起来了。注意端口不是常见的 8080 或者 50070,Hadoop 3 默认是 9870。
5. 第一次启动就翻车:Hadoop 安装常见坑与排查指南
环境搭建这一步,几乎所有新手都会在某个地方卡住。我自己第一次搭的时候也折腾到半夜。下面四条是最典型的坑,每一条按“现象→原因→解决”的顺序写,你遇到类似的问题直接对照着查。
5.1 Datanode 起不来,Live Nodes 显示 0
现象:启动完成后,jps 里怎么都找不到 DataNode 进程,或者浏览器访问 9870 端口,发现 Live Nodes 数量是 0,明明 NameNode 还活着。
原因:八成是你之前不小心执行了多次 hdfs namenode -format。每次格式化都会生成一个新的集群 ID(Cluster ID),而 DataNode 启动时,会拿着自己上次记住的集群 ID 去和 NameNode 核对。两边对不上,DataNode 就拒绝启动。这就好比你搬家换了新小区门禁密码,旧门禁卡自然刷不开门。谁造成的最多?反复格式化的人。
解决:让 DataNode 忘掉旧 ID,重新认识新 ID。具体做法是找到前文 core-site.xml 里 hadoop.tmp.dir 指定的数据目录,把里面的数据删掉,然后重新格式化。
# 先停掉所有 Hadoop 进程 stop-all.sh # 删除临时数据目录(路径要和 core-site.xml 里配的一致) rm -rf /usr/local/hadoop/tmp # 重新初始化 NameNode hdfs namenode -format # 重启集群 start-all.sh # 再次确认进程 jps之后再去 9870 页面刷新,Live Nodes 应该显示 1。记住一个血泪经验:正常运行的集群,永远不要去动格式化命令。
5.2 浏览器打不开 9870 页面
现象:输 http://localhost:9870 之后,页面一直转圈、拒绝连接,或者显示“无法访问此网站”。
原因:分三种情况。第一种是 HDFS 根本没启动成功,jps 里看不到 NameNode;第二种是系统防火墙拦截了 9870 端口;第三种是你在浏览器里访问的地址写错了,比如把 localhost 写成了虚拟机的 IP,而那个 IP 不对。
解决:先做诊断,按顺序检查。第一步,回终端执行 jps,看 NameNode 进程在不在。不在,说明启动失败,回去看 5.1。第二步,NameNode 在但页面打不开,执行 sudo ufw status 看防火墙是否开启,如果是,执行 sudo ufw allow 9870 放行端口。第三步,确认访问地址:在虚拟机本机用 http://localhost:9870 访问,别用别的地址。
5.3 配置了环境变量,重开终端又提示命令找不到
现象:上次明明 export 了 JAVA_HOME,hadoop version 也能用,重开一个终端窗口后,再敲 hadoop version 又提示 command not found。
原因:你只在当前终端里执行了 export,没有把 export 写进 ~/.bashrc。export 的作用范围仅限于当前终端窗口,关掉就没了。你误以为“我配过了”,其实是“我临时用了一次”。
解决:把 export 语句写进 ~/.bashrc 文件,然后 source 一下。如果你已经写进了 .bashrc 还是不行,检查是不是写错行——比如写到了 export PATH 之外的地方,导致语法被注释掉(开头多了 #)。改完后执行 echo $JAVA_HOME,能输出路径才算真配好。
5.4 遇到问题就想 rm -rf 清空重来,结果越搞越糟
现象:集群某个进程起不来,你第一反应是把整个 hadoop 安装目录删掉重新解压,或者不确认进程状态就格式化,结果问题没解决,反而把原本好的部分也弄坏了。
原因:没分清“安装文件”和“运行时数据”。安装文件是解压出来的那一整套程序,删掉重来很伤;运行时数据是 tmp 目录里由集群自己生成的元数据,出问题时需要清理的是这些。这两者的位置不同,作用更不同。同时,删文件前没先停进程,系统还在写这些目录,删一半锁死,下次启动自然起不来。
解决:制定一条纪律:动手删除之前,先执行 jps 确认所有进程已停止;再确认目录路径,只处理 core-site.xml 里 hadoop.tmp.dir 指向的目录,而不是整个 hadoop 安装文件夹。不放心的话,把同名目录复制一份存到别处,再删。格式化命令执行前,同样按这条纪律走一遍流程。
6. 用 Shell 指挥 Hadoop:从这次实验到下一个实验
环境跑通了,最后一步是亲手用命令操作 HDFS,感受一下“分布式文件系统”和本地文件系统的区别。这也是实验的收尾,做完它,你的第一站就算真正走完了。
6.1 hdfs dfs:像操作本地文件一样操作分布式文件系统
HDFS 有一套自己的命令体系,以 hdfs dfs 开头。你可以把它理解成“Hadoop 版的文件管理器”,只不过操作不是用鼠标,而是用命令。
# 为 hadoop 用户在 HDFS 中创建用户目录(-p 表示父目录不存在时自动创建) hdfs dfs -mkdir -p /user/hadoop # 在刚才的目录下创建一个 test 文件夹 hdfs dfs -mkdir /user/hadoop/test # 查看目录内容,确认 test 已存在 hdfs dfs -ls /user/hadoop/test # 把 Linux 本地家目录下的 .bashrc 上传到 HDFS 的 test 文件夹 hdfs dfs -put ~/.bashrc /user/hadoop/test/ # 再查看一次,能看到 .bashrc 文件就在上面 hdfs dfs -ls /user/hadoop/test/ # 把 HDFS 里的文件下载回本地 /usr/local/hadoop 目录 hdfs dfs -get /user/hadoop/test/.bashrc /usr/local/hadoop/重点理解一下路径的差别:这里的 /user/hadoop 不是本地磁盘上的目录,而是 HDFS 内部的一个命名空间。它看起来像 Linux 路径,其实完全独立,相当于一个“网盘目录”。你写的文件上传到了 HDFS 里,和本地 /usr/local/hadoop 完全不是一回事。这一点理解了,后面学 HDFS 的读写原理会轻松很多。
6.2 接下来怎么走
做完这个实验,你已经具备了三项能力:会装 Linux 虚拟机、会基本 Linux 操作、会把 Hadoop 伪分布式跑起来。下一步建议这么走:
第一,跑一遍 Hadoop 自带的 WordCount 实例。它可以算作 Hadoop 的“hello world”,几分钟就能跑完,能跑通就说明你的环境完全正常。实验指导书里通常会给出明确命令,照着执行,观察输出结果即可。
第二,趁热打铁理解三个概念:块、副本、元数据。刚才操作过 HDFS,这三个词就不再是抽象理论了——你上传的文件被切成块存进 DataNode,副本数由配置决定,文件的所有目录信息都由 NameNode 管理。把这三者的关系想清楚,HDFS 的原理就算入门了一半。
第三,往编程方向走一步。下一个实验通常是 HDFS 编程,用 Java 或 Python 写一个程序,连接集群完成文件上传下载。到那时候你会发现,今天在 Shell 里敲的每条命令,都能在代码里找到对应的 API 调用,两边一对照,学得会特别快。
从那以后,我每次做 Hadoop 相关的实验,都强制自己先开一个终端执行 jps,确认进程状态,再决定下一步做什么;动手格式化之前,永远先看一眼 core-site.xml 里配的目录路径。这个习惯帮我挡掉了无数个本可避免的深夜调试。这份资源把从零到跑通的路都铺好了,剩下的就是你亲手敲一遍。希望帮到你。
本文还有配套的精品资源,点击获取