I'll admit that prior to coming to Microsoft, I rarely clicked "Send report to Microsoft" when something would crash, and I never participated in the customer experience improvement option when offered. Now that I'm participating on some teams that deal with servicing the product after it's released, I see how valuable this data really is. They've gotten extremely good at dealing with those crash dumps in the error reports and the usage data from the customer experience improvement program. So please send us that data! It's really useful and will help make our products even better! Even if you think you've submitted the same one before, submitting it again is a pseudo vote for getting it fixed.
I have been meaning to make a post listing out the blogs of some of Microsoft's senior testers, and I was reminded of that task today when I found out that James Whittaker has started blogging. If you're interested in testing, these are great places to see inside the minds of some of the industry's best testers!
James Whittaker
Alan Page
Michael Hunter
Keith Stobie
If you want more from these guys, we are all part of the Tester Center team so you can keep an eye out for articles and videos there too.
Michael Hunter and I recently recorded an interview with Bryan Lipscy, a tester on the Windows help team. I never thought about all the work that goes into testing the help system, but it's quite impressive. The video is currently on the front page of Tester Center or you can find it in the Tester Spotlights column.
Thanks to the team over at Microspotting.com for sending me an "I Am The Empire" t-shirt!

One of my favorite parts of my job at Microsoft is the wide variety of people that I get to interact with on a daily basis. Want a meet a guy who toys with buying a hovercraft? How about the guy who wrote a bunch of the code books on my shelf? What about a competitor in national foos ball championships? I can introduce you to all of them.
There's a blog called Microspotting that takes time to profile a few of the people who work for our company. If you come work here, maybe you'll work with a member of Harvey Danger or the former Technical Director of Farts and Explosions for South Park.
We recently ran into an interesting issue with our installer which requires elevated permissions to run on Vista SP1. The installer wrote registry entries to HKCR. This is a virtualized hive and the entries are actually written to HKCU. When we ran the app with elevated permissions, the app could not find the entries in HKCR. This is because elevated processes do not see the per-user entries and can only see COM registrations in HKLM\Classes for security reasons. When we changed the installer to write to HKLM instead of HKCR, everything worked fine. However, this means that we cannot do a per-user install when the installer runs with elevated permissions. If you're dealing with strange COM issues when running elevated vs. non-elevated, you may want to look into this.
MSDN has more information.
Here's a quick testing tip: make it as difficult as possible for your test to pass. Otherwise, a failure to fail may be reported as a success and mask a real problem. For example, if your method returns non-zero for a failure, initialize your result code to a non-zero value and only set it to 0 when you're positive that everything has finished and worked correctly.
I recently had the pleasure of meeting both Michael Hunter (the Braidy Tester) and Rob Straavaldson to videotape a Tester Center Spotlight interview. You won't see me on the video, but those two guys are much more interesting than me anyway. I'm lining up some more of these videos and will hopefully be getting them posted through the summer.
The video is currently highlighted on the front page of the Tester Center, or you can find a permanent link to Rob's interview here on the spotlight videos page.
If you haven't read the question yet, you can read it here.
The answer for this lies in the C# specification. Specifically, read section 8.13. There are two different ways you can use a using statement and in this case we are interested in the second way. The key words from the spec are "in this case ResourceType is implicitly the compile-time type of the expression, and the resource variable is inaccessible in, and invisible to, the embedded statement."
So effectively what the code in our question means is:
Foo x;
using (/*y =*/ x = new Foo())
{
} // this calls y.Dispose();
In this example, y is effectively the copy of x that is made so that x becomes inaccessible and invisible to the embedded statement. If Foo is a reference type, you don't really see the difference because x and y point to the same type. However, if Foo is a value type, it is actually making a copy of the value and you're dealing with a completely different memory location.
This brain teaser also comes courtesy of Simeon Cran.
What will the following code output? When you think you know, copy the code into Foo.cs and run “csc Foo.cs” and then run “Foo.exe”. Did it output what you expected? The brain teaser is to come up with the correct explanation for why the program outputs what it does.
using System;
struct Foo : IDisposable
{
bool disposed;
public void Dispose()
{
disposed = true;
Console.WriteLine("Disposed");
}
static void Main(string[] args)
{
Foo foo;
using (foo = new Foo())
{
}
Console.WriteLine(foo.disposed);
using (foo = new Foo())
{
foo.Dispose();
}
Console.WriteLine(foo.disposed);
}
}
Have read the question yet? Read it here.
- The problem is pretty simple if you have 00111 (where all the bits after the first 1 are also 1’s.) You shift right, run the NOT operator, and then AND that result with the original. For example:
ORIGINAL = 00111
SHIFT RIGHT = 00011
NOT = 11100
AND with ORIGINAL = 00100
- The question now becomes, how can I take a number like 001xxxxxx and make sure all those subsequent values are 1? Well if you take 001xxx, shift right 1 and OR, you’ll have 0011xxx. Then shift right two and OR and you’ll have 001111x. Make sense? Shift by 4, then 8, then 16, 32, 64 and you’re done.
Here's the code:
// Clears all the bits on the given value except
// the leftmost bit that was set
static ulong KeepHighestSetBit(ulong value)
{
value |= value>>1;
value |= value>>2;
value |= value>>4;
value |= value>>8;
value |= value>>16;
value |= value>>32;
return value & ~(value>>1);
}
Congrats to Raj Kaimal for figuring this out!
This brain teaser comes courtesy of a co-worker named Simeon Cran.
Using C# and no branches, and no method calls, no allocations, and no unsafe code, write a method that takes a ulong and clears all the bits in it except the highest bit that was set. Use as few operations as possible.
e.g.:
0 -> 0
1 -> 1
2 -> 2
3 -> 2
4 -> 4
5 -> 4
6 -> 4
7 -> 4
8 -> 8
9 -> 8
10 -> 8
…
Maybe I'm the last person on the planet to learn about this, but I have new love for my command prompt. I live in multiple command windows all day long so I can't believe I haven't seen this before. I tested this on Vista and Win2k3.
F2 + character: Prints the last command up to the specified character
F3: Moves down in the history list
F4 + character: Deletes the current command up to the specified character
F5: Moves up in the history list
F7: Shows the command history which you can scroll through
F8: Start typing a command from your history and press F8. The most recent match will be autocompleted
F9 + number: Directly reference a line in the command history
I found these on accident when I fat-fingered something. What else am I missing?
There was a lot of extra information in that brain teaser. All you really needed was these two sentences:
Clearly 41 runs * 1210 feet = 49610 feet. The watch incorrectly said that I had skied 20,100 but had the correct number of runs.
So if I had looked after one run, the watch would have said 1210. After two runs it would have said 2420. After 10 it would have said 12100. Obviously that line of reasoning can’t continue indefinitely because by the time we get to 41 runs, the watch isn’t showing what we expect. So what happened?
The number is stored as a 16 bit signed integer. The maximum 15 bit number is 32,767. After reaching that number, the counter rolled over to 0 and kept increasing. 32,767+20,100 = 52,867. That’s close enough to the expected 49,610 to be reasonable. The difference can be accounted for by slight rises and falls in the run (it’s not perfectly smooth all the way down) and a little barometric pressure variation throughout the day.
That's my theory anyway. Until I check the watch just before 32,767 and then do it again and check just after 32,767, I won't be sure. It seems very reasonable though.