After “Green Grass and High Tides,” that Metallica song is the bane of my Rock Band guitar-ing existence. I don’t know if I’ll ever be able to survive either song. 43% and 86% (on expert), respectively, are my magic [failure] numbers.
But I digress.
As a warning, this is going to be a lengthy entry. There are many items I’d like to cover, so feel free to skip around if you prefer / have no patience / are playing hopscotch. I’ll even make it easier for you, gentle reader, by bolding the main points so you can search for them! Isn’t organization awesome?
Spring break was incredible. I spent every last bit of it (except for Easter) with my girlfriend in Ohio. There was snow everywhere, and she planned and flawlessly executed a surprise birthday party for me at a local Irish pub, The Claddagh. Bagpipes and irish coffee and everything.
She knows me. 🙂
Over the last several weeks, I have been pursuing a job lead as a software engineer with Facebook. During my stay in Ohio, I had two phone interviews – the first with a recruiter, and the second with a developer. It was nerve-wracking, to say the least. I’m quite sure I sounded like a blathering idiot to the recruiter, and while I feel I did significantly better with the developer, I blanked on a few technical questions of his.
For instance: in PHP, what is the difference between “require_once()” and “include_once()”?
I knew this. But not once he’d asked the question.
For instance, part deux: There is array of numbers, 1 through n, but one of those numbers is missing (so the array is of length n – 1). How can we figure out what number is missing (efficiently)?
For instance, part tres: Again, the array of numbers with one missing, except now units of time are based on lookups of single bits, rather than entire integers, so looking at the first bit of the first number requires one clock cycle (must be an old CPU). Again, what is the most efficient way to figure out what number is missing?
To some degree, I blanked on all three (rhyme!). I kind of got 1 correct, I answered 2 correctly but it wasn’t perfectly efficient (O(n2) instead of O(n)), and I needed some hints on 3 to really get going (though I did figure out the answer was in O(log n) time).
Sad. In my opinion, and knowing what I’m capable of, it was pretty weak. I ended up not getting the job. But I shall keep plugging away regardless.
Good news, though: with the exception of NYU, whose application is not due until June, all my graduate school applications are fully complete, with Carnegie Mellon having finally been polished off this past week after several emails back and forth with the admissions officer.
On the note of school…
The second phase of the operating systems project was due over spring break, and yet again it managed to coax a few near-sleepless nights out of me in terms of work. The main deliverable of this phase was rather interesting. The first phase dealt with creating a basic multithreaded HTTP server and multithreaded load tester client. In this phase, we created a proxy that sat between the server and client and forwarded requests back and forth. However, the caveat was an interesting case where the proxy and the server sat on the same machine. If they detected the presence of the other, instead of using sockets to communicate, they were to used shared memory.
Opting out of the recommended but (relatively) archaic System V shared memory standard (shmat, shmget), I went instead for the (relatively) modern but platform-dependent POSIX shared memory standard (shm_open, mmap). Unfortunately, while I understood shared memory perfectly in concept, I had a lot of trouble understanding it in practice. The issue that vexed me all the way up to the deadline was as follows:
If either the server or the proxy was running with shared memory enabled, they created two shared memory entities: the first, a metanode that essentially served as a switch to both that indicated if the other process was alive and present; the second, a linked list of shared memory blocks either process could use to transmit data between them.
By definition, the server would be responsible for creating the two entities, since it is the essential component. The creation would go off without a hitch. However, once the proxy entered the scene and tried to gain access to the shared memory structures, all hell would break loose.
Access to the metanode would work properly; the proxy would successfully realize the server was present by the switch within the metanode. The proxy would successfully gain a foothold through the head pointer of the linked list. Once the proxy tried to access any nodes beyond the head node, however, one of two things would happen.
First, it would segfault on the spot, and the proxy would crash. Or, as stepping through the debugger revealed, the proxy would successfully gain access to the shared memory list, but as it allocated (and by “allocated” I simply mean “gained access to,” since the server had already allocated the shared memory) each node and gained access to it, the server would lose access to that very node.
As best I can tell, the bug had something to do with memory offsets in shared memory, and a slightly different behavior of pointers – from a base starting point (the head), each node needed to store the memory offset to the next node, rather than an explicit pointer to it. If anyone has any further insight into this conundrum, please feel free to post it.
I have since revamped my design to be a dynamically allocated array of structs (created once and never resized), each with a statically allocated array of characters to act as data buffers between processes. Still, I am curious to know exactly why my previous design failed so miserably.
On another note, I just solved the prime number aspect of this puzzle while attending my sister’s art history lecture, which was the last bit I hadn’t quite figured out. It certainly can’t hurt to turn in a puzzle solution.
Google Summer of Code
Yes, I’m getting involved in it this summer. Today is the deadline for student applications, and I will be submitting anywhere between 5 and 8 applications to some or all of the following open source companies:
My top priorities are the reddened names. The list was originally longer, but I had to put my ego on hold and be realistic. First of all, the GSoC is not for the faint of heart. These are serious, real-life, production projects. I would have loved to work with Adium, but I am simply not familiar enough with their code base or their development tools to be of any serious help sans a learning period. These are essentially job applications.
I will post in the coming weeks if I am accepted and with whom. This stuff is IMMENSELY exciting!
I apologize for the lengthy post, but not only am I somewhat of a loquacious individual, it’s also been awhile and I figured somebody missed me.
Back to GSoC!