作者:Austin Z. Henley

编译:码农翻身

有不少学生和专业的开发人员都想做一个业余的项目,以此来锻炼提高自己的技术能力,但是他们并不清楚要做点啥。

我给大家看下这几个让我受益匪浅的项目,每个项目都可以多做几次,每次都会让你学到新的东西。当你不知道学习什么东西的时候,不妨以这些项目作为驱动。

文本编辑器

我们每天都使用文本编辑器,但是你知道他们到底是怎么工作的吗?忽略掉那些炫酷的功能,你怎么实现一个能够支持选择,插入,删除文本,并且移动光标的文本框呢?

当然了,你不能使用那些GUI框架中已经做好的文本框组件。

最大的挑战就是弄清楚如何在内存中保存文档,我首先想到的就是数组,可是数组在插入文本的时候有着很差劲的性能。幸运的是,还有几个漂亮的数据结构来解决这个问题。

另外一个难点就是理解光标在文本编辑器中的行为,比如,当我在一个文本的中央,开始按“向上”箭头的时候,光标应该向哪里移动?

在同一列移动?不,如果上面的那一行比较短,光标会移动到那一行的末尾,然后再往上移动,如果那一行文本较长,光标还会回到那一行的中间位置。

这就意味着需要记住光标所在的列,这样才有可能回来。我之前根本没有注意到这些小细节,直到我开始实现的时候。

实现了基本的编辑功能以后,下面两个更有趣的挑战是:undo/redo单词换行

以有效的方式来实现undo/redo让我大吃一惊,我先是尝试了用一个数组保持之前的状态,然后转向了Memento 模式,最后才使用了命令模式。 而单词换行会强迫你把文本的内存存储和视觉表现分开。

从文本编辑器能学到的东西

  • 存储文本的数据结构:array, rope, gap buffer, piece table.

  • 光标的行为和实现 

  • undo/redo的设计模式 

  • 利用抽象把文本的存储和表现分开 

进一步阅读:

文本编辑器的数据结构:

https://www.averylaird.com/programming/the%20text%20editor/2017/09/30/the-piece-table/

设计和实现一个Win32的文本编辑器:

http://www.catch22.net/tuts/neatpad#

《数据结构和算法:Java描述》

(码农翻身老刘乱入:我更推荐《算法》)

2D 游戏 -- 太空入侵者  

即使是最简单的游戏也需要独特的数据结构和设计模式,我们是来学习的,所以最好使用一个简单的2D图形库(如SDL,SFML,PyGame),而不是一个隐藏了很多细节的大型游戏引擎。

首先,你得学会如何在屏幕上绘制东西,实际上你是在清理屏幕,然后快速连续地绘制屏幕的每个部分,一秒多次,以产生物体移动的效果。

其次,你会学会游戏循环,一个游戏实际上是在绘制,获取用户输入,处理游戏逻辑中间的有效的循环操作。

第三,你会学会如何处理用户的输入,我之前从未注意过按下,按住,释放一个按键或者鼠标的细微差别,更不用说处理双击操作了。另外你多久检查一次用户输入?如果一直检查,那游戏的其他部分就被冻结,无法工作了。

第四,你会学会如何创建和管理游戏中的对象,以及他们的状态。例如如果动态地创建一定数量的敌兵?工厂模式能帮助不少。

第五,你会学会如何应用游戏逻辑,什么时候更新子弹的位置?什么时候更多的敌兵应该在屏幕上出现,你如何得知敌人被消灭?什么时候游戏结束?我之前从未用过按模计算,现在我的游戏代码中到处都是了。

基本的游戏运行起来以后,可以增加一点屏幕菜单,游戏结束的画面,探索如何实现有点儿智能的敌兵,如果还觉得不够的话,还可以增加材质,声音,在线的多个玩家!

能学到的东西:

  • 屏幕绘制 

  • 获取用户输入 

  • 游戏循环 

  • 创建和管理动态数量的物体 

  • 状态机 

  • 播放声音,使用材质, 网络功能 

进一步阅读:

《游戏编程模式》

https://gameprogrammingpatterns.com/contents.html

《Data Structures for Game Programmers》

《Programming Game AI by Example》

我从8个视频游戏中学到的8个教训

http://web.eecs.utk.edu/~azh/blog/8lessons8games.html

编译器- Tiny BASIC 

我做过的最引人注目的项目是编译器,时至今日,如果我周日的下午有空编程的话,我仍然回去写编译器。

通过创造一个东西,使得别人能创造更多东西,这种感觉实在太棒了。

通过实现一个编译器,我必须得学习很多复杂的编译器技术,这些技术通常来说根本想不到。我建议从零开始写编译器,并且从一个很小的BASIC-like的语言开始(例如Tiny BASIC,https://en.wikipedia.org/wiki/Tiny_BASIC ),然后把它编译成你所熟悉的语言。

例如,你可以用Python写一个编译器,把Tiny Basic编译为C#代码, 不需要输出成汇编,这能让你专注到编译器本身。

编译器的第一个障碍就是如何做词法分析,然后你需要构建一颗抽象语法树递归下降是个非常漂亮的技术。

接下来做语义分析,确保代码是有意义的,规则会被遵守。最后输出目标代码。

不要被那些术语吓住,编译器有海量的资料,先让你的基本的编译器工作起来,然后增加一些标准库(如简单的2D图形功能),优化参数传递,改进错误提示。

最后,你应该用自己的语言写一些例子程序,向全世界展示你的工作成果。

可以学到的东西

  • 词法分析

  • 语法分析

  • 递归下降分析

  • 抽象语法树

  • 语义分析

  • 代码优化

  • 代码生成

进一步阅读

《Crafting Interpreters》

https://www.craftinginterpreters.com/contents.html

《Write an Interpreter in Go》

《Let's Build a Compiler 》

https://compilers.iecc.com/crenshaw/

PeayBASIC source code :

https://github.com/AZHenley/PeayBASIC

迷你操作系统 

在课堂上,操作系统的数据结构和算法看起来太抽象而没啥用处。但实际上,他们是非常有用的。多年来,我把操作系统的基本概念应用到了广阔的领域,如游戏编程,甚至预测人类行为的模型。 实现一个操作系统能帮助我们深入地理解底层的情况。

由于依赖硬件,所以刚开始的时候,学习曲线陡峭,有不少障碍,但是如果跟随一本书或者教程,你可以快速地得到一个可以启动工作的OS,并且能运行你自己的程序。

我强烈推荐这本免费的书籍:《Making a RISC-V Operating System using Rust.》

需要学习的内容

  • 交叉编译

  • 操作系统自举

  • BIOS

  • 中断

  • x86 modes

  • 内存管理和分页

  • 调度(e.g., round robin)

  • 文件系统 (e.g., FAT)

进一步阅读:

OSDev.org's wiki of resources

https://wiki.osdev.org/Main_Page

Making a RISC-V Operating System using Rust

http://osblog.stephenmarz.com/index.html

《操作系统概念》

如果你能走到这一步,已经非常厉害了,但是.... 

如果你觉得还是不够难,试试这两个: 

电子表格  

电子表格(例如Excel),把文本编辑器和编译器这两大挑战结合起来了, 需要学会怎么表示单元格的内容,并且实现一个解释器,以便对单元格的内容进行公式计算。

进一步阅读:

有向无环图

https://en.wikipedia.org/wiki/Directed_acyclic_graph

反应式编程

https://en.wikipedia.org/wiki/Reactive_programming

《Spreadsheet Implementation Technology》

视频游戏控制台模拟器 

为视频游戏写一个模拟器(或者虚拟机)把编译器和操作系统的挑战给结合起来了,当你把别人的游戏在你的模拟器上运行起来以后,那种成就感相当棒。

这个模拟器其实就是虚拟机,能让那些游戏以为自己在真实的CPU和其他硬件上运行,难度相当高。我建议从模拟CHIP-8开始,这是一个简单的虚拟控制台,然后再转移到一个真正的视频游戏控制台。

NES、SNES、Gameboy和Gameboy的高级版本都是可以模拟的,已经有了大量的文档和开源模拟器。尽管它们都有自己的怪癖,使事情变得有趣(例如,某些游戏可能依赖于特定硬件的无文档记录的bug /特性)。还有PICO-8,它已经成为一个非常有利可图的“幻想”游戏机。

进一步阅读:

Writing a Chip-8 emulator

https://aymanbagabas.com/2018/09/17/chip-8-emulator.html

JavaScript Chip-8 Emulator

http://blog.alexanderdickson.com/javascript-chip-8-emulator

《How to Emulate a Game Boy》

https://blog.ryanlevick.com/DMG-01/public/book/

PyBoy source code

https://github.com/Baekalfen/PyBoy

后记:我觉得这篇文章列举的项目都偏重基础,非常适合在校的大学生,可以锻炼最基本的编程能力,建议多做几个。如果已经工作了,很难会有大块的时间去折腾了,可以考虑选一个自己最感兴趣的去实现。

原文链接:

http://web.eecs.utk.edu/~azh/blog/challengingprojects.html

每个程序员都应该挑战的6个项目相关推荐

  1. 100%的程序员都想挑战的算法趣题!| 码书

    计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,"算法" ...

  2. 我敢打赌,这是98%的程序员都想挑战的算法趣题!

    计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,"算法" ...

  3. 100% 的程序员都想挑战的算法趣题!

    作者 | 图小敏 计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,&quo ...

  4. python项目了解_神级程序员都是这样来开源 Python 项目!今天算是涨知识了!

    工具和概念 项目布局 当准备一个项目时,正确合理的布局(目录结构)是十分重要的.一个合理的布局意味着想参与开发者不必花时间来寻找某些代码的位置; 凭直觉就可以找到文件的位置.因为我们在处理一个项目,就 ...

  5. 老程序员都去哪儿了?

    摆在老程序员们面前有三条路,一是转行,二是继续钻研成为技术大牛,三是转型为管理人员. 我最近采访了十五位30岁以上的老程序员们,在此我想发表下我的观点. 网络上总有这类观点-- 「如果所有的技术都想着 ...

  6. 每个程序员都必读的10篇文章

    作为一名Java程序员和软件开发人员,那些每个程序员都应该知道的XXX的文章教会了我不少东西,它们提供了某个特定领域的一些实用的并且有深度的信息,这些东西通常很难找到.在我学习的过程中我读到过许多非常 ...

  7. 内卷严重?加班多?给几条程序员都适用的建议

    " 王兴曾说:"2019年可能会是过去十年里最差的一年,却是未来十年里最好的一年".谁曾想,一语成谶. 2020年,一场肆虐全国的新型冠状病毒肺炎疫情,让许多中小企业们陷 ...

  8. 每个程序员都必读的12篇文章

    作为一名Java程序员和软件开发人员,那些每个程序员都应该知道的XXX的文章教会了我不少东西,它们提供了某个特定领域的一些实用的并且有深度的信息,这些东西通常很难找到. 在我学习的过程中我读到过许多非 ...

  9. 那些35岁的程序员都去哪了

    阅读本文大概需要11分钟. 大家好,我是findyi,前段时间写过一篇关于大龄程序员的文章:那些40岁的程序员都去哪了,引发了大家的思考和讨论,不少读者私聊问:除了这些出路,还有没有其他可能? 最近想 ...

最新文章

  1. 安全专家十年磨一剑的独门秘笈,威力堪比《九阴真经》
  2. Linux 错误 Permission denied问题
  3. 十四、爬取天气气温,制作最低气温排行榜
  4. 龙芯开源社区上线.NET主页
  5. 7.25第一次组队赛
  6. 中南大学 09 MATLAB 矩阵的处理
  7. python3.x Day3 文件编码
  8. IIS7的应用程序池详细解析
  9. wordpress搭建 ubuntu16.04 apache2 + php7.0 + mysql
  10. 借助Haproxy_exporter实现对MarathonLb的流量和负载实例业务的可用状态监控
  11. 玻利亚(Polya)的《怎样解题》
  12. 卷积神经网络(CNN)实现手写体识别
  13. linux用isilon扩容分区,linux – Isilon群集上的间歇性NFS锁定
  14. ajax读取txt出现乱码问题,ajax读取txt文本时乱码的解决方案
  15. 解决Android SDK Manager无法更新下载 - 猪悟能 - 博客园 (cnblogs.com)
  16. 牛逼!女生怒考 692 分,想当程序员,卷了卷了。。
  17. vue--百度地图之离线地图
  18. PMP证书容易考吗?
  19. Python 海龟绘图 100 题——第 72 题
  20. random.RandomState()用处

热门文章

  1. 【python图像处理】tiff文件的保存与解析
  2. sqlserver 标准系统数据库
  3. android调用系统设置
  4. 理解离散傅立叶变换(三.复数)
  5. 科来网络分析系统概要介绍
  6. 基于opencv实现图像差异检测
  7. 完整的维纳滤波器Matlab源程序
  8. 统一建模语言UML要点全面简析
  9. u9系统的使用方法仓库_HPE产品认证证书查询系统使用方法
  10. clustering