I started writing this a couple months back, and could never finish this cause I kept thinking of more “rules”. I decided to go nuclear, cut the rants and maybe half the content, to just get something delivered. I hope it helps folks getting into software, or at least re-affirms things you already know. Also, feel free to debate on these “rules”. These are my subjective opinions that I’ve witnessed in my not so long experience (I think it’s five years now) in working with software professionally.

Photo by Toa Heftiba on Unsplash

Be as specific as you can, when asking for help

I’ve seen this rule broken constantly, and the proof why this rule matters, is right where you’ve seen this rule broken. Nobody will help you if you don’t put any effort. See, people are lazy. They know that if you ask a very generic and broad question, they are going to have to ask clarifying questions and/or make an assumptions before they can answer. That’s a lot of work. Try to meet them at least half way.

People can only help you as much as you can make yourself available to help. If you need help, explain what you’re stuck on, what you’re doing, what you’ve tried, and what you think is the answer. Nobody (well hopefully) will judge you if you make the wrong conclusions about something, they will judge you if you don’t put in any effort and will likely not help you.

Also, people like to help others, especially when it’s public. If you help someone else, you broadcast your helpfulness, and people remember that.

If you can’t reason about something in plain English, you probably are overcomplicating your design

Choosing the right level of abstraction is often the hardest problem of computer science. Too much of it, and you’ve transformed your problem into these generic clouds of words that you no longer can reason about and are too far away from the problem to be useful. Too little of it, and you can’t discuss a change without mentioning every little thing in your solution for it to make sense. Always strive to make things as simple as you can, until you can’t, then go back and try to makes things simple again — but you have to a strike a balance between too simplified and/or too low-level. Now it’s easier said than done, but this tip is just a signal for you to investigate if you can minimize complexity, not how to actually do it. You should be able to talk to a stake-holder in plain English about how a process in your code works, and it should roughly translate over to the operations in your code base. Another litmus test for your codebase complexity, is see how quickly engineers onboard to your codebase.

Leave your judgement of the competences of others at the door

Everyone makes judgements, the important thing is not to act on them. Focus on the problems and solutions, not the folks involved in them. There is no value in having an internal-dialogue about the competencies of a co-worker, it is always counter productive. Prying on others, and giving your unsolicited take on their skills, reduces you to a bully, will harm your brand, and will take away from your time to do actual work. When performance review time comes, that’s the time to give your honest feedback (with data), and continue working. But don’t let it pollute your brain, instead, focus on yourself. If you want to think about competency, think about yourself. Think critically about how you could better run that meeting, or accomplished that task. When you get feedback, understand why you got that feedback, and derive a plan on how to improve it. For example, If someone asks you to reexplain something that you‘ve explained before, re-explain it again differently and then ask what helped them understand it better now so that you can do better next time. Focus on yourself.

Don’t worry about talking smart, be smart

Photo by Headway on Unsplash

Brevity is the soul of wit. The goal of communication is to get your point across as quick as possible, it’s not to impress people with your vocabulary. Having an enhanced vocabulary will help with choosing the right words so that you can do this, but using “fancy” words just for the sake of them, is objectively counter productive. This doesn’t mean speak like a cavemen, but this means, don’t make your language so opaque that person listening to you won’t understand what you say, because you want to use a lesser known adjective vs a common one. Be direct and easy to understand, and of course, choose your vocabulary based on your audience. i.e. don’t talk about “behaviors” with stakeholders or “ebitda” with engineers.

I recall once joining in a meeting with C-suites of a very large blue-chip company. I expected these MBAs to speak with very posh English matching their tailored clothing, but no they spoke with the same candor as a high school student. “When can this be finished”, “do we really need to do this right now”, and “how is this different than X”. If someone entered the conversation with corporate jargon, they see right past it and ask specific questions. The same holds true for technical folks, if you hide behind your technical jargon, eventually you’ll run into someone who wants to get to the bottom of what you’re communicating. Hopefully then you can respond specifically, but you wasted all this time getting there.

Speak simply and clearly, choose the right words, and get your point across. Use examples, and analogies if you need to. If every conversation you have turns into a rant, your core message will get diluted and your audience will lose track of your point. You probably need to frame your ideas better. Just having simple jot notes (even for trivial meetings) of what you’re going to say, let’s you stay on track, get your points across, and leaves you more room to actively listen to others. Stop using jargon for the sake of it. People will see right through your bullshit. Look at people’s faces, are they nodding, are they still interested in what you have to say, are they asking follow-up questions. Use these signals to judge how well you are getting your point across. And, when you want to ask if something makes sense to people, don’t just ask “does this make sense”, ask a question specific to your topic reaffirming their understanding. i.e. “so do you understand now why we choose X instead of the Y”.

If you can’t communicate a point, don’t say anything. Also, writing

Always scaffold

When I first started coding, and I’m sure others felt the same way, one of the hardest things that I found was writing that first line. You’re just staying at your black screen with that blinking cursor, and you’re thinking how should I start. I remember my TA back in university then saying, just write comments about what you’re trying to do, and then slowly fill it in with code. I still use this idea to this day. It’s similar to how you were taught when writing essays where you start with the structure and points, then you just fill in the words. You don’t always have to start at the beginning, you can fill in the things you know for sure are to be completed, test them, and then maybe by then, you’ll understand how to write the beginning. Many times we deal with quite complex problems where the solution is emergent when you need to work through something to solve it vs something that can be solved declaratively at the start. Scaffold, work on what you know, and then hopefully, you will get more clues on what will or will not work. As you get more data and familiarity, you can then come back, and fix parts you don’t like. Scaffolding also guarantees that you have at least some structure to your code from the start.

There is no such thing as Perfection

Photo by Nick Fewings on Unsplash

Your code will never be perfect. If you sit there constantly pondering how how to make your code as clean as possible, you’re wasting time. You’re dealing with inputs from the outside world. You are never dealing with a closed system. Do your absolute best when you can, but keep moving forward. Section off time to deal with technical debt, when it starts breaking down productivity, but don’t do it in isolation. There should always be a reason, since it does take work. My hot take is that perfect code isn’t useful. It’s so optimized for a defined problem that it can’t morph for new ones. Strike a balance, let the problems define the code base, not your sense of code design (which also is extremely contentious among programmers). Okay this is debatable, you could argue perfect code would be able to handle new problems and they’d be a way to extend it without code modification, but I ask you this, have you ever gotten all your requirements up front from a customer, and can you truthfully name zero examples of you being surprised with a requirement. There will always be something you can’t capture in the domain you’re coding in (you’re making a model). You won’t be able to capture it all in code, and if you did, you would have to make assumptions, and in too many assumptions, some are bound to be wrong. Use the principle of parsimony, choose the option with the least amount of assumptions. Don’t couple your code to reality.

Don’t always code

This is a short one. I find coding extremely enjoyable. You get to solve problems hands-on. It scratches an itch for me. I love seeing what I’ve built being used. But don’t overdo it. I’m a firm believer that you have only a select amount of time of deep work per day (approximately 4 hours), and that is given that you are well-rested with no distractions. If you try to churn out code in more than that allocated time, it actually becomes counter productive because you will burnout. This will cause a net negative effect on your productivity.

Also, if you code 24/7, you tend to become a jaded person that people don’t really like to be around. Life is pretty fun! Don’t make it all about your job. I always find that proper breaks and doing activities completely irrelevant things to coding, actually makes me better at coding. It’s similar to a good night’s sleep. Refresh your brain, and come back with fresh ideas. Let your subconscious debug your code problems.

Understand your environments and how to fully utilize them to achieve correctness

Take time to learn your editor inside out. Once you learn the hotkeys, and get an IDE that indexes your codebase. You can quickly search symbols, files, strings, and dive into functions, check your types, docstrings etc. You can get to the bottom of reading code fast.

Understand how your application is deployed. Know the differences between how your applications run on your computer vs in your deployment system. Don’t worry about the hardware, but see how your configurations are set. A lot of times, you can prevent painful bugs by being cognizant of how the application will run in the cloud from the start. You also then get good feedback while coding, run tests quicker, and utilize all the tools you need for correctness. While it is a pretty huge upfront cost to set this up and understand all this, it will pay dividends later and help you in all your future projects. Also, DevOps and SRE folks will like you more.

Great collaborations skills are just as valuable as technical skills

Collaborators are able to combine the brainpower of the people around them to solve a problem quicker and more correct. We work with concepts that are too large to store in one’s head and there is limited bandwidth in which people can communicate with. If you’re able to create an open environment and probe the discussion in the right way, you can ensure a good network of communication in which you will get to a great solution faster. Everyone you work with has a different set of eyes and perspectives, if you can get all their input towards a decision, you can be sure it will be better than you one you came up by yourself.

Don’t get attached to your ideas. It’s just a job

This is an easy one, never personally invest yourself into your code or solutions. We put a lot of effort into things, but sometimes, things just don’t work out. You run out of money, or time, or the problem no longer exists. That shouldn’t bother you. It’s just a job. Take pride in what you learned, and use those learnings for your next challenge. The absolute most important skill is learning how to learn.

Don’t just blindly suggest changes, do your research

Sometimes the reason behind the choice of a certain tool (that you dislike) at your company is arbitrary, but most of the times it not. There is often a long lineage of decisions that is needed to be understood and debt that needs to be paid out, before you can implement a new solution— and it could also be the case that your solution does no better than the original when it is tested at the same scale. So similar to the earlier tip “Be as specific as you can, when asking for help”, make an effort! Ask yourself, “what are the issues with the current system that the new one addresses?”, “have you estimated the amount of money/time migrating this new database is?”, and “how does this affect customers (if it does at all)?”. Solutions should come from problems and they must be derived from evidence.

Write code for the reader

Don’t write code that optimizes for less lines. Write code so that the reader can understand. That’s the only rule. Compilers these days are extremely robust, they will get rid of extra lines/operations and shrink your code before it is run. So optimize for readability, not number of lines. The off chance that the compiler will run an extra instruction or two because you chose a more verbose way to express you code, is worth it, if the reader can understand it quicker. Practice clean code, name things as best as you can, and write test cases that explain your system. Don’t do those stupid one-liners. Use declarative over imperative syntax if you can.

Assume humans will eventually mess things up

Photo by Kilian Karger on Unsplash

This is just Murphy’s Law. Just think of yourself in the most sleep deprived and distracted state using your system. You wouldn’t want to leave anything important to yourself in the state. Validate as much as you can. Don’t leave technical details to the hands of humans. Make sure you have safeguards, test those safeguards in isolation, and then test using the safeguards in your system. Make sure your AZ-5 works. I once deleted a table in production (there was two tables with the same name, one that was unused for months and was supposed to be deleted — and the other well, it was used heavily, they were in different namespaces and I didn’t know my script had access to the one being used) because of some bad logic in my script and I didn’t validate it before clicking delete. I also love to click buttons, and I had already been running the script for weeks. Luckily, I knew how to restore the table from back up. You will make mistakes. It’s impossible for you think of all the edge cases and you can’t automate absolutely everything. So at least when you’re doing something that you can’t automate and has huge repercussions if done wrong, do it with a partner and/or explain out loud what you’re doing along the way.

It really is just pattern recognition most of the time

You won’t get better overnight at writing software. You will slowly accumulate an abundance of little facts and prompts to google. You will recognize the same patterns, and come up with solutions quicker. It is a marathon. You will start with one framework. Maybe learn a language or two. Then, as you start a new project, it could be a completely new set of tools. But you will start to recognize similarities. You keep doing more projects, and keep coding. Eventually, you will have a repertoire of experience that will aid you in quickly understanding new things. Your brain will just pick up on the concepts quicker since you’ve already been primed. It literally just gets easier and easier but you just have to start and climb through the hard starting stages.

know the difference between good and bad evidence

Anecdotes are crap. Look at data, and direct proofs (walk through the solution yourself). Understand the logical fallacies. Now it may be the case that you don’t have any data or direct evidence on why to do something, in that case, clearly state your assumptions and in your first trial of a solution, include a process on how to get data so that you can either prove or falsify your solution. A sneaky trick that some engineers do is that they provide reasons for doing X to fix a problem Y but Y doesn’t actually exist. They show mountains of evidence bout how X will fix problem Y, but they don’t clearly define problem Y. Then, you realize that the actual problem can’t be reduced to problem Y so their whole spiel about doing X is baseless. Catch that, and don’t be afraid to challenge it. Save wasted work.

know the difference between a fact and an opinion

A fact must be true or it’s not a fact. An opinion needs to be sold with facts, and it is also an idea, and ideas usually have emotions attached to them. This doesn’t mean discard people’s opinions, it just means you need to do some extra work to ensure another person’s opinion holds true, you can’t just assume it’s true like facts are. Get all the facts, let go of feelings attached to ideas and validate them, establish your evidence, then derive a conclusion on top of them.