in which i hold forth upon various and sundry issues of import to persons employed in the
production of software and am promptly and roundly ignored
Your Resumé Should be an Exciting Story Starring You
15 October 2019
I have been reading resumés lately in a couple of different capacities, and let me
tell you all something: They suck.
The Conventional Wisdom Makes you Look Conventional
The conventional wisdom of resumé writing has you buzz-wording up your
achievements and relating everything you’ve ever done in terms of crushing
those KPIs and LOOK AT ALL THE MONEY.
This isn’t bad advice, but it tends to result in a whole lot of largely
indistinguishable pablum. A resumé that performs all of the standard tricks is
like a Ford Focus - servicable, but unexciting. (Full Disclosure: I drive a Ford
Focus. It’s a fine automobile, but I don’t get excited about driving it. Your
goal in applying for a job is get your future teammates excited about working
with you.)
The kind of resumés I get to read are obviously for software developers and the
ones that get rejected fall into two basic categories.
All Computers I Have Known
I Am A Self-Directed Learner Who Likes To Solve Hard Problems
As a human, these are the ones that make my eyes glaze over and skip to the end
where I can plausibly say I’ve reviewed your resumé and then throw it away.
Please do not make my job hard. If you make my job hard before I’ve even hired
you, you have violated the One Commandment of Getting A Job:
Convince your future teammates that you will make their life easier.
Interestingly - I find that senior resumés tend toward the first type while the
junior resumés are clustered around the second. I get that the plural of
anecdote is not data, so take that with as much salt as you need.
Let’s talk about these two failure modes and what you ought to do to address
them.
The Conventional Wisdom is Actual Wisdom Tho
But first, an aside: I kinda ran down the “conventional wisdom” back there,
which was a little unfair, because there’s some good stuff in there. I’m
guessing you all know or have heard of these, since we all have Google and we’ve
all looked up “why does my resumé keep getting rejected?”
So quick recap:
Action Words - make it sound like you’re the star of this story, because
you are!
Measurable Outcomes - All these graphs go up and to the right, because
that’s where the future is!
Please, please, please proofread - You probably won’t get dinged for dangling
participles or whatever, but consistent misuse of words or a lot of common
grammar mistakes (they’re, there, their) are Bad News.
Now onto critiquing the bad resumé you may have already written.
To All The Computers I’ve Known Before
Let’s start with How To List your Skills. This is very, very straightforward.
Copy them from the job ad
That’s it. That’s the whole thing. Copy each of the technologies listed in
the job ad over to your resumé, then delete them if you’re not comfortable with
them. If you know something adjacent then you can put that in instead. Like
you can put down “Cloud Formation” instead of “Terraform” if you don’t have
Terraform.
Now if there’s no overlap at this point, then maybe consider that this isn’t the
job for you.
Let’s try one on for size (modified from an actual listing):
Experience with Processing.js
Experience with Python, Ruby, or Node
Strong knowledge in OOD, domain-driven design, and microservices
Experience working in Agile Teams
Skills I might write down:
Ruby
Python
NodeJS
Software Architecture including DDD, OOD and microservices
Agile Methodolgies including Scrum and XP
Note how I skipped Processing.js because I have never used it. With this amount
of information it’s not possible to know how important Processing is to the job,
so we’ll just leave that part out.
I tend to put these in a little list right under my name, so that
people can read my resumé and see the intersection between what they’re looking
for and what I have right away. That way, they don’t have to read several pages of
responsibilities, or things like this:
Created custom dashboard for Elatic Monitoring for RHEL 6.4 clusters written in
Processing.js and Graylog
I don’t know what half of that means, and I have to read your resumé really
carefully to come up with the answer to my question “Does this person know
Processing.JS?” - if the prime directive of job interviewing is showing how
you will make your team’s life easier, start by demonstrating this by making
the reviewers job easy.
If you by some chance find yourself writing a bulleted list of technologies
longer than like … 5 then just stop. Back up and write down the interesting
ones! I’m sure it’s interesting to the right audience that you used some Java
program I’ve never heard of to do a task I don’t understand, but this is a
Python shop and I just wanna know if you can AWS.
You are unique, just Like every other self-directed learner who likes to solve hard problems
Next to “I’m sorry sir, but that’s our policy.” - this has got to be my least
favorite sentence in the English language. It’s almost entirely content free
and everybody knows that you’re either lying or dissembling.1
For the love of dog, if you have this sentence in your resumé or cover letter,
please remove it unless you know for a hard absolute fact that you are talking
to a machine. It is the platonic form of “telling not showing” in writing. Like
the sentence “Sir Gilroy the Fair is the hero of this story” - it only really
works as satire. You need to find a way to demonstrate this truth to your reader
without just baldly stating it.
Think about this: What’s an engaging way of telling this story, without
resorting to asserting it free of context? Start by telling a story
about a time it was true of you:
“This one time, I was supposed to make a poker game, but I didn’t know anything
about poker, so I learned all about poker, and wrote a program that I couldn’t
beat at poker.”
Now, if you’re a newish developer you might have to dig pretty deep on this one -
and you probably only have a limited set of really good stories to draw on.
But think about it - when was the last time you encountered a seemingly
intractable problem you needed to do some research to solve? Last week?
If you’ve never had to do this, then you might need to do some more
training. Being a “self-directed learner who likes to solve hard problems” is
a significant fraction of being a developer. Everybody has this.
Tell Me A Story
People tend to approach cover letters and job applications as opportunities to
list a lot of good things about themselves, or to tell other people about
themselves. I think this is exactly the wrong approach. Tell me a story with
you as the hero. Make it engaging. Make it a thing that I want to read so that
at the end of your resumé I’m having a The-End-of-Return-of-the-Jedi moment.
“Yeah, that was awesome! What happens next? Let’s make a sequel! And not wait 30
years!”
Okay, RoTJ might be a bit of a stretch, and I’m not advocating for you to
include tiny, savage bears in your cover letter, but please make your job
application engaging. I read enough boring business writing everyday. I do
enough work. Again, the main dimension people are hired on is “is this person
going to make my life easier,” and if you begin by making me read a long, boring
document then you’ve just demonstrated the opposite. STAHP.
All of that is easier said than done. Here are some actionable tips to
make your resumé better.
Read. It. Aloud.
Seriously do this one. This is like the secret to good writing. Read
it aloud, maybe even to an audience and see if it sounds engaging. Perform your
resumé like a one act play and make sure that you’re the hero.
Write the Resume You Wish You Had
Do not send me lies, but write down a fictionalized account of your career up to
this point. This shows you your values. Did you write “* Improved
performance of page load 1000%” or “* Created a new process for gnarfling the
garthok that saved the company $1000 per millisecond”? You have revealed the
kind of thing you’d like to write down, and the sort of story you’d like to
star in. Now go back to your “real life” and write the same sort of stories
from your experience. “* Decreased page size from 20M to 150K” and “*
Developed a Garthok Gnarfling Guide to share with other developers.”
Keep it short. Tailor it to every job.
Every job is different. Get good at tailoring your experience and
accomplishments to individual companies. Do not tell me how good you are at
sword fighting if we’re going to get in a laser gun fight on Endor. This seems
like a lot of work until you do it a few times and you find that you can remix a
lot of the same content. A sentence here, a phrase there. You want to tailor
it for every company because you want to keep it under two pages. I’m busy, and
I have reasonable expectations about how exciting a resumé can be. Think Cat in
the Hat not War and Peace.
Action! Excitement!
A Jedi might not crave these things, but your resumé reviewer does. If you’re a
clever person who likes to have a good time don’t be afraid to let that come
across in your resumé. I mean, don’t try too hard, but don’t wordsmith your
introduction to the point that it sounds like it was written by a lawyer. If
you’re a detail oriented perfectionist (good for you!) then make sure your
resumé reflects this - a single conservative font with perfect kerning!
It is okay for your resumé to be a statement about who you are, that’s why we
read it.
Read. It. Aloud.
Did you just say “yeah sure” before and then not do it? I mean it. Do it.
Here is your Handful of Salt
So first off - this is not a “How to Get A Job” post - this covers just the
resumé and cover letter section. There are several other steps you need to
pass, all of which have higher signal. Interviews, code challenges, phone
screens, etc. If you’re an asshole or you have no relevant skills, no amount of
“kickass resumé” is going to overcome that deficit.
Second - I read the resumés of software developers, so if you’re applying for a
job as a Marketing Manager, understand you’re outside my area of expertise. Some
hiring processes are designed to remove as much personality as possible from the
process (looking at you, academia.) So, while software hiring may be broken in
many ways, so far we’re doing an okayish job at not reducing “Do I want to
spend eight hours a day discussing math and puzzles with this person?” to a list
of impersonal checkboxes.
Now, I’m sure there are companies in the world that get so many resumés that
nobody reads them, and most of them are simply run through a keyword analyzer.
So in that case, follow this advice anyway. The strategy of copying
qualifications directly into your resumé ought to overcome simple keyword
filters, and anything more complex than that is just a pile of linear algebra
nobody understands anyway. Just ignore scare-mongering
about automated systems. Those kinds of systems are designed to generate
plausible deniability, not “find good candidates.”
Now, for a uncomfortable truth: There is a giant element of chance in
getting past an initial screen. There isn’t a whole lot to go on in a resumé, so
a chunk of what gets a reviewer to give you a thumbs up hinges on whether your
resumé speaks to them. The Lord of the Rings is probably my favorite book
of all time, but a lot of people find it terribly dull. You cannot write
for all audiences, and attempting to do so will result in you writing for no
audiences. Be yourself, tell your story in an engaging way, and you’ll land
at a place where people want to spend half their waking hours engaging with
you.
And, when you think about it, would you want to spend that much time at a place
that thought you were just too interesting?
1. “But I’m not lying, that’s really true!” - You know, I’m sure
it is, but have you ever said this outside the context of a resumé or cover
letter? If not, you need to find a more engaging way of saying this that not
every person with a pulse is also writing in their applications. If you have
said this in “real life” … you need to go to better parties.
The Book of NATS I - Chapter 3
13 March 2018
Sit down everybody, lemme tell you a story. Flicks the lightswitch
In a time long ago, there was ActiveSupport::Notifications, and it was good.
But the people desired to send messages to remote applications without crafting
specific calls to special API endpoints. And Prater came upon this problem and
decide “I will fix it” so he paired with Peychich and created the NATSAdapter
for Goldstar Notifications, and it required no code changes to work with
existing code. And he looked upon his PR and saw that it was good.
And then, behold he tried to deploy it to Staging and all was well, and he
looked upon his code and he should have been suspicious, but his mind was
undone with the promise of the beauty of the world to come, and the elegance of
the thing he had crafted, and he put down his doubts, and he pushed himself to
deploy.
And deploy he did. In the beginning the Deploy was with Jenkins and the
Jenkins had the deploy - and lo it came to pass that Staging was Very Different
Than Production, and signals that were received in Production were not received
in Staging, and therefore that case was not handled. So Prater went back to
his editor, where he introduced reconnection logic. And the PR review saw that it
was good and smiled. And they deployed the reconnection logic to Staging, and all
was well.
But when, in the fullness of time, he deployed to production again, the Great
Enemy MultiThreading bared it’s mouth of fangs and said “Lo, beware, for
although you have introduce reconnection I have Thread Safe Concurrency
Constructs that are as Queues and Condition Variables and it is not my will that your
deploy should go smoothly.”
Indeed, when the time for the deploy was upon the developers, the Unicorn
processes would shut down, and they would disconnect from NATS, and they would
send messages that said “We are no longer interested in what you have to say,
for we are tired, and wish to shut down. Give your messages to the children of
the new master!” But little did the developers know, that they had been
deceived - for no messages could be received on any channel when they were
disconnected, and there was much wailing and gnashing of teeth - for every
deploy resulted in 15 seconds of intermittent downtime.
But then Prater and Jared beheld the situation and in their folly they
proclaimed “A one line change!” and so they changed the one line and proceed
with testing. For in in the darkness had been crafted that most terrible
of sins, the thing that developers have dreaded since the dawn of time - a
library bug. And Prater and Jared looked upon their minimal reproduction case
and despaired - for the bug was not in their code, but deep within the library,
and any method called from within the threaded closure would fail, and it’s
children would fail, and so-on for ever and ever, deadlock.
Many changes were thrown against the problem that day - and many dark avenues of
promising fixes came to their ends in alleys of shared state, but finally, in a
a final fit of desperation, Prater and Jared decided to use the weapons of their
enemey against them, and introduced a Thread Safe Queue to their own code.
And there was much rejoicing in the land, for all of their testing indicated
that it would work. The developers recreated an environment with forks and
signals locally and they applied their changes, and everything worked as expected, and
connections were not lost, and the people did feast upon the glory that was a
distributed pub-sub system, and there was much rejoicing in the land.
But still, Prater is watchful - for he has been burned before and it has left
scars upon his heart, and fell mood upon his mind.
The Path of Least Cost
07 November 2017
In raster GIS analysis there is a relatively common piece of analysis called the
“least cost path.”
The algorithm itself is pretty simple - given a “cost surface” find the
cheapest way to get to a different point on the plane. The “cost surface”
itself is essentially a grayscale picture where the highest numbers represent
the highest cost. The analysis is excellent for finding the path that water
will take down hills, or if you want to get a little creative, the fastest way
from your house to the coffeeshop given what you know about road conditions.
It’s a simple algorithm - it finds all the paths to the goal, adds up the
costs, and takes the cheapest one. Does that process sound familiar? Could it be
SATAN AGILE?
But the algorithm is not infallible.
One of my favorite examples of how people “know” better than the least cost
algorithm comes from archaeology. (Disclaimer - I am not an archaeologist, but
I am married to one so I get some osmostic learning.) Here’s the story:
In Central Arkansas, the Arkansas River runs near the base of Petit Jean
mountain. Petit Jean is covered in Native American rock art, but
there’s little evidence of long term habitation there. Instead, it seems that
most of the people in the area lived in the nearby bottom land and “commuted” to the
top of the mountain for ritual practice.
Wanting to know what sort of path they might have taken to get to the top of the
mountain - a researcher runs a “least cost analysis” between a known village site
and a known rock art site. The path leads straight into a shear cliff, and
happily climbs directly up it. Turns out that it’s cheaper to climb the cliff
than to go round to the nice, gentle slope, and cool refreshing water falls on
the other side of the mountain.
I mean … c’mon. Clearly - no reasonable human is going to stumble upon a shear 100
meter cliff and think to themselves “I bet scaling this is easier than going
around.”
Now - if you’re a developer and not a rock art specialist you’re probably
thinking one of two things depending on your personal proclivities.
“Agile’s such horseshit - no longterm thinking and now we’re staring down a
metaphorical cliff of technical debt.”
“This is probably MVP. I wonder if we could just do the ritual right here at
the base of the precipice.”
Perhaps suprisingly - this story has an obvious ending.
Nobody climbs a hundred meter cliff.
They especially don’t climb a hundred meter cliff if you can go a few kilometers
out of your way and take a nice easy walk through bountiful forests.
Maybe there’s a story here - that the “easiest next step” is not always the
“correct next step” - a little bit of vision here can go a long way. We can
no more imagine clueless native pilgrims stumbling up to a surprise cliff face
than we can them climbing it. Because they weren’t stupid.
Without robotic devotion to process we all see the cliff coming - but the desire
to make Software into a Factory has produced a type of willfully ignorant Agile
Cult that (like all cults) has convinced themselves to believe things they know
aren’t true, and to deny truths they can plainly see.
Software Is Not A Factory
We (by which I mean “the people who write the checks and the code”) want, and
maybe even need, to believe that once we ‘discover’ the correct way to write
Software we can eliminate human creativity from it and get right into producing
software exactly like we do cars or houses or anything else that’s mass
manufactured by humans.
Eliminate the ability (or need) to make decisions and we can Taylorism our way
right into profitability. I’m pretty sure this is mostly wrong for several
reasons - but one of the biggest gets back to our parable of the Least Cost
Path.
Software Is Not A Factory - but it is also not a journey with a map. There is
little doubt given the “least cost path” analysis that it is in fact cheaper
to climb the cliff. It’s not really arguable that from the birds-eye view
(where you can clearly see the entire cost surface) that walking around the cliff
is the more expensive option. But while planners like to see themselves as
the algorithm - with perfect foreknowledge of the lay of the land and all of
the costs associated - we are far, far, far more like the people trying to get
to the top of the mountain to make some Rock Art.
It’s a pretty sensible approach to not start out with idea that we’re going to
go the long way round - and so start hiking directly toward the peak of the
mountain (where lies our Finished Product) - but we don’t have to walk all the
way up to the base of the cliff to realize the cliff is there and that maybe we
should go another way. And, on our next trip, there’s no reason to take a
several-days detour to the base of the cliff to see if it’s still there - we can
start planning for the walk around.
Convincing yourself that you don’t know things that you do know is just as
much of a cognitive bias as convincing yourself that you do know things you
don’t know - and it has the same kind of negative impact.
You plan for the world as you see it, and if you see it wrong, you plan for it
wrong. That’s something of a truism and extraordinarily reductive - but I think
it’s something that we could all benefit from remembering. Programmers even
have an acronym for this: Garbage In Garbage Out.
So it goes, watch out for cliffs.
So you wanna be a programmer
09 November 2016
Before I start dashing your hopes and dreams, let’s get one thing out of the way.
You are smart, you are capable, and if you desire, you can find success as a
software engineer.
You already have a leg up on the vast majority of people for
whom computers are a magical black box, so even though it may seem daunting, be
aware that once you’ve left orbit, you’re halfway to anywhere.
Now for the unpleasant bits:
No one will hire you based on your boot camp experience (unless they have a
program designed to hire boot camp graduates.)
Most of that knowledge is syntax and technology. These are orthogonal to
your actual skill set, which is the ability to LEARN syntax and technology.
You will never be “good” at this job.
No one hires bootcamp graduates
This is not strictly true. Lots of places hire bootcamp graduates, but few of
those graduates are hired BECAUSE they went to bootcamp. Bootcamp code is
generally throw-away quality, and that’s okay. Hiring managers and engineering
teams care more about your ability to contribute than anything else.
Convincing your future teammates that you will make their life easier / better
is not a guaranteed job, but failing to convince them of this is a significant
hurdle, and convincing them of the opposite is a success-proof strategy.
One of the ways that you show you CAN contribute is to ACTUALLY contribute. Find
an open source project and make some patches. With a few notable exceptions,
OSS projects love receiving well thought out patches from new contributors. If
there is a project you like and an itch you’d like to scratch, that’s an excellent
way of writing “real” production code without actually having a job. This doesn’t
need to be an established OSS project. You have a hobby right? Aim coffee and
code at your hobby and write some software to make your life easier. Nothing
speaks louder than your code, so show off as much of it as is reasonable.
The other avenue for this is freelance. Be careful about accepting freelance
too far above your skill level, but don’t be afraid to seek out and perform
work that is outside of your comfort zone. Although you probably do not command
top tier freelance rates, don’t feel bad about charging for your work. You will
know when something doesn’t seem fair - adjust your time accordingly, or seek out
non-profit or low-budget projects where you can work at your own pace.
A bootcamp graduate with meaningful open source contributions
(make them on Github!) is immediately a cut above junior level devs without them.
I’m sorry to have to tell you that the answer is “work for free” - but so it is.
A lot of the hiring managers and Sr. Devs now working grew up hacking around on
things in their free time. The expectation is not that you “work for free” but
that you apply your skills to things you care about, and that your copious youthful
energy be directed into ‘meaningful’ things.
Your actual skills are not programming
Two of the main skills that a “good” Jr Dev will have are stubbornness and
curiosity.
You’ve probably already got a stubborn streak if you’ve made it this far, and
you’re going to want to nuture that in a certain ways. Don’t give up, even when you
are defeated, and have an no-quit attitude. This is HARD. One of my
mentees was interviewed at a financial services firm, and they gave her a
coding test as part of the interview. The test was UTTERLY beyond her abilities,
and she had no hope whatsoever of completing it. She was obviously upset as this
was her first interview at a promising company, and she was devastated to know
that she was going to blow it. I encouraged her to complete the test even though
she would miss the deadline (she missed it by almost 3 weeks, but she did complete
it.) She did not get that job, or the next one, but by her third interview coding
tests were old hat, and she aced it and got the job. You WILL lose. Keep fighting.
The other “winning” attribute is curiosity. A different mentee of mine was working
with me on a complicated graphics project. I had mentioned offhandedly some
point about RGB color math. He didn’t understand what I meant, and although I
explained the immediate application to him, he wasn’t satisfied - instead he went
home, read a bunch of articles and blog posts on the subject and came back a few
days later with questions that I couldn’t answer. He wound up writing the color
math portion of the project because he understood the problem better than I did.
If you apply these two traits to your work, that will go much farther than
knowing the basics of an additional framework. Jr Devs are hired based much more
on potential than on actual production, and displaying an unwillingness to accept
defeat at the hand of a machine and a deep curiosity for problems you encounter
is a good way to convey to teammates that you will be an asset to them in
the future.
Note that this doesn’t necessarily mean you shouldn’t have a life outside of
computers - you really should - but that your potential teammates are primarily
concerned with your life vis-a-vis computers. Stubbornness and curiosity maybe
your two most important skills, but it’s also important that you not be a raging
jackass to everyone you meet. Try to be humble, approachable and teachable.
For a discipline revolving around unfeeling machines, people skills are
shockingly important to your career as a programmer.
You will never be “good” at this job
Remember when we talked about a refusal to accept defeat? Get ready to lose.
A lot. Your career from here on out will be near constant terror that you just
fucked up so royally that THIS time they’ll finally find you out. Spoiler alert:
you didn’t. Everyone feels this way all the time. Seemingly misplaced
confidence is another good trait for junior engineers. “I don’t know how to do
that but I can certainly figure it out!”
This is very much a “fake it until you make it” sort of behavior. If you’re
always moving forward, trying SOMETHING, eventually you find that the things
you try work more and more often, and that you really pooch it up way less
frequently. More spoiler alerts: the number never gets to zero.
A lot of freshly-minted developers take the exhortation “Be Confident!”
as a sexist scold to stand up for yourself. To an extent this is true, but the
take away from “Be Confident!” is not to develop a “rock-star-ninjaneer” ego
but to be confident in your ability to solve problems. Developers have been
talking around this problem for as long as the discipline has existed - “Strong
opinions weakly held.”, etc. Be willing to fail, be willing to try. The good
news is that, as a computer programmer, things rarely explode when you make a
mistake, the better news is that as a Jr engineer, you are likely to
(and should!) be insulated from making critical errors by Sr Developers and
managers. So, go for it. What’s the worse that could happen?
How is a developer like a writing desk
This sounds all negative-nancy and Eeyore’s pity party - and to a certain extent
learning that the several thousand dollars you spent on a dev bootcamp is not a
job guarantee is certainly bad news - but I’ll reiterate - you are already half
way there.
Being a Jr. Developer is HARD. In a lot of ways it’s harder than being the
grizzled old vet. You don’t know what you don’t know, and you’re entering
an industry, where, frankly, social and professional norms are different.
You might face additional challenges like being from an under-represented
race, gender, or sexual orientation. You might not have the kind of hacker
personality that makes engineering and logic problems come naturally to you.
And that sucks. It won’t be easy, things worth doing rarely are.
You don’t need to have a lifelong dream of being a programmer to be a successful
one - if your passion is romantic French literature (my boss for instance) that’s
fine. You don’t have to follow your passion, but you need to be passionate about
doing good work. I won’t say that you won’t encounter some people who are just
useless assholes. People like that are everywhere. If you stick with it, you’ll
(hopefully) get to the point where you’re well paid. But, if you’re in this for
the money, you’re going to have a hard time. Being subject to continuous
failure and the relentless, heartless criticism of the machine can suck the joy
out of any paycheck, no matter how big.
I will say this though: The people who become successful programmers often have
the same basic traits that you do. They are passionate, they are curious, and
fundamentally they want you to succeed. They have ALL been where you are now,
confused, uncertain, excited, and amazed at what they can make that machine DO.