Most universities only teach the basics of coding, not the software engineering knowledge required to actually build the systems in industry. If you have learned basics of programming, you are on a level playing field with most new grads. It doesn't take much learning to teach yourself some basic software engineering concepts and implement an example project to stand out significantly when looking for that first job. Additionally, a lot of these companies have extremely inconsistent codebases which often require you to learn it from scratch every job you start. This results in most people, even experienced engineers, being surprisingly unproductive for a long periods of time. If you’re highly motivated to learn whatever the system is, you can carry yourself extremely far with just that in an organisation.
I would say this is the smallest subset of knowledge to get started in Software Engineering. While it all can seem pretty overwhelming, it’s a surprisingly little amount of knowledge you can familiarise yourself with to get started building an app.
After you create a couple of tutorial apps, you basically have the skillset to get started in industry. This is what a lot of coding bootcamps do, often charging thousands of dollars. I don’t think this is necessary given the amount of good, free tutorials available. Supplement your learning with articles and YouTube videos while you implement. Don’t worry too much about technology specifics (languages, frameworks, etc.) since they change wildly from job to job and you want to get yourself in a position where you are being paid to learn them.
I will outline a good place to get started below, but remember that technologies move so fast that they often go out of date, so whatever you learn, prioritise the concepts over the specific implementation details.
In the following article, we will use a basic Blog website as an example. We can reduce this down to these functionalities:
Note that the acronym here spells CRUD. This is a very common pattern of functionality within these systems. In this article, I will attempt to explain in detail each of these functionalities and the software architecture involved.
Most Software engineering work comprises of “Front-end” and “Back-end” engineering. Engineers that can do both are known as “Full-stack” engineers. I’d recommend having some experience with both to A) figure out what you like and B) maximise your usefulness across the stack. If you can create end to end platforms, you have all the tools you need to basically build and run a company by yourself.
The "Front-end" is what the users interact with. It pulls the data it needs to display the information from the "Back-end", which is a data orchestration layer, often accompanied with a database.
The front-end is the website you see and interact with in the web browser. It should be primarily used to interface with the back-end in a way that is intuitive to the user. Modern websites are built with the following technologies:
I wouldn't recommend explicitly learning HTML or CSS beyond the basics; most of the time you can just learn by doing what you need within a given project.
Visual design is a large component too of front-end; the goal is to make an interface to enable the user to execute whatever task in the most intuitive manner.
You might have heard of the term API to describe this - think of this as just a non-visual way of interacting with a database or executing some kind of logic. It might have some kind of authorisation which requires you to login before accessing.
Backends generally follow a MVC (Model-View-Controller) design:
A good backend divides functionality up into well defined layers. It is possible to write any old code to pretty much do anything, but a lot of the skill in Software Engineering comes down to deciding how to structure the code into layers that each have specific responsibilities. These are called Design Patterns and MVC is an example of this.
When sending data between your front-end and back-end, we do this by sending Requests and receiving Responses. We do this using HTTP (Hypertext Transfer Protocol) which is a set of standards which enable online systems to communicate with each other. Requests require an HTTP method as well as a URL and can have an optional body which is used to attach payloads of data.
When we make a request, we use an HTTP method against our url. The most important ones to consider in our context are the following:
GET and POST are by far the most common and you can build most systems with just a combination of the two.
To successfully send a request and receive a response from our back-end, we need an HTTP method as well as a url. The combination of these two is an HTTP Endpoint. These are defined in the View layer of our MVC design pattern. Certain urls may seem identical, but each should be associated with it's own HTTP method which in turn would have it's own functionality as defined in the controller layer of the backend design. To reference our blog example again in terms of the CRUD functionality, we would need the following endpoints:
Note: this is just a portion of the URL relative to the back-end itself. The fully public equivalent would map to something like "http://www.myblogwebsite.com/api/blogs".
Good software design on the backend defines HTTP endpoints that are easily understood and consistent with existing software design patterns.
When data is sent and received via HTTP, it is attached to the Request or Response body as a payload. This takes the form of JSON (JavaScript Object Notation) which allows for a standard format to be used between the front-end and back-end. This way, our front-end can make assumptions about what our backend data looks like; when we request our backend for a list of blogs it will use JSON which might look something like this:
[ { "id": 1, "title": "Blog title 1", "body": "My first blog", "date": "2023-01-01" }, { "id": 2, "title": "Blog title 2" "body": "My second blog", "date": "2023-01-01" } ]
The square brackets “[]” imply a list with a bunch of elements denoted with curly brackets “{}”. These elements are singular blog entries that have all the attributes defined in our Blog example.
We also send a body of JSON to our backend via a POST/PATCH/PUT request. The body of a POST request that creates a new blog might look something like this:
{ "title": "Blog title 3", "body": "My third blog", "date": "2023-01-02" }
The responses sent back from the back-end always have a status code which let you know how the backend has managed the request. A few basic ones are as follows:
There are many others you can learn as you go along. I wouldn't recommend learning these all up front as you will just come across them as needed. 400-499 are generally issues to do with an invalid request. 500+ are generally due to problems that the backend is facing.
We will list a bunch of use cases we wish to have for our blog website and define all the HTTP interactions associated with that:
REQUEST:
RESPONSE:
[ { "id": 1, "title": "Blog title 1", "body": "My first blog", "date": "2023-01-01" }, { "id": 2, "title": "Blog title 2" "body": "My second blog", "date": "2023-01-01" } ]
REQUEST:
RESPONSE:
{ "id": 1, "title": "Blog title 1", "body": “My first blog", "date": "2023-01-01" }
REQUEST:
{ "title": "Blog title 3", "body": "My third blog", "date": "2023-01-02" }
RESPONSE:
{ "id": 3, "title": "Blog title 1", "body": "My third blog", "date": "2023-01-02" }
COMMENTS: Note that the id is generally created on the backend, often by the database incrementing automatically. It’s good practice to return a detail view in the response to a create/update request.
REQUEST:
{ "body": "My third blog", "date": "2023-01-02" }
RESPONSE:
{ "error": "Blog must have a title" }
REQUEST:
{ "body": "Update my blog body!" }
RESPONSE:
{ "id": 1, "title": "Blog title 1", "body": "Update my blog body!", "date": "2023-01-02" }
COMMENTS: Note that we’re doing PATCH here. With PATCH we can send a partial subset of the model fields we want to update. A PUT request would require us to supply all the fields and they would all be updated to what we set in the body. Note that this would be behind some degree of authentication so only you as the authenticated admin would see it.
REQUEST:
RESPONSE:
COMMENTS: It’s not often we actually use this type of delete, often opting for more of a “soft delete”, whereby you would have an “active” column in the database, and you do an UPDATE request, setting the “active” attribute to false. Note that this would be behind some degree of authentication so only you as the authenticated admin would see it.
I would recommend just getting yourself familiar with some front-end and back-end technologies with the intention of developing your first project. This blog is just a high level explanation of some core concepts, nothing could be more useful than getting into these technologies yourself and resolving the challenges associated with that. Once you have these basic concepts down, creating your own app won't seem as daunting as it does now. All you need is a computer to start. You will hit technical learning curves, but every time you overcome one, you will expand your technical knowledge such that the subset of things that are unknown will get smaller.
I recommend that you create at least two apps and have them deployed online. You can use these as portfolio pieces and discuss them in your future interviews. If you can't deploy them online, no problem. Create a Github account and upload all of your code there so prospective employers can view it.
With a couple of apps under your belt, you can often change the narrative in interviews away from being tested about technical knowledge into a discussion about your experiences in making these apps. This has a much higher chance of getting you hired as most organisations - especially smaller startups - only really care about getting stuff done and with these projects you have shown that you can contribute.
Implement a blog website as seen on the tutorial below. Once you have finished the tutorial, extend what you’ve done by personalising it to something you’re interested in. Some ideas could be: a recipe website, restaurant recommendations, movie script repository, or maybe some tool for tracking road potholes! This will give you some front-end styling experience as well as something you can share with friends and family.
Once you have done that, create another app (or extend the current one) to build on what you’ve learned. Perhaps try something which hosts media like an image upload. That way you can build something that has user profiles (like an instagram clone or a dating website!).
Areas to explore further that I haven't gone into too much detail with is things like an authentication system (e.g. user accounts that can login) or more complex algorithms such as a recommendation system for serving up related blogs.
This should be enough domain knowledge to get started in building your own app. You should start with a blog app.
Obviously, there will be a lot of implementation problem solving specific to the tutorials you follow.
I would recommend starting with something in React, a Javascript library (a set of tools) for creating front-end applications. The technology has progressed such that you don’t really need to worry about a separate backend since we can actually just create a full stack application with the React framework Next.js. This is all we need to get quickly up and running with creating full-stack applications:
I would recommend just going ahead and following this tutorial to set up a blog website: https://vercel.com/guides/nextjs-prisma-postgres
Depending on your experience with coding, different things will have learning curves.
Language
Just learning the programming language can be frustrating; it might help do a quick coding tutorial to get familiar with a specific language. Many of these are free on places such as CodeAcademy.
The Terminal
When running code, you have to familiarise yourself with the terminal/command line. It's basically just a text way of interfacing with an explorer within an operating system. It helps to do quick tutorial covering the terminal to familiarise yourself with the useful commands.
Frameworks
Getting to grips with a library/framework can also be a little confusing. A React project uses many different code libraries that all have to be connected in a specific way to work. When you download a starter project and install node, you have to install all the dependencies via the command:
npm install
This will install all the code dependencies via the npm package manager as outlined in the file package.json in your project. As you progress, you can learn about how to update/add new packages to do specific tasks. Most software engineering ends up less about writing code to do everything and more about piping up different packages and libraries to do the task for you. Why bother implementing something when someone else has already coded and rigorously tested it! Sometimes getting all the dependencies to work together can be a massive pain and you might find yourself having to debug different versions of your libraries.
Debugging
Most of software engineering comes down to debugging - something isn't working and you need to figure out why. It often requires a decent amount of understanding on how the language and framework functions. It really helps to be able to read code and make guesses based on your knowledge about what might be the problem. You can likely get by initially by just Googling errors. Most common issues are well outlined on Stack Overflow. Get familiar with searching for solutions to problems. Eventually, you'll understand enough to just fix them yourself with enough experience.
Maintainability
You'll find that you'll often forget how something was implemented, especially if it was written a while ago. It's for this reason, maintainability is important; always opt for the most straightforward implementation, striving for consistency over complexity within your project.
For your first software engineering job, I couldn’t recommend a startup enough. Prioritise smaller startups. (8-20 people). Founders can often be non technical in nature and can be impressed by a small body of work that you can present. While working in a small startup, you can pick up things really quickly due to the lack of defined process and the need for everyone to roll up their sleeves and work on everything. In positions such as these, you are better able to experiment with your abilities and more importantly, learn a ton on the job. Getting paid to fill in your domain gaps should definitely be the priority.
In my experience, larger companies are mired in process around hiring and software development. You’re likely to be put on a task on the job which only touches a tiny amount of the codebase. This will stifle your learning as it makes it a lot harder to learn the end to end pipeline of software engineering. If you wish to work at a larger company, I would do this after a few years of startups since it’ll be much easier with experience. These types of companies often pay more than startups, but it’s going to be far more limited with what you can learn and they likely have more difficult interview processes.
I would recommend going for a new grad job or an internship for like 4-6 months (which likely would lead to a full time position). Getting the first job is always the toughest and it's likely you will be getting underpaid relative to a corporate software engineering position. You should probably expect $70-80K for these positions right out the door. Take the time though to learn as much as you can as the salaries often increase rapidly after the first 2-3 years of work. Most Software Engineers can easily be on 6 figures within a couple of years.
Create a resume from a template.
Try to structure your points with a software engineering concept, followed by what it does while namedropping technologies (recruiters often are just looking out for certain terms). Following on from the linked tutorial, this would be something like:
Don't list everything you've ever done as most people recruiting will merely glance at it for 30 seconds. Make sure points are succinct and reflect your knowledge and experience accurately. Also be prepared to talk about any point in a potential interview.
Feel free to reach out once you’re at this stage. I’d be happy to review your resume with you.
Be sure to make a LinkedIn account too and try to mirror the information on your resume there.
Getting that first Software Engineering job is probably the trickiest part of it all; companies are often wary that new grads need a lot of guidance, so if you can prove competence with a few certain technologies, you will stand out significantly. Students in university don't often get to a point where they're building functional apps, so you’re already ahead of most new grads if you have some experience in building stuff.
It’s going to be a volume game. Take that for what it is and don’t be disheartened when you send out 100 resumes and only hear back from a few of companies. They often use automated systems at large companies to filter resumes, so it's unlikely anyone's eyes got on yours. You only need one company to hire you. After a year or so experience, it will be a completely different ball game; recruiters will start approaching you and your professional network will be large enough to easily find the second job.
Websites such as LinkedIn, Indeed, Wellfound will be great for finding positions. Don’t spend too long on individual applications (e.g. you don’t need to do a cover letter). It’s good to have a spreadsheet to keep track of your status with every company you’ve applied to.
The reason I recommend startups is that the interview process is likely to be more flexible; you generally do a small coding challenge and are able to spend more time discussing your projects. You are also often interviewed by the people who you would be working with so you can gauge better what the culture will be like.
Larger companies do very specific types of technical interviews. You are often being interviewed by random people at the company, not the team you are directly interviewing for. I would say you have less control over how you sell yourself in these interactions. These are generally split into two types of interviews:
Most of this is luck based; getting the right interviewer with the right questions can sometimes take a little while. You will likely bomb interviews (I certainly did!). It sucks, but don’t feel bad - just take it as a learning experience for the next one.