Wednesday, October 31, 2007

Happy Halloween!

It is once again Halloween which, here in the U.S. means a time when all the kids dress up in costumes and go door-to-door "trick or treating" (which means begging for Candy).  I like this holiday.  It's fun to see everyone dressed up at the door.  Unfortunately around here at least, the tradition seems to be waning.  Malls, businesses, churches, etc. all have their own trick-or-treat times and few kids come to the door.  I can count on my fingers the number of groups we see in my neighborhood.  Sigh.  The upside is that with so few kids, we give out full-sized candy bars.  :)


Microsoft of course is one of those businesses which offer trick-or-treating.  The kids get dressed up and walk office to office.  Most people bring in candy.  It feels a lot like cheating.  When I was a kid we had to work for our candy.  Now, they get a whole bag-full in less than an hour.  Kids these days...

Monday, October 29, 2007

Vinyl Better Than CD?

An amazingly lucid discussion of the benefits of Vinyl over CD (or lack thereof) is going on over at Slashdot right now.  So far the trolls are straying away.  If you want some understanding of dynamic range compression, sampling, etc.  Check it out.


For the record, I'm in the CD is better camp.  It handles the frequencies that humans can hear (with perhaps a very small minority left out) and is much more stable.  Unless we are mastering CDs for our dogs to listen to, 44.1 is probably sufficient for a consumption medium.  Sure, there are mastering issues on many CDs right now but that's not the fault of CD but rather the process.  A CD without all those issues could easily be produced.

Saturday, October 27, 2007

A Little C= 64 Love

Here's a fun one for the weekend.  A retrospective of the Commodore 64 and it's place as a great game machine.  The C= 64 sold something like 17 million units and is, to this day, the single greatest selling computer model of all time.  My first computer was a Commodore 128 which was basically an expensive C64 with a lot of worthless hardware in it.  I don't think I ever did much with it other than run C64 programs.  Well, when I programmed in Basic I did so in C128 mode.  You could renumber lines there. 

Thursday, October 25, 2007

Testing A Daily Build

It is becoming accepted in the industry that teams should produce a build on a daily basis.  Every project at Microsoft does this as do most projects elsewhere.  If you happen to be on a project that does not, I suggest you work to get one implemented soon.  The benefits are great.  After a daily build is produced though, what next?  What do you do with it?  Here is my suggested work flow.  This is for a large project.  If yours is smaller, feel free to collapse some of the items.

  1. Deal with build breaks - If anything failed to compile, jump on it right away.  Drag developers out of bed and get it fixed.  Either that or back out the offending checkin (you are using a content management system aren't you?) and build again.
  2. Build Authentication Tests (BATs) - The first thing to run against a build are the BATs.  These are test cases that merely ensure that the build is not entirely broken.  These should ensure that all the right files were produced, that the setup works and places files correctly, etc.  Some very basic functionality may be tested here as well.  If the BATs fail, have someone look into the cause immediately and get it fixed.  Do not proceed with any more work on this build until BATs pass.
  3. Build Verification Tests (BVTs) - BVTs are a set of tests to verify basic functionality in your build.  These are not comprehensive tests.  Rather, they are limited in scope and time to the things that matter most.  I'd recommend you ensure that these complete within an hour.  If these fail, the build must not be released for further testing.  Developers must be called in and fixes generated quickly.  I've talked about these previously.  It is worth repeating a little here though.  BVT failures are not acceptable.  These are the canaries we take with us into the mine.  If they fall over, it's time to head for the exits.  Only put tests into the BVTs that meet the criteria that you're willing to block a build's release when they fail.
  4. Functional Tests - This is most of the rest of your test collateral.  These tests are initiated upon completion of the BVTs.  The functional tests contain all of your automation and any manual tests you deem worthy of being run on a daily basis.  These can take all day to execute if you want.  It is acceptable for functional tests to fail.  Each failure should generate a bug that is tracked.  The point of the functionals is to get a feel for the true state of the product.  Everything you want to work should be tested here.  When most (all?) of your functional tests are passing, you know you have a product ready to release to the world. 

That's it for the daily testing regime.  However, that's not all for testing.  There are other tests you probably want before you are ready to release.  These include:

  • Stress Tests - Make sure your code can work under stressful conditions like repeated use, high CPU usage, and low memory.
  • Longhaul Tests - Ensure that your code will continue to work over long periods of time.  The exact amount of time depends on the usage model of your tests.
  • Customer Acceptance Tests - Make sure the customer is happy with the product.  This is usually a series of manual tests that verify that the usability is acceptable.

Wednesday, October 24, 2007

New MSDN Tester Center

MSDN now has a home for test information.  Check out the new MSDN Tester Center.  It has articles, videos, and a collection of blog posts all revolving around the idea of testing.  If you are a tester or test developer, bookmark this site.  It looks like it will be useful.

Tuesday, October 23, 2007

What Self-Taught Programmers Are (Often) Missing

Some self-taught programmers can hold their own with the best coders out there.  Others, although smart people, are fundamentally less good at programming.  While there is variation among classically trained coders too, they are on average better than their self-taught peers.   Why is that?  Why can't self-taught programmers become as good in similar numbers?  There are a lot of reasons for this I'm sure, but here is one item that I believe has a large effect.  Self-taught programmers often have very little exposure to good programming. 

It is not uncommon for a self-taught programmer to work largely alone or with others with similar training.  Programmers don't tend to read a lot of others' code.  If they do, they read the small snippets they find on Google or Live.  They don't read whole programs.  Admittedly, it is hard to do this.  What gets lost without reading full programs is the way they are laid out.  Reading a sample on the web demonstrates how to call an API, but doesn't show how to organize code into a larger cohesive whole. 

I often compare programming to writing.  Someone who just knows the syntax of a language and tries to program is like someone who knows grammar and tries to write.  Technically, it will be correct, but it might not be much fun to read.  Good writing is more than just proper words in proper sentences.  It is the way the story flows that separates a good book from a poor one.  It is similar in programming.  It is the way the objects and functions interact that separates good programming from poor.

Think about a good writer.  How did she learn to be a good writer?  Practice.  But also exposure to other good writing.  Someone who is a good story teller usually exposes herself to other good stories.  I suspect that most good writers are, or were, avid readers too.

What does this tell us about becoming a better programmer?  Like a good writer, it is important that one is exposed to good examples.  In college, this comes in class.  You are exposed not to large programs--although that happens sometimes--but rather to the ideas that make good programs.  Exposure to algorithms, data structures, OS principles, design patterns, etc. all contribute to building up a repertoire to draw upon and emulate.  Self taught programmers often don't get this exposure.

This leads to a simple solution.  If you are a self-taught programmer, get exposure to the ideas of others.  This can be done either in the classical manner by reading books on databases, compilers, operating systems, patterns, etc. or by reading the code of programs that implement these ideas.  If you work in software development, read the modules written by the senior team members.  Don't read for syntax, but try to understand how the big pieces work together.  If you don't, go look at sizeable open source projects.  Become familiar with how the pieces fit together.

Monday, October 22, 2007

More Amiga History From Ars Technica

Ars just released another edition of its history of the Amiga series.  The first deals with the purchase of the Amiga by Commodore.  I'll be updating this post as new articles in this edition are posted.


Part 4 - Enter Commodore


Part 5 - Postlaunch Blues

Helping Groups Succeed

or What to do when you aren't in control but neither is the leader.

A while back I wrote about providing clarity as a leader.  As part of that essay I mentioned some techniques for keeping groups on track.  Those are well and good if you are the leader, but what if you aren't?  What if the leader of your group didn't read my post and is making a mess of things.  It's common for someone to be in a position of leadership but not be leading.  This usually results in meetings that are contentious, long, and don't bear fruit.  If they do produce anything, it comes at a tremendous price.  What should you do if you are caught in such a meeting?  Below are some techniques that will help.

First, it is important to get a good feel for what is causing the failure.  If the cause of failure can be understood, then the solution can be derived from there.  Many meetings fail because there is no shared vision.  There are two very important items that must be shared by all participants for a meeting to be successful.  First, there must be a shared vision of what the outcome should be.  What is the specific decision the group is trying to make?  What is the goal of the design?  How detailed does the design need to be?  Second, there must be a shared vision of the rules.  It must be understood how you are going to make the decision.  Without this shared vision, there will be a lot of time spent talking past each other, driving toward different agendas, following rabbit trails, etc.

Given that situation, what are the things a person can do to help the meeting succeed?  There are two primary tactics that I've seen work.  First, help form consensus.  Second, help bring things back on track.

Forming consensus involves several actions.  It means listening carefully to what is being said.  If two or more people are coming from the same or similar places, point this out and try to get other members of the group to agree.  A poor leader will let these similar voices get lost in the noise.  Stepping back from one's own agenda to try to point out and support the development of consensus is important.  It can help to move the meeting forward.  If there is no consensus forming, try stepping back from the immediate decision.  Is there a more fundamental decision that, when decided, could help constrain the current decision to more tractable territory?  If so, lead the group to that other decision.

Once consensus is formed, it is common for non-germane conversations to take place.   An interesting, but not relevant topic may be discussed.  Someone may bring up a new point on a decision already made.  If these are the case, it is important that someone bring the group back on track.  Point out that the conversation is straying and then bring up a point that is on topic.  Do so in a friendly manner.  You don't want to be seen as bossy. 

There is one other tactic which can work but doesn't always.  That is, grab the power.  Whoever is controlling the pen or the keyboard has a lot of power.  Offer to take the notes or write on the white board.  This gives you the opportunity to have influence on what gets written.  If you see consensus starting to form, just write it down.  If there is something tangential, don't.

Saturday, October 20, 2007

Another Project BBQ is in the can

It's October and that means it is once again time for Project Bar-B-Q.  This is the premiere computer music/audio think tank event.  It's a gathering of 50 people from all across the spectrum.  There are those who make audio hardware, operating systems, audio for games, midi controllers, etc.  Again this year I had the opportunity to attend.  It's been very enjoyable and quite productive.  I get the opportunity to meet many new people and learn new things.  It's a great chance to comingle with those who use our technology and see what they need us to change for them.  I also get to rub elbows with a lot of people I wouldn't otherwise meet and learn about new technologies and ideas.  I always come home recharged and ready to work hard to change the world.  This year is no exception.

Friday, October 12, 2007

Interviewing the Experienced

This week there was an interesting conversation over on Slashdot.  The subject of the post is an age discrimination suit against Google.  However, the discussion has gone to other interesting places.  The question is being asked if there is a difference in the way you should interview experienced people vs. those just out of school.  It reflects something I've come to understand after years of interviewing.  The software/IT industry is relatively young.  This is true both in terms of the workforce and the maturity of the work ecosystem.  The result of this is that we don't tend to have very sophisticated interview processes.  To be sure, they are good, but they are not flexible enough.  They are aimed at hiring the young hotshot recent graduate.  They are not usually designed to find someone with experience.  That will have to change as the median experience in the industry raises.

What is it that biases interviews toward those recently in school?  The questions we ask favor those who have graduated in the near past over those who have been in the industry for a decade or two.  It is pointless to ask a newly minted graduate about his/her experience.  They will likely have a few group projects and perhaps a summer internship to talk about, but the projects are all limited in scope.  Even someone who has been in the workforce for a few years will likely have been implementing someone else's design.  Assessing non-trivial design skills is hard and still harder in an hour-long interview.  So often we don't evaluate this.  Instead, we turn to the easily measurable.

We, as an industry, tend to ask a lot of questions that are more about particular knowledge than about problem solving skills.  Sure, we couch them in terms of problem solving skills, but they are really about particular knowledge.  Asking someone to describe OS internals (processes, memory, garbage collection, etc.) is biased toward someone who has recently taken an OS class or the few who work on the guts of operating systems.  It's not that most experienced people can't understand them, it is that they don't need to.  Many coding questions are about syntax or simple tasks no one faces in real life.  Asking someone to swap the words in a string without using extra memory isn't about problem solving as much as it is about knowing the trick.  Expecting someone to be able to characterize the running time of some algorithms is a test for how long it has been since they last took an Algorithms class.  I've even seen people take the simple question of "sort this list" and turn it into "can you implement quicksort in your head?"  Why would anyone need to?

As developers grow in experience, their work changes.  While the specifics of an implementation are still important, the harder work is about the interaction of objects.  Design becomes more important than syntax.  Strategy more important than tactics.  This has an impact on their specific knowledge.  Everyone knows that most of what we learn for a CS degree is of little value in the industry.  Why then should it be surprising that those whose graduation date has a different 3rd digit than that of the current year don't have fast recollection of such facts?  There is only so much information a mind can hold at a time.  It is thus more important to know where to find an answer than to be able to recall the answer off the top of one's head.

If the test of tactical information is not what we need on bigger projects and is not what experienced programmers are best at, how do we change the interview process to dig out the strategic skills we should be looking for?  Unfortunately, I don't have any great answers.  I'm hoping some of you can help here.  My best advice is to think about the questions you are asking.  Ask yourself if the skill required to solve it is something an experienced programmer would use every day.  If not, don't ask the question.  Instead, look for questions that are more central to work people actually do.  Also, make sure to expand the repertoire of questions to include design questions.  These take more time to think up than "code a fifo queue" but are a better judge of the utility someone will bring to the team.  Don't be afraid to ask softer questions about a person's experience.  What were the difficult problems the candidate ran into on their projects?  How did they handle them.  These questions will elicit low-value responses from a recent grad but a cornucopia of information from someone who has been around the block a few times.

Thursday, October 4, 2007

Understanding MP3 Compression

Another great article from Ars Technica.  This time about MP3 compression.  If you'e ever wondered how MP3 works, this is a great article to start with.  No math is necessary.