Blog

Smart, gets things done, opinionated

I've been helping a client with their technical hiring. They need more developers and it's notoriously hard to select the good ones. It's extraordinarily difficult to tell the difference between someone who sounds good and someone who is good. It's practically impossible if you're not a developer yourself; that's where I came in.

One standard tenet of screening programmers comes from Joel Spolsky:

How do you know whether to hire someone? In principle, it's simple. You’re looking for people who are

  1. Smart, and
  2. Get things done.

That's it. That's all you’re looking for.

That's definitely a great starting point. But I think the list needs one more item: opinionated.

It's not enough to be smart and to get things done. I've interviewed a number of candidates who had a strong history of both. But as soon as I tried to get an opinion out of them I found myself stuck in a bog of equivocation.

Taste

Sometimes the opinions are matters of taste. I like to ask candidates what websites they like, what tools they use, and what they like about them. The last part's the key. I'm not trying to bond with you when I ask what websites you like; I'm trying to get a sense for your taste, your critical eye, and your ability to intuit what's under the bonnet. I'm not going to rule you out for using NetBeans when I like vim; if you're interviewed by someone who will, you probably don't want to work there anyway. I'm trying to figure out how you approach problems, what crutches you have1, and how much thought you've given to how you work.

Here's an example: you interview two candidates and ask them for their favourite websites. Both say they like Twitter. "Why?" you ask. Candidate A mumbles something inoffensive about how he likes talking to his friends. Candidate B talks about the problem of distributing messages to millions of people, near-instantaneously, pushing the data to web browsers and mobile devices. Who's the stronger candidate?

But delivery is important, too: what if candidate A had spoken confidently about how Twitter's changed how he interacts with his friends, how the public interacts with celebrities, and completely reinvented breaking news: all of a sudden it's not so clear-cut. One candidate is more focused on technology, the other on sociological impact. The right choice depends on your company & the job role, but now you've got more information to make the decision.

Technology

Sometimes the opinions are about technology. I always try to include an open-ended design question in an interview; lately I've been using "How might you design a system that lets people play Monopoly with each other over the internet?"2. The openness is a feature; good candidates will ask a few questions before diving in, and there are lots of dramatically different ways of answering.

One candidate proposed a peer-to-peer solution. That's uncommon, but not insane. You can make that work. But he couldn't explain the strengths or drawbacks. He couldn't explain why he'd chosen that instead of a client-server approach. "There's a number of factors involved" isn't an answer if you can't name some factors. I'm totally fine with a candidate changing their mind! A great answer would be "I started this as a peer-to-peer solution, but now I see problems with synchronisation and preventing cheating. So, in retrospect, I think a client-server model would be better." Unfortunately I couldn't get anything out of this candidate; I encouraged and cajoled, but he stuck with neutral platitudes.

The best people I've worked with all have strong opinions about how software & the Internet should work. We don't always agree, but being unafraid to express an opinion means we can discuss a problem and find a decent solution.

There's one final nuance: the people you want have pragmatic opinions and respect other points of view. I don't want people who insist they're right, don't listen to others, or ignore reality. Sometimes there are valid reasons to cut corners, do a hacky job, or do something that stinks. You need people who will roll up their sleeves and get stuck in. But equally, you should expect to hear about how you screwed up, how the situation should never have reached that point, and how to stop it happening in future.

I'm a developer. What am I supposed to do differently?

  • Be fearless in interviews. Your goal is to demonstrate your skills & knowledge, not avoid offence. Let's say you discovered the company's using a PHP-based stack, your CV says you just migrated from PHP to Java because PHP was unscalable, and now the interviewer's asking you what the problem was. Trust me: he's not feeling hurt. He's not saying that PHP's great and Java's crap. He wants to know what the problems were, and how changing language fixed them. Don't apologise, or equivocate, or say things like "That's just my opinion." It's obviously your opinion. Explain why you hold it.
  • Look at things with a critical eye. Pick a website or app you use daily. What's good about it? What sucks? If you could wave a magic wand, what would you change? What would you change it to? Why do you think it's not that way already? If that change made things better for you, would it make things worse for others? If so, do you still think it should be changed?
  • Ask questions. An opinion isn't a snap judgement, and it's only useful if it's been thought through. Interviews aren't interrogations – you get to ask questions too. Don't immediately jump into an answer if someone asks you to design a system; you don't know enough yet. How many users are we expecting? How technical are the users? Are there budget constraints? Is it web-only, desktop-only, mobile-only, or some combination thereof? Is performance an issue? Is it more important to optimise for server-side performance or client-side performance? Can we presume that all our users speak English? Can we trust our data to be valid? Can we hand-wave past a particular bit for now, or would you like me to outline that first?
  • Work on your interpersonal skills. Disagreement is fine. Discussion is great. But you must express that disagreement constructively, otherwise you're just being an asshole. Dale Carnegie wrote the classic book on this; The Usual Error is also worth reading.
  • Sometimes you have to watch the world burn. Maybe your interviewer is offended by your dislike of PHP, your belief in semantic HTML, or your system design. Be open to the possibility that you're wrong, and be humble, but remember the interviewer's done you a favour. Do you really want to work with someone who isn't open to other people's ideas and won't listen to explanation? Do you want to work somewhere where disagreements are settled with "I'm right because I've been here longest?"

  1. Everybody has crutches; they're not a bad thing. Why wouldn't you want the computer to make your life easier? Some of my favourites include syntax highlighting, auto-indentation, and auto-lint-on-save. IDE users probably like automated refactoring, inline help, and code generation.  ↩

  2. Shamelessly lifted from Reginald Braithwaite.  ↩

My FAWM 2013 experience

Earlier this year, a Hackspace member offered the mailing list a free MIDI controller. I'd been considering taking part in FAWM – February Album Writing Month – and this pushed me over the edge. I accepted the MIDI controller. I signed up for FAWM and announced my intentions. So how did I do?

Not well.

FAWM sets a simple goal: 14 songs, 28 days. People take part for all kinds of reasons and have different criteria for what constitutes a song. It's a challenge, not a competition: you're only accountable to yourself. Personally, I wanted to write chiptunes – 8-bit/retro computer game music. I've admired the genre for a long time, and I messed around with making some a couple of years ago. But I didn't manage more than a couple of 20-30 second snippets back then. It taught me how to use the software/hardware (I'm working on a separate article about that), but this would be the first "proper" music I've written since my GCSEs.

I wasn't expecting electronic music to be so time consuming. At full speed, with no blocks on inspiration, I could make one track a day. But that's an entire day of effort; 8-10 hours doing nothing else. More realistically, I could write 1 song every 2 days. I thought this would be enough, especially if I worked hard on weekends. But by February 10th I'd only managed 3 tracks and I knew I wasn't going to catch up. Between work, Valentine's day, & a friend's week-long visit from the USA I was never going to hit 14 songs. I intended to make a couple more songs with what was left of the month, but I wasn't enjoying it. So I gave up.

I've got a few half-written tracks left over, including one that's a "proper" chiptune (written with the Gameboy's hardware limitations in mind). One of my worries was that although I was using simple synths and tone generators, I wasn't making "real" chiptunes. The chiptune police would kick down my door, NES zappers drawn, shouting "Imposter!". Thus I tried sticking a bit closer to the original medium. I'd like to finish them off at some point, but I'm waiting for the desire to return.

So here they are: 3 songs that were meant to be chiptunes but probably count more as "chiptune inspired":

Would I do it again next year? Probably not. The FAWM community itself is amazing and I really appreciated the encouragement I received. But I don't think I can cram 14 chiptunes into one month without putting everything else on hold; even if I could, that doesn't seem like a fun activity. If I did take part again it would probably be something acoustic.

A brief dose of futurism

Much has been written about Google's self-driving cars. To recap: Google has started publicly demonstrating a car that can drive on public streets all by itself. It's deeply impressive technology, and is a manifestation of a decades-old prediction. Cars that drive themselves! No more congestion! No more accidents! Tomorrow's world today!

Because this technology is still stuck in the lab, demonstrated under carefully controlled conditions, my instincts are to dismiss it as speculation or decades away. But I've learnt that my instincts are basically slaves to my lack of long-term imagination. When I was 14 I read about e-ink and flexible displays. They seemed far-fetched then, but Kindles have been around for years and flexible displays seem just around the corner. Self-driving cars are probably closer than I think.

So how would that affect the tech world? Why would Google bother? Google say it's to advance society, which is probably partially true. But to me, the interesting part is the data. A self-driving car necessarily involves a whole bunch of sensors and cameras. A GPS and internet link are practically a given. So when this technology makes it into commercial vehicles Google's going to have a huge competitive advantage when it comes to maps and local data.

You won't need a dedicated street view team because you can use the imagery from people's cars. 3D maps like Apple's come from laser rangefinders and cameras, both of which will be built in to people's cars. Traffic flow data already comes from people's phones; it's a tiny step to pull it from the car directly. Updating maps with new/missing/altered roads is a similarly small step. As mobile bandwidth increases, the idea of a live streetview might actually be feasible. Scary as hell, but feasible.

This is all obviously good news for Google and good news for Google's users, but mapping competitors should worry. It's not about taking the human out of the process; it's taking the employee out of it. Other companies would have to pay people to gather data that Google's harvesting ambiently.

And now something completely unrelated

For a while I've been trying to figure out how to fit this thought into 140 characters, and failed:

You may think that with iPads and private space travel and drone strikes that we're living in the future. But your washing machine's UI begs to differ.

But trying to get a thought into a tweet can leave it open to misinterpretation. Is it a less-pithy version of "The future's already here, it's just not very evenly distributed"? Did Warren Ellis pre-emptively skewer it? The answer to both questions is "Yes and no."

My intention wasn't to normalise the age we're living in. I was trying to express the concept that some things are mind-blowingly amazing, whereas others remain mundane and niggling. I thought the great promise of the future isn't a few giant things, but a thousand tiny ones. Maybe we're condemned to overlook them; progress itself is a thousand tiny steps rather than one giant leap.

The shape of my life now is radically different compared to my life in 2003. And yet I still have to do my best Egyptologist impression when doing the laundry. A courier can't be more specific about a delivery time than a 12 hour window. I still buy pasta from the supermarket and find 3 unopened packs when I get home.

All I'm saying is there's still some room for improvement.

Help! Chrome's ignoring my Cache-Control headers!

You're a web developer and you've discovered your web app's sending a lot of static assets over the wire with every page load. These are static assets, so there's no need – they don't ever change. If you configure your web server with the right headers, you can tell browsers to cache them forever. Pages will load faster, and your server will be under less load. So you create a .htaccess file with something like this in it:

<ifModule mod_headers.c>
Header set Cache-Control "max-age=604800, public"
</ifModule>

You load your website and watch the network inspector in Chrome. You hit refresh, but you still see loads of requests for your static files. You hit refresh again. Maybe it cached this time, or maybe not. But refresh again, and everything gets retransferred! You start looking at individual requests. The headers are being set properly. You read the spec, and everything looks fine. Other browsers are respecting the headers and doing the right thing. What the hell's going on?

You're not going mad, and you probably haven't messed up. Chrome's trying to be helpful: it can't tell you're a web developer, and it doesn't know you're tapping that refresh button to test the server. Chrome's detecting the multiple refreshes, presuming you're doing it because the page is broken, and reloading everything from the server. I haven't figured out the exact behaviour it uses to do this, but it seems it involves whether you click through to other pages or not. As a result, you'll get more reliable testing if you navigate around your app a bit rather than clicking refresh.

Trick or Treat?

I've lived in London for 6 years now, but tonight was the first time I was visited by trick-or-treaters. Every year prior I indulged the Guardianista fantasy of making friends with the local youth – and the Daily Mail fantasy that I must bribe my way to safety via sweeties – by buying a giant bag of fun-size chocolate bars. And every year prior nobody came. I was left with broken dreams and a lot of chocolate.

But tonight was different. I arrived home late, and had just collapsed on the sofa when there was a sudden knock on the door. Standing up, I gazed down the half-lit hallway to see the silhouette of a teenager in a bad costume. "I'll pretend I'm not in," I thought. Then a couple of braincells kicked in and I realised the lights were on. I had to answer it.

I rushed to the kitchen and looked in the cupboard. Nothing. No sweets, no pastries, no chocolate. But there was one thing. One vague possibility. I grabbed it and headed to the door.

When I opened it the two teens had cut their losses and were halfway across the road, but they turned around when they heard the door open. "Err, trick or treat?" one asked, hopefully, not moving closer. And that's when I found myself possessed by a spirit infinitely older than my own, speaking words I'd promised myself I would never utter.

"I'm really sorry, I've just got home from a long day at work and I haven't got any sweets in the house," I said. "But I can give you this pomegranate if you wanted."

At some point – some point in the past year – I have changed from the person who buys sweets for Halloween to the person who offers trick-or-treaters fruit. Children tell playground horror stories about people like me. I can make excuses and plead special circumstances, but let's face facts: they asked for sweets. They got fruit.

The ghouls shrugged non-committally and walked off, and I thank them for that. No egging of the house, no shouted abuse. Perhaps they understood that the crashing realisation of what I have become is the greatest trick of all. But they probably just thought they'd try next door.

My biggest co-incidence

It's 2005. I'm in Australia, technically. I'm on a boat sailing round the Whitsunday islands with 30 other people. We put to sea for 3 days. 3 days of beautiful scenery, deserted beaches, and giant card games below decks. 3 days of diving, sunbathing, and talking. 3 days of whales. 3 days of no shaving, no warm running water, and no phone signal.

Sunrise over the Whitsunday islands.

I got talking to one of the English women in our group. We soon discovered we'd gone to the same university. But not only that: at the same time. But not only that: we had some friends in common. But not only that: I had been to her house. One of our friends in common was her old housemate, and we'd met there for pre-club drinks. And here we were, in the middle of nowhere, on the opposite side of the planet.

My laser-cut iPad stand

I sometimes use my iPad as a second screen – an auxiliary display for alerts (if you're a masochist) or side-channel apps (to do lists, calendars, Pomodoro timers, etc). If you've got a smart cover you can use it as a stand, but otherwise you have two choices: buy one, or make one. I made one – or actually two. One for home, one for work.

I started with a design on Thingiverse and made some minor changes: I altered the slot size to work with 5mm Perspex and extended the rear feet because I was worried about the stand's stability. After a few rounds of trial and error on the laser cutter, I got a snug fit and a working stand. I used some scrap Perspex for mine, so there are some small cut-outs on the bottom edge.

If I were doing this again I'd either make the rear leg rounded so the notch wasn't supported with such a thin bit of Perspex (Perspex shatters easily) or make this out of something like MDF or ABS. I've used this stand for over a year on a daily basis and it's not failed in use, but I did drop one and the foot broke at the narrowest part. I'd also consider raising the iPad a little further off the desk, so you could charge it in a portrait orientation.

My main use case for this these days is to display Concentrate! while working, though I've also used it to keep an eye on the news at times of civil unrest and media inquisitions.

Download the DXF file to make your own, or check it out on Thingiverse.

Workarounds for a couple of unetbootin bugs

Bug number one: a corrupted Ubuntu installer

The symptom
the Ubuntu 12.04 alternate installer fails when installing the base system, telling you that the disk is corrupt. You'll get an error message along the lines of "problem reading data from the CDROM".
The problem
Unetbootin/7zip have known bugs with long file names/file paths. These have been open for a couple of years, so don't expect them to be fixed soon.
The solution
Use Ubuntu's startup disk creator instead. You can either run it from the launcher or as usb-creator-gtk from a console.

Bug number two: your DBAN USB key won't boot.

The symptom
When you try to boot from your DBAN USB key you get the boot menu, but attempting to boot any of the entries fails with the message "Could not find ramdisk image:/ubninit".
The problem
Unetbootin doesn't configure syslinux.cfg properly.
The solution
Edit syslinux.cfg, replacing all occurrences of "ubninit" with "ISOLINUX.BIN" and the one occurrence of "ubnkern" with "DBAN.BZI". It's case sensitive, so make sure it's all uppercase.

Bonus DBAN/Unetbootin tip

Unetbootin creates a default boot option for DBAN that includes the --autonuke flag. This means your DBAN key is especially dangerous – if you boot off the key, either by accident or design, it'll wipe all disks without any human intervention. Avoid this by removing the --autonuke option from the section marked label unetbootindefault while you've got syslinux.cfg open.

Everything I know about selling on eBay

I've been selling a lot of stuff on eBay as part of an ongoing decluttering/minimalism drive lately. I've given a few people this braindump in person, but it's probably more useful as a written list. All of these tips apply to eBay auctions – I've got little experience with "Buy it Now" items.

Make sure it's worth it.

By the time you've photographed, uploaded, form-filled, written about your item, packed it, addressed it, and taken it to the post office you will have spent at least an hour per item. This isn't a good use of your time if it sells for 99p. (I sometimes list stuff that I know isn't going to perform well if it's not suitable for charity shops and/or I'll feel guilty about throwing it away.)

What does and doesn't sell?

Things that sell well:

  • Photographic equipment
  • Computer equipment
  • Anything that would make you go "Oooooh" at a jumble sale.

Things that sell OK:

  • CDs
  • DVD boxed sets
  • Actually collectible collectibles
  • obsolete computer hardware
  • small organisational things (wallets, purses, folders, cases). I don't understand why, but they seem to.

Things that don't sell:

  • Books
  • DVDs
  • Chargers and cables
  • Small furniture.

Don't get your hopes up.

Searching eBay for completed listings similar to your item will give you an idea about what it's really worth. You may think it's worth £100 but if everyone else's sold for £40, yours will sell for £40. A good listing and a bit of luck might help you do a bit better, but it might also do a bit worse.

Buy a scale, and use eBay's postage calculator.

I bought a small hanging scale for £5 and weigh everything I'm selling. If you weigh the item with a jiffy bag you'll get an exact cost for postage. I recycle envelopes and boxes from other purchases, but you can also buy packaging from pound shops and on eBay itself. Don't buy from the post office – it's really expensive.

List items for free.

If you your listing starts at 99p and only has one photo then you don't pay anything. You can use custom HTML in the description and include extra photos that way, presuming you have somewhere to host them. Beware! Flickr explicitly blocks image links from eBay referers.

Place 10 day listings and start them on Thursday evening.

It's worth spending 6p per item to schedule all your listings to start on Thursday evening. They'll finish on Sunday evening – a time when people are at home and likely to be looking at the computer. It also gets two weekends to attract bidders and watchers. Theoretically you only have to go to the post office once, on Monday, but there's always one arsehole who won't pay you until Tuesday evening.

Buy it Now probably isn't worth it.

The Buy it Now option disappears as soon as you get your first bidder. People will make a 99p bid in to stop other people buying it outright.

Good pictures help, lots of pictures help.

If it's just a book or a DVD this isn't important, but if you want to sell something that's worth more than £50 then photograph it from every angle and write a lot about it. You'll get more watchers and bidders that way. If you can include photos of your item working, then do so.

Cross-link if you like, but it doesn't work.

If I'm selling a bunch of similar items then I add links to the others in each listing. Other books by the same author, a laptop case for a laptop, or a keyboard that matches a mouse; that kind of thing. I've also got a standard boilerplate that links through to my other items for sale. Despite this, it's very rare to sell more than one thing to anyone. It's probably not worth the hassle.

Most bids happen in the last few minutes.

It's not unusual for bids to trickle in for the first 9 days and only pick up in the last few minutes/seconds. If you've got a lot of watchers – say, more than 15 – then this becomes more likely. Don't panic if you've not hit your expected price before the last day.

Fill out the proof of postage certificate at home.

You can save yourself some time at the Post Office by filling out the certificate at home. Sometimes the counter staff will give you a pad for free, but you can also order over the phone or online. I've also managed to order via email but I've seen suggestions that this only works for business addresses. So far I've never had to use the proof of postage, but it's reassuring and definitely worth doing for larger trades. PayPal and eBay are biased towards the buyer, so if there is a dispute all documentation helps you.

Take a book to the post office.

There will be queues. You will be bored. Take a book.

How to run a script when a filesystem gets mounted on Linux

I wanted to run a script when a filesystem gets mounted on my Ubuntu server. I thought this would be a common task but it took me a while to find the answer. Some people suggested using udev, but udev responds to device changes. If you're trying to trigger something like a backup when you plug in a USB drive, udev is the way to go. But it's no use if your device is always connected but not always mounted.

When my server starts, /home isn't mounted automatically. /home's on an encrypted filesystem, and the system runs without a keyboard and monitor, so I want it to boot up normally without /home and I'll mount it the next time I login. When /home becomes available, it should start a media server and NFS sharing.

It's not well documented, but it's easy under Ubuntu. You need to use upstart and create an init script. These live in /etc/init/ and can have any name ending in .conf. You can either write your script directly in the init script, or call another script elsewhere. As I only had a couple of tasks to perform the behaviour's more obvious if it's in the init script. Here's what mine looks like:

# mounted-home - Trigger actions when home becomes available. 

description "Trigger actions when /home becomes available." 

start on mounted MOUNTPOINT=/home 

task 

script
    /etc/init.d/forked-daapd restart
    service nfs-kernel-server restart   
end script

You could also write a complementary script that stops these things when the home directory is unmounted, but I don't normally unmount my home dir and there's no harm in running this script repeatedly – the restart command will start it if it's stopped, or bounce it if it's already running.