Picture this situation: you woke up this morning to find that there’s no water coming through your valves and taps. No sink water. No shower water. Having no plumbing experience, you call around for a plumber.
Plumber #1, let’s call him Mario, tells you he can’t be bothered to come check out your issue because it’s minor and he’s very important and too busy for it. You explain that you really need a plumber, and he explains he’ll do it for 1.5x what everybody else costs, and only if you have lunch and coffee ready for him when he arrives. You have no water, keep in mind, so making coffee is an extra special effort.
Plumber #2, let’s call him Luigi, agrees to show up and assess the damage. He walks in your door, doesn’t bother to shake your hand or introduce himself, and immediately gets to work. A few minutes of inspection later and Luigi is telling you that all of your plumbing is wrong. None of the pipes are plumbed how he’d plumb them, so they’re wrong. He needs to rip out the whole plumbing system and do it all again from scratch, which will cost you thousands of dollars. He has a reputation for being skilled: his past references love him, but this is going to cost a lot of money and take a lot of time. It’ll be at least a week before you have running water again.
Plumber #3, let’s call her Peach, asks you some detailed questions about the problem over the phone. “How long have you lived in the home?” “Have you had any prior plumbing issues?” “Has this happened before?” “Do you have any other sources of water?” Based on this analysis, she tells you she has a good idea of what the issue is and agrees to come over later that day, since she’s in the area anyway. She shows up, immediately discovers that the pesky neighbour kids shut off your water main, turns it back on, and then gives you some advice: “it’s not something you need to do right now, but you should upgrade to a locked main switch that operates with a key so that this won’t happen again! Call me if you want something like that installed.”
Now, which one would you hire?
Back to Programming
Let’s take this [terrible] analogy back to programming. Plumber #1 is a rock star developer who demands special treatment and pampering. Plumber #2 has a huge ego, a serious case of not-invented-here syndrome (they didn’t plumb the house so it’s wrong!), and might also be a rock star. Plumber #3 is pragmatic, friendly, sensible, analytical, and balances cost of time and money with urgency. For me personally, #3 is the only one I’d happily hire.
It seems so obvious that egos and not-invented-here cost a lot of money and do a lot of damage in that analogy. It’s less evident in the workplace. Some companies foster the ego and demand to hire rock stars, believing that the “ten ex” developer will outperform others they could hire. What they don’t realize is that the cost of this hire almost certainly outweighs the benefits.
There’s no place for ego in programming. An egotistical programmer does incredible amounts of damage to those around them. They do cultural damage to your company, emotional damage to their peers, and financial damage to your budgets. Those rewrites aren’t cheap!
Don’t be a rock star. Rock stars are cold, hard to approach, notoriously unfriendly and self-absorbed, make no time for others and teaching them (because everything’s about ME!), and are frequently dramatic and rude (to get in the “news” – after all, any publicity is good publicity).
Seriously, "rock stars" are arrogant narcissists. Plumbers keep us all from getting cholera. Build functional infrastructure. Be a plumber.
— Molly Sauter (@OddLetters) June 17, 2016
I don’t know about you, but I want to work with Peach. I prefer a humble, thoughtful, talented peer that can teach me while maintaining respect and a relationship of trust. That’s the kind of workplace that I get up every morning excited to go to. Peach is probably not perfect, and has her flaws, but the lack of an ego and attitude means she’s willing to learn and grow – and that’s the key to success in this industry.
If this analogy hit a little close to home, it’s time for a little introspection. The beauty of the human condition is that we are always on a path, growing and changing. Who you are today is not who you are forever. Think about which plumber you resemble above, and then adjust. Next time you’re about to say “that’s all wrong!” or “we have to write it ourselves!”, pause and think: there’s probably a decent a reason that the code exists in its current state. Is now really the time to undertake a very expensive rewrite / greenfield project? Probably not.
Almost exactly 1 month ago today I found myself on a video call with Joel Spolsky. It feels insane to write that, even now, as it was a banner moment in my career. For me it was the equivalent of meeting a movie star who I had idolized since I was old enough to know what movies were. There had always been this Joel Spolsky guy throughout my career that I regularly read about and whose opinions on software development agreed with mine, and suddenly I was talking with him face to face. It was awesome.
Reaching this conversation was not the easiest thing I’ve done in my life. It took a few weeks and in all honesty it was a bit trying to find time to have so many interviews. How many interviews, you ask? Prior to Joel I talked with 5 or 6 other amazing people (Marc Gravell and Nicholas Larsen included). Somehow I managed to impress each of them enough to reach the end boss: Joel Spolsky.
The conversation lasted about an hour. It felt like 5 minutes to me, probably because of the excitement. Joel and I discussed the pros and cons of various software methodologies, mistakes each of us had made in our careers, some of the challenges of Dache (my open source software), and a few other topics. Then he said something awesome: “We’d love for you to come and work with us at Stack Exchange!” So much adrenaline hit me at this moment that I could have lifted a car with my bare hands. It was surreal.
A few days from now I officially start working with Stack Exchange. I feel very fortunate and excited for the opportunity. So far the Stack Exchange team have proven themselves an insanely skilled and professional organization that treat employees as human beings instead of expendable resources. I’m already loving the culture and interactions with my coworkers.
IMPORTANT NOTES: First and foremost, the commentary here consists of my views alone and not those of Stack Exchange or any other entity. This post is merely to reflect upon the interview process and discuss the aspects and traits of my career and knowledge which I feel helped me get the job. This is not a tell-all or any sort of shortcut or easy way out. If you want a job at Stack Exchange, you will have to endure the same technical and soft skills challenges that I did – the details of which I will NOT be disclosing. 🙂
So, with that disclaimer out of the way, here are my thoughts on how I got a job at Stack Exchange, and how you can too:
Ego is the mind killer, so kill the ego. Most developers that I’ve met (including some prior versions of myself) have massive egos. Egos so big that the room can barely hold them. Egos that even put the illustrious Kanye West’s attitude to shame. This is natural given that we spend all day creating things from scratch (which is a god-like quality) that often generate significant revenue for companies. We start to feel very powerful and even fawned over. We learn the entirety of the software and hardware vertical of our current job’s domain, and then make a Superman-like flying leap to conclude that we know EVERYTHING about ALL software and hardware.
Thinking you know everything is the easiest way to suck as a programmer. If you believe that you know everything, you stop trying to learn new things (since you already know them, duh). So, while you’ve mastered ASP.NET MVC 3 at your current gig, 4 and 5 came out… the catch is that your company never upgraded because it’s too risky, and so you never learned them (or cared to). Now a year or two later you’re so far behind the current development stack that you can’t even see it with binoculars. And did I mention those little things called Ruby and PHP and even Java that you’ve never written a single line of? And how about MongoDB, Couchbase, Azure, EC2, and the literally thousands of other platforms and programming languages? I should hope that by now you realize that you know a little bit about a handful of languages and hardware configurations amidst a sea of thousands… By percentage, you’ve conquered maybe 0.1% of all that there is to know about development. So have I, and that’s OK.
Don’t be a rock star developer. This is something that I did for a few years and it only hurt my career. Many companies employ a strategy of intentionally furthering the developer ego in order to make them feel valuable (often without handing out appropriate compensation). Being a rock star sounds cool, but really it’s a nasty strategy that can cultivate incredibly destructive developer attitudes. Companies seek out and hire rock stars, and rock stars have a sense of entitlement. They develop huge egos and run their mouths at meetings, interrupting and talking over others. They seem to love circular logic (they’re right because you’re wrong because they’re right). They feel that all other team members exist simply to serve their every whim… and everyone loathes working with them.
The thing is – while you may actually be a 1 in 1 million bona fide rock star developer – nobody cares. Talk is cheap and in my experience people will say nearly anything and everything to portray an image of who they want you to believe they are. If you are really good at what you do, telling people doesn’t do anything other than make them despise you… Hearing about how amazing your proprietary code is gets annoying – especially when it’s the 5th time this week you’ve said it. A good developer doesn’t need to brag about how good they are: their work speaks louder than any boastful words could. People around them will naturally do the bragging for them. Hallway conversations to the tune of “wow, he’s really smart” or “she knocked that out in hours when we thought it’d take days” will be fostered, and that isn’t a bad thing. Let people talk about you all they’d like, but maintain a sense of humility and reality. You might be the best developer on your team or even at your company, but you are still a human being and this is still a job. Nobody has been hired to serve your ego (even if their job is to serve you). Being a good developer doesn’t make you better than anyone as a person; it just makes you successful in your career. Never lose sight of the fact that thousands of other developers are great at their jobs too. What separates you from the pack is being a great developer AND modest. It is a very rare combination in my experience, and the complete package that many companies are striving to hire. So, while it’s cool that you’re the very best developer that there ever was, stop believing your own hype and telling everyone who will listen. They don’t care, and you shouldn’t either.
Know that you know enough to know that you don’t know enough. Know what you do know, and know what you don’t know, and never be afraid to say “I don’t know” when it’s the truth. A developer who isn’t afraid to say “I don’t know” in front of a room full of people is a rare gem. By being honest you create trust and credibility. You also foster positive relationships with your peers and company. Nobody will remember that you’ve never heard of Angular.js or Couchbase, though they’ll always appreciate that you didn’t waste their time or money by pretending that you did. You can’t trust a developer who doesn’t know what they don’t know.
Know your data structures and algorithms. High level programming languages such as C# abstract so much away from the modern developer that many of us have no idea what’s actually happening “under the hood” when it executes. It’s cool that you can sling LINQ everywhere, but do you know the computational complexity of what you’ve done? Do you know what a hash table is and why it is useful? Could you sort a list of things efficiently? Can you think of a scenario where a stack is the best option? Note that you don’t need to memorize things like sorting algorithms (hell, I couldn’t if I tried), but a working knowledge of data structures such as trees, hash buckets, lists, queues, and stacks combined with the rudimentary knowledge of things like sorting, searching, and caching is a very valuable skillset. It’s the difference between a good programmer and a great one. Anyone can write C#, but only those who understand even the low level operations of each deliberate method call will write good, clean, efficient code. You owe yourself a fundamental understanding of how data structures like stacks and heaps work, as well as by-value vs by-reference memory addressing. These core concepts apply to ALL programming languages. Too many developers ignore the complexity of their algorithms and just call pre-made methods without understanding the implications. Educate yourself on data structures and algorithms and suddenly you’ll be ahead of the pack.
Know why your code works and why your code doesn’t work. Have you seen this image circulating on sites like Reddit?
Despite being funny, the popularity of this image pisses me off. It claims that the essence of programming is having no freaking clue why your code does or does not run. I feel that this is unacceptable. A great developer strives for the WHY in every single thing that they do, not just HOW to quick-fix it. Code doesn’t compile? WHY? Race condition across threads? WHY? In asking “why” you further your knowledge and expand your skillset with the functional, rational “how” which allows you to become a better programmer. Most great programmers don’t repeat the same mistakes over and over, though they of course make mistakes… They just make new and interesting ones!
I remember the days of slinging shoddy code and then copy-pasting lines from blogs and sites like Stack Overflow until my code seemed to work (though I wasn’t sure if or why it did). Those days are long behind me. When my code doesn’t compile, 99% of the time I immediately know how to fix the issue. When my code has a bug, I usually know exactly how to track it down and resolve it, and in doing so I often learn how to avoid it in the future. Having no idea why your code works is like being a lawyer who has no idea why their client is not guilty: fairly useless, overpaid, and an amusing spectacle at times. Make sure that you know why your code works and why it doesn’t. In my opinion this is a basic competency of being a professional developer. It’s OK to create bugs and make mistakes – it’s not OK to make the same mistakes repeatedly.
At this point I feel that I’ve done a reasonable job of representing my skillset and core competencies. These are the things I showed to the Stack Exchange team in my interviews. I didn’t necessarily have the exact answer (or even most efficient answer) to each of their technical questions, but I was modest and never afraid to ask for help or say “I don’t know” when I got stuck. My answers involved efficient data structures and algorithms, and I was able to explain why the data structure was the best choice in solving the problem. When I created bugs I was mostly able to identify them and indicate how to fix them. In doing all of this, I demonstrated competency and confidence as a developer and fortunately ended up with my dream job.
I think that most devs would agree when I state that the definition of success in the corporate world of development places less emphasis on “good” code and more emphasis on “working” code. Working code is code that can be released to production on or before the deadline, regardless of performance or even bugs in most cases. As a developer, you ultimately feel as if you’ve failed when you toil for nights on end to meet steep deadlines and churn out crappy code. As a business, however, you’ve succeeded when you hit the deadline. My experience tells me that the typical metric upon which development teams are measured is often not quality of code or unit tests or even performance, but instead ability to meet deadlines and deliver solutions to clients. You’ve failed when you do not meet the deadlines and thus piss off the clients/customers. Your job has become a veritable boolean result with the outcomes of true and false. Deadline met? True. Deadline missed? False.
Doesn’t it feel awful to be measured in such a binary way? All or nothing, success or failure, deliver or delay. These are the only outcomes according to the people who write and sign your paychecks.
Why does this happen? A little introspective thought brings light to the subject, at least for me. The reason for these types of metrics becomes obvious when you consider their source. You work for a company who pays you (often with I.T. seen as a cost-center or “money pit”) to accomplish things which the company can then sell to clients. You’re an expensive tool by which they accomplish their means. Though these companies often see software as a profit source, they see the means by which they get the software as an expense and cost. Kind of strange, really.
The problem begins at the very core of the organization; the structure of the company is the starting point for guaranteed failure. In my experience, the dichotomy that forms in most companies is “I.T.” versus “The Business” in a bout-to-knock-the-other-guy-out. The minute you create this relationship of opposing fronts, you’ve already guaranteed development failure. With competing and contrasting goals (the business wants to sell stuff ASAP while I.T. wants to build stuff properly which takes longer) it is not possible for trust to exist within the organization. The Business will not believe a word that I.T. says when it comes to estimates, deadlines, or things that need to happen to ensure stability of the product in the future (technical debt). I.T. will not trust The Business to make rational decisions when it comes to features, development timelines and ensuring product quality. The result is a boxing match where each side is trying to force the other into compliance. Now you have conflict. Conflict dismantles good companies.
The Business is used to tracking their sales teams by metrics like “how many calls did you make/receive today?” and “how many sales did you make?” and “did you make X sales by Y arbitrary date?” where Y could be the end of each month. These are things that they understand, and thus like to control. Ask your favourite sales person for their opinion on the metrics by which their success is measured, and I am confident you’ll find that most will sum it up as “the faster I sell things, and the more things I sell, the more successful I am.” This makes sense from an empirical, see-the-figures-on-paper-on-my-desk-in-my-executive-office point of view, but I bet that the sales person in this case is not loving their life. A constant push to sell more, make more money, and do more. Any success in the future just raises the bar for the success which must follow. It’s a losing scenario. Eventually, they either get promoted out of the trenches of sales or they move to another company, resetting the bar which has been set too high. This buys them another year or two of raising that bar, until they ultimately repeat the process again.
Sales people who are put under the gun in such situations often resort to employing any tactic that they can to reach their goals… One of these strategies is saying anything at all to sign the client up. “Sure, the software can create rainbows and unicorns, just sign on the dotted line!” they say. It’s unfortunate, because customers who are hooked into these contracts tend to be very unhappy with the product when they find out that the software does not, in fact, create rainbows or unicorns. Or even a colour wheel and horses. It doesn’t even come close.
In the above case, The Business fails to measure the things that, long-term, make you the most money: client satisfaction and relationships. A good sales person (they definitely exist) is one that keeps the client happy with rational discussions and promises, and who is very transparent about what can and cannot be done and why. A great sales person is one the client loves so much that they’ll keep using your product, even when a better product exists, simply because they fear losing the relationship. This client is a client for life (or at least a long while) and makes you a lot of money. But how do you measure “happiness” and “relationships” long term? It’s a hard problem. Dating sites have been trying to solve it for over a decade. The Business will likely not dedicate the time and resource to do so themselves. So, they measure phone calls, sales, and other crappy metrics to ensure that the sales team are doing their job.
Here’s where we get back to the topic: developers and failure. The Business, who in most cases pays I.T. to create things to sell, employs these same arbitrary measurements when grading development teams. They often only know how to see success as a measured outcome of facts, and so they create the only measurements that they can empirically apply: features and deadlines. Does the dev team build all of the features and hit the deadline? Great. Do they not? Not great. These measurements themselves are acceptable (even good), but the combination of them (lots of features on short deadlines) is the problem.
The Money Talks
Where it gets tricky is in the realization that “show me the money” is how business ultimately tends to run. The sales people very overtly make the money, so they are seen as successful and important people in the company. The dev team also makes money, but is perceived to cost money, and they are seen as a cost-center that must be carefully weighed and measured to avoid excessive spending. What this leads to is an unhealthy practice of allowing sales people the freedom to employ any tactics necessary to land sales and make the money. In a business such as The Business as described, your life as a developer begins to suck.
To close the deal, the sales person will often promise the client almost anything about the software that you develop. They may promise new feature X by the end of the month, they may even promise 10 new features by the middle of the month. Whatever makes the client sign on. Then, the client says let’s rock and your quality of life drops sharply.
The very next thing that happens is The Business casually tries to confirm what seems obvious and even mandatory to them. “So your team will have these 10 things ready to go by the 15th, right?” they say. “This is a million dollar client, and it would be horrible if we lost them because you couldn’t deliver!” and now the pressure is on to do the nearly-impossible in virtually no time.
The dev team might try to politely push back and say that this is practically impossible, but The Business sees the dollars on the dotted line and will not listen. Flip the kill switch. Forego the QA time, all developers must focus on all of these features, day and night, so that the deadline can be met. Why? Because that’s how the team is measured. If the team doesn’t hit that deadline, they’ve failed and the million dollar deal is lost with the dev team seemingly at fault. Developers don’t want to work extra? Order in pizzas and promise them time-in-lieu as soon as the deadline is over with. Note that they will likely never actually see this time-in-lieu because right after this deadline will be the next one, with similar outlandish expectations and even tighter deadlines. And after that, another one. And another one. And the cycle will probably never end.
The Mad Production Dash
So, as the developer, you develop it as fast as you can. The code starts to resemble Frankenstein as you tack on bits and pieces to make it work ASAP. You subdue your ego and uneasiness about the quality of code by commenting // HACK: undo this crap later everywhere. Somehow that makes you feel better as it creates the slight glimmer of hope that eventually you’ll have enough time to come back and undo this monstrous pile of garbage. But you never will get that time, because the next deal is coming down the pipe. And so the code becomes worse. Your development effort completes 1-2 days before the arbitrary sales deadline, and after your QA team flips their lids on having 48 hours to test 1000+ hours of work, they do “critical path testing” to make sure it at least does something correctly and certify it as “good enough.”
The team releases to production early in the morning of the deadline day, and though it takes 5 hours because there are 17 untested things to fix on-the-fly (and realistically they have no option to abort the release or roll back because the consequences will be dire), they eventually shove the hacked up code out the door and declare it done. The Business shows their appreciation in the form of a short, impersonal e-mail that doesn’t name any person of achievement specifically. The development team is feeling underappreciated and pissed off.
What does the future hold for such a company? The code will probably spiral into bug-filled oblivion until it can’t do anything correctly or in any reasonable amount of time. Despite the weeks and months during which the development team pleaded with the business for time to clean up the technical debt, they are brushed off because taking time off of features loses clients and thus money. Then, as it starts to come crashing down in production, they suddenly beg the developers for a quick fix. “Do whatever it is that needs to be done!” they plead as they see their sales going down the drain. And now, because it is on fire and burning to the ground, the dev team is finally given a moment to pay back some of the technical debt that has been accrued during this vicious cycle. Repeat.
When a dev team has no say in the deadlines of the work they must do, they will usually fail. And when they are set up for failure from the start, they will likely get tired of being blamed for the problems without ever being given the time to devise the solutions. This leads to bad work culture, high turnover, and low productivity.
The way to guarantee dev team success is obvious at this point. It’s really as simple as trust between I.T. and The Business. They must keep each other in the loop as stakeholders. The Business has no product without I.T. and I.T. has no job without The Business’s clients. It’s a mutually beneficial relationship and it should be treated as such, rather than mutually parasitic.
A good company’s sales team will often consult with I.T. prior to promising any dates and deadlines when unknowns are involved. It is practical to ask the people responsible for a task how long it will take them to complete a task. This is much like how you might ask a waitress how long it will take for the food to arrive or a painter how many days they need to paint your home. This is a positive and productive discussion. Hallway conversations should become commonplace: “Hey dev team, I’ve got a client who wants to sign on but not until we build X, how long will that take?” The reply is as easy as “We’ll discuss it as a team and send you an estimate with some assumptions to confirm with the client” and just like that there’s a great working relationship that practically guarantees success. The team knows what work is coming, and also knows how long they have to complete it.
The Correct Measurements
If a dev team continues to fail in an environment where trust exists, then that team is likely not competent. They either cannot estimate correctly or cannot deliver within their own estimates. Sometimes devs suck at estimating because they’ve been making estimates under the oppressive sales gun for so long that they’ve effectively forgotten how to give themselves a fair amount of time. The blame for this remains entirely on the dev team, and they (or The Business) must repair the situation quickly and effectively to maintain the mutually beneficial relationship based on trust. As The Business owes I.T. input into the deadlines, I.T. carries the burden of being fair, accurate, and responsible with those deadlines.
Assuming that The Business now has a competent, skilled dev team, the question turns to the customers. If the customers do not like the estimates given to them, this may cost the company sales. Perhaps the customer wanted the impossible and The Business is giving them a dose of reality. Perhaps The Business does not want such a needy customer and they’re in a situation to be able to afford to tell them no thanks. Perhaps The Business realizes that the client’s request is reasonable but the timeframe of the estimate feels a bit long. In that case they can ask I.T. why. If the answer is not sufficient and justifiable, then perhaps the dev team is still not competent. No dev team should be let loose without checks and measures on productivity, but those metrics should be reasonable.
Ultimately, if you want to guarantee the failure of a development team, simply promise features to clients and customers without ever asking for (or trusting) the input of the team that is actually going to build those features. It’s just like telling the waitress that your food must be on the table in 10 minutes, without first asking the cooks how long it takes to safely and properly make it.
If this situation sounds familiar, try talking with The Business about it. Try to help them see it from your point of view. Ask them “how successful would you be if I demanded that you sell 20 new clients by Friday?” and perhaps some light bulbs will start to go on. Ultimately, we as developers often know nothing about sales and have no business dictating their measurable work expectations. They similarly have no business dictating ours, but a relationship of trust can be built to allow us all to work together and accomplish great things.