Andrew Hitchcock's Website
Introducing Mach Block
2011-05-15 23:56:47 by Andrew Hitchcock G+

I'm very excited to announce that my friend Jeff just released his first iPhone game. Mach Block is available today in the App Store.

Mach Block is an arcade-style puzzle game. Each of the 50 levels contains platforms, jump blocks, and enemies. You must kill and then collect all enemies to move on to the next level. You can only shoot enemies on the same platform as you, so you must use the two types of jump blocks in order to dash around the map. After you've shot an enemy it is stunned for a short while, during which time you have to move to the enemy in order to kill it for good.

Jeff designed and implemented Mach Block all by himself, including conceptualization, programming, artwork, music, and sound effects. I've been talking with Jeff since he started and it was interesting to watch his progress and see how much work it really takes to produce an iPhone game from scratch. Indeed, I felt the first beta he gave me had many cheap deaths, but after some gameplay tweaks it really improved and I only died when I made mistakes. Jeff wrote an extensive blog post about the development of his game. It gives a behind the scenes look at the making of the app.

Beyond the arcade-style killing enemies, the game also has a puzzle aspect. Later levels start to introduce mazes and moving platforms which make the game even more challenging. The mazes require you to dash around the map in order to reach a platform right next to you. The routes can get complex and it takes many plays before you start to learn how everything connects and how to efficiently reach every platform. This increases the challenge because you have a limited amount of time to reach a platform that a stunned enemy has landed on. You better learn the maze quickly (or get lucky) because those enemies will respawn before you can reach them!

I beat the game a few days ago after many hours of play. In addition to just proceeding to the end, you can also challenge yourself by going for new high scores. Queueing up attacks and quickly collecting enemies gives you bonus multipliers so skilled players can rack up a huge number of points. In addition to bragging rights, points also lead to extra lives which come in handy on the later levels.

Mach Block is fast paced and always entertaining. Unlike many of the "top 10" iPhone games I've played, Mach Block never felt tedious or slow. You must be engaged at all times and success is more determined by skill than randomness or the subpixel alignment of a slingshot. Once you complete a level you are never more than six seconds away from starting the next; there are no intermediate score screens to slow you down.

In addition to one player mode on the iPhone and iPod, Mach Block also supports two player cooperative mode on the iPad. This is built into the app at no additional cost. Two player mode is more forgiving by providing infinite respawns, as long as one player remains alive. The high score is determined by the lesser of the two players' scores, to encourage both players to contribute equally.

Mach Block is priced at only 99¢ and provides hours of challenge. It is also one of the few games that doesn't try to charge an iPad premium, everyone gets the entire package. I highly recommend checking it out, especially if you are a fan of classic arcade-style games.

Creating An Amazon IAM User Who Can Access A Single S3 Bucket
2011-03-26 16:53:47 by Andrew Hitchcock G+

This article will show how to create an AWS IAM user, grant them access to a single bucket, and allow them to access that bucket using the AWS Management Console.

I have a friend who is trying to start a small website using Amazon S3's new static website feature. Since their site is likely to be a rounding error on my AWS bill I offered to host it and avoid them the hassle of setting up an AWS account and learning how to use everything. I wanted to give them access to a single bucket under my AWS account and nothing else. AWS IAM fits this use case perfectly, but can be a little tricky to set up. Since it took me a few hours to get everything working I thought I'd document this for myself and others to benefit from in the future.

Tooling

Since IAM doesn't have a Console page you'll need to use their command line tools. After downloading the tools there a few steps you need to perform to set them up. First, copy aws-credential.template to aws-credential and fill it out with your account keys. The tools also require some environment variables. Since I'm on a Mac, I added the following lines to my .bash_profile:

export AWS_IAM_HOME=/Users/Andrew/Downloads/IAMCli-1.2.0
export PATH=$PATH:$AWS_IAM_HOME/bin
export AWS_CREDENTIAL_FILE=$AWS_IAM_HOME/aws-credential

Source the your bash profile and you should have access to all the IAM tools.

$ source ~/.bash_profile

Create User

Now that our tooling is ready we can start setting everything up. First I created an S3 bucket for my friend using the AWS Management Console. Then I created a user with the IAM tools.

$ iam-usercreate -u username

Since they will only be accessing S3 using the Console they didn't require a keypair. If they want to use other tools such as S3 Firefox Organizer or s3cmd you can add a -k to that command and a keypair will be created.

Create and Grant Policy

Next we have to create an IAM policy and grant its permissions to the user. I used the AWS Policy Generator to get a sample policy that was similar to what I wanted and then edited it until it fit my needs. You can go this route if you want custom settings, but if you only need to grant a user a permission to a bucket you can just copy mine.

{
  "Statement": [
    {
      "Action": [
        "s3:ListAllMyBuckets"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::*"
    },
    {
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"]
    }
  ]
}

The only thing you need to change here is the name of the bucket. Replace all occurrences of my-bucket with the actual name of the bucket you created. The policy states that the user can list all buckets (necessary to use the AWS Console) and they have full permission to their own bucket.

Save your JSON policy to a file and then issue this command to grant permissions:

$ iam-useruploadpolicy -u username -f policy.json -p usernames3

There are three arguments here. First is the username, obviously. The second is the path of the file where you saved your policy. Finally you have to give the policy a name. I named the policy after the user and appended "s3".

Accessing the AWS Console

In order to let the user access the console you'll need to create a password for them. Run this command, substituting in the appropriate username and password.

$ iam-useraddloginprofile -u username -p password

If you need to change the password at a later time you can use the command iam-usermodloginprofile. If you delete and then re-add the profile you'll have to wait a while for the changes to propagate, so prefer the modify command instead.

Now that you've created the user they can login using a special URL. In order to access the S3 console, you can use the following URL:

https://012345678901.signin.aws.amazon.com/console/s3

You'll need to replace the number with your account number. The account number is found at the top right of your account credentials page. Remove all hyphens for it to work. Another gotcha: you can't have a trailing slash at the end of the URL or it won't work.

Now give your new user the special URL and they should be able to login to the AWS Management Console. They'll be able to see a list of all buckets for your account, but they'll only be able to access or modify the one you gave them permission to.

Tech Interviews Demystified
2011-02-20 18:52:45 by Andrew Hitchcock G+

I encounter a lot of misconceptions about interviewing for software engineering positions at large tech companies. I’d like to spend a little time trying to debunk and demystify the tech interview for people outside the industry. I’ve interviewed at a few large tech companies and have performed interviews while working at Amazon. This article presents my own opinion and does not represent the views, opinions, or beliefs of my employers, past or present.

There have been a few articles in the mainstream media talking about the incredibly difficult interview practices of large tech companies and the bizarre questions they ask. It is natural that people who’ve never experienced a tech interview find them bizarre and intriguing (“they make you write code on a whiteboard!?”). Just as I have no idea what a non-tech interview is like (having never done one), most people have no idea what actually happens in tech interviews. Note: Some of the details presented only apply to large tech companies (such as Amazon, Google, etc.) and not small companies or startups.

Background

Before we begin I need to explain a little bit about the tech industry. The tech world has a high degree of meritocracy. There is a huge range in ability of programmers and this range has to be taken into account when hiring.

There is a vast range in programmer ability. Good programmers can be many times more effective than bad ones. In fact, bad programmers can have a negative productivity because they slow down the rest of the team. Also, the difference between good and bad programmers isn’t a matter of speed. There are some problems that mediocre programmers would never be able to solve given all the time in the world, or their solution would be too riddled with bugs to be useful.

Companies receive many more resumes than they have open positions, but most of these people are unqualified for the job. This is exacerbated by the fact that good engineers will almost always have a job and when they want a new one will selectively apply for the few companies they are interested in. On the other hand, bad engineers will be sending their resume to dozens of companies in the hopes that one will hire them. Even after receiving more applications than positions, companies will still be left with open positions because not enough applicants met the hiring bar of the company. You don’t want to hire people that will make your company weaker.

The Process

Interviewing is very expensive, so the overall goal of the interview process is to eliminate unqualified candidates as quickly and cheaply as possible. The secondary goal is usually selling the engineer on the company. Talented engineers will often have multiple options of where to work, and the interview process is one of the most direct means engineers have of evaluating the company before joining.

The tech interview process generally begins with phone interview, often referred to as phone screen. These occur after the resume pool has been narrowed to remove the undesirables and blatantly unqualified. The goal of a phone screen is to narrow the candidate pool even further by eliminating candidates who are unlikely to pass the onsite interview. Phone screens tend to involve a brief discussion of past experience, followed by a few technical and coding questions, and finishing with a brief Q&A with the candidate (letting the candidate ask the interviewer questions about the company, etc.). The answers to the coding questions are either read over the phone or written in an online collaboration tool like Google Docs that lets the interviewer watch as the candidate types. A phone screen usually lasts between 45 minutes to an hour.

After one or two phone screens the company will have enough confidence to bring the candidate on site to be interviewed, meet the engineers, and see the office. If you are from out of town they will fly you in and put you up in a hotel. The candidate will meet with one or two engineers at a time, for usually between 45 - 75 minutes. This is a full-day event, with somewhere between four and eight meetings. During this the candidate is asked to code on a whiteboard.

All of the interviewers (both phone and onsite) write up their feedback to exchange thoughts. Depending on the company, either the original interviewers or a hiring committee will review the feedback and make a hiring decision. The hiring committee will want to reach consensus on a candidate. Interviewers with a strong opinion on the candidate one way or the other will try to convince the other members of the committee. It is not at all uncommon for members to switch their preference during the course of discussion. If a member is unsure or on the fence, they should fall on the side of not inclined to hire.

Goal Of The Interview

The final goal of the interview process is to determine whether a candidate should be extended an offer. The decision is made by assessing the candidate on a number of attributes, such as knowledge, experience, and intelligence. The question becomes: how do you quickly assess the candidate on these criteria with a high degree of confidence?

Questions are designed to be open-ended in order to give the candidate a lot of room to show their ability. Programming questions in particular will often have multiple solutions, ranging from a relatively easy and straightforward one to perhaps several that are trickier but better. The candidate is encouraged to start with the easy answer, which they should get fairly quickly, and work their way toward the better ones. Along the way they might go on small tangents. Throughout this, the interviewer watches for signals that indicate strengths and weaknesses. These signals can include knowledge of a certain class of problems or the tendency to get stuck on little details that are irrelevant to the problem at hand. Dead ends and false starts don’t necessarily reflect badly on a candidate because they allow the interviewer to see the candidate’s thought process.

Interviewing is a very inexact process and there are many things which can throw off an interview. The candidate might be jet-lagged and under-caffeinated, or the interviewer might be in a grumpy mood. Interviewing is expensive but hiring the wrong person is even more expensive, so companies tend to fall on the side of caution when hiring. It is much better to have false negatives than false positives. This uncertainty prevents a precise ordering of “good” companies or “good” candidates. You might get an offer from one company and then not get an offer from the same company a year later. Engineers shouldn’t take it personally when they are not hired, because there are any number of factors which could lead to a negative.

The Questions

In my experience, tech interview questions tend to fall into three categories. The first category are coding questions, where the candidate is given a high-level specification and is asked to write the code that implements it. This is usually done on a whiteboard or piece of paper in the language of the candidate’s choice. At the simple end is a question like FizzBuzz where the interviewer tells the candidate precisely what the program should do, and the candidate must write the code to do it. Side note: The FizzBuzz question is somewhat famous because it is super simple and easy to explain, but many programmers absolutely fail when trying to answer it.

The second type of question involves algorithms. The interviewer gives the candidate an abstract problem and asks them for an algorithm that solves it. For example, given a list of numbers in sorted order, determine whether it contains a specific number. These questions will often overlap with coding questions, where the candidate must first find the algorithm for a problem and then write the code that implements it. Sometimes the interviewer will ask the candidate to think through a couple possible algorithms before asking for the code.

Finally, some interviews include design questions. The interviewer will describe a very high-level problem and ask the candidate to explain roughly how they would solve it. For example, the interviewer might ask the candidate to create something like the Facebook news feed and the candidate would have to describe the components they would use to implement it and how they interact with each other. This might include a database to store all recent status updates, a means of updating statuses, and a way of seeing all of your friends recent statuses (perhaps weighted by some relevancy metric).

If a candidate is going down the wrong track, the interviewer will often give hints about in the direction of the solution. There is no value in watching a candidate struggle with something that will never work. On the other hand if a candidate is helped out of a rut you can watch to see how far they get and where they start to struggle again. The goal of an interview isn’t to stump the candidate but to observe them.

Articles in the mainstream media often give supposed sample questions from tech companies as an illustration of how crazy and bizarre tech interviews are. They tend to attribute the questions to the current tech company media darlings (in the ‘90s that was Microsoft, in the early ‘00s Google, and more recently Facebook). The questions listed are often wrong or inaccurate. No one asks brainteaser questions like “Why are manhole covers round?”. If you get asked that in an interview, that should be a strong indication that you shouldn’t work there.

On the other hand, one article I read gave the following question as an example of the types of “bizarre” questions tech interviewers ask. “I’m thinking of a number between 1 and 1000. How many guesses would it take you to find the number I’m thinking of if I can only tell you if my number is higher or lower than your guess?” This is not bizarre at all and is actually describing a fairly basic computer algorithm called binary search. This is covered in introductory computer science courses. The way you solve this is by always guessing in the middle of the possible numbers, so the first guess would be 500. Every guess decreases the number of possibilities by half, which means the answer to that question is the base-2 logarithm of 1000, or slightly less than 10. Determining the running time of an algorithm is called complexity analysis and is an important skill for good programmers to have.

I could give examples of some of the more challenging tech interview questions I’ve received, but I’m going to decline out of respect for the companies I’ve interviewed with.

My Experience

It turns out I don’t actually have that much interview experience, but I have interviewed at some of the large tech companies that are often discussed in the media. Here are the companies I’ve interviewed with in roughly chronological order. Bold indicates that I was extended an offer.

While I only have a 50% success rate, I feel all of the interviews have been interesting and rewarding experiences. Each company has a different interview culture. I’d say my Google interview was the most technical and well organized. I’ve heard lots of Google horror stories (mostly from a few years ago), but my experience was mostly pleasant. Amazon also asked interesting technical questions. In my opinion, Apple and Facebook generally asked the easiest questions.

In terms of length, Apple was by far the longest at a grueling eight hours (including lunch). Google and Amazon tied at around 4 - 5 hours and Facebook was around 3 - 4. The worst organized was my original Facebook interview a couple of years ago. They had much improved when I interviewed there again recently.

Conclusion

I hope I was able to demystify the tech interview process. It really isn’t that weird, at least for those of us within the computer science ghetto. In summary:

Thank you Will and Jeff for reading drafts of this article.

AirPort Extreme IPv6 Tunnel
2010-05-05 21:02:24 by Andrew Hitchcock G+

I recently set up a tunnel from my AirPort Extreme to Hurricane Electric so I can access hosts using IPv6. I had done this previously using m0n0wall and documented it so others could follow in my footsteps. This post does the same but for AirPort Extreme.

The first step is to create an account with Hurricane Electric's Tunnel Broker service. From there select Create A Regular Tunnel. Enter your IP address and then submit the form. Once the tunnel is created click Tunnel Details. The page should look something like this.

Screenshot of Tunnel Details

Now open AirPort Utility and go to Advanced ➔ IPv6. For IPv6 Mode select Tunnel. From there you want to change Configure IPv6 to Manually. This will give you a couple of text fields which you can fill out using values from the tunnel detail page. Here is my configuration.

Screenshot of AirPort Utility

In other words, here is the mapping from Tunnel Broker to AirPort Utility.

Server IPv4 address ➔ Remote IPv4 Address
Client IPv6 address ➔ WAN IPv6 Address
Server IPv6 address ➔ IPv6 Default Route
Routed /64 ➔ LAN IPv6 Address

To make this even more useful, Hurricane Electric runs a nameserver that supports Google over IPv6. If you set this as your nameserver you will receive AAAA records for certain Google properties. To enable this, in AirPort Utility go to Internet ➔ TCP/IP and under DNS Server enter the address found in Tunnel Broker's Anycasted IPv4 Caching Nameserver field.

To test that everything worked you can try pinging Google.

$ ping6 google.com
PING6(56=40+8+8 bytes) 2001:470:e822::21f:5bff:fe32:7fc9 --> 2001:4860:8005::63
16 bytes from 2001:4860:8005::63, icmp_seq=0 hlim=55 time=8.619 ms
16 bytes from 2001:4860:8005::63, icmp_seq=1 hlim=55 time=9.442 ms
16 bytes from 2001:4860:8005::63, icmp_seq=2 hlim=55 time=9.336 ms
16 bytes from 2001:4860:8005::63, icmp_seq=3 hlim=55 time=8.963 ms
Aunt Rosie — Google Wave Translation Robot
2009-10-10 15:58:10 by Andrew Hitchcock G+

Google Wave used to have a realtime language translation robot named Rosy Etta. Unfortunately it isn't currently available, so I had to write my own. I named my translation bot Aunt Rosie after my aunt and as a tribute to the original Rosy.

If you include a special keyword, Aunt Rosie will reply to your message with a translation in the language you specified. Watch the video for a demonstration.

To get started, you should add aunt-rosie@appspot.com to your contacts. Now invite her to a Wave.

To begin translation, type "/translate:xx" in your blip. The XX is an ISO 639-1 code which specifies the target language. Chinese is the exception. Use "zh-CN" for simplified Chinese and "zh-TW" for traditional. Note: Aunt Rosie is in beta and still has some bugs. As such, you need to add a space and a newline after the language target. Rosie should appear as soon as you you type in this keyword. If she doesn't, then you might be doing something wrong.

Rosie automatically detects the language you are writing. However, this means you'll need to type enough text for her to recognize the language. Usually it takes 5-6 words before she starts translation. If you are using short words or proper nouns, it might take even longer. Try not to put too many proper nouns in one sentence or she'll get confused.

Aunt Rosie uses Google's machine translation software as her backend. She speaks all the languages Google supports. She is written in Java and runs on Google's App Engine.

Update 2009-10-13: I just finished making Aunt Rosie a lot easier to use. Instead of having to type special keywords and remember two letter codes, Aunt Rosie will automatically insert a language drop down into your blip when you've typed enough for her to recognize your language. Select the language you'd like to translate to and she'll reply with the translation. Easy as pie.

Update 2009-10-23: Occasionally the bot stops working due to a bug in Google Wave. I've mirrored the bot at webmaster@appspot.com, so switch to webmaster if Aunt Rosie is broken. You can track bug 278 on Google Wave's developer site

Update 2010-07-19: It took a long time to get work approval and then I was lazy uploading it somewhere (and in the meantime I switched to Git), but the source code is finally available on GitHub.

View All Entries
Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License.