每个程序员都应该尝试的有挑战性的项目(2019)

一篇热门的“每个程序员都应该尝试的有挑战性的项目”清单——从文本编辑器和玩具操作系统到模拟器和光线追踪器——引发了关于什么样的副业项目真正能培养有价值技能的讨论。许多人认为,重新实现基础系统能加深对软硬件工作原理的理解;而另一些人则认为,现代软件工程更关乎库的选择、复杂度管理和团队协作,而不是底层实现。讨论还触及了工作与生活平衡、“程序员”和“软件工程师”的区别,以及过度依赖第三方代码与陷入“非我发明”(Not Invented Here)习惯之间的风险。

项目 vs 生活平衡 / 非电脑类爱好

  • 有人认为“每个程序员都应该”这类清单让人反感;工作已经够累了,空闲时间不应被规定性地用来写代码。
  • 一些人提倡完全与电脑无关的爱好(木工、园艺、音乐、徒步),并明确提醒读者要“去摸摸草”。
  • 也有人指出,户外/身体活动和深入的编程项目并不互相排斥。

建议项目的难度与范围

  • 关于 Game Boy 模拟器是否比“小型操作系统”更难存在分歧;有人说操作系统更难,另一些人则认为带有精确时序和边缘情况的模拟器更棘手。
  • 光线追踪器被视为一个连续谱:从一个简单的周末光线追踪器,到耗时数月、可用于生产的系统。同样,“网页浏览器”也可能只是纯文本浏览器,也可能是现代完整浏览器。
  • 许多人强调,出于学习目的,你完全可以停留在一个最小但可工作的子集,而不必追求完全还原。

其他项目点子

  • 常见建议:搜索引擎 + 爬虫、CAS(计算机代数系统)、光线追踪器、类似搜索引擎的文本搜索、简单的 HTTP 包装器、Web 框架、Netcat 克隆、类似 memcached 的缓存、迷你数据库、文件系统、基础 Docker 克隆、通过 xv6 实现的迷你 OS、简单 MMO、机器人、无人机、CFD / 流体动力学、倒立摆机器人。
  • 安全相关建议包括缓冲区溢出和 SQL 注入实验、Wireshark 探索,以及 CTF。

编程 vs 软件工程之争

  • 一派观点认为:玩具编译器/OS/编辑器能提升“程序员功底”,但不能提升“软件工程”能力(库的选择、大规模设计、可维护性、优化权衡)。
  • 反方观点:没有扎实的底层基础,就不可能成为优秀工程师;实现这些东西会让你知道什么时候不该重复造轮子。
  • 关于 Big-O 也有激烈争论:有人说在 CRUD 应用里很少相关;另一些人则将缓慢、臃肿软件归咎于对复杂度的无知。

非自造轮子 vs 通过重实现来学习

  • 很多人为重新实现编辑器、搜索、数据库等辩护,认为这属于“娱乐性编程”,也是深入理解系统的一种方式。
  • 批评者称这是一种 NIH,并认为现代系统(例如搜索引擎)不可能合理地完全从零构建,必须集成现有库。
  • 也有人强调平衡:在业余项目里可以从头写,但在生产环境中应务实并谨慎选择依赖。

文本编辑器、数据结构与可用性

  • 关于将文本存成数组还是 rope/piece table 的争论:有人表示基于数组的编辑器在兆字节级别仍然很好用;另一些人则警告病态编辑和超大文件会出问题。
  • 多个人认为编辑器的可用性和正确性比内部数据结构的微优化更重要。
  • 只渲染可见文本以及高效处理超大/超长行文件,被认为是真正的挑战。