I'm what I think would be considered an 'advanced' programmer. I have years of experience doing reverse-engineering, kernel/compiler/emulation/game development, many programming languages under my belt, etc. Up until about two years ago I felt I was continually learning about coding, and I was a good coder but my overall development (documentation, management, organization, etc) skills were poor, so that became the focus of my learning. Now that I feel those have matured to the point where it's not worth complete focus, although obviously I still have a ton to learn, I now feel like my learning has largely stagnated. I had prided myself on learning new things constantly, but eventually there comes a time where the interesting things to learn are few and far between.
I've been trying to come up with little exercises to continue advancing my knowledge -- building a Tokyo Cabinet type DB being my latest idea to that end -- but I'm simply running out of places to go. It's having a definite effect on my morale as I move forward, feeling like I'm nearing the end of the road, so to speak, despite that I know there's far more out there I haven't even considered.
So my questions are these: How do you go beyond this point? What programming exercises, big or small, will expand my mind? Lastly, has anyone else out there hit this point, and how did you get over it?
Edit: I want to clarify a bit. I don't think I've learned everything there is to know about my fields, or anywhere even near it. I know there's a lot left for me to learn, but I simply don't know what that actually is, which is largely the point of the question. In addition, I've wanted new ways of expanding my skills as a tech person, not just as a coder, so thanks to everyone that's given such recommendations. There's a lot to take in here, but I think this will all help greatly.
I feel your pain. It must be very tough being so good you know almost everything. How about spending time teaching others of lesser abililty? That might inspire you again.
You can reassess your proficiency by looking at this Programmer Comptency Matrix [1].
[1] http://www.indiangeek.net/wp-content/uploads/Programmer%20competency%20matrix.htmit sounds like you're on the edge of burnout; been there and back again a few times. here's some things to do to change your perspective, which might help you relax enough to find your next passion:
when your head has cleared, then go to a good university library, pick up an ACM or IEEE Computer publication at random (any of them), and start skimming. The field of computer science is enormous, and growing/changing rapidly. There is far more to it than language X or database Y.
You have a great gift - how are you going to use it? Can you change the world? Should you?
Here are some suggestions:
I havent hit this point, so take my advice lightly. I think you need to take visit a few university websites and see what people are publishing in the fields your interested in. That might give you some inspiration.
What programming exercises, big or small, will expand my mind?
I don't want to hurt your feelings, but you the way you write about yourself shows that you, yourself, see you as the limiting factor to becoming a true master.
Note that even though with lots of practice most people can get good at what they are doing, only a few will be able to become a true master of their art.
A lot of answers here will get you thinking. Learning new things, piling up knowledge, going the way of "always more" might be not the way to true greatness.
Maybe you have known a lot of the things written here for a long time, but you did not want to decide on which way to go now.
You are at a junction right now, as long as you don't decide for yourself which way to go, you will not move (forward).
Might be a bit philosophical, but it is the best advice I can give you.
Good luck in finding your way.
To close with a Yoda comment: "Do, or do not. There is no try."
Write a C compiler in PostScript.
On a less painful note; Try your hands at cutting edge technology and try to participate. Create an open source project for it if you need to.
Or you could try to design your own language.
It sounds like your motivations are changing, which can feel disorienting when you've relied on the old set for many years. First, please be assured that there are plenty more technical challenges out there. If what you want to do is program, you can keep programming new and challenging things forever.
About five years ago I went through what seems like a similar crisis where I lost my old set of motivations. Two things helped get me out of it:
Something else that helped me was taking some time to understand why I was dissatisfied. One thing I found helpful was "morning pages", where I sit and hand write two pages in a notebook without ever letting the pen stop.
Even though what you are going through is hard, this is an opportunity for you to take your skills and apply them at the next level. I wish you success.
I know this may sound sarcastic--but really I'm not being sarcastic. I'm quite serious.
Have you ever worked in an IT department and written code for an end-user? Writing a compiler or a driver or such like that, as hard as it is in its own right, is a different beast than dealing with constantly changing user requirements and actually interacting with the users of your products. It's not that one is harder than the other; they're just two different types of development and each has its own challenges and difficulties.
Edit:
Among some of the other challenges the IT department developer faces:
1.) Legacy code--maintaining and interfacing with.
2.) Unstable requirements
3.) Arbitrary and usually inflexible deadlines
4.) No choice of programming language (language is set for you by management or customer)
Cody, I can highly recommend looking into Dunning Kruger [1]. Consider its implications for your position and go from there.
[1] http://en.wikipedia.org/wiki/Dunning-Kruger_effectI don't see a mention of Functional Programming, or other paradigm shifts. While I haven't personally gone through the "Ah-ha!" that such a paradigm shift can give you, it makes sense that such a change in your style will give you a new perspective on programming in general.
You are not at the end of the road. You are at a junction.
The different directions are:
I don't feel that you are "less inspired" than you've been before, you want to expand your views and therefore you ask this question.
Something I've done to keep my knowledge at top edge is to teach others, as the top voter states, this helps you get inspired. But teaching doesn't only inspire it gives you a great, somewhat, new view of your programming.
You might not have had to do this before, but when others rely on your code being good, you really need to have it good.
So what you learn from teaching is:
Many people hate to teach and stand infront of people. And if you are one of those, surely you are not left to the wolves, Filip got another suggestion for you; Start a Blog. Now that might sounds somewhat stupid and retro, but think about it; How do you get readers? Well you write about common interests and you do it well. Meaning that you need to be speaking at a "teaching" level, having people to question your reasons but you will easily answer them!
So this takes you back to the start, what should you teach or blog about? Well you must have a programming hero or somewhat, we all do ( stupidly enough mine is Bill Gates, yes yes laugh all you want. ) and think of; how will you exceed this persons knowledge? Is it possible? ( If we talk about Jon Skeet, No, but don't quit, just because you can't become a God doesn't mean theres no chance for you ).
You must have some old code lying around, how about, taking that code, analyze it and just re-write it? What good will come from this? Well for starters you probably have a little bit more knowledge than you did when you wrote it, so what should you re-write? Sure there is no purpose in re-inventing the wheel? Of course not! Architeture is the fundamentals of life, what would we do without the pyramids or other such cool stuff from back in the days. Architecture in all manners are highly important and too this comes great responsability, take your code, analyze it, re write it, giving it a new, nice, architecture. I always programm as if 100 000 other programmers will use my "API" each day, so i need to keep it clean, commented and functional.
And when you do write code having the structure as a focus, you start to think about other parts aswell, how do i really test the functionallity the best way? what do others need and what do others think that this part actually does? This gives you; The mind of a teacher.
Im gonna end this, feeling endless, post with some project suggestions that might be interesting:
I know this post has been fun to read because i put a lot of effort in making it such, there are however a lot of good information here and i hope you will get some insight in my views.
Good luck
Write a new OS from the ground up. You can name it HUBRIS
Try pushing yourself outside your comfort zone. For example, you mention that you know many programming languages, but if they're all they're all C variants (C++/Java/C# etc etc) then try exploring more esoteric ones like Lisp/Scheme/Haskell/Smalltalk. I've found that my doing this it gives you greater insight into the coding process and really helps you come up with alternative solutions to problems.
Learn CUDA
Oh, so you are bored with the tactical level aspect (=coding) of software development? Well, maybe you can indulge in the world of software architectures or requirement engineering. That's one step up in scope. No worries, you will quickly find 10 textbook-like books to absorb.
Or you can go one step down in scope and indulge in computer science, complexity theory (how about the P=NP problem), quantum computing, language theory or genetic algorithms. These are distinct fields.
Or you can enter the Ivory Tower of Mathematics.
Do you mean coding or programming? Because to me there's a difference. I'm far from being in your situation, but if I were you, I would either try to create familiar things in new environments (another web app in Java if you're into .NET), or rather explore the creation of developer tools (MVC frameworks, IDEs, ORM tools for example). After all it all depends on what you like to do. If you're into architecture, find a very big project/framework to design. If you're into algorithms, then find something to optimize. If you're into programming languages, then learn one new each month (I'm sure you haven't worked with all of them).
Then the other option is to dive into something different than coding. Probably try to improve the development process in your organization, dive into management, or write a book. This is very subjective actually, I'm just listing all the options I would consider.
Here's a few:
Get involved with some open source projects that could benefit from your involvement. There are a world of good ideas out there that need traction to move forward.
Try something outside your normal area of expertise.
Try something tangential to software development.
Pick something you don't know anything about, go learn it inside and out and write a book about it.
I have taken the liberty of looking through your profile and website, and have assumed (possibly incorrectly) that you are an experimentalist engineer with a bias towards decompilation: as described by this paper which breaks down computer scientists into two categories [1]. What you will want to do is start exploring the theorist side.
From what I have gathered, the things you have been doing have mostly been in exercise in conventions. I have dabbled in those areas you described yourself and in 90% of the time was spent learning conventions such as calling conventions, stack layout, OS API, syscalls, peculiarities, etc... There is one layer deeper than this, and that is to design a CPU (one with modern features like pipelines and parallel arithmetic) by yourself. This subject alone could keep you occupied for a lifetime and you will learn much about computers as I did.
But more on the theoretical side: there is much to do.
Automated Art
AI
Programming Aids
Hardware
Information Theory
Reverse Engineering
Bioinformatics
I am kind of person who too hate being static. So what i will usually do, find my interest in some other parallel field. Another challenge in another language, domain, project etc.Some time contribute to open source projects as well. As being a developer of almost each platform i feel this thing always give me courage to learn more and more.
pick an unsolved problem and hack away until you've solved it
One option would be to find a business or industry that interests you. This does not necessarily mean a computer or technology industry. Just find something that you can get passionate about, you need to get into it pretty deep. Every company has room to imrove. The idea is to learn as much as possible about that business and its processes. Then design solutions that they need to solve their issues. You can approach this as an employee, consultant, independant software vendor, etc. whatever works for you.
The act of coding is only one small part of what a real developer does in a day. The biggest thing is to have domain specific knowledge.
If you want to advance yourself and your skills, pick a different domain and learn the complexities of it.
You choose! Learn the Banjo or Accordion
Since you are 20 years old, I hope that you will read this post and reply to it when you are 40. Frankly, I think two things are happening here.
1) you've lost some inspiration. There are tons of areas you know nothing about, but you do not feel drawn towards anything. I say continue to search and fine your inspirado.
2) Technical knowledge is the easy part of becomming a programming guru. The only way to move from adept to guru is wisdom. Code wisdom is only gained from experience.
My advice: go work for or collaborate with someone who will school your arse. You know that there are better programmers out there than yourself. Search one out and let him/her teach you.
I'm a novice programmer at best, but my recommendation would be to try and utilize what you have already learned. I too have a deep desire to learn, but my desire to create takes priority 99.99999% of the time. The whole reason I got into programming in the first place was to build, the skills needed to do so were an afterthought. But what do I know?
Do something new. Anything. Web development, desktop development, Flash. Get out of your rut and find something enjoyable to tinker with. We all get to this point, and honestly, that's when I left my last job. When I stop learning, I quit. Personal enrichment is great, but couple that with a working environment that promotes that amount of keeping current and you're gold.
It's also helpful to remember that programming alone doesn't make you a better programmer [1]. And for the others who seem offended by the OPs questions, remember also that:
[1] http://www.codinghorror.com/blog/archives/000543.html[In the analysis of Coding War Games results, 1977 - 1986, we found that] people who had ten years of experience did not outperform those with two years of experience. There was no correlation between experience and performance except that those with less than six months' experience with the languages used in the exercise did not do as well as the rest of the sample. (Peopleware, p. 47)[2]
I've had a similar problem... I know there's quite a bit more to CS than what I know, but pure CS is no longer interesting enough in itself.
I don't see embedded development in your list. The satisfaction for me of seeing a physical device move around under your control is much greater than pixel flipping on a screen. The challenge is also greater, in a way. When you can't trust your hardware or even your compiler things can get really interesting.
Plus, the average embedded developer is WAY behind, so you can really shine there. The scope and architecture of PC development dwarfs most any embedded project... so we're well practiced in a level of system complexity embedded developers can usually only dream (or have nightmares) about. If you can master the additional debugging and toolchain complexities in embedded development, you're way way ahead.
FPGA development is great for even more insane levels of control, speed, and complexity.
I've moved my contracts into about 1/3 embedded and FPGA development, and just about all of my hobby projects are now in these two areas. I plan on expanding that to between 1/2 and 2/3.
I'm generally much more motivated now. I have a long term goal again... learning any component parts required to build physical electronics products (being sure to have a lot of fun along the way).
Oh, by the way... in case it's not clear... there ARE significant challenges to embedded that WILL make your a significantly better programmer. So, if your only goal is to improve as a pure programmer, this is still a valid direction to go in.
Do some work with databases. Large databases. From looking at what you do have experience with (reverse-engineering, kernel/compiler/emulation/game development) it doesn't seem like you would have had a lot of exposure to working with very large dataset, or even using databases. Take a look at the web technologies. There is a lot to learn when you have a system that will be accessed by thousands of people at a time, with hundreds of gigabytes of data that they will be accessing.
Start a microISV and sell a product. You will then learn a whole new world of skills in addition to programming, including:
product management
usability
customer support
QA
documentation
marketing
Instead of looking into some specific area, you should try to get the chance to work together with 'expert' programmers ('expert' being 'more advanced than advanced'). Interaction with others and learning from their experience is invaluable, because you can ask a question about each little detail and learn WHY some stuff is better done some way, instead of just HOW.
A good way to get to work with top programmers is to join some open source project and contribute to it. People tend to be more polite when you're helping them for free ;)
Move yourself down a level, and learn embedded systems programming and electronics / robotics. You already know some ASMs so the learning curve will not be anywhere near as steep. Build your own ALU out of logic gates and you will learn a ton about computers! :)
Edit: Or, genreate a PAL/NTSC video signal using no external hardware and just a R2R ladder! :)
The best way to advance is to ask someone who you want to emulate what you can do to improve. You probably have some programmers / computer scientists that you look up to and think "I'd like to be like that some day." Ask one of them to be your mentor and accept their guidance in your development.
My opinion is that you have several routes:
1)Enhance your academic credentials. I'm guessing you would be looking at a PhD. That's a challenge. Can you do it? Do you want to? It would push you very hard.
2)Move into engineering. Coding gets old after about 6 years or so. But can you engineer code? Design and develop systems? This is a very difficult thing(in my opinion).
3)Move into business/management. Can you manage coders? Can you manage projects? This is a huge challenge for many people.
Just throwing thoughts out there. :-)
How about putting all that knowledge to work and create the next Google? That would certainly be an experience to learn from.
You could try learning more math. (full disclosure: I'm a math guy 8^)
The idea being that at this point in your development, you've got "details are ephemeral, but fundamentals are forever" down pat, and math is the most fundamental thing out there. Another way to look at it: if you're running out of new things to program about, learning more math can give you that.
Exactly what math to learn depends on what catches your interest. Doubtless you have all the basic CS stuff down pat, but there's way more CS stuff out there than any one person can learn. If you can bring your honed development sense to some of the more arcane algorithms out there, you'll do us all a favor....
Alternately, there's the kind of quantitative stuff like in Numerical Methods, which is similarly endless. The flavor is very different from the discrete stuff you get in conventional CS, and doing it right requires broad comprehension, deep understanding, and close attention to detail.
Funny, I think I hit a similar state a few years ago.
I did exactly the same thing - went off "into the wilderness" and honed new business analysis and consulting skills (think: software development lifecycle) rather than development-specific skills.
Personally, I believe I add more value now because I can still apply technical experience (and mentoring), but also I can better communicate with business stakeholders and other team members.
The second thing I did was to align myself more with a specific set of products, e.g. MS SQL Server, rather than working as a broader IT generalist (as I had been doing). Now I have a deeper understanding (in a particular product line) and I get to do more intricate/detailed work.
Ultimately I think I'm probably a better IT Professional now, as opposed to being a good developer/software engineer.
I'm nowhere near reaching this point, but why not champion an underutilized language you enjoy the style and strength of? If I were in your shoes, I'd try to revolutionize the language I enjoy, and find nifty in and of itself, and turn it into something better. For me this would be LISP, which I find highly attractive except for the lack of freeware non-SLIME based tools.
Certainly you could write your own programming language, but why not champion something in need that you happen to already enjoy?
Best of luck in continuing to learn, Cody. I hope you find something to apply yourself to, and enjoy doing it.
You take everything you know. Find the most annoying problem that everyone has in some area you've worked. Solve it. Start a business to take money from people who need your solution. Works especially well if you really know the area you're selling to. Additionally running a business requires a whole new set of skills and will let you see your old positions from a new perspective.
Not to seem flip, but get used to the feeling. All the best people I've heard always are striving for a better problem, better tools and mastery of the tools. I've heard Donald Knuth speak and read a bit and he only seemed interested in the next problem. I'd add that getting some work into the open source world and listening carefully to all feedback will go a long way.
Try your hand at writing a risk management system for mortgage backed securities. You may find there are a few banks interested.
You could try changing your main OS.
Switching to a different OS was an interesting experience for me it altered the problem solving domain I was used to, forcing me to adapt and learn new things.
Try to solve a NP problem in a polynomial time
Read SICP [1]. It's an introduction to programming. I can assure you that most things you'll learn in this book are new to you if you haven't read it already (writing a compiler for Scheme for example).
[1] http://mitpress.mit.edu/sicp/Expand your mind with a new language that will make you think differently. Haskell [1], Lisp, or Scala [2] will do.
[1] http://www.haskell.orgI'd recommend reading up on different design patterns (as most people gloss over this area of programming), and then toying with some 'exotic' programming. Neural Networks. Adaptive algorithms. Compression logic (build a better .zip!). That sort of thing.
If in doubt, contribute to an open source project. There's a nigh-infinite realm of learning there, as it's being written more quickly than you can possibly read.
Make a game. And put your skills and knowledge to the test on it. Games have the advantage that not even the sky is the limit if your doing it for fun (as opposed to for work). You can just keep shooting higher and higher until you decide its enough.
Work somewhere you often feel like the dumbest person in the room.
I can't really attest to this first hand, but I've often heard others extol the benefits of such an environment.
If you can't find such a place, maybe try getting in a position where you can often teach others what you know?
I know how you feel. It happened to me differently, but I got to a point where I said to myself "how many more problems of logic am I going to solve"? Problems of logic were boring.
So I left programming for a couple of years and did management, where I encountered something called "business strategy". This was not boring and I was good at it. I found that I was good at it because it was a problem of logic, but was about something else - called the "bigger picture".
When I got back to programming I realised that software architecture is much like business strategy and that there is something called "design". Not UML and model-view-controller models etc, but something more intuitive and holistic - ie the big picture. So I now create software architectures and in the process I write and manage code.
Now I am a developer and I run my own business and I'm not ever bored. Stressed, happy and sometimes very tired, but not bored.