I'm doing something pretty goofy today: I'm leaving Google. My tattered old employee badge goes back to HR during my exit interview at 4:00 this afternoon. After that I'll be an ex-Googler.
Working at Google was as amazing as everyone says it is. Sure, the perks were nice. I'll miss the delicious meals, the ski trips, the commuter shuttle, and TGIF. But any company could provide such benefits, given enough free cash flow. What makes Google unique is its culture of respect. The tough interview process means that engineers are treated with respect from their first day. In such a supportive environment, even the most timid person works with self-confidence, which is marvelous to witness. This element of the company's culture was the biggest difference between Google and every other place I've worked in the past. I hope to take it with me throughout the rest of my career.
Which brings me to the future. What's next? I'd originally intended to take a year off and bang on a few software ideas that have been rattling around my head. I'd then pick the most promising one, find some friends, and start up a new venture. As it turned out, things went faster than I expected, and not exactly in the order I'd expected, but the result was the same.
My new venture is a software startup called FSX. I think of the company as a mashup of eBay, Charles Schwab, and American Idol. FSX will use a highly accurate, simulated brokerage to identify skilled stock portfolio managers. For the majority of participants, the fun of FSX's community and fantasy stock exchange will be its own reward. But there will be a tiny number of managers who we find can consistently outperform the field. For those newly discovered stars, we'll provide a market of investors willing to entrust real investment funds to their management.
The business idea is risky, no doubt. The Random Walk Down Wall Street crowd has seen all this before. But the premise that stock-picking is a legitimate, repeatable skill also forms the foundation of the hedge fund and mutual fund industries. If you (or your pension plan) have any of your money in a managed mutual fund or hedge fund, then you believe the premise, too.
The technical challenges are less risky, but to me they're even more fascinating. The uptime and integrity demands are arguably higher than those of a real brokerage. A slow trade in a real brokerage might cost one customer a certain amount of money. In fact, depending on how the ticker goes, the mistake might even earn the customer more money. But every complaint about FSX's performance damages its status as a faithful brokerage simulation, and that in turn damages the value of its entire community. Building a top-tier brokerage website would be hard enough. Our goals are much higher than that.
eBay built a global marketplace out of Pez dispensers and Elmo dolls. They made it possible for you to find that one guy out there who wants to buy your dusty old deluxe chartreuse dinglehopper. He completes his dinglehopper collection, you get some cash and some extra space on your shelf, and the world's a better place. FSX will do the same thing for investments and investment managers. If you think you have management talent, we'll prove it for you. If you want hedge fund-level talent cheaper than the cheapest mutual fund, we'll find it for you.
If you'd like to see a preview, add the Fantasy Stock Exchange application to your Facebook account. If you're a smart software engineer in Silicon Valley and want to join something big while it's still small, .
One of my home PCs has crossed the Singularity. I had an old Windows PC from 2003 that I've kept around because it has lots of important stuff on it, including node-locked commercial software. This weekend I duplicated it into a VMWare image and successfully booted it up inside a newer workstation. I don't need the original physical PC anymore, so after taking out the hard drives I'm carting it off to Google's recycling station.
I wish I'd done this since I was a kid. I could have mirrored all my old Apple II data onto a few Macintosh disks and continued to run Drol and Star Blazer inside an emulator, and then when I lost the Mac faith back in 1997 I could have migrated to whatever Mac-on-Windows emulator must have existed back then. True, there's probably little practical value to reading my Magic Window-formatted book reports from seventh grade, but the geek value is enormous.
Mirroring the PC would probably have been easy with VMWare Converter, but I didn't take that path at first. I was cheaping out and going with free Microsoft Virtual PC 2007, which meant I had to create the drive image myself. Here are the steps I took:
- Move all "live" data (stuff I could see myself accessing more than once a decade) onto a file server.
- Uninstall soon-to-be inapplicable software, such as video drivers and CD/DVD authoring applications.
- Defragment the hard drive.
- Boot into a live CD and run GParted to shrink the drive partition as much as possible, leaving just a bit of room so that Windows can still comfortably run.
- Copy the drive partition to a file on a second drive using a command roughly like this:
dd if=/dev/hda1 of=/mnt/other_drive/hda1.img bs=1M - Also copy the MBR and other fluff:
dd if=/dev/hda of=/mnt/other_drive/hda_header.img count=63(I determined the 63 value by using GParted to figue out where Partition 1 started) - Boot back into Windows and assemble the two parts into a single .vhd file. In retrospect, it would have been much easier to calculate the point where hda1 ended and just copy from block 0 all the way to there, but I was learning as I went.
- Try to trick Virtual PC into accepting the new file as a hard drive. After no luck, do a bit of research on the web to find out the format of the last sector in a .vhd. Write a quick C program to generate it (reprinted at end).
- Tack on the final sector. Confirm that Virtual PC now lets me create a virtual machine using this as the drive.
- Boot the virtual PC. See that it hangs on mup.sys. After finding on the web that a mup.sys hang is a symptom of any of the top 1,000 possible things that could go wrong with your computer, give up on Virtual PC and try VMWare Workstation.
- Learn that my particular PC is actually hanging on sptd.sys. Delete that. Try again. Success.
- Now fire up VMWare Converter. Import the working .vhd into VMWare. Clean up the PC and shut it down.
- 7zip the new VMWare machine into a .7z file (getting about 50% compression!). Drop the .7z file onto a file server for safekeeping.
- All done!
Here's the code to generate the .vhd footer for a fixed-size drive (though if you read my instructions start to finish you'll just do what I wish I'd done and avoid Virtual PC):
#include <windows.h> #include <objbase.h>typedef struct {
unsigned char cookie[8];
unsigned char features[4];
unsigned char file_format_version[4];
unsigned char data_offset[8];
unsigned char time_stamp[4];
unsigned char creator_application[4];
unsigned char creator_version[4];
unsigned char creator_host_os[4];
unsigned char original_size[8];
unsigned char current_size[8];
unsigned char disk_geometry[4];
unsigned char disk_type[4];
unsigned char checksum[4];
unsigned char unique_id[16];
unsigned char saved_state[1];
unsigned char reserved[427];
} hard_disk_footer;void write_int16(unsigned char *p, unsigned short val) {
*p++ = (unsigned char)(val>>8);
*p++ = (unsigned char)val;
}void write_int32(unsigned char *p, unsigned int val) {
*p++ = (unsigned char)(val>>24);
*p++ = (unsigned char)(val>>16);
*p++ = (unsigned char)(val>>8);
*p++ = (unsigned char)val;
}void write_int64(unsigned char *p, ULONGLONG val) {
*p++ = (unsigned char)(val>>56);
*p++ = (unsigned char)(val>>48);
*p++ = (unsigned char)(val>>40);
*p++ = (unsigned char)(val>>32);
*p++ = (unsigned char)(val>>24);
*p++ = (unsigned char)(val>>16);
*p++ = (unsigned char)(val>>8);
*p++ = (unsigned char)val;
}int _tmain(int argc, _TCHAR* argv[])
{
hard_disk_footer hdf = { 0 };memcpy(hdf.cookie, "conectix", 8);
write_int32(hdf.features, 2);
write_int32(hdf.file_format_version, 0x00010000);
write_int32(&hdf.data_offset[4], 0xFFFFFFFF);
memcpy(hdf.creator_application, "vpc ", 4);unsigned int totalSectors = 62914560; // 30GB
unsigned int sectorsPerTrack;
unsigned int heads;
unsigned int cylinderTimesHeads;
unsigned int cylinders;if (totalSectors > 65535 * 16 * 255) {
totalSectors = 65535 * 16 * 255;
}
if (totalSectors >= 65535 * 16 * 63) {
sectorsPerTrack = 255;
heads = 16;
cylinderTimesHeads = totalSectors / sectorsPerTrack;
} else {
sectorsPerTrack = 17;
cylinderTimesHeads = totalSectors / sectorsPerTrack;
heads = (cylinderTimesHeads + 1023) / 1024;
if (heads < 4) {
heads = 4;
}
if (cylinderTimesHeads >= (heads * 1024) || heads > 16) {
sectorsPerTrack = 31;
heads = 16;
cylinderTimesHeads = totalSectors / sectorsPerTrack;
}
if (cylinderTimesHeads >= (heads * 1024)) {
sectorsPerTrack = 63;
heads = 16;
cylinderTimesHeads = totalSectors / sectorsPerTrack;
}
}
cylinders = cylinderTimesHeads / heads;write_int16(hdf.disk_geometry, cylinders);
hdf.disk_geometry[2] = (unsigned char)heads;
hdf.disk_geometry[3] = (unsigned char)sectorsPerTrack;write_int32(hdf.disk_type, 2); // fixed
ULONGLONG totalSize = UInt32x32To64(totalSectors, 512);
write_int64(hdf.current_size, totalSize);CoCreateGuid((GUID*)&hdf.unique_id);
unsigned int checksum = 0;
write_int32(hdf.checksum, 0);
unsigned int counter;
unsigned char *p = (unsigned char *)&hdf;
for (counter = 0 ; counter < sizeof(hard_disk_footer); counter++) {
checksum += p[counter];
}
write_int32(hdf.checksum, ~checksum);FILE *f = fopen("e:\\hdr.out", "wb");
fwrite(&hdf, 1, sizeof(hard_disk_footer), f);
return 0;
}
If life were Hollywood, I'd be typecast as The Guy Who Understands AMT As It Applies To Your Company's Stock Options. I get asked certain questions often enough that it's time to write up my answers. But remember, I'm not a tax lawyer or accountant; I just play one in movies. So get real tax advice from a professional.
Two questions are popular. First: "I just joined a company and got some stock options. There's something in the agreement about early-exercising. I understand how options work, but I don't understand why anyone would exercise early. What's the deal?" Second: "Oh boy, we're going public in six months, and the lockup expires 6 months after that! Should I exercise my options now to get the long-term capital gain rate on my zillions in profits?"
There are two considerations when you exercise ISOs (Incentive Stock Options): capital gains, and alternative minimum tax.
If you sell an asset more than a year after you acquired it, you're federally taxed on the profit at 15%. Less than that and it's the same as your ordinary income tax rate, which is probably 28%. So if you exercise your options, that means you buy the underlying stock, and that starts the cap gains period running, and you might cut your federal tax on the profits in half. Note that there are some funny rules for ISOs that effectively change this period for early-exercised stock to two years; either way, it's beneficial from the cap gains perspective to exercise as early as possible.
However, AMT can really screw you over. AMT is like an alternate universe that's even weirder than the normally taxed universe. You're potentially taxed on imaginary income, for example. In our case, the imaginary income is the difference between so-called fair market value of your stock on the day you exercise, and if that amount is large, you have to pay AMT on it, even if your stock ends up worthless by the time you're actually able to sell it.
Here's an example.
- On 1 Jan 2008 Joe gets 10,000 options of ABC Corp. at strike price of 5 cents.
- On 1 Jan 2010, ABC files for IPO for the coming month of June. The Board of Directors determines FMV of ABC is $75/share.
- On 2 Jan 2010, Joe is very excited about the upcoming IPO, so he exercises his options, writing a check for $500 (10,000 x 5 cents).
- On 1 Jun 2010, ABC goes public at $100. After an accounting scandal, the stock tanks. Joe ends up selling his shares for $1 each, or $10,000 total, the day the employee lockup expires. Joe's bummed out because he was briefly a millionaire, but still happy because he made a profit of $9,500.
- On 1 Apr 2011, Joe's accountant determines that Joe owes AMT. Joe "earned" imaginary income of $749,500 on 2 Jan 2010. The accountant asks Joe to write a check to the IRS for approximately $250,000.00 to pay his 2010 taxes. Joe says "wait a minute, why am I paying taxes of $250,000 on a profit of $9,500??" His accountant says "Because you suck."
Joe should have either exercised on 1/1/2008, or never early-exercised at all. Early exercise avoids AMT and starts the cap gains holding period. Never early-exercising means you pay higher taxes on the gains, but you avoid AMT (and, of course, you don't put any money at risk by exercising).
Obviously, things change if you assume the share price will go down. But you wouldn't be working at that company if you believed that.
Final disclaimer: all of this is probably wrong or at least out of date. For example, I heard from a friend that for 2007 you're allowed to recover quite a bit more than usual of AMT paid in prior years, so the situation is possibly not as awful as it has been in the past. Again, hire a professional.
The salad I just bought at the grocery store says it contains three servings. Yet it includes only one plastic fork. How rude!
The Nokia CA-75U's pinouts are identical to the Creative Zen Vision A/V cable's pinouts.
