2011/02/27

Interviewing Tips

At my current gig, we are hiring Perl programmers. Lots of them. I mean, not tens of thousands, but we are actively interviewing people. And as I interview these applicants a few things have jumped out at me. I'll confess I thought all these things were obvious and self-evident. But after half a dozen candidates all making similar mistakes, I figured maybe I'd post about it. Following my tips won't get you a job, but it might prevent you from losing an opportunity you might have been well-suited for.




1. Know Your Target Company
Like I said, I thought this was obvious, but apparently not. If you are applying for a job at a company, a few minutes on Google will tell you quite a bit about that company. Why you would ever apply at a company you don't know anything about is beyond me.

Perhaps you are desperate for a job and so you sent out hundreds of applications? I'm not sure how wise a strategy that is, but you have at least 5 minutes before the first phone call to do some sleuthing. If you are in such dire straits that you are sending out applications willy-nily, surely 5 minutes to do some basic research about the company would be a good idea?

This is especially important since companies like to think you are interested in them. For some reason, we aren't too keen on hiring people who could care less about our goals and interests. Just sayin' ...

2. Tell Me Why You Should Have the Job
Ah, the lost art of the cover letter. It goes hand-in-hand with #1. If you know anything about the company and you have any related job skills, you should have a clear idea of why the company should hire you. Let me give you an example:

You write Perl. You see my job posting for Perl programmers specializing in MVC. You look up my company and see we are into making websites. Ok, here's you chance! Tell me why I should hire you. It should be obvious, right?

  • I've been writing Perl for X years, and I have successfully completed Y number of projects that allows customers to create websites. I wrote several specialized toolkits for easy processing of data and creating HTML pages from it. Blah, blah, blah.
  • I've also been experimenting with iOS/Android/WebOS/WP7 (God help you), and I have some experience in making websites scale to these emerging platforms. While this may not be your current target, I believe my experience here could blah, blah, blah, blah
See what I did there? I took related skills, and I combined them with a cursory knowledge of the company and position. With that very simple combination, I specifically show how you could be useful to the company.

This is apparently a new concept to a lot of people. My mother—the long-suffering English teacher—is shaking her head right now, as she has taught this to High School Juniors for years. It's called a "cover letter". You don't even need the formal cover letter in today's email-centric world. Just give me a blurb about your experience (executive summary tailored for my job posting) and another realistic blurb about how you think your skills would be a good fit. Put it right there in the email where you send me your resume (in PDF, for crying out loud—what's wrong with you?).

Really, it's not that hard. And you would be surprised how much it impacts your interview process.

3. Know Your Stuff (Duh)
If you are interviewing for a Java job, you better know your collection classes. If you are interviewing for your Perl, you better know how to use regexes to capture text. If you are interviewing for JavaScript, you better understand prototype-based inheritance.

Here's a tip: before the phone interview where I (or someone else) calls you and grills you about your technical knowledge, why not brush up on what you are interviewing for? Seriously.

If you are interviewing for a Perl job, I expect you to know regexes. I'm not expecting you to be the Regex God, but I am expecting you to know how to capture text with regexes. You might slip on some syntax here or there, but you need to know the basics.

Kind of obvious, but again, I've been seeing problems :-(

4. Know How To Say "I don't know" Properly
Question: how do the Perl functions exec() and system() differ?

Now if you know the answer, awesome. But eventually, you are going to have that interview where you will not know the answer. The following are two examples of saying "I don't know."

Answer 1: I don't know.
Answer 2: I don't know. But I know that system() does X, Y, Z, so if I were to guess, about exec(), maybe it's about A and B? Can you give me a context in which they might be used?

I'm going to give you exactly one guess which one helps you in an interview.

5. Know How to Be Wrong
Along with knowing how to say "I don't know properly" is the valuable skill of knowing how to be wrong in an interview. Because eventually, you are going to get an answer wrong. It happens to the best of us, and I'll let you in on a secret: most interviewers are purposefully trying to make you screw up.

Now sometimes that's because you are being interviewed by a sadist (it happens). But usually, it's because the interviewer is trying to find out what you know, and they can only do that by asking you a whole range of questions. But more important than what you know is how you handle what you don't know. In software, you are always having to learn new things, always getting tossed into the deep end (sometimes with some bowling balls to juggle). We interviewers know this. So we purposefully try to find holes in your knowledge or trip you up. We want to watch how you think, how you react, how you approach being in over your head.

Sometimes you can get more than half the questions wrong and still pass the interview with flying colors. No joke.

I'm not sure there's one, right way to handle being wrong. But I can tell you some very unhelpful ways to handle it:

Defensive: It's an interview. Breathe. It's ok. We all hate being wrong (trust me, I get it). It's not the end of the world, and no matter how much you want this job, being defensive about being wrong is not going to get you the job. Quite the opposite, actually.

Excuses: There's a fine line between explaining how you got tripped up (sometimes useful) and making excuses. Tip: don't blame the interview question—even if it was a crappy question :-)

Dismissive: "I don't see why you would do that anyways." Oh boy. It's an interview question, my friend. Of course, it may be contrived. It might even be purposefully confusing. That's not the point. The point is that you were asked a question, and the interviewer wants an answer. You may think it's a dumb question, but saying so isn't winning you points. Just sayin' ;-)

6. Be On Your Best Behavior
Unless you are interviewing with some very, very weird company, they are probably looking for an individual with the following traits:
  • Friendly
  • Able to get along with others
  • Not prone to outbursts of anger
  • Willing to give the benefit of the doubt
  • Hard worker
  • "Team player"
Companies are made up of people. People need to (more or less) get along. During the interview is not the time to highlight how you do not suffer fools or idiots. It's not the time to brag about how you had this manager who was an idiot and they dismissed your idea—and how you went around them and triumphed. It's not the time to talk about how much your current job sucks.

I cannot underscore the importance of this one. We'd rather hire a humble, friendly intermediate programmer with a lot to learn than some rock-star programmer who treats everyone else as lesser beings beneath his brilliance. All the better if you are a rock-star and know how to get along with people!

7. Work On Your Resume (Please)
This may be because my mom was an English teacher or because I took English Literature as a major, or just because I like to read. Whatever the reason, I highly recommend you put some work into your resume.

As for me, I found a really good format that worked for me and worked for my interviews. I've been using the same format for years (literally since 1997), and it serves me fine. But I update it every year, and I always check it for typos or awkward wording. Not because I'm looking for a job, but because that resume is such an important part of my career.

Don't just slap your resume together. Don't give me the same resume you gave the other guy—especially if we are not in even remotely related fields or vertical markets. I'm not saying you need to customize your resume for each job; I am saying you need to consider it though.

Say you made your bread-and-butter in Java like I did, and you are now applying for a job at a Mobile App company. Now is the time to go back and change your resume to highlight all the skills or projects that make you an ideal fit for this Mobile company. Don't give me a resume all about your EJB experience when all I care about is your iOS or Cocoa experience. Instead, highlight how your projects were about distributed apps, high volume processing, high reliability, flexible UIs based on clients, etc. I.e. give me something that shows that even your experience from 10 years ago is actually an asset—one I should not go another day without having on my team!

Oh, and give me the resume in PDF, type-set in all its awesome glory. Don't give it to me in DOC or DOCX where it might not display on my version of Word or on my Mac. Why short-change yourself? Just print it to PDF (take a look at PDF Creator if you are not blessed to be running a Mac) and make it as portable and beautiful as possible. Or send me both. But make sure I get the PDF.



There are many more tips, but I thought I'd just get these obvious ones out of the way.

To those out there job hunting, good luck! I mean it. I've been on both sides of the process, and I know how nerve wracking it can be to be out there, searching and searching for a job. Just take the time to work on these simple points and your interviews will be a lot more productive!

So It's Been a Loooong Time

Ok, I'm looking at my blog, and what can I say? It's been a very, very busy 2.5 years, but no blog posts.


I've got a few things to write about now, but I just wanted to get it out of the way: yes, it's been a long time, and no, I don't have a real good excuse :-)

2008/04/01

RH EL 5 perl interpreter bug?

Ok, so I have a contract where I do some perl work. I've been coding away very hard on building a new version of an internal app for my client, and the new work leverages Catalyst. The work has been going very well, and Catalyst is a lot of fun to use. I've also been using Moose, and that has been real fun. So we reach a milestone and I test out our code on the dev integration server, and I start seeing funny, troubling results. My code seems to be performing 20-30 times slower on a machine that should be much faster than my local, aging MacBook Core Duo. What the heck?

Database? No. Memory? Don't think so. Object allocation? Err. That's not good. Could it be Moose? Oh, please no—my whole system is leveraging Moosey-goodness. So I put together some unit tests (if you don't use unit tests in your development process, you are insane), where I'm instantiating/allocating a lot of hash references, some blessed hash references (regular, ole Perl-OO), some vanilla Moose objects, and then my troublesome classes. Low and behold it wasn't Moose at all. It was overload. Whenever I instantiated my base class for my object sytem (which used overload), everything crawled to horribly slow speeds. 60% of the time gets spent in the "new" method, despite nothing really going on in there.

I hack up another unit test where I'm just using plain, vanilla Perl-OO via blessed hash references, and sure enough the class with overload takes forever to instantiate on the dev server. It runs just fine on my MacBook. Now I'm getting suspicious.

I went to the #moose IRC channel, and someone brought up that Red Hat stock perl interpreters are rumored to have issues with overload. So I downloaded the source for perl 5.8.8 (to match the version used in the Red Hat perl RPM) and I built it using the same options—I just installed it to ~/perl instead of to the system at large.

Sure enough, the unit test runs just like it does on my MacBook using the built-from-source perl interpeter (there was less than a 1% difference between the class with overload and the class without). I then re-ran the test with the stock interpreter from Red Hat and the stock interpreter took 300 times as long to instantiate the same amount of objects. You can see my test results here.

Off to bugzilla to get Red Hat involved. Hopefully it won't take too long to get a patch. At the worst, we can use an interpreter built from source until RH issues a fix.

2007/12/17

"A foolish consistency is the hobgoblin of little minds."

So I was writing some code for some data access code and I realized that there was a certain amount of what be considered "boring sameness" about the stuff I was writing. As I added additional methods for manipulating the state of a business object, I realized that I pretty much copied-and-pasted the last method, tweaking it for the new method. In this particular case, I would copy a Perl object method, change the name and POD documentation, change which SQL string it would use (two variable names), change the variable name being added to the array of bind values, and then tweak the return (if at all). All in all, I would copy and paste 100 lines of code and change usually 4-10 lines. Over the course of the past 30 minutes, I had done that 6 times.

If you write software right now, you are probably saying "so what?" You'd say this because it is very common. At some point, you factor out all the tough or repetitive code and you get down to a "diminishing returns" point where nothing else can really be factored out and that you are reusing the same method calls, tweaked for different scenarios, over and over again. This kind of work can actually be a bit boring—even mindless.

The important thing to point out here is that this "boring" copy and paste is a sign of good foundation underneath your code. Or at least it is in business software or code dealing directly with business processes. The reason this work is boring is because you are basically copying and pasting the same stuff over and over again with small tweaks. The reason this is good is because you have gotten your underlying code so consistent and straightforward that you can copy and paste the same basic stuff all over again.

I think this is important to point out because I so often don't see this boring sameness in the code I am asked to update or maintain. I'm not sure why the people who wrote the code originally didn't try to refactor their code to make it more regular and consistent, but again and again it's something I find missing in a lot of code these days. Perhaps they were in a hurry? Or perhaps they thought such optimization was unneeded? Perhaps they (mis)quoted to themselves Emerson, "Consistency is the hobgoblin of little minds." But that's not what Emerson said. He said:

A foolish consistency is the hobgoblin of little minds.
He never discussed what "foolish" versus "wise" consistency was, but he did make a qualification for his statement by mentioning "foolish consistency" specifically. While we in software engineering may not be poets (or care about Emerson), I think we need to take this quote (and its converse) to heart when developing software.

I've talked about the need for modular programming in another post. I didn't bother to discuss "going too far" because I rarely see that problem in my work. But it is possible to go too far. For instance, in the copying and pasting I was doing, I wondered briefly if there was some pattern I might extract so that I could eliminate even the copying and pasting. I say briefly because I thought about it and discarded the idea. The project I am on currently does not want to leverage any ORM or database query toolkits; whether this is a good idea or not could be debated, but the fact remains it was a constraint for my current work. So if I couldn't use a DB toolkit, any further optimization would either be creating my own DB toolkit (which would be dumb) or making optimization code that is so specific to the current work that it would either be brittle or not useful beyond the specific work I was implementing.

Here's where my early comment about "diminishing returns" meets Emerson's "foolish consistency". To optimize further in an attempt to eliminate the copying and pasting I was down to at this point would be wasted effort. This is where the proverbial 80/20 rule comes in. How you apply 80/20 depends on the situation, but you can pretty much invent almost an infinite number of ways to find 80 percent of something hiding in another 20 percent of something else. Regardless, the point is that I could have further optimized, but the amount of work required versus how much benefit and reuse I would gain later wasn't worth it—especially since in this case, I would have ended up creating my own limited DB toolkit. To demand additional optimization that has no real end benefit to reuse or clarity would be to insist on an additional level of "foolish consistency."

However, there's a definite balance or gray area about what is foolish and wise consistency in software engineering. I personally feel a lot of the ability to judge what is foolish and what is wise comes from experience and by learning from truly elegant software. Here, working through the classic Design Patterns or perhaps Knuth's Art of Computer Programming would help even the most seasoned programmer. The reality is that the relation between elegant software and discipline and experience is significant. You will only be able to produce (and to some extent, judge) the elegance of a solution through experience and training.

The rule of thumb I would leave you with is that design optimization—striving for common, consistent APIs or elegant, concise paradigms—is never "foolish consistency". Taking an extra hour or two to get an API consistent is never wasted effort. Consistent APIs are self-documenting (that is, they are plain to read and using one aspect of the API builds or directly translates into using another aspect). Most code I have found has erred on the side of "there's not enough time", and has regarded most attempts at consistency as foolish. Only painful experience and some training will ever cure those errors.

And who likes pain? So try to aim for boring cut and paste, the kind that isn't duplicating critical code over and over again. If you find that the code you are copying would require you to make a change in more than one place (possibly a dozen places) if some lower API or data structure changed, stop. Pause for a second and ask yourself what kind of consistency you have. Crack open a good book like Design Patterns and see if anything in there might help you. You might be really glad later on!

Oh, and throw in some documentation while you are at it :-)

2007/12/13

Leopard and its non-intuitive volume change

Ok, so I have finally figured out why I hear my email screaming in the night.  Well, screaming deserves a little explanation: I use sample of a Jawa from Star Wars for new email notifications (the little scream of excitement when they zap R2D2—sounds a little like "Ooteedee!").  In my new apartment, my office is right next to my bedroom; I can easily hear the sounds from my computer in my bedroom.  Anyways, the last thing you want when you are drifting off into sleepy land is a screaming Jawa telling you email has arrived (and let's face it: email at that hour is usually spam anyways).

So, I took the obvious approach to solving the problem: I pressed mute on my keyboard.  Problem solved, right?  Not quite.

I have my MacBook hooked into a computer stereo speaker system.  One night, I heard some interference from my iPhone and thought it might be the cheap Radio Shack cable I used to hook it in.  So I unplugged the cable and went back to bed.  Just as I'm drifting back to sleep, I hear a screaming Jawa again—but I had hit mute.  What the heck?

I get up again, and hit mute.  Finally, silence.  I wake up the next morning, and I hit unmute (still not hooked into the stereo), and sounds resume.  Later in the day, I realize it isn't plugged into the speakers, so I plug it in.  No sounds.  Huh?  I try unmute again, and then I have sound.

Now maybe I'm just incredibly slow and stupid around bed time and when I get up in the morning (well, I know I'm slow and stupid in the morning), but it took me a few days to finally figure this out.  And I'm pretty sure this is a Leopard change, as I never remember having this much trouble back with Tiger.  Here's the deal ...

As near as I can tell, Leopard is trying to be helpful like the iPhone.  With the iPhone, if you set the volume while listening to the headphones, you'll notice that the volume setting will change if you unplug the headphones.  This is because the iPhone can tell when you have headphones plugged in and when you don't; so the volume for headphones and the volume for the speaker are kept separate.  This is good, when you think about it, as you would probably have the speaker louder than the headphones.  You wouldn't want your headphones to be blasting at the same volume.

It turns out, Leopard does this too.  Again, maybe this happened in Tiger, but I never remember this happening.  As I remember, mute was mute—period.  No matter what was plugged in or not, mute meant no sound.  Well, Leopard tracks volume—along with mute—based on what is plugged in (or not) into the headphones jack.  So you can set the volume level while you have something plugged into the headphone jack, unplug it, and then the volume level is now different.

Perhaps there is some nice feature here that I am missing.  But there's one flaw with this approach: mute should be mute should be mute.  I can't ever imagine a time where you would like to mute your computer sounds, only to have the sounds resume when you unplug it.  Usually when you choose mute, you want mute, regardless of whether your computer is plugged into headphones or not.  I could see the separate volume levels being useful, but not the separate mute settings.

Maybe I'll go create a radar ticket and see if Apple thinks it's a feature ...