Expanding your horizons: Actions
In theory, there is no difference between theory and real life.
In my previous blog post, I discussed my belief that the best value you get from learning is learning the very basic of how our machines operate. From learning about memory management in operating systems to the details of how network protocols like TCP/IP work.
Some of that has got to be theoretical study, actually reading about how those things work, but theory isn’t enough. I don’t care if you know the TCP specs by heart, if you haven’t actually built a real system with it, and experienced the pain points, it isn’t really meaningful. The best way to learn, at least from my own experiences, is to actually do something.
Because that teaches you several very interesting things:
- What are the differences between the spec and what is actually implemented?
- How to resolve common (and not so common problems)?
The later is probably the most important thing. I think that I learned most of what I know about HTTP in the process of building an RSS feed reader. I learned a lot about TCP from implementing a proxy system, and I did a lot of learning from a series of failed projects regarding distributed programming in general.
I learned a lot about file systems and how to work with file based storage from Practical File System Design and from building Rhino Queues and Rhino DHT. In retrospect, I did a lot of very different projects in various areas and technologies.
The best way that I know to get better is to do, to fail, and to learn from what didn’t work. I don’t know of any shortcuts, although I am familiar with plenty of ways of making the road much longer (and usually not very pleasant).
In short, if you want to get better, pick something that you don’t know how to do, and then do it. You might fail, you likely will, but you’ll learn a lot from failing.
I keep drawing a blank when people ask me to suggest options for things to try building, so I thought that I would ask the readers of this blog. What sort of things do you think would be useful to build? Things that would push most people out of their comfort zone and make them learn the fundamentals of how things work.
Comments
For this same reason, Chad Z. Hower and I started a C# Operating System project (called Cosmos) several (7-8 years) back.
For me personally, I had to learn intel assembler, cil opcodes, operating system basics (what is protected mode?), et al, while implementing the first iterations of the compiler and the kernel. After the obvious parts, we have a working VS debugger engine (even allowing assembly-level debugging). All interesting parts to work on (and even more awesome to see working)
The project is still alive, but we're a bit low on resources (dev's), so we could really use devs interested in learning operating system development and spending some time on learning new stuff.
For more information: http://cosmos.codeplex.com, or join our mailinglist: http://tech.groups.yahoo.com/group/Cosmos-Dev/
Regard, Matthijs ter Woord
I used to play around with Microcontrollers like 8051 and the PIC 16f84. I think this is one of the most eye opening experiences I've had with programming as it made me appreciate the comfort of the higher level programming languages.
After that I didn't took things for granted anymore and I still think it's a wonder how things work seamlessly together. The simple fact that the text that I'm typing in now shows up on my screen and will on a later time show up on your screens is simply staggering if you know what is going on in the background.
I think there is one shortcut available, namely to have a mentor with whom you could work closely. While a good mentor will definitely let you do your own mistakes, he will be able to let you do those that help the most :)
Sadly, I never had one of those, but the internet does help a little.
The comfort zone is quite different for every one of us, but I think where most of us would have trouble on a fundamental level is trying to figure out how much of it may or may not help in certain situations: the use of neural networks in everyday programming. Areas where it may be used (but I don't know) are prediction models of server loads in clouds. An area where I could imagine it could help is optimizing UI layout for individual users. So much for the theory, only practice would help if it is just crazy or something that could be amazing shit.
I personally struggle to read books, but put as much effort as i can to sit and read now-n-then. Most of what I've learnt is from trial and error, sometimes I struggle reading peoples blog posts about particular topics so when I post something I try to write it in a way that I understand so that maybe it can help someone else.
Currently building a personal project with RavenDB so I could learn it and because (I hope) the end result will be something that helps people. :)
I've learnt a lot from people i work with but after 8 years I still feel like i know absolutely nothing :(
I think the answer what people should try to build depends on their field. If you're working a lot with network technology I would suggest trying to build you're own HTTP(S) Webserver. For desktop developers it might be useful to write you're own windowing (GUI) layer based on DirectX.
BTW: Why is the publication date of you're articles in GMT timezone and comments have an Israeli timestamp (GMT +0200)? Isn't it much simpler to keep all dates into the same timezone?
I totally agree that debugging complex low level stuff gets you an insane amount of knowledge. A couple of years ago I wrote an Ethernet bootloader for an ARM Cortex M3 and the necessary PC software. This needed assembly to copy the program into RAM, an ARM BOOTP client, a .NET BOOTP server, an ARM TFTP client and a .NET TFTP server. Debugging these relatively simple protocols was so much fun and unless everything was near perfect, it just didn't work. Wireshark is your friend!
Useful but difficult things to build:
1) a DSL that can generate code from spec 2) an emulation of a specific thought process - http://en.wikipedia.org/wiki/List_of_thought_processes 3) a static analysis mechanism that searches a common code base for duplicate or extensible code with near matching preconditions & postconditions
For learning about performance and efficient code, working with algorithms and graphics in general, I find ray tracing highly motivating. There seems to be nearly infinite aspects to focus on and if you focus on making it fast, you can learn a lot about the cost of things you may take for granted such as garbage collection, boxing/unboxing etc. It's a bit heavy on the math though, so it might not suit everyone.
For me it is building an obfuscator for .NET. I know understand how the CLR is initialized, assemblies format, CIL opcodes, stack-based languages, abstract syntax tree and control flow, parallel pipelines,authenticode and strong-naming, many quirks of class/interface hierarchies, WPF, XAML/BAML, XAP, etc. I have also done some quite advanced graph algorithms (for prunning and name collisions) and this got me back to the nice times of programming quests I participate in :)
My recommendations for leaving .Net Developers Comfort Zone: - do some programming on Linux. - configure linux box as a network router. Add DNS, dhcp, vpn client, ssh etc. - check how Linux/Unix system tools and services are implemented. Learn to use them, browse the source code. Think about filesystem/file operations, /proc, accessing system services and compare to Windows - well, to compare anything to Windows you have to know how these things work in Windows. Think about complexity and usefullness of system services and tools provided with the system. - write few Lisp programs - or write a Perl script (yet on my TODO) - or learn TCL/Tk (I'm still waiting for such elasticity in .Net) Just start to unlearn .Net instead of learning more and more of it.
Build a physics-based game and make it perform well. You'll learn a lot about being efficient with resources and memory by building a game - even in a managed environment. Build a chat bot with XMPP. Build a chat bot that utilizes Python's Natural Language Toolkit, and do some natural language processing.
Very well put example for modern times. Reminiscent of Edison's quip about the lightbulb: "I didn't fail 10,000 times, I learned 10,000 ways not to do it".
I learned to love programming by writing MUDs and text-based games. Few other endeavors have such a natural mapping from concept to code, and there's a wide range of interesting problems to tackle: TCP socket programming, data storage and schema/format versioning, AI, tons of data structures, graph algorithms, language processing, and compilers are just a few topics I delved into writing a MUD from scratch.
Another thing I highly recommend people write is an OSS library for public consumption. Good naming, good documentation, and good design are things that should be much more highly valued.
Comment preview