Lessons from my first software engineering internship

Posted by on September 6, 2021

I started university two years ago with minimal programming knowledge and only a few lessons making Pong in Scratch under my belt. So in the beginning of my Computer Science degree, I spent a lot of time playing catch-up. My experience here at FreeAgent is what has finally caught me up.

Unlike in most internships, it was business as usual from day one for me, rather than one big project. This gave me exposure to a great amount of the codebase, and the work I did varied vastly from week to week.

I began my internship working on the front end of FreeAgent, improving the onboarding process of new clients for our accountancy practice partners via their dashboard. This was the only project I oversaw from beginning to end, an opportunity I was very grateful to experience.

The second half of my internship was spent removing mentions of accountancy services whose white-label had been removed from the codebase. This is where I achieved my greatest accomplishment: during my internship I officially deleted more lines of code than I added! Don’t be mistaken, though: it was not a simple job of pressing backspace like I initially thought. Instead, many hours were spent making sure the lines deleted did not affect any other areas of the codebase.

I was also given the opportunity to be on ‘bug catcher’ duty (a term used here at FreeAgent for an engineer whose role is to fix any bugs found) where I had to put my detective hat on to recreate steps to figure out how bugs had arisen. 

So why not share some of the lessons I have learnt, as someone who only entered the software engineering world two years ago?


The simplicity of Ruby promotes quick development and easy collaboration. It is a language that, even with minimal experience, is quite easy to read. This means less time spent on understanding convoluted syntax and more on understanding what the code is trying to achieve. There is a lot of magic that goes on in Ruby on Rails, a term I have heard quite a bit here at FreeAgent. It took me a few weeks to realise that this is a term that a lot of Ruby programmers, both in and outside of FreeAgent, use to describe the simple directives that execute complex operations, rather than a general descriptive phrase. 

As is common with a lot of Computer Science students, my course mainly used Java. Ruby, in comparison, is more streamlined as it takes less code to write basic structures. On the other hand, Java is generally faster and more efficient. The key difference between a statically-typed language and a dynamic one is when errors are detected. With Java, I tended to catch errors earlier in development, as everything needs to be meticulously labelled but, in my experience, this slowed down the development process. The pros and cons for me were equally weighted in both languages. By learning Ruby I now have the choice of two very different and powerful languages.


When I first started programming personal projects, I either stored all the files locally on my machine or spammed hundreds of commits straight to master, as keeping the codebase organised wasn’t a skill I had quite mastered yet. Cut to now, where I use git multiple times every day. But when I first started my internship at FreeAgent, the first commit, the first push and, worst of all, the first pull request were all frightening. Never had I had felt such a responsibility with the code I had written; in my mind it was as though with one tiny mistake I could bring the whole site down! Fortunately, such power does not lie in the hands of engineers here; instead, there is a meticulous process in place that ensures all is well before your code is merged with master. Firstly, it is vital that your code passes all the applicable tests in the codebase in Jenkins. It then needs to be code reviewed for any improvements to make or small mistakes to correct. Finally, right before merging, your code needs to pass pre-production testing (PPT) to ensure it hasn’t broken any part of FreeAgent. 

The other important tool is one that is integral to any operating system -the terminal. From watching the engineers on my team during our pairing sessions, I have noticed that implementing the habit of using the terminal for almost everything is crucial to be a successful software engineer. The common factor that I saw through my time pairing with the engineers on my team is that efficiency is key. Initially learning my shortcuts and customising the terminal did not seem too important but the speed of the development was greatly increased once implemented.

University vs industry code

What I was most curious about before starting my internship is what codebases look like for big applications. So I was very eager to dive right into FreeAgent’s codebase, which I learned in the first week is a monolithic structure with thousands of files. This was a big change for me, as I was only used to my university assignments having 10 or so files at a time. This meant that my best friend during my FreeAgent internship was command F. As I mentioned earlier, I benefited heavily from Ruby being extremely readable. When trying to figure out how to implement a feature, there are a ton of examples in the codebase there to help out. 

For me, university has been much more individualistic. More often than not, I have held the sole responsibility for the projects. Here at FreeAgent, on the other hand, the most enjoyable part of my experience has been the pairing sessions, where I’ve had the opportunity to ask a lot of questions – and I mean a lot! And through collaboration with my coworkers, I get a unique insight into how different engineers take such different approaches to solving complex problems.

At university, my experience has been that the main focus is getting the expected functionality to work, rather than the code being maintainable. A big part of having maintainable code is actually not the code itself but the documentation. Rather than in extensive comments, the significance of good documentation is found in commits and pull requests. Interns  are naturally only short-term workers and we will not be around in a few months to explain our code. Therefore, our descriptions need to be well-written: explaining the problem at hand, focusing  on the why rather than the how, and making sure that commits state any side effects or other unintuitive consequences.


When I was 17 I had an opportunity to get an insight into one of the biggest civil engineering consultancy firms in the world. What stood out the most to me was one of the employees saying that the most important part of a bachelor’s degree is not the course itself but the summer internship you take. With all the lessons I have learned over the summer here at FreeAgent – from learning how to use a version control system like Git to the process your code has to go through to get deployed – I now know why. 

Leave a reply

Your email address will not be published. Required fields are marked *