Backend
Building My Own Technical Interview Practice Repository
Johann Gaviria DEV Community
1 views
Preparing for technical interviews has made me realize something:
solving more exercises doesn't necessarily mean practicing better.
I've spent quite a bit of time solving programming problems, reviewing Python concepts, working on backend projects, and preparing for technical interviews.
But there was always something missing.
I didn't have a consistent way to practice.
Sometimes I'd solve an algorithmic problem. Other times I'd work on some business logic. Then I'd look at a random interview question online.
It worked, but it felt disconnected.
So I decided to build something for myself.
The project is called Technical Tests.
It's a repository designed to help me practice technical interviews for Junior Backend Developer, Junior Python Developer, and Software Engineering Intern roles.
Why Build Another Exercise Repository?
There are already plenty of platforms for coding challenges.
LeetCode, HackerRank, CodeSignal, and many others are great resources.
But I wasn't trying to replace them.
I wanted something slightly different.
I wanted exercises that felt closer to the kind of problem I might actually encounter during a junior backend interview.
Not necessarily:
"Implement this famous algorithm."
But rather:
"Here's a small system with some business rules. Figure out how to process this data correctly."
That difference is important to me.
Backend development isn't only about algorithms.
You also need to understand requirements, translate them into logic, handle edge cases, choose appropriate data structures, write maintainable code, and think about complexity.
So the exercises are designed around those skills.
What Kind of Exercises?
Each exercise is intended to take roughly 30–60 minutes.
The difficulty stays within:
Easy
Easy/Medium
Medium
And each exercise focuses on one coherent problem.
For example, an exercise might involve an inventory system where you need to process stock events and determine which products need to be reordered.
Or a room allocation problem where you need to process booking requests according to availability and business rules.
These problems can combine several concepts without becoming artificially complex.
Some of the things I want to practice are:
Lists and dictionaries
Sets
Sorting
Searching
Frequency counting
Two pointers
Sliding windows
Stacks and queues
Basic greedy strategies
Data transformations
Business rules
Validation
State management
Resource limits
Edge cases
Time and space complexity
The important part is that these concepts appear inside a problem, rather than as isolated exercises.
The AI Part
One of the more interesting parts of this project is that I'm using AI coding agents to help generate and evaluate the exercises.
But I don't want the AI to simply generate a problem and a complete solution and call it a day.
That wouldn't really help me practice.
So I created repository-level rules that define how exercises should be generated.
The agent has to follow constraints such as:
Generate exactly one exercise at a time.
Keep the problem suitable for junior developers.
Avoid trivial programming exercises.
Avoid simply copying well-known platform problems.
Keep exercises self-contained.
Prefer the Python standard library.
Include public and hidden tests.
Include evaluation criteria.
Keep the candidate-facing starter code minimal.
That last point became particularly important.
The Starter Code Problem
Initially, I was tempted to provide more structure in the starter code.
For example, an exercise might start with predefined:
constants
enums
dataclasses
error types
helper functions
domain models
result structures
It looked organized.
But there was a problem.
It was also giving away too much of the solution.
If the exercise tells me that I need a BookingStatus enum, a BookingResult dataclass, three helper functions, and a particular domain model, then I'm already being guided toward a specific implementation.
That's not what I wanted.
So I changed the philosophy.
The starter code should answer:
"Where do I implement my solution?"
Not:
"How should I implement the solution?"
For example, a starter might simply look like:
def process_bookings(rooms: list, requests: list) -> dict:
"""Process booking requests and return the allocation report."""
raise NotImplementedError
That's it.
The README explains the requirements.
The starter tells me where to start.
I decide how to solve it.
That means I have to make the design decisions myself:
What data structures should I use?
Do I need helper functions?
Should I create classes?
How should validation work?
How should errors be represented?
Can I solve it in one pass?
Do I need sorting?
What's the complexity?
That's much closer to an actual interview.
README → Starter → Candidate
This led to a simple principle for the repository:
README
↓
What needs to be solved?
Starter
↓
Where do I implement it?
Candidate
↓
How do I solve it?
Tests
↓
Did the solution actually work?
The tests shouldn't care whether I used three functions or one.
They shouldn't care whether I created a class.
They shouldn't care whether I used a dictionary, a list, or another appropriate data structure.
They should care about the documented behavior.
This also makes the evaluation more fair.
For example, if two candidates solve the same exercise using completely different internal designs, both should be accepted if their implementations satisfy the contract.
Testing
Each exercise has public and hidden tests.
The public tests are there to make the expected behavior clearer and allow the candidate to verify their implementation.
The hidden tests are intended to catch cases such as:
Empty input
Single-element input
Duplicate values
Boundary conditions
Conflicting business rules
Invalid states
Large inputs
Incomplete implementations
Cases where an apparently correct solution breaks under less obvious conditions
The tests interact only with the documented public interface.
They don't depend on the internal structure of the candidate's solution.
For example, if two candidates solve the same exercise using completely different internal designs, both should be accepted if their implementations satisfy the contract.
Evaluation
After solving an exercise, the repository can also evaluate the implementation.
The default scoring model is:
Category
Points
Functional correctness
50
Edge cases
15
Code quality
15
Complexity
10
Python usage
10
Total
100
The score is then converted into a grade from 1 to 10.
The evaluation also produces feedback about:
What was done well
Problems found
Potential improvements
Complexity
Code quality
Interview-oriented feedback
The goal isn't to pretend that an automated score is equivalent to a real interviewer.
It's simply another way to get structured feedback after solving the exercise.
Keeping the Architecture Simple
Another decision I made was to avoid unnecessary infrastructure.
These aren't backend applications.
I don't need:
FastAPI
Django
PostgreSQL
Redis
Docker
External APIs
Authentication
Cloud infrastructure
The goal is to practice problem solving and Python, not spend an hour configuring infrastructure before getting to the actual problem.
That doesn't mean those technologies aren't useful.
They are.
But they belong in other projects and exercises.
For this repository, the Python standard library and pytest are enough for most problems.
Repository Structure
The repository is intentionally simple:
technical-tests/
├── AGENTS.md
├── README.md
├── docs/
│ ├── EXERCISE_RULES.md
│ └── EVALUATION_RULES.md
│
└── exercises/
└── YYYY-MM-DD-test-name/
├── README.md
├── EVALUATION.md
├──
├── docs/
│ ├── README.es.md
│ └── EVALUATION.es.md
├── pyproject.toml
│
├── solution/
│ └── solution.py
│
└── tests/
├── test_solution.py
└── test_solution_hidden.py
Each exercise is self-contained.
The root README acts mostly as an index.
The detailed rules live separately so that the project documentation doesn't become unnecessarily large.
The Workflow
The workflow I'm aiming for is simple:
The interesting part is that the repository itself becomes part of the learning loop.
Instead of just solving a problem and moving on, I can look back at:
How I approached the problem.
Where I made mistakes.
Which edge cases I missed.
Whether my solution was unnecessarily complex.
How I could improve the implementation.
Over time, that should give me a better picture of where I actually need to improve.
What I'm Learning From Building It
Ironically, building a repository for practicing interviews has already taught me a few things.
1. Designing a good exercise is harder than it looks
It's surprisingly easy to create a problem that is either:
too trivial,
too ambiguous,
too difficult,
too long,
or accidentally gives away the solution.
Finding the middle ground is harder.
2. More structure isn't always better
I like clean architecture and well-defined abstractions.
But an interview exercise doesn't necessarily benefit from having every possible abstraction predefined.
Sometimes giving less structure creates a better problem.
3. Tests are part of the specification
Writing tests forced me to think about what the actual contract of an exercise is.
If a test depends on an internal implementation detail, that's probably a bad test.
4. AI needs constraints
AI can generate code and problems extremely quickly.
But "generate something" isn't the same as "generate something useful."
The repository rules are there to constrain the agent and keep the exercises consistent.
What's Next?
For now, the project is intentionally small.
My plan is to gradually build a collection of exercises covering different areas of backend-oriented problem solving.
I'd like to eventually have exercises around:
Inventory management
Orders
Reservations
Loans
Scheduling
Permissions
Billing
Resource allocation
Data processing
Algorithms and data structures
But I don't want to turn it into a giant collection just for the sake of having hundreds of exercises.
I'd rather have fewer, well-designed problems that actually make me think.
Final Thoughts
I'm building this mainly for myself.
I'm currently preparing for professional practice and junior backend opportunities, and I wanted a more structured way to work on the part of software development that is difficult to practice through personal projects alone:
solving problems under constraints.
Maybe it will eventually be useful to someone else too.
But for now, the goal is pretty simple:
practice consistently, understand my mistakes, and get a little better with every exercise.
And what do I know, I'm just a junior dev.
Repository
The project is available on GitHub: Technical Tests
If you're also preparing for technical interviews, feel free to take an exercise and solve it without looking at the reference solution.
That's kind of the point.
Created with ♥️ by JohannGaviria; And what do I know, I'm just a junior dev.
Read original: https://dev.to/johanngaviria/building-my-own-technical-interview-practice-repository-24m3
← Previous
Does an LSP help a coding agent?
Next →
OpenAI can't rule out that it stole its most recent breakthrough
Related
Building a Resilient WhatsApp Cloud API Webhook Handler in Node.js
Backend
2
Dev.to (EN Zone)
We Replaced the Entire Secrets Management Stack with Go's Standard Library
Backend
2
Dev.to (EN Zone)
Zero Dependencies Sounds Easy Until You Have to Build Everything Yourself
Backend
6
DEV Community
Zero Dependencies, 456 Tests, and One Bug All of Them Missed
Backend
7
DEV Community
Comments0
No comments yet — be the first