
What is the most effective thing you did to improve your programming skills? - dangrossman
http://stackoverflow.com/q/76364/280598
======
zedshaw
I wrote build scripts for my projects that tracked:

1\. Syntax errors on compile (it was C). 2\. Test failures. 3\. Time of the
run. 4\. Lines of code.

Then I used R to create graphs and reports that were generated periodically.
About once an hour I'd go look at them and see what synax+failure levels were
per line of code at that time. I'd then plot this as a run chart and start
trying to find causes of my high defect indicators.

Eventually it got to where I found a bunch of the ways I wrote defective code
and started to avoid them. I have a set of macros for C now that prevent it,
and I use the patterns in my other coding.

It was pretty insane though. I don't recommend it for anyone, and definitely
not on a project you have to do for a living. Well, maybe if it's a missile
command system or medical device.

~~~
JoshCole
Has anyone made a plugin or anything of that sort which abstracts away the
grunt work of using this sort of system? It sounds like a great thing to try
out were it not for the opportunity cost of trying it.

~~~
zedshaw
Not that I know of. I imagine emacs or vim has good error-line parsing which
you could steal/copy and get really good results. You could then extend it to
work on any language you wanted.

Biggest thing I couldn't get right was automatically connecting frequency of
errors to particular lines or modules. I found that I made the same mistakes
over and over, and I had to just spot them and jot down what not to do or
think of a ninja way to avoid it. I also found that there was a strong
correlation between syntax/test failures while writing code and how bad the
code was.

What would have helped is if I could calculate the stats per function, line,
or file and then have some pattern analysis spit out common grammatical
structures that I do which are correlated with errors. It'd be something like:

function/while/if/return 24% chance of defect found in blah.c:func1 and
blah.c:func2

Then it'd get closer to predicting defects and letting me go check the spots
it recommends.

But, never got around to it since it became really insane after a year already
without that level of analysis.

------
edw519
I wrote a framework.

Instead of thinking, "How do I want this program to work?" I had to think,
"How do I want _every_ program to work?"

Instead of organizing this data, I had to organize _any_ data.

Instead of worrying about what my customer needed, I had to worry about what
to put in my toolbox before I called on that customer.

Instead of handling the current outlying case, I had to learn to _anticipate_
possible outlying cases.

Instead of worrying about instances of what we do, I had to worry about
_classes of instances_ of what we do.

Instead of benchmarking and optimizing performance, I had to understand the
kinds of things that affected performance.

Instead of scaling, I had to design an architecture that would scale.

Instead of conducting analysis and design, I had to build an application to
handle and apply system parameters.

Instead of covering bugs, glitches, and inefficiencies, I had to _eliminate_
them before they compounded exponentially before my eyes.

Instead of having fun, I had to build a world within which I could always have
fun.

~~~
JesseAldridge
Big design up front? Seems like a lot of your advice flies in the face of
prevailing agile principles.

What do you think about YAGNI?

<http://bit.ly/cpbljR> (YAGNI Wikipedia article -- apparently HN doesn't like
apostrophes in urls.)

~~~
edw519
_Seems like a lot of your advice..._

I gave no advice. I shared my experience. Take it or leave it.

 _What do you think about YAGNI?_

Never gave it much thought before. But after reading your referral, let me
rephrase the question: "How do you know what you're going to need?"

After servicing hundreds of customers, I built a framework that provided what
over 90% of had already needed. I figured it was a pretty good bet most new
customers would too. So far it's worked out great. The framework has easily
replaced one or two other programmers.

But then again, that isn't even what the original question was about. OP asked
the #1 thing that made me a better programmer. This was the #1 answer by far.
I think everyone should write a framework, whether you need one or not. You'll
never think the same way again.

~~~
jemfinch
The key to your success is the "after servicing hundreds of customers". YAGNI
is for the people who try to build the framework first, before they serve any
customers.

------
pg
One was to write a book about programming. Your programs literally have to be
exemplary. It was interesting how much work that took.

~~~
runjake
I usually don't upvote pg's comments, because he could say "I like turtles."
and get 1,000 upvotes, but pg's advice here is gold.

You should do this. You don't even need a publisher, you could approach your
topic like Zed Shaw did with "Learn Python The Hard Way".

Or you could do a series of blog posts. You WILL get feedback and this will
improve your skills.

~~~
davidw
If you're only focusing on the 'writing really good code' aspect, sure. But in
the wider world, writing a book can be a spectacularly bad way to invest your
time.

I've made way more money from my "Slicehost vs Linode" article than I have
from my portion of "Tcl and the Tk Toolkit, 2nd edition", even though the
latter required a ton of hard work.

~~~
aaronblohowiak
I think the value is in the _writing_ itself, not the monetary feedback.

~~~
davidw
Yes, I acknowledged that - but I think that most people would do well to at
least consider the other aspects of writing a book as well.

------
jakevoytko
Introducing variety into my routine always improves my programming skills.

I started in high school writing homework helpers in Java and C++, and writing
graphing calculator scripts to make fun patterns. Then I worked with other
programmers, and started structuring my code to make it understandable to
others. Then I started ACM programming competitions, and learned to rigorously
solve problems. Then I found Python, and learned that finishing can be quick
and easy. Then I got an internship at a major corporation, and discovered I
never want to be an enterprisey programmer. Then I got a GSoC gig and learned
to collaborate remotely and make estimates. Then I got a real job and learned
to work with code for months and years, instead of churning out small
projects, and the importance of finishing early and often. Then I experimented
with Lisp, and learned the importance of abstraction, community, and
salesmanship. Then I played around with Tornado and started learning about the
web. Recently, I got a better job and started learning the importance of
testing, the importance of listening to users, and the value of a second set
of eyes. Recently, I've started experimenting with the Android SDK, learning
the power and limitations of major constraints.

I can't wait to see what the future holds.

------
mattmight
As a freshman in CS, I took a course where we reimplemented several of the
standard Unix commands (like date, ls and cut) and much of the standard C
library.

We also had to implement a subset of the bash shell, a lynx clone, a GNU make
clone, a Lisp interpreter and a Lisp-to-C translator.

Having to implement many of the tools I've come to use on a daily basis was a
transformative experience for me, and a great way to learn how to write
efficient yet safe C code.

That experience inspired me to take the compilers class the next year, where I
programmed in a functional language (Standard ML) for the first time. I was
impressed with the expressive power and robustness of functional programming,
and I've clung to it ever since.

These two experiences also set me on the path to becoming a professor. Now I
teach and research compilers and programming languages for a living. I find
hardly a day goes by where I don't learn something to improve my programming
skills.

------
aurynn
I wrote a parser and lexer by hand. Building the mental abstractions to figure
out how a syntax tree should be constructed and walked was amazing. It gave me
the tools to visualize how code is structured, how to avoid poorly structured
code, and how program flow actually works.

The first revision took me around 6 months to implement, and the second about
3 days. Worth every moment of futzing around and hacking and designing.

The language is getting rewritten (this time with an actual grammar!), and I'm
finding it still has a mountain of useful things to teach me about
programming. I can't recommend it enough. :)

~~~
al05
Did you cheat and use a regex library in your lexer, or did you build a regex
engine aswell?

I built recursive descent parser, and a lexer using the posix regex libary in
2 days first attempt and extra 14 days for semantic analysis and x86 code
generation which operated by walking the ast. Most of those days were mostly
learning x86 assembly. I can't understand 6 months, unless you did everything
from scratch like the regex engine I.E Constructing NFA's, converting to DFA's
etc etc.

~~~
aurynn
I think I cheated and used an existing regex library - it's been a while.

As far as the 6 months, it was my first major, major project and required so
much learning and research on just how to structure code that it took a long
time to craft. It didn't help that the design was so complex that debugging it
was a chore. :)

Hence the V2 rewrite that took a couple of days.

------
iamwil
For me, they are:

    
    
      * become more sensitive to your daily pain points and 
        move to eradicate them
      * read other people's code
      * before sitting down to build anything, think: 
        "is there an easier way to solve it?
      * learn about good architecture and engineering 
        practices, but don't worry about them until 
        a) you know what you're building 
        b) they're a problem.
      * learn programming languages in different 
        programming paradigms.

~~~
unoti
Your idea about tracking daily pain points was the most important thing I ever
did, as well-- sort of.

I tracked, over a one year period, every single defect that made it into
production that I had to correct. I did this at the inspiration of a book on
continuous improvement I read. I analyzed the underlying causes of the
defects, organized them by category, made Pareto charts, and looked at my
underlying procedures to see how I could avoid them.

What I learned surprised me, and changed the way I approached projects from
then on. What I learned was that by far the number one problem I needed
correct in order to avoid production defects and downtime had nothing to do
with my code.

I discovered that the number one cause of avoidable defects in production had
to do with the quality of my test data, differences between production
environments and test environments, and discipline in how code gets promoted
to production. And of course establishing a process for such things as
promoting code-- a process which is formalized, followed, every time, and
continuously improved as needed.

Learning this gave me a new respect and appreciation for the importance of a
faithful and realistic staging environment that mirrors production as closely
as possible. It's often impractical or expensive to various degrees to
replicate or simulate a production environment faithfully for a variety of
reasons. What I learned is that not all projects deserve the expense and
trouble of that faithful reproduction of the production environment, running
production loads in staging. But to whatever degree we don't do that, we take
on more risk, and it's good to at least understand those risks.

Perhaps I'm talking more about project management, infrastructure, process and
procedure than about pure "programming". But what I learned through this one
year exercise was that often times when people think about wanting to get
better at programming, improvements in some of those areas are really what's
needed to get to the higher tiers of excellence.

~~~
elimisteve
"I tracked, over a one year period, every single defect that made it into
production that I had to correct. I did this at the inspiration of a book on
continuous improvement I read."

Which book?

~~~
unoti
It was "Improving Software Quality: An Insider's Guide to TQM" from Wiley. A
lot of people fear the idea of formalized process, thinking that it is going
to saddle them down with the useless baggage of unneeded red tape and forms.
It's actually quite the opposite. It's all about keeping processes as simple
as possible, even simplifying existing processes.

------
ericflo
I coded, a lot, on things _just_ beyond my ability. IMO this is the path to
success in anything: practicing, a lot, on something just beyond your current
ability. It's not always the most fun though, because since it's just beyond
your ability, it's hard and sometimes frustrating.

------
51Cards
Start getting paid to do it. Once you have feedback coming in from customers
who are your bread and butter, and you start trying to implement that feedback
to keep them happy only to find your framework was ill thought out, you'll
quickly learn to do things right from the start. Reading proper technique is
useful, peer review is useful, but that first time you sit up all weekend
revamping several core routines because you didn't plan well you'll learn more
than the other two combined about not cutting corners. (edit: this also
applies to learning to test properly too)

Disclaimer: the above comment may or may not be based on several moronic
experiences the poster is too embarrassed to confess to over his 20-ish years
in the 'biz'. Maybe.

------
jefe78
Co-founded a tech startup as CTO with no developers on staff - yet. I ended up
having to code the tools I wanted/needed and learned things I would have never
learned if I'd just, "learned to program" in my free time. Have a goal.

EDIT: I have a comp-sci degree; it taught me very little about 'programming'.

------
neilk
It's not something I did per se, but one former employer had mandatory pre-
checkin code review. This is a controversial practice but in my experience,
only with people who haven't really tried it.

Not only does this help find bugs, it will force you to write code that isn't
embarrassing. You will end up communicating much more with colleagues; before,
during, and after the code review process. I believe it will clean up, or at
least address, almost every bad habit you have.

If you can't get this at work, try an open source project that has a similar
review process.

~~~
dalore
I've implemented this too. You take a branch of the mainline, work on your
feature, integrate mainline if it has moved on in the meantime. When your
ready to submit you tell one of the reviewers. They checkout your branch, do a
diff and if it's good they submit. If they have questions you talk about it
and if something is not right or missing, they get told to add it.

It stops lazy check ins and it means at least 2 people know what code has gone
in recently.

------
michaelchisari
Started an extraordinarily ambitious open source project when I was just naive
enough to not know better.

~~~
Joakal
Mind if I asked why it was extraordinarily ambitious?

~~~
michaelchisari
Well, at the time (2004), it was extremely unexplored territory. Social
networks themselves were almost brand new, and the idea of creating a
distributed, open source one was almost unheard of. The nearest project (DiSo)
didn't show up for two years after that.

Also, my intention quickly became more than just a social networking app, and
I really wanted to turn it into a framework for social apps. So that brought
up all kinds of issues of MVC framework design and how to build an API and
other large architectural issues.

Not to mention that a lot of the project I've had to do myself, with both very
little precedence, and very little help (comparatively). Some of that was my
fault, for not being better at documentation and project management, but I
also learned that soliciting help for open source projects is a lot harder
than The Cathedral and The Bazaar made it out to be.

It's easier now, that the groundwork has been set, and there are competing
projects I can look at and learn from, but the first few years of flying blind
was a hell of a crash course.

------
sammcd
A lot of these mention working with people that are better than you.

I currently work at a startup where I am the only developer. I'm also starting
a company on the side where I am the only developer.

Does anyone have any advice on how I can supplement this? I'm currently
looking into working on large open source projects, so I can work with other
people, but I'm just not sure if that will work.

------
didip
I build apps, quite a number of them. And force myself to push every single
one of them to completion (launched and deployed).

Every app must have at least 1 non-monetary gains for myself. Examples:

* When I build an app with Tornado, it's because I want to see how event driven server works and how to interact with epoll.

* When I build an app with Rails, it's because I want to experiment with things I probably won't do for professional rails work. E.g. using Rubinius or Erubis.

* One of the older app I killed was written in Zend framework because CakePHP was (a while back) too slow and I think modularity in PHP app is a good thing.

* The latest one is being written in Lua because I have heard so much awesomeness about its JIT.

* With every single app that stays running, I continually learn something new about Ubuntu administration and jQuery plugins.

Of course I killed my apps if they don't take off because VPS renting gets
expensive fast.

------
Ogre
My first paying programming job was adding peer-to-peer multiplayer to an
already fairly mature game that was not designed for it. This gave me a LOT of
experience debugging other people's code. That style of multiplayer, common in
RTS games, requires every computer to run the same calculations in lockstep.
This particular code base had complex AI... with a surprising number of
uninitialized variables. I guess it wasn't THAT bad looking back, but tracking
them all down took me months, and I learned a lot about developing and
debugging large projects in the process.

(The game was Close Combat, if anyone was going to ask)

------
davidw
Be born to parents who got me a computer when I was 5. Computers have always
felt 'natural' to me as a consequence, even if, clearly, there's lots to learn
about what actually makes them tick.

------
thisisnotmyname
Got employed writing software full time. Tried to make my job a little bit
easier every day.

------
wccrawford
Lot of good things here, but there's 2 I haven't seen:

Learn a new language. In particular, learn one that requires thinking about
programming in a different way. Coming from Basic, C, C# and PHP, learning
Ruby was a real eye-opener and improved my coding.

Find a mentor. Watching someone code who is better than you at some (or all)
aspect(s) is a very quick way to polish your skills. Especially if you can ask
questions and have them suggest improvements.

------
tassl
There were 2 projects back in the university that made me improve my
programming skills: building an OS (multithreading based on a DOS system) and
building a compiler (using JavaCC).

In a different way, learning Lisp and Prolog, which basically widen your
perspective.

Also, I have a question; most people say that they learn by reading good code,
which I agree. Do you have any recommendation of a piece of code that you
consider it has "something to teach"?

------
keithba
Here's what I did to make me better at shipping software (which is slightly
different than the question asked.)

I read moneyball (<http://en.wikipedia.org/wiki/Moneyball>) - a book about
using sabremetrics to create a winning baseball team and realized that
everything I knew about being a great programmer and creating a great team was
wrong.

The key takeaway I took from the book is that the things we think make a great
baseball player (such as RBIs and HR) aren't what help win a game. There are
better stats, such as on-base percentage.

In the world of software, I correlate between winning a baseball game with
shipping software. And I suspect that what we traditionally recognize as
strong individual performance isn't really what leads to shipping great
software (same as having someone hit a lot of HRs on your team doesn't mean
you'll win a lot of games.)

Right now, I suspect that (so-callled) soft skills around communication and
time management are the fundamentals stats that are more important. So I've
focused heavily on things like personal and team time management, and writing
skills.

------
DanielBMarkham
Read lots of books to understand how expert programmers _think_ about
problems. (SO and other sites don't qualify as this as they as they are
focused on "How do I do X?" which is a completely different thing -- mostly
trivia)

Pair program/code review to learn what you're doing wrong.

Teach it if you want to really know it. PG's idea of writing a book is great,
but I've found the interactive nature of hands-on teaching really makes me
grok something. Writing, for me, helps me organize my thoughts, but coding is
something you never do "perfectly" -- the goal is to solve a problem for real
people, not create the perfect mathematical construct -- so I'm much more
interested in how different personality styles and moods approach problem-
solving in a language more than I am the details of the language itself.

Each of these works at a different level: strategic, quality-control, and
tactical. Depending on personality type, folks have a tendency to get hung up
on one level or another -- as if learning all the syntax of a language or how
to use the IDE is the same as mastery -- but for me I've found I need all of
them in equal parts.

------
Joakal
Before you can learn programming, you must first learn programming concepts.
This is why smart universities teach you how to do programming rather than
teach a language alone. eg: You can implement a SQL JOIN query but do you
understand what the SQL JOIN query does?

Otherwise, you may find yourself being stuck to certain languages (and
functions!) which can be pretty bad. eg Using if then when a switch would be
clearer and quicker. Or, applying indexes to every field in the hopes it'll
make the database quicker. etc.

That said, I found the best way to learn a language is to do an (Extremely
small!) side project for a certain area. eg eCommerce website? Pretend you
only want to sell 4 items (2 per page) and attempt to make it pretty so you
understand how designers design. And aim to understand WHY the code does what
it does. (There are more ideas and projects out there)

If you're going to attempt a start up, I suggest learning frameworks and APIs.
Both typically save lots of money and time until you become commercially
viable to cost (by then, you should be profitable).

------
alok-g
This is not something I did, but something that happened. Nevertheless, this
was a valuable lesson for me:

I learned programming on a machine (ZX Spectrum+) which performed syntax
checking as I typed. On the other hand, run-time errors often led to crash,
making me loose my programs (system had no hard-disk!). Without me realizing
then, it taught me how to write bug-free programs (since penalty for bugs used
to be so high). Yet, with PC-based code editors, my programs have a lot of
syntax errors.

I realized this when I met someone who could write five thousand lines of code
without compiling even once and yet with less than two syntax errors!! This
person was trained by writing programs on paper, and penalty for even syntax
errors was set too high.

My lesson has been to dislike test-driven development. I like to certify my
programs as correct by looking at them. When bugs are found during testing, my
brain ends up getting trained automatically not to repeat those bugs without
requiring tests to discover those bugs.

~~~
alok-g
After-thought: Best way to learn something is to let the human brain do it in
ways that humans don't currently understand...!

------
abecedarius
Not the _most_ , but: take code by a master and try to improve it. Someone
like Ken Thompson or Peter Norvig. It's best if you can get an early version
and then see what _they_ did with it, after your own work, though that isn't
often possible. (Norvig's PAIP has answers to some of the exercises -- lots of
such opportunities there.)

------
giberson
Single most effective thing I do to improve my programming skills?

Refactor.

It might be enough to get a hack done to get some functionality working but if
you never revisit it you wont learn what you did wrong or what you could have
done better. Refactoring your solutions trying to improve efficiency, or
usability (of the code), the process of examining your previous work and
discovering how it could be made better will greatly benefit your learning
process. Some times you may realize right away after finishing a piece of code
how you could have done it better. Other times, its not until months or years
later when you've learned and experienced more that upon revisiting the code
you realize how you could improve it.

It's one thing to learn about programming techniques and designs, but it's
refactoring your old attempts with those new techniques and designs that leads
to understanding and empowerment.

------
ojbyrne
Touch typing.

~~~
zedshaw
Yes! This. A thousand times this. You wouldn't believe how being able to type
your code and watch it while you type improves what you write.

------
wallflower
The most effective thing I did to improve my programming skills was to join a
team that was accountable for a goal with a real deadline.

If you don't have accountability, you don't need to make progress. No one
knows or cares that you didn't work on your software project if you don't tell
them. But if you have people counting on you, you have to make weekly
deadlines.

Accountability is the key to success. Especially one it is accompanied by a
strong desire to gain acceptance and approval from the cool kids (e.g. the
really good coders who you are working with).

------
cloudhead
Hands down: Taking on projects far beyond your skill level, and getting to the
end of them.

~~~
thinkingeric
I'd add to that having already been paid for it and needing to hand off to
others to maintain. I guarantee that the next project you do will be at a
whole new level.

------
danparsonson
Personally I've taken great strides every time I've changed job - being forced
to learn a new set of skills and new problem domains, plus interacting with
different (hopefully more experienced) people have always been very beneficial
to me.

------
darkxanthos
I learned to communicate my programming desires and thoughts in concrete ways
including but not limited to domain modeling via UML-ish diagrams on the white
board.

------
geophile
\- Learn new stuff. But not every new thing. Yet another
framework/language/library for xyz isn't usually worth it.

\- Work with the smartest people you can.

\- Strive for beautiful code.

\- Keep simplifying.

------
jemfinch
I learned Ocaml. The type discipline I learned in that language improved my
code in all other languages, especially dynamically typed ones.

------
grammr
Write code with testing it in mind. Testing is often introduced far too late
in the programming learning process, if at all.

~~~
farout
Every book I read by a real-world programmer - never does this. They always
put testing in a separate chapter or never address it at all, example:
programatic programmers.

Even any tutorials online or in a user group - it's never done. It's always
talked about. I come from a engineering background so I really wanted to
programming the "right" way. But here is so little code that includes testing
that I can use to "tutor" myself. Even opensource.

I find this very odd.

~~~
codeslush
Have you looked at this Rails tutorial? <http://railstutorial.org/chapters/>

Source code control, deployment and testing are all baked into the tutorial
from the very first section where coding is started. It's also available in
print form.

~~~
farout
Thanks, I will when I get back into rails. I have given up on it as of right
now. It nice to know there are more resources that include testing than there
were 2 years ago for rails.

------
antirez
reinventing the wheel many times, in the form of implementing all the kind of
algorithms and programs I could find interesting, was very useful for me.
Chess programs, device drivers, data structures, network servers, and so
forth. About design skills, I think reading many RFCs is a great help.

------
bobf
Get involved with a community related to the programming language; I've had
great success with IRC.

------
rjrodger
Read Steve McConnell's Code Complete. This book takes you from apprentice to
journeyman.

------
thibaut_barrere
For me it's: learn one little thing every single day (even a really small
one).

------
ivanzhao
Write short functions.

------
ecaradec
If it doesn't hurt, you aren't trying hard enough...

------
dustingetz
after you get the tactical stuff down, find someone smarter and more
experienced than you and turn him into a mentor.

------
binarymax
Read, code, read, code, read, code...

~~~
nostrademons
Throw a "read code" in there too.

------
ed2417
Fix my own bugs.

------
farout
program. recreate ones in tutorials from scratch several times. Then modify
them to make them do what I wanted them to do. Then create my own.

Program 16 hours a day. 7 days a week. Then sit and beam at my work.

PS don't program 16 hours a day. I had put ice packs later on my arms from the
pain.

also get a super monitor, awesome keyboard, and a comfortable chair.

------
bonch
Unit tests. I also read code recreationally.

