SLR Consulting · Software Engineer
Updated · 2026-09-24

SLR Consulting Software Engineer
Interview Questions & Guide 2026

THE 60-SECOND BRIEF

At SLR Consulting, the Software Engineer role bridges the gap between complex environmental data and actionable engineering solutions. You will work at the intersection of technical software development and high-stakes environmental consultancy, creating tools that allow SLR Consulting's teams to model, analyze, and mitigate environmental impacts for global clients.

Scope in the operational half of the job when the seat carries on-call. Rollout, rollback and what you would put on a dashboard belong inside a design answer rather than after it, and an answer that never reaches them reads as someone who has built systems but not run them.

SLR Consulting candidates report 2 rounds · ≈ 2-4 weeks. The stages below are what candidates describe, not a published process.

Bound credential lifetime by the engagement end dateEvolve schemas expand-contract across un-upgradable client deploymentsMake integration retries idempotent without target-side idempotency keys

33 min read

Browse Software Engineer questions

See the practice prompts

13Practice promptsAcross five skill areas
3With worked solutionsIncluded in the practice prompts

At SLR Consulting, the Software Engineer role bridges the gap between complex environmental data and actionable engineering solutions. You will work at the intersection of technical software development and high-stakes environmental consultancy, creating tools that allow SLR Consulting's teams to model, analyze, and mitigate environmental impacts for global clients.

This role is critical to the firm’s ability to scale its technical advisory services. Whether you are developing bespoke software for tailings management, environmental monitoring, or resource analysis, your code directly influences how the firm manages natural resources and ensures compliance. You will collaborate with multi-disciplinary teams of scientists and engineers, turning abstract technical requirements into robust, reliable, and high-performance software systems.

01

Initial Screening

reported

The person on this call usually cannot evaluate your code and does not need to. They write a short paragraph, and that paragraph is what a hiring manager skims when deciding who to put on your loop. So the test is not whether your work was hard, it is whether a non-engineer can repeat it correctly. Name systems by what they did rather than by their internal codename, give each project a shape (what was breaking, what you changed, what happened after), and keep the whole walkthrough near ninety seconds. Depth that cannot survive a paraphrase reads as vagueness.

What to demonstrate

  • Whether a non-engineer can restate your projects without distorting them, since their paraphrase is what travels to the hiring manager, not your sentences
  • Whether each project has a shape rather than a stack list: the failure or constraint, the change you made, the result and how it was measured
  • Whether you can say what was yours inside a team project without either inflating it or disappearing into the plural

How to prepare

  • Rewrite each headline project as two sentences with no internal system names and no acronyms outside your company, then say them to someone outside engineering and have them repeat them back. Fix whatever came back wrong
  • Attach one measured number to each project: the baseline, the change, and the window it was measured over. Where nothing was ever measured, say that plainly rather than reaching for a plausible percentage
  • Time the background walkthrough against a clock. If it runs past two minutes, compress the earliest role to a single clause and spend the recovered time on the most recent one
PracHub interview research ↗
02

Technical Deep-Dive

reported

The same problem is scored by two different mechanisms depending on the format, and preparing for one does not cover the other. With a person watching, partial progress is visible and a hint is a correction you can absorb; silence is the expensive failure, because nobody can read a half-written function. With an automated grader there is no partial credit for what you were about to do, nobody to ask, and the worked examples in the prompt are the entire specification. Read them as a contract, down to whether an empty result should be an empty list or no output at all.

What to demonstrate

  • In a live session, whether your commentary tracks what your hands are doing, and whether a hint redirects you or gets defended against
  • In an automated one, whether you cover the cases the examples do not show, since the hidden cases are where the score moves
  • Whether you manage the clock on purpose: abandoning an approach that is not converging while there is still time to write something simpler that finishes

How to prepare

  • Have someone hand you a problem and feed you one deliberately wrong hint. Practise testing it against a concrete case instead of accepting or rejecting it on authority.
  • Do one timed run a week in a plain browser editor with autocomplete, linting and your own snippets switched off, which is closer to what these environments give you
  • For the automated format, write the harness before the solution: a main that feeds the worked examples plus an empty and a single-element case and prints expected against actual, so a wrong submission is caught by you first
PracHub interview research ↗

PracHub editorial advice for the preparation topics above.

01

Long-lived shared credentials for client systems

One static key used by the connector runtime, a debugging script and three engineers cannot be attributed to a person in an audit, cannot be expired at engagement close, and cannot be rotated without breaking an unknown number of consumers at once. The expensive part of the eventual incident is not the leak; it is that rotation requires finding every holder under time pressure, and nothing recorded who they were. Issue per-principal, per-target, short-lived grants from a broker so rotation is a no-op, attribution is automatic, and closure is a TTL rather than a search.

02

Depending on a client field because it is always populated

It is populated by their operational process, not by a constraint in their database, and their process changes without telling you. When it stops being populated, a permissive pipeline writes nulls or defaults into derived data and the damage spreads for weeks before anyone notices. Validate at the boundary and fail the run with failure_class='schema_mismatch' plus a redacted sample, so the failure is loud, attributable to the client's change, and cheap to diagnose. A run that fails clearly is far cheaper than a backfill that has to reconstruct which rows were silently wrong.

03

Issuing one query per row of a result set

Fetch related rows in a single batched query keyed by the ids you already hold, or join them into the original query. A per-row round trip multiplies network latency by the row count, and it looks perfectly fine against the ten rows in your development database.

04

A queue or buffer with no bound

Every producer-consumer boundary needs a capacity and a policy for reaching it: block the producer, shed load, or drop the oldest entry. Unbounded buffering converts a temporary slowdown into memory exhaustion and hides the backpressure signal that would have revealed the consumer was falling behind.

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

10 technical prompts3 include a worked solution

Measure credential exposure past engagement close without double counting

medium
interval mergesweep linecredential ttl

For one engagement you have credential_grant rows: (grant_id, principal_id, target_system_id, issued_at, not_after, revoked_at which may be NULL). The cutoff instant T is the engagement's ends_on plus access_grace_days. A grant is live over the half-open interval [issued_at, min(not_after, revoked_at)). There are up to 200,000 grants across target systems. For each target_system_id, return the total wall-clock time after T during which at least one grant was live, plus the disjoint segments that make it up. Grants that overlap must be counted once.

Approach
  1. Clip each grant to [max(issued_at, T), min(not_after, coalesce(revoked_at, +inf))) and discard any interval whose start is not strictly before its end. O(n), and it removes every grant that already expired inside the engagement window.
  2. Bucket the survivors by target_system_id and sort each bucket by start. O(n log n) overall, and sorting dominates the whole algorithm.
  3. Sweep each bucket once, holding one open segment [s,e): if the next start is greater than e, emit [s,e) and open a new segment, otherwise set e = max(e, next_end). O(n) after the sort, O(1) working state, O(number of emitted segments) output.
  4. Total exposure is the sum of emitted segment lengths, which is the measure of the union. Summing per-grant durations instead answers a different question and is unbounded above by the elapsed wall clock.
  5. Produce a second, conservative figure that ignores revoked_at and uses not_after alone. revoked_at records that you asked for revocation; whether the client's identity provider honoured it is not something this table knows, and a self-contained token validated offline stays valid to its own expiry regardless.
  6. If a bucket does not fit in memory, sort externally and sweep the stream, or push end timestamps into a min-heap keyed by end and pop those below the current start. Same O(n log n), memory proportional to the maximum number of concurrently live grants.
Follow-up
  • Three grants overlap and one of them belongs to an offboarded contractor. What must the sweep emit so exposure can be attributed per principal?
  • Which of your two numbers is the real bound on access if the client system validates tokens offline, and what does that imply about issuing TTLs in the first place?
  • Run this across 20,000 engagements as a nightly job with a fixed memory budget. What changes in the shape of the computation?

Resolve effective-dated engagement versions for two million access checks

hardWorked solution
binary searcheffective datingcomplexity budget

The engagement table holds 500,000 effective-dated rows: (engagement_id, version, effective_from, effective_to which is NULL for the open version). A database exclusion constraint guarantees that per engagement_id the tstzrange(effective_from, effective_to) values never overlap, and the ranges are half-open. You must answer 2,000,000 access checks of the form (engagement_id, at_time) in one process with no database, returning the version open at that instant or none. Also report, per engagement, any coverage gap between adjacent versions. Give the complexity of the scan-per-check approach and say why it is not an option.

Approach
  1. State the naive cost first: scanning the table per check is 2e6 x 5e5 = 1e12 range comparisons. Even at 1e9 simple comparisons per second that is roughly fifteen minutes of pure compare work, against a budget measured in seconds. It is correct, just unaffordable, and the fix is an index built once rather than a faster comparison.
  2. Build a hash map engagement_id -> array of versions sorted by effective_from, once. O(V log V) to sort, O(V) memory. The build is amortised over 2e6 lookups, which is what makes it worth doing at all.
  3. Answer each check by binary-searching for the last effective_from <= at_time, then confirming effective_to IS NULL OR at_time < effective_to. If the confirmation fails, the instant lies in a gap and the answer is none, not the neighbouring version. O(log v) per check, O(V log V + Q log v) total.
  4. Name the precondition: predecessor search is only valid because the ranges per engagement do not overlap, which the exclusion constraint enforces with btree_gist for the equality operator. Without that guarantee you need an interval tree returning all stabbed intervals, at O(log n + k). Use the same half-open convention as the database, where at_time equal to effective_to belongs to the next version.
  5. Find gaps with one O(V) pass over each sorted array comparing prev.effective_to against next.effective_from. The exclusion constraint forbids overlaps, not holes, so a hole is entirely possible and is where an access check fails closed for a reason nobody can see in the contract.
  6. If the checks can be buffered, sort them by (engagement_id, at_time) and merge against the version arrays: O(Q log Q + V log V), usually a large constant-factor win over 2e6 random binary searches because the merge walks memory in order.
Worked solution 35 min
  1. Index engagement E1 with v1 [2026-01-01, 2026-04-01), v2 [2026-04-01, 2026-07-01), v3 [2026-07-01, NULL), and engagement E2 with v1 [2026-01-01, 2026-03-01) and v2 [2026-04-01, NULL).
  2. Query (E1, 2025-12-31): predecessor search finds no effective_from <= at_time, so the answer is none.
  3. Query (E1, 2026-04-01T00:00:00Z): the predecessor is v2, not v1, because the boundary instant belongs to the later range under half-open semantics. Query (E1, 2026-06-30T23:59:59Z) returns v2 and (E1, 2026-09-01) returns v3.
  4. Query (E2, 2026-03-15): the predecessor is v1, but at_time is not less than v1.effective_to (2026-03-01), so the confirmation fails and the answer is none.
  5. Adjacent-pair pass on E2: v1.effective_to = 2026-03-01 is earlier than v2.effective_from = 2026-04-01, so report the gap [2026-03-01, 2026-04-01).
EXPECTED RESULTE1: none, v2, v2, v3 for the four queries in order. E2: none at 2026-03-15, with a reported coverage gap of [2026-03-01, 2026-04-01). The scan-per-check approach is O(Q*V) = 1e12 comparisons; the indexed approach is O(V log V + Q log v).
Follow-up
  • The open version has effective_to NULL. How do you keep both the sort and the comparison total without a sentinel that overflows your timestamp type?
  • A gap exists for one engagement and a check lands in it. What should the access path return, and what should it emit so someone fixes the amendment?
  • Amendments are being written while you answer checks. What read model keeps an answer self-consistent, and what does a check mean if the snapshot is a second stale?

Compare release versions and report the live estate spread

easy
parsingversion skewordering

Each environment row carries reported_release as TEXT: either NULL, or a version of the form MAJOR.MINOR.PATCH with an optional -rc.N suffix. Up to 400 environments. Ordering rule: compare major, then minor, then patch numerically; a -rc.N build precedes the same MAJOR.MINOR.PATCH with no suffix, and rc numbers compare numerically. Return the lowest and highest reported versions, the minor-version spread between them, and the count of environments whose reported_release is NULL. NULL means the environment's version is unknown, not that it converged.

Approach
  1. Parse each string once into a comparable tuple: (major, minor, patch, is_final, rc), where is_final is 1 for a plain release and 0 for a pre-release, and rc is 0 when absent. Tuple comparison then yields the stated order for free, including 3.10.0-rc.1 < 3.10.0. O(L) per string, O(n*L) total.
  2. Track min and max in one linear scan rather than sorting: O(n) time, O(1) extra space, and n is only a few hundred so the parse dominates either way.
  3. Fail loudly on a string that does not match the grammar instead of defaulting it to 0.0.0 or to the newest release. An unparseable reported_release is a reconciliation-ingest bug, and either default hides it in the direction that looks safe.
  4. Compute the minor spread only when min and max share a major version. Across majors the difference of minor numbers is meaningless, so return the pair of versions and flag the condition rather than a number.
  5. Report the NULL count as its own output line. Folding unknowns into 'converged' is how an install ends up running a release nobody knew was still live.
Follow-up
  • Two majors are live at once. What does 'spread' mean now, and what single number, if any, would you still publish?
  • reported_release is a claim from the environment, and last_heartbeat_at may be days old for a client-managed install. At what staleness does this figure stop being usable?
  • How would you enforce the supported window when the rollout plan is built, instead of reporting a violation after it already exists?

Roughly ninety minutes on weeknights with one longer weekend block. The plan cuts scope rather than compressing everything, on the assumption that one thing finished per night beats four half-started.

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
01Fix the scope and take a cold baseline
  • Read the role description and write the three things the loop will almost certainly test, then write an explicit not-doing list and keep it visible all week.
  • Take one twenty-five-minute coding problem and one fifteen-minute design prompt cold, and write the single sentence naming what blocked each, because those two sentences decide where the remaining evenings go.
  • Set the week's rule: one thing finished every night, including the night you only have forty minutes.

Deliverable: A one-page scope with a not-doing list and two cold attempts, each carrying one sentence on what blocked it.

Practice prompt ↗Practice prompt ↗Worked solution ↗
02One pattern, written three times from blank
  • Choose the single pattern most likely to appear in your loop and write it three times from an empty file rather than editing the previous attempt.
  • On the third pass, write the invariant as a comment before the loop body and the complexity before the first line of code.
  • Stop at ninety minutes even if the third version is imperfect, and write the one thing you would fix given another hour.

Deliverable: Three independent implementations of the same pattern plus a note on what changed between them.

Practice prompt ↗Practice prompt ↗
03One design, only to the depth you can defend
  • Take one system shape and go only as far as requirements, interface and data model, refusing to draw a box you could not survive a follow-up about.
  • Attach one number to each non-functional requirement, deriving it rather than asserting it, and write the assumption the number rests on.
  • Write the one tradeoff you are choosing against and the observation that would make you reverse it.

Deliverable: One design at interface-and-schema depth with derived numbers and one written reversible tradeoff.

Practice prompt ↗Practice prompt ↗
04Only the fundamentals you will have to defend
  • Write, in under two hundred words each, the answers to the two questions that follow almost any implementation: why this structure and not the obvious alternative, and what happens to this code at a hundred times the input.
  • Write what an index actually costs: faster lookups on the indexed columns against a write that now maintains a second structure, plus the cases where the planner declines to use it anyway, low selectivity, or a predicate wrapping the column in a function.
  • Delete any answer you cannot deliver aloud in under a minute, since an answer that needs reading is not an answer you have.

Deliverable: Three written answers, each under two hundred words and each timed aloud.

Practice prompt ↗Practice prompt ↗Worked solution ↗
05Your own work, timed
  • Write a ninety-second and a four-minute version of your main project and time both aloud rather than reading them.
  • Prepare the two follow-ups that always come: what you would do differently, and how you knew it worked.
  • Put one number in the first sentence and be ready to say exactly where it came from and what it excludes.

Deliverable: Two timed narratives with one defensible number in the opening line.

Practice prompt ↗Practice prompt ↗
06The one full rehearsal, in the weekend block
  • Run a sixty-minute mock covering a coding round and a design round in one sitting with no break, because sustained attention is the thing evenings have not trained.
  • Immediately afterwards, and before hearing any feedback, write the three moments you lost the thread.
  • Spend the rest of the block only on those three moments, and on nothing you merely feel shaky about.

Deliverable: Mock notes naming three failure moments with a specific fix written under each.

Practice prompt ↗Practice prompt ↗
07Taper
  • Write the twenty-minute warm-up you will actually do on the morning: one problem you can already solve from a blank file, one design you can narrate, and nothing you have never seen.
  • Re-read only your own notes from this week and open no new material.
  • Write the logistics down: the editor or shared document you will be working in, whether execution and lookups are permitted, and the sentence you will use when you do not know something.

Deliverable: A one-page card holding the design structure, the project numbers, and the logistics.

Practice prompt ↗Worked solution ↗

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

Bring the two or three numbers the story rests on and know how they were collected. A p99 whose timer starts inside your handler excludes the time a request spent queued, so it can sit flat while users wait longer. Give the window, the percentile and what the measurement left out, or drop the number.

How do you handle conflicting requirements from stakeholders who may n…

medium
behavioural and engineering judgement

How do you handle conflicting requirements from stakeholders who may not understand the technical limitations of a system?

Approach
  1. Close with what you would do differently, concretely.
  2. State the situation in two sentences and spend the rest on the reasoning.
  3. Pick a story where you made the decision, not one where you watched it.
Follow-up
  • What did you decide not to do, and why?
  • How did you know your change caused the improvement?

Walk me through a time you had to optimize a slow-performing algorithm…

medium
behavioural and engineering judgement

Walk me through a time you had to optimize a slow-performing algorithm or data query.

Approach
  1. Name the disagreement and how you resolved it with evidence.
  2. Give the blast radius: what could have broken, and what you measured.
  3. Close with what you would do differently, concretely.
Follow-up
  • What did you decide not to do, and why?
  • What would you do differently if you ran that again?

Report a residency boundary crossing you discovered yourself

hard
data residencyescalationegress controls

You discover that a global sink, such as an error tracker, a central metrics pipeline, an analytics export or a cross-region support tool, has been receiving fields that originated in a restricted residency region, through no feature change at all. Describe a time you surfaced a problem like this: something nobody was asking about, with a contractual dimension, that would have been easier to leave alone. State how much scope you established before escalating, who you told and in what order, and what you changed so the class could not recur silently.

Approach
  1. Establish scope before raising it, and time-box that work: which fields crossed, roughly how many records, over what period, into which sink, where that sink stores its data and what its retention is. An escalation missing those is noise that spends credibility you will need later.
  2. Stop investigating alone at the point where the answer changes who must know. A residency crossing usually carries a notification obligation, so the engagement owner and legal enter before your scoping is complete, with the unknowns named explicitly.
  3. Say what you stopped versus what you left running. Cutting the pipeline can destroy the very records you need for scope, so the usual move is to stop the egress at the source and preserve the sink under legal hold.
  4. Give a structural fix rather than a cleanup: a redaction allowlist at each egress point instead of a denylist, regionally partitioned sinks with no cross-region data dependency, and a test that fails when a tagged payload field reaches a global sink.
  5. Name the incentive you were working against, since the finding was yours and it created work for people who had not asked for it, without turning the account into a story about your own integrity.
Follow-up
  • Your scoping query would itself read the crossed data out of the global sink. How do you scope without widening the exposure?
  • The pipeline was added by another team for a good reason and their change passed review. What did the review process miss, and what would you add that does not slow down every change?
  • 01

    How do you handle conflicting requirements from stakeholders who may not understand the technical limitations of a system?

  • 02

    Walk me through a time you had to optimize a slow-performing algorithm or data query.

  • 03

    You discover that a global sink, such as an error tracker, a central metrics pipeline, an analytics export or a cross-region support tool, has been receiving fields that originated in a restricted residency region, through no feature change at all. Describe a time you surfaced a problem like this: something nobody was asking about, with a contractual dimension, that would have been easier to leave alone. State how much scope you established before escalating, who you told and in what order, and what you changed so the class could not recur silently.

PracHub interview preparation framework ↗
Is this an official SLR Consulting interview guide?

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

PracHub interview research ↗
How much time should I dedicate to preparation?

Plan for at least two weeks of focused preparation. Spend time reviewing your past projects and ensuring you can articulate the "why" behind your technical decisions.

PracHub interview research ↗
What differentiates successful candidates?

Successful candidates show a high degree of ownership. They don't just write code; they understand the business problem the code is meant to solve and take responsibility for the final outcome.

PracHub interview research ↗
Is there a focus on specific technologies?

Candidates report that core engineering fundamentals count for more than any single language, but being able to demonstrate proficiency in your primary language of choice is essential.

PracHub interview research ↗
How is the culture at SLR Consulting?

The culture at SLR Consulting is described as highly collaborative and project-driven. Candidates report that the firm values individuals who are proactive, communicative, and passionate about solving complex environmental challenges.

PracHub interview research ↗
Sources & methodology 3 sources ↗

No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.