您的位置:首页 > 职场人生

每个程序员都应该挑战的6个项目

2019-12-17 08:50 731 查看

作者: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


往期精彩回顾
我是一个线程

我是一个Java Class

面向对象圣经

函数式编程圣经

TCP/IP之大明邮差

CPU阿甘

我是一个网卡

我是一个路由器

一个故事讲完HTTPs

编程语言的巅峰

Java:一个帝国的诞生

JavaScript:一个屌丝的逆袭

负载均衡的原理


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: