Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: How can I self-evaluate my programming skills?
94 points by bdg on Jan 6, 2012 | hide | past | web | favorite | 43 comments
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.

How should I be evaluating myself?

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?


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.

Lets say someone is just starting their tennis training. They like the game, but they want to learn how to play well. Would you tell them that all that matters is whether they manage to beat their next opponent, and to focus on that?

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.

I agree somewhat, but would shorten that to: "pay attention to the whys when you learn the hows."

I didn't know that by programming, I was playing tennis.

Tennis and programming = bad analogy. When you program you have to know far more than just how to make the code work. You're usually learning at least 3 languages to get one program working, you have to understand the interactions between your program and the server or the OS and the hardware that your software will run on, then you get into maybe learning how certain compilers work, your IDE and other tools, frameworks, object oriented or functional style, etc. On top of that everything is constantly changing on you.

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.

Lets not get bogged down in the tennis; I don't even play tennis, I just chose it because almost everyone recognises that investing time in fundamental skills is important in sports.

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!

Yeah, you're right. Enough with the tennis. I think there's equal merit with what you're saying and what Ed is saying. We're trying to answer a question that doesn't really have a right answer. Add to that the fact that there are so many ways to evaluate how much youve improved or how you stack up that maybe we should focus instead on how not to measure these things.

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.

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.

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.

The next step would then be to expand the functionality of whatever you built by making it do something it was not originally supposed to do. You should then discover the shortcommings of your original solution and from that learn how to work your way around it or that it might be necessary to rebuild it because you did a crap job the first time.

Rebuild stuff!

Precisely. The best measure is what you need to learn to scratch your itch. I like to call it just-in-time learning.

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.

This is slightly off topic but may be of value. When I solve a particularly difficult problem, I stop and ask myself a couple of questions that help me grow as a developer.

* 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?

Ed, you're an odd cookie.

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. :)

It remember me a party where a friend was constantly asking me and a couple of school mates what algorithmic is... oh gosh=) So, we were making huge explanations with 'complex' words.. It lasted hours =)

Finally, she said: "Oh I think I got you guys, you are finding solutions to solve problems."

Happy! :>

The funny thing is that it's nearly impossible to evaluate where you stand before you've reached the next level or even the level after that. You think your solution is clever? Wait 6 months and you think it stinks. You think you have a nice abstraction? Wait until you need to do something you didn't think of and you find it's useless/too complex/unnecessary and so on.

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

"You think your solution is clever? Wait 6 months and you think it stinks."

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 usually roll my own first, even if i'm sure a library exists. it helps me get a better understanding of the problem space, and since i'm still a greenhorn this understanding is critical.

i am then grateful for the library and how easy it makes my life!

Your book selection is among the best.

I'm surprised that you feel you were able to measure something accurately with that list. I feel like it's very vague, and I don't have a clue how good I actually am for many of the important things like "problem decomposition", "systems decomposition", "communication", "code readability", et al. I'm sure there are probably people who would consider themselves "level 3" that I would scoff at, and there are probably people who would consider themselves "level 3" who would scoff at me. Basically, "level 3" seems to span everything from Norvig and djb to someone who got a BS and just read Code Complete.

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.

"Basically, "level 3" seems to span everything from Norvig and djb to someone who got a BS and just read Code Complete."

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:

  - directed practice
  - reflection
  - publish and be criticized by others (good way)
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.

To be fair you just picked out the things on the list that are hard to measure and partially comes down to personal preference/style. For example I absolutely detest the code behind DotNetOpenAuth but I can't really tell you why and I'm sure others would say it's fine.

It's not a bad measure of where you are as long as you're honest with yourself.

I did, but I think those also intersect with the most important things in everyday work -- soft skills, founded on judgement and aesthetic sensibilities, which are hard to measure, but which make the difference between an OK solution and a really great solution. It's very hard for me to perceive how large the range of ability is in those skills, or where any single person is in it.

(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.)

Start keeping journals.

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! :)

Look at code that others have written and make sure you understand it. Once you have some basic proficiency, there is a tendency to do things the way you know how to do them. Looking at real code written by others can really open your eyes.

I never intended to, but this approach has helped me tremendously by accident.

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.

I haven't used it personally, but one useful tool might be http://codereview.stackexchange.com/

Here's one thing I've always found reassuring: When I look at code I wrote a year or two ago, I invariably find a lot of things I could have done better that I didn't know of back then. This generally tells me that I have improved and I am looking at the code with a greater set of evaluation tools and/or a better thought process.

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.

The more I think about it, self evaluating is hard without a reference to "guide" you towards a particular domain. For example, aside from the foundations (name your variables properly, writing readable code), the rest starts going into too esoteric requirements (writing libraries that simplify an api?, author of a framework?). Some of these requirements are unjudgeable (I can author a framework to encode/decode ssl packets, but in itself it's a poor indication of my skill), now writing a framework that stands the test of time (is rarely revised) is a different measuring stick, but that can only be 'evaluated' by someone who understands what are the pitfalls of writing a framework (http://lcsd05.cs.tamu.edu/slides/keynote.pdf). And if you are in an area that writing frameworks is not desirable (a lot of security-centric projects are like that, you want to use trusted sources and not venture in writing your own thing), then that measure becomes irrelevant.

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)

Not sure if that approach is useful. Wouldn't it be better to build something and note where you struggle the most along the way?

I 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.

> I currently face a similar problem, as I want to pick up playing the guitar again. How to get into deliberate practice mode?

OT: Try WildChords (http://www.ovelin.com/) :)

I heard about that, sounds like fun. I don't have an iPad yet, though.

I'm not sure if this helps you out or not, but I've found working through practice problems, such as Project Euler, to be helpful.

Actually, I've started Project Euler, I worked my way through them the hard way (ie, finding a general abstraction that's optimized for performance). I've learnt a lot, but more about math than software per se.

I still find it entirely fascinating, I'm putting a post up tomorrow with what I learnt from problem one.

I was going to suggest the same (Project Euler specifically). I think the great thing about a site like Project Euler is you have a set result your code must produce to get it correct, so you must think through the correct way to code the algorithm.

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.

Another good thing about Project Euler is that the problem is usually presented in a simple form, which you first try to reproduce, and then it scales up in a way that you have to optimize in order to achieve success in under 1min of cpu processing time. The result is that you learn a lot about how to make more elegant solutions.

Project Euler is good fun and great for improving your algorithm design and understanding of basic programming constructs, but I think its a poor way to improve software engineering skills in general. Being able to write clever efficient algorithms is good but not nearly as critical as grasping important design patterns, OOP, methodologies like TDD, frameworks and databases you're using, etc.

Developer here.

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 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.

Sorry, there is no oracle that can tell you in absolute terms how good a programmer you are. The only thing you can do is pursue both a width and depth of knowledge in the field and get better. To improve: tackle various types of tasks both high and low level, try out different patterns and styles, and focus on improving important code qualities. The qualities I find important are bug count, code size, and ease of doing the right thing.

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.

Never stop coding. Look back each 3/6/12 months at code you wrote back then. If it looks as cool as it was 3/6/12 months ago - you stuck. If it looks like shit - you are on a right track and right speed.

Occasionally, I take 2-4wk coding breaks to re-evaluate something that's been nagging me each time I code. Is OO working for me? Do I like functional languages (I don't)? How's that PHP treating you (unstable buggy broken)?

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.

Offtopic, but since I see you lean more toward OO - look into perl's Moose. There are few presentation on Moose basics out there. Especially, look for Roles/Traits.

measure yourself, with innovation, product launches and how successful they are. Worrying about measuring yourself is a factory mentality.

I don't know if this question can be adequately answered. There's enough to say about this as there is to learn about programming as a whole! In my experience I've found that the best thing to do is to just keep making things, challenge yourself, be humble, and remember that you will never be as good as you want to be. Someone out there will always be better and measuring against someone else is usually the best way to take the wind right out of your sails. Don't do it. Just be better than you were yesterday.

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.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact