Improving the Interviewing Experience

One of the great things about getting honest and timely feedback is the ability to use that to improve things. So how about the interviewing experience? Can we get enough useful feedback to improve in the right ways? I recently tweeted

and wanted to expand a bit on what I was referring to in this context.

When you’re interviewing a candidate, you have power: you decide which questions get asked, how the candidate should answer them (whiteboard? laptop? paper?), what an acceptable answer is, and, ultimately, whether you’ll recommend the candidate to be hired. Expecting the candidate to push back on any aspect of the interview (“I’d rather do this on a computer, if that’s OK”), or expecting honest and useful feedback after the interview (“How’d that go? Anything you’d suggest we do differently in the future?”) is asking for quite a lot from someone who’s sole purpose during the interview process is to impress you and make you, the interviewing team, feel good so that you’ll hire them. You may get honest and useful answers from the rare person who is either unaware of the power imbalance, doesn’t care, or is super-confident, but it’s not something you can count on.

If you want real feedback for your interviewers, you can ask the people you’ve hired, but that’s a bit biased, because I think it’s important to make sure the experience is good for all candidates, not just the few who are hired. Asking those candidates to whom an offer was made, but not accepted, can be useful, as well as those who ended up not getting an offer, but none of them have any incentive to take the time and provide the feedback (and there might well be some negativity from those who feel the process was in some way unfair).

In my experience, a useful way to get better is through mock interviews. Practice being both the candidate and the interviewer in as realistic a setting as possible. It can be hard to get into the role-playing aspect, but it’s important to simulate the real thing as much as possible. You can also bring in friends to provide a more outside-in opinion on the process (and then take them to lunch/dinner/drinks at the company’s expense for their time).

I don’t see enough attention being paid to the whole interview experience (IX?), when that’s the main — if not only — way that candidates will be evaluating your company. We generally are better at evaluating and improving the user experience of our products and services, especially by doing usability testing, so why not pay as much attention to your candidate’s experience?

Fixing an Incorrectly Rotated Monitor for MATE on Ubuntu 14.04

I recently installed the MATE desktop environment on my Ubuntu 14.04 machine (because I wasn’t happy with other ones I tried). However, for some reason, the single monitor I have connected would come up rotated counter-clockwise (aka “left”). The quick solution that I found was to do

xrandr -o right

Which fixed it. Unfortunately, after I rebooted (due to a power outage) and then logged in, the monitor was rotated again. I got tired of doing the xrandr each time, so after some searching around (getting sidetracked by X11 configuration) I found that MATE looks at this file: ~/.config/monitors.xml, which looked like this:

The key part was line 14 with the <rotation> element, which clearly was wrong for my current setup. I changed the element to be normal, and then restarted X11 (Ctrl+Alt+Backspace) and now the monitor no longer rotates!

Making JSON Strings a bit easier to write in Java

One of the annoying things about writing Java unit tests that involve JSON is that standard JSON uses double-quotes for property names and string delimiters. This means you end up writing:

Using the escape \" as the way to embed a double-quote. I find this annoying to read and write, and I thought it’d be easier if I could just use another, more readable, character instead and then do a replace. So I did:

And thought that it was more readable. I specifically use the back-quote ` instead of a single-quote ' because single-quotes are often used in text (it’s, for example), but back-quotes are less often used, but still have a quoting “flavor”.

CORS for Dropwizard 0.7.x

In a previous post, I showed how to add the CORS (cross-origin) filter to Dropwizard 0.6.x. I forgot to make a post when I upgraded to 0.7.1, since the mechanism for registering the filter has changed. So, if you’re using Dropwizard 0.7.x (not yet sure about the forthcoming 0.8.0 as I haven’t looked at it), here’s how to register the CORS filter:

From your Application class’ run() method, call configureCors(environment), i.e., pass the environment to this method:

Thanks to Mike Clarke for commenting on my previous post, which reminded me to write this one. He posted a similar solution here: https://stackoverflow.com/questions/25775364/enabling-cors-in-dropwizard-not-working/#25801822. Also, thanks to Vitor Reis for pointing out the missing import for EnumSet (I’m so used to IDEA’s auto-import, that I didn’t even notice it being missing).

Changing the networking for a VirtualBox VM without restarting it

I’ve been using VirtualBox for a lot of things, most recently for hosting an OpenStack deployment that leverages “DevStack”. Since I wanted the OpenStack deployment to be able to access the outside world (in my case, to install Docker and the nova-docker driver), I set up the network to be NAT. However, that means that I couldn’t access the OpenStack guest, and I didn’t want to re-start the VM, so I found that I could make some changes to the VM while it’s running using the controlvm command with vboxmanage.

For example, so be able to SSH in, I set up a port-forward so that connecting to my localhost:2222 would forward to the VM’s port 22 (it’s running on IP 10.0.2.15):

vboxmanage controlvm "Icehouse" natpf1 "guestssh,tcp,127.0.0.1,2222,10.0.2.15,22"

“Icehouse” is the name of the VM (used to identify which VM I’m modifying), “natpf1” is the 1st virtual network card; “guestssh” is the name of the rule (you could leave it out, but you may as well give it a useful name); then the local IP address (if you leave it blank, then all incoming traffic is forwarded, but for my use, I only need to forward traffic from me); the local port to use (I didn’t want to stomp on my own machine’s port 22, so I used 2222); the remote IP address and remote port.

For more details, the NAT port-forwarding configuration parameters are documented here: https://www.virtualbox.org/manual/ch06.html#natforward and controlvm itself is documented here: https://www.virtualbox.org/manual/ch08.html#vboxmanage-controlvm.

Handling CORS in Dropwizard and Jetty

[Update Sept. 12, 2014: If you’re looking for Dropwizard 0.7.x support, the mechanism has changed from the 0.6.2 method below, and I posted the new info here. Thanks to Mike Clarke for prompting me to update this.]

I’ve been developing an internal application that uses AngularJS on the front-end, and Dropwizard (currently 0.6.2, but will be upgrading to 0.7.0 soon) on the back-end. I’m using IntelliJ IDEA which has a “Live Edit” feature that instantly reflects changes in the front-end code in the Chrome browser. However, since this requires a little web server to run, it ends up using a different port (e.g., http://localhost:63342/) than the back-end that’s providing the API (e.g., http://localhost:9090/). This means that I’m doing cross-origin access, which the browser prevents unless the back-end says that it’s OK by putting the appropriate headers in its response.

The key to getting Dropwizard’s embedded Jetty to do the right thing is to add the CrossOriginFilter class to the Dropwizard environment. First, you’ll need to add a dependency on Jetty’s “servlets” module like so:

For Dropwizard 0.6.2, the version of Jetty being used is 8.1.10, so you can set the Maven property like this:

Or, if you prefer, you can put the version directly in the dependency itself, though having properties makes it easier to update things later.

Once that’s done, you need to add the CorsOriginFilter to the Dropwizard’s environment, so add this to your run() method inside your Dropwizard Service:

  • Line 1 specifies the filter class and sets the “URL Pattern” to apply to all URLs, i.e., /* and everything underneath. However, if you only wanted to allow a subset of your resources to be cross-origin capable and they were at http://host.example.com/webapi/, then you’d use /webapi/* for the URL pattern.
  • Line 2 indicates which origins are allowed access to the resources. Here I’m specifying that any calling domain can use the resource, since I’m behind a firewall, it’s the easiest to specify. If I only wanted http://www.example.com to access the resource, then that’s what I’d specify, e.g., .setInitParam("allowedOrigins", "http://www.example.com"). You can specify multiple domains by separating them with a comma.
  • Line 3 is the list of headers that can be sent from the client in a request when asking for the resource during a “pre-flight” request (see Mozilla’s docs on this for more). These are the common ones and should handle most situations.
  • Line 4 is where I got hung up for a while, since I thought I could use a wildcard ("*") to allow all methods, but, alas, it’s a list of allowed methods. In my case, I needed to support DELETE for some resources, so I listed all of the methods here.

AngularJS

On the AngularJS side, it’s pretty simple to ensure that CORS works by configuring the $httpProvider‘s defaults.useXDomain setting to true. For example:

Or, if you already have a config section, just tack on the $httpProvider like this:

Resources

Here’s some good reading on the topic of Cross-Origin Resource Sharing (CORS):