Tuesday, October 21, 2008

How Not To Implement a Linked List Insert *and:* Fun with Amtrak

Intro
Yesterday, I took a trip down to Columbia, MD for a job interview. Columbia is a great little area (at least from the parts I saw and the reviews I have read, that seem to continually rank it among the United States' top 10 best places to live.) The actual trip was quite a disaster, but the interview went rather well. We'll see what happens; I've got my fingers crossed.

How Not to Implement a Linked List
I'm sure everyone who would be interested in reading this would also be smart enough to not do this, but you never know. I thought I was smart enough to not do this. Please don't laugh too hard.

So here I am, interviewing, thinking everything is going well, and then it's time for the whiteboard implementation of a linked list insert routine. I seriously wrote this:
struct list {
int data; /* whatever payload our list is carrying */
struct list *next;
};

void list_insert(struct list *head, int payload) {
struct list *tmp, *tmp2;

tmp = head;
while (tmp && tmp->next != NULL) {
tmp = tmp->next;
}

tmp2 = malloc(sizeof (struct list));
/* err... yeah, skipping out on error checking here */
tmp2->data = payload;
tmp2->next = NULL;
tmp->next = tmp2;
}
Yeah, it works, but that's not the point. It doesn't work well. Comments are things I mentioned amidst writing it out. But I also, while writing while on the whiteboard, had my brain kick in. Well, halfway. My brain said, ``Oh hello there, jolly ol' chap. That's not optimal. But I'll be damned if I'm telling you why!'' So here I am, with while (tmp && tmp- written up there, saying, ``Yeah, uh. This is by no means any kind of optimal.''

But I couldn't figure out why.

Other than that, the interview went well, and I had a lot of fun. (Except for the travel, which was a nightmare, but an acceptable one.)

So I'm back on the train, heading up to New York, and all of a sudden it hits me. ``He said implement a linked list insert, not append.'' D'oh. Of course append *does* insert, but unless you're sorting or whatever... it's really useless.

Except I didn't have any way to do the quick post-interview email. I had just brought a book for the train, and I certainly wasn't going to ask any of these weird businessey-salesy-markety guys to borrow their laptop with its nifty 3G PCMCIA card. (``Why not,'' you may ask. Because my train was delayed for an hour, I wasn't going to be getting home until 2AM at the earliest, and I simply wasn't in the mood to interact at that point.)

Anyway, at the point that I did get home (at about 1:45AM, no less), I hopped on the computer and fired off an email. (I mean, seriously, who implements an O(n) linked list insert?) Instead, what you are supposed to do is insert at the head of the list:
struct list {
int data; /* whatever payload our list is carrying */
struct list *next;
};

void list_insert(struct list **head, int payload) {
struct list *tmp;

tmp = malloc(sizeof (struct list));
tmp->data = payload;
tmp->next = *head;
*head = tmp;
}
So, yeah. Go go brainiac me. Oh well, at least I was still awake enough to realize I needed the pointer to pointer to be able to change the list head.

Fun with Amtrak
I quite possibly could have named this section Worst Train Ride in the History of Man, or possibly something a little less exaggerated, but less sarcastic. In that case, I'd simply modify the title to [I Did Not Have Any] Fun with Amtrak. Let me explain.

The actual travel itself was not so bad. In fact, I rather enjoy trains. I used to hop on them all the time when living in Holland, and so it's nice to see this manner of public transportation still have viable use here in the States. No, the travel itself was fine. But Amtrak has absolutely GOT to do something about their schedules.

Clocks, guys. Fix your Clocks
Amtrak's clocks are broken. Before you tell me that my clocks are broken, I'd like to remind you that I'm a geek, and I'm nutty about time. I'm the kind of asshole that ignores pastes including timestamps if it's somehow obvious that the timestamp is incorrect. By any verifiable amount of time. Not only that: if the timestamp includes a seconds part (my client doesn't show seconds), I'll go run date and determine whether that user actually is off by seconds.

So it should serve as no surprise for you to understand that when I walked into Amtrak at 4:55AM, and they said the 5:10 train had left, and their clock showed 5:12, I was pissed. Yeah, I can understand a car clock being off by a couple of minutes, since it's not the type of thing you look at fixing daily. But how the HELL do you get 15 minutes of drift?

Changing Tickets
Apparently when you change your tickets, any discounts applied to your old ticket doesn't apply to your new ticket. So the company interviewing me had purchased my ticket, and they put the AAA discount on the thing. Apparently they don't copy that over to any further transactions to make on your itinerary. So I paid $10 to change the couple tickets over to take the next train to NY Penn station, and then the train from there to Baltimore. And I took the next train, which was about an hour later, and got me in two hours later than I was originally going to be arriving.

Taxi Drivers in Baltimore are lol
They might know Baltimore, but ask them to go 10 miles out of it and they get lost. Having never been to the offices of this company, *I* had to guide the taxi driver. What a noob.

FIX YOUR GODDAMN TRAINS
Yeah, so... Amtrak? You remember how I said to fix your clocks? Fix your trains too, while you're at it please.

I get to the BWI station, and I was going to need to change over one of my tickets to make the 4:23 train at BWI (instead of the 4:34 train at Baltimore Penn) so that I could interview a few minutes longer and make it to the station on time. I got to the station on time, and I go in to change my tickets. But I'm in line, and I notice it hits 4:23, and there's no train.

Yeah. The 4:23 train was delayed an hour and a half. So instead of being able to take that train, I had to take the 5:33 train up to New York Penn. My connecting train up to Albany left at 8:34 or something. The 5:33 train would get me there at 8:37. (Seriously, what the fuck?) Oh, the best part: the next train to Albany after *that* left at 10:45 and didn't get to Albany until 1:15AM.

So, whatever. In the end, I ended up getting out at NY Penn, calling my girlfriend and she came and picked me up in the city. We got home at around 1:45AM, which was still sooner than we would have gotten home if I had taken the train up to Albany (though I suppose I should place that part of the blame on the fact that both of us live in the middle of nowhere.)


Sunday, October 19, 2008

I'm Awful At Updating My Blog.

Intro
I've been super busy with everything recently and haven't had a chance to update my blog in forever. (That also might be because I haven't actually done much software / sysadmin related stuff in quite some time -- not entirely true, but we'll get into that later). Where've I been? Caught up in projects and real life. Between working on SocialGamer, attempting to pick up some random contracts here and there, and my recent real life adventures, there's not been much time left over for blogging or the Internet at all (outside of what I've been doing; read further).

Real Life
So I finally got a life. This is partially attributed to me finally taking steps to doing fun real life stuff and partially due to having a girlfriend now who actually likes doing fun real life stuff. We've gone on more hiking / rock climbing / random drives around abandoned towns in the past two weeks than I've been on in the past three years. It's quite fun, and makes me realize how much I've missed in the past few years since I've been back in the US. This past weekend, we drove out to Sam's Point in Ellenville, but the trails were so packed (and you have to pay to get in) that we decided we'd try to find something else. On the way back down the mountain, we saw some random place marked for hiking, so we pulled over and walked down a bit, but it turned out there really wasn't any kind of trail.

So we continued our drive out to the middle of nowhere, trying to find some house on the top of a mountain. We never found the house, but we found the weirdest community I've ever seen anywhere. There was this mix of Jewish communities (which were all fenced in and run down, which was odd to see, since it reminded me a lot of Nazi-style ghettos), (probably) million dollar estates (most were for sale, so perhaps they're no longer of such value) and trailer parks. There were burned down / abandoned community centers that had remnants of swimming pools, basketball courts, and tennis courts... and then half a mile down the road, there'd be this shoddy community with an outdoor basketball court that looked better maintained than any of the houses surrounding it. Crazy.

Down one of these roads, we found a `general purpose' nature area. Upon walking down the `trail' (or what may more aptly be described as `area that looked most walked over' since there was no trail to speak of), immediately apparent were an empty mini-keg of Heineken, a bucket and beer bottles, all shattered and riddled with bulletholes, as well as some empty 12 gauge shotgun cartridges. We walked farther into the woods, finding some spectacularly colored leaves on the ground. We found this stone wall running through the middle of the woods. Apparently these sorts of constructions exist all over the place in this area; I'd never really seen them before, and I still wonder the stories behind the walls. What were they marking? When were they built? Who built them?

After walking for perhaps a quarter of a mile into the woods, we thought it best to continue back to the car since:
  1. There was no trail and we'd probably get lost if we went too much further, and
  2. The area was so skeevy, we didn't really trust the car being left alone for too long.
Back to the car we went, and to some general store that has local crafts and seasonal items. It was a pretty nifty shop, some of the local foods they had looked really good. Also, they had some local mega-gigantic Reese's cup-style candy, which I would have bought if it wasn't $2.15. For that price, I'll buy a bunch more Reese's, thank you very much.

Projects
I've been working the last couple months pretty much non-stop on promoting a website I created called SocialGamer. The idea is to have a social networking community for gamers of all types, be they video gamers, board gamers, or active gamers (paintball, footbag (Hacky Sack), frisbee) or otherwise. This is difficult because I've run out of money to piddle around with a website for 80 hours a week. We're trying to get the site migrated over to Django, which would be cool, because that would make it much easier to maintain most of the content on the site, as well as to extend the site in the future. I'm pessimistic about the amount of time I'm going to be able to put into the site in the upcoming month or two (or even in the long term). This is disappointing, because many people love the site. I may hold a fundraiser for it starting in November, but I'm not sure that much is going to come out of that. Either way, that's not going to give me any more time to work on it given I have two upcoming job interviews, will likely have to move for both of the jobs if I get them, and I also have an upcoming contract.

The contract is to develop a browser plugin for an x264 encoder that can stream via RTMP to a Flash Media Server. This plugin must work on FireFox, Internet Explorer, Safari, and Opera and must target Windows XP, Windows Vista, and Mac OS X (10.5). The funny thing about this is that the Mac port looks like the easiest. Quicktime can open cameras and capture devices and encode into x264 natively. So we looked at DirectShow. What a hassle that is!

DirectShow requires you to open a DirectShow device, assemble a bunch of filters for it, and then do whatever with audio / video. In the end, it looks doable, but it's going to be a lot more work than the OS X version which gives you a single, encoded A/V stream. The DirectShow version, we're going to have to do our own A/V syncing! (Why it cannot do this for us is beyond my imagination).

On top of that, it's going to be interesting to code up an NPAPI plugin for two different operating systems and STILL have to code up an ActiveX plugin for Windows. Why in the world did MS remove NPAPI support from MSIE? *Sigh*.

I'll post more about DirectShow weirdness as I get past various issues, I'm sure.


Outro
That's about it, but it's enough to keep anybody busy 168 hours per week. To put my case in point a little better, I set up some water to boil for some noodles midway through this blog entry. I then spent 15 minutes forgetting that it was boiling. Off to fix my noodles and continue on with my various stuff. Gotta prepare for that big interview tomorrow!