Monday, March 1, 2010

On becoming a practicing software engineer

If you're a recent or soon-to-be college grad (or maybe you realized your undergrad degree in Art History ain't gonna pay the bills) and you are passionate about computers and computer programming, here are my tips for becoming a successful practicing software engineer.  Many of these things probably aren't the things they taught you in your college programming classes, but all of these are important.
  1. Practice! Practice! Practice! You learn to code by, um, reading and writing code! If you don't have much experience and want to get started, find an open source project you care about and contribute a patch or two.  The "View Source" feature of Web Browsers and the open source movement are 2 of your greatest assets when learning to code.  Use them! As someone who started his career copying BASIC programs from Compute! and Byte magazines, I can't tell you how great it was to discover the magical "View Source" menu item in Netscape.  Open Source projects will teach you about packaging, style guidelines, automated testing, bug tracking, and version control -- while also giving you much needed practice.

    Don't forget, your code doesn't *work* until someone else uses it.  If you can't work at a startup and need to get code into the hands of users quickly, open source projects are a great way to go.  I still recommend going with the startup, though.  At Knewton, everyone from summer interns to new full-time engineers ship code (that customers actually use) in their first couple weeks of starting.  I'd like to get this down to the first day.

    In your early practicing, make sure to develop really strong habits.  I learned the most of my habits from Steve McConnell's Code Complete and Kent Beck's eXtreme programming.  Write code others can support if they need to, but try to make it so they don't need to support it :)

    I'd also recommend checking out PragDave's Code Kata site to work on solving problem:

  2. Work at a startup! You will learn more in your first month at a startup than you will in your first year in any other company.  The first company I worked for was a 3-person shop in Syracuse, NY.  I learned everything from how to become a practicing software engineer, to how to be a customer support person, estimate and bid consulting jobs, write requirements, QA, write user manuals, configure SQL Servers, configure IIS Servers, configure linux firewalls ... If your first job entails you being handed requirements that you then write code for and hand "over the wall" to QA - run!

    Don't just take my word for it.  Here's what one of our former interns who recently graduated and landed a sweet job in CO had to say:
    "I had NO experience as a coder.  You guys gave me a LOT.  In fact, more skillz than you can really understand. Things that transferred over beyond Ruby, RUnit, Rails, MySQL unix commands (I'm loving that I actually understand how to use the CLI in my Ubuntu set up btw...), etc - more the ability to take a bunch of instructions I barely understood and google my way/solve my way to a solution."
    Chris Dixon also has a couple nice posts on this topic:
    Joining a startup is less risky than you think.

    More specifically, work for my startup:

    If there's nothing interesting to you there, check out these couple of other sites:

  3. Don't be afraid to make mistakes! or Perfection is for popes and Chinese emperors.
    In 1999, I got my first big job at an online brokerage (Datek) in NYC.  This was back when everyone, probably including you, traded online and doubled their money daily - basic fundamental laws of economics changed... until they didn't.  The day of my first big release, I took down the ability to login to the production site at market open.  This was, as my CTO at the time reminded me, "reeeeaaaaaaalllllly baaaaaddddd."  However, we talked through the problems and took the appropriate steps to ensure I couldn't make the same mistake again (it involved improper DB connection handling, lack of performance testing, deployment timing and rollback procedures).  If he fired me, maybe I'd feel differently about making mistakes.  Fortunately, for me, he understood these types of mistakes will happen -- as long as you're willing to grow from the mistakes and not repeat the same mistake twice.

    Don't forget that coding is a creative endeavor; typically, there is no one correct solution.  Be prepared to try several.

  4. Reality...zen and the art of "boring" tasks.
    You studied sexy problems in school, you know how to solve nine-queens efficiently, find shortest path in a graph, compute Chebyshev distance in a metric space...the large part of your day as a software developer will not be spent working on such problems. More than likely you will spend a day on a far wider range of tasks that are comparatively less interesting in an engineering/problem-solving sense. These lower-level tasks are generally more simple and yet each decision that is made in their execution can be evaluated and perhaps improved upon. Design details as small as method signatures, naming conventions, loop constructs or recursion, tail-recursion or not (maybe even that's too sexy!), are both extremely important and regularly overlooked. A large program is built on many lines of code. Each line contains required prior decisions to produce. An appreciation for these small details will contribute a lot not only to the quality of the program as a whole, but to the education of the coder.

    If you're not already in a coding-related field, look for ways to make your current job more efficient through automation.  This can be as simple as creating access databases, word mail merges and batch files to automate tasks that used to take you hours or days to complete.  This is actually how I got my start coding professionally, by building MS Access database apps that made week-long tasks takes hours (mass mailings to customers at an HVAC rep and students at the SU Masters of Public Administration program).

  5. Finish!
    You don't get any points for effort.  You need to finish what you start.  Half-written, incomplete code atrophies very, very quickly.  If you find yourself starting more than you finish, you need to revisit the scope of your problems.  Code against smaller problems, but finish the code!
While not everyone is destined to be a great coder, if you're interested in learning how, I strongly recommend the list above.  I'm not certain this is an exhaustive list; I'd love to hear any other suggestions.  Good luck, and have fun!


    1. In retrospect I wish I had started off reading other people's code more often. I learn something new almost every time I read someone else's code or at least see things from a different perspective.

    2. I had a bit of an unfair advantage. I started my career solo, only using code from magazines which tends to be higher quality than most "legacy" code. At Datek, the first project I wrote all the code from the ground up was a port to Java from C using the code of a ridiculously prolific developer who had the cleanest code I've ever read -

      Josh had the most counter-to-best practices pieces of advice for me on coding, too -- I asked him if he had a library for one of the libraries he developed (for sequencing and guaranteed delivery of UDP), to which he responded "No. That code is soooo easy. I rewrite it every time I need it. Every time it's better than the last."

      Not having a CS degree makes me assume that most other coders know something I don't...

    3. Perhaps something worth mentioning to up and coming developers is that keeping things simple is really a top priority and learning to do that in an industry which is inherently complex is a real plus.

      Don't get sucked into "white-tower" type thinking, try to be pragmatic in everything you do, and remember... YAGNI.

      Embrace some form of test-driven development, because it's the evolution of our industry which has led us there.

      Leave your ego at the door when you come in to work. You should, and must, learn from everyone around you. That includes the n00b front-end guy with the mohawk and nose ring... seriously.

      Good luck!

    4. Heh, for the mohawked, nose ringed n00b - You Ain't Gonna Need It.

      I love that the lean startup movement is finding ways to apply YAGNI to product development. If no one clicks your adwords, no need to create the product... :)

    5. Nice writeup Pete....I really agree with you about the practice, practice, practice... Certainly this is extremely important to the new guys coming out of school or aspiring while in school. But what really amazes me, is the practice part disappears once folks are in the trade for several years. One mark of an improving software engineer is someone who can look at a past design or implementation and realize there is a better approach.

    6. @mike-silliman, your point about looking at a past design, approach or implementation and identifying a better approach is something 2 of my coders mentioned -- yet it somehow fell out of my list. will eventually refine. I know I've thought several other MVC solutions were far more elegant (and secure) than my implementation for DSI Cart :) In fact, I might even go a bit further than you and say if you can look at code you wrote, as recently as 3 months ago, and not find something you'd do differently today -- you're not learning!

      I can't think of a single line of code I've written that I looked back a month later and not though, "ick. what was i thinking! why didn't i do *this* instead?"