Archive for January 2003

 
 

Interviewing

Me: Please write a function that takes an array of ten integers and sorts it.

<he starts writing crap on the whiteboard and doesn’t get anywhere>

Him: I don’t have my algorithms book here; it’s in my car.

What I want to say is, I won’t hire you because you suck. But I don’t want to make the guy feel bad, so I lie:

“We, um, need someone that can be productive right now. Your knowledge seems a bit rusty so you would need at least six months to get up to speed. We don’t have that much time.”

He looks at me with this indignant expression and says: “Oh, that’s all right. I would never work for a company that doesn’t want to invest in me.”

Formula One Programming

If you are trying to improve your software development process, do some research into what Alfred Neubauer has done for Formula One racing.

Alfred NeubauerNeubauer was the head of the Mecedes-Benz racing team during the first half of the twentieth century. Mercedes had an on-and-off interest in professional racing until the 1930s, when Hitler declared that Germans need to win in all sport competitions in order to demonstrate the superiority of the Arian race. Neubauer was given the task of making Mercedes the Formula One champion.

Formula One, at that time, was an activity in which rich gentlemen competed for fun. Neubauer applied professional standards and optimized the hell out of it.

The first thing he did was improving communication. From his racing experience he knew that F1 drivers had extremely limited awareness of everything but the track in front of them. This problem was so severe that in 1926 Caracciola won the race yet was unaware of this and kept on driving.

So Don Alfredo came up with a system of hand and flag signals for communicating with the three Mercedes drivers. At the beginning of each race he would take a red and a black flag and stand next to the racetrack, and he would provide the drivers with vital information throughout the race. At first the race officials tried to remove him, but he would not budge.

He would also count down time to start for his drivers using his fingers. This provided more convenient that looking at the starter so pretty soon the other team’s drivers began looking at him during countdowns.

Those seven second pitstops you see on F1 racing today are Neubauer’s invention. Before him pitstops were a rather leisurly affair. But he assigned a team to each car and had each member of the team do exactly one thing during the pitstop. Practiced mercilessly, this extreme specialization has enabled Mercedes to shave huge amounts of time.

Paint was removed from the cars to make them lighter. Drivers were put on special diets before the competition. The goal was to leave as little as possible to chance.

In the end, Mercedes became so good that they made the competition meaningless. Races would end with Mercedes in the first three places, and the rest of the teams would trail them by as much as five minutes.

The Mercedes team has withdrawn from Formula One in 1955 undefeated after an accident in Le Mans in which one of their cars has ran off the racetrack and killed 83 spectators.

“In Formula One, you win by doing everything right.”

Unit Testing Frameworks

Something strikes me as extremely wrong with all these unit testing frameworks that are popping up all over the place: they all provide an indication of how many tests have passed and failed. Huh? What’s the purpose of that? When a unit test fails, I want the test execution to immediately stop in the debugger at the offending line so that I can see where the problem is. To do anything else is a lack of good sense.

Marketing Windows Forms

Windows Forms is a huge step forward from GUI frameworks we used under Windows. So you must be wondering why Microsoft is marketing .NET as a web services platform and not as a better desktop app platform?

It’s simple: Microsoft is a business. And it’s not making money on the .NET framework, it’s making money on the platform on which that framework runs. .NET is there to help sell Windows.

Windows already dominates the desktop OS market. There’s not much point in Microsoft spending its marketing dollar there. But Windows still has a lot room for growth in the servers/enterprise market, so naturally Microsoft is directing its marketing effort there.

D-Link WiFi Cards

If you have a Toshiba or a Dell laptop, don’t get a DWL-650+ WiFi card.

I got three of these for the laptops we have at home. They work perfectly with the Compaqs, but on my Toshiba they frequently lose the connection for no reason and the driver caused a BSOD a couple of times.

I looked at the comments on Epinions and Amazon, and most people are happy but there is a number of Dell and Toshiba users experiencing the same problems that I am.

Tailcall

It seems that the .NET runtime is significantly slower in executing tailcalls than in executing “regular” function calls.

For those that have’t used a functional programming language, a tailcall is just like a regular function call except you don’t blow the stack if you call a function recursively too many times. This is done by effectively jumping into the function you are calling instead of calling it.

One usually expects a tailcall to be significantly faster than a regular call. In functional languages like OCaml you use recursion instead of loops, and things work just as fast as they do when you code the loop in C. Not so in .NET.

I wrote two versions of a recursive function, one that uses a tailcall and one that doesn’t. Here is the original C# source of the function:

private static double Test1 (double d, int k) {
    if (k > 1) {
        return Test1 (d * (k + 1) / k, k - 1);
    }
    else {
        return d;
    }
}

The corresponding IL code is:

.method private hidebysig static float64
  Test1(float64 d, int32 k) cil managed {
  .maxstack  3
  IL_0000:  ldarg.1
  IL_0001:  ldc.i4.1
  IL_0002:  ble.s IL_0016
  IL_0004:  ldarg.0
  IL_0005:  ldarg.1
  IL_0006:  ldc.i4.1
  IL_0007:  add
  IL_0008:  conv.r8
  IL_0009:  mul
  IL_000a:  ldarg.1
  IL_000b:  conv.r8
  IL_000c:  div
  IL_000d:  ldarg.1
  IL_000e:  ldc.i4.1
  IL_000f:  sub
  IL_0010:  call float64 TailCallTest.EntryPoint::Test1(float64, int32)
  IL_0015:  ret
  IL_0016:  ldarg.0
  IL_0017:  ret
}

To make that into a tailcall, simply add the tail. token before the call token:

.method private hidebysig static float64
  Test1(float64 d, int32 k) cil managed {
  .maxstack  3
  IL_0000:  ldarg.1
  IL_0001:  ldc.i4.1
  IL_0002:  ble.s IL_0016
  IL_0004:  ldarg.0
  IL_0005:  ldarg.1
  IL_0006:  ldc.i4.1
  IL_0007:  add
  IL_0008:  conv.r8
  IL_0009:  mul
  IL_000a:  ldarg.1
  IL_000b:  conv.r8
  IL_000c:  div
  IL_000d:  ldarg.1
  IL_000e:  ldc.i4.1
  IL_000f:  sub
  IL_0010:  tail.
  IL_0012:  call float64 TailCallTest.EntryPoint::Test1(float64, int32)
  IL_0017:  ret
  IL_0018:  ldarg.0
  IL_0019:  ret
}

I have a test that calls each of these 10000 times, with parameters d = 1 and k = 20000 (k is chosen so as not to blow the stack of the non-tailcall version). The regular function executes in ~ 15 seconds on my laptop, while the tailcall version takes ~ 25 seconds.

So much for language neutrality in .NET.

The code that demonstrates this can be found here.

New Build of Composite

I’ve posted a new build of Composite. It works around the SoapFormatter bug I described yesterday, has better focus management, and fixes a bug with parsing feeds that have single tags like <this/>.

SoapFormatter chokes on some strings

It seems that SoapFormatter has a problem encoding strings.

If you have a string that contains a character with a value between 0×1 and 0×1F, SoapFormatter will not encode that character when writing the resulting XML, but will then puke when reading it.

Here’s the code that demonstrates the problem. The call to Deserialize in the last line of the function below will throw an exception.

void Test () {    string s = "\x01";    MemoryStream stream = new MemoryStream();    IFormatter formatter = new SoapFormatter();    formatter.Serialize(stream, s);
    stream.Seek (0, SeekOrigin.Begin);
    string q = (string)formatter.Deserialize(stream);
}

I’ve added this bug to the .NET Bugs Registry.

Many thanks to Hugh Brown who reported being bitten by this one when using Composite.

RSS Aggregator

Here’s a new release of the RSS Aggregator that I did for the Chris Sells coding contents a while ago. Go here for more details.

Many thanks to Hugh Brown for providing some excellent feedback on the interim versions.

Outlook

I’ve recently switched my e-mail program from Outlook Express to Outlook so that I could run SpamNet, and I’m hating every moment of it.

Outlook Express is fast and ellegant. It was a joy to use.

Outlook is big and sluggish. Whenever it starts downloading a large number of e-mails the main UI thread gets so overloaded that it becomes unresponsive.

The thing that bothers me about both of these programs, though, is that they don’t index and present e-mails the way I want them to. Right now I need to find an e-mail that a colleague of mine, Jim, has sent me last week. That should be as simple as right-clicking on his name and then selecting “View last week’s corespondence”. But instead of that I have to either look manually or use that horrible search dialog.

And don’t get me started on searches through message bodies. Those take forever. Would it be too hard to index e-mail bodies as they are received?

Yuck.