A Comprehensive Guide to Applying for Software Engineering for Cambridge Engineers (and Closet CompScis)

Applying for internships especially during Michaelmas term time can be quite stressful, especially with the exponential build up of examples papers and missed lectures you need to catch up on. For most engineers who go into info engineering and really just want to do software engineering (which I will refer to as SWE), most people don’t even know where to start preparing and often its too late by the time the actual interview rolls around. It doesn’t help that the engineering degree itself pretty much doesn’t help a single bit until the later years in teaching any of the skills required for acing those coding interviews.

This guide will be based on my own personal experience applying to internships during Michaelmas of Year 3, and I will talk about the things I have learned and the mistakes that I have made so you don’t have to make them too. For context, in the previous summer I interned as a Research Engineer (within software research) for Adobe Research in Summer 2021 and then applied to Palantir, Microsoft and Meta this time round. I was rejected from Palantir and then after a significant amount of extra coding practise, I got offers for Microsoft and Meta and I’ll be interning at Meta Summer 2022.

A good time to start preparing would be about two months before your coding interview (for a comfortable, stress-free experience) and ideally not during Michaelmas (so start this summer break when you can!) – this should be sufficient if you had zero practise prior to this. Let me tell you about my experience:

I didn’t start preparing for my coding interviews until sometime in Michaelmas – that was a bad idea…

– a very behind third-year engineering student (me)

I didn’t think about applying to SWE at all until the start of Michaelmas, where I received my first ever coding interview during term time. I started my preparation and solved my first ever interview coding practise question in Week 2 of Michaelmas. Since then, I had a total of 11 interviews for Palantir, Microsoft and Meta. I pretty much ended up focusing mostly on interview preparation and I fell really behind on my Michaelmas work (by the end of term, I was 40 lectures and 6 examples papers behind!). It also kind of sucked because my last interview was at the start of the Lent term, which made it difficult for me to focus on Michaelmas revision during the Christmas break. Although I am currently catching up now during Lent term and it is going pretty well!

I know the sheer number of interviews sounds kind of gross, but that’s also the reason why I’m writing this article – it’s to let you know you so you can start preparation earlier if you can! Be aware that some software positions have early deadlines and decide on applicants on a rolling basis so the earlier you are able to apply the better.

LeetCode is by far the best way to prepare for the coding interviews. You can usually use whatever language you are most comfortable in, unless the job role specifies otherwise (I used Python for all my interviews). Generally most SWE coding interviews assess the knowledge of Data Structures, Algorithm and expect a good understanding of time and space complexity (they will often ask you to talk about the complexity of your code).

Useful Resources

*Microsoft, Amazon, Google, Apple, Facebook and Palantir

I recommend getting LeetCode Premium (this article is not sponsored by LeetCode) because it is really helpful – CUES is currently working on getting the university to subsidise this cost, so do ask someone on the committee about this!

What worked well for me was studying the solution a couple hours after attempting a problem if I had not reached a solution yet, then coming back to try it again in a few weeks time, eventually timing myself, aiming for around 20 minutes per question. Sometimes there can be many ways to solve a problem so if there was time, I would try and understand all of them and their pros/cons. As I went along, I also tried to actively think about the space and time complexity of my solution.

Don’t be worried about the overwhelmingly large number of different kinds of coding questions on LeetCode – here’s a priority list to get you started:

Essential: If you have time:
1. Arrays & Strings (hashmaps, sets)
2. Graphs/Trees (BFS, DFS, stacks and queues)
3. Heaps/Sorting
4. Linked Lists & Intervals
5. Search
1. Dynamic programming & memoization
2. More advanced graph concepts:
-> Topological sort
-> Tree traversals (inorder, preorder and postorder)
-> Dijkstra, Bellman Ford, A* search

A Crash Course on Complexity

If you are not too sure about what time and space complexity – it shouldn’t be too difficult to get the hang of it once you grasp the general idea:

  • Time complexity: Describes the amount of computer time it takes to run the algorithm and how much it scales with the given input data (a function of the characteristics of the input).
  • Space complexity: Describes the amount of memory space required by an algorithm until it executes completely (a function of the characteristics of the input).

Describing complexity uses the Big O Notation – if you’re not sure what that is, you can read about it here.

Usually it is more important to optimise for time complexity rather than space complexity. Take the Two Sum problem as an example: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target. There are two main ways you can solve this problem:

Approach 1: Brute Force

This just takes the problem literally and solves it by iterating through the rest of the array for each element in the array until it finds two numbers that add up to the target number:

def twoSum(self, nums: List[int], target: int) -> List[int]:
    for i in range(len(nums)):
        for j in range(i + 1, len(nums)):
            if nums[j] == target - nums[i]:
                return [i, j]
  • Time complexity: O(n^2), since you are iterating through the rest of the array for every element in the array.
  • Space complexity: O(1), since you are not needing to store any variables that scale with the input.
Approach 2: Using Hashmaps

If we keep a hashmap/dictionary of all the complement values as we traverse the array, we can solve the problem in linear time:

def twoSum(self, nums: List[int], target: int) -> List[int]:
        nums_map = {}
        for i in range(len(nums)): 
            complement = target - nums[i]
            if complement in nums_map: 
                return [i, nums_map[complement]]
            nums_map[nums[i]] = i
  • Time complexity: O(n), since you are just iterating through the input array once.
  • Space complexity: O(n), since you are keeping a hashmap that will be (in the worst case) equal to the size of the input array.
Time complexity comparison

In general, you want to aim for an algorithm that can run linearly in O(n) time if possible. A few things to note:

  • n describes the input size. If you have several inputs, you could name them anything and have a complexity that depends on a combination of the different input characteristics. For example: O(n+m), where m may be the size a second input and you iterate through each of the first and second inputs linearly at some point separately during your algorithm.
  • Binary search is O(log(n))
  • Sorting is O(nlog(n))
  • Log in this case is base 2
  • Space complexity does not count the space required to hold the output answer.
  • Any linear combination of complexity simplifies, for example O(n) + O(n) or O(kn) (where k is a constant) simplifies to O(n)
  • Take the most significant complexity as the overall complexity (e.g. O(n) + O(n^2) becomes just O(n^2))

I prepared for my behavioural interviews by thinking of my answers to a bunch of behavioural questions before the interview and writing them all down. Typically a good answer uses the STAR method.

Occasionally questions can be a little unpredictable and it can be difficult to come up with some thing on the spot during the interview. If you find that you can’t think of an answer immediately during the interview, it is better to take a minute during the interview to think, instead of diving straight into answering the question and trying to think as you talk.

Example Questions (including some questions I actually got asked😉):

  • Tell me about your past work experience (can be university project or internship or any other relevant examples):
    • What did you do? What have you learned?
    • What would you wish you could have done more if you had more time? Would you have done anything differently?
    • Did you play a leading role in the project/take initiatives? How?
    • What didn’t you do so well? How could you have done it better?
  • Tell me about your personal projects – how did you go about solving the problem?
  • Tell me about a time you worked with a difficult group.
  • Tell me about a time you had to admit a mistake to your mentor/boss.
  • Tell me about a time you were made to make a morally grey decision – how did you deal with it?
  • What do you do when you come across a bug in your code?
  • Tell me about any problem in the world that you could solve using software.
  • What product would you improve at X company and how/why?
  • Why do you want to work at X company?
  • If you were to choose another offer over X company.. why?
  • What are the top 3 most important factors to you when considering an internship offer?

A good CV helps you get your foot in the door and secure that first interview. Recruiters like to see any experience you have had with programming – don’t worry if you haven’t had any software-based internships before. Any personal programming projects you’ve done is very valuable CV material, along with any hackathons or related events that you have attended. Link your GitHub if you want and keep your CV as concise as possible, keeping it to one page only if possible. Somewhere in the CV, it would also be good to include a list of software and programming languages you have experience in.

Coding interviews typically come in two different forms:

  1. Over video call – most common, you will code on a shared coding environment that the interviewer can see too
  2. Online assessment – timed unsupervised online assessment

The video call type of interviews can take a bit of time to get used to and it can be especially nerve-wracking. It helps a lot to practise explaining your code and your thought process as you do the problems when you practise. It is best practice to give a high level overview of how you will write your algorithm first before diving into the actual coding. You will naturally get better the more actual coding interviews you do – so don’t worry if your first few coding interviews go badly… mine did too!

I applied during Covid times so I am not sure whether usually there is an in-person process and what that would be like. Different companies can vary quite a lot in their interview process. The following will be directly from my personal experience applying for internships for the summer 2022. The hiring processes can change so this might not hold up completely in a year’s time, but hopefully it can give you an idea:

At Palantir I had applied for the FDE position which is slightly different from SWE in the sense that the role focuses a lot more with dealing directly with the clients but still has a lot of traits of an SWE role. Understanding the nature of this position is they key to doing well in their interviews. I got to the final round of all four of the interviews before I was rejected.

  1. Phone Interview: A coding interview in Karat (1 hr, interviewer over video call)
  2. On-site interview: Two interviews in a row – Learning and Decomp (1 hr each)
  3. Hiring manager interview: Varies – generally behavioural and either a decomp or technical question

In the coding interview, it started off with some algorithm questions (pseudocode and complexity questions) for 15 mins before diving into coding problems for the rest of the interview. For the coding problems, they cared more about getting a fully complete solution than a fully optimal solution (i.e. the best run time complexity), although if possible, a more optimal complexity would be preferred. They will always more problems to ask you if you manage to complete the questions – so aim to complete around 2 or 3 problems. The questions get increasingly harder and I would say I got a Leetcode easy, medium, then hard.

I can’t tell you too much about the on-site interviews, but in the learning interview they show you a concept that you may have never seen before and see how well you pick it up (they are there to help you) and in the decomp interview they ask you to design a solution for a problem and they are mainly looking for you to be the one driving the interviews.

Offer Details

I didn’t get an offer but a couple of my friends did so I can tell you a little bit about the offer details:

  • Compensation upwards of £70k annualised
  • Free corporate accommodation or alternative stipend
  • Free food!

I applied for the general Microsoft UK Software Engineering internship through their website. It seems like most applicants ended up going directly to Microsoft Azure for Operators which is a team that works on 5G telecommunications using the Azure cloud. I didn’t realise that I would be put on this team and thought I could work on some other things but maybe I didn’t read the description properly? I’m not too sure myself because I don’t think I saw this team allocation in the job description.

  1. Phone Interview: Online coding assessment (3 questions, 85 mins, no interviewer) & one technical and behavioural interview (30 mins)
  2. On-site interviews: Four interviews, same day, back-to-back (45 min each, 15 min break in between)

The online coding assessment compromised of three coding problems of about one LeetCode easy and two medium (this could vary).

Each of the four on-site interviews had the same format: 1 technical question and 3 behavioural questions (total 12, way too many!).

One thing the hiring manager said he really liked about my interviews (on post-offer call) was the user-focused answers that I gave and that not a lot of people apparently remembered to mention.

Offer Details

  • £2800/month
  • No provided accommodation but a £400 accommodation and £300 commuting allowance

The Meta interview process was the shortest with only two interviews and I spaced my interviews out over two months to give myself ample time to prepare for them.

  1. Phone Interview: 45 min coding interview
  2. On-site Interview: 45 min coding interview

Both interviews were exactly the same format: two 20 minute questions and 5 minutes for questions for the interviewer at the end. There were no behavioural questions.

According to the recruiters, they expect applicants to be able to finish both of the coding problems within the time limit provided. Apparently they assess mainly on how the applicant approaches the problem, how quickly they solve them and how much prompting the interviewer needs to give.

During the interview, there are no opportunities to compile and run your code, so they expect you to be able to go through your code line-by-line with test cases until you are confident you have a working solution. They also value optimal code, so expect you to be able to come up with an algorithm that has the best time complexity. They will also expect you to be able to give the time and space complexity of your solution.

The questions I got were LeetCode mediums, but you could get an easy and a hard question depending on what interviewer you get.

Offer Details

  • £4400/month
  • Free corporate accommodation or £1k.month housing stipend
  • Subsidised laundry
  • Free food 3 meals a day 5 days a week 😀

This is probably the most important thing to consider before starting applying is timing your interviews well so that you can in the best case scenario you could receive offers at around the same time, not worry about offer deadlines before you hear back from other interviews (and even get the opportunity to potentially negotiate your compensation with them!).

If you have any offers or are further in the interview process you can contact your recruiter to move interviews forward, otherwise try to time your interviews wisely (although understandably this can be difficult to get right). Try and get your interviews done before Christmas because it can be a nightmare moving interviews forward during that time and recruiters may not be be willing to comply/extensions on any existing offers will not take into account of working days.

Some companies give exploding offers like Microsoft which only gave me a week to accept the offer and did not give any offer extensions. This was problematic for me at the time because I was not able to move my Meta interview forwards and had to make a decision quickly…

In the worst case scenario, you receive an exploding offer for your second choice company and you are still waiting on hearing back from your top choice company. In this case you will have three options:

  1. Decline the offer: You will risk not getting any offers at all if you get rejected from your top choice!
  2. Renege the offer: This means accepting the offer and potentially going back on your word if you get your top choice offer… this is generally bad practise and the company could potentially blacklist you but you will at least have an internship!
  3. Accept the offer: Just work at your second choice. Decline your top choice regardless of its outcome.

It is up to you which decision you make in this scenario and it is not an easy choice – but that is why timing your interviews wisely is so important! If you do end up being in this kind of situation, either option is definitely a gamble. You’ll need to ask yourself: Are you happy with the possibility of losing all offers? Are you prepared to burn bridges with your second choice company?

In my case, I was lucky to have a back-up return offer from Adobe which had no deadline so I declined Microsoft before hearing back from Meta and continued with the Meta interview process because I didn’t want to risk burning bridges with Microsoft.

Yes! (Although my DoS would probably disagree…) Securing that intern position gives you opportunities to secure a grad position (especially if you are applying for a penultimate year internship) where you don’t have to worry about this process later on at the start of 4th year. If you were not able to get the internship position you wanted, all that preparation experience you did will stay with you afterwards so the next time you apply and you will only get better and better with each interview you do.

I hope this article was useful and if you are thinking of applying to SWE positions and have any questions, feel free to drop me an email at [email protected]!

P.S. I’d like to thank my friend Ethan Mak (M&C Director) for teaching me a lot of this stuff and giving me advice throughout my interview process – not sure whether I would have gotten this far without him!