你无法像机器一样工作
过去一年,我在下班后又做了什么?按时间顺序: 一个博客网站(也就是本站的上一个版本) fork 开源代码,修改、测试、部署。 在当时,我认为最好的方式是 Notion 存储博客内容 + Vercel 部署 Next.js 博客应用。这个方式有最好的编辑体验,具备最新的技术栈来实现现代网站效果。我天真地想,这样我就能坚持更新博客,不断分享我的想法。 然而,这套技术栈在出问题时,debug 对一个后端程序员来说很有难度。并且在这个过程中我遇到了一些其他奇怪的问题,也许 Notion 并不想让我用它作为 CMS。 我到最近才突然意识到:博客的外在并不重要,我应该专注于博客文章的内容、坚持写作。我对博客的不满意,只能通过这一个唯一途径解决。 一个尝试盈利但快速失败的网页应用 这个项目受哥飞启发,我想尝试快速上线一款产品,使用低成本部署 + AI 辅助开发。MBTI 是典型的刻板印象工具,我认为 LLM 可能会非常擅长解释刻板印象、处理用户的提问输入。 失败原因:项目断断续续地进行了大约 3 周后,我决定完全放弃。我不喜欢这个产品的任何内容,我自己不可能是这个产品的用户,包括 MBTI 这个概念,我感受不到乐趣! 也许最大的乐趣是通过 AI 生成前端代码给我带来的新鲜感。随着项目进行到后期,我需要对组件/界面进行具体调整。而我对项目使用的前端技术栈并不熟悉,只能借助 LLM 寻找零碎知识,逐个复制粘贴、运行尝试,我是一只在敲键盘的疯狂猴子! 虽然哥飞分享了许多有用的产品设计/运营经验,但我在这个项目中并没有认真执行这些步骤(好可惜!)。这个产品没有准确的目标受众,设计上也毫无乐趣;至于运营推广,我还没有进行到 SEO 步骤就放弃了。 一个支持中文搜索的 Telegram 机器人 我从多年前就开始维护一个 Telegram 频道,分享各类编程开发、游戏设计、音乐制作相关的网页链接。Telegram 对中文搜索的支持非常烂,有时候我想找一个我曾经看过的链接,我没有任何办法搜索! 我重构了之前的笔记软件后端代码,新增了文本搜索功能(PostgreSQL)、Telegram 频道数据同步任务。 这个项目解决了我自己的需求,项目完成时我获得了巨大的成就感。 一个每日更新的定时任务,翻译、总结 Hacker News 等网站的新闻内容,执行结果保存为纯文本 Markdown 我需要及时获取科技新闻,但我不想每天在各类网站上花大量时间注视着英语走神发呆。终极目标:我不用再浏览社交媒体,每日新闻将会在这份 Markdown 报纸上告诉我所有我关注的内容。然后,我的时间和注意力可以用来做有意思的事情,而不是在推荐流、信息兔子洞里耗费大量时间。 这个项目的特殊性在于,它的运行结果是一堆 Markdown 文件,存储在 Github 仓库上。因为,编辑器是程序员最好的朋友。 又一个解决自己需求的项目。我的个人使用体验真的很不错,每天只需要花一点时间就能获取到大量有用的信息。它的使用体验类似于阮一峰的科技爱好者周刊,但是是每日更新的。这个项目解决了我的问题,可能也能解决其他人的,我不确定是否真的有市场。 我的本职工作并不轻松,晚上下班时间晚,我曾经一直认为缺少时间是我的最大阻碍。经过对自我的长期观察,我发现最大的问题可能不是缺少时间,而是缺少“心力”。 工具 使用喜欢的工具做我真正想做的事情,这是对我来说维持状态最重要的因素。当满足这个条件时,工作将会和玩耍一样开心。如果你必须要用一个讨厌的工具(比如,JavaScript?),你应该想办法让它变成喜欢的工具。 关于这个话题 Pieter Levels 对我的启发最大,他在这期播客中多次提到了这方面内容:Pieter Levels: Programming, Viral AI Startups, and Digital Nomad Life | Lex Fridman Podcast #440 ...
如何不依靠自律学习
因为工作内容的缘故,我常常需要和网络概念打交道,例如:Kubernetes 网络模型之间的区别、各种云计算网络技术的作用。计算机网络知识体系庞大且复杂,虽然学习起来并不难,但如果缺乏实际操作经验,随着时间流逝,书面上的知识往往会被遗忘、混淆。 我在一年前决定要重新学习计算机网络,重拾缺失的细节。然而实施学习计划时充满坎坷,无论是书还是视频,我都没办法在业余时间坚持学习;这类需要系统学习的内容,一旦暂停学习,重新启动阻力极大。 本文以下内容将讲述最近我使用的学习方式,如何通过方法而不是自律最终达成了我的学习目标。 TLDR 围绕目的学习,而不是根据学习资料做计划(例如:“读完某本书”)。 将总结内容以树状结构整理记录。这样能清晰地划分知识层级,并且还能保证更新时的灵活性。我使用 Workflowy 记录笔记,其他支持多层级列表而且节点可折叠的笔记软件也可以替代。 由于我并不是初学者,使用 ChatGPT 来辅助学习对我的帮助极大:提问资料中忽略但我感兴趣的内容;联系不同章节的内容提问;在我一头雾水时直接提问而不是自顾自琢磨。通过与 AI 交互学习,满足好奇心。 明确目的、找到脉络 为什么我要学习计算机网络?我需要应付考试?应付面试?为了装 X?我要在工作中使用这些知识,并且构建对计算机网络知识体系的理解,当我遇到问题的时候,我希望我能知道如何寻找答案。明确目的后,我的学习范围缩小到了一个具体的区域,哪些需要学哪些可以忽略,判断标准清晰明确。而且,我有了提问的动机。 计算机网络知识体系本身就有一个清晰的学习脉络:OSI 模型。每层的作用是什么?哪些特性降低了成本或者提升了效率?解决了什么问题?层与层之间是如何交互的?为什么在 X 层的问题在 Y 层没有?为什么 X 层和 Y 层有相似性?为什么要分层?这个层使用的专业术语是什么?如何 Debug?类似的问题可以问很多。问题的答案才能达成我的学习目的,而不是读完一本书达成了我的学习目的。我并不是初学者,这次重新学习,我想了解背后的设计原理。原理是不会轻易被遗忘的。 拖延症、意志力管理 你自律吗?在少量可支配的时间里,钢铁一般掌控意志力专心学习,对我来说很难做到。想要完成“重新学习计算机网络”这样耗时长的事情,对我最有用的方式是维持吸引力。读完书的某个章节,从结果上看有吸引力,但是执行起来很容易走神,特别是在业余时间。我换了一个思路,我对技术问题的答案非常感兴趣,与其被动地记录读书笔记,不如反过来将学习计划制定成解答具体的问题。其次,如果能实际操作,我不会选择只看资料,动手不会让我感到枯燥。实际操作会带来更多具体的问题,进而引向更深刻的理解。向 ChatGPT 提问也能保持学习的兴趣,阅读、验证它的回答比阅读大部头书容易。 树状结构学习笔记 所有学习的内容都会被遗忘,这次学习的大部分内容我可能半年不到就忘了。但是如果我记录了学习笔记,再次查阅时我可以快速回忆,重新理解。对于新学到的知识,记录笔记是一种很好的消化方式。不过为了把笔记整理得清晰有序,需要耗费额外的时间成本。 综合上述因素,有没有一种平衡的方式?这个问题类似信息系统中读写方式的权衡,如果我想快速记笔记,那再次读出来的时候往往比较困难,反之亦然。 最近半年我开始使用 Workflowy 记录学习笔记,这款软件对我最大的吸引力是它能以嵌套列表的形式记录,并且列表的节点可以折叠。听起来是一个很简单的功能,但是我发现我需要的所有功能,就是这么简单! 我的笔记是树状结构。节点之间不平衡。例如,klog 这个节点的内容远比其他同级别节点多。当我在处理某一块内容时,可以折叠其他不相关的节点。 首先,我正在学习的知识是树状结构的。这个结构正好和 Workflowy 的结构一致,符合我的直觉。当我新增内容时,它一定是某个节点的次级节点,我可以在这个范围内随意记录,在回顾时再整理节点。我习惯把一句话拆分成多个列表节点,当我拆分完成时也理解了内容。 其次,分层结构的学习笔记非常容易查找;并且可以跨越层级,在同一个浏览器页面同时展开多个节点下的内容进行对比阅读。 回顾知识时,我常常移动节点的位置,调整、合并笔记内容。这个操作相比于其他以文档为单位的笔记软件方便很多,我的笔记通常也并不是文档。 次级节点还能用来表示评论、待办记录,我不需要笔记软件真正实现了这些功能。 以上就是我记录学习笔记的方式,这是目前我尝试过的最高效的方式,在不记笔记与记录清晰文档之间的平衡点;在快速记录和快速查阅之间的平衡点。 神奇海螺 综合上述内容,我的学习过程变成了玩自己给自己设计的填字游戏。对于寻找具体问题的答案,ChatGPT 是最快速的途径。 我常常有完美主义倾向,喜欢偏离主线花费大量时间精力纠结细节。如果浪费了太多时间,主线任务会因坚持不下去而被放弃。通过 ChatGPT 获取信息学习,显然是不完美的。 我知道自己没办法严格按照流程完整地阅读完所有学习资料,但我的目的是学习自己工作中需要了解的内容,而 ChatGPT 正好可以帮我完成这项任务。我没办法保证我通过 ChatGPT 学习到的内容 100% 正确,但是我能在可控的时间内达成我的主线目标。这远比什么都不做或者中途放弃好!关于验证信息真伪,如果我不能判断这个信息的正确性,很可能说明我并不需要关心这部分知识。 通过 ChatGPT 获取信息是交互式的,我能提问资料中忽略但我感兴趣的内容;联系不同章节的内容提问;在我一头雾水时直接提问而不是自顾自琢磨。这对于一个充满好奇心的懒人来说,简直就是神奇海螺。 总结 每个人的思维方式不同,但年复一年的应试教育常常引导我们只练习一种学习方式。找到自己的学习方式、搭配适合的效率工具持续学习,战胜挫败感。这无疑是一种 ROI 极高的长期主义投资。希望这篇文章对你有所帮助。
业余项目 roots 失败总结
两个月期限已到,项目终止。我想做十个失败的业余项目,这是第二个。roots 是一款多人在线沙盒挂机游戏,灵感来源于 Global Game Jam 2023。 截至目前的开发进度 实现了一个棋盘状无边界地图的模拟沙盒引擎,Go 语言实现。具备基本地图功能(BFS 寻路、向量、框选等)、游戏循环控制(类似 Unity 引擎的 Update 方法)。 状态机框架、游戏物体状态数据结构(可拓展,有背包系统)。已经实现的角色行为:挖矿(寻找资源,开采)、种植作物(寻找合适条件的地形,改变土地块状态)、攻击、无目的漫游。还不能满足生命周期循环需要的所有行为。 debug 工具/流程。目前的方式是直接在终端打印 emoji,如上图所示。 未完成:生态系统、部落冲突、贸易市场、决策系统。只有这些内容完成了,这个游戏才会有第一个真正有可玩性的版本。 为什么失败了? 时间安排/项目管理。 我对整个项目的工作量预估过度乐观,项目开始时,我认为只需要两个月的业余时间就能开发出可以玩的版本。其次,我没有考虑情绪以及精力。下班时间非常晚,我以为自己是天选之子般的快乐码农,但精力有限就是有限。一个业余项目如果不能以愉悦的方式来完成,对我来说没有必要坚持下去。说到这里,想玩音乐了! 缺乏热情。 这个游戏并不是我喜欢的游戏类型,事实上我没有认真玩过任何一款作为参考的游戏。超过最后期限后,再花时间来开发这个游戏,不再像一开始那样吸引我了。 焦虑情绪。 在应该休息放松的时间,这个项目给我带来了不少情绪底噪:“如果你现在有空,你应该去完成这个项目!”我渐渐发现,找到生活的心流状态远比一切更重要。 缺乏游戏开发经验。 游戏开发过程中,排查错误、运行测试十分繁琐。游戏逻辑代码基本没办法写单元测试。其次,我对于许多游戏开发的设计模式、最佳实践了解程度较浅,在实现功能时需要耗费更多时间构思设计。以上仅仅描述了开发时遇到的问题,对我个人而言,更大的问题是:在这个项目中我常常陷入玩法设计的困境;而且在独立开发的情况下,我时常要更改玩法设计。 学习新技术的目的没有达成。 在项目开始时,我想顺带学习的技术(gRPC 在线程序、sqlite 数据库持久化、Go语言程序性能分析优化)实际上不适合在这个项目中学习。这个项目需要的时间远远比想象中多,我还没有进行到学习这些技术的阶段。 学到了什么? 关于编程: 不要在看不到代码的时候思考代码。让代码编辑器成为思考延伸的助手。 独立开发特有的编程策略:代码随时调整,如流水一般。逻辑层可以反向影响框架层,在写代码时并不可能严格按顺序设计、实现;尝试直接开发有代表性的上层逻辑代码能反向为底层框架设计提供思路。 关于项目计划: 对我个人而言,我会过度乐观地判断一些我并不熟悉但又略有了解的事物,在这个项目中主要是玩法设计。而这些错误的判断往往会阻塞整个项目推进的进度。 即使是业余项目,项目管理也要制定更周全的计划,尽力控制项目执行过程中才发现的难题。我只能告诉你在那以前要多想! 由上述内容联想,上班确实是一个程序员最靠谱的进步途径之一。 关于游戏设计: 虽然这次项目实践的体验十分痛苦,但是我还是认为:独立游戏的玩法应该由游戏自己生长出来,并由开发者探索出巧妙的设计。 关于业余项目: 每一周投入到业余项目的时间非常少,每个月能达成的目标十分有限,进展缓慢会消磨意志。 找到心流远比达成目的重要。 感谢自己又认真失败了一次!