Ask HN: How do I test that I'm improving as a software developer?

76 points by tathagatadg ↗ HN
(a) contributing to open source projects. long term disciplined approach, takes time to get evaluation (b) ship a real product. too many environmental parameters, takes time to get evaluated (c) participate in coding competitions. These tend to test your algorithm chops, and less of system design. But accurate results. (d) be generous about recruiter requests. show up for interviews without doing much interview prep (like practicing problems cracking coding interviews). but quick and fast evaluation. This gets very hard when you don't work remotely. (e) exact opposite to (d). be picky about interviews, prepare a lot for an interview. (f) attend conferences, hackathons. time consuming and may be costly and not sure how effective it is. (g) read some classic cs books cover to cover. no accurate measure

What do you do regularly to evaluate if you are getting better?

55 comments

[ 0.24 ms ] story [ 133 ms ] thread
How fast do you ship products and/or deliverables to the world and to your bosses?
Do you have an ideal that shipping/delivery should conform to?
read project code from a year ago. also have a person review your code in a language you are new to.
I would suggest this also. Every so often it's humbling to look back on your older code and think about how you might write it differently. If you cringe with frequency, you're likely improving.
Agreed, if you don't cringe either you were already pretty good or you still don't know the same things you missed before.
Or you've changed focus.

I look at my old code from 10 years ago and on a line-by-line aesthetic basis, it's pretty good. It's probably better than the code I wrote yesterday, given that I haven't yet setup my IDE to reformat it into a consistent style...

But that's exactly what's changed in the last 10 years. Now I consider my code in the context of the world around it, and don't waste time doing things that I can get machines (or other people) to do for me. So while my actual code has gotten worse, I'm much more inclined to use third-party libraries and frameworks when appropriate to solve problems. The problems I solve are more important to me. I pay more attention to how the code fits into the rest of the world around me than how it looks inside.

(comment deleted)
Going through your previous implementation gives one sure sign of whether you are improving. When on a steep learning curve, its very easy to spot bad implementation. It's akin to getting your code reviewed by someone with additional year of experience. Although, some of the mistakes you spot may be attributed to perhaps your enhanced domain knowledge but you will be able to distinguish between the two.

Additionally, to remain on the steep learning curve, I think its imperative to expose yourself to well written code and solving different set of problems.

Most of these are hard to measure. It will come down to your own variables.

Interviews are a whole different world so I don't think that they test how much you have actually improve.

Creating your own products is a great way to improve your code. Learn about the system your want to design, create the database, write your services, do the UI and iterate. After a few failed products you'll understand that what ever your wrote until know it was crap and your code will be cleaner and better.

The best would be to contribute to open source projects. That way you have to study other peoples code. Understand it. Improve it. And then send your code for it to be reviewed and merged for the whole world. Off course it will always depend on how good the original author of the project is.

Reflect on the past year or so.

You sound like you are watching your feet when you are running, start looking ahead. Set some goals for the year. Your career is a marathon not a sprint. The items mentioned above are activities that could contribute to you reaching a goal, but they are not goals (except b) and they are not testable.

“Do not confuse motion and progress. A rocking horse keeps moving but does not make any progress.” ― Alfred A. Montapert

> Your career is a marathon not a sprint.

My favorite part of this analogy is that the classical Greek marathon tale ends with the death of the runner because he gave it everything he had.

I, for one, do not want to die because I worked so hard.

We call those people workaholics.

I want to be good, but not dead. :-D

You don't want to die because you ran too much. What you want is the feeling that, when you die, you ran as far and as fast as you could during your whole life.
How many problems do you miss until you start debugging? Getting complex models and systems right in your head is a matter of training.

Also: How good is your documentation? The more experience you gain the more you will be able to plan ahead and build the a scaffold first before you start fiddling with details. This often leads to well documented code where the documentation always matches the code. A lot of tinkering often means that the documentation and your code won't match.

How well do you know your tools/frameworks/language? Can you start coding or do you find yourself trying out something in a REPL or a small test project before implementing it? (Note: This may vary since even quite senior developers have to learn new tools)

How well can you explain your code / your program / your project? Once again getting a good grasp at complexity is a matter of training.

Compare your code to open source projects and other code you can find. You'll see that there are always some good practices one still can learn. On the other hand becoming more experienced will make you see code and decide that there is room for improvement or you would have structured it better.

I read old code I wrote. "What were these people thinking?"
Read through other people's code and criticize their decision-making. Answer questions on SO related to whatever you're currently doing. If you can't explain it, you don't really know it.
> (c) participate in coding competitions. These tend to test your algorithm chops,

I believe Topcoder has design competitions too.

I open up some old repositories. If I cringe and spot mistakes I had made then I know I've improved. Sometimes I spot areas where I've regressed in my knowledge and need to practice.

You can only measure against yourself. Keep a record. Review it from time to time.

I do the same with old blog posts... I frequently spot areas where I've regressed and need to practice. The longer I spend doing "real" work between working on prototypes or katas, the more I feel like that's the case.
Interesting question. I don't think there's a perfect metric to rate software developers. One issue is that it's difficult to separate general software development skills from the area of expertise. For instance developing web apps, video games, distributed systems, compilers, financial software and so on... all require different types of expertise.
I do only one thing : I solve problems and compare my results every week or so.
Taking into account that being a developer requires a really broad range of competencies (from "hard" knowledge about languages, frameworks, databases, systems and so long, through a variety of skills like analyzing, solving problems etc. to "soft" aspects communicating and cooperating with others, not to mention the business domain requirements which often are crucial) I think you should first focus on finding one narrow area you would like to improve and then seek for a right metric for it.

How to choose it? It depends on the reason why you would like to improve: to be more attractive on the job market? To spend less time coping with specific problems? To earn more money? To gain recognition for your work? To have more personal satisfaction from what you do and how you do it? etc. Knowing the "ultimate" goal can help decide what exactly you want to focus on, establish a baseline and measure the progress.

You'll be writing less LOC;
Am I making the same mistakes?

Yes - :8( I'm not getting better.

No - :8) Lucky me, I'm getting better.

I remember fondly the advice of my first computer science instructor in the mid-80's: Becoming a great programmer is easy! Get a notebook. When you make a mistake, write it down. Don't make that mistake again.

It's simplistic, but it's resonated with me for 30+ years.

You sound like you're rushing. This is a journey of several decades, not a few weeks.
"(f) attend conferences, hackathons. time consuming and may be costly and not sure how effective it is."

Watching videos of presentations or listening to them during the commute (if possible, given the topic) will work. Optimistically a video from 2010 that was pure confusion at the time might be crystal clear when heard today.

I don't currently work at a strong dev culture place with many devs, but at a previous employer we'd brown-bag lunch and watch presentations together, and sometimes the company would provide food or we'd all chip in for pizza. Its a fun way to spend a rainy lunch hour. You need to set up a rotation of who picks the topic or everyone will go crazy. Do not let management pick the videos or you'll all be stuck watching OSHA videos, until everyone stops attending anyway. Corporate videos were the worst, con videos were generally pretty interesting.

I use Sijin Joseph's Programmer Competency Matrix[0] as a guide.

[0]: http://sijinjoseph.com/programmer-competency-matrix/

That is a highly debated matrix as evidenced here:

https://news.ycombinator.com/item?id=4626695

Personally I don't see much value in telling someone they need high-level CS studies to be a good programmer. How does knowledge of NP-hard problems really help your average developer? I feel that this comic more closely represents the average programmers situation (based on subjective anecdotal evidence only): https://pbs.twimg.com/media/B64WFyuCIAAjq3u.png

I don't think the point is that you can't be a good programmer unless you understand NP-hard problems (at least I hope so, otherwise I'm in trouble). I think the point is that you can use this matrix as a guide towards improving your knowledge and skills.
Exactly. You do not need to understand what does NP-hardness mean to be an excellent developer.

Understanding complexity, computability and modern logics is pretty satisfying, I'm personally in love the Godel's incompleteness theorem. But it is just one of many variables. There's plenty of things to improve on.

I think that without a lengthy disclaimer the author is misrepresenting his opinion to novices as being some sort of guide where you can choose your path from level 0 to 1 to 2 for rows in the table and that somehow you will become a good programmer. This is evidenced by the comments section with one user asking to "tell us a roadmap or path using which a programmer can advance his skills from Level to Level 2 and from Level 2 to Level 3."

To cherry-pick an example that helps my argument, how does having a blog remotely affect my ability to ship good code that is on-time and within budget? Why are Erlang and Prolog considered to be level 3 languages when they are not suited for all tasks (in fact languages are but a tool that should be chosen appropriately for the task)? Why must I author a framework to reach level 3?

The more I look at that table the more it disturbs me in it's subjectivity but is nonetheless an excellent resource for starting the discussion on what skills should be considered relevant for one's career.

Well, I will argue with the examples you have provided.

As to maintaining a blog, take a look at Joel on Software's "Advice for Computer Science College Students"[1], section "Learn how to write before graduating."

Learning Prolog, Erlang, Haskell, VHDL or some other out-of-the-box language is an eye-opening experience, and even more so is writing an interpreter or a compiler for such a language. It is a way to discover brain functions that you were not even aware are there in your mind. I speak this from my own memories about fiddling with a Hindley-Milner inference implementation.

Authoring a framework is not on my 'done' list, and it is not on the 'done' list of any of my friends, so I have no idea how influential is such an exercise. However, I will give the author of the matrix the benefit of the doubt - he got the rest well.

[1] http://www.joelonsoftware.com/articles/CollegeAdvice.html

During hiring interviews people want to quickly evaluate the software developer skills and there are obvious incentives to get it right. Thus, the things people are doing during interviews are the best tests we currently know.

Evaluating yourself has the additional problem of various biases working against you. So the real question is: Are interview techniques also the best techniques for self-evaluation?

Thus, the things people are doing during interviews are the best tests we currently know.

This is, unfortunately, disastrously false. For example, we know -- via copious academic studies -- that work-sample tests are the best available method of predicting performance. Many companies in the software industry do not administer work-sample tests during job interviews. Instead, they have a disinterested person who you won't work with make up a random question on the spot (seriously, this is not only a thing that exists in the world, it is the default hiring method in our industry). The disinterested engineer interviewing you then spends most of their time preening about their own intelligence while ignoring your answer, and returns a decision known to be primarily determined by demeanor, rapport, demographic similarity, and other things which all decisionmakers will profess that they are not assessing for.

Do not pattern your internal decisionmaking off of software interviews. Software interviews suck.

[Edit to add: Incidentally, one of the reasons that one would predict "Well, clearly identifying talented candidates is important, so there is an incentive to get it right, so weak form Efficient Market Hypothesis suggests that companies are not freaking terrible at it." and still be disastrously wrong about the world we live in is that interviews have a principal/agent problem. The principal -- the firm -- cares a lot about extracting meaningful signal in interviews. The agent -- the engineer who is responsible for interviewing you -- is in no way rewarded for interviewing well. In many cases, their presence in the interview is already a strike against them because it takes time from doing the engineering work that they are actually scored on. They have not even the attenuated incentive to select good coworkers, because 90% of interviews result in No-Hire and of the remaining 10% the 95%++ case is that the new hire ends up working in some other part of the organization that the interviewing engineer will never need to meaningfully interact with. Faced with these very attenuated incentives for being a good interviewer, the engineer may instead to pay attention to more direct incentives like "get an ego boost by demonstrating my intellectual superiority over a captive, terrified, unable-to-resist audience."]

I think one of the problems with "How to improve as a software developer?" is that it represents many different skills. So the first thing to become a better developer, before you read any books, or write any code is to figure out what it means to be a better developer. Specifically where you want your career to take you and how can you make progress on that path.

What makes a good compiler developer for Microsoft is going to be very different from what makes a good developer at a start up. If you plan on working at start ups, particular early stage start ups, it would be very beneficial to see where you are lacking any experience to increase your breadth. For instance are you familiar with source control, unit testing, scripting, database optimization, communication skills, trouble shooting, etc... Find any skill where you are behind some of your pears and improve it. Obviously a combination of reading and practice will help you get there.(With the proportions of each depending on the skill)

If for instance you are a developer for the Microsoft compiler it might be beneficial to go really deep. Find as many papers as possible on language design, compiler design, etc... Maybe work on a couple of different open source compilers to get introduced to more ideas, or implement some new language ideas from papers into an open source compiler, while trying to minimize any types of breaking changes. But these skills and how you improve upon them are probably very different from what makes a good start up developer.

*Warning I do not actually know what skills are needed to be a Microsoft compiler writer, or a good start up developer, these were just examples to illustrate a point. My experience has been primarily enterprise, and I probably should have used that as an example but now its too late because the compiler is finishing up.

One thing I like to do which isn't at all specific to software is writing down accomplishments. This way I can look back and see if I've been progressing or staying still.

You could try writing down whatever you learn each time you learn something new to so you can look back and realize you are getting better, assuming you are. If you aren't then at least you know and can reevaluate.

I recommend to candidates I work with to update their resume every 6 months - 18 months (depending on your employer's project timelines). If you find yourself consistently struggling to add things to your resume, whether those are new skills or accomplishments, it's either time to look for a new job or time to start considering projects to maintain marketability.
Assuming you are working with a team, you can always just ask others for feedback on how you're doing.
This is the core challenge with measuring skills acquisition. To avoid talking my book about measuring developer skill, mind if I instead talk about my first love, which is learning foreign languages?

A lot of people have vague goals like "I want to learn French" or "I want to be fluent in Japanese." There is no defensible definition of the word "fluent." Instead, you should have specific goals which test ability to complete tasks that are representative of the larger set of tasks you need to be good at to achieve metagoals which are important to you.

This is why I care relatively little about "fluency in Japanese" and quite a bit about "what percentage of commercially significant terms in my apartment lease did I understand without having to ask a Japanese speaker to explain them to me?" That task is roughly representative of many tasks required to achieve my metagoal, which is "being a functioning adult / educated professional in Japanese society."

Now how do I measure progress? Well, I have some notion of groupings of tasks by difficulty level. The "apartment lease" task is in the same grouping and difficulty level as the "employment contract" task was or the "extract the relevant rule for recognizing SaaS revenue from the National Tax Agency's docs" was. Given roughly comparable levels of difficulty, if I start doing better on a task where previously I did poorly, then I'm progressing.

Why don't I just take Japanese tests yearly? Because my metagoal is not becoming the best Japanese test-taker there is. They are good from the perspective of many decisionmakers, since they allow decisionmakers to compare me against other people in a reproducible and cheap-at-the-margin fashion, but that doesn't get anything that I value. I don't care how I compare to Frank or Taro -- being better than Frank will not save me social embarrassment if I have to ask an accountant "Here is my... um, I don't know what the word is, but it's the piece of paper that records the historical prices I purchased by assets at and then their declining present value representing their worth diminishing over time as calculated by the straight line method. There's an accounting word I'm searching for here and I bet it is followed by the word 'schedule.' DEPRECIATION. Yep, that's the one, thanks."

Anyhow: all tasks are an opportunity to gauge my present skill level. I could, theoretically, even keep a journal of them, and I actually did that back in the day. (It's in the other room at the moment. Entries included things like "9/1/2005: Watched a nightly news broadcast about an earthquake. Understood it was about an earthquake and that there was one fatality. Didn't understand remaining 80%.") This gives me both a list of representative things to try leveling up on and some intrinsic motivation because when adding new entries to it I was occasionally pleasantly surprised how far I had come, where that very rarely occurred to me in the moment. (I often feel "Man I'm totally lost at this!" but exposure to the historical record shows that I'm totally lost on tasks which are MUCH HARDER than the tasks I struggled with years ago and that those tasks are now so below the trivial floor that I've forgotten they were once representative examples of things I wanted to strive to be able to do.)

Treating every little thing as an example to both practice and evaluate progress lets me work on focusing things which generally matter to me, gives me a reasonably quick evaluation cycle, and gives me frequent opportunities to achieve mini-victories even in the course of a long, long, looooong learning process.

Evaluating your skill with engineering is, roughly, similar. What relevant things can you do today which you weren't able to do a while ago? That's the progress you've made. Where poss...

Thanks for this fascinating post.

I'd love to read more from you about your experience learning Japanese — though it's possible you already wrote an essay about it that I missed.

Update your resume/CV periodically (eg every month, quarter or year). If you don't have something to write about, then you are likely not improving. If you are improving then you'll have a nice record.
I use a skills matrix with my team that contains the following:

Debugging

Architecture

Release Management

Git / Version Control / Branching Strategy

Scoping (chunking, costing)

Problem solving (fuzzy reqs)

Communication

Patience

Mental Discipline

Code Review

Every other week, we each self-assess in these areas, and pick three that we want to improve upon for the month/quarter/whatever. Then we keep track of our self assessments over time.

So far the self assessments have been pretty accurate.

you forgot 2 more points

h)... i)PROFIT

;-) now serious!

Refactoring!

Sometimes I learn something new, then I revisit any project I started and refactor it.

If you want to get some numbers to compare, you might look on lines of code removed, or timing the operation took. If it gets better, you can smile and say, I'm smarter than myself in 2014