Good vs Bad Software Engineer, while a cliché, was something that I wanted to write about. Thankfully, I realised very early that there are no good or bad engineers. Instead, there are the engineers that improve over time and the ones that don’t. Everyone starts the journey at various points in the badness meter and, only with persistent efforts, becomes better at their skill.
A bad engineer is one who does not improve with time.
Hence I am not going to focus my energy on writing about a topic with a negative connotation. Instead what I am going to do is to share my perspective on how to improve at your craft and become a better software engineer – something that I really care about.
Know your tools
One of the metrics to measure the skills of an engineer is productivity. Productivity is the ability to generate high-quality results with the least amount of effort and time.
Tools play a big part in ensuring engineer productivity. A feature rich Integrated Development Environment (IDE), a capable debugger, a great unit testing tool/framework all make our lives simpler. The onus is then on us to make the best use of these tools.
Take the IDE: it’s a cardinal sin not to know the keyboard shortcuts for all the common tasks you perform every day inside the IDE.
Using a debugger (maybe part of IDE or not), then learning about its capabilities and how to debug effectively. For example, do you know the difference between Step Into, Step Over, and Step Out?
You can go a step further and extend your IDE with numerous useful extensions/add-ons to make your life easier. Extensions/add-ons such as ReSharper (for Visual Studio), TSLint (for Visual Studio Code) are some good examples in this category.
The bottom line: learn to use your tools effectively and constantly look for new tools/extension that can further reduce manual effort.
Handling information explosion
Even with a decade of experience under my belt, I still at times feel overwhelmed by the pace at which the technology is evolving. Keeping abreast with what’s happening around can become a daunting endeavor. How do we manage this information explosion? There are a few things that have helped me keep ahead of the learning curve. These include:
A healthy mix of new technology and fundamentals
While technology evolves every day, fundamentals remain the same (or do not evolve that rapidly). Still, there is a mad rush to learn new technologies and blatant disregard for fundamentals. Fundamentals may vary based on domain, but these are the building blocks for any technical expertise. Be it programming fundamentals, networking fundamentals, operating system (OS) fundamentals or web platform fundamentals – we ought to have our fundamentals sorted out.
For general programming, there are some classics (books) out there that are almost technology agnostic. Read them! Here is a small list that I recommend (in no particular order):
The Pragmatic Programmer, Andrew Hunt and David Thomas
Clean Code, Robert C Martin
Code Complete, Steve McConnell
Release it, Michael T Nygard
Design Patterns, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides
Refactoring: Improving the Design of Existing Code, Martin Fowler
Growing Object-Oriented Software, Guided by Tests, Steve Freeman and Nat Pryce
Test Driven Development: By Example, Kent Beck
Follow the thought leaders
Every professional field has a few thought leaders who are the best at their trade. Identify thought leaders in your area and follow them. Read what they write, explore what they endorse. Remember, they’ve walked the path you are on now. Follow them.
Follow high-quality content aggregators
There are some excellent content aggregators out there. Explore them. Sites like:
InfoQ – a great resource for software engineers with a focus on software development. A site that I personally use and recommend
TechCrunch – for business and tech news
ProductHunt – “a place for product-loving enthusiasts to share and geek out about the latest mobile apps, websites, hardware projects, and tech creations”
Sites like these do a great job of aggregating high-quality content, helping us keep ahead of the tech curve.
Don’t give up when the going gets tough
I have worked with engineers who yearn for challenges and others that are content with just copy/paste. The tendency of copy/paste engineers is to learn the easy parts of a technology and/or project and ignore or delay the not-so-easy stuff. They’re always looking for shortcuts/hacks when working on any nontrivial assignment. Engineers like this focus mainly on getting things done, instead of getting things done the right way.
An example of this that is fresh in my mind is around AngularJS. We were early adopters of AngularJS. The team was new to the platform. Over time, the engineers that excelled at AngularJS were the ones who looked beyond the standard usage. They understood what prototypal inheritance worked with Angular, how AngularJS data-binding worked and how/when to create directives (HTML extensions).
To become a better engineer, you can’t simply learn everything at a superficial level. You must develop expertise in product/technology areas that you work day in and day out. Something that I touch on again later in this post.
Understand the big picture
Understand the big picture. If this has not been told to you in one form or another, then you have not built anything substantial! When working on a problem, more often than not, our focus is too narrow. At times, we don’t understand how the components we are building fit into the complete solution context. Neither are we aware of the business value of our deliverables. This leads to suboptimal solutions and/or missed requirements. Avoid this and always, always look at the big picture!
Besides the solution and business value context described above, there is one more vector that I should add. Understand the big picture in terms of the software development life cycle (SDLC).
I remember my early days, fresh out of college I had a preconception that software development is all about writing code and everything else is optional. Boy, was I wrong!
Writing code, while important, is just one facet of software development. There’s more to it, and you need to understand the big picture here too!
To become a better engineer, learn about every aspect of building software and if possible, get involved. Learn about requirement gathering, prioritisation/triaging, project/sprint planning, deployment (CI/CD), testing (automated, smoke, regression, UAT) release management, operations and support. The earlier you learn about them the better you understand the big picture. Don’t restrict yourself to taking the requirement, building the software and throwing the code to the other side of the wall for someone to test. You will never grow!
Learn about operations
Thanks to the devops culture, engineers are getting involved in areas which they had limited exposure to previously. This is definitely helping everyone understand the big picture and write better software.
If you haven’t adopted devops, then I highly encourage you to learn about the deployment and operational aspect of your software. To get better at what you’re building, you need to understand where it is deployed and how it is used by the end customer. Learn how deployments/releases are made, the deployment topology and what the operations team is doing. How are they monitoring the health of the deployment?
Learn from mistakes
“Experience is the name everyone gives to their mistakes.” – Oscar Wilde
You will make mistakes! Learn from your mistakes and from the ones that you observe others making. Mistakes are part of our learning process and, as long as we learn from them and take corrective measures, they give us great insights into what works, what doesn’t and why. It’s difficult to appreciate the right way of doing things unless you’ve made a few mistakes and suffered. But remember:
“Learn from the mistakes of others. You can’t live long enough to make them all yourself.” – Eleanor Roosevelt
A great engineer makes fewer mistakes, learns from others and makes sure he does not repeat them again.
Become an expert on things you are actively involved in
Pick any technology domain and I bet you can spend a copious amount of time mastering it. There is so much to learn that when it comes to actually deciding what’s worth our time, we become indecisive. The easiest choice here is to gain in-depth expertise on areas that you are actively involved in; the technologies that your project uses, the tech stack your Org endorses. This is also a great way to stand out among your peers and align your expertise with business needs.
Challenge the status quo
The hallmark of a skilled professional/master is that they don’t accept the status quo. They are constantly striving for improvements in all aspects of their domain of influence. Part of this is not accepting the excuse “but we have always done it this way”. This also means having an opinion and a strong foundation to support your opinion. To challenge the status quo requires us to be experts in our domain and look at everyday work challenges with a fresh perspective.
Learn from your peers
I have saved the best for the last. Pairing with a smart co-worker is accelerated learning! Working with a master teaches you more than what is possible through any book/video/tutorial. Working with an expert gives you deep insight into how they approach a problem, deconstruct it, structure and verify their solution. If your organisation is a proponent of practices such as Pair Programming, great benefits can be derived by working with masters of their trade. While this is the best form of learning, it’s not always possible to pair with someone at work. The next best option is to look at their work/code/solution and learn from it. The web has made this a level playing field; if there’s no one around you, look at GitHub repos of smart engineers and great projects.
To conclude, I will paraphrase the opening statement:
A good engineer is one who learns and improves over time.
I hope you find these tips helpful and please do share your mantra of learning and self-improvement with me by emailing email@example.com.