Ask HN: How can I self-evaluate my programming skills?
I set out on a mission to improve my programming skills in general, and my first step is to not only find out where I stand, but where I need to improve.
One thing I saw was the [Programmer Competency Matrix](http://www.starling-software.com/employment/programmer-competency-matrix.html) which looked like a really good idea to me, but a few things stuck out as awkward to me, or perhaps dated.
My question is: How should I be evaluating myself? How often? How should I decide what to work on? Does my ability relative to others matter, and if so, how do I know what it is?
---
For anyone interested, I [wrote down]( http://cowbelljs.blogspot.com/2012/01/programmer-competency-matrix.html) where I felt I was for each level, this is my present bench-marking approach.
44 comments
[ 3.2 ms ] story [ 102 ms ] threadI currently face a similar problem, as I want to pick up playing the guitar again. How to get into deliberate practice mode? I consider just going through a book step by step. On the other hand, as my real goal is songwriting, perhaps it would be better to just start writing songs and try to learn what I need along the way (presumably by copying elements from music I like, that is, trying to figure out how to achieve certain effects).
I have also considered to just check out random guitar lesson videos on you tube. Perhaps that way I could pick up new techniques and then see what I can create by employing them.
OT: Try WildChords (http://www.ovelin.com/) :)
Anyway, it looks like you're good enough at stuff to be a good generalist, so you should probably just study and work on whatever you're interested in and improve naturally.
It's not a bad measure of where you are as long as you're honest with yourself.
(And many of the other, more concretely specified skills still suffer from the lots-of-room-at-the-top syndrome, e.g. I don't think that "has written custom macros" makes me an Emacs wizard, but whatever.)
I was going to post that reading Code Complete is one way perhaps to help OP recognize when you are improving, but there's more to it, you need to read, lots.
A programming career can be a long one, and many people may never stray far from their home town, whilst others might wash up, bedraggled, all across the globe.
There have been lots of articles on HN recently about self-development, but common threads seem to be:
Between reading the great books, writing real code and exposing your code to others' criticism, there should be a path that leads to serious improvement at a steady pace.I've interviewed recently, and it's caused me to look carefully at what I do, and how much I know. That in itself has been valuable, and helped me pick out what to read (C and C++ books in my case), and given me a target to become more surefooted in my programming.
I find that the best way to evaluate yourself is to look at your code all the time and think critically. Be careful not to overdo it though, maybe take a closer look in between projects or in some interval is fine.
What should you work on? What do you find interesting? I think you're a lot better off working on something you find interesting than forcing you into something that you don't find thrilling. As always you should do stuff you're not comfortable with: do some low/high level stuff, try a new framework or do something you think is hard.
I wouldn't obsess too much on how good you are compared to others, there's always someone better, period.
Instead focus on your relative improvement. If you read your old code (which you should) you should think "this is awful, I could write something better" or at least "this is ok... but if I did it this way it would be much better".
And finally read code, read books about code, try to code with other people and try to make something useful.
Some book tips:
The Pragmatic Programmer: Read this!
Introduction to Algorithms: If you don't know algorithms, here's a nice book for it
Effective Java, Effective C++, More Effective C++: Just good practices
I can't even count the times I've put together a "clever" function only to find out that an optimized solution existed in a common library and I could have done the same thing in 1/20th of the code. Software development is humbling.
i am then grateful for the library and how easy it makes my life!
I still find it entirely fascinating, I'm putting a post up tomorrow with what I learnt from problem one.
Another benefit of Project Euler is, after you solve the problem, you can discuss different approaches to the problem in different languages with other people who have solved it. Reviewing these discussions can help to see if there are other ways to code the program which may not have occurred to you.
When you start a new project, start a new journal. Record your thoughts. If you have to make a particularly hard decision, write out your thought process and what you ultimately decided.
Then review those journals every year or two. Ask yourself if you would have done anything different based on the experiences and knowledge you've accumulated.
Also, seek criticism. Learn from others. And read as much as you can! :)
I don't think there's any one litmus test that will give you a grade. It's a process of practiced introspection. Know thyself! :)
The only metric that matters is the delta between what you know and what you need to know to build what you have to build. How do you find out what this is? By building that which must be built. When you get stuck, you will have to find a way to get unstuck: by getting educated, by consulting others, by finding others' solutions, or just by old fashioned figuring it out.
How often?
Continuously.
How should I decide what to work on?
Work on what needs to be worked on, not what you need to get better at. Any other approach would be backwards.
By definition, the "Competency Matrix" you cite is a bad goal. Every entry has different level of importance for every person and every situation. By trying to aspire to this flawed ideal, you will be wasting time on things that aren't important and missing things that are.
(Aside: When I reviewed the Competency Matrix, I had to laugh. Many of the items were so important that you couldn't help getting better at them just by building lots of stuff. And many will never be important at all.)
The best way to get good at what you should be getting good at is to build what needs to be built. Then trust the process and yourself to fill in the gaps.
Does my ability relative to others matter?
No! There will always be many people better than you. There will always be many people worse than you. You will probably be the best at something (or some combination of skills). You will probably never get very good at something (or some combination of skills). And you know what? It doesn't matter!
All that matters is whether or not you can successfully build that which must be built. The ability to figure out what that is and how to do that is the most important skill of all.
Moral of the story: Go find out what people need. Then build it. The more you become concerned with their needs and the less about your own, the sooner you'll take care of both.
I would add to this that it's important to learn how to build what must be built efficiently. If you create what appears to be an elegant piece of software on the surface but resembles a Rube Goldberg machine internally then it's going to be quite difficult to maintain or enhance it later.
Rebuild stuff!
A good place to look for where to improve is by reading your own code. Read stuff you wrote a week ago. Are you happy with it? What's wrong with it? Too verbose? Not legible enough? Poor perfomance?
If you don't know exactly how to improve, try leaving your safety zone. Experiment with different languages or designs, see what they have to offer that your current toolbox is lacking.
Or might you say "Dont worry about whether you win or lose for a while, instead focus on improving your fundamental skills"?
The first strategy, where you only learn whatever you need to to achieve the next immediate goal, is a bit like greedy optimisation. Its got its merits; but its also got its flaws - for example, you could pick up bad habits that help you win your first few games, but then hinder your later development.
Most teaching of advanced topics, which typically happens at university, seem to focus on building a broad foundation of theory, and move on to applications later; the whole idea underpinning this is that we can learn more efficiently than by just having people focus on solving the next problem they have.
I would advocate planning ahead, to try and find efficient paths through the space of programmer knowledge. Hence I disagree with edw519's advice - if you are on a mission to improve your general programming, I think you are starting in the right place, by evaluating where you are, and trying to figure out whats most efficient to learn.
There is merit to grounding learning in solving real problems; but there's merit to trying to think ahead, and anticipate, too.
In tennis you have a set of unchanging rules. The equipment may advance slightly over the years but they're basically the same. So you really in tennis you learn the rules, strategies, equipment, and you're good. You could program all your life and not even scratch the surface of it all. That's why I think edw's advice is totally perfect. Learning by finding out how to get a task done is the way to go because you could learn all sorts of programming related stuff all day that you never use. In tennis you're far more likely to get an opportunity to use all you've learned.
Nice try with the tennis, it's a good argument but it doesn't work out in the end.
I spent some time, last August, playing with Haskell. This didn't help me build the next thing I needed to. I didn't need Haskell to help me solve any immediate problem either then, or since.
I spent that time because I believe that the experience will make me a better programmer, in the long run, and give me a bigger toolbox with which to conceptualize problems. I thought that, in the long run, in some sense, it would improve my fundamentals.
You seem to be arguing that things are so dynamic, that there's no point making long term investments like that.
If things were so dynamic that I thought there was a good chance I'd be making sandwiches for a living next week, I'd agree.
But things do not change that fast in programming. There's a copy of SICP on my desk that I'm reading; its the 2nd Edition from 1996, of a 1984 book, and the code is in Scheme.
And I don't feel like I'm wasting my time reading it, at all!
I've been so tired that I'm prone to losing my train of though half way through writing so hopefully my last comment wasn't totally incomprehensible.
You always give the obvious, common sense answer. But you always give it in a way that provokes thought and reflection, even if we already know the answer. So, thanks. :)
* If I created the problem, How could I have avoided creating this problem? Was it a design error, was I careless or sloppy, did I fail to test or understand something?
* How did I solve the problem? What steps did I take to solve it? How can I optimize my problem solving skills to solve problems quicker. Does this apply to a broad range of problems or is likely a unique problem?
Finally, she said: "Oh I think I got you guys, you are finding solutions to solve problems."
Happy! :>
First off, reading code is kinda boring, and if you don't know everything about a language, it can be easy to get stuck in a spot and not know where the code goes next. What I did was configure a debugger. I do Ruby, Objective-C and PHP work, and all three languages have excellent debugging support (rdebug, gdb and xdebug, respectfully). Configure your IDE/editor to hook into the debugger of choice for your language of choice, and for something as simple as figuring out what a variable holds without having to litter your code with errant puts/echo/printf statements, set a breakpoint and run your code. Step through the program one step at a time, and you'll easily see how your request to do X also makes your program do A, F, G, and Z through the framework or libraries you are using.
Plus, learning how to use a debugger will be a tremendous boon to your skillset.
There is a meme floating around that says improving means the worst code you have seen is the code you wrote six months ago. Don't go down that route. It is a sign that you have stopped genuinely improving and started chasing fashions. You should be able to look at your old code and either call it good or identify room for improvement. You should also be able to tell it is getting better.
Where I would get scared is if I looked at code that was 2 years old and I couldn't distinguish it from code I would write today. That to me would be a clear sign that I am not improving.
I think that there is only two ways to improve in our field.
- Write, write, and write code. The more complex the better. Two caveats:
Maintain what you write. One-off projects don't count, you gotta live with what you write, since that's forcing you to make it maintainable.
Write with people, if other people have to live with what you write, they will tell you if something stinks (of course this is assuming your teammates have a decent level of professionalism).
- Be mentored: Essentially someone who did the above, and then shows you how he suffered :)
Hope this helps.
Freddy (http://www.javapubhouse.com)
I've discovered that PHP makes me angry. Functional is good for small stuff. I need [much] more practice with OO. I don't know anything about ... a lot.
The next 2-4 wks are spent reading and comparing alternatives to doing whatever it was that was nagging me. These time blocks do actually include small coding problems (1-2hrs), but I can't really call it coding. I then begin with new optimism about the new language/skill/feature/paradigm that I've now incorporated into my daily programming.
I check back with the competency matrix semi-annually to re-evaluate where I'm at. Anything that I'm unfamiliar/unskilled with is fare game for the next 6 months.
If I were focused solely on global supremacy, I would check the matrix weekly, but alas, I have work to do, and I'm competent enough to do it now.
READ. It's the best way to discover the unknown unknowns.
Your ability compared to others only matters only when framed in the context of "What do I want?" What skills do you need for the career path you want? What skills do your future employer(s) need from you. What are the non-academic PhD guys working on, and does that interest you enough to wake up at 3am for?
I measure myself like this: I ask, "would I have been able to build this a month ago"? If yes then it's time to start challenging myself.
Secound, there is a huge diversity among programmers, don't try to be like everyone else.
3rd, there are forums to find people who code like you, you find out very easily where you stand.
4th, join a site like http://codercharts.com/ or project euler for fun. You can use any language you want.
5th, I'm trying to build up a team for an AI competition where you code a bot for Starcraft 1 http://code.google.com/p/bwapi/ You can learn a lot there, just drop me a line ..
I believe that master the ability of learn on-the-fly is the most important thing. We simply do not have enough time to learn all knowledge.
Whatever you are working on, if you ask deeper and deeper questions, you will be able to continue to learn. And this way learning is much less abstract.