Acing the technical interview

If you want to get a job as a software witch, you’re going to have to pass a whiteboard interview. We all do them, as engineers–often as a part of our morning ritual, along with arranging a beautiful grid of xterms across the astral plane, and compulsively running ls in every nearby directory–just in case things have shifted during the night: the incorporeal equivalent of rummaging through that drawer in the back of the kitchen where we stash odd flanges, screwdrivers, and the strangely specific plastic bits, the accessories, those long-estranged black sheep of the families of our household appliances, their original purpose now forgotten, perhaps never known, but which we are bound to care for nonetheless. I’d like to walk you through a common interview question: reversing a linked list.

First, we need a linked list. Clear your workspace of unwanted xterms, sprinkle salt into the protective form of two parentheses, and recurse. Summon a list from the void.

(defn cons [h t] #(if % h t))

“That’s not a list,” the interviewer says. “That’s an if statement.”

“What else are lists,” you reply, your eyes flashing, “But alternatives?”

user=> (def x (cons 1 (cons 2 nil))) #'user/x user=> (x true) 1 user=> ((x false) true) 2

“What’s x exactly?” The interviewer makes every attempt to appear friendly. Answer at the REPL, but do not be deceived for an instant. They are not a friend. Your oath at the Front Desk forbade it.

user=> x #object[user$cons$cell__4431 0x3b89cc1c "user$cons$cell__4431@3b89cc1c"]

“To know a thing is to name it,” you advise. True names have power. The K language was invented by Ursula K. Le Guin, and is among the oldest and tersest forms of magic. To imbue a language with a letter of your own name is to give up an element of your self. Your own initials ache at the memory.

“Erm, OK, so how would you get an element out of this list?”

The expression in your mind is beautiful, unfurling like a red carpet underneath your bare feet. The Oscars were on last night, but you long for the kiss of different stars upon your naked skin, as when you dwelt in the mountains of Sørøya, and called the moon your lover. Except for the bounds check, you get it right the first time.

(defn nth [l n] (when l (if (= 0 n) (l true) (recur (l false) (dec n)))))

“Could you just show me, you know, a regular list? Like in Python?”

You grit your teeth, plant your feet against the floor, and dredge a pretty printer from the void. Your palms are calloused now, your eyelids limned with crystalline, soot-black snowflakes. Every action comes at cost. Pure functions are side-effect free.

(defn prn-list [l] (print "(") (loop [l l] (if (nil? l) (print ")\n") (do (print (l true)) (when (l false) (print " ")) (recur (l false))))))

No time for descriptive variables, examples, or docstrings here. In the whiteboard interview, time is of the essence. Pretend you are a Haskell programmer, as your grandmother was, before her continuation passed.

user=> (prn-list (cons 1 (cons 2 (cons 3 nil)))) (1 2 3)

The interviewer smiles, reassured. We are on, or at least above, familiar ground. “So, to reverse it, you’d…”

You seize his hands in yours, his mind a frantic clockwork unwinding, skittering ticker-tapeworm unraveling, pitter-patter heart askance and out of place, and in the ancient tongue, recite an epigram.

(defn reverse [l] (loop [r nil, l l] (if l (recur (cons (l true) r) (l false)) r))) user=> (prn-list (reverse (cons 1 (cons 2 (cons 3 nil))))) (3 2 1)

As you release your hold, he stutters something polite, and zips his hoodie to protect against the frost. There will be other meetings, but you need not participate. Send an eagle in your place.

They will refuse, of course, and ever so ashamed, cite a lack of culture fit. Alight upon your cloud-pine, and exit through the window. This place could never contain you.

Azzie
Azzie, on

I’d laugh, but that had happened to me

Spelling Troll
Spelling Troll, on

s/sieze/seize :)

Bill Smith
Bill Smith, on

Nice writing, Aphyr. Were you reading William Gibson last night?

Cesar D
Cesar D, on

this was awesome.

Blaz
Blaz, on

This was seriously and awesome read. Worth a goof and a chuckle.

Eric Fode
Eric Fode, on

<3

Nathan
Nathan, on

Pure awesome. Thanks for writing Aphyr.

zpojqwfe1wfhiunz
zpojqwfe1wfhiunz, on

@Bill, The William Gibson version would begin thusly:

It was hot, the night I burned the Seeker. Moths batted themselves to death against the humming neon signs just outside the single window in the cramped room. There were ancient electronics piled to the ceiling in here, hot new chipsets from Taiwan still unwrapped distributed unevenly amongst them. The Seeker put his hands on his hips, brushing aside the corners of his Sukajan jacket bomber jacket replica. "I heard you and Bobby were hotshots, once. Real.. artístes", he said, the last word paired with a smug grin. "Heard you could do things." "Things like what?" It's been 20 seconds and you've already wasted too many cycles with this guy. "Things like making lists, just, fold up inside themselves. Come out the other way around. Crazy things." You grit your teeth. The dex has left your system and you're starting to feel a massive drug deficiency coming on. "Crazy things cost money", you manage. The lists already unfurling in your head, you start typing as quickly as you can to hide the microtremors.
Your Fan
Your Fan, on

Truly sublime.

Paul
Paul, on

Excellent. Reminds me of something by China Mieville.

Aaron
Aaron, on

Not Gibson. He’s obviously been reading The King Killer Chronicles by Patrick Rossfuss. “To know the name of a thing, is to have power over it”.

Nice incantations btw.

mario
mario, on

DAYYYAAAAAM

Marty
Marty, on

I don’t know, I sort of prefer

(defn cons [h t] #(if (or (= 0 %) %) h (if (number? %) (t (dec %)) t)))
Ahmed
Ahmed, on

Someone has been reading Rothfuss :)

anonymous
anonymous, on

Nope, I need a false?. Better:

(defn cons [h t] #(if (or (= 0 %) (false? %)) h (if (number? %) (t (dec %)) t)))
Nijiko Yonskai
Nijiko Yonskai, on

After the candidate took his leave the interviewer being bombarded with questions by the holders of steak stared out from inside the bustling warehouse wondering if he would ever truly understand what a list really is.

doktorpaine
doktorpaine, on

Kyle, you beautiful, mad man.

I need to try this in my next interview. Perhaps with raw lambda calculus for shits & giggles.

anonymous
anonymous, on

A transliteration in Python, because why let Clojure have all the fun?:

#!/usr/bin/python def cons(if_true, if_false): return lambda which: if_true if which else if_false def reverse_but_as_list(generated_cons, the_list = []): if generated_cons(False) is not None: return reverse_but_as_list(generated_cons(False), [generated_cons(True)] + the_list) else: return [generated_cons(True)] + the_list def reverse_but_as_cons(generated_cons, the_func = None): if generated_cons(False) is not None: return reverse_but_as_cons(generated_cons(False), cons(generated_cons(True), the_func)) else: return cons(generated_cons(True), the_func) l = cons(1, cons(2, cons(3, None))) # Reverse as Python list (normal order -> output is reversed from here) print(reverse_but_as_list(l)) # Reverse as Python list (the reversed cons -> output should be the same, but in a Python list instead) print(reverse_but_as_list(reverse_but_as_cons(l)))
bottombear
bottombear, on
.'"". I LIKE PYTHON BECAUSE I ENJOY HOMOSEXUAL c' )"/ S/M. OH GUIDO MAKE ME USE THAT FUCKING __> /_ INDENTATION. OH BABY I'M CUMMING. .-`_ ._'-. ( -' \ :/ )/ THERE IS ONLY ONE WAY TO DO IT: GUIDO'S \\._| ( // WAY! THAT MEANS YOU CAN'T USE ALL '-/) \(, CONTROL STRUCTURES. IF YOU NEED A DO- / ) ) WHILE LOOP, A SWITCH OR BREAK OUT OF A / .'\ | NESTED LOOP, TOO BAD. GUIDO SAYS IT'S TO /.' \| KEEP THE LANGUAGE CLEAN, BUT IT'S ACTUALLY || || TO PUNISH HIS SLAVES. THIS DOESN'T MEAN __|/ |/__ THAT PYTHON IS FLAWED, JUST WORK AROUND IT. _._) (,__; FUCK I'M CUMMING AGAIN.

Post a Comment

Please avoid writing anything here unless you are a computer: This is also a trap:

Supports github-flavored markdown for [links](http://foo.com/), *emphasis*, _underline_, `code`, and > blockquotes. Use ```clj on its own line to start a Clojure code block, and ``` to end the block.

Copyright © 2017 Kyle Kingsbury.
Non-commercial re-use with attribution encouraged; all other rights reserved.
Comments are the property of respective posters.