After being in this industry for more than a decade now, there are a huge set of learnings that I have gathered.
From programming microprocessors in assembly language on a dedicated hardware programmer to working on petabyte scale data pipelines, I have gained experience with many different paradigms of programming world.
Also, from working in a small one-room startup to a global conglomerate, to starting my own, I have also experienced many different organizational aspects and how they shape the entire software development process.
All these have allowed me gain a lot of insights into the software development process (and in general, people too).
Here are a few of those. Hope they’ll be of help.
1. Know your tools
Make sure to know your tools very well before you start off using them. Know all/most of their default configurations, settings, as well as understand what implication tweaking any of these has on overall system, as well as other parts of the system.
2. Monitor everything that can impact your system
Monitoring is a must. Make sure to have detailed insights into the workings of every system, at every second.
3. Have performance numbers for all parts of your system
Measure performance of every component of your system, and how much it can be overloaded, and for how long. Also measure what happens in overloaded situations.
4. Keep it simple, stupid
KISS principle (Keep It Simple Stupid) with all your heart and energy. If it’s going beyond being simple, use a framework or a library, but not before.
5. Minimize shared state, and the distribution of it
If there has to be a shared state between systems, make sure it is at one, and only at one place, and is itself NOT distributed. In a scenario where this shared state suffers corruption of data, all the systems communicating with this should halt immediately, and none should make any further change. Of course, realtime alerting is a must.
6. Never handle-and-ignore exceptions/errors in helper methods, throw them to the caller
Never catch any exception in helper method(s). Just throw them. Make it the duty of the caller to catch all/any kind of exception. If there’s any extra information that a callee can add to the exception, for example to aid with debugging, add it, and then throw it again. But never, ever, catch and ignore exceptions in helper methods.
7. Never trust anything not in your control
Never fully trust anything that’s out of your system and control. It may not function as expected, no matter however reliable it is advertised. At least have a retrial, manual intervention, alerting, and halting mechanisms in-place.
8 fallacies of distributed computing… remember them
- The network is reliable.
- Latency is zero.
- Bandwidth is infinite.
- The network is secure.
- Topology doesn’t change.
- There is one administrator.
- Transport cost is zero.
- The network is homogeneous.
9. Write test cases, they help when you’re in need
Write test-cases. They consume a lot of time to write, maintain and generally slow-down development a lot. But down the line, after a few years, and with a different set of engineers from those who wrote those codes originally, you’ll be hard-pressed to explain how, and in certain situations, even why, a certain piece of code works. Things become legacy really fast. Faster than you may think initially. Test cases help. You can start by writing a few cases for the most complex pieces of your code, and gradually add more.
10. Have code reviews
Get your code reviewed. It doesn’t matter if you are the senior most person in a company. Anyone can spot a mistake. Everyone can contribute. And anyone and everyone can have a different perspective on the problem at hand. Get people involved. You’ll have much higher chance of deploying a better code. Not to mention, you’ll learn from other’s thought processes too.
11. Never stop learning
Keep learning. Keep experimenting. Keep reading articles, blogs, use-cases, specs, papers. All of these help to keep you keep updated. Also they are pretty fun to read. Just keep playing around with anything you can get your hands on. It doesn’t even have to be directly related to what you do. Have curiosity that of a child.
12. Do what’s right, take stand for it
Take a stand for what is right. Even if that means speaking against your seniors and your colleagues. Never hesitate to do the right thing. Don’t fall for emotional traps. If the situation requires, and unfortunately does come to this, leave your job. There’s no point to keep working at a place which doesn’t honor your points knowing they are right.
13. Design comes first, implemention later. Don’t mix these two
At the start of a new project don’t just jump straight away to code. Spend more time, much more time in thinking about the design of the system. Go through the requirements again and again until you clearly understand them by your heart. Point out anything if it’s not clear or you believe does not have rational explanation. Coding should come last. You should have complete end-to-end picture ready before you write even one line of code. Remember: adjusting the design on paper or a whiteboard is much easier to do than so in code.
14. Over-optimization IS a thing, and is bad
Do not over optimize. It looks awesome initially, but ends up creating much more unoptimized system in long runs. How…simply because simpler systems are much easier to optimize (and maintain) than overly complex ones. Simplicity has it’s beauty in everything, including code. Embrace it.
15. Read the f***ing manual
RTFM (Read The fucking Manual).
StackOverflow are both helpful, but real thing is in official manuals and docs. Copy-pasting works most of the time, but what you end up missing is the other stuff. That other stuff is something that could have helped you design a system better the next time you approach a similar problem. If time constraint is there, make sure to add it to your reminder to go about it some other time.
16. Consistency in code helps everyone
Follow consistent naming conventions. It’s ok to differ on naming conventions across languages, but for a given language, make it a habit to have consistency. Such consistency not only helps in understanding of the code better (and fast), but also allows usage of many automated tools which rely on such consistent naming conventions.
17. Have the ability to experiment fast
Have the ability to run code locally from day one. This might seem trivial for smaller projects with zero to almost zero dependence on external services, but becomes pretty cumbersome once the project has grown big and relies on correct functioning of 10s of external services. Mock those services if, for whatever reason, any of those can’t be run locally. Having the ability to experiment fast gives you the ability to build fast, and build right.
18. New technology is a long-term commitment… plan for it
When planning to introduce a new technology or a framework into your stack at a critical place, make sure to do a very thorough analysis of it. How active it is, how many issues does it have, how helpful the community is, how extensive the documentation is, how many questions/answers are there on stackoverflow, how steep is the learning curve, etc..
19. Get moving
As much as
designing a system before jumping to code is important, equally important is to
begin. Many a times you might find yourself in a situation where you have no clarity on next steps. Also, almost all the times requirements will keep changing, and that can happen down to the very last day of your sprint cycle. What’s important is to just begin. Once you start something, you gain better familiarity with it. That means you can now add your inputs to every changing requirements, and help finalize them faster and better.
20. Learn to articulate your thought, well
When explaining something to others, make it a habit to first be able to articulate it in one sentence. If it takes more than one, write it down. Writing things down puts a pressure on your brain that is much more than just thinking the same in your brain. This simple rule helps even while coding.
21. Engineering is an art, treat it like one
Software engineering is an art. Treat it like one. Art requires patience, thinking, and a lot of focus. Software programming does the same.
22. Learn from other’s work
Reading others' code can actually make you write better code. Use github extensively for this. Go visit
github's trending section at least once a week. Pick up any project and just skim through the code. No need to full understand everything. Just a brief browsing will add a lot to your understanding.
23. Assumptions are bad, undocumented ones, the worst
Assumptions in software development process are bad, but they inevitably make their way into it. No matter how much you try and avoid them, they find a way into the system. The best thing you can do when you can’t get rid of them is to
document them at a centralized place where anyone can look them up. Adding to project’s README is one such place. Centralized, company-wide documentation space, is other. Undocumented assumptions are a ticking time bomb.
24. Know the ABC’s of technologies you use regularly
Learn the internal workings of technologies we use almost daily. They help you in your daily work and make you appreciate the effort others have put into them to make life easy for you. Some of these are, http handshaking, encryption, SSL, DNS, system calls, database transactions, character encoding, storage technologies, access control strategies, ldap, kerberos, oauth, saml, and more.
25. Be open to other’s thoughts, suggestions, ideas..
Be open to others' inputs. Your solution, or point might be valid, or even the best one, but that shouldn’t stop you from hearing others out. Listen with an intent to fully understand and appreciate what others are saying. In almost all the cases you’ll gain something better.
26. Put yourself in other’s shoes when building something
One of the best ways to build something right is to put yourself in the shoes of your user. Your user can be your product’s user, or a colleague from another team. Building this way gives you a perspective that is generally missing otherwise. It also makes you relate to the other person, or team, much much better and helps build a trusting relationship.
27. Work-life balance, is an important thing
You work so you can live, not the other way around. Remember this. You are the best judge of maintaining this balance. Each one impacts the other.
28. Be humble and respecting to others
That’s all, folks ¯\(ツ)/¯
Drop me a mail at
firstname.lastname@example.org or DM me on twitter if you have any suggestions or need any help with software development.