
1. 先别急着开新坑看看手头积灰的项目到底卡在哪如果你混过技术社区一定见过“Ask HN: What are your unfinished projects?”这种帖子。每次出现都能收获几百条回复从半夜写了一半的编译器到只跑通过一次的爬虫脚本再到连 README 都没写的开源库什么都有。这个提问能火不是因为大家喜欢晒失败而是它戳中了一个程序员普遍存在但很少认真面对的事实几乎每个人手里都有几个没做完的项目而且数量往往比你愿意承认的要多得多。这篇文章不完全是在回答“你有哪些没做完的项目”而是想聊一个更实际的问题这些项目为什么会烂尾烂到一半的项目还有没有救以及下次再开新项目时怎么避免让同样的事情再发生一遍。我不打算写一堆“坚持就是胜利”的鸡汤。我自己电脑里就躺着至少四个超过一年没碰的项目。其中一个是从零手写一个轻量级消息队列当时已经实现了基本的发布订阅结果因为换工作、换电脑、依赖环境变乱加上后来看到成熟方案越来越多就彻底停在那里了。另一个是给本地 Markdown 文件做全文索引的小工具功能已经能跑了但 UI 丑到我自己都不想打开。说出来不怕丢人这些项目停更的真实原因并不是“代码太难写”而是我在关键节点上做了错误决策。这也是我最想在下面展开聊的项目未完成很少是技术问题更多是优先级、范围和内部动力的管理问题。先给结论没做完的项目可以分成三类第一类是已经学不到东西、删了也不可惜的第二类是核心功能完成 80%、补个收尾就能用的第三类是做着做着发现方向本身有问题、需要重做的。不同类别处理方式完全不同。最怕的是把所有未完成项目都装进一个“迟早要做完”的筐里最后变成长期的自我消耗。2. 先想清楚一个项目算“完成”还是算“跑通了”在讨论怎么处理未完成项目之前有个更基础的问题值得先掰扯清楚你觉得“完成”的定义是什么很多人停更不是因为项目没有价值而是因为一开始就把“完成”定义得太大大到永远够不着。比如说你写了一个自动整理下载目录的 Python 脚本。脚本能跑能按文件类型和日期把所有文件归好类——这时候项目其实已经是一个“能用”的状态了。但很多人的真实想法是“我还想给它加个 Web 界面”“我还想做成 Windows 服务”“我还想支持自定义规则”“我还想打包成 exe 发给朋友用”。需求本身没有错。错的是把这些需求全部放进“完成”的定义里。你以为自己在做一个下载目录整理脚本实际上你给自己造了一个永久开发不尽的工具平台。最后脚本躺在硬盘里连基础功能都没享受到。这种情况非常典型。项目做到一半放弃往往不是因为能力不够而是因为验收标准里塞进了太多属于“以后再说”的东西。所以处理未完成项目的第一步不是打开编辑器继续写代码而是重新定义“完成”对脚本类工具完成 能处理我的典型输入且输出可读。对开源库完成 核心接口具备明确使用方式配套一两个示例。对练手项目完成 关键知识点已经实践过一遍且留下笔记。对产品化项目完成 有一个可用版本而不是一个完整的商业闭环。如果你手头那个未完成项目撤掉那些附加的“以后再说”需求剩下的核心功能已经能用了那它就不是烂尾而是处于“功能完成、包装未完成”的状态。这种项目只需要花一两个周末收尾就行。反过来如果一个项目连基础功能都没跑通或者跑通了但你对它已经没有好奇心不再想打开相关文档这种情况更多要从“是否继续”的角度去判断而不是硬逼自己收尾。我自己习惯用三个问题判断一个半成品项目是否继续投入时间如果今天把这个项目删掉我会不会明显觉得可惜如果答案是“不会”说明这个项目本身对你的价值已经趋近于零留着只是心理安慰。这个项目目前承担的“学习价值”是否已经被消耗完手写消息队列的功能我已经学完了剩下的大部分是工程打磨这个打磨过程对我当前工作帮助不大。要不要再设一个至少两小时能完成的小里程碑再停如果没有宁愿停在这里。给每个项目留下一个“可以继续也可以封存”的干净状态比永远开着一堆烂摊子更好。3. 为什么项目会烂尾常见原因和真实信号要对应起来看大部分人会把项目没做完归因于“懒”“没时间”“不够自律”。我在社区帖子和自己经历里看到的真实原因其实更具体也更有迹可循。下面这几条是把未完成项目分类整理后比较高频出现的原因每条后面我会补上对应的“真实信号”。表格可以帮你快速判断自己的项目到底属于哪种情况常见归因真实原因真实信号没有时间实际是在其他项目里学不到新东西动力断档每次打开项目前都要重新看文档回忆背景代码太乱写不下去需求一直在变缺乏一个小范围冻结线功能越来越多但从没正式跑通过一版完整流程被更好方案取代想挑战问题的部分已经被解决剩余只是体力活逛 GitHub 时发现自己想做的功能已经有人实现且做得更好搬砖太累没精力项目交付标准被定得无限高每次给自己定了大版本目标但一个周末根本完不成不知道怎么继续缺少“下一步可执行动作”的拆分习惯项目停的地方没有一个具体的、能被检验的阶段性成果把原因拆到这一步处理方法也会清晰很多。3.1 动力断档型项目已经学完了该停就停这类项目往往是“教科书式”的练手项目。比如你为了学 PyTorch照着文档手写了一个图片分类 Demo。模型训练完准确率打个八九十分你顺手贴了个截图发到朋友圈。然后呢没有然后了。因为你想学的东西已经学到了。这不是失败。这是项目完成了它的历史使命。如果你把“学完一个技术点”也算作一种交付那你对这些项目的愧疚感会小很多。真正的问题不是中途停掉而是停下来之后没有留下一份“项目结论”我当时用它验证了什么方法、走了哪些弯路、如果继续做下一步会做什么。写这段结论比继续给项目加功能重要得多因为它能把已经学到的东西沉淀成可复用的经验。3.2 需求蔓延型项目尝试单枪匹马对抗所有边界情况有个识别特征很典型这种项目的问题列表不是 Bug而是“要不要支持……”。你今天想支持 Windows明天想支持 macOS今天想支持 PDF明天想支持 DOCX今天想低内存运行明天想支持 GPU 加速。每一条需求单看都合理但合在一起就是一个无底洞。如果你现在正在做的项目已经陷入“什么都要支持”的状态建议做一次需求大扫除。把需求分成四类现在必须做核心链路缺失则无法使用。现在不做没有它当前场景也能凑合。等有人用再说目前只有你自己在用不叫“用户反馈”。直接砍掉做出来只会增加维护成本没有实际价值。我记得自己有一个文件批量重命名工具本来只支持按时间戳命名。后来想支持正则提取、Excel 映射、自定义模板越做越复杂。最终冷静下来后我只保留了“时间戳 序号 原文件名关键字”这一个组合把其他方案全部砍掉。那个周末就发布了一版后面再也没有大改过。3.3 被替代型项目别为了沉没成本续命开源社区有一个经典现象一个新框架火了你立刻想到“我用它能做个同款”。做了一两周发现某个成熟项目已经把所有坑都填完了你的实现根本追不上。这时候最不划算的决定是给自己找一堆借口继续写下去只因为“都写了这么多了”。如果成熟方案已经能覆盖你的需求那就直接转用成熟方案。你写的代码付出就算了不叫浪费叫试错成本。至少你知道了那类方案的技术难点在哪里。但有一种被替代型项目是建议你换个方向继续的如果成熟方案能覆盖 80% 场景而你真正想做的是那 20% 的细分场景那你要做的不是“做一个完整方案”而是“做一个成熟方案的补充模块”。后者要写的内容会少一个数量级实际被使用的概率也会大很多。3.4 标准过高型项目学一下“做一半也能用”的发布观这个问题其实在编程新手身上很常见但资深工程师也会犯。表现形式是不做完最后一个功能、不加完所有注释、不写完全部测试就不愿意让别人看到这个项目。我见过一个朋友做开源项目流程图工具整整一年都没有在社交平台发过链接。他说每次打开项目都会发现有细节没调好比如节点连线的弯曲程度、明暗主题下的配色、拖拽时的吸附效果。他说等这些都做完再发布。一年之后市面上出现了两三个非常成熟的可视化工具。他这个项目彻底失去发布窗口。没发布过的项目不能算“完成了”只能算“存在于本地”。更好的做法是第一版先只支持最基础的功能UI 丑一点没关系文档就写一段核心逻辑能跑就行。发布出去让三五个人真的用一下再根据真实反馈迭代。未完成项目的反义词不是“完成度 100%”而是“在任何环节都没有对外输出过价值”。哪怕只是自己写一篇文章记录当时踩过的坑也算一种收尾。3.5 卡在未知问题型项目把“不知道怎么办”转化为“下一步试验”有些项目停得更可惜核心流程已经通了但剩下一个稳定复现的未知问题。比如某个特定输入会导致内存溢出或者并发超过某个数量就丢消息。卡了一段时间没有解决项目就搁置了。这种情况技术含量往往比较高但也很容易陷入“试图一次解决所有可能原因但没有任何一个原因被验证”的状态。我的建议是不要直接进入调试状态先把问题拆成一个一个假设然后每个假设设计一个最小验证实验。一个下午验证完所有假设能定位就修定位不了也把实验过程和结论记录下来方便以后继续排查。4. 别急着继续写代码先按这套流程给项目做一次“资产盘点”处理多个未完成项目时最忌讳一上来就开始给每个项目加功能或搭新框架。你需要的不是更多代码而是先知道自己到底有哪些项目、每个处于什么状态、每个还值不值得继续。这套盘点流程可以当成季度清理或年度清理的固定动作。我自己已经跑过三遍效果还不错。4.1 把项目全部列出按状态归类先把电脑里所有个人项目列成清单。判断状态时不要看代码行数也不要看上次提交时间只看一个指标它当前是“能跑”还是“不能跑”。能跑是指打开项目你能在不失忆太多的情况下用一条命令或一个脚本把它跑起来产生预期的输出。不能跑则可能卡在依赖、环境、文件结构或文档缺失上。很多人以为自己是在维护一个项目实际上每次打开都在重新考古。建议把项目放进三组A 组值得收尾而且距离可用状态不远。这类项目最有弹药价值优先处理。B 组项目本身有价值但需要先补环境重建和文档把“能跑”的基础找回来。这组要控制数量比如整个季度只挑两个。C 组已经学完、被替代、或不再感兴趣。这类项目在清单上标注一个简短结论之后从活跃列表里移除。4.2 记录每个项目的“最后状态”和“恢复成本”只列项目名还不够必须为每个项目记录两样东西最后停留的位置代码写到哪一步、数据从哪来、输出长什么样。恢复成本把它重新跑起来大概需要多久是 15 分钟、半天还是一天以上。这两个信息的价值在于它能告诉你“哪些项目值得紧急封存”。如果一个项目恢复成本已经高到超过它剩余功能的价值那直接补一个 README 当历史项目封存即可。如果一个项目最后状态写得很清楚恢复成本低那它才有资格进入“继续收尾”的池子。4.3 给出明确的取舍建议别让所有项目继续挤占注意力盘点完以后你会发现一个很常见的事实90% 的未完成项目其实不值得花一个周末来收尾。它们只是精神上的安慰剂让你认为自己还有很多事情在做。你需要做的是把它们从“未完成”的状态里释放出来给它们落一个“明确终止”或“长期封存”的盖章。我自己有一条经验法则一个项目如果两周没打开先给它写一次“当前状态”再关掉。一个项目如果两个月没打开就把它从默认工作目录移除放进专门的 Archive 文件夹。一个项目如果两年没打开它对你的未来大多数时候已经没有意义。保留仓库但别再占用计划表。真正值得投入时间的是那些你愿意把它从 Archive 里移回活跃区的项目。这种项目极少但当你找到时你会比一口气开十个新坑要快乐得多。5. 如果确实想把某个半成品做完记住这三条加速收尾的方法不是所有积灰项目都需要放弃。有些项目就差一个周末就能从不能见人的半成品变成可以贴到简历、发到社区的作品。如果你决定把某个项目捡回来我建议你采用严格控制范围的收尾策略。5.1 先恢复“可运行状态”其他一概不管打开旧项目第一件事不是改代码而是恢复可运行状态。安装缺失依赖、调整 Python 版本或 Node 版本、修掉破坏性 API 变更、确保测试或启动脚本能跑通。这一个步骤的完成度就是“至少能看到输出”。这条非常关键因为旧项目的环境恢复常常比预期复杂。不要在这个阶段顺手优化代码也不要中途想加新功能。你要做的只是把状态从“不能跑”变成“能跑”。恢复成功之后立刻跑一次完整流程记录关键输出。如果你连这个项目当初要解决什么都已经忘了先看 README 和最近一次提交说明。没有这些就从代码入口开始顺一遍。5.2 把待办清单缩小到一个固定版本的可交付范围写完“能跑”基础之后列出真正阻挡交付的障碍清单一律限制在十项以内输入样例 A 解析失败输出格式不对README 缺失无法从命令行调用依赖安装步骤没记录每完成一项就摘掉。不要让新冒出来的“要不要支持”类问题进入这份清单直到做完十项为止。这里的关键是不要追求完美追求“可以对外演示”。一个能演示的、有逻辑闭环的项目远比一个看起来功能很多、却连入口都找不到的项目有价值。5.3 补一个名为“如何运行”的文档比补大量注释更值钱很多人收尾时最喜欢的动作是给代码加注释。但在长期未更新的项目里注释的作用远小于一个清晰的运行文档。这个文档应该包含前置环境系统版本、依赖管理器、数据库版本如果有安装步骤从 clone 到跑通需要依次执行哪些命令输入输出示例给一个最小输入和对应输出已知问题当前版本哪些场景不支持哪些问题还没解决给这个明确交付打个勾那这个项目的完成度就已经到了“低摩擦可交接”的程度。哪怕后面几个月你再没动它也不至于重新看三天才能回忆起上下文。6. 给“未完成项目”重新定性有价值但要有结束状态回到黑客新闻那个问题。很多人看到“未完成项目”这个词第一反应是“我是不是拖延症晚期”第二反应是在回复里忏悔自己没有坚持下去。我更倾向用另一种方式理解一个项目是否失败不取决于它是否按原计划收尾而取决于你是否从里面拿到了足够的产出。这里说的产出不全指软件还包括经验、复盘视角和审美判断。你手写过一个轻量级消息队列虽然最后没有演进成产品但你因此理解了分布式系统里那些看似离奇的设计到底在解决什么问题这就是产出。你写过一个自动化爬虫最后因为反爬严格而放弃但你学会了请求频率、代理池和异常重试之间的关系这也是产出。你做过一个半成品编辑器虽然不完善但你知道了为什么“撤销/重做”功能在某些数据结构下那么难做这同样是产出。如果你能把每个未完成项目都给出一个“结束状态”而不是像一堆烂帐一样悬在空中你心理上的负担会小很多。结束状态可以是已移除文件备份后删除或归档不再占用注意力。已冻结项目中已记录最后状态和运行方式未来条件合适时可能继续。已交付完成了一个可用版本哪怕发不到十个人手里也能算完成。已学到经验项目本身终止但沉淀了一篇文章、一段笔记或一套排错思路。7. 开源不是唯一终点发布一个最小可用版本也算完成很多积灰项目停更是因为当事人完全没有考虑过“发布到很小范围”这件事。他们把项目当成只用自己看的东西直到失去兴趣然后宣称失败。一个更好的思路是把所有项目都按“可以对外展示”的标准来写。你不一定非要发到 GitHub 首页、推到社交平台只需要想象一下“如果我现在把这个 README 和 Demo 发到一个几十人的技术群别人能不能立刻看懂它要做什么”。为了达到这个状态自然就会倒逼你补上 README、清理环境依赖、精简启动步骤、写清楚输出示例。也会自然阻止你一直加私人大而全的需求因为“对外展示”版本天然需要一个边界。如果你有一堆做完 80% 但从未发过任何版本的项目先挑一个最有信心、恢复成本最低的集中一个周末做到最小可发布状态发到自己的公开仓库或者给两三个同事看一眼。收到一点反馈之后你会意识到这个项目终于不是在消耗你而是开始回馈你了。我个人更建议按“发布一个最低可用版本然后快速宣布一个阶段完成”的方式推进。哪怕代码不够优雅、覆盖场景不够多、设计也称不上漂亮这都是正常状态。把那个版本留在那里作为一段记录。以后某个节点想继续你有一个干净的起跑线不想继续它至少是一个保存完好的完整示例。7.1 给每个半成品配一张“项目收尸卡”如果你对整理多个项目还是觉得无从下手这里有一个很具体的产出物也是我每次清理项目时最先写的东西叫“项目收尸卡”。它不是文档规范更像是一个关于具体项目的极简备忘。卡片包含四至五条内容项目名和一句话目标这个项目原本要做什么。当前状态核心功能完成到什么程度是否能运行。停止原因是学不到东西、需求蔓延、被替代还是单纯没兴趣。最有价值的产出这个项目让我学到了哪一件事。如果未来继续第一步做什么只写一个动作不写宏大计划。你别看这张卡片内容很简单写一次通常只要十分钟但它产生的效果非常明显你能从一个“什么都想保留但什么都没做”的混沌状态直观看到每个项目的价值与成本。以后再看到 Ask HN 式的帖子你能坦然地写一句“我曾经有一堆未完成项目后来我把该冻结的冻结、该删掉的删掉、该收尾的收尾手头只保留两三个真正想推进的。”这种状态比囤积一百个半成品工程健康太多。8. 真正该警惕的不是“项目没做完”而是用新项目逃避收尾和复盘最后想点一个很多程序员自己未必会意识到的现象开一个新项目经常是逃避收尾最舒服的工具。写旧的半成品意味着你要面对混乱的环境、之前不成熟的代码和一堆没解决的工程问题。而开一个新项目意味着你可以重新规划目录结构、选择新技术栈、获得“从零开始”的快感。这两件事里后者容易太多爽感也大太多。所以真正让我觉得有问题的场景不是电脑里躺着几个没做完的项目而是每次遇到瓶颈就去开新项目并且从不对旧项目做任何结束处理导致所有知识经验都无法沉淀成一个可被复用的成果。如果你的 GitHub 和本地项目里有大量半年以上没碰过的仓库可以花一个周末执行一次“存量项目终结计划”。这不是让你把代码全删掉而是认领你的历史给它们一个安排。做完后你会发现一个很简单的道理真正健康的开发状态不是把所有项目都做完而是知道自己为什么留下这个、为什么停掉那个并且对正在做的少数几件事保持专注。那批“Ask HN: unfinished projects”的帖子之所以每年都会被重新顶起来本质上就是因为无数人都在同一件事上反复挣扎开始总是容易收尾和停下却很少被认真练习。如果你能把每一次“不做了”都变成一次清晰的选择而不是一次悄无声息的搁置那你对项目的掌控感会回到自己手里。这比多写完一个功能更值钱。