Welcome to MSDN Blogs Sign in | Join | Help

Keep Your Eyes on the True Goal

We recently went through mid-year reviews and I found myself repeating similar advice several times.  Here it is:  Be very clear about what your goal is and continuously reassess whether you are on track to get there.

To make this more concrete, consider a plane trip from Seattle, WA to to Austin, TX.  If you look at a map, you can see that the heading to Austin is something like 135 degrees from Seattle and the flying time might be 7 hours.  Does the pilot take off, set the compass to 135 degrees and set an alarm for 7 hours later?  No.  If he does, he could be in Little Rock by the time he wakes up.  Why is that?  Wind will push the plane around.  If the pilot doesn't correct for the wind, he won't end up where he expected.  Instead, the pilot constantly monitors his location and recalculates the necessary heading and speed to get to Austin on time.

There are two tendencies I've noticed among developers which can be rectified by following the example of the pilot.  The first is the tendency to fail to monitor progress.  The second is to focus on the trip, not the destination.

There are three aspects to the tasks most developers are asked to accomplish.  They are called upon to implement some functionality by a specified time and in a quality fashion.  When a developer decides up front what work needs to be done and then plows through it without reassessing along the way, he runs a high risk of failing to deliver.  There are too many unknowns (and unkunks) for a plan created at the onset to be successful.  Without reassessing on a regular basis, the developer won't recognize that he is behind and thus will not be able to correct.  Like the pilot who lands in Little Rock instead of Austin, the developer who does not evaluate progress along the way will get to the end of the project and realize he still has a month of work to do.  This is one of the secrets of Scrum.  It forces reassessment on regular intervals.  Another technique I have found to work is to break up your tasks over the project (or milestone) into granular work items.  Each item should be a few days at most.  Then, at least weekly, mark off progress against them.  Keep track not of how much time you've spent so far but rather how much time is left and compare that to the amount of work left.  When work remaining exceeds time left, it is time for a course correction.  Because quality cannot be sacrificed, either move out the delivery date (if possible) or cut features.

A different problem is when a developer mistakes the assigned tasks for the goals.  An example comes from the test development side of the world.  Let's say the goal is to test a new video manipulation API.  This Core Video or DirectX Video Acceleration or something.  To test whether this works correctly, it is determined that it makes sense to write a simulator.  The test developer starts writing this simulator.  Along the way, he confuses his real goal (test the API) with his task (write the simulator).  If, at the end of the milestone he has a great simulator but hasn't had time to actually use it to test the API, has he succeeded?  In his mind, he has.  Unfortunately, he is like the pilot who confused "Fly at 135 degrees for 7 hours" as his goal instead of "Land in Austin."  What is the solution?  Always keep your eyes on the real goal.  If the simulator is taking too long to complete, consider alternatives.  Is there a way to cut a feature and still test most of the API?  Would it be better to cut the losses and approach from another direction? 

Constant course correction can only work if the pilot knows his true goals.  Having the wrong goal in mind or not recognizing when he has flown off course is disastrous for a pilot.  Likewise, not noticing you are behind or that you aren't going to accomplish the real goals of your project is disastrous for a developer.  Work with your manager (or program manager) to understand what the reason for your project is and always keep that in mind.  This way, you'll be able to correct course before it becomes a problem.  Don't mistake your tasks for your goal.

 

Note:  I'm not a pilot.  Some of what I say about planes is inevitably incorrect.

Posted by SteveRowe | 1 Comments
Filed under:

A Microsoft-Yahoo Takeover Primer

Marc Andreessen has a great blog post today laying out the possibilities in the Microsoft-Yahoo talks.  Unlike most posts on the subject, this one isn't trying to guess what might happen.  Instead, it lays out the options and the forces affecting those options.  What is a proxy battle?  How would it take place?  Who are the investors we're talking about?  What is a tender offer?  How is it affected by a poison pill?  If you are following the subject, check out his post.  It's a good primer for the rest of the pontificating on the subject.

Posted by SteveRowe | 0 Comments
Filed under:

Prefer Composition Over Inheritance

It's probably about time to bring my "Design Principles To Live By" series to a close.  This is the last scheduled topic although I have one or two more I may post.

Let's begin with some definitions:

Composition - Functionality of an object is made up of an aggregate of different classes.  In practice, this means holding a pointer to another class to which work is deferred.

Inheritance - Functionality of an object is made up of it's own functionality plus functionality from its parent classes.

For most non-trivial problems, there will be similar code needed by multiple classes.  It is not a wise idea to put the same code in more than one place (a topic for another day).  There are two strategies in object-oriented programming which attempt to solve the problem of duplicate code.  The one most popular in the early days was inheritance.  Shared functionality was implemented in a base class which allowed each child class to inherit that functionality.  A child would just not implement foo() and the parent would do the work.  This works, but it is not very flexible.

Suppose that the shared functionality is some kind of encryption algorithm.  Each child class will only inherit from one base class.  What if there is a for different encryption algorithms?  It would be possible to have multiple base classes, say AESEncryptionBase and DESEncryptionBase, but this necessitates multiple copies of the child classes--one for each base class.  With more than 2 base classes, this become untenable.  It also becomes very difficult to change out the encryption routine at runtime.  Doing so means creating a new object and copying the contents of the old object to it.

Another difficulty is the distortion of otherwise clean class hierarchies.  Each child should have an "is-a" relationship with its parent.  Is a music file and AESEncryptionBase?  No.  Here is a particularly telling examples from Smalltalk.  In Squeak (the dominant open-source Smalltalk implementation), Semaphore inherits from LinkedList.  Is Semaphore a linked list?  No.  A linked list is used in the implementation, but a sempahore is not a specialization of linked lists.

A better approach is to contain the new functionality via composition.  A class should contain instances of objects it needs to utilize functionality from.  In the music file case, it would have a pointer to an EncryptionImpl class which might be AES, DES, or ROT13.  The class hierarchy will stay smaller and the music file implementation does not even need to be aware of which encryption method it is using.  In the Semaphore case, Semaphore would contain a LinkedList object which it would use to do the work.  Clients of Semaphore would not be expecting LinkedList functionality.  Extraneous methods would not need to be disabled.  Composition would also allow for more flexibility later.  If an implementation based on a heap or a prioritized queue were found to be advantageous, they could be without clients of Semaphore knowing. 

Think twice before inheriting functionality.  There are times when it is a good idea such as when there is a logical default behavior and only some child classes need to over-ride it, but if the intent is to utilize the functionality rather than expose it to child class callers, composition is almost always the right decision.

Posted by SteveRowe | 2 Comments
Filed under:

A History of Filesystems

Ars Technica has a very interesting article about the history of filesystems.  They cover all the major systems including FAT (MS-DOS), HFS (Mac), NTFS (NT), Ext2/3 (Linux), and many others like the Amiga.  They also cover upcoming systems like ZFS.  If you have interest in the systems space, check it out.

Posted by SteveRowe | 0 Comments
Filed under:

Know That Which You Test

Someone recently related to me his experience using the new Microsoft Robotics Studio.  He loaded it up and proceeded through one of the tutorials.  To make sure he understood, he typed everything in instead of cutting and pasting the sample code.  After doing so, he compiled and ran the results.  It worked!  It did exactly what it was supposed to.  The only problem--he didn't understand anything he had typed.  He went through the process of typing in the lines of code, but didn't understand what they really meant.  Sometimes testers do the same thing.  It is easy to "test" something without actually understanding it.  Doing so is dangerous.  It lulls us into a false sense of security.  We think we've done a good job testing the product when in reality we've only scratched the surface.

Being a good tester requires understanding not just the language we're writing the tests in, but also what is going on under the covers.  Black-box testing can be useful, but without a sense of what is happening inside, testing can only be very naive.  Without breaking the surface, it is nearly impossible to understand what the equivalency classes are.  It is hard to find the corner cases or the places where errors are most likely to happen.  It's also very easy to miss a critical path because it wasn't apparent from the API.

There are three practices which help to remedy this.  First, program in the same language as whatever is being tested.  A person writing tests written in C# against a COM interface will have a hard time beginning to understand the infrastructure beneath the interface.  It can also be difficult to understand the frailties of a language different than the one being coded in.  Each language has different weaknesses.  Thinking about the weaknesses of C++ will blind a person to the weaknesses of Perl.  Second, use code coverage data to help guide testing.  Examining code coverage reports can help uncover places that have been missed.  If possible, measure coverage against each test case.  Validate that each new case adds to the coverage.  If it doesn't, the case is probably covering the same equivalency class as another test.  Third, and perhaps most importantly, become familiar with the code being testing.  Read the code.  Read the specs.  Talk to the developers. 

Posted by SteveRowe | 3 Comments
Filed under:

Slow blogging season

I apologize for the very light blogging of late.  I've been busy working on the project for my latest class at the University of Illinois.  CS classes really take a lot of time at the end of the semester.  At the beginning you just have reading, homework, and lectures.  At the end they pile a project on top of that.  Depending on the class, that can mean a lot of work.  This isn't the worst, but I'm adding code to a large codebase which means a lot of time spent understanding it and a little time coding.  It's a lot simpler to write a project from scratch than to add functionality to something large.  As I'm taking a 500-level OS class, we're modifying an OS (Windows CE 6.0) and thus the code base is pretty big. 

It's coming together and I hope to get back to blogging more soon.  I just took a Microsoft class for Senior SDETs and have a lot of interesting ideas to blog about...

Posted by SteveRowe | 0 Comments
Filed under:

Don't Blame the Compiler

It's been a busy week without much time to blog.  In the mean time, here's a good reminder.  It's Always Your Fault.  Jeff Atwood explains why it's always the wrong idea to blame your tools.  New programmers especially see something they don't understand and assume that the tools (compiler, OS, libraries, etc.) are at fault.  While this is sometimes indeed the case, it is so rare that it's not worth considering.  Even if you do see an issue in the compiler or OS, you are unlikely to be able to get it fixed so you'll have to understand the issue and work around it anyway.

Posted by SteveRowe | 0 Comments
Filed under:

Which Language To Learn Next?

Once you have mastered one programming language, it is a good idea to branch out and learn some others.  Each language is optimized for different things.  Knowing multiple will give you a larger set of tools one of which which may solve the problem at hand better than others.  Additionally, and more importantly, different classes of languages approach problems very differently.  Learning languages from other groups will expand your thinking even if you stick to one language for most of your programming tasks.  C++, Java, and C# are all from a similar language class.  Languages like Lisp or Smalltalk are not.  Learning those requires learning new ways of thinking.  Christopher Diggins from Dobbs Code Talk presents a list of languages he recommends learning and what to get from them.  If you are looking to expand your horizons, check it out.
Posted by SteveRowe | 1 Comments
Filed under:

Your Hard Drive Probably Isn't Running At Full Speed

Here's a little known fact that could speed up your life.  Most SATA hard drives in the market today ship in 1.5 Gb/s mode instead of the 3.0 Gb/s mode they are capable of.  I know for sure that Seagate and Maxtor both ship retail drives with jumpers set to the slower mode.  I can only assume that this is for compatibility reasons.  Unless you need the compatibility though, you can get some extra speed out of your drive by changing the jumpers.  Look on the drive or in the manual for which jumpers to change.  It usually inolves merely removing the jumper but check to be sure.

Posted by SteveRowe | 0 Comments
Filed under:

Ten Years Later...

It was ten years ago today that I joined Microsoft as a full time employee.  When I started we were just finishing Windows 98.  Microsoft was around 25,000 employees.  My first job was testing DVD playback in the operating system.  Since then I've reported to 5 managers, resided in 5 buildings, occupied 8 different offices, and shipped 6 operating systems.  I also had a hand in shipping several versions each of IE, Windows Media Player, and Windows Media Center.  Ten years later, something like 17 products under my belt, and I'm still having fun.  I guess I chose the right profession.
Posted by SteveRowe | 7 Comments
Filed under:

Audio Not Keeping Up With HD Video?

Here is an interesting read about how the audio in HD TV is not keeping up with the video.  People are buying 1080p TV sets.  The networks are paying more attention to the quality of their video, but they are not yet doing much with the audio.  Many movies recording in 5.1 are broadcast in 2 channels. 

The article posits that this will change in 2009 when everything goes digital.  I'm not sure I agree.  Most everything is practically digital today.  There are people watching SD with rabbit ears, but they're in the minority.  Most people get their TV via cable or satellite.  Even so, there's still a whole lot of SD content out there.  Will turning off the analog broadcast airwaves make the need for that SD content over cable go away?  Probably not.

This article also highlights the tension between audio engineers and those holding the purse strings.  How much do people actually care about better quality audio?  The failure of SACD and DVD-Audio along with the heavy adoption of MP3 even in its overcompressed form would seem to indicate not nearly as much as we audio types would hope.

http://production.broadcastnewsroom.com/articles/viewarticle.jsp?id=329804

 

Posted by SteveRowe | 0 Comments
Filed under: ,

Update on Windows Home Server Corruption Issue

The WHS team has an update on their blog regarding the corruption issue.  In short, they fully understand the issue and are working on a fix.  The issue is at a low level of the operating system and so requires a lot of testing to be sure that the fix works and that it doesn't break anything else.  The ETA for a fix is June 2008.

 

Update is here.

Posted by SteveRowe | 0 Comments
Filed under:

Four Years and 300 Posts Later

It was four years and approximately 300 posts ago that I began this blog with a simple hello world.  Thanks to everyone who has taken the time to followed me during that time.  It has been an honor to write for you and to receive feedback on my ideas.

Now back to our regularly scheduled programming...

Posted by SteveRowe | 0 Comments
Filed under:

Suggestions for Smoother Meetings

A few weeks ago I attended a training and had an opportunity to try out the ideas generated from my earlier training.  As part of this most recent training we had an exercise where we were divided into two groups.  One group represented the technical team for a company.  The other group represented the marketing team.  We were presented with a series of possibly projects for the company to work on and asked to come up with a unified, prioritized list. 

Time Boxing.  We began by working as separate teams.  I was on the technical team.  One of the things we did early was to turn our work into a time-boxed activity.  We would take 1 1/2 hours before meeting with the marketing team.  After that, we would take 1 hour to merge the lists and 1/2 hour to write up the results.  Within our 90 minute time block, we set aside 1 hour to brief each other on our respective projects and 1/2 hour to actually rank them.  Setting up time boxes before the meeting began helped us not just to stay on track, but kept us on topic.  If the conversation started wandering afield, someone would just note the time and we would quickly wrap up that part of the conversation and get back to the central task.

It can be tempting to just dive into a meeting, but if the topic is contentious or open-ended, setting up boundaries beforehand can be essential to a successful outcome.  Having time bounds forces people to prioritize their actions and items that are interesting but not terribly relevant will be reduced.  People will self-select the most important parts of the conversation.

Search for Consensus.  When we merged with the other team, our lists looked quite different.  Our #1 item was their #2 but their #2 was our #5 (out of 6).  Other items were a little jumbled up.  The teams immediately started hashing out which was the most important for #1.  This argumentation would then carry down the list as we discussed each relative position.  I took a moment to look at the lists.  Upon deeper investigation, the lists weren't too far apart.  After their #2, we were within 1 position of each other on most items.  Thinking back to our internal discussions, we had decided on a decision framework to pick 1 long-term and 1 short-term item to be at the top of the list.  They had 2 long-term items at the top.  I inserted myself into the conversation and explained our decision framework.  Could they agree to such a framework?  They could.  With that agreed upon, we could focus our efforts arguing which long-term project to go after, but the loser would then fall to the bottom of the list.  We would be spared bubbling it all the way down the list.  This helped us get to total consensus on the list in less than the allotted hour.  Looking for consensus points rather than disagreement helped frame the conversation differently and removed much of the contention.

I've seen a similar technique used in stack-rank meetings.  At Microsoft come review time, we put the whole team into a ranked top-to-bottom list.  Sometimes there are ties in the middle but most of the time it's a complete list of the team from most valuable to least valuable for whatever criteria we decide on (future value, current contributions, etc).  What I have found to be very successful is to ask each manager to come prepared with his/her list already in a stacked order.  Then the meeting can focus on merging the lists.  The pre-created lists reduce the contention considerably.  Rather than having to argue each person's merits individually, it is possible to argue only key points.  If we have two lists:

List 1 List 2
Person A Person E
Person B Person F
Person C Person G
Person D Person H

and we can agree that person B is better than person E, we don't have to discuss person A.  If we can then agree that G is better than C, we only have to decide on the C,D,H merge.  We don't need to argue that F is better than C because that comes by default when G is better than C.

The same techniques can be applied to many other areas.  Look for points of agreement and focus on those rather than on points of disagreement.  This will narrow down the places where disagreement exists and thus narrow the bounds for argument.  It will still be important to hammer out agreement on the contentious issues, but if the arguments can be focused on only a few points of contention, a better decision will be made and it will take less time to get there.

Posted by SteveRowe | 0 Comments
Filed under:

Hello World Podcast

MacBreak Tech has a recent podcast talking about learning to program.  They begin with the question "how do I start programming games" and break it down.

  1. Pick a project.  Don't learn for learning's sake.  Learn to accomplish something.  It will give you a structure to hang your learning on.
  2. Pick a language.  They suggest Python, Basic, and Flash.  Those aren't bad places to start.
  3. Book or class?  Think about your learning style.  Classes force the pace.  Books are often better than reference material.  They make a cohesive whole out of all the parts.
  4. Borrow code.  Think about starting by modifying something someone else has already done.

Of course, the podcast is a little Mac-centric.  They don't mention Visual Basic or C#, but most of the content is applicable to any language.  If you have an MP3 player and are wondering where to start, try this podcast.

 

Posted by SteveRowe | 1 Comments
More Posts Next page »
 
Page view tracker