Archive for the 'career' Category

Update on “Thoughts on Software Development”

I got some good feedback on my previous post, Thoughts on Software Development. I wanted to get back to everyone with a few more things.

Matjew earlier questioned the value of computer science degrees and placed a great emphasis on the ability to learn how things work.  I appreciate his feedback. I’ll be the first one to admit that a computer science degree isn’t necessarily the best training for a career in software, and I spent five years earning one 🙂 However, I think that traditional engineers are no better, and are in many cases, worse.  I work at a CAD company and look at code written by mathemeticians, physicists, and mechanical engineers all day, and trust me, they’re no inherently better at software development than Asians are inherently good at math. 🙂

Here’s why.  While problem solving skills and the desire and perserverence to understand how things work are admirable traits common among more traditional engineers, I have seen that this personality-type often backfires.  I can tell you with certainty that in most software projects:

  • Intuitive encapsulation:  Good
  • Disproportionately large amounts of time spent on debugging and maintenance:  Bad
  • Code that everyone can use: Good
  • Intellectual masturbation: Bad

Good code should self-documenting.  Code that is meant to be called by others should have some sort of recognizable interface.   If you take enormous pride in making a career out of decyphering and maintaining difficult code, wouldn’t that time and pride be better spent making sure the code never got to that state of decay in the first place?  Doesn’t the “detective” attitude just enable and encourage more code that requires a genius figure out? I see too many “ultra-genius” employees from the math, physics, and mechanical camp who delight in telling long, long stories about how some code was, how it changed, and how it doesn’t make any sense any more, but they figured it out, and how that’s “cool,” and I have to ask myself, “why?” 

Here’s a great example of code written by a math person:

http://forums.thedailywtf.com/forums/p/8489/161407.aspx

While understanding is good, the goal is to get the job done. We’ve all heard the phrase “Work smarter, not harder.” In software, having the humility request to stand on the shoulders of genius rather than prop them up, to demand that the code you work with is usable, rather than debugging and testing for hours and days just so you can say “I did it!”, is truly the smarter way to work and is what a real “good” engineer should do.

Thoughts on Software Development

I recently had my fifth anniversary at the software company I work for, and I also recently had the opportunity to interview some potential summer interns. I began to look back on my career and education and try to catalog everything I had learned. What have I learned? Was my formal education worth anything? Did I really learn anything “on the job” or “on the streets?” The conclusion I came to was that while my college education was certainly very valuable, it only offered about half of the insight and context I really needed to be successful. I wanted to squeeze in an analogy about about how majoring in music won’t make you a rock star (oops, I already did), but I’ve tried to condense everything into the points below.

  1. Becoming a software developer is difficult because the software industry hasn’t been around long enough for us to:
    • Know how to properly educate students
    • Know how to properly train employees

    To put it another way, software development has evolved from PhD-level math and physics research to something more on par with MTV in less than sixty years, and education simply hasn’t kept pace with industry. As a result, software professionals typically like to or are forced to learn on their own and do things their own way. While this soft of self-motivation seems inspiring, it often leads to very messy, buggy software and disgruntled, disillusioned employees.

  2. The best way to become successful in software development is to be born with a very high IQ and start writing C, C++, and assembly when you are eight years old. This may feel horribly unfair if you are already over four feet tall when reading this now, but that’s life. The second best way involves doing *a lot* of reading, study, and practice outside of school and work. There’s no way around it. I was a horrible programmer in college. I wasn’t much better after my first internship. Things didn’t magically, automatically improve when I started my first “real” job after college, either. I only realized that I had finally “made it” as a software developer when I noticed that I looked forward to writing code that did something useful and non-trivial for fun, outside of work and school, and sharing it with people.
  3. Unless you have a masters or PhD in math or computer science, while possible, it is unlikely you will spend a lot of time working on data structure or algorithm design or analysis. This is disappointing to many young software professionals (and a relief to many as well :)). However, studying data structures and algorithms is important so that you can appreciate the appropriate one for a given task, even if you use a library’s implementation. While libraries for searching, sorting, etc… offer enormous benefits that few can afford to ignore, failing to have at least basic understanding of the difference between a “brute-force” algorithm and one that is at least reasonably optimal will give rise to serious problems if left un-checked. To put it another way, you have to know “it” even if you don’t use “it”, because you will use “it,” perhaps indirectly, when you least expect “it.”On that note, most modern software development actually often consists of:
    1. Gathering data from various sources, lightly processing it, and putting it somewhere else.
    2. Organizing existing data structures and algorithms into objects.
    3. Making separate pieces of code communicate (building your own middleware)
    4. Fixing bugs or making minor tweaks
    5. Adding or changing user-interface
    6. Listening to and understanding requirements
    7. Re-doing what has already been done a slightly different way (legacy code maintenance)
    8. Writing and maintaining high-level scripts to automate mundane tasks.

    If you ever want to get to the algorithm/data structure level, be prepared to stay in school another few years or pay your dues with a lot of work on 1 through 8.

  4. One of the biggest Achilles-heels in software development is that computers allow to people quickly create systems that are more complicated than any one person could ever understand well. One of the biggest misconceptions about software is because computers are inherently logical, one can always find a concrete, correct answer for any problem. These two phenomena are not un-related. To put it another way: Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. ~Brian W. Kernighan
  5. One of the luxuries that a software developer often strives to have is the opportunity to work exclusively in programming languages or technology areas he or she is an expert in. Unfortunately, most real-world projects and bug-fixes require sparse bits of basic and advanced knowledge of many different topics. You will often find yourself reading single pages of many books and articles just to fix a single line of code. After working in industry for a few years, you are likely to find yourself a “Jack of all trades, master of none.” Consequently, a developer can potentially invest much time in his career in specific areas such as MFC, OLE, OpenGL, and still not have gathered enough skills to feel satisfied as comfortable or “proficient” in any of them. See the second part of item (2) for a possible solution.
  6. Learning to develop software without being overly dependent on a certain environment is another aspect of the real world that new software developers will need to get used to. There will be many times that for some reason, good, bad, artificial, or unfair, you will need to develop code without free, popular libraries (STL, Boost), without garbage collection (Java, C#, etc…), or without wizards or an IDE (Visual Studio). While it’s not much fun to parse a text file using little but C, fscanf(), emacs, and gcc, you should be able to do this to a reasonable degree upon request. No on expects you to be at your best here, but you can’t go to pieces without your favorite tools.A related point: Larger, older companies often have made investments in technologies years ago that are, by the popular software media’s standards, “obsolete.” While MSDN Magazine will tell you that COM, MFC, and Windows 2000 are dead and that .NET and web-services are what you need to know in today’s workplace, unless you’re working for a small startup company, you’ll likely find that many of the books you’ll need to buy for your job still have copyright dates from the nineties.
  7. Software development, if nothing else, will drill the idea into your head that everything works in theory, but in practice…do I really need to finish this sentence? :). While everything that you learned in your computer science degree is important, you will see your four years of study bastardized, satirized, perverted, and disregarded every day in most software-oriented workplaces. Your job is to make an attempt to use what you have learned as much as is practical while allowing for the reality of deadlines and customers. To put it another way, software development is not unlike your typical feel-good movie where a young, inexperienced teacher takes a job in a poorly funded, inner-city high school, is overwhelmed at first, but through charisma, dedication, and unorthodox techniques, ultimately makes a difference. Your mileage may vary on the “makes a difference” part.
  8. The best software developers are the ones who can cope with, in a diplomatic, team-friendly way, all of these frustrations, even if they are against them in principle.

Success and Failure

 
I’m trying to debug an (allegedly) obscure and difficult .NET interop issue with MFC-based COM. So far, I’ve learned very little and have no idea what I’m doing. In my typical “think outside the box” style of avoidance / coping mechanism, I wrote this.

 I recently visited www.worsethanfailure.com, a site dedicated to stories and essays about software development escapades gone horribly wrong. I can’t find the particular text right now, but I do remember reading somewhere “Failure is the best teacher. One doesn’t get better by winning, does he?” While many tough-love advocates enjoy this cliché, I disagree. To put it another way, I think that Edison’s optimism on all his failed light-bulb attempts was a bit shallow. I was recently watching “House,” and Dr. House, as usual, was browbeating his team for performing tests that eliminated potential diagnoses. He belittled their efforts by making the comparison, “I asked you to find out what two plus two is—you’ve been up all night and all you can tell me is that it isn’t twenty-three?” While House is certainly an ass, he’s right. While I am not a big fan of the lukewarm “everything in moderation” crowd, I feel that a combination of success and failure is the best teacher.

 Okay—it’s time for another analogy. Does anyone remember the episode of “The Simpsons” that featured a battleship game? Millhouse has managed to fire a shot at every single vacant square on his opponent’s field. All that remains are the un-touched ship areas, surrounded by an envelope of misses. Has Millhouse learned anything? Even “perhaps” is a bit of a stretch, but even given that, he learned very, very slowly, and fostering slow learning isn’t typically the mark of a good teacher.

 I’m not sure what the ideal ratio of success to failure is when learning something new. (I’ll be a jerk and say 50% success to start, and hopefully, the success/failure feedback loop will drive that percentage up as learning progresses.) Keep in mind, though, that in life, the number of things you could possibly do wrong in a given scenario typically dwarfs what you could do right, and not all failures are useful learning experiences any more so than claiming 2+2 is “twenty-three” or “George Washington.” A useful failure would be to get a hit in a battleship turn, guess one space to the left next time, notice it is a miss, and then use process of elimination to make the next guess statistically more likely to be successful. However, one can never have that experience without some initial “seed” success. success x failure = learning and insight. If you take this literally, then 50% actually is the idea ratio.