Fora Travel · Software Engineer
Updated · 2026-09-24

Fora Travel Software Engineer
Interview Guide

THE 60-SECOND BRIEF

Fora Travel builds web platforms for travel advisors, replacing legacy industry tools so advisors can book trips, manage bookings, work with clients and use data-driven travel recommendations. Software Engineers work across that stack, from JavaScript and CSS interfaces to REST APIs, live notifications and location-aware backend services.

This guide covers the three stages candidates report for the Software Engineer role: Recruiter Screen, Technical Evaluations and Panel Review. It also covers the question categories behind them: array coding with complexity analysis, frontend debugging in CSS and JavaScript, REST API design for nested resources, geospatial notification design, and behavioural questions on travel motivation, explaining technical decisions and AI tooling.

Fora Travel candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.

Hold money in minor units, rounding per jurisdictionDerive idempotency keys from attempts, never from retriesDecrement per-night inventory with one conditional update

34 min read

Practice 14 Software Engineer prompts
9Company bank questionsSnapshot · Sep 24, 2026 PT
1Candidate experiences ↗Read their reports
14Practice promptsAcross five skill areas
3With worked solutionsIncluded in the practice prompts

Fora Travel builds web software for travel advisors and aims to replace the legacy industry tools advisors have used to book trips, manage bookings and work with clients. Software Engineers build those products across the stack: client-facing web applications and UI components in JavaScript and CSS, REST APIs for hierarchical content, live notifications, and location-aware backend services.

The reported interview questions cover the same ground. The reported coding questions are array fundamentals. The main reported problem is merging an unsorted array into the empty tail of another, sorting the result, and stating its time and space complexity. Design questions cover a three-level REST API (Course, Module, Lesson) and a mobile backend that turns periodic location reports into proximity notifications. A frontend debugging exercise asks you to fix CSS layout errors and JavaScript runtime bugs in a broken application.

The behavioural questions reported for the role ask why you want to build tools for the travel industry, when you had to explain a technical decision to a peer or hiring manager, and how you use AI productivity tools in your daily work. For each one, prepare a specific answer that holds up to a follow-up question. A named decision, a named tool or a named advisor problem gives the interviewer far more to work with than general enthusiasm.

01

Recruiter Screen

reported

Candidates describe the recruiter screen as a conversation about career history, salary expectations and interest in travel technology. The reported question bank also includes a question that asks directly about salary expectations and interest in travel. Take both topics seriously. A vague range or a generic love of travel leaves the recruiter nothing concrete to pass on, while a clear range and a specific reason to build software for travel advisors move the process forward cleanly.

What to demonstrate

  • How clearly you summarise your career history and connect it to full-stack web work
  • Whether you give a specific salary range instead of deflecting the question
  • Whether your interest in travel technology is tied to the advisor's work rather than to your own trips

How to prepare

  • Write a short career summary that ends on the work closest to this role: web interfaces, REST APIs, notifications or location data
  • Set your range from a few current data points for the level and location, and practise saying it plainly in one sentence
  • Prepare one specific reason to build software for travel advisors, such as managing bookings, client communication or replacing legacy tools, and a question of your own about the product
PracHub interview research
02

Technical Evaluations

reported

Candidates report that this stage covers live coding, frontend debugging and architectural design, including API hierarchy and geospatial notifications. The reported coding questions are about arrays. One asks you to merge an unsorted array b into the empty tail of array a, sort the result and then state its time and space complexity. Another asks for the first element that meets a filter or merge condition. The debugging exercise asks you to fix CSS layout errors and JavaScript runtime bugs in a broken frontend. The design questions include REST APIs for a Course, Module and Lesson hierarchy, and a mobile backend where clients periodically report their location to trigger proximity-based notifications.

What to demonstrate

  • In-place array handling that respects the reserved tail and edge cases such as an empty b, plus an exact time and space complexity for the approach you chose
  • A methodical debugging process in plain CSS and JavaScript: reproduce the bug, isolate it, fix it, then verify the fix
  • Clean resource modelling, request and response contracts, authentication and consistent error handling across nested REST endpoints
  • A geospatial design that separates location ingestion from notification processing and indexes locations for proximity queries

How to prepare

  • Solve the merge two ways: copy b in and then sort, and sort both parts and merge backwards from the end of a. State the complexity and extra space of each out loud.
  • Debug a deliberately broken page with browser devtools. Include a flex or grid misalignment, a box-model overflow and an unhandled promise rejection.
  • Design the Course -> Module -> Lesson endpoints end to end: URIs, verbs, payloads, pagination, authorization checks at each level and one error format
  • Sketch the proximity notification backend with a named spatial index (geohash, S2 or quadtree), an ingestion queue and push delivery that does not send duplicates
PracHub interview research
03

Panel Review

reported

Candidates describe a final panel with a Hiring Manager and senior leaders that assesses execution and alignment. It may be held in the office or as a video panel. The reported behavioural questions are not tied to a specific stage, so have them ready for this conversation as well as earlier ones. Those questions ask about explaining a technical decision, using AI tools day to day and why you want to work in travel technology. Be ready to revisit projects you described earlier. The scope, trade-offs and results you quote here should match what you said in the technical conversations.

What to demonstrate

  • Evidence of execution: projects where you carried work from requirements to production and can name your part in it
  • Alignment with the role and with building software for travel advisors
  • Consistency between how you describe a project here and how you described it in earlier stages

How to prepare

  • Choose two projects and write down the facts you will quote for each: scope, your role, the main trade-off and the result. Rehearse until they come out the same every time.
  • Prepare the reported behavioural answers: a technical decision you explained to a peer or manager, how you use AI tools and check their output, and why you want to build software for travel advisors
  • Prepare questions for the Hiring Manager about the team's product area and how engineers work with product and design
PracHub interview research

1 candidate reports. Individual accounts describe a particular role and hiring cycle.

Software Engineer

Fora Travel Software Engineer Interview Experience — Coding, System Design, and API Design in One Technical Screen

Technical Screen

Coding The question was pretty simple: Q: Given two unsorted integer arrays a and b, where a has enough placeholder positions at the end to hold all elements of b, merge b into a and sort the final array in ascending order. Example: Additional constraints: Both a and b are unsorted a has enough placeholder positions at the end to hold b The final result needs to be placed in a There was no explic…

Read full experience

PracHub editorial advice for the preparation topics above.

01

Treating the array merge as concatenate-and-sort without using a's reserved tail or stating the space cost

The reported prompt gives you array a with empty slots at the end, sized to hold b. Write b into those slots by index instead of building a new array, then sort a in place. Then state the cost: O((m + n) log(m + n)) time, with extra space set by the sort you use (heapsort needs O(1), Timsort up to O(n)). If you are asked to improve it, sort b and the filled prefix of a, then merge backwards from the last slot so no value is overwritten before it is read. Test an empty b, an empty prefix in a, and duplicates that appear in both arrays.

02

Rewriting or restyling the broken frontend instead of isolating each bug

Reproduce each bug before changing code, then narrow it down. For layout errors, inspect the computed box model and the flex or grid container. For runtime errors, read the console and the stack trace. Fix one bug at a time, say what caused it, and confirm the fix at the viewport or interaction where it broke. A broad workaround hides whether you understand box-sizing, stacking contexts or promise rejection, so name the concept behind each fix.

03

Nesting every Course, Module and Lesson route three levels deep with no shared auth or error model

Nest routes only where the parent scopes a collection, for example POST /courses/{courseId}/modules or GET /modules/{moduleId}/lessons. Address individual resources by their own id, such as GET /lessons/{lessonId}, so reading or updating a lesson does not need redundant parent ids. Check authorization against the resource's parent chain, looked up from the stored record rather than taken from the path. If you do expose a fully nested route such as /modules/{moduleId}/lessons/{lessonId}, return 404 when that lesson does not belong to that module. Use one error body with a machine-readable code on every endpoint, and add pagination and filtering to the list endpoints.

04

Designing proximity notifications as one synchronous path from location report to push

Separate ingestion from processing. The write path for periodic location reports should only validate and enqueue. Proximity matching then runs asynchronously against a spatial index such as geohash prefixes, S2 cells or a quadtree. Explain how reporting frequency affects write volume and device battery. Explain how you avoid sending the same notification twice when repeated reports land inside the same geofence, and how you retry or record a push that fails to deliver.

05

Answering the salary and why-travel questions with generalities

Candidates report that both come up in the recruiter screen. Give a range based on current data for the level and location, and say it once, clearly. For motivation, name a problem in the advisor's work, such as managing bookings, communicating with clients or working around legacy tools, and connect it to something you have built. Liking travel yourself is not a reason the recruiter can pass on.

Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.

11 technical prompts3 include a worked solution

Given two unsorted integer arrays `a` and `b`, where `a` has enough pl…

medium
data structures and algorithms

Given two unsorted integer arrays a and b, where a has enough placeholder positions at the end to hold all elements of b, merge b into a and sort the final array in ascending order.

Approach
  1. Walk one small example through your approach before writing the whole thing.
  2. Name the brute-force solution and its complexity before improving on it.
  3. State the target complexity and say which constraint rules the naive version out.
Follow-up
  • What is the worst case, and how likely is it on real data?
  • How does this change if the input no longer fits in memory?

What is the time complexity and space complexity of your array merging…

medium
data structures and algorithms

What is the time complexity and space complexity of your array merging and sorting approach?

Approach
  1. Restate the input: its shape, its size, and what is guaranteed about it.
  2. State the target complexity and say which constraint rules the naive version out.
  3. Name the brute-force solution and its complexity before improving on it.
Follow-up
  • How does this change if the input no longer fits in memory?
  • What is the worst case, and how likely is it on real data?

Given an unsorted array, return the first element after applying a spe…

medium
data structures and algorithms

Given an unsorted array, return the first element after applying a specific filter or merge condition.

Approach
  1. Walk one small example through your approach before writing the whole thing.
  2. Restate the input: its shape, its size, and what is guaranteed about it.
  3. Name the brute-force solution and its complexity before improving on it.
Follow-up
  • How does this change if the input no longer fits in memory?
  • What is the worst case, and how likely is it on real data?

Find stay dates where committed units exceed capacity

mediumWorked solution
sweep linedifference arrayhalf-open intervalscapacity

For one unit_type_id with known physical_unit_count and oversell_allowance, you are given up to 200,000 confirmed booking rows as (check_in_date, check_out_date, units) where nights are the half-open range [check_in_date, check_out_date), plus active inventory_hold_night rows as (stay_date, units). The horizon is at most 500 consecutive stay dates. Return every stay date on which confirmed booking units plus active hold units exceed physical_unit_count + oversell_allowance, with the committed count and the excess on each. Target O(M + D) time and O(D) space.

Approach
  1. Build a difference array over the horizon. For each confirmed booking add +units at check_in_date and -units at check_out_date. Because nights are half-open, the checkout date is where consumption stops rather than a night that is consumed, so the negative delta lands exactly on it with no offset.
  2. Normalise the holds into the same array: each active hold night is a one-night interval, so +units at stay_date and -units at the next civil date. The input arrives at two different grains, and converting both to deltas is what lets a single sweep handle the mixture without a join.
  3. Index the array densely by stay_date - horizon_start rather than using a sorted map. That makes the pass O(M + D) rather than O(M log M), and at D <= 500 the array is a few kilobytes, so the dense choice is free.
  4. Prefix-sum left to right; the running total at index i is the committed units on that stay date. Compare each against physical_unit_count + oversell_allowance — the allowance is part of the invariant, not a fudge factor applied afterwards — and emit the breaches with their excess.
  5. Filter the inputs correctly at read time: cancelled bookings and non-active holds are excluded, and so are the hold rows of a booking that has already converted. During the conversion window the same units legitimately exist as both an active hold and a confirmed booking night, and counting both manufactures a breach that is not real.
  6. Deltas that fall outside the horizon still matter. A booking that starts before horizon_start contributes to every night inside it, so clamp its +units to index 0 instead of dropping the booking, or the first days of the horizon will read low.
Worked solution 25 min
  1. Set physical_unit_count = 3 and oversell_allowance = 1, so the ceiling is 4. Horizon 2026-03-01 through 2026-03-06.
  2. Take two confirmed bookings: Bk1 check_in 2026-03-01, check_out 2026-03-04, units 2; Bk2 check_in 2026-03-03, check_out 2026-03-05, units 3. Take one active hold night: 2026-03-03, units 1.
  3. Write the deltas: +2 at 03-01, -2 at 03-04, +3 at 03-03, -3 at 03-05, +1 at 03-03, -1 at 03-04.
  4. Prefix-sum across the six dates and list the committed count per date.
  5. Redo the same fixture with the closing delta wrongly placed at check_out_date + 1 and compare the two breach lists.
EXPECTED RESULTCommitted counts are 2, 2, 6, 3, 0, 0 for 03-01 through 03-06. Exactly one breach: 2026-03-03, committed 6, ceiling 4, excess 2. The phantom-night variant reports 2, 2, 6, 5, 3, 0 and produces a second, false breach on 2026-03-04 with excess 1.
Follow-up
  • Make this incremental: a single new booking arrives. What do you recompute, and what does that cost compared with the full sweep?
  • Run it across 500,000 unit types instead of one. Where does the dense-array choice stop paying, and what would you partition on?
  • A breach is found. How do you decide whether it came from a real oversell, a double-counted conversion, or a hold the sweeper failed to expire?

For someone who has spent the last few years shipping features and reading other people's code, and who has not solved a timed problem from a blank file in a long time. Five days rebuild the primitives and the patterns that sit on them, working from invariants rather than remembered solutions, and the last two attach that back to the rest of the loop.

Small steps. Visible outcomes.0 / 7 completed
ONE WEEK · YOUR PACE

Prepare, practise & reflect

One practical outcome each day. Spend longer where you need it.

0 / 7 done
01Array merge into a reserved tail, with complexity
  • Solve the reported merge: write b into a's empty tail by index, then sort a in place
  • Solve it again by sorting b and the filled prefix of a, then merging backwards from the last index of a
  • For both versions, write the time complexity and the extra space, and name the sort you relied on
  • Solve merge-two-sorted-arrays with a two-pointer scan, then test an empty b, an empty prefix, all-equal values and negatives

Deliverable: Two working merge solutions, each with a one-line complexity statement and a passing list of edge cases.

Practice prompt ↗Practice prompt ↗Worked solution ↗
02First-element queries and linear array sweeps
  • Put the reported first-element question in a concrete form: merge two arrays and return the first element that appears exactly once, using a count map and an order-preserving scan
  • Normalise an array of API values that may contain nulls, strings or unexpected types, keeping only valid numbers, and state how each bad type is handled
  • Write duplicate detection for an array two ways in code, once by sorting and scanning neighbours and once with a hash set, and state the time and extra space of each
  • Work the capacity-breach worked exercise (drill-coding-3) by hand on its fixture and check the committed counts it lists

Deliverable: Three solved array problems with complexity written for each, and the drill-coding-3 fixture reproduced correctly.

Practice prompt ↗Practice prompt ↗
03Frontend debugging in plain CSS and JavaScript
  • Break a small page on purpose with an overflowing flex item, a content-box width wider than its container and a z-index trapped in a new stacking context. Fix each one with devtools and write one line on its cause.
  • Write and then fix three async bugs: an unawaited promise, an unhandled rejection and a stale closure in an event handler. Explain how promises and async/await relate.
  • Review React state versus props, and outline how you would keep a large data table responsive with stable keys, memoisation and virtualised rows

Deliverable: A bug log with six entries, each giving the symptom, the cause and the fix.

Practice prompt ↗Practice prompt ↗
04REST APIs for Course, Module and Lesson
  • Design the full endpoint set: URIs, verbs, request payloads, query parameters for pagination and filtering, and response shapes
  • Add authentication, show how the caller's identity reaches each handler, and add an authorization check that walks the parent chain
  • Work the booking-confirm error-contract worked exercise (drill-design-4), then apply the same error envelope to the course API
  • Add per-user lesson progress and say which endpoint writes it and how a repeated request stays idempotent

Deliverable: One page with the endpoint table, the error format and the progress endpoint.

Practice prompt ↗Practice prompt ↗Worked solution ↗
05Proximity notifications from mobile locations
  • Design the backend end to end: location ingestion, a queue, proximity matching and push delivery. Keep ingestion and processing clearly separate.
  • Choose a spatial index (geohash, S2 or quadtree), design the schema and index around it, and explain how a proximity query uses it
  • Cover delivery reliability: deduplicating notifications, retrying failed pushes, and keeping device state in sync after a missed message
  • Explain how you would scale location writes when many devices report at once

Deliverable: A design sketch with the data flow, schema, index choice and one paragraph on notification reliability.

Practice prompt ↗Practice prompt ↗
06Caching and booking data
  • Work the availability worked exercise (drill-sql-1): size the derived and materialised options and write down the invalidation path
  • Run the cache-stampede debugging drill (drill-debugging-5) and write its ordered checklist and fix
  • Sketch an idempotent pipeline that syncs booking data from several supplier APIs: normalisation, deduplication keys, and how a retry avoids creating a duplicate record
  • Outline a multi-layer caching plan for a hotel booking read path and say what each layer protects

Deliverable: Written answers for drill-sql-1 and drill-debugging-5, plus one supplier-sync sketch.

Practice prompt ↗Practice prompt ↗
07Recruiter screen, panel stories and a full mock
  • Write your salary range and a specific reason to build software for travel advisors, then say both aloud until they sound natural
  • Prepare two project stories with fixed facts, including one where you explained a technical decision to a peer or manager
  • Prepare the AI-tools answer: which tool, for which task, how you checked the output, and a case where you chose not to use it
  • Run a mock with one array coding question and one design question, narrating your reasoning from the first sentence

Deliverable: A one-page answer sheet for the recruiter screen and panel, plus notes from one narrated mock.

Practice prompt ↗Practice prompt ↗Worked solution ↗

Expand any day for tasks and deliverables. Your progress is saved on this device.

The behavioural questions reported for this role are about motivation, communication and working habits. Answer each one with a specific example that holds up under follow-up questions: the decision you made, who you explained it to, what changed as a result, or which tool you used and how you checked its output.

How do you handle authentication, identity propagation, and standardiz…

medium
behavioural and engineering judgement

How do you handle authentication, identity propagation, and standardized error responses across nested API endpoints?

Approach
  1. Give the blast radius: what could have broken, and what you measured.
  2. Name the disagreement and how you resolved it with evidence.
  3. State the situation in two sentences and spend the rest on the reasoning.
Follow-up
  • What would you do differently if you ran that again?
  • How did you know your change caused the improvement?

How do you approach incorporating AI productivity tools into your dail…

medium
behavioural and engineering judgement

How do you approach incorporating AI productivity tools into your daily software engineering workflow?

Approach
  1. Close with what you would do differently, concretely.
  2. Give the blast radius: what could have broken, and what you measured.
  3. State the situation in two sentences and spend the rest on the reasoning.
Follow-up
  • What did you decide not to do, and why?
  • What would you do differently if you ran that again?

Reverse your own decision on hold expiry

medium
reversibilityhold lifecyclemeasurementjudgement

You chose sweeper-only expiry for inventory_hold_night: a job flips lapsed rows from active to expired and returns units, and the availability read trusts the state column alone. Production contradicted the choice. Describe a decision you reversed: what you originally believed and why it was reasonable, the specific observation that changed your mind, how long you waited before reversing, what the reversal cost, and what you kept from the first design. Name the metric that moved and one that did not.

Approach
  1. Say what made the original choice reasonable, because a reversal story with no defensible starting point reads as carelessness rather than judgement. Sweeper-only expiry keeps the read path trivial and lets the partial index on (unit_type_id, stay_date) WHERE state = 'active' answer availability with no clock in the query.
  2. Give the observation that broke it, in numbers. When the sweeper falls behind by L seconds, up to L seconds of lapsed holds still read as active, so availability is understated and searches lose bookable inventory on exactly the dates where holds are densest, which are the dates that sell. Availability understatement is the metric that moves first.
  3. Separate it from the opposite failure so the reversal is not mistaken for a panic. A sweeper that releases a hold the booking path has already converted increments capacity back and oversells, which is why the release must be conditional on the active-to-released transition and not a bare increment. Both failures are real and they pull in different directions.
  4. State the reversal concretely: evaluate expiry against the clock at read and write time, filtering active rows by expires_at_utc, and keep the sweeper for cleanup. Name the constraint that shapes it, namely that now() is not immutable so 'not expired' cannot be a partial index predicate; expiry is always a filter over the active set, which is exactly why the sweeper has to keep that set small.
  5. Report the cost honestly: a re-tested read path, a migration of in-flight holds, and a measurable increase in rows filtered per availability query. Then name a metric that did not move, because a candidate who claims everything improved is not measuring.
  6. Close on how long you waited and what you would watch earlier next time. Waiting for two data points beats reversing on one anecdote; waiting for a quarter is a different mistake.
Follow-up
  • What is the right TTL for a hold, and what evidence would set it rather than a round number?
  • How do you stop the sweeper from releasing a hold that the booking path converted a millisecond earlier?
  • If the sweeper falls two minutes behind under load, what does a traveller see and what does the revenue graph show?
  • 01

    Why are you interested in working at Fora Travel and building tools for the travel industry?

  • 02

    Tell me about a time when you had to clearly explain a technical decision to a peer or hiring manager.

  • 03

    How do you approach incorporating AI productivity tools into your daily software engineering workflow?

  • 04

    What are your salary expectations, and what draws you to travel technology?

  • 05

    What role do you see technology playing in modern travel advising?

PracHub interview preparation framework
Is this an official Fora Travel interview guide?

No. It is PracHub's own research and practice material for the Software Engineer role at Fora Travel. Rounds and questions reflect what candidates have reported, not a process Fora Travel has published, and they change over time. Confirm the current format and scope with your recruiter.

PracHub interview research
Which language should I use in the technical evaluations?

Candidates report that algorithmic tasks can be done in your preferred general-purpose language, while the frontend debugging work uses JavaScript, HTML and CSS. Practise array problems in the language you write most fluently, practise debugging in plain JavaScript and CSS, and confirm the environment with your recruiter.

PracHub interview research
How much does interest in travel matter?

Candidates report that the recruiter screen covers interest in travel technology alongside career history and salary expectations, and the reported questions include one about why you want to build tools for the travel industry. Prepare a specific answer tied to the work of travel advisors, such as managing bookings, client communication or legacy tools, rather than to your own trips.

PracHub interview research
Will I be asked about AI tools?

A reported behavioural question asks how you incorporate AI productivity tools into your daily engineering workflow. Answer with a concrete example: the tool, the task, how you checked its output, and a case where you decided not to use it.

PracHub interview research
What kind of coding questions come up?

The reported coding questions focus on array fundamentals: merging an unsorted array into the empty tail of another and sorting the result, stating the time and space complexity of that approach, and returning the first element that meets a filter or merge condition. Practise in-place array handling, edge cases such as empty inputs and duplicates, and stating Big-O for time and extra space without being asked.

PracHub Software Engineer practice
What should I study for the design questions?

The two reported design topics are REST APIs for a three-level Course, Module and Lesson hierarchy, and a mobile backend where clients periodically report their location to trigger proximity-based notifications. For the first, practise URI structure, payloads, pagination, authentication and a consistent error format. For the second, practise spatial indexing (geohash, S2 or quadtree), keeping ingestion separate from processing, and reliable push delivery.

PracHub Software Engineer practice
Sources & methodology 3 sources ↗

Official role evidence, timestamped platform data and clearly labeled preparation advice.