Finding Product/Market Fit

by breeve 25. February 2010 16:49

Behind the sounds of keyboards clanging out lines of code and second hand Aeron chairs brushing against the floor lies the passion of a dedicated few bringing to market a product they believe customers will actually give them money for. Like a bird working feverishly to build its nest, they dig for ideas and scavenge for employees while carefully constructing their business plan. If they execute well and build the product they envision the market will reward them because the path is laid before them and all it takes is enough determination to navigate it.

Unfortunately, the path can fork and the very skills that entrepreneurs must have like self confidence and egotism can make it hard to recognize forks. Many get so emotionally invested in their idea that when sales fail to materialize they rationalize it away by thinking the next feature or sales pitch will make the difference. Their mind can become so clouded that they come to expect the market to care about their shiny new product as much as they do. In reality, the market is not interested in shiny objects but rather in how those shiny things solve their problems. Much to the dismay of the entrepreneur, the market’s needs could be down the dodgy path, the one that nobody likes to walk down because it is covered with mud, weeds, and crabgrass.

Of all the ingredients that make a product a success, none are more vital than matching a product to what the market wants. Few have observed this process with more first hand experience than Eric Ries who was involved with a business which failed badly—blowing through 40 million in five years—and a later one which he started that was very successful. The failed first experience encouraged him to try something new with the second. A process he calls the Lean Startup.

The unintuitive first step of the lean process is to start with the assumption that you don’t know what the market wants but you are willing to learn. In order to learn what the market wants, you start with a small hypothesis of what you think it may want and then create what he calls the minimal viable product. The minimal viable product should be created with as little effort as possible and he goes so far as to suggest that it is commonly overridden with bugs. If that weren’t enough, he mandates you charge for it as well.

When I first heard the concept of a minimal viable product, I felt violated as a software engineer because a software engineer creates well designed low bug products not quick and dirty buggy ones. The thought of releasing something to the public that is buggy and worse expected to be buggy is nothing short of shameful. How could any self respecting engineer even consider shipping a buggy thing that will bring embarrassment to themselves?

What most engineers fail to understand, however, is the more time you put into a product without showing it to the market—what is commonly called stealth mode—the harder it is to change direction. Code that has lots of time, money, and reputation invested in it is hard to throw away and is often the source of emotional attachment which can ultimately drive a product into the depths of failure. This is precisely what happened in Eric’s first startup experience.

The real strength then of the minimal viable product is not just low emotional attachment but the ability to rapidly try different products ideas by releasing, getting feedback, and repeating until the market clearly signals what they want. The ability to change directions quickly and keep the burn rate low before a product/market fit is found is essential to the process of founding a successful business.

But how can one know when a product/market fit is found? No one has a better acid test for this problem than Sean Ellis. His method is shockingly simple. Survey the customers with one simple important question: if the product was discontinued would you be severely disappointed?

According to Sean’s experience with various startups, if 40% or more of the users say they would be severely disappointed if the product went away, the product has a fit and thus a market. So vital is the number that even Sean himself thinks twice about working with a company with a number less than 40% because the fate of the startup is still in question. Marketing a product is hard enough but marketing a product that no one wants is a losing situation anyone with smarts will thankfully leave to others.

Tags:

Essays

Windbg and SOS for Visual Studio .NET Weenies

by breeve 10. February 2010 16:07

I first realized I was a Visual Studio weenie when I showed up to a Mono conference in Spain with a Windows laptop in a sea of Linux ones. I was so outnumbered I entertained the idea of not booting the Windows laptop at all because having the familiar Windows boot tone echoing off the conference walls would undoubtedly gather unwanted attention. Eventually, I calmed down and even managed to boot my Windows machine without too many stares.

One of the talks at the Mono conference—Mono is an open source implementation of .NET for Linux based machines—was about the progress on the Mono .NET debugger. Mono had released without a debugger initially and the debugger quickly become the #1 requested feature, no doubt mostly from .NET Windows users looking to port their .NET apps to Linux. The debugger being worked on, the presenter informed us, would not just be a command line debugger like GDB but would be fully integrated into MonoDevelop—the Linux equivalent of a Visual Studio—so that breakpoints could be set next to the source code. He even had a cute demo that worked. This is nice, I thought. After all, who needs a complicated command line debugger that takes years to learn. I needed to get things done.

During the many breaks we had between presentations, I was able to sit next to a few of the Mono developers and watch them code. They were very efficient with GDB and VI—the command line debugger and editor of choice for any self respecting Linux hacker. Still I figured, I was just as productive in Visual Studio.

And for the most part I am, except for nasty programming realities like memory leaks. For those, Visual Studio was at a loss and I was too until I discovered Windbg, the command line debugger for Windows, and its extension SOS. After learning a handful of commands, I was impressed in how quickly I was able to track down the source of leaks that had eluded fellow Visual Studio zealots. Maybe those Mono guys were on to something. After all, nothing says I am a debugger extraordinaire quicker than opening up Windbg and pounding out a few commands in front of your fellow programmers.

Below is a few commands and a tutorial on tracking down a leak in an example program.

!dumpheap -stat            Displays every managed type on the heap

!dumpheap -type typename   Displays every managed type that matches the specified type

!dumpheap -mt methodtable  Displays every instance of the specified method table

!gcroot address            Shows reference chain

!dumpobj address           Shows fields and addresses of references

!dumparray address         Shows objects in an array

!dumpmd                    Dumps the method description

!u                         Show assembly code

g                          Continue, let the program run

Ctrl+Break                 Break into the Windbg debugger

!help [command]            Show help

The .NET Windows Forms example program I wrote draws circles on a form. The circles are placed in random locations and move from top to bottom until they vanish. There are 500 circles on the form at any time. The program works well except it leaks memory like the Titanic. It went from 10MB to 20MB in 30 seconds and climbs into the hundreds of megs if left to run.

The code is below. See if you can spot the issue before we run Windbg.

public partial class Form1 : Form
{
    private const int NumberOfCircles = 500;
    private Timer _timer;

    public event EventHandler<DrawCircleEventArgs> Draw;

    public Form1()
    {
        InitializeComponent();

        _timer = new Timer();
        _timer.Interval = 100;
        _timer.Start();
        _timer.Tick += new EventHandler(OnTick);
        InitCircles();
    }

    private void InitCircles()
    {
        for (int x = 0; x < NumberOfCircles; x++)
            AddCircle();
    }

    private void AddCircle()
    {
        Circle circle = new Circle(new Rectangle(0, 0, Width, Height));
        circle.Done += new EventHandler(OnDone);
        Draw += new EventHandler<DrawCircleEventArgs>(circle.Draw);
    }

    private void OnTick(object sender, EventArgs e)
    {
        Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (Draw != null)
            Draw(this, new DrawCircleEventArgs(e.Graphics));
    }

    private void OnDone(object sender, EventArgs e)
    {
        AddCircle();
    }
}

public class Circle
{
    private static Random Rand;

    private Rectangle _parentBounds;
    private Point _position;
    private Size _circleSize;
    private byte[] _bytes;
    private bool _done;
    public event EventHandler Done;

    static Circle()
    {
        Rand = new Random((int)DateTime.Now.Ticks);
    }

    public Circle(Rectangle parentBounds)
    {
        _bytes = new byte[10240]; //10K for no reason but to make object bigger
        _done = false;
        _parentBounds = parentBounds;
        int xPosition = Rand.Next(parentBounds.Left, parentBounds.Right);
        int yPosition = Rand.Next(parentBounds.Top, parentBounds.Bottom);
        _position = new Point(xPosition, yPosition);
        _circleSize = new Size(10, 10);
    }

    private void OnDone()
    {
        _done = true;
        if (Done != null)
            Done(this, EventArgs.Empty);
    }

    public void Draw(object sender, DrawCircleEventArgs args)
    {
        _position = new Point(_position.X, _position.Y + 1);
        Rectangle rect = new Rectangle(_position, _circleSize);

        if (!_parentBounds.Contains(rect) && !_done)
            OnDone();
        else
            args.Graphics.DrawEllipse(Pens.Green, rect);
    }
}

To find the leak, I will open Windbg and attach to the program using File>>Attach to Process. If you don’t have Windbg, download the debugging tools for windows here. Next, load SOS like:

.loadby sos mscorwks

With SOS loaded, I can run commands from above like:

!dumpheap -stat

658551a8      163         3912 System.Windows.Forms.InvalidateEventArgs
641b8c4c       95         5320 System.Configuration.FactoryRecord
6585394c       78         5616 System.Windows.Forms.Internal.DeviceContext
6a72a930      190         6840 System.Collections.Hashtable+HashtableEnumerator
6a73303c       28         7608 System.Collections.Hashtable+bucket[]
6a7308ec      812        61060 System.String
6a7040bc      153        63636 System.Object[]
6a729b58     4804       153728 System.EventHandler
00126ba8     4847       155104 System.EventHandler`1[[Leaky.DrawCircleEventArgs, Leaky]]
00126ac4     4725       245700 Leaky.Circle
0032c6b0     1754       279984      Free
6a73335c     4729     48451204 System.Byte[]

This shows all types on the heap, number of instances, and the sizes with the largest on the bottom. I can see the byte arrays are taking 48 Megs and Leaky.Circle is 245k. The large byte arrays are a field of the Circle class designed to show the leak easier. What is more interesting is there are 4725 instances of the circle class. I was expecting only around 500 because as the circles go outside the form they should be garbage collected. So what is causing these Circle instances to stay in memory? I dump the method table listed for the Circle like:

!dumpheap -mt 00126ac4

071deb54 00126ac4       52    
071e13f4 00126ac4       52    
071e40fc 00126ac4       52    
071e699c 00126ac4       52    
071e923c 00126ac4       52    
071ebadc 00126ac4       52    
071ee37c 00126ac4       52

This shows all the instances of that method table on the heap. I can now use !gcroot on one of the addresses like:

!gcroot 071e13f4

ebx:Root:01c842b4(System.Windows.Forms.Application+ThreadContext)->
01c83878(Leaky.Form1)->
071f0bfc(System.EventHandler`1[[Leaky.DrawCircleEventArgs, Leaky]])->
064c5b38(System.Object[])->
071e3c54(System.EventHandler`1[[Leaky.DrawCircleEventArgs, Leaky]])->
071e13f4(Leaky.Circle)

This Circle instance is being held by an event handler which is being tracked back to the form itself. Let’s examine why the event handler above is holding onto the Circle instance by using the dump object command.

!dumpobj 071e3c54

Name: System.EventHandler`1[[Leaky.DrawCircleEventArgs, Leaky]]
MethodTable: 00126ba8
EEClass: 6a4c3518
Size: 32(0x20) bytes
 (C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
6a730508  40000ff        4        System.Object  0 instance 071e13f4 _target
6a72fd60  4000100        8 ...ection.MethodBase  0 instance 00000000 _methodBase
6a7331b4  4000101        c        System.IntPtr  1 instance   12c118 _methodPtr
6a7331b4  4000102       10        System.IntPtr  1 instance        0 _methodPtrAux
6a730508  400010c       14        System.Object  0 instance 00000000 _invocationList
6a7331b4  400010d       18        System.IntPtr  1 instance        0 _invocationCount

Finding the method this event handler is pointing to is a bit tricky. First, we dump the raw memory for the _methodPtr field

dd 12c118

0012c118  1c4653e9 00005f00 00126aac 00000000
0012c128  00000000 00000000 00000000 00000000
0012c138  00000000 00000000 00000000 00000000
0012c148  00000000 00000000 00000000 00000000
0012c158  00000000 00000000 00000000 00000000
0012c168  00000000 00000000 00000000 00000000
0012c178  00000000 00000000 00000000 00000000
0012c188  00000000 00000000 00000000 00000000

Then we dump the method description who’s address is located on the first line fourth column

!dumpmd 00126aac

Method Name: Leaky.Circle.Draw(System.Object, Leaky.DrawCircleEventArgs)
Class: 008f0b28
MethodTable: 00126ac4
mdToken: 06000014
Module: 00122c5c
IsJitted: yes
CodeAddr: 002f0770

The event handler is pointing to the Draw method on the Circle and keeping it in memory. I must not be unhooking the event. Looking at the source code, it becomes apparent that I am not unhooking that method anywhere in the code. The proper place to do it would be in the OnDone method of the Form1 class.

private void OnDone(object sender, EventArgs e)
{
    Circle circle = sender as Circle;
    Draw -= new EventHandler<DrawCircleEventArgs>(circle.Draw);
    AddCircle();
}

Now if I run the same test as before and dump the heap I get:

!dumpheap -stat

6a72b16c      245         5880 System.Collections.Stack
6a73303c       28         7608 System.Collections.Hashtable+bucket[]
6585394c      245        17640 System.Windows.Forms.Internal.DeviceContext
6a729b58     1193        38176 System.EventHandler
00146ba8     1230        39360 System.EventHandler`1[[Leaky.DrawCircleEventArgs, Leaky]]
6a7308ec      755        59232 System.String
00146ac4     1176        61152 Leaky.Circle
6a7040bc      315        95188 System.Object[]
0035c6b0      918      1738620      Free
6a73335c     1180     12066856 System.Byte[]

Notice there is a smaller number of circles and byte arrays and when I run for a long time the memory doesn’t go over 30 megs. There are 1176 circles but most of those are waiting to be collected. This may seem like a contrived example but from my experience it is all too real. Most memory leaks I have found in code bases are because of event handlers not being unhooked.

Tags:

Software

The Dreaded Switch Statement

by breeve 27. January 2010 15:21

One of the quickest ways to bring a delightful code review to a halt is to slip in a big switch statement somewhere in the code. Upon encountering it, some will feel uncomfortable and not know why while others will give you a long soul piercing stare.

Switch statements get a bad rap for a number of reasons. The chief among them being when a value is added to an enum you have to track down every switch statement that is using that enum and add your new code. This may seem simple but most of the time there is more than one switch statement to contend with. Often the changes needed are in unfamiliar code which leads to a long and error prone process.

There are alternatives thanks to object oriented programming and polymorphism. To understand such an approach, the C# code below shows a scenario with a switch statement. The class Rect takes an enum FillStyle as a property. In the Draw method it creates different brushes—depending on the FillStyle property—using a switch statement. Code like this is very common.

public enum FillStyle
{
    Solid,
    Gradient
}

public class Rect
{
    private Point _location;
    private Size _size;

    public Rect(Point location, Size size)
    {
        _location = location;
        _size = size;
        FillStyle = FillStyle.Solid;
        FillColor = Color.Green;
    }

    public FillStyle FillStyle { get; set; }
    public Color FillColor { get; set; }

    public void Draw(Graphics graphics)
    {
        Brush brush = null;
        Rectangle bounds = new Rectangle(_location, _size);
        switch (FillStyle)
        {
            case FillStyle.Solid:
                brush = new SolidBrush(FillColor);
                break;
            case FillStyle.Gradient:
                brush = new LinearGradientBrush(bounds, FillColor, Color.Red, LinearGradientMode.Horizontal);
                break;
            default:
                Debug.Fail("Not a valid FillStyle");
                break;
        }

        using (brush)
        {
            graphics.FillRectangle(brush, bounds);
        }
    }
}

An alternate and better approach is to use an abstract class with public static concrete instances. The primary motivation for this is the abstract class can masquerade as an easy to use enum. This way the code the API user has to write is exactly the same as before and most importantly just as simple. In fact, most users, will never notice they are working with an abstract class with singleton instances; to them it just looks like an enum.

In our case, an abstract FillStyle class is created with two public singleton instances that have the same names as our original enum values above. The FillStyle class has one abstract method called CreateBrush. Reworking the above example looks like the code below.

public abstract class FillStyle
{
    public static readonly FillStyle Solid = new SolidImpl();
    public static readonly FillStyle Gradient = new GradientImpl();

    protected FillStyle()
    {
    }

    public abstract Brush CreateBrush(Color color, Rectangle bounds);

    private class SolidImpl : FillStyle
    {
        public override Brush CreateBrush(Color color, Rectangle bounds)
        {
            return new SolidBrush(color);
        }
    }

    private class GradientImpl : FillStyle
    {
        public override Brush CreateBrush(Color color, Rectangle bounds)
        {
            return new LinearGradientBrush(bounds, color, Color.Red, LinearGradientMode.Horizontal);
        }
    }
}

public class Rect
{
    private Point _location;
    private Size _size;

    public Rect(Point location, Size size)
    {
        _location = location;
        _size = size;
        FillStyle = FillStyle.Solid;
        FillColor = Color.Green;
    }

    public FillStyle FillStyle { get; set; }
    public Color FillColor { get; set; }

    public void Draw(Graphics graphics)
    {
        Rectangle bounds = new Rectangle(_location, _size);

        using (Brush brush = FillStyle.CreateBrush(FillColor, bounds))
        {
            graphics.FillRectangle(brush, bounds);
        }
    }
}

The first thing you will notice is the Draw method on the Rect class is simple and adding new values to the FillStyle class has become substantially easier than the former traditional enum example because the code can be added in one central place. Gone is the frustrating experience of updating every switch statement in the entire code base. The introduced abstraction adds to the extensibility of the design. If a user wants to add a custom FillStyle—not originally anticipated by the API authors—they can by inheriting from FillStyle and overriding CreateBrush in the same way.

Tags:

Software

HOA Forum Software Developed

by breeve 15. January 2010 16:25

Over the last months in my spare time, I developed a web based HOA (Home Owners Association) forum tailored to HOA organizations. I have posted all the code—above the screenshot—with instructions on how to get the software up and running should you care to run or modify it. You can do whatever you want with the software—it is now open source software.

The project started as a desire to play with ASP.NET MVC, LINQ to SQL, and jQuery. As the functionality increased, I tried my hand at pitching it to different neighborhoods. No interest. Not even for free. Most already had forums running like phpBB. I would be lying if I didn’t admit that part of my motivation was to develop a better looking forum than phpBB and hopefully banish it from all existence in the HOA space. Nathan Philpot helped with design work to make it look great but even that didn’t help as HOA organizations seemed just fine running their existing forums. The switching costs were just too much.

In reality, switching costs where just one reason it wasn’t adopted. HOA organizations, I found out, have very different ideas of what they want forcing the market into fragmentation. In fact, many build their own solutions in house.

Features Include:

  • Posted topics can be voted on which allows popular issues to rise to the top.
  • Each topic can show a voting history graph
  • Search topics
  • Each user has a page that lists:
    • Their posted topics and replies
    • Their reputation (gained by others voting on their topics or replies)
  • Topics can be flagged as spam or inappropriate by anyone, allowing an administrator to delete off color topics.
  • Posted topics are sorted by 4 main tabs
    • Recent - topics listed by date
    • Popular - topics listed by votes
    • Hot - topics listed by recent activity
    • No Replies - topics with no replies
  • When HOA members post, a special HOA icon is displayed notifying readers of a more official response
  • The HOA corner area on the right allows HOA members to post ideas, status, or announcements
  • RSS / Email updates

Hoa.zip

Tags:

Software

Developer Decision Space

by breeve 31. December 2009 11:14

Software Developers build things. Not physical things that people can admire from afar but rather invisible instructions that travel along wires as pulses of electrons. These instructional bursts can move data around from one place to another, add subtract multiply and divide numbers, and even draw complicated objects on the screen. A computer is like a piano; by itself it just sits there. It takes someone with enough persistence to sit and learn the thing to make it do something.

Persistence is a rare quality but one that is sorely needed when programming a computer. After all, programmers must painstakingly assemble instruction after instruction. Never was this more true than in the old days when programmers had to think in terms of ones and zeros. 10010101 could mean store a number, for example, while 10111010 might mean add two numbers. Programming this way was the only way to get things done and it drove many to the point of insanity. It is the equivalent of building a house by molding your own nails and milling your own two by fours. In other words, it took a lot of grunt work to get anything useful done.

Programmers understood this and in time became determined to make programming more time efficient by introducing what they like to call abstractions. Abstractions increase productivity by abstracting away the details of how something works. For example, compilers were introduced that would take high level languages like the C programming language and compile it into ones and zeros that the CPU understood. Now you could program with nails and two by fours already cut which was a fantastic performance boost.

Taking the idea of abstractions further, libraries were developed. A library consists of many routines—commonly called functions—that a programmer can call to get something done. Want to draw a circle on the screen or do a FFT; chances are some other programmer already created a library to do that and all you really have to do is call it with the right parameters. Forget about ones and zeros, programming became a task of calling a bunch of libraries.

Today there are hundreds of programming languages in addition to C and many more libraries that do everything from request a web page to move a robot some determined distance forward. Programming these days has become a game of how well you know a given set of libraries—typically called frameworks—and what programming languages you know to call those libraries. It’s a world of abstraction upon abstraction designed to make life better.

Before you get the idea that programming today is easy because there are all these cushy libraries to call and high level languages to do your every bidding, think again. Although things are generally easier, the shear amount of frameworks available makes it very hard to know what is going on under the hood. Most of the time you don’t care and frankly don‘t have to. However, every so often you will undoubtedly encounter a library that is not doing what you would expect. A kind of bad behaving library if you will. This is were the trouble usually starts.

During these times, the questions come flooding into your mind. What is causing the issue? Are you calling it correctly? Does it just not work? Should you try to use something else? A road block has presented itself in the otherwise smooth journey of programming bliss and you must get around it and continue on the journey. Spend any time next to a group of developers deeply concentrated in coding work, and it will become painfully clear that navigating road blocks happen on a daily basis. The clues come in the form of expressions like: “That doesn’t make any sense” or “What were they thinking” to more colorful expressions of the four letter kind.

Call it what you want but road blocks are a fact of life and developers have a similar set of terms for there solutions. Some issues will often have a well know solution called a “workaround”. A workaround is like an official response from the library creator in effect saying we screwed up and this is how you get around the issue. If the problem is less known it becomes the task of the developer to creatively implement a way around the problem in what may, depending on the degree of elegance, be referred to as a “kludge”—a kind of less elegant quick and dirty solution. Regardless of how the issue is solved, in the end the developer must make a choice. Economics have a term for this called opportunity cost. By choosing one thing you forgo the potential benefit of choosing the other.

What makes this so fascinating is after lots of workarounds or kludges you could look back at the web of decisions made and wonder if you made the most optimal path. The shear amount of paths through the web of choices is what I call the developer decision space. Two programmers may achieve the same result through different paths but one will be more efficient. The new game becomes navigate through all the pitfalls and landmines with the most optimal path possible.

To get a feel for how this plays out, I have a recent example. For work, I have been tasked with trying to get some of my code to run on the new Microsoft framework called Azure. Azure is a cloud platform that allows you to host your code on Microsoft servers rather than buying your own.

Everything was going smoothly until I hit an issue with uploading my app to the cloud. Staying as light as possible on the technical jargon, I had some loose .NET assemblies in a folder under the root application that were not getting included into the Azure package.

My first attempt to resolve the issue fell into the kludge category. I had found out about a way to create the Azure package unencrypted that would allow me to manually put my assemblies there. This turned out to not work as I received an error when uploading it to the Azure cloud—I contributed this to some check sum they must have in the Azure package. With this part of the decision space blocked, I focused my attention on other ideas. I decided to included the assemblies into the ASP.NET project which solved the issue but caused a new problem—my included assemblies were Silverlight ones and ASP.NET was trying to load them on startup. That forced me to try a different idea of copying the assemblies into the Azure local storage on startup which ultimately worked.

I shared this experience not to show that I am some technical genius who solved a problem but rather to illustrate the complex interplays of the decision space because an interesting thing happened when I uploaded my final solution to the Azure cloud. I got an error; an eerily familiar error about an invalid package similar to the error I received when uploading my first attempt with the unencrypted package. It turns out the reason for the error is a bug in Azure where you have to delete your entire Azure project and re-add it rather that upgrading it. After I did that my final solution worked but I couldn’t shake the feeling that I had missed the most optimal path.

The pestering feeling was the result of discovering new information that I didn’t posses at the time of my first failed attempt. It wasn’t until I was down other paths, trying new things, that this new information came to light which had the potential to open up other paths that I had previously closed.

In my case, I wondered if the error I got on the unencrypted package, my first attempt, was related to the bug in Azure that I discovered later and not a checksum thing after all. If that was the case my first attempt, which was a couple of branches higher in the decision space, was most optimal.

This is what makes programming more of an art than a dull mindless practice most chalk it up to be. It requires the ability to make seemingly unconnected insights and connect them. It is like solving some kind of big puzzle with limited information. As you start to solve the puzzle you learn more and that new information has the potential to unlock a number of issues you thought were previously hopeless.

I am convinced the great programmers have a heightened ability to see these connections. Not only a couple of layers above, like mere mortals, but through most of the decision space. This is even more remarkable when you consider that each decision has an opportunity cost and keeping track of all those decisions that effect other decisions is hard if not close to impossible. But the better these can be tracked mentally the greater the potential breakthrough insight; like Niels Bohr unlocking the secrets of the atom that others failed to see.

Unfortunately, there are only so many Niels Bohrs in the world. However, I believe more developers should put greater effort into understanding the developer decision space. Too often developers make their way through the space by making a decision then immediately relieving their tired brains of the circumstances and implications that justified that decision and move on to the next one. Continuing this pattern a couple more times and it becomes blatantly clear that they have no hope of applying new insights to old decisions and breakthroughs will never happen. Instead what commonly happens is they find themselves wondering in strange roads and thinking to themselves: How did I get here?

I don’t know if this is from pure laziness or simple unawareness. Software development experience tends to help some because after a couple of times traveling strange roads one starts to remember how they got there so they can find their way out. But experience alone doesn’t mean the skill will automatically develop since some experienced developers don’t seem to possess it. If it is unawareness, consider yourself informed. If it is laziness, then you probably haven’t made if this far in the article anyways.

Tags:

Essays

Eight Foot High Corn Field

by breeve 14. December 2009 16:42

During my later college years in Utah, each year around Halloween people became enamored with corn mazes. The most popular time to go was at night and during one of those nights I found myself staring at a dark corn field entrance illuminated by flood lights.

To the scientific thinker a corn maze can be an incredibly frustrating experience. One must navigate through endless corridors to somehow arrive at the one opening on the far end. I didn’t have any strategy in mind–after all my wife told me this was supposed to be fun–so I went with the flow.

After some time in the maze, I was hopelessly lost and not having much fun. I was seeing the same people over and over again. I remembered hearing my dad say once that when lost in a maze just put your hand on a wall and follow it until you eventually arrive at the end. I followed that strategy for a time–not really thinking it through in my head to verify if it really works–until I got bored and did what every corn maze zealot would shrink with disdain at: I walked through the walls until I was outside the maze and made my way to the entrance lights.

Some years later I found myself in my first programming gig writing graphs, meters and knob components for scientific applications in .NET/C# and Windows Forms. My first assignment was to develop a program to benchmark how fast an early prototyped .NET graph would run. I took the assignment in stride–not knowing much about the .NET framework–and implemented an application that worked. My boss on the UI team, to which I belonged, sat down and had a code review with me. It was my first official code review and it didn‘t go well.

I was crushed. However, as the code review went on I began to see where I could improve. After all, I had never developed a professional application before and had honestly never seriously studied one. Most of my projects in school were little in scope designed to prove I knew how to create a linked list, code a quick sort, or create Huffman code trees. They were not designed to be extended or maintained by someone down the road.

In the months that followed, I worked double hard to prove I belonged. I studied the code base and learned all kinds of code patterns I didn’t know existed. Visitor, Observer, and other patterns–that oddly were never mentioned in school–that I would later read about in the famous Design Patterns book. Over time my code got better.

Which brings me back to the corn maze. Like someone navigating a corn maze, when you are starting out as a programmer you tend to make decisions one at a time without any greater context to guide you. Function A throws an exception so that means it must not work so use Function B instead. These decisions are made one by one, in isolation, until a program is assembled into some kind of greater whole that runs. A more senior programmer–who hopefully has the ability to look at the maze from high above–might wonder why you took the long route or worse never arrived at the finish.

If the goal is to become a more effective programmer by seeing the maze from above, how does one get there? Before we explore that goal, we should become comfortable with a sometimes not understood secret in the programming field. Not everyone with experience can see the corn maze from above. Some, try as they might, can never seem to get their heads above the corn. Others find they can get their heads a few feet above the maze which delights them to no end. Fewer still are able to successfully position themselves effectively over the maze.

To reach the programming pinnacle of understanding above the maze, you must position yourself in a work environment with others who are able to at least get a glimpse into the maze. Learn how they think, how they code, and why they make the decisions they do. As you progress in your career it will become vital to learn from those who possess greater powers of levitation. Finding these types are hard, but once you find one–like finding traces of gold–the chances of finding other high performers is high. Good programmers like to work with other good programmers and its in these pockets of intellect where you will make the greatest strides.

Tags:

Essays

The #1 Debugging Lesson

by breeve 2. December 2009 15:45

If you ever find yourself driving along US 20 just Northeast of Idaho Falls, Idaho be sure to look to the South at the small rolling hills because if you look closely, you might be able to pick out some small brown buildings huddled together amidst all the potato farms. It was in those buildings, early into my CS degree, where I learned my first valuable lesson in debugging.

I was sitting in the small Computer Science lab agonizing over a CGI Perl script. I had a problem. My variable was losing its value and I had no idea why. I would print out the value and then print it out again and the value was lost. I checked the code between the printings and nothing was doing anything suspicious to the value. As the hours passed, I was falling deeper and deeper into frustration. I had a depressing thought: How could I possible succeed at this profession when my variables can’t keep their values.

Looking for ideas, I did what every self respecting programmer did before Google existed and looked for some human help. No one was in the lab so I sheepishly made my way over to the professor’s office which was conveniently located just off the computer lab. This, after all, was a small college where professors weren’t self absorbed in their own research and actually talked to students.

Luckily, he was there and willing to help. We pulled up my program—which was a very busy thing with lots of variables. I jumped in trying to explain things to gain credibility. He immediately began to pull out chucks of my program and put them into a new Perl program to run. Then we would verify the piece ran as it should. We continued to do this until the problem was discovered; my variable was misspelled ever so slightly. Perl, of course, is a dynamic language and had simply created a new variable instead of using the one I wanted.

I was embarrassed—especially considering the problem was discovered in under 5 minutes—but I learned a lesson. When something is not working and the program or function has lots of working parts you must simplify. Creating a new program from scratch and pulling over code to run eliminates all the noise from the surrounding code.

I have used this technique effectively countless times since. Still, I am surprised sometimes by professional programmers not using this technique when trouble shooting issues. They will toil with the whole beast of a program trying to fix the issue but it is hopeless because there is just too much noise. Simplify.

Tags:

Essays

Unit Tests vs. Integration Tests

by breeve 23. November 2009 15:32

Unit tests are all the rage today. Talk to anyone who has been reading the unit test literature and they will talk with such passion you might for a split second think you were sitting in a town hall health care meeting.

To understand the arguments for unit tests, we must first understand how code is typically tested. Code is usually tested by an integration test. Integration tests run against the entire stack of dependencies when testing your code. Integration tests are hard to set up because all dependencies must be installed correctly for the test to run. They are associated with long test times. This can be especially bad for continuous integration systems which are brought to their knees by running them on every check in. If a test fails, the bug might be in a dependency or in the component under test making it hard to tell where the issue really is.

Unit tests aim to fix these issues. A unit test is written to test one specific unit of code and differ from integration tests in one critical way; unit tests do not test dependant code. To eliminate the dependencies, they are mocked—often with mock frameworks—to return certain hard coded values to your code. Your code is tested to function properly given the mocked implementation of the dependencies. The tests run fast and if a test fails it is guaranteed to be in your code.

Let’s say I have a library that is responsible for storing data. It stores the data in the cloud by calling a web service. Unit test advocates want the web service dependency eliminated for testing purposes. To accomplish this, the web service dependency is made into an interface—or what is typically called a seam—allowing me to plug in a mock implementation. Something like:

public interface IStorage
{
    public void SaveAsync(string name, Stream stream, Action<Boolean> callback);

Now, I can mock up an implementation of the IStorage interface for my tests without having to go to the actual network. If the behavior of different parameter values into the function are well defined, I can write many unit tests for all combinations of input. Technically, with all combination of inputs covered, when the code goes into production with the real web service implementation it should just work.

This seems splendid. In reality, chances are the real web service has a bug in it because the author doesn’t believe in unit testing or the API behavior was not well defined because you thought passing a null name was ok but apparently it isn’t because the server barfed when it couldn’t find the name in the XML. This brings me to my first negative about unit tests.

Unit tests desperately depend on strong API contracts

There are two types of API contracts: compile time and runtime behavior. The first, compile time, is self explanatory. The second, runtime behavior, simply means the function has well defined behavior for certain values that are passed in. For example, if a function returns 0 for errors and then is changed to return negative numbers for errors it is a behavior change and will break code that uses it.

Behavior changes are devastating for unit tests. Remember, a mock simply mimics what the dependency is supposed to do. If behavior is changing in the dependencies, a unit test is essentially worthless until the mocks are updated with the changed behavior. Worse still, if communication is poor between API owners about behavior changes, out of date mocks can remain in unit tests creating false negatives (tests don’t fail when they should).

When false negatives exist in unit tests—hiding like an explosive IED alongside an Iraqi roadway—there might be 100% unit test coverage in your code but that won’t prevent your boss from hunting your butt down when your code doesn’t work with the product as a whole. Even the slightest behavior changes in an API can bring an entire product down.

Mocking up dependencies is not always trivial

It is possible to mock every external dependency to your component if you have a lot of time. Many components have not just one but many dependencies with large API footprints. To make matters worse, many external components are not easily mocked.

If developers simply apply a brute force approach to mock all dependencies and create wrappers for ones that aren’t easily mocked, weeks will go by without much to show. Meanwhile your boss is in his office looking at budget numbers scratching his head wondering how you are creating customer value.

Unit tests don’t catch funky issues

Because unit tests run against a fake implementation of the dependencies, real product integration issues are never found. I am talking about those hard core issues that everyone pretends don’t exist like having 10 concurrent threads running in God knows what through 15 different API layers implemented in 15 different programming languages.

So what’s a time deprived developer to do?

This is not an easy question to answer. For reasons stated above, even if you have extensive unit tests you will still need integration tests. I believe the balance between the two depends heavily on stability of dependant APIs and how well they are tested. Developing against unstable buggy APIs, cover your butt with integration tests. Stable well tested API’s like the .NET framework, unit test away.

Tags:

Essays

Programmatic Publish for an ASP.NET Project

by breeve 19. November 2009 16:07

I recently needed to automate an ASP.NET project build so that it copies itself to a directory. This is accomplished in Visual Studio 2008 by right clicking the ASP.NET project and selecting Publish. For ASP.NET projects, the Publish command copies all files needed for the site.

After searching some, I found this can be done by using msbuild. Below is my solution that copies all files needed to C:\Data\Projects\TestDeploy. It invokes msbuild to build the web application then uses an existing task called _CopyWebApplication to copy all the files over.

msbuild /t:Build;_CopyWebApplication /p:Configuration=Release
/p:OutDir=C:\Data\Projects\TestDeploy\bin\
/p:WebProjectOutputDir=C:\Data\Projects\TestDeploy
C:\src\Branches\HOA\HomeOwners.Mvc\HomeOwners.Mvc.csproj

Note that this solution does not precompile the site. To precompile, use aspnet_compiler.

Tags:

Software

Measure Twice Cut Once

by breeve 10. November 2009 16:40

Ever wonder what is going on behind the scenes when you install a Microsoft product and it asks: "Do you want to help make Microsoft products better?" I don’t check that option but apparently a lot of people do.

That checkbox allows Microsoft to gather user statistics on how you use the software. Everything from where you click to what features you use to what keys you press. The data is sent back to Microsoft in a user anonymous way and digested by the giant.

The data helps Microsoft learn how customers use the software.  In the brilliant presentation “The Story of the Ribbon” given during Microsoft’s MIX conference, we get a glimpse into how the data is used. During one part of the presentation, a slide displays all the features in Microsoft Word—collected by 3 billion user sessions—and ranked according to use. What they found is most people use only a small fraction of the features. In fact, a lot of features have been used only once and some not at all.

The most used features are what you might expect like copy, past, save, undo, bold, underline, and font size. What is shocking is how fast the feature use falls after those. Ever heard of the feature: “Change shape to lightning bolt”. This was clicked only once, undoubtedly, by some poor soul lost in the maze of menus.

Who is to blame for all these unused features ideas? The answer is not entirely clear as there seems to be some finger pointing. Program Managers typically have the role of proposing new features and in a field of work where a career gets a boost from a well thought out feature, the stakes are high. Unfortunately, most of the feature ideas are little more than gut instinct and turn out to be lemons.

Software engineers, whether they admit it or not, are not innocent bystanders. The thing with engineers is they are smart and they know it. They like to dream up scenarios in their heads all day about how a user is typing into Microsoft Word, somewhere in the world, and has an image that they want to copy into their document exactly 100 times and how frustrating that must be. So they purpose a copy image 100 times feature to their boss. Meeting after meeting ensues until everyone becomes convinced this is a huge usability issue. The feature is implemented and the software engineer gets a great deal of satisfaction knowing the nagging issue is put to rest.

Letting futile features slip into a product can lead to the real possibility of losing touch with customers’ needs. Adding to the fire, once a feature is implemented, the battle internally over the features usefulness is over. We just assume the feature is being used and adding value. So more features are added and added—engineers say recursively—until the program becomes so bloated with features that users don’t know how to use the program anymore and the engineers can’t make simple changes without breaking all the existing features so everyone is complaining and eventually the engineers want to rewrite the product from scratch because then it would be simpler like it was before all those features were added.

The ugly reality is almost all programs follow this lifecycle pattern. What makes the “Story of the Ribbon” presentation so fascinating is that Microsoft noticed this pattern with the Office products and took a step back to look at what features were actually being used by real live paying customers. This of course led to the famous ribbon interface by making heavily used features more prevalent and most importantly removing hardly used ones.

Tags:

Essays

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

About Me

I am a Software Engineer with 8 years experience developing and releasing software products. I started developing in C/C++ then moved into .NET and C# for the last 6 years and have tech lead multiple projects. I have developed products in Windows Forms, ASP.NET, Silverlight, and WPF. I currently reside in Austin, Texas.

Currently Reading