Michael Weiner

August 22, 2021

Reflecting on my first software engineering internship

I just completed my first software engineering internship this past week. The opportunity to join a team enabled me to learn about the health and tech industries as a whole, software development, and myself. Below are some of my biggest takeaways that I will bring with me to future professional opportunities. 

Document everything.

Whenever you join a new team there is sure to be lots of learning and set up. Having current and thorough documentation helps existing team members move to a new project and for the onboarding of new hires - among other things. My philosophy the last 3 months was to leave documentation I came across in a better state than when I found it.

When my mentors or other colleagues helped diagnose and resolve one-off environment issues that I was facing I documented fixes that I thought other employees might find useful. More importantly I tried to get that documentation into source code repositories as markdown files or the company's documentation tool so it could be used and updated by future employees.

Most often I spent time creating documentation for what I was working on. Software engineering is more than just writing code - it is probably more documenting and planning than actual code writing. For good reason. 

Having documentation to explain what you have worked on, what you tried, what problems you encountered, alternative designs, why you implemented something the way in which you did, and having a place for colleagues to review and leave comments on your thought process is critical. 

I kept documents for all of the functionality I worked on, bugs I fixed, learning courses I completed, acronyms and terminology I had to look up, questions I had asked, and I kept a list of all of the existing documentation that I updated rather extensively to bring it up-to-date. This information came in handy more times than I can recall over the course of the summer.

At the end of my internship it also provided a great way to not only reflect on what I accomplished but to also show upper management what I had spent my time on over the summer. 

Solving a problem is just the start.

As I began to work on implementing functionality for a variety of projects I realized that being able to explain why the solution I chose was the best choice was significantly more important than solving the problem itself

Efficiency, resiliency, and scalability are at the heart of any decent piece of software. As an intern you won't be solving the world's hardest problems, but chances are high that you will probably be facing more complex problems than you have ever seen in a classroom setting (more on this later). 

Being able to document why the solution you have implemented is the superior choice comes down to examining past issues with the code base, explaining the efficiency of your solution, knowing how your change mitigates the risk of introducing new bugs, and knowing how your change could impact future functionality of a code base is critical. 

Documenting this information allows for future team members to look back on your thought process and understand not only how your code was implemented, but why it was implemented in the way that it was. Often times that is more important than anything else.

Real world problems don't always have pretty solutions. 

The problem with CS courses in a classroom setting is that problems tend to be well defined, isolated, and rather limiting. In lower-level CS classes the problems you are given usually come with a pretty handy set of instructions for you to follow to solve the problem at hand. Throw that out the window with the real world.

Get comfortable taking larger tasks and breaking them down into many smaller, more manageable tasks. Real world problems are complex. They often interact with many moving pieces, can be caused by a numerous factors, and they don't always have a great solution.

I have listened to lectures where a professor has told the room to never do X, Y, or Z in the "real world" because you will never see it done. Well, on day one as an intern I was looking through some source code and I saw one of those things I had been told I would never see in the "real world." 

Further examination of that particular portion of source code led me to agree that it was the only way to effectively achieve what was being done. I later found some documentation to explain why it had been done and the reasoning was absolutely sound - and other team members agreed. 

When working on some of my own tasks it was important to be able to track down issues through the code base. Logging is helpful, but being able to read source code like a book was even better. Knowing how to use a debugger is great too. 

As I hit problems I talked with my mentors and other team members and realized that maybe there was not a great solution without an entire re-design of the underlying architecture. Sometimes that is a valid outcome. Other times they were able to point me in the direction of something similar that had already been implemented somewhere else. 

So, I documented everything. What I tried, what issues were hit, who I talked to, alternatives tried, and the final outcome that was decided upon. 

It's good to ask questions, but ask the right kind of questions. 

Asking questions is good. As an intern you should not be expected to join a team and know a system inside and out on day three. Often times you will be working with engineers that helped to design and code the tool you are working on. There is no chance you are going to be able to out learn the creator of a system. 

On that note, everyone on the team is working and they don't have time for a question every minute. More likely than not, they are stretched thin with their own deadlines and meetings.

When I hit a stopping point I went to look for some documentation. I also tried to read through the source code to determine what was going on. After being stuck for an extended period I asked for some help. I tried to make my questions very pointed by:

  1. Making a note that the question was not urgent and that when the person I was asking had a second I needed some guidance. 
  2. Briefly explaining what I was trying to accomplish. 
  3. Briefly explaining what I had already tried and where I thought things needed to be going. 
  4. Where specifically I was hitting an issue by referencing line numbers or files when appropriate. 

There were times where I was just stuck, wasn't sure why, and asked for help - and that's okay. Don't beat your head against the wall for 3 days because you don't want to ask for help.

Technical skills aren't everything. 

Working on a team is different than working by yourself. My internship was entirely remote (thanks, COVID), so it was not a typical technical internship. Virtual meetings are always interesting and trying to get to know your colleagues over Zoom or Microsoft Teams is more challenging. Make it a priority. 

Being able to share your ideas, communicate effectively, and be a team player are more important than any technical skill you might or might not have. Technical skills can always be taught. Interpersonal skills can't be taught. 

Be easy on yourself. 

Don't compare your day ten to some one else's day one-thousand. Things will ebb and flow. Some days you will feel like you got a ton done and other days will be extremely frustrating. Welcome to software engineering. :)

--

All of the items discussed above are solely my opinions and do not represent the position(s) or opinion(s) of my former employer. 

About Michael Weiner

Hey, visitor! I'm Michael, a software engineer based in Minnesota, USA. I am an IBMer working on IBM Cloud Kubernetes Service. Feel free to poke around some of my work at michaelweiner.org. Below are some of my personal thoughts on business and my experiences in the computer science industry. Thanks for reading!