

Ask HN: How can I self-evaluate my programming skills? - bdg

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.<p>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.<p>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?<p>---<p>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.
======
lawn
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

~~~
glimcat
"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.

~~~
kellyreid
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!

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

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

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

~~~
mquander
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.)

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

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

------
windust
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>)

------
edw519
_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?_

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.

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

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

~~~
feral
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!

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

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

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

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

~~~
Eeko
> 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/>) :)

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

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

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

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

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

------
jsmartonly
IMHO.

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.

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

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

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

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

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

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

