Best Django Hosting: Where to Host Your Projects

So you’ve decided to use Django for your next side project. That’s a great choice! Django is a fully-featured web framework that comes with a lot of things already set up for you. This means that you can develop and iterate quickly and get your project pushed out to your users. Some of the largest websites and organizations in the world: The Washington Post, NASA, Pinterest, and many more, use Django as their web framework. You get versioning, a browserable API, and the ability to push regular releases. If that all sounds good, the next thing you need to figure out is: where the heck should you host your application? Today we’re going to take a look at the best places to host a Django web application. Specifically we’ll focus on people who are just starting out. If you have an established website that you are looking to move onto the Django framework, that is out of scope for the purposes of this post.

Today, we’ll look at the best hosting providers to get started with a Django application and framework. Depending on how much flexibility you want versus ease of use, one of the three providers below should suit your needs perfectly.

Provider 1: DigitalOcean

Best Django Hosting: Digital Ocean
DigitalOcean. Great flexibility and great prices.

DigitalOcean is a well-known provider of Linux-based hosting. As of 2018 they were the third-largest hosting company in the world, so you know that they are a well established service. They were one of the first cloud-hosting companies to offer SSD-based virtual machines. While setting up the environment and server will be more involved than the other choices on this list, they are still a fairly easy platform to deploy and manage on. DigitalOcean also scales fairly well, and prices start at a very reasonable $5/month for 1GB of memory, 1vCPU, 25 GB of disk, and 1TB of transfer. For a starting application that is more than enough. Because the cloud server is an SSD, the speed is also quick, which is important, especially if you are serving mobile users with your web application.

Because DigitalOcean provides a standard hosting service (think something like Linode), there is a high amount of flexibility and customization that you can do for your server. On the other hand it means you have to set up everything yourself. Thankfully, DigitalOcean provides you a great amount of detailed tutorials for set up–including how to set up django on a debian 9 server. They also include tutorials for various versions of Ubuntu, and you can even request tutorials if you’d like to use some other method of deployment such as Docker. You can see by the length of the tutorials that the setup will be somewhat involved, but the detail that the tutorial goes into means that you shouldn’t have any issues.

If you’re already comfortable setting up a VPS going with DigitalOcean is probably your best bet. The main downside is that you have to manage everything on your own, which can be time-consuming, especially for people who are setting things up for the first tim

e. The other services on this list are more straightforward to set up and manage a lot of other things for you, at the cost of being less flexible.

Provider 2: Heroku

Best Django Hosting: Heroku
Heroku, a PaaS that is simple to set up.

Heroku is a PaaS service that was originally built for Ruby projects, but spread to support multiple different projects and frameworks. One of the great advantages of Heroku is how simple it is to deploy a project–it’s as simple as a one line git push command. They also have several other ways of deploying applications as well. Heroku also comes with a free tier of usage to start, so if you’re on a really tight budget, you can get an application up with no cost. Do note, however, that the free tier is limited in terms of compute hours and your app will go to sleep to conserve these hours if it isn’t active after a set period of time. If you’re just starting to build your app this shouldn’t be a problem. They also provide a Heroku-based subdomain for your application so you don’t even need to buy a website to get started serving your application to customers. It’s also easy to scale up the compute power you need by scaling the number of instances you need.

Heroku used to be unable to support websockets, however this has changed and they have several tutorials on how to integrate websockets for different programming languages. The main downside of Heroku is that if you need to add functionality, you can do so via various add-ons that Heroku provides, but they can add up in price very quickly. Moreover, as your app scales, Heroku can be more expensive compared to other options such as DigitalOcean and Amazon. Since Heroku itself is running EC2 instances, shifting over once you scale means you’ll get better prices but less of the deploy and management aspects of the application handled for you. However, it’s something to consider if you feel that Heroku becomes too expensive when scaling up.

If you’re looking for something that requires less set up than DigitalOcean, Heroku is a good choice. There is still some set up but it is much easier to manage compared a service like DigitalOcean where you have to do all of the server set up by yourself.

Provider 3: PythonAnywhere

Best Django Hosting: PythonAnywhere
PythonAnywhere provides you an already set up Python environment.

PythonAnywhere is another service that allows you to deploy Django web apps. In general they support webapps written in any WSGI framework such as Flask. PythonAnywhere starts as a fully configured Python environment, with most of the system packages updated to the latest versions and tested to work together. It behaves more like a server, with local storage to edit files, read logs, etc. In some sense you can think of it as a standard server provided by a VPS with a python environment already set up for you. PythonAnywhere has a free plan like Heroku, which gives you a single worker for you webapp. This is the equivalent of Heroku’s dynos, where you are given a free dyno for your Heroku application. It is very easy to set up an application because the environment is already set up for you beforehand.

Note that PythonAnywhere does not support NoSQL databases nor does it support websockets. Django itself does not officially support NoSQL databases, but there are side projects and forks that allow NoSQL functionality if you need. Django supports websockets via Channels, however PythonAnywhere does not. That’s something to keep in mind while choosing a provider. If you need NoSQL or websocket functionality, you’ll need to do extra work to integrate with your webapp if you’re using a PythonAnywhere hosted instance. They also don’t offer register services so you’ll need another service to manage the DNS, unlike Heroku, which provides a simple method to set up your nameservers.

If you’re looking to get an app up and running as quickly as possible, PythonAnywhere is quite good. Just be aware that it doesn’t support some of the functionality that the other providers offer for you.

Conclusion: Best Django Hosting

If you’re looking for hosting for your Django web application, the three hosting providers above should be a good start. Depending on whether you need more flexibility, or you’re looking to push your application live as quickly as possible, one of the providers above will get you what you need. Just note that as you start scale, it starts to make more sense to move off of the services and start handling the server set up yourself as the savings can be significant.  

How to Create a Gantt Chart

If you’ve read about learning how to define project scope, you know that it’s important to keep a schedule of the engineering work you need to do. Here you’ll see the thinking process involved in how to create a gantt chart for keeping track of an example project. The example in this case is a website for so a travel team can book flights more efficiently. Think something like Skyscanner for your company. Building a fully functional, user-facing application is not something that can be done within a day. So what is the best way to schedule out the project and let your end users know the delivery date? Say that you need to make a tool that presents the cheapest airfares. There are a couple of ways to do this–in this article we’ll explore how a gantt chart can be used to do this.

High-Level Tasks

When creating a gantt chart, start with broad strokes. Define the high-level goals that you need to accomplish, and from there work down in more and more detail until you have small-sized tasks that will take a couple of days to complete. Once you have that level of detail, you will have a good grasp on the amount of time it will take you to deliver the project, as well as a long-term schedule of the work you need to do. This will make it easier to reschedule things if (when) unexpected updates occur. You can shift whole blocks of the project forward or backward as needed.

For flight search, there are a couple of problems that need to be tackled. First up is user discovery. You’ll need to talk to users, identify needs, and create a detailed specification for the user’s needs. This will impact what work needs to be done on the engineering side. If you have a project manager, they will be the ones in charge of taking on this job.

Once the user discovery is sufficient to start technical design, you’ll need to identify what infrastructure is needed. Some of the questions that may be asked include:

  • Is a database required?
  • What services is the application dependent on and are there new ones that need to be built?
  • Is the product user-facing–does it need front-end design and a user interface?

For flight search, at a high level, you’ll likely need a data pipeline consisting at minimum of a service, potentially a database as well, that aggregates flight data and feeds it to the user-facing application. The user-facing application itself is another large section of the build that needs to be broken down further.

Finally, there is the testing and launch phase, where the product will need to be tested to see what problems could need monitoring, and to debug the product before launching it to the end user.

Getting More Detailed

Now we have the general high-level tasks that need to be accomplished, they need to be broken down into more actionable bits. In this example the high-level tasks are user discovery, building the data pipeline, building the front end user interface, and testing the product and monitoring key metrics. All these tasks need to be done for the product to be complete, but at this level of description it is hard to figure out what exact steps are required to complete each task and how long it will take to finish each task. There needs to be a more precise description of each task so that a better estimation of the time required can be made.

User Discovery

In the user discovery portion, it is important to figure out the needs of the users. What are your end users most interested in? For flight search, outside of price and flight time, what else are they interested in? What filtering options do they need? This means talking to users and identifying what exactly they need from the product. From a preliminary list, create a specification of the product, that describes at a high-level what the problem the product is servicing and what it is not servicing. For example, you might find that for this tool, adding a feature to automatically perform the flight booking for the end user is out of scope for the project.

Data Pipeline

Now that you’ve determined exactly what the users need from your product, it’s time to get technical. You investigate APIs for flight data and find a couple that look promising, but they come with a price tag. Unsure whether or not the pricing will work with your company’s engineering budget, you come up with an alternative option that involves scraping the data from other websites and files that you can download.

Do you see what just happened there? This is one of the big advantages of getting granular and making a gantt chart. If you had left the tasks as their high-level descriptions instead of breaking it down, the potential problem of pricing would never have been caught until you were knee-deep in the technical implementation. Then you find out that, no sorry, that’s out of budget, your next couple of days involves trashing code, and now you’re behind schedule.

Since you were smart and decided to plan out a detailed project schedule beforehand, you raise the question of price at this point to your team. If they know that the pricing for the API fits within budget, you can go ahead with the API integration. Otherwise, you need to sort out the alternative options and work that in to your schedule instead.

With the data fetching determined, you can determine how you need to parse that data to present it to the frontend side, and what kind of metrics you use to determine flight quality.

User Interface

Here you need to determine how your users will interact with your service. Planning this out should happen in tandem with designing your data pipeline, as your user interaction will often inform how you need to retrieve data. For example, let’s say that one of your end users is a PhD statistician with a penchant for penny-pinching, and he wants to search by flight number and retrieve historical data for a flight route.

Your product manager understands that the company needs to cut costs wherever possible or cut people, so he adds the feature as in scope for the project. During your task planning for the data pipeline, you look into the APIs and find that while you can aggregate bits and pieces of the data from different websites, no one API provides all the information that you need. In addition, you need to provide the exact range of dates you need the data for.

This means that your front-end interface will need to include some sort of date picker and a field for flight number as part of its search interface. In addition to the error state you need for standard flight searches, you will also need to include an empty results state if a search has no results, as well as validation that your flight numbers are valid.

From there you also need to determine how you will show your results to your end users. For a standard flight search it makes sense to show the results in a list ala Skyscanner, but how will you show the results for custom searches such as the historical data search? These are questions you will need to raise for the user interface design that will determine exactly what the website you build should look like.

Testing and Monitoring

This part is generally straightforward, though the execution can be difficult. From your user stories you should be able to identify which parts of your application and service need to be monitored to determine how successful it is.

Before you launch, you should identify the interactions that a user can have with your service, and run through a list of testing scenarios to fish out any bugs that are hiding in your code. This will let you know what fixes you need to apply before pushing live.

Assigning Time

How to create a gantt chart: A sample template
Your gantt chart will end up looking something like this.

Now that you have more detailed tasks for your project, determine the amount of days you think that it will take. Then add some amount of buffer time, as it in most cases it will take longer than you think. People will get sick, go on vacation, and of course, have meetings, which means not 100% of the day will be spent working on the project. By assigning time to teach of your tasks, you will have built a rough schedule of when each of your larger tasks is expected to start and end. Say that after you have assigned time, the timing for your larger tasks looks something like this:

  • User Discovery: 1 week
  • Data pipeline: 2 weeks
  • User facing application: 2 weeks
  • Testing and monitoring: 1 week

This is something that you can let your end users know about and keep them updated as you move through each of the larger tasks.

This is where the other advantage of the gantt charts come in. When unforeseen events occur, your timelines will be impacted. Most of the time this is in a negative way. Say that your company has contracted with one airline, and your search tool needs to only display results from that airline, which has no API. Changing circumstances have rendered your API plan unusable, despite your best efforts. In this case, you will have to factor in the building time of an alternative solution. Say that you find an alternative solution will take an additional 2 weeks to implement in addition to the 1 week you have already spent on the data pipeline. Then you can insert those two weeks into the middle of the gantt chart and shift everything behind it back, and update your end users with the new delivery dates easily.

How to Create a Gantt Chart:  Parting Thoughts

Creating a gantt chart and keeping it up to date is just one way of effectively defining project scope. As you can see, the process of creating a gantt chart is a good way of ferreting out potential problems or dependencies before the development process begins. It is also a good way of giving more accurate estimated timelines, and it makes it easy to adjust timelines when unforeseen events occur or the amount of time required for previous work was underestimated.

Get out there and make a gantt for your next project!

How to Define Project Scope

If you haven’t had a job in the software engineering industry before, it’s likely you haven’t had to deal with scope before. One of the advantages of working alone or in a small team is that you can move quickly and don’t have many requirements to adhere to. When was the last time you wrote out a task list or held weekly planning for a side project of yours? Probably rarely, if at all. However, learning how to define project scope is vital to becoming a better engineer. It may even help you manage your time for your larger individual side projects.

What does project scope mean? Project scope is basically a definition of what you will work on for a project. It defines what you aim to accomplish, and, this is important, what you don’t aim to accomplish. While it is the product manager’s job to nail down the user stories which determine what problems are in or out of scope, as an engineer it’s important to understand these as well. If you understand the user stories, you can offer suggestions of simple engineering solutions that still meet user needs. Therefore you should aim to understand both the scope of the product, the engineering scope and how you will execute the creation of that product.

Product Scope

Generally product scope will be defined for you as an engineer. However, the product scope determines the engineering scope, so it’s in your best interest to be very familiar with the product scope before planning out a feature or application. Failing to understand the product scope, can lead to scope creep. Scope creep is when features that were not intended in the original plan make their way into the requirements. This adds complexity to your job and can lead to missed deadlines and lots of refactoring, if the code you previously wrote is now incompatible with the new requirements of the project. Basically, it makes your life hell, so avoid it like the plague. 

Cat asks, how to define project scope
Mr. Fluffy after he realized he has extra work because of scope creep. Don’t be Mr. Fluffy.

Understanding the project goals allows you to propose solutions from an engineering standpoint. Let’s face it–your product manager may or may not have an engineering background. This means that they may suggest solutions are totally impossible from an engineering perspective. If you understand the needs of the users, you may be able to suggest a solution that is just as effective but requires much less time to build. Even better, you may be able to break up the work into a series of smaller, iterative products that allows you to collect more data from the user along the way. This allows you to identify if a project or given timeline is unreasonable and establish a reasonable schedule for accomplishing a project. You will also be able to identify potential dependencies on other engineering teams where work needs to be finished before you will be able to launch your product.

Finally, understanding user needs is just a useful skill to have. If you ever want to strike it out on your own, start your own company or sell a small service, you NEED to understand your user’s needs. By thinking deeply about how to translate user needs, goals, and explicitly define non-goals, you will have acquired a valuable skill for building something that people actually want.

Engineering scope

This is where the bulk of the scoping work is for an engineer. You have a set of user needs and non-goals for the current project, as well as a high-level idea of how much time it will take. The objective of you and your team is to nail those down into concrete times and clarify as many unknowns as possible. Only the engineers should be scoping this project. Your team will know best how long it will take them to build the project.

Here you will need to figure out how much time general blocks of the project will take and manage expectations in terms of time spent. If you find that you will take more time than expected, inform your product manager. It’s important to raise and manage expectations in terms of time spent early and often. This is also where the work done during product scope comes into play. If the product has been scoped correctly, then you should have must-haves, nice-to-haves, and non-goals for the product. If the product has a tight deadline and there’s an unreasonable amount of work left, it’s time to cut the nice-to-haves from the scope. Don’t be afraid to cut scope as needed, and always be cautious of feature creep. Sometimes feature creep will be unavoidable. Maybe a new law is passed regarding the industry you’re in or another team has recently changed a dependency and you need to rework something to integrate it. However if it is not absolutely vital to the product, aim to keep it from being added to the scope.

Make sure to manage expectations in terms of performance as well. Given the time you have to build your project, it may not be as performant as you would like. Maybe there are bottlenecks from your dependencies that will take extra time to work around. Again, this is where the work done during product scope comes into play. Based on the priority of your features, you should have an idea of where to optimize and where to leave it be. Be sure to monitor the performance of your project once it is live. Usage statistics will tell if something is getting higher usage than normal and is something that you should reprioritize.

How to determine build and timelines–Execution

Once you have a general idea of what needs to be built, it’s time to get granular. It’s important to bring in your team. The more engineers there are, the more thorough your plan will be. Your teammates will often catch dependencies and corner cases that you may not see on your own. Better that they surface now, at the planning stage, than 2 weeks out with you scrambling to meet deadlines.

For each project you should try and create a long-term tasklist of the execution, identifying what aspects you want to tackle for each week. This will allow you to nail down an expected finish date for your stakeholders. Remember to leave time for monitoring, testing, general buffer time, and bug fixes. This will also allow you to manage your dependencies, and see what order work needs to be done in. There are several ways that you can do this. A common method is a gantt chart. For more granular daily tasks, teams also use project management software like Jira, Trello, and Asana. Generally getting tasks down to roughly 1-2 days has worked well. Tasks that are scoped for a larger amount of time often take longer than expected because the subtasks weren’t as clearly defined as they could have been. Experiment with what level of granularity works for your team.

Example of how to define project scope with a gantt chart
Example Gantt chart template. Doesn’t look pretty but it gets the job done.

Don’t assume that initial timelines are set in stone! More often than not, new requirements will come up or you’ll be able to cut scope. When this happens, make sure to update your project schedule! This will allow you to keep your product manager and stakeholders informed at timelines, letting them know early and why delays or speedups in the project are expected. The earlier your product manager knows, the better they will be able to manage user expectations. If you are building your project in iterative installments, set some milestones at each installment. Schedule an expected delivery date for each iteration, giving some time for feedback to come in, and adjust the plan for future iterations based on the data that you receive. You may even be able to completely scrap development time for future iterations if your early product delivers what your users need better than you expected it to.

How to Define Project Scope: Conclusion

Scoping well means the difference between a smoothly executed project and tons of angry stakeholders stampeding your desk and asking why the product isn’t done yet. By making sure you have an accurate grasp on the scope of your project, you can avoid having it slip and fall behind schedule. If it does happen to fall behind schedule, you’ll know why and have an explanation ready; better yet, everyone who needs to know should have been informed well in advance, since you’ve regularly reassessed your timelines and found ahead of time that you would need to adjust the delivery date.

Make sure that the people receiving your product have the right expectations coming in and they’ll be satisfied and you’ll be less stressed. It’s a win-win.

How To Write Clean Code

So you got a job. The hard part is over, right? You can just keep coding the way you’ve always been, right? If you want to integrate well into your team and do work that people will notice, you need to learn how to write clean code. You’re no longer coding alone, and any bad code you write can easily come back to haunt you. Maintenance, not only of your own code, but also of your coworkers’ code, is now part of your responsibilities. The less you need to do, the better.

All Code Comes Back to Haunt You

How to Write Clean Code? Don't write in brainfuck.
Hello World in Brainfuck. Don’t let your code look like this.

It’s simple: the cleaner your code is, the easier it will be to pick up. Some of you may have side projects from a couple of months or years back. Maybe some of them were completed, maybe some of them weren’t. If you’ve ever tried to pick up an unfinished project, you know the pain of messy code. It’s hard to figure out what exactly is going on and what you were thinking 6 months ago. In fact, sometimes you may even have thought, “alright, let’s just trash all of this”. Even for short bits of code, say some of the first medium or hard leetcode problems you did (you are doing interview practice, right?) it can be difficult to understand, especially if you have variable names like var1, var2, and poor spacing inline and between logical blocks.

What you experienced from your side projects and interview questions are the consequences of writing bad code. All that code is only seen by your eyes, though. The code you write at your job will be used by your current teammates, your new teammates in the future, and if you leave, people that you may never meet. Any piece of code you write you now own. Teams that have dependencies on the code you wrote will ask you for help if they need to integrate or alter it in some way. And the harder your code is to understand, the more people will need to come and ask you to explain it to them. This not only takes up more of your time, but also slows down the team trying to integrate with your service. So as you can see, poor code quality can lead to slowdowns across multiple teams and ends up creating more work for yourself. This is not the kind of effect you want to have.

It’s even more important that you keep your code pristine if you work on something mission-critical. Some famous examples of bad code having disastrous effects include rockets being mislaunched, and bugs in medical implants that can cause deaths in the people that depend on them. Few of you will work on products with such large importance–if Facebook is down, life goes on–but if you do, it’s even more important. Poor code can lead to uncaught bugs, which can lead to expensive and even fatal failures.

Simple Things To Make Sure Your Code is Clean

So how do you keep your code clean? There are a couple of rules you can follow. First, use a linter. A linter will run through your code and point out any lines that don’t follow stylistic convention. This will make sure you fix up your code before you commit it to main codebase. Here are some other conventions you can follow to keep your code readable.


Use line breaks, empty lines, and indentation to give your code a readable structure. Remember that code from Brainfuck? Don’t let your code be spaced like that. Some languages like Python you must indent correctly, but you can still use line breaks and empty lines to break up logical blocks. The denser your code is, the less readable it is. Space your code out like a children’s book, not an article out of Harvard Law Review.


Make sure to use meaningful names for variables, functions and methods. Var1, var2, and the like may have been okay when you were practicing, but there’s absolutely no way they should ever make it through code review. If by some miracle a badly-named variable did, you can be sure the next time someone needs to work on that area of code, they will be coming to your desk. So what makes a good name? The name should suggest what the variable, function, or method is used for or what it represents.


Keep your functions small and focused. The more modular your functions are, the easier they will be for other people to understand. They will be easier for you to test. And, they are more flexible. If you have a function performing several different tasks and they need to be separated, suddenly you’ll have a lot of refactoring to do. If instead you had just one function for each of these tasks, calling each as needed, you wouldn’t need to refactor at all.


The fourth thing can be somewhat controversial, which is to use comments for clarification when needed. Some people will argue that clean code should not require comments. They say that comments are a crutch which are unnecessary for people with clean, readable code. Unfortunately, sometimes reality interferes. You may have to operate within a structure or integrate with an external API that requires you to break some conventions. In this case, a brief comment–no longer than 1-2 lines–can go a long way towards clarifying why you need a certain piece of logic.

How To Get To Clean Code

So you know what makes clean code. Now how do you keep your code clean?

If your company does not have a style guide or some consistent rules, make one. It’s important that everyone is consistent with their definition of clean code. If everyone is inconsistent, it’s the same as having no clean code at all.

Second, keep a note of the four above things. Before you send out code for review, read over your own code–always do this–and check for things you can clean up. Outside of debugging, keep an eye on the four conventions and note where you can implement them wherever possible. Do the same for your coworkers’ code when reviewing. For example, if you don’t understand the logic behind a certain line, even after rereading, ask if it might need a comment. By doing this, you can ensure that your whole team writes high-quality, easy-to-read code that will make your own lives and other teams’ lives easier.

Track comments that you receive on your first couple of code reviews. There are many things, often belonging to company stylistic preferences, that you may fail to catch. For example, you may need to separate imports into certain groups, or group files into certain directories. Make sure you log these comments. Then, when you read over your own code, not only should you check for the four things above, you should also check for the comments that you received. Over time, this should become more and more automatic as you learn the style, and you should be getting fewer and fewer comments on your code reviews. If they continue to increase, then something is wrong–break up your commits into smaller sections, ask your team members about stylistic conventions, and make sure you are logging feedback fastidiously.

How To Write Clean Code; Parting Thoughts

Clean code means less bugs, less frustration, and less time wasted for you, your team members, and teams dependent on your work. It’s easier to maintain and will free you up to spend more of your time building new things as opposed to debugging and maintaining already written-code. It also ensures that you don’t meet with the worst-case scenario of having to completely rewrite an existing module or feature because it would be too difficult to integrate with otherwise.


Basic Python Programs For Practice: Why Interview Practice is the Only Practice

If you want to get a job in software development, you’re gonna have to do coding interviews. “But,” you say, “When will I ever have to invert a binary tree in my job?” The answer: probably never. However, if you can answer it you’ll have a job. If can’t answer it, well, best of luck on the next one. For anyone who wants a job, you better start working on basic python programs for practice.

In all seriousness—there are companies out there that don’t use coding questions in their interviews. And while more companies should do that, the VAST majority of companies will ask you to solve a coding challenge or ten. There’s just no way around it, and you’ll only restrict your options if you can’t do it.

For people who use Python everyday at their job, and for the absolute beginners, I recommend practicing algorithmic interview questions. While novice Python programmers will need to get used to the syntax, Python is readable enough that you can start doing these questions almost immediately.

What you need to get started

Data structures

Before you do any practice, the first thing you need is data structures. If you’ve been out of college for awhile, or you’re an absolute beginner, you’ll need to (re)learn these. It is vital that you start here first. Here is the basic list of data structures you have to know:

  • Hash maps
  • Trees
  • Binary Search Trees
  • Queue
  • Stacks
  • Linked Lists

You have to understand the above data structures. The more you know, the better. Some others that are covered in a standard data structures course include:

  • Graphs
  • Heaps
  • Tries

For a very gentle introduction into the subject there is Cracking the Coding Interview, which you’ve seen recommended in every article about interviews under the sun. Picking up a meatier resource on the subject is highly recommended. Data Structures and Algorithm Analysis is a standard undergraduate textbook that will serve as a good resource. There is also the infamous Introduction to Algorithms.

All you need from python

Next, if you’re a python beginner, familiarize yourself with the language. Go to the standard library documentation. You need to read chapter 5, sections 5.1 to 5.8, inclusive and section 7.1 at minimum. Bookmark these as you’ll need to refer to them often. Go to CodeAcademy and work through lessons 1-8 of their python course (no need for the pro courses). From here, interview questions are the only practice you should do. That’s all the learning you need.


Now that you have a solid grasp on data structures and the language, it’s time to learn some algorithms. You should know what the following are:

  • Worst-case (Big-O) analysis
  • Recursion
  • Breadth-first search and depth-first search
  • Dynamic programming
  • A sort that is O(nlog(n)) 
  • Backtracking
  • Other graph traversals (Bellman-Ford, Djikstra’s)

Introduction to Algorithms is a good resource for learning these algorithms. MIT also has a free set of video lectures covering these topics on Youtube. Of the algorithms listed above, you NEED to have worst-case (Big-O) analysis down pat. For everything else, as long as you know what the algorithm means and can work through an example problem, that’s enough. Mastery will come in the next part.

How long will this take me?

For a dedicated person with 3 solid hours of free time a day, learning this will take anywhere from 3 to 4 weeks. Remember, at this point you only need to know what these are, not how to implement them.

The 80/20 of interviews. How to practice

This is where to real learning gets done. Practicing is mandatory—there’s no way around it. But practicing more efficiently can save hours of work. The short of it is that the practice you do, the better you will get. 

The Plan

It’s important to have a plan of how you want to tackle these subjects. To put it another way, think about a basketball player. How does he practice? Does he just play game after game after game? No. It’s inefficient. So how? By doing drills. They’ll working only on passing, only on shooting, and strengthen their body independently in the gym. It’s the same with practicing interview questions. What happens if you do a little recursion practice, then a little dynamic programming practice, and a little queue and stack practice? You end up with mediocre recursion, dynamic programming, queue and stack problem solving abilities.

So study like a basketball player practices. Pick a single data structure or algorithm, go to leetcode and filter by what you chose. Watch a lecture about the item you are focusing on and make sure you have a structure for solving these problems. If you’re a complete beginner, start doing just easy problems until you can easily solve them. When you can, start doing medium problems. When you can do those, move on to hard problems.

Basic Python Programs for Practice: Whiteboarding your algorithms
Make sure you can write your code by hand.

Doing Problems

What exactly does doing a problem mean? It means solving it completely and correctly under interview conditions. For each problem you do, take a timer and start it. Write your algorithm out by hand on pencil and paper. Go through it for bugs and run through some test cases you think of by hand. Once you are certain the algorithm is bug-free, type it into leetcode and submit your solution. If your algorithm is not accepted and it takes more than 5 minutes to fix to an accepted solution, record the problem in a list. Note the bug that occurred and the time it took to fix your solution. If you did solve the problem correctly, then place it into your archive. The bigger your list of solved problems the better your interviewing skills will be.

If 1 hour passes and you are unable to solve the problem or come up with a correct solution, note this problem in another list, and prioritize it for review. Read the solutions on LeetCode and implement them.

Every week, keep one day for reviewing old problems. Work through the list of problems you are unable to solve. If they are solved correctly, remove them from the list and archive them. Otherwise keep them on there.

How many basic problems is enough? If you can do most mediums in <20 minutes you should have a decent understanding for passing interviews. If you can do most hards in that time then you should be in very good shape.

Example of a Practice Schedule: Recursion


Let’s say you want to study recursion. You watch some lectures and take a look at the wikipedia page describing recursion. From here you realize that for any recursion problem, you need a base case and a set of rules that reduce other cases towards the base case.

That’s still a little too abstract, so you take a look at the Fibonacci problem and its solution for a more concrete example. Working through the solution, you see that the base cases here are F(0) = 0 and F(1) = 1. The recurrence relation that reduces everything to the base case is F(n) = F(n-1) + F(n-2). If you try it for, say F(8), you can clearly see that eventually F(n-1) and F(n-2) will cause your expression to reduce to a sum of F(0) and F(1).

With this base structure in mind, you go to LeetCode and filter by recursion and easy problems. You start working on problems in a very specific way. Start a timer, write code on a piece of paper, and always try to answer these two questions: What is the base case? What is the recurrence relation?

Doing the problems

For every problem there are 3 outcomes.

  1. You successfully solve the problem. The problem statement, description, code are archived in some notes for later review.
  2. The problem is eventually solved, but debugging via the Leetcode testcases was not trivial. Record the problem in a list for review later.
  3. The problem was not successfully solved within an hour. You go to leetcode to view the solutions, identify what the base case and recurrence relation are. Implement the solution to make sure you understand. Record the problem in a list for prioritized review.

After 20 or so problems, you find that solving easy problems has become quick and efficient. You move on to mediums and repeat the above process. It takes a bit more time, but mediums fall under your circle of competency, and soon hards do as well.

Now you’ve become a master at recursion problems. You swap off to the next topic on your list, keeping your recursion skills fresh by doing a single medium/hard problem every week or so.

Basic Python Programs For Practice: Conclusion

Practice makes perfect. But the best of the best will structure their practice to be as effective as possible. Recognize that becoming good at interviewing practice is a skill that you can improve. To do so, you need to practice as effectively as you can. Don’t think you can just go into an interview cold and knock these problems out. It’s often the senior engineers that struggle with these types of problems. (That says something about their efficacy, but ultimately it’s something you have to be capable of.)

So get out there, make your data structures and algorithms hit list, and start crossing things off.