Around 2001, I was laid off. It was still early in my career, so it was very upsetting. Those who were in IT at the time probably remember the situations that leads to mass layoffs (Dot-Com bubble burst; 9/11). I felt that I was a valuable employee, and had feedback as such, so it was confusing to my still-naive sense of fair play that I should be handed a pink-slip. After the fact, on a phone call with a VP who had left of his own accord around that time, he shared a tidbit that stuck with me ever since, “Managers never lay themselves off.” The truth of it was undeniable, and it lead to a thought experiment that has always nagged at me: if it turned out I was a part of the problem, and not part of the solution, would I have the courage to lay myself off for the betterment of the company?
I have, on many occasions, been a terrible technical lead. For years, I had no idea why people continued to promote me into these positions, even across different jobs. It’s not like I wanted to be a technical lead, they would just walk up and tell me that would be my new job. I was a terrible technical lead, because I could never work out what the job entailed. To become a technical lead, you had to be the most skilled of any of the other engineers — at least that’s the idea. However, to stay skilled you need to code constantly — that’s the “technical” part. The “lead” part, however, never seemed to fit, because to lead, you have to do more than sit at your desk and code all day with your headphones on. How can you stay technical and still lead?
Look, I don’t want you to be offended, but I just don’t want to pair with you. No, I fully understand the benefit of pair programming, and have paired successfully quite a bit with other people. The problem isn’t with pair programming as a concept — the problem is you. I just don’t want to pair with you. You know how people say, “Don’t take it personally?” This isn’t one of those times — you should take this personally. Fundamentally, I am less productive as an engineer and less happy as a person when I pair with you. As a result, I’m not going to.
Ever heard this one: “Come on everyone! If we’re going to make the deadline, we’re going to have to put in some hours!” or “Jimmy is really working hard — look at all the hours he’s putting in!” Yes, Jimmy is putting in a lot of hours. Yes, Jimmy comes in at 9:00 am, and leaves at 11:00 pm. Jimmy is putting in hours. Jimmy is also writing crap that has to be re-written, missing requirements, and pumping out more bugs than functional production ready code. But boy, he sure is putting in hours.
Obviously, if you want a high quality product with a clean codebase and low defect counts, you need to be very careful and methodical in your approach to developing software. Ready-Fire-Aim is a sure road to disaster, leading to chaos and confusion. Not only that, but it speaks to a general immaturity and lack of professionalism of the development team and its members. That is, unless you iterate rapidly and continuously improve.
The psychology of the average software engineer is fascinating. Not only do they develop a sense of entitlement towards management, as well as an attitude of elitism toward Product and QA, they will also seek to segment themselves from other software engineers through the selection of their programming language. Following a fraternal instinct, the overwhelmingly male software engineering community clumps into programming language cliques, and once the bond is established it can last their entire career. Sadly, much like college frat-boys attempting to define themselves through Greek letters, defining yourself by your programming language is both pathetic and myopic.
School has conditioned us to think that someone who does not know the right answer off the top of their head is an idiot. At this very moment, all around the world, students are called on by their teachers to answer a question, and are publicly humiliated when they don’t know the correct answer. Their peers are taught that it’s OK to jeer at someone who doesn’t know the right answer – even if they don’t know the right answer themselves. As adults in a technology profession, we see this same mentality manifested as interviews that go badly because of one wrong answer (“They should have known that!”) and first impressions that are forever stained (“That guy doesn’t know what he’s talking about”). If only it was that simple.
A closing interview question I sometimes like to ask is, “Is writing software more like stacking bricks, or playing high speed chess?” Asked my own question, I might answer, “It’s like playing high speed chess in order to figure out which bricks to craft so that I can stack them.” Stacking bricks, with no caveat to explain their origin, couldn’t be a more incorrect metaphor for developing software. It is monotonous, predictable, and not mentally taxing in the slightest. Playing high speed chess, on the other hand, is a grueling intellectual process, and one that cannot be sustained indefinitely.
In the English language we don’t say, “They made so many mistakes in the past that they know how to avoid them in the future.” Instead we say, “They’re experienced”. Making mistakes is what gives you experience. If you come out of college, and for your whole career never made one mistake, then only one of two things have happened: 1) You are bull[sh*t]ing yourself 2) You have never tried anything outside of your comfort zone. “Comfort zone” refers to things you already know how to do well. When you step outside your comfort zone, you will make mistakes, and the question then is how to recover.
I once created an engineer performance grading system to help management understand when an engineer was ready to be promoted from junior, full, senior, and through to principal. There were seven criteria, one of which was “Grace Under Pressure”. As you become more experienced, your ability to deal with the pressure of tight deadlines, fluctuating requirements, and idiot co-workers should increase as you find creative ways to cope with the stress. Dealing with stress becomes the hallmark of someone with a lot of experience. One of the best ways to deal with stress, I think, is humor.
In the software industry, there are always jobs. Sure the larger economy might tank, unemployment might skyrocket, but there are *always* jobs when it comes to writing software. This is one of the reason why people go into writing software in the first place — guaranteed employability. If you’re an out of work software developer, and think I’m being unkind try this: drop your asking price below market – they’ll hire you. The problem is, a job is one thing, but finding the right job is another entirely.
Held captive in a status meeting, your moment of shame approaches. Vulnerable and exposed, like a naked baby laid before encroaching doom, you await your turn. Your peers’ bold claims, naive honesty, and feeble excuses are recorded for posterity by a stone faced facilitator. They work their way around the room, thinly masking disdain at any answer that is not a crisply delivered “I’m done”. Finally, the time of judgement is upon you. As you fumble to explain your lack of completion, you are interrupted by a question that has struck down even the strongest among us: “When will you be done?” Fighting back a swelling tide of emotion, you try desperately to think of what you can say that you haven’t already. Step aside my child, let me handle this.
Want to find out if an engineer performance tested their application? Tell them to do one thing for you: Make it crash. That’s right, bring the network traffic to a crawl; force it to run out of memory; take away disk space. Have them demonstrate that they know the limits of their application so well, they can make it fall over at will. If they’re bad ass, they’ll whip out a test script and start it up. In a few minutes, the application should crash in a predictable way — predictable if the application is well designed. But really, my point here is to try to make it crash but not be able to.
Corporate culture is obsessed with the term “leadership”. They pride themselves on being “leaders”, and for fostering “leadership” within their organization. We even have the idea that everyone is a “leader” in his or her own right, each taking personal accountability over what they do every day and “leading” in their own special way. I glaze over when people talk about leadership. I fully expect that you’re glazing over just reading the opening of this article. It’s old. It’s stale. We’ve heard it all before. At this point it’s boring. Someone who takes ownership of cobbling together a PowerPoint before a big presentation, and the people who lead troops to storm Normandy ain’t the same type of leader. They ain’t even in the same ballpark. Those types of leaders didn’t want to lead, they were drafted into it and rose to the occasion. To the rest of us, these are the people we want to call leaders.
If you’re a senior-or-above talent, you know how work longer hours without it significantly impacting your work product. For this, I’m talking about the 40-50 hour range. Most people start to fall off around the 50-60 hour range, and we all start producing crap around 60-80 hours. Beyond 80 hours, it probably time to look for a new job. Having said this, let’s focus on the 40-50 hour range. If your employer suggests or requires that you work these extra hours, it’s probably not going to destroy your home life, or wreck your sense of well-being, so the impact should be minimal, if not negligible. Why not work these extra hours? Because you’re not getting paid for them.
In yesteryear, in the time of our coding forefathers, ancient project managers would gauge a developer’s productivity my measuring the lines of code added per unit time. This was a convenient and intuitive metric, as there was seemingly a correlation between number of lines coded and number of features added. When companies then started rewarding developers according to this metric, it lead to a rash of bad programming habits – most notably copy and paste coding. In modern times, we consider ourselves enlightened, and claim to have realized that not only is there no direct correlation, but that attempting to measure developer productivity in this way is both meaningless and destructive. Yet, if you corner the average development manager and ask them to compare developer productivity, many of them would not be able to resist the urge to pull metrics from source control. This due to a lack of awareness of a complete reversal in the way in which lines of code reflect productivity.
Nobody wants to manually test software. “That’s not true! I do!” you say, missing my point. If you think you want to manually test software, then you need to dig deeper into what that entails: To do your job well, every time any developer changes anything to any part of the system you need to re-test everything. Anything less and you’re not doing your job. If you’ve heard different then they’re lying to you. *That* is what Quality Assurance is – the assurance of quality. The only way you can be sure that some developer didn’t break something is to test the whole system again no matter how minuscule the change. On a simple mobile app, that’s not so bad; on an enterprise system, you may end up throwing yourself down a flight of stairs just for a change of pace.
First, let’s define “fired”: At some point, you were informed that your company has made the decision that they no longer want you working there. There are 3 broad categories for which you can get fired: The first is a violation of company policy, which includes absenteeism, tardiness, poor personal hygiene, threatening a fellow employee, discrimination, and sexual harassment. If you’ve been fired for any of these you deserved it, and you better get your life right before you look for another job. The second is incompetence, but most companies require extreme incompetence for a long period of time even after their attempts to train you have failed before they fired you. If you’ve been fired for that, well, you may not be smart enough or hard working enough for this line of work. Blame your parents for not making you study and do your chores. Finally, there is getting fired for standing up for what you believe in, but what you believe in is not in line with the what the company wants.
No organization would say they strive for mediocrity, yet so often they inadvertently reward employees for mediocrity and punish them for excellence. This slippery slope begins by attempting to define a job by the lowest common denominator of skills and responsibilities. Indeed, we hire for this lowest common denominator, and upon hiring we inform our new employees that they will have their performance measured, with an emphasis on executing in accordance with their new job’s requirements – job requirements that were determined through an examination of lowest common denominator expectations. There is often a hint at how an employee can exceed expectations, but no matter how this is presented it typically traces back to number of hours worked above those required. Having hired for mediocrity, set expectations for mediocrity, and offered incentives for longer hours which will lead to an eventual reduction in overall performance, we have successfully created a drone – a fungible resource that can be replaced or scaled a moment’s notice should the need arise. This, in essence, is the role of a middle management – to recruit and groom drones incapable of stepping outside of a company’s documented expectations.
Look, I don’t see what the big [flippin] deal is. We all curse – all the time. Stop [bull pooing] about it – you do, they do, we all do. When you’re around your friends having a drink, you curse like a [mother flippin] sailor on shore leave. So why is it not allowed in the work place? Because it offends people. Well you know what? It offends me that I can’t curse! Now I have to spend all my [gosh darn] time tiptoeing around your [flipped] up [bull poo] instead to telling you like it is! That’s not only frustrating, it’s a waste of valuable company resources!
It’s human nature to be trusting. We don’t want to think people are out to get us, because we don’t want to live in constant fear. I get that. As a normal human being, you can’t walk through life being afraid of your shadow and paranoid that someone is out to get you. However, as a software developer writing internet deployed code, that exactly how you have to think. If you are constantly vigilant, do everything right, cross all your t’s and dot all your i’s, you will still introduce vulnerabilities without knowing it. Sometimes, the attack will come in ways that will blow your mind…like say a camera phone in a coffee shop.
Fresh out of college, you have no idea what you’re doing. This fact is true no matter how much you paid for you college education, where you went, what your GPA was, or what Latin title was bestowed upon graduation. You have no clue, because you’ve never had a real job – this is your first. The number one gauge of being good at a job is experience in doing that job, and you have none. You may think that your college education is an indicator of how quickly you will master your job, but there is no correlation. It might actually work against you, because if you believe you already know everything you won’t be open to learning anything. If you want to get good at a job and you have no experience, you’ll need to apprentice under someone who can show you the ropes.
“Good morning everyone. First, let me say how excited I am on this, the first day of our new project! The goal of the project is to build a single family home, and we have a month to build it. Working closely with our team of engineers and architects we have broken down all the individual requirements for the house, estimated how long they will take, and all we need to do today is prioritize them. Since building houses is intuitive to everyone, this shouldn’t take too long, but I’ve blocked out 2 hours just in case we need extra time. Let’s get started!”
How good are you – really? Are you a master of your craft, merely mediocre, or do you suck? How would you know? Asking other people tends to yield nothing more but polite indirection and flattery, or at the other end of the spectrum rudeness masquerading as honesty. Within your organization, there are annual reviews, but they only gauge your performance against set expectations, not how you stack up to your peers. Without true visibility into other organizations, much less how their employees perform, you’re left with how they describe their employees: Typically infallible and elite. In truth, there is no yardstick to assess your own abilities compared to others, so what are you to do? How do you know if you need to improve, if you’re perfectly adequate, or if you’re so good that you need no further improvement?
Stop adding features. That one mantra — if followed consistently — would improve the majority of user interfaces. In terms of concrete evidence, it’s out there in droves, but I leave it to the reader to discover the truth of it. In essence, humans have a tough time finding what they need in a sea of what they don’t. The more features you add, the more the likelihood that you’re adding what the user doesn’t need at a given point in time. This guideline, as simple and intuitive as it is, is an extremely difficult pill to swallow for business that make their money selling new features.
The majority of meetings are a waste of time for the majority of people in them, yet we call them mercilessly whenever we feel there is the slightest communication need. Meetings have no cost that can be directly measured, but a benefit that can: People sat in a meeting for a period of time. Really, as stated, that can only be a good thing — especially if it’s the right people. With this in mind, great care is taken in the selection and culling of meeting attendees. After all, without the right people, how can it have the right outcome? This is where the concept of the meeting breaks down, as “the right outcome” is rarely understood much less articulated to attendees.
I never get why people panic at any point during a deployment. When you’re doing a deployment you’re in only one of two situations: 1) You’ve never deployed the app before 2) You have. If you never deployed the app, there’s no audience to complain if things go wrong, so take your time and figure them out – no need to panic. If you have deployed the app before, you damn sure better have a rollback rip chord in place. Fact is, the vast majority of deployments are done without even the semblance of a rollback plan. The best they have is to restore the database from dump files and build an earlier source control tag. That’s not a plan, that’s inviting disaster.
If, as a developer, you care about security, you need to be constantly running pentests against your own code. Constantly – and I’m not talking about buying an off the shelf tool that will do the scanning for you. Those are important, but they’re something that QA or Operations can use to cross-check your work. What I mean is good, old fashioned, trying to break into the software you just wrote. This shouldn’t be too hard, you wrote it! You know where you usually slack off, so you’re in the best position to find vulnerabilities in your own code.
Agile. Don’t roll your eyes. Yeah yeah yeah you say, and I appreciate that – at least you’re being honest. Agile ain’t panning out. All of these good things were supposed to come out of it, but it all just seems like a disorganized mess. People are complaining, work isn’t getting done, and all the while you’re reading about how good it is. You don’t get it. I understand. You wouldn’t get it, would you? You’re doing it all wrong. You made the common mistake of thinking that somehow Agile was a relief from the rigors of Waterfall methodologies, and that you could be on a perpetual process vacation.
Deploying sophisticated software onto the internet is not easy. It involves lots of fine, intricate steps being executed in exactly the right sequence, and if any one of a thousand steps is not done in precisely the right order, the whole thing will fail. Knowing this, what do we do? We put a bunch of people on standby just in case anything goes wrong, and make sure that everyone is on a conference call and in a too-massive-to-communicate-effectively chat room at 2:00 am so that they can be Johnny-on-the-spot if something goes to wrong. Here’s a tip: If you are so nervous that something will go wrong that you need to have dozens of sleep-drunk people around ready to fix something they might have broken (or harass someone else who may have broken it) then you have too many damn humans involved in a process that needs to be fully automated.
When we see a crappy user interface we know it. We can’t articulate it, but we know it. We look at it, have that sinking feeling in our gut, and try to figure out a way to say something about it. But we can’t. We’re afraid that we’ll offend someone, or worse yet have the wrong opinion. And really, that’s all it is – your opinion. That’s really the problem. If your assessment of a user interface is only your opinion, how can it be valid? It’s valid because you *know* it’s crappy. You don’t need a degree in human-computer interaction, industrial design, or usability engineering to know it’s crappy – it just is.
Well, we’re all writing services now. This is a service, that is a service. We need a persistence service, a web service, service generating service, and services that service other services. Please stop. Put the word, “service” down and think about what you’re doing and saying. Everything you’re writing ain’t a service. “Service” ain’t the new term we’re using for “code”. You’re not always writing a “service”, sometimes you’re just writing a class. When you’re writing a service, it’s got a higher purpose and meaning that your average piece of software. It’s got to service something, or someone.
Hand me your credit card, you idiot. No, when things start running slowly don’t just blame the hardware. Yes, hardware can affect performance, but if you just did a release, and at the same time you started to see a spike in system resources without a spike in load, the problem is in your software. “But hardware is cheap! We can just buy more hardware!” or the more contemporary, “Cloud instances are cheap! We can just spin up more instances!” You twit.
Maintenance sucks. I don’t care who you are, or what you’re into, maintaining legacy code sucks. You spend your days getting asked to fix other people’s bugs in a labyrinth of crappy code that was clearly written by angry monkeys who could inexplicably hurl feces at a keyboard in a manner that would yield compiling code. In fact, it’s not called “maintenance” if the code is good — that’s just normal development. If you’re on maintenance, then you have done something very wrong at some point in your life — or you’re just starting out. Much like anyone new to anything, you’ve got to pay your dues. In software development, that’s working maintenance.
Shockingly, the word “arrogant” has haunted me my whole career – and really my whole life. I’ve looked up the definition of “arrogant” more times than I care to admit, trying to contrast it with “confidence” and “humility”. I’ve been told more than once that I needed to work on being “humble”, and have genuinely tried to be so. Tried and failed. In terms of personal soul searching, “arrogance” has occupied a disproportionate amount of my staring-at-the-ceiling-trying-to-fall-asleep time. I don’t want to be arrogant – I don’t like the very idea of it, and am ashamed and confused that I seem to attract the description with alarming frequency. Ironically, an aspect of arrogance is an abundance of unwarranted confidence, yet I have no confidence that I can conquer the label of arrogance.
Would quality be better if there were no Quality Assurance people? Let’s face it, most engineers abuse QA. They write a bunch of crap they’ve never tested, declare it’s done to much fanfare, and throw it over the wall to QA while they sit back knowing it’s going to take QA at least a day or two to start writing up bugs – more than enough time to get in some solid games of foosball. Furthermore, once they have *said* they are done, the pressure is off of them, and on QA to find them, at which point the engineer can sit back and pick and choose what they feel like fixing under the guise of “triage”.
When your boss comes demanding you scale your team, don’t immediately fire up all the recruiters you know and start sifting through resumes looking for the perfect hire. First, give some thought as to what you were just asked to do. You weren’t really asked to hire more people (that’s expensive and risky), you were asked to boost productivity. The first place to look for more productivity is at your current team – especially at the novices. Most teams have some novice to average players who could use improvement, but we tend to ignore them assuming they can’t get better at what they do.