It’s been a few years since I’ve been working as a software engineer. During this time, I’ve worked on various domains - backend, data science, data engineering, devops to name a few. I’ve worked for multiple organizations ranging from the biggest names in tech to small scale startups building products from the ground up.
Here are 5 things that I’ve learned in the last 8 years of my software engineering career that no one told me about, when I started. And note that are all of these are skills that you can hone and sharpen over the course of your own journey
Growth mindset is your most important asset
A growth mindset is the belief that abilities and intelligence can be developed over time through effort, learning, and persistence. This concept was popularized by psychologist Carol Dweck. In contrast to a "fixed mindset"—the belief that abilities are static and unchangeable—a growth mindset encourages a person to view challenges as opportunities to grow, embrace failure as a learning experience, and focus on improvement rather than fearing mistakes.
People with a growth mindset tend to:
Believe that effort leads to improvement.
Embrace challenges rather than avoid them.
Learn from criticism and feedback.
Persist in the face of setbacks.
In your professional setting, you’re going to receive critical feedback. Whether you’ve just started or have reached more than 20 years in your discipline, one always makes mistakes and one can always be better. To become better however, you have to learn how to not take feedback personally but instead, see the situation objectively. What could you indeed do better? Is there something you missed? Instead of being hard on yourself, that you made a mistake, remember that you’re human and even if you’re one of the best in your field, there’ll always be room for growth. Be kind to yourself and allow yourself to grow, allow yourself to see things that you can do better, and make it a habit. Like a plant by design, always grows towards light, allow yourself to always find your way towards growth.
Your only competition is you
You’ve heard this countless times and hence I’m not gonna bore you with an explanation of this. Compete with your yesterday’s self and not other engineers, people etc. You may have been conditioned to compare yourself with others, by your family, teachers etc, but it is time that you unlearn this mindset and grow a mindset of getting better than what you were yesterday. Focus on consistent growth instead of impulsive growth and you’ll find yourself finding your direction much more easily than others
Stakeholders are not your enemies
If you’re working as an engineer, you’ve at least once blamed the problem on a stakeholder. It’s either - “Requirements change way too often.” or “I don’t understand why they can’t make up their mind”. As a software engineer, it’s easy to fall into the trap of viewing stakeholders—be they product managers, business leaders, designers, or clients—as adversaries or obstacles in the development process. This mindset often stems from a perception that stakeholders are out to impose unrealistic demands, disrupt your workflow, or dictate technical decisions without understanding the complexities of software engineering.
This mindset won’t help you. And what doesn’t help can change for good. Stakeholders are your partners in creating successful products. They’re not your enemies—they’re the key players who ensure that your work aligns with business goals, user needs, and market realities. In order to become a better engineer, you need to understand your product. And it’s very likely that you do not understand your product as well as your stakeholders do. Here are some things that you can do to understand your stakeholders better and to co-partner with them in building great products
Understand your customers. One of the primary roles of stakeholders is to advocate for the needs and desires of the customer or end-user. As a software engineer, you may not always have direct access to the people using the product, but stakeholders do. Their job is to gather insights, feedback, and market research, ensuring that what you build solves real problems and provides value.
Understand the context for decision making. Stakeholders often hold a broader view of the product's goals, vision, and market positioning. While you may be an expert in how things work from a technical perspective, stakeholders understand why those things matter in the larger business context. They can provide critical context when making decisions about features, timelines, and trade-offs.
Most stakeholders come from non-tech backgrounds. They can give you insights about your work, that may not be apparent to you. There’s a huge potential for growth by analyzing the perspective of someone who comes from a different background than you, and sees the world differently than you.
In truth, once I learned this myself, I started having a much better time in my stakeholder talks. I became friends with many of them, and I’ve had great discussions with some of my stakeholders and continue to enjoy spending time with them outside of work as well.
Being a problem solver is better than being a language specialist
In the world of software engineering, there's often a debate about the best path to success: Should you become an expert in a particular programming language or framework, or should you focus on developing problem-solving skills that are language-agnostic? While mastering a specific technology might give you deep expertise, becoming a versatile problem solver can offer far more long-term career benefits. It’s important to remember
Languages Are Tools, Not the End Goal
At its core, software engineering is about solving problems and building solutions. Languages, frameworks, and tools are just the means to that end. Whether you're working with Python, JavaScript, Java, C++, or even newer languages like Rust or Go, the programming language itself is just a tool to implement your ideas. What truly matters is your ability to break down complex problems and devise effective, efficient solutions, regardless of the technology stack you’re using.
It’s a rapidly Changing Industry
The tech industry evolves at a breakneck pace. New programming languages, libraries, and frameworks are being introduced constantly, and tools that were popular a few years ago may become obsolete or less relevant. A language specialist may find themselves tied to a technology that has lost favor in the industry, whereas a problem solver has the flexibility to pick up new tools and technologies as needed.
Being adaptable makes you more marketable and more likely to succeed over the long term, as you can take on a broader range of projects and adjust to the needs of your organization or the industry.
Cross-Disciplinary Expertise
In modern software development, projects often require collaboration with professionals from diverse disciplines, including UX/UI designers, product managers, QA testers, data engineers, and even non-technical stakeholders. A problem solver is better equipped to work in these cross-functional teams because they can communicate solutions and trade-offs in terms that everyone can understand—whether it's a technical team member or a business stakeholder.
This skill is especially crucial as software engineering has shifted towards full-stack development, where engineers are required to have a broader range of knowledge across both front-end and back-end development, as well as cloud infrastructure, databases, and security.
Long-Term Career Flexibility
Career longevity in software engineering is largely driven by your ability to adapt and solve problems rather than your deep knowledge of a specific technology. As the industry shifts and new trends emerge (such as the rise of AI, blockchain, and cloud computing), your ability to learn and apply new technologies quickly becomes much more important than your expertise in a particular language.
True Value Lies in Delivering Results
In the end, software engineering is about delivering results that meet user needs and business goals. While mastering a particular language might make you technically proficient in certain areas, the ability to consistently deliver effective solutions to real-world problems is what will make you stand out as an exceptional engineer.
Feynman technique for learning things
The Feynman Technique is a powerful method for learning and deeply understanding concepts, named after the Nobel-winning physicist Richard Feynman, who was known for his ability to explain complex scientific ideas in simple, clear terms. This technique involves four simple steps that help you internalize information and identify gaps in your understanding. Here’s how it works:
Choose a Concept You Want to Learn
The first step is to pick the topic or concept you want to understand. This could be anything from a specific software engineering concept like recursion or object-oriented design, to a broader topic like machine learning or quantum physics. The idea is to select something that you either don’t know well yet or want to deepen your understanding of.
Teach It to a Child (or Anyone Without Expertise)
This is the heart of the Feynman Technique: explain the concept as if you're teaching it to someone with no prior knowledge of the subject. The idea is to simplify the topic to the point where even a young child could understand it.
In the context of software engineering, this could mean explaining an abstract concept like polymorphism to a beginner by using everyday analogies (e.g., "Think of a car. A car can be driven, but depending on the car, the type of fuel it uses or the engine under the hood may differ, just like how polymorphism allows different classes to use the same method but behave differently.").
This step forces you to get rid of jargon and complex language, and distill the information to its most fundamental, easy-to-understand points. If you struggle to explain something, it’s a clear sign that your understanding of the concept isn’t as deep as it needs to be.
Identify Gaps in Your Knowledge
After attempting to explain the concept simply, you'll likely realize parts of the explanation are unclear or incomplete. This is where you spot gaps in your knowledge. If you can't explain a particular part of the concept easily, or if you’re unsure about certain details, it indicates that you need to study those parts more deeply.
At this stage, go back to your source material—be it textbooks, tutorials, or documentation—and review the areas that are unclear. This might involve re-reading concepts, seeking alternate explanations, or practicing the material through examples and exercises.
Simplify and Refine Your Explanation
Once you've identified your knowledge gaps and filled them in, go back and simplify your explanation again. The goal is to make your understanding as clear and concise as possible. This final step often involves refining your ability to explain the concept in an even more accessible way, ensuring that the information is both accurate and easy to understand.
Why It Works
The Feynman Technique works because it encourages active engagement with the material. Rather than passively reading or listening to explanations, you are forced to process and organize the information in your own words. This makes you internalize it much more deeply.
Additionally, by teaching the material to someone else (real or imaginary), you simulate a situation where you have to explain things clearly, which makes you more likely to remember and understand the topic thoroughly. The process of identifying gaps in your knowledge also ensures that you're constantly learning and improving.
Example: Feynman Technique in Software Engineering
Let’s say you want to learn about Asynchronous Programming in JavaScript. Here’s how you might apply the Feynman Technique:
Choose the Concept: Asynchronous Programming (Promises, async/await).
Teach It to a Child: Explain it like you're teaching a beginner or a child.
"Imagine you’re making a sandwich. Instead of waiting for the sandwich to be made before you can eat, you start another task, like making a smoothie. When the sandwich is ready, you come back to it. Asynchronous programming is like that—you don’t wait for one thing to finish before starting something else. You can work on multiple tasks at once."
Identify Gaps: While trying to explain it, you may realize you aren’t sure how Promises handle multiple tasks or how error handling works in asynchronous code. You go back and read up on Promise chaining or error handling in async/await.
Refine Your Explanation: After you’ve filled in your gaps, you rephrase your explanation:
"Asynchronous programming lets you start one task (like making a smoothie) while waiting for another (like the sandwich) to be completed. When the sandwich is done, you handle it. In programming, a Promise is like a waiter that will give you your sandwich when it’s ready. If something goes wrong, the waiter can tell you with an error message."
This was a long article. If you’ve made it so far, congratulations. You’re one of the rare people who are able to retain attention in a world where people are finding it harder and harder to concentrate. If you liked reading this, consider subscribing to this substack. I’ve reading and implementing ways to be more productive, and do meaningful work since the last 4 years and I’d like to share some of those things with the world. You may find some thing of value here afterall…