Ted’s Rants and Raves by Ted M. Young

November 22, 2009

How To Do Your Best in a Technical Interview, Part II: Questions

After I wrote yesterday’s blog, I knew I’d forgotten something, but forgot what it was that I actually forgot (I believe that’s first-order forgetting). Now I remembered (actually I remembered during this morning’s run): questions. Not my questions (as the interviewer), but your questions (as the candidate). Maybe it’s inexperience, but since we (Guidewire Software; we’re hiring!—plug, plug) have mainly been hiring senior (as in experienced and skilled, not older) people, I’m amazed that I don’t get asked in-depth questions about our development process, or even about the day-in-the-life of an employee at my company. After all, you should be interviewing the company just as much as they’re interviewing you. After all, you can’t just assume that it’s a great place to work, right? I’ve made that assumption in the past, and I’m too old to put up with certain practices, such as lengthy code reviews before checking code in (I’d prefer to pair program).

So, what are some good questions to ask? I’ll supply some of the questions I used to ask when interviewing (as a candidate) and those I would like to hear in a future blog entry, but I’d rather you give some thought to the kinds of questions you should come in with. Think about what you’d want your day to be like as an employee of the company, then ask questions relative to that ideal. Obviously you’ll never find an ideal workplace, but it’s up to you to find out on which axes the company is not ideal and whether you can live with that for the next 3-5 years.

The Best Question I’ve Never Heard

OK, I’ll give you one great question that I have yet to be asked (and this is after doing 12+ years of interviewing!): how many people have you referred to the company and how many of those have been hired? My answer would be 5. That will tell you a lot about how me, the interviewer, likes the company, more than a typical question I get, i.e., how long have you worked at Guidewire. There’s a world of difference between me working somewhere for a period of time and being willing to ask people I know and respect to work at the same place.

November 21, 2009

How To Do Your Best in a Technical Interview

I’ve been meaning to write this post for a while, but after some frustrating interviews, I was motivated to finally put it down into words.



We’ve been interviewing a lot lately at my company (Guidewire Software, in case you’re interested) and I’d like to offer some tips on how to do your best. Note that I’m not going to tell you "how to succeed" or "how to get the job", because that will depend on your talent and skills. What I can tell you are the things that will allow you to make the most out of those talents and skills.

1. Communicate. In fact, over-communicate. If I’m interviewing you, tell me why you’re doing what you’re doing. Don’t make me guess. Don’t make me ask.

You may be the best darn programmer around, but if you’re thinking quietly and writing on the whiteboard in total silence, and then you make a mistake (and you will!), I won’t be able to help you. Just like in school where the motto "show your work" helps you get at least partial credit, if you just showed the answer it becomes either Pass or Fail—not where you want to be. So, if you tell me what you’re going to do and why and lead me through your thinking, then I’ll be much more willing to give you some hints or help and I’m definitely going to get a better sense of how you solve problems than if you keep your thoughts inside. As an "Introvert" (on the Myers-Briggs scale), I know that this can be hard, but if you can’t do it in an interview, then how do I know you can do it on the job?

1A. Verify assumptions.

This is the "be a good listener" part of communication. Repeat back what you think you’ve heard from me and make sure that agrees with what I said. For example, saying "so some other code will instantiate my object and I don’t have to worry about that, right?" is a good thing to do, because that may be completely wrong, but at least you found out before you started.

2. Admit when you don’t know something.

It’s much better for you to say "Y’know, I’m not really familiar with X" or "I don’t know Y" than to try and fake it or muddle through. If you admit you don’t know something, it’s unlikely I’ll hold it against you (unless you say "I don’t know Java" when the position clearly requires Java and you have Java on your resume). But if you push on through when it’s clear that you don’t really know it, I’ll be concerned that you’ll do the same thing on the job and not ask for help and therefore make serious mistakes.

3. Admit when you’ve gone in the wrong direction.

Similar to #2 above, but I’ve seen interviewees bomb when they keep pressing forward with a solution that’s not working or won’t work and they know it. If you’ve followed #1, I probably wouldn’t have let you go down that road so far.

4. Check your work.

I’m amazed (or dismayed) at the number of folks who write a bunch of code on a whiteboard and don’t read through it to see if they missed anything. Take a few minutes to read through your code and make sure there’s at least not anything obviously wrong. Pretend you’re the computer and execute your code.

5. Know how to write tests.

Seriously. In Java, main() methods with System.out.println()s are not tests (this isn’t 1996, y’know). One test for your code is not enough. 3 tests for 4 different classes is not enough. Naming a test "testValidation1" and "testValidation2" is going to make me wonder about how you name things (whiteboarding is a bit different, which I’ll talk about in a bit). In an interview I won’t push you to do TDD, but you have to know how you would test your code, since that’s as much part of the job as writing the code in the first place.

6. Know how to whiteboard.

Don’t write out every single little thing on a whiteboard. It’s perfectly fine to say "and then I just do more of the same here" or "normally I’d give this a name such as testWhenUserLoginFailsAnAuditLogEntryIsCreated, but I’ll just write testLoginFails". Time is of the essence in an interview and you don’t have time to write compilable code. As long as you’re following tip #1 and communicate well, you can take a lot of shortcuts on the whiteboard.

There are other things, but if you follow these tips, especially #1, the rest is up to your ability to actually program.

November 2, 2009

PragProWriMo: Day 1

Filed under: General Rant

If you’ve followed my tweets, you already know that I’m participating in the November PragProWriMo, or the Pragmatic Programmers Writing Month. It’s not a contest or anything, but it is an opportunity to start writing what might become a book, or just a series of blog posts.

Note that these are not really blog posts, or even self-contained tidbits, but just what I’ve happened to write on that day. So, while you can feel free to comment, I’ll not really be paying attention to the comments and certainly expect things to not be well-written, let alone make sense without additional context. This is simply a way to allow people to see my writings as soon as they’re written and nag me if I miss a day of writing.

Day 1


Fluent Testing

ATDD, or Acceptance Test-Driven Development is one of the more recent techniques in developing software. The idea is to use code-based acceptance tests instead of English-based specifications or requirements. While it seems that English accetpance tests would be easier to write, in fact, they are more difficult to write well. It’s quite hard to be precise in a natural language where words are often ambiguous. For example, in this English-based acceptance "test"

* Filter searches on the Account number and the Policy number

The context here is a text field for a "filter" that limits the records that are shown. This simple statement can be interpreted in different ways. Before reading my interpretations, think about how many ways you could interpret it.

1. Text entered in the filter text field is used to search in the account number field, the policy number field or both.
2. The text is searched for in both the account number and policy number fields and must be found in both in order for the record to appear.
3. The filter text is used to search in the account number field, and if no records are found, then search in the policy number field.

You might be thinking that this is obvious and should have been stated more precisely when this requirement was discussed. However, it’s very difficult to always express the intent of requirements with enough precision on a consistent basis without missing something, or contradicting some other requirement. Even if you do end up with sufficient precision, you’ll likely end up with a 300 page requirements document that, I guarantee you, will end up being interpreted differently than from how it was intended. Since the whole point of agile development using story cards is to discuss these details (as in a "token for conversation") on an as-needed basis, how do you make sure that the developers don’t forget the details as they’re developing the code? The answer is executable acceptance tests.
The problem I’ve seen in coming up with a good form for executable acceptance tests (no, I won’t call them EATs) is that in trying to formalize the English, you end up with something that is close enough to English that people understand the intent, but not quite enough like English so that people find it hard to write. The solution here is a fluent testing API. Something that is not only precise, but can be executed against production code once the code has been written and, going with the ATDD technique, use by developers while they’re writing the code. For example (using JUnit in Java):

  public void sortByInvoiceDatesIsVisibleOnlyWhenGroupingByInvoiceAndByItem() {
    openCreateDirectBillPaymentPage(account)
      .groupByInvoice()
      .aggregateByItem()
      .assertSortByInvoiceDatesIsVisible("Sorting by invoice should be visible for Group By Invoice Aggregate By Item");
  }

 

It’s true, this test only checks that the "Sort By" selection element is visible, depending on various combinations of other selections ("Group By" and "Aggregation"), but it’s also very explicit under what conditions it should be visible and, most importantly, is not that much less readable than if it were written in English. It’s hopefully clear that after opening the "Create Direct Bill Payment Page", we "group by invoice", then "aggregate by [invoice] item", and finally, the check (assert) that the "Sort By" element is indeed visible. The string passed to the assert is the failure message, and helps describe why the assertion should be true.
There’s an additional feature that puts this over the top, and that’s an IDE’s ability to provide a list of choices of methods that are available on each object, aka, code completion. This allows the executable acceptance test author to be guided by the code completion of methods that are available at each point. This turns out to make test writing much easier than if it were an /external DSL/, because the choices are constrained by the objects that you’re working with, i.e., on the DirectBillPaymentPage, the IDE will "tell you" that you can do "groupByInvoice" and "aggregateByItem" by showing those methods as auto-complete options.

 

Get free blog up and running in minutes with Blogsome
Theme designed by Jay of onefinejay.com