
嵌入式学习找工作第十七天--第一个项目Linux个人博客走到第十七天这个节点算是一个值得停下来认真复盘的位置。前面两周多的时间里大概率已经啃完了 Linux 基础命令、vim 的基本操作、环境变量的概念甚至可能被 gcc 编译器的各种报错折磨过几轮。但说实话这些零散的知识点如果不落到一个完整的项目里面试时很难形成战斗力。我当时的策略是第一个项目不选复杂的嵌入式板级开发而是先做一个看起来不太嵌入式的 Linux 个人博客。这个选择后来被证明非常正确今天这篇就是围绕这个项目完整展开的记录包括学习路线上为什么这么做、环境怎么搭、技术怎么选、部署时踩了哪些坑以及最后怎么把项目变成面试素材。很多嵌入式初学者会有一种误解觉得找工作拼的是板子玩得有多深驱动写得有多花于是急着去搞 ARM 开发板、内核移植、驱动编程。但实际上企业招一个应届生或者转行者最看重的是你是否具备完整的项目经验以及你对 Linux 系统本身的理解。个人博客这个项目虽然不涉及硬件但它能逼着你把 Linux 的系统管理、网络配置、服务部署、故障排查全部过一遍——这些恰恰是嵌入式 Linux 开发中每天都要打交道的东西。往下看我会把每一步怎么走、为什么这么走都交代清楚。1. 嵌入式学习第十七天为什么第一个项目选了个人博客1.1 学习路线推进到这个节点项目驱动比继续刷课更重要第十七天是一个很尴尬的时期。说基础吧你确实懂一些了ls、cd、grep、ps、kill这些命令已经用得挺顺说深入吧真要让你独立分析一个系统问题又感觉哪哪都是漏洞。这时候如果继续埋头刷课效果会越来越差因为大脑已经进入知识饱和期输入的东西缺乏落点。我当时的判断是必须用一个完整的、可展示的项目来检验这十七天的积累。项目不需要大但一定要完整——从零开始搭建、配置、部署、排错、上线整个过程缺一不可。个人博客正好满足这个要求它不涉及复杂的业务逻辑但覆盖了 Linux 服务器操作的几乎所有高频场景。你在部署过程中会遇到网络配置问题、权限问题、端口占用问题、服务启动失败问题这些问题每一个都是嵌入式开发中的熟人。提示第十七天做项目的另一个好处是项目带来的正反馈能帮你扛过后续更枯燥的阶段。嵌入式学习的中后期会涉及大量的交叉编译、驱动调试那种短期内看不到成果的挫败感需要一个已经跑通的项目来支撑信心。1.2 博客项目对嵌入式的三个隐藏价值不只是写文章这么简单第一个价值是命令行熟练度的质变。平时敲命令是跟着教程走c盘的路径切到虚拟机的/home目录是一种状态但当你需要自己在服务器上创建目录、移动文件、修改权限、重启服务、查看日志时命令就成了解决问题的工具而不是练习题。这种用命令解决真实问题的感觉刷多少遍教程都替代不了。第二个价值是对 Linux 系统运行机制的理解。部署博客要装 Nginx、要配置 systemd 服务、要处理防火墙规则、要申请 HTTPS 证书每一个环节都在和你 Linux 的基础知识对话。比如你执行systemctl start nginx你知道它在启动一个守护进程但你未必清楚这个进程的启动脚本在哪、它的运行日志怎么查看、它为什么启动失败。博客项目会逼你把这些问题逐一搞清楚。第三个价值是面试时有东西可讲。嵌入式岗位的面试官普遍喜欢考察 Linux 基础而我独立部署过一个 Linux 服务可以自然带出进程管理、网络通信、文件系统权限等一系列话题。比起干巴巴地背八股用一个真实项目串起来讲可信度和深度完全不一样。尤其是当面试官追问你部署过程中遇到什么问题时你现场讲一个排查故事比背十道面试题都有说服力。2. 部署环境准备VMware 里跑 Ubuntu这些细节决定你是否五分钟放弃2.1 VMware Workstation 个人免费版与虚拟机参数取舍准备阶段最先遇到的就是虚拟化环境选择。目前 VMware Workstation Pro 已经对个人用户免费用个人邮箱注册一个账号就能拿到正版授权这一点体验很好。当然你也可以用 VirtualBox完全开源免费但我在实际对比中觉得 VMware 在 Windows 11 上的兼容性和稳定性表现更好尤其是 USB 设备透传、虚拟机快照这些功能用起来更顺手。创建虚拟机时的参数分配我的建议是别太抠门也别太奢侈。如果你的电脑是 16GB 内存给虚拟机分配 4GB 内存、2 个处理器核心、60GB 虚拟磁盘是比较合理的组合。磁盘大小可以稍微给宽一点因为后面要装编译工具链、下载源码包空间很快就吃掉了。需要注意的一点是虚拟磁盘默认会动态增长所以给 60GB 并不等于立刻占满你宿主机 60GB 空间放心分配就行。注意Windows 11 宿主机默认开启了基于虚拟化的安全VBS和内核隔离这些特性会和 VMware 的虚拟化层互相干扰导致虚拟机运行时 CPU 占用偏高、响应变慢。如果你发现 Ubuntu 在虚拟机里明显卡顿可以去 Windows 安全中心里暂时关闭内核隔离之后虚拟机的流畅度会明显改善。这个问题在网上讨论很多属于 Windows 11 VMware 的一个经典坑。2.2 Ubuntu 版本选择和换源apt 装包慢到怀疑人生先换源版本上我建议使用 Ubuntu 22.04 LTS而不是 24.04 或更激进的非 LTS 版本。原因很简单LTS 版本有五年支持周期软件源的兼容性最好网上针对 22.04 的教程也最多。个人博客这种项目用不到最新内核的特性稳定压倒一切。装完系统后第一个必须做的操作是换源。Ubuntu 默认的 apt 软件源在国外服务器上国内网络环境下执行apt update经常只有几十 KB/s装一个 Nginx 可能要等十分钟。换成清华或阿里云的镜像源之后速度能提升到几 MB/s体感完全不一样。具体操作上Ubuntu 22.04 的源配置在/etc/apt/sources.list先把原文件备份再用编辑器把源地址替换为镜像站地址。这里有一个细节不同版本 Ubuntu 的源格式不一样22.04 是 deb 开头的经典格式24.04 换成了 deb822 格式复制源内容的时候一定要确认版本匹配否则apt update会报错。换源完成后再执行sudo apt update sudo apt upgrade顺手把系统更新到最新状态。这一步做完了后面装任何软件都会顺畅很多。2.3 网络模式选 NAT 还是桥接以及快照这个救命功能VMware 默认的网络模式是 NAT虚拟机通过宿主机共享 IP 访问外网宿主机之外的设备无法直接访问虚拟机。这个模式下虚拟机上网没问题但如果你想让手机或其他电脑通过局域网访问博客就必须要切换到桥接模式。桥接模式相当于虚拟机直接接入物理网络拥有和宿主机同一网段的独立 IP其他设备可以直接访问。我的建议是部署前期全程用 NAT 模式就够了先把搭建流程跑通等真正需要对外展示时再切换到桥接模式。两种模式切换只需在虚拟机设置里改一下不影响系统内的配置但要注意切换后 Ubuntu 可能因为 IP 变化而需要重新获取地址执行sudo dhclient -v或重启网络服务就行。快照功能是 VMware 里被严重低估的一项能力。在干净的 Ubuntu 系统上做完更新、换源这些操作后立即创建一个快照。后面无论你把系统折腾成什么样——装了一堆奇怪的包、改了某个配置导致系统起不来——都可以一键回到这个干净的初始状态。对我这种喜欢边学边试错的人来说快照就是一张无限次使用的后悔药。强烈建议在关键节点都留一个快照比如刚装完系统、换源后、Nginx 部署成功后。每次快照只需几秒钟关键时刻能救你一命。3. 技术选型Hexo、Hugo 还是 WordPress嵌入式学习者该听劝3.1 静态博客生成器的逻辑不需要数据库不需要 PHP这才是适合新手的方案部署博客前会面临一个经典的选型问题用 WordPress 还是 HexoWordPress 是动态博客系统功能强大、插件丰富但它的运行要依赖 PHP 环境和 MySQL 数据库等于你在博客部署之外还要先搞定一套完整的 Web 运行环境。对嵌入式学习者来说这套东西的复杂度会带来大量与目标无关的干扰你会花很多时间去处理 PHP 版本兼容、数据库配置、后台权限管理却和 Linux 底层的知识关联不大。静态博客生成器Hexo、Hugo 这类的思路完全不同。它做的事情很简单你本地用 Markdown 写文章它把 Markdown 渲染成一个纯静态的 HTML 网站然后你把整个文件夹上传到服务器由 Nginx 这类 Web 服务器直接托管。没有数据库没有 PHP没有后台。访问者看到的每一个页面都是提前生成好的静态文件。这种方案对嵌入式学习者的好处是显而易见的。第一技术栈非常干净整个链路上你只需要理解 Nginx 如何提供静态文件服务就能把全链路讲清楚第二排错非常简单页面打不开就三种可能文件没传上去、Nginx 配置不对、端口被防火墙拦了。不会出现动态网站那种页面 500 了但不知道是 PHP 还是数据库出了问题的窘境第三本地写作的习惯完全符合工程师的表达方式——Markdown 本身就是为技术人员设计的书写格式。3.2 我的选型结论本地写 Markdown服务器上 Nginx 托管具体选型上我推荐 Hexo不是因为它比 Hugo 更强而是因为它的中文社区资料极其丰富遇到的问题几乎都能搜到现成的解决方案。Hugo 的构建速度确实更快但那点速度差在个人博客这种体量下根本感知不到。Hexo 的 Node.js 环境安装也比较友好虽然要装 Node.js但整个流程在 Windows 下都有成熟的教程可以参考。项目的工作流是这样的本地安装 Node.js 和 Hexo初始化一个博客目录选择一个顺眼的主题然后用hexo new post 文章名创建新文章在你的 Markdown 编辑器里写作最后执行hexo clean hexo generate生成静态文件。生成的静态文件默认放在public目录下这就是一个完整的网站可以直接扔给 Nginx 托管。上传这一步我用的是scp命令把本地public目录整包复制到服务器的/var/www/blog目录。为什么用 scp 而不是 Git因为 scp 的语义最直白不需要在服务器上配置 Git 仓库也不需要处理钩子脚本。当然如果你对 Git 更熟用 Git 做版本管理也没问题还能顺便练一练 Git 的使用。我建议先把 scp 的方案跑通后面再逐步引入 Git不要一开始就把技术栈复杂度拉满。提示嵌入式学习过程中的所有工具都遵循同一个原则——在满足需求的前提下选择最简单的方案。个人博客的目的是让你完整跑通 Linux 服务部署流程而不是让你变成一个 Web 全栈工程师。分清主次才不会在无关的技术细节里耗掉太多时间。3.3 Nginx 配置解析从目录列表到真正能访问的网站Nginx 的安装很简单sudo apt install nginx一步到位。装完默认会启动此时在浏览器访问虚拟机的 IP应该能看到 Nginx 的欢迎页面——这是第一个里程碑说明 Web 服务的底层链路基本是通的。但默认配置只能让你看到 Nginx 的欢迎页离我的博客上线还差一步要把 Nginx 的站点根目录指向/var/www/blog。Nginx 的站点配置在/etc/nginx/sites-available/目录下默认有一个default文件。我的做法是新建一个博客专用的配置文件内容大概这样server { listen 80; server_name your-domain.com; # 没有域名就先填服务器 IP root /var/www/blog; index index.html; location / { try_files $uri $uri/ 404; } access_log /var/log/nginx/blog.access.log; error_log /var/log/nginx/blog.error.log; }配置写好后把这个文件软链接到/etc/nginx/sites-enabled/然后执行sudo nginx -t检查语法。这一步非常重要Nginx 对配置文件语法错误是零容忍的有错误会直接拒绝启动。确认nginx -t输出syntax is ok后执行sudo systemctl reload nginx让配置生效。此时刷新浏览器如果你的public目录已经上传到了/var/www/blog博客就应该能看到了。try_files $uri $uri/ 404这一行值得多说一句它的意思是当请求到来时先按路径查找对应的静态文件找不到就按目录查找再找不到就返回 404。对纯静态博客来说这一行已经足够优雅地处理所有访问路径了。4. 从部署到公网访问实测踩过的坑和完整排查过程4.1 第一次访问失败的现场域名、端口、防火墙三连排查博客文件上传完了Nginx 配置也改好了浏览器打开网站却是无法访问此网站。这是部署过程中最经典的一幕几乎每个人都会遇到。我当时花了接近一个小时才把问题彻底定位。这里把完整的排查链条复盘出来下次你再遇到就能直接照方抓药。排查的第一步是确定问题范围。先在虚拟机本机执行curl http://localhost如果返回了博客的 HTML 内容说明 Nginx 服务和博客文件都是正常的问题出在外部访问这个环节。如果 curl 都不通说明问题在 Nginx 服务本身比如没启动、配置文件有语法错误、日志目录没权限。在 curl 本机通的情况下第二步检查防火墙。Ubuntu 默认安装了 ufw 防火墙执行sudo ufw status verbose查看状态。如果显示Status: active并且输出里没有80/tcp ALLOW这一行那问题就找到了。执行sudo ufw allow 80/tcp后立即测试访问。这一步是初学者最容易漏掉的地方因为 Nginx 装好了、配置也改了谁也不会想到系统默认的防火墙会挡在 Web 服务前面。4.2 systemd 日志与错误定位别总盯着浏览器猜去看日志如果防火墙放行后还是访问不了那就不能再靠猜了必须去看日志。Nginx 的错误日志默认在/var/log/nginx/error.log访问日志在/var/log/nginx/access.log。执行sudo tail -f /var/log/nginx/error.log边看日志边刷新浏览器任何访问错误都会实时打在这里。还有一个更强大的工具是 systemd 的日志系统。Nginx 是由 systemd 管理的服务执行journalctl -u nginx --since 10 minutes ago就能看到最近十分钟内 Nginx 服务的完整运行日志包括启动报错、配置加载失败、监听端口失败等信息。这个命令在嵌入式 Linux 开发里同样是排查某个服务为什么起不来的标准手段。我在排查中遇到的一个具体问题是Nginx 配置里把listen写成了listen 8080但防火墙只放行了 80 端口。这种配置与安全策略不一致导致的问题如果你只是反复在浏览器和防火墙之间来回试探可能很久都定位不到。但打开日志一看[emerg] bind() to 0.0.0.0:8080 failed (13: Permission denied)这种信息直接就把问题指向了端口和防火墙权限。所以遇到问题第一件事永远是看日志而不是去百度网站打不开怎么办。4.3 云服务器安全组的隐藏坑控制台放行端口这一步和防火墙同等重要如果虚拟机用的是云服务器比如为了后续找工作方便直接用一台云主机练手还有一个和本地防火墙并列的隐形关卡云服务商控制台里的安全组规则。安全组相当于云环境中的第一道防火墙它在操作系统之前生效。即使你在 Ubuntu 里把 ufw 关掉、把 iptables 清空只要安全组没有放行对应端口外部流量依然进不来。我当时用的是一台轻量云服务器默认安全组只放行了 22 端口SSH和 80 端口。我把博客部署完成后想用 8080 端口做测试结果外部访问死活不通但服务器本机curl localhost:8080完全正常。这就是典型的操作系统一切正常但流量被云平台拦截的场景。解决方式很直接在云控制台的安全组管理页面添加入方向规则放行 TCP 8080 端口几分钟内生效。这个坑在纯本地虚拟机环境是遇不到的但只要以后从事嵌入式开发尤其是服务器、物联网设备联网相关的工作云安全组的配置一定会再遇到。建议把它写进你的排查模板里外部访问不通顺序检查——服务是否启动、防火墙是否放行、云安全组是否放行三步走。4.4 HTTPS 证书申请和自动续期给博客加把锁博客能通过 IP 访问之后下一个建议做的操作是上 HTTPS。浏览器访问http://网站时经常会出现不安全的警告提示对于个人博客来说体验很不好而且搜索引擎对 HTTPS 站点也有更高的权重。国内可以申请免费的 SSL 证书我用的是 Lets Encrypt 的免费证书配合 certbot 工具全程自动化申请和续期。安装和申请流程很简单sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d your-domain.com前提是你已经有一个域名解析到服务器 IP。没有域名的话也可以先用 IP 访问等把整个流程都跑熟了再考虑域名。certbot 会自动修改 Nginx 配置添加 SSL 相关的配置块并完成证书签发。整个过程只需要几分钟签完后检查一下 Nginx 配置你会发现它自动加了证书路径和 443 端口监听。免费证书的有效期是 90 天所以自动续期是必须的。certbot 在安装时已经自动配置了续期定时任务执行sudo certbot renew --dry-run可以模拟测试续期流程是否正常。这一步做完你的博客就具备了完整的公网服务能力域名、HTTPS、自动续期每一个知识点拿出去面试都有的聊。5. 博客项目不是终点它如何变成嵌入式面试的谈资5.1 简历上这样写第一个项目面试官愿意多问两句项目本身并不复杂但怎么写简历却很有讲究。我看到很多人的简历上写搭建个人博客一句话带过这等于把最有价值的项目白白浪费了。我的建议是用问题-方案-结果三步来包装描述项目时不要只写我用 Hexo 搭建了博客而是可以说完成了从服务器环境搭建、Nginx 服务配置到 HTTPS 证书申请的全流程部署解决了部署过程中遇到的防火墙拦截、安全组放行等问题。这样写的含义很明确我不光会跟着教程敲命令还会独立排查问题。在项目技术栈一栏可以写LinuxUbuntu 22.04、Nginx、systemd、ufw、Lets Encrypt。这些关键词都是嵌入式 Linux 技能树上的核心节点面试官看到了自然知道你的底子。具体到面试陈述你可以准备一段两分钟的项目讲解先讲为什么做为了系统学习 Linux 服务器的部署与维护再讲怎么做环境准备、技术选型、部署流程最后重点讲遇到的问题和解决过程防火墙、安全组、日志定位。这一段讲完面试官基本就能判断你的 Linux 实操能力处于什么水平。5.2 从博客部署联想到的嵌入式面试考点博客项目表面上是 Web 部署但它的底层知识和嵌入式 Linux 面试的经典考点高度重合。面试官围绕这个项目可以顺藤摸瓜问出一连串问题提前想好答案都比死记八股效果好得多。第一个考点是进程管理。Nginx 是一个典型的守护进程它的启动、停止、重启都是通过 systemd 的systemctl命令来进行的。面试官可能会问systemd 是什么systemctl start和service nginx start有什么区别Nginx 的 master 进程和 worker 进程有什么关系关于最后这个问题Nginx 采用多进程模型master 负责读配置、管理 workerworker 才真正处理请求这跟嵌入式 Linux 里的多进程通信、信号量处理就自然联系起来了。第二个考点是文件系统与权限。/var/www/blog目录、配置文件里的user www-data指令、chown修改目录所有者这些操作背后全是 Linux 权限模型的知识。面试官问普通用户想绑定 80 端口为什么会被拒绝时你如果能把前面提到的bind() failed (13: Permission denied)错误讲清楚就能顺势引出 Linux 的权限机制。第三个考点是网络通信。从浏览器输入域名到看到页面中间经过了 DNS 解析、TCP 三次握手、HTTP 请求、Nginx 返回响应这个完整链路本身就是网络知识的最佳应用题。面试时不需要背 OSI 七层模型把这个故事讲清楚就够了。5.3 后续你可以继续演进的方向博客部署完成后不需要急着进入下一个全新项目可以先把博客本身继续演进让它的技术含量再往上走一层。这样你在同一个项目身上获得了更多可展示的深度比东做一个项目西做一个项目更有面试说服力。第一个演进方向是给博客加上评论功能。评论区稍微复杂但值得考虑方案是集成开源的评论系统比如采用基于 GitHub 的评论方案把评论功能和 GitHub 账号体系结合起来这样就不用自己搭后端同时还能练一练 GitHub API 的调用。第二个方向是加一个 Nginx 层面的 HTTPS/2 加速配置一下 chrome 开发者工具里看加载速度变化体验一下 Web 性能优化的感觉。第三个方向更有意思把博客从 x86 服务器迁移到 ARM 设备上跑或者干脆在你的嵌入式开发板上部署。这个操作听起来高端其实就是交叉编译 Nginx 和上传静态文件的问题真做下来你的交叉编译能力直接上一个台阶。提示还有一个实用的小技巧——用 systemd 定时任务给博客做个全站备份。写一个简单的 shell 脚本把/var/www/blog打包压缩推到对象存储或另一台机器上再用systemd timer定时执行。这个操作练完你和嵌入式文件系统备份、定时任务配置相关的经验就很完整了这在产品开发中是很常见的运维需求。6. 第十七天做第一个项目的总体复盘与日常节奏建议从第十七天的时间节点回看做第一个项目的最大收获不是我拥有了一个博客而是我建立了学习-实操-复盘的闭环。前面十六天输入的知识在项目里得到了集中的输出和检验。我会建议后续的学习继续保持这种节奏每学一个阶段就找一个可以落地的项目练手保持持续的学习动力。我的做法是每天固定三件事早上花半小时过 Linux 基础题白天专注推进项目晚上写一篇当天遇到的问题记录。等你积累十五六篇这样的记录后你已经有了一个自己亲手踩坑的项目库这在面试时展现出来的学习能力远比一句我自学了三个月要有说服力得多。