What I Learnt From My First Internship
Key takeaways from my first software engineering internship.
internshipswelife
My first internship was as a Full Stack Developer (for my dear non-technical audience, don’t worry, it’s not a technical article 😄) in the summer of ‘22.
During these 3 months, I learnt a lot about Software Engineering, most of which can be generalised to other domains too, and had quite a few important realizations. Here, I’ve summarised the ones that I think will benefit you the most. Some of them (admittedly) sound platitudinous but once you truly internalize them, I hope you’ll be able to see their value.
Disclaimer: Any opinions expressed are solely my own and do not express the views or opinions of my former employer.
Key Takeaways
- Don’t make promises you can’t keep.
- Doing the right thing is far more important than doing the thing right. Doing the right thing focuses on a higher goal, a sense of purpose, the destination, the “top line”. Doing the thing right focuses on the details, the journey itself, the “bottom line”. It’s more important to be going in the right direction than to be going fast.
- Don’t be in a rush to prove yourself right. Be in a rush to understand clearly what’s going on and try to get to the bottom of things, i.e., find out the truth or reality. If you’re right now, you’ll probably be right 5 minutes later too.
- Spend your energy in areas of high-impact rather than just “being busy”. You can be extremely busy, yet extremely unproductive. Have your priorities clear.
- When you don’t know the answer, say so. Be humble. Admitting you don’t know something is a prerequisite for learning. You can’t put water into an already full glass.
- Most difficult questions in life don’t have a model answer. It depends on the context.
- When there’s a problem, don’t jump to fix it. It’s much more effective to first focus on diagnosing the problem and designing a solution. Treat the illness, not the symptoms.
- Switching costs are often significant. That is, it takes energy (and effort) to switch between contexts and solve different problems concurrently. Sometimes, it’s often more effective to laser-beam your focus on one problem at a time, solve it, and then move on to the next one.
- Don’t be overconfident about your opinions. If you really want to increase the chances of being right, ask others to “stress-test” your opinion. The more number of (reasonable and smart) people you can get to agree with you, the greater the degree of confidence you should have.
- Precise communication is crucial. Make sure everyone in the team is clear on what is going on and what needs to be done. Synergy between team members is pretty important for the project to be a success. The whole is greater than the sum of its parts.
- Don’t feel afraid to ask for help from others when you need it.
- “Just okay” is not okay. Even “good” is not good enough. Strive for greatness.
- Metacognitive thinking accelerates growth. Understand what works for you and what doesn’t.
- Knowing what you don’t know is far more important than knowing what you already know.
- Asking the right questions is perhaps the most important skill. Force yourself to think of alternatives even when you’re quite sure of something, just like lawyers preempt the opposition’s arguments.
- All (important) decisions should be made by considering the trade-offs between possible routes. More specifically, every decision is an expected value calculation that involves considering the probabilities and returns of each possible outcome (while ensuring that the risk of ruin is nil).
Okay, here’s where it gets slightly software engineering (SWE) specific (though you can feel free to extend these insights across domains).
Also, these are just my thoughts/learnings — so don’t treat them as objective truths. (I’m not really qualified to make bold statements regarding SWE anyway 😅)
SWE Learnings
- Understanding the client’s requirements is often much harder than actually implementing them.
- Software engineering is less about writing code, and more about solving problems.
- Not all software engineering problems are tech problems. They are often people problems, process problems, operational problems, management problems, etc. In other words, technology is just a means to an end — not the ultimate goal. Coding isn’t the solution to all problems. A hammer cannot replace a screwdriver.
- Receive, refine and reject client requirements as you deem fit.
- Nothing is free — everything has a trade-off. Consider the tradeoffs between complexity, generalisability, maintainability, ease of use, scalability, extensibility, etc. and pick the design that fits your context.
- “Make it work, make it right, make it fast.” — Kent Beck
- Building a useful product is more important than building the perfect app (in terms of UI/UX).
- Use the white elephant test to prioritise what to do: think what would happen if a certain feature was removed from the product. How much impact would it have on the clients? The greater the impact, the higher the priority.
- Having an operational plan is as important as building features. Don’t neglect one for the other.
- It’s better to underpromise and underdeliver than overpromise and underdeliver.
- While designing a SWE solution, imagine yourself using the product/feature/whatever. Visualize the entire process in your head. Simulate the user-flow (to see if it makes sense). Exercise imagination and creativity.
- Context is critical while coding. Context refers to everything you have to consider regarding the business-domain, i.e., the problem you’re trying to solve. Many times, when new teams take over a project, they miss out on the context details that the previous team had and then they make blunders by trying to “improve” (because they think they can write “better code” than the previous team when in reality, the previous team’s code was more robust and bug-free than the current one). Realize that all the weird chunks of code you see in a legacy codebase are probably there for a reason and possibly solve some issue faced by an earlier team. Don’t just remove them without understanding their purpose, i.e, don’t throw away bug-free code in exchange for cleaner and simpler code: that’s a bad deal (especially when clients are already using your code!).