2010-02-13

Looking For A Job?

Looking for a job isn't fun. You have to boast of your accomplishments, which some find distasteful; you have to repeat yourself a lot as you send out your résumé and ever-so-slightly customized cover letters all across the internet, which some find tedious; and you have to do all this while in the throes of unemployment (or on the QT while still employed), which nobody enjoys.

It's no picnic for the hiring manager, either, especially at start-ups. Managers are usually expected to do other things than manage--lead engineers are supposed to code, VPs of marketing craft email campaigns, UX directors whip up Photoshop designs, and so everybody is chronically strapped for time, not least the person in charge of coordinating 30 positions that need to be filled yesterday without completely ignoring the existing employees and their ongoing issues. You have to balance the supreme requirement of hiring the right people (i.e. being ruthlessly selective) with the urgency of the hire and the overhead of screening, interviewing (and rejecting) a non-zero number of candidates. It's pretty common to find yourself in the following paradox loop:
"We need to find a (programmer|designer|marketer|PM|salesperson) pronto or we're never going to (ship|sell|market) this thing this year"
and
"I really don't have time to (screen|interview) those applicants"
I've been privileged to participate in hiring a lot of great people over the years, either as an interviewer or a hiring manager; and because I've been knee-deep in résumé-screening trying to fill a couple of positions for a little while, I thought it might be useful to recap a couple of the hurdles applicants and hiring managers always seem to be running into.

RTFR

One of the hiring manager's more enervating enemies is the job trawler. The job trawler applies for dozens (hundreds) of jobs at the same time, with little regard for the posted requirements, presumably in the hope that the hiring manager will take it on faith they can learn the skills on the job, or not notice they just filled a real-time embedded-systems development position with a JSP programmer who's never even heard of C.

To spell it out in simple terms:

"Requirement" means "you have to know this stuff"

and so this:
"Requirements: 4+ years Oracle, PL/SQL, 6+ years C++, excellent knowledge of Unix/Linux performance optimization"
means that this won't cut it:
"Skills: Java (2 years), MySQL (3 years), perl, Windows Server"
Applying for a job whose requirements you don't meet is worse than ineffectual: it's counterproductive. It sucks up time out of a busy person's schedule that they could be spending interviewing qualified candidates. And if they have a modicum of organization, they might remember this when you apply for another position at their company.

Don't do it. And for Pete's sake, if the hiring manager sends you a rejection letter telling you you don't meet the requirements, don't argue with them.

Let Me Show You My Pokemans

Spelling, grammarsilly kitties and punctuation are mostly arbitrary and capricious. That's partly why software developers came up with various devices to help supplement their fallible memory (or typing skills), such as spelling- and grammar-checkers. Many are even free. So when you send in something like this:
dear mr/msr,

i wanted to apply for the engineer position in ur compny on craigslits i am a hardworking programmer with 2 yr. experience in java technologys. i guarante dedication to ur company because i need the money so i won't let u down.

Skill:
  • java, j2ee, jni, xml, soa
  • well communication skills
  • work good under pressure
i look forward to discuss my application.
it just doesn't make a good impression, and when a hiring manager is screening résumés to find candidates that are worth spending over 10 man-hours wooing and interviewing, your first impression is all you have. Maybe Donald Knuth, Brian Kernighan and Ray Ozzie are ready to be your references at a moment's notice; maybe you did write seven bug-free patches that got checked into the kernel tree; but if your résumé and cover letter look like a Scrabble game board after a tornado, you'll never get a chance to show off those 1337 skillz, or to get Knuth on the phone with your boss.

There's nothing wrong with not having a hypertrophied command of English. There is, however, something wrong with not turning on your word processor or Web browser's spell-checker, or not spending 10 minutes going over your application materials to make sure they will impress your future boss into calling you in for an interview. If you're in school, visit the career center. If you're employed, ask a trusted co-worker (or your boss, if you can). Librarians love to help, and they're often the hyperliterate type that can smell a typo from a mile away. It's a cheap investment with very high returns.

Stating The Obvious

Of course, all of this stuff is trivial and should be self-evident. Joel Spolsky has written at length about it; he even started a job board. If you're like me, you want to hire people who read Joel Spolsky, so it's extra disheartening when so many of the resumes that come across your monitor show no evidence of Spolsky-awareness (or common sense).

In the case of software engineering jobs, in particular, you'd think people with the brains, education and experience (nominally, at least) to go after a job that can bring in six figures pretty quickly1 wouldn't even have to be told these things.

Rejecting a candidate is not something hiring managers do lightly: the opportunity cost of not hiring a great candidate is high; and we've also all been in an applicant's shoes, so we know how hurtful and discouraging it can be not to be called in for an interview.

So if you're a hiring manager, make sure your job postings and requirements are clear, follow up with applicants (both good and bad) in a timely manner, and renounce the "Screening applicants is such a time sink" attitude. If you're looking for a job, stack the odds in your favor, don't apply for jobs you're not qualified for, and knock 'em dead with a crisp, punchy résumé. And if you're a database or data warehouse engineer, get in touch ASAP.



1. If you're reasonably good at it.

2010-02-03

Breaking the Unit-Tests-Take-Too-Long Cycle

Unit Testing in Theory

By now (2010) every experienced software developer worth her salt has heard about unit testing. If you're not familiar with the concept, here's how it goes in a nutshell, using some fake programming language:

class Thingie
{
public static function do_something(param)
{
if (param == 0)
{
return false;
}
c = new network_connection();
data = c.fetch();
return !empty(data);
}
}
class ThingieTest extends TestFrameworkTestCase
{
public function test_do_something()
{
T = new Thingie();
this.assert_equals(T.do_something(1), true);
this.assert_equals(T.do_something(0), false);
}
}

TestFramework ThingieTest

..
1 test, 2 assertions, 0 failures.


Many languages have unit-testing frameworks available. Unit testing is an elegant, systematic, automatable system that makes obsolete all the ad-hoc programs developers often write to test various parts of their code. The field is both fresh and mature enough that there's a small, well-known set of standard practices that make it easy to start writing unit tests in language A if you're familiar with unit tests in language B. By and large, it's a great invention with considerable benefits.

Some have embraced the practice and follow it almost religiously, writing their unit tests first and actual software second. Others apply unit testing more like salt, pepper and nutmeg, as needed but not in excess. Still others write tests reluctantly and need to be reminded frequently, like patients chided for their infrequent flossing by their dental hygienist. And others just write code and custom test scripts (I actually know superlative software developers who've never written a single unit test and probably never will). You may find that a developer's attitude towards unit tests has some relation to the year they started getting paid programming gigs.

Unit Testing in Practice

The majority of developers I did, do, may, will, and won't ever work with, interview and hire probably fall in the unit-tests-as-spice camp: they're reasonably convinced unit testing is an excellent insurance policy, they may even evangelize the practice with unenlightened colleagues, but they readily admit their unit test coverage is spotty or out of date, with a curious mix of rational self-confidence ("I try to test code that's important, not getters and setters; 100% coverage is silly") and underflossed guilt ("I probably don't write as many tests as I should"). I'm certainly one of them.

A lot of (most?) software shops put a lot of pressure on developers to just crank out code that does something. As a result, software that doesn't do anything visible gets short shrift if it gets written at all, and unit tests are often the first to get the axe. Oversimplifying, the tacit (and circular) rationale looks a lot like this:

  • a good developer's best code is bug-free
  • bug-free code will pass all its unit tests, by definition
  • therefore, writing tests is a waste of time, since they won't uncover any bugs
Making Tests Work

A common strategy to encourage beneficial behavior is to wrap the hard-to-do stuff inside something they normally do: hide a cat pill inside a yummy treat, or stick a tongue-scraper on the non-bristly side of a toothbrush head. Brush your teeth and clean the rest of your mouth at no extra charge!


Similarly, the benefit of unit tests can be self-sustaining if you can make your tests:

  • run as often as necessary
  • run at no cost to the developer
  • draw attention to their usefulness very forcefully when something breaks
  • remain invisible otherwise
This could mean suppressing all output when all tests pass, but warning the entire development team when a check-in is going to break the build so the bug can be fixed immediately rather than rot in your bug tracker's entrails, forgotten until your boss demos your product to the board, trips the bug, and sends your entire team into a panic trying to hot-fix the problem in the program QA signed off on two hours ago.

Here are suggestions to increase your team's enthusiasm for, and the effectiveness of, consistent unit testing. All of these tips are some variation on the parasitic-benefit approach outlined above.
  • trigger your unit tests automatically using a pre-commit hook in your source-control system. Every time someone tries to check in her code, all your tests run automatically, and any failure blocks the commit. You have to fix the code (or the test) before you're allowed to check in your code.
  • trigger all your tests automatically, including your integration tests, at the top of your release or build script. The release or build is blocked if any test fails.
  • use a bootstrapping framework or wizard to generate boilerplate code, including matching unit test code, for every class you write. The less code you have to write, the more time you have to work on the good stuff. Ruby on Rails or Django are such bootstrap systems; they're easily extended to add boilerplate unit test code.
  • have your unit tests create persistent, semi-random test data in your dev database. Every time you run your tests, you get more data in your development database, which makes your application more realistic during testing and can uncover issues you only run into under actual use conditions (e.g., you might realize what a mess your UI is when it tries to display 250 items on a single form).
  • have your unit tests obliterate the test data in your dev database every time they run. This weans you from over-reliance on test data, which can be handy if you're shipping a brand-new product with zero user data on launch day: you consistently get to interact with the same product your early users get to see on day one. Yes, this is exactly the opposite of the previous point; use your judgment.

There are many other approaches, including forgoing unit testing altogether, and sometimes that might be just what the doctor ordered. Don't be afraid to try new things, nag at your colleagues (not too much), drop what fails and pursue whatever works for your product and organization. And by all means share your experience--open-source processes are just as vital as open-source software.