cswork / libraryOpen practice workspace

Interview guides · Carbon Lighthouse

Carbon Lighthouse Software Engineer Interview Guide

Carbon Lighthouse Software Engineer interview guide: three reported rounds, practical test prep, behavioral STAR answers and a seven-day plan.

The 60-second brief

Carbon Lighthouse is described in candidate-facing material as a company working on energy efficiency in commercial buildings. The software engineer role, as candidates describe it, builds and maintains software systems that analyze energy consumption data, adds new features and keeps existing systems running. Day to day, the work is reported to involve product managers, data analysts and energy engineers, so the code you write turns requirements from non-software colleagues into working tools.

This guide is for candidates interviewing for the Software Engineer role at Carbon Lighthouse. It covers the three reported rounds (Phone Screen, Practical Test, In-Person Interview), the behavioral, technical, problem-solving and project-management questions candidates report, and a plan for rehearsing them. The requirements candidates describe list Python, Java or JavaScript, plus experience with data analysis tools. Cloud platforms, front-end frameworks and knowledge of energy systems are described as nice to have.

Candidates report three rounds over roughly three to five weeks: a Phone Screen, a Practical Test built around data analysis or a coding exercise, and an In-Person Interview made up of several conversations with different team members.

Focus areas

  • Behavioral Interviewing
  • Microsoft Excel
  • Data Analysis

Overview

The reported loop mixes two kinds of evidence. One is what you have done: the behavioral and project-management questions ask for stories about wrong decisions, difficult colleagues, deadlines, scope changes and coordination across teams. The other is what you can do on the spot: the practical test is described as a data analysis or coding exercise, and the problem-solving questions are about energy-consumption tracking, missing values, slow applications and deployments that go wrong. Prepare both, because neither round type is optional.

The product domain shapes the technical preparation. Software here analyzes energy consumption data, so the exercises you rehearse should look like it: tabular readings over time, gaps and obviously wrong values, aggregation by building or period, and a calculation that compares measured use with some baseline. Candidates also report Microsoft Excel and data analysis among the topics, so be ready to do a quick pivot, a lookup or a chart in a spreadsheet as well as a script in Python. Whichever language you choose from Python, Java or JavaScript, write it cleanly with a few tests, because working code you can explain is the point of a practical test.

The role is described as collaborative, with product managers, data analysts and energy engineers as partners, plus code reviews and sprint planning. That makes the project-management questions (time, tools, scope changes, stakeholder updates, coordination) as worth rehearsing as the algorithms. A good answer names a real project, who needed what from you, and what you changed after the conversation.

One practical point: the reported material does not give a fixed question list per round, so do not assume a question will arrive in a particular round. Build a small set of reusable assets instead: five or six STAR stories that can bend to several prompts, one tidy data-analysis routine you can write from memory, and one system-design outline for an energy-tracking service.

The Carbon Lighthouse interview process

Candidates describe three stages, with a timeline of about three to five weeks end to end. The wording below reflects what candidates report, not a published schedule.

Phone Screen

The Phone Screen is reported as a first assessment that covers both technical skills and behavioral competencies. Because both appear, treat it as a short version of the whole loop: a concise account of your background, a clear statement of the languages and tools you know best, and one or two stories ready to tell. Pick the language you will speak about up front (Python, Java or JavaScript are the ones the role lists) and prepare three concrete things you built with it. Keep each story to a few sentences of setup, with the weight on what you decided and what happened.

What to demonstrate

  • Technical background, shown through specific projects in your strongest language
  • Behavioral competencies, shown through short stories with a clear outcome
  • How clearly you can describe your own past work

How to prepare

  • Write a two-minute walk through your CV that ends on why energy-efficiency software for buildings interests you, with no claims about the company beyond what you can verify
  • Prepare an honest answer for experience with a specific language or tool: what you built, how deep you went, where you are weaker
  • Have two STAR stories ready (a wrong decision you corrected, and a time you took initiative) that you can cut to under two minutes
  • Prepare questions about the team, the data it works with and how engineers work with energy engineers and analysts

Practical Test

The Practical Test is reported as a data analysis or coding exercise. Candidates also list Microsoft Excel and technical problem solving among the topics. Expect to be judged on working output and on whether you can explain how you got there. Start by restating the task and the assumptions (units, time zone, what a missing reading means, what baseline a savings figure is measured against). Inspect the data before computing anything: row counts, ranges, duplicates, gaps, outliers. Then write a small, readable solution with a couple of checks, and finish by stating what you would verify with more time.

What to demonstrate

  • Working code or a correct analysis on realistic tabular data
  • Handling of missing values and anomalies in the data
  • How clearly you explain your method and assumptions

How to prepare

  • Rehearse a pandas routine on a synthetic meter-reading file: parse timestamps, resample to hourly and daily totals, count gaps, flag values beyond a threshold
  • Practice the same task in Excel with a pivot table, a lookup and a chart, since Excel is a reported topic
  • Write a function that calculates energy savings from a baseline and a measured series, with tests for empty input, negative values and mismatched lengths
  • Run the exercise aloud against a clock you set yourself, and stop to state your assumptions before you start typing

In-Person Interview

The In-Person Interview is reported as several conversations with different team members, covering technical and behavioral areas, and candidates describe it as possibly running for several hours. The reported question types you can expect to see are system design for tracking energy consumption, debugging and performance, scaling, deployment problems, project coordination and the behavioral set. Prepare for repetition across conversations: you may tell the same story twice, so know two versions of each one. Bring a clear picture of one complex project you built, because several question types (past projects, code quality, learning a technology) can all start from it.

What to demonstrate

  • Technical depth across design, debugging and performance topics
  • Behavioral evidence across several separate conversations
  • Collaboration with product, analytics and engineering colleagues, as the role describes

How to prepare

  • Outline an energy-consumption tracking service: meter or sensor ingestion, a time-series store, aggregation by building and period, a read API, handling late and missing readings
  • Prepare a debugging sequence you can narrate: reproduce, narrow by bisecting, check recent changes, confirm the fix with a test
  • Prepare a rollback-first answer for a deployment that behaves differently than expected, including how you would tell users and teammates
  • Write down your project, the people you coordinated with and one decision you would now make differently

Where candidates lose points

Treating the practical test as a coding puzzle and skipping the data inspection, so missing readings or odd values skew the result.

Open every data task by looking at the data: row count, time range, duplicates, gaps and extremes. State what a missing reading means and how you treat it (drop, interpolate, flag) before computing totals. Say aloud that you checked.

Writing an energy-savings calculation without saying what it is compared against, or with unit and period mismatches.

Define the baseline and the measured series, confirm they cover the same period and units, and write tests for empty input, negative values and unequal lengths. Share your assumptions at the start so the reader can correct them.

Giving a system-design answer for energy tracking that lists technologies and never reaches ingestion, late data or aggregation.

Follow the data: how readings arrive, where they are stored by time, how hourly and daily totals are computed, how late or missing readings are handled, how the read API serves a building and a date range. Then address scale and failure.

Behavioral answers where the story is vague, the 'we' hides your part, or the result is missing.

Use STAR with the weight on Action and Result. Say 'I decided' and 'I did' for your part, name the people you worked with, and finish with a number or an observable change. Keep a different story for each prompt and a second one in reserve.

Claiming skill in Python, Java or JavaScript and then being unable to go beyond the basics, or not knowing what the project the story came from actually did.

Prepare three specifics for the language you name: a project, a limitation or mistake, and how you test it. Re-read your own past work the day before so the details are fresh.

Questions & practice

Canonicalise a request body into a stable idempotency fingerprint

Medium · parsing · canonicalisation · hashing

idempotency_key.request_fingerprint is a SHA-256 over the method, path and canonicalised body, and a retry whose fingerprint differs must be rejected with 422 rather than served the stored response. Write the canonicaliser. Bodies are JSON up to 256 KB nested at most 32 levels; clients vary key order, whitespace and unicode escaping, and some send 64-bit ids as JSON numbers. Produce a deterministic byte string such that semantically identical bodies match and any semantic difference does not. State your complexity and name two normalisations you refuse to perform.

Approach

  1. Parse once into a tree, then re-serialise under fixed rules: object keys sorted, array order preserved, one escaping convention, no insignificant whitespace. Parsing is O(n) and sorting keys is O(k log k) per object, so O(n log n) overall with O(depth) stack, and the 32-level cap is enforced during parsing because hostile nesting is how a canonicaliser becomes a stack overflow.
  2. Sort keys by their UTF-8 bytes and say why the obvious implementation is wrong in some runtimes: a default string comparison that orders by UTF-16 code units places surrogate pairs, meaning code points from U+10000 up, below U+E000 to U+FFFF, which is not UTF-8 byte order, so two services written in different languages disagree on the same document.
  3. Do not re-encode numbers through a double. IEEE-754 binary64 represents integers exactly only up to 2^53, so normalising a 19-digit id through a float changes it, and 1 against 1.0 cannot be reconciled without deciding whether they are the same value. Preserve the literal token, and require ids as strings at the API boundary if you want them comparable.
  4. Reject duplicate keys rather than picking one. JSON permits them and parsers disagree, most keeping the last, so any choice you make ties the fingerprint to a parser detail that the code handling the request does not necessarily share.

Follow-up

  • A client sends the same logical request with an extra field your API ignores. Same key, different fingerprint, so you return 422. Is that the right answer?
  • Where does the fingerprint get computed relative to request decompression and the body-size limit?

Merge partitioned event streams into one ordered feed with bounded lateness

Hard · k-way merge · watermarks · out-of-order streams

The read-model service consumes 64 log partitions carrying about 4,000 events per second in total. Each partition is ordered within itself, but partitions drift by up to 30 seconds, and the activity feed must present a tenant's events in occurred_at order. Produce the merge. State its complexity, the buffer it requires in events and in bytes, what happens when one partition is idle, and what you do with an event that arrives after you have already emitted its position. Payloads average 1 KB.

Approach

  1. Merge with a min-heap over the 64 partition heads keyed on (occurred_at, event_id): O(log P) per event and O(n log P) overall. The tie-break on event_id is what makes the output deterministic when two partitions carry the same millisecond, which matters because the feed is paginated and a non-deterministic order reorders pages under the reader.
  2. Emitting the heap head is only correct once every partition has produced everything up to that timestamp, so the emit condition is a watermark: the minimum across partitions of the highest occurred_at seen, less the allowed lateness. Events are held until the watermark passes them, which is what turns individually ordered streams into a jointly ordered one.
  3. Size the buffer from the lateness rather than guessing: 4,000 events per second times 30 seconds is 120,000 buffered events, and at 1 KB each about 120 MB of heap. That number is the real price of the ordering guarantee and belongs in front of whoever asked for it.
  4. Handle the idle partition explicitly, because it fails the feed rather than corrupting it: a partition with no traffic never advances its own maximum, so the watermark freezes and output stops entirely. Either every partition emits a periodic idle marker carrying the broker's current time, or the watermark falls back to wall clock for a partition silent beyond a threshold.

Follow-up

  • The lateness budget is raised to five minutes. What is the new buffer, and what besides memory changes?
  • The consumer restarts. Where does it resume from, and what does the feed look like for the first 30 seconds?

Diff a projection against the primary without per-row point reads

Hard · reconciliation · range hashing · throttling

The listing projection has drifted and some rows show a stale version. The primary holds 40,000,000 resource rows across 12,000 tenants while serving 1,200 writes and 14,000 reads per second. The obvious repair, reading each resource row and comparing its version against the projection, is correct and would eventually finish. Explain precisely why it is unacceptable here, then give a diff that finds the differing rows, state its complexity, and make it safe to run against a live primary. Replication lag is usually under 100 ms and is not bounded.

Approach

  1. Quantify the naive cost rather than calling it slow: 40,000,000 point reads at even 0.5 ms each is over five hours serialised, and the only lever is concurrency, which is exactly what you cannot spend. The primary's pool is sized for the write path, and 40,000,000 random reads evict the buffer cache that sustains the 85 percent cache hit rate, so the audit degrades the system it is auditing.
  2. Replace random access with one ordered pass per side. Both sides can be read in (tenant_id, resource_id) order, which is a sequential scan on each and a merge join in O(n) time and O(1) memory. For a dense diff that is the whole answer, and it reads the primary once instead of 40,000,000 times.
  3. For the expected sparse case, compare range hashes instead of rows: partition the key space, compute per range an order-independent aggregate over hash(resource_id, version), compare aggregates, and descend only into ranges that differ. With d differing rows and branching factor B, at most d ranges mismatch per level, so the drill-down examines O(d log_B(n/d)) ranges and reads full rows only in mismatching leaves.
  4. Aggregate with a sum modulo 2^64 or a multiset hash, never XOR. XOR is order-independent but self-cancelling, so two rows wrong in the same way, or a row duplicated on one side, leave the range aggregate matching and the range is declared clean.

Follow-up

  • The diff reports 900 stale rows. How do you decide between patching those rows and rebuilding the projection from resource_revision?
  • Same job, but the projection lives in a search index that cannot be scanned in key order. What changes?

Denormalise tenant onto revisions and backfill it live

Hard · denormalisation · online migration · backfill

resource_revision (revision_id, resource_id, version, actor_user_id, change_kind, patch, request_id, created_at) has 400M rows and no tenant column; tenant_id lives only on resource. Two reads need it: a tenant-scoped audit feed ordered by created_at DESC, and an offboarding purge. Both join back to resource today. Justify adding tenant_id to resource_revision against those two reads, name the anomaly the copy introduces and the constraint that prevents it, then give the ordered migration for a live table taking 1.2k writes/second — the lock each step takes, how the backfill is batched, and where each step stops being reversible. PostgreSQL 16.

Approach

  1. Justify from the access path rather than from taste. Without the column, the audit feed either scans resource_revision by created_at and discards other tenants' rows, or resolves the tenant's resource_ids first and probes with them — both proportional to the tenant's whole history rather than to one page. With (tenant_id, created_at DESC, revision_id DESC) it is a seek that stops at 50 rows, and the purge becomes a ranged delete instead of a join.
  2. Name the cost exactly: a second copy of a fact can disagree with the first. Make the disagreement unwritable rather than documented — add UNIQUE (resource_id, tenant_id) on resource so it can serve as a foreign-key target, then FOREIGN KEY (resource_id, tenant_id) REFERENCES resource (resource_id, tenant_id) on the revision table. A revision can then only ever carry its parent's tenant.
  3. Step one, expand: ALTER TABLE resource_revision ADD COLUMN tenant_id BIGINT NULL, with no default, so it is a catalogue change and no rewrite. It still needs ACCESS EXCLUSIVE for an instant, and that instant queues behind the longest open transaction on the table while every later query queues behind it — set lock_timeout to 2s and retry rather than wait.
  4. Step two, dual-write: deploy the writer that populates tenant_id on every new revision while reads still use the join. Reversible by redeploying the previous build, because nothing reads the column yet.

Follow-up

  • The backfill is half finished and a rollback is required. What state is the table in, and what does the previous build do with a half-populated column?
  • How do you verify the backfill actually finished, given rows are still being inserted while it runs?

Write the update path that detects a concurrent edit

Medium · optimistic concurrency · transactional outbox · audit history

resource carries version INT NOT NULL DEFAULT 1. resource_revision holds revision_id, resource_id, version, actor_user_id, change_kind, patch JSONB, request_id, created_at with UNIQUE (resource_id, version). outbox_event holds aggregate_type, aggregate_id, aggregate_version, event_type, payload, status. A PUT carries the version the client read. Write the exact statements for the single transaction that applies the edit, records the revision and enqueues 'resource.updated', and give the handler's branch on zero affected rows. Then say what PostgreSQL 16 does under READ COMMITTED when two of these updates hit one row at once.

Approach

  1. One transaction, three writes, no network call inside it: UPDATE resource SET title = $3, version = version + 1, updated_at = now() WHERE resource_id = $1 AND tenant_id = $4 AND version = $2; then INSERT the resource_revision row at version $2 + 1; then INSERT the outbox_event row at the same aggregate_version. The event goes to a table rather than a broker because no transaction spans both.
  2. Branch on the affected-row count before doing anything else. Zero has three causes — stale version, wrong tenant, row gone — so re-read once and map to 409 carrying the current version, or 404 for an id outside the caller's tenant, which also stops the endpoint confirming that another tenant's id exists.
  3. State the engine behaviour instead of assuming it. Under READ COMMITTED the second UPDATE blocks on the row lock, and when the first commits PostgreSQL re-evaluates the WHERE clause against the newly committed row, so the version predicate now fails and the statement reports zero rows. Under REPEATABLE READ the identical collision raises SQLSTATE 40001 instead, so the handler must fold both shapes into one conflict response.
  4. Keep UNIQUE (resource_id, version) even though the predicate already serialises writers. It is what makes a lost update unwritable if any other path ever reaches the revision table, and it converts a logic bug into 23505 rather than into a silently missing history row.

Follow-up

  • A client sends the version it read ten minutes ago and the resource has moved three versions. What is in your 409 so it can resolve the conflict without a full re-fetch?
  • Two editors, two disjoint fields, no overlap. Does your answer still refuse the second write, and should it?

Describe a complex software project you've worked on in the past.

Medium · Technical Questions

Approach

  1. Pick one project where you owned a defined piece, and open with the problem, the constraints (data volume, latency target, team size, deadline) and the specific thing that made it complex, such as three data sources with conflicting schemas.
  2. Sketch the architecture in four or five components and trace one request or one record through it, so the listener can follow the data flow before you go deep on any part.
  3. Name the one design decision you would defend, the alternative you rejected (batch vs streaming, relational vs document store, monolith vs service) and the trade-off that decided it.
  4. Tell one thing that went wrong, how you found it and what you changed, then give a measured result (latency, error rate, cost, hours saved) and how it was measured.
  5. Keep your contribution separate from the team's: say "I wrote", "I chose", "I reviewed", and be explicit about what others owned.

Follow-up

  • If you started that project again today, what would you design differently?
  • Which part was hardest to test, and how did you test it?
  • What broke in production, and how did you find out?

How do you ensure code quality and maintainability in your projects?

Medium · Technical Questions

Approach

  1. Start with automated gates that run on every pull request: a formatter and linter (black and ruff or flake8 for Python, Prettier and ESLint for JavaScript), type checks (mypy or TypeScript), and a CI test run that blocks the merge when it fails.
  2. Describe the test mix: many fast unit tests on pure functions (an energy-savings calculation is a good example: fixed inputs, known output), fewer integration tests against a real database, a handful of end-to-end tests, and a regression test added for every bug fixed.
  3. Explain how you review code: small pull requests, Git branch protection, and review comments spent on naming, error handling, edge cases and missing tests rather than style the tools already enforce.
  4. For maintainability, keep I/O separate from logic so the logic is testable, define clear module interfaces, avoid abstraction until a second use case exists, pin dependencies, and record non-obvious decisions in a README or decision record.
  5. Treat coverage as a signal, not a target, and back the answer with one concrete case where a test or review caught a real defect before release.

Follow-up

  • A teammate's pull request works but is hard to read. What do you do?
  • How do you change a legacy module that has no tests?
  • When is it acceptable to ship without full test coverage?

Explain a situation where you had to learn a new technology quickly.

Medium · Technical Questions

Approach

  1. Choose a real case with a deadline attached, and name the technology and why the work needed it (a new framework, a cloud service, a data library), not a course you took for interest.
  2. Show the method: official docs and the getting-started guide first, then the smallest end-to-end spike that touches every layer you need, then reading a working example or the library source for the parts the docs skip.
  3. Show how you managed the risk: a time-boxed spike, pairing with someone who knew the tool, targeted questions, and a written fallback if the spike failed.
  4. Name one thing you misunderstood at first (an async model, a caching default, a pricing or permission rule), how you found out, and what you changed.
  5. Close with what shipped, by when, and what you left behind for others: notes, a template repo or a short internal walkthrough.

Follow-up

  • What did you get wrong first, and how did you notice?
  • How did you know your code was idiomatic and not just working?
  • If you had to pick up a front-end framework you had never used, what would your first week look like?

How would you design a software system for tracking energy consumption?

Medium · Problem-Solving Questions

Approach

  1. Clarify scope first: data sources (interval meters, building management systems, utility bills), number of buildings and meters, read frequency, who reads the data (analysts computing savings, client dashboards) and how fresh it must be. State assumptions out loud: 10,000 meters at 15-minute reads is 96 reads per meter per day, about 960,000 rows a day and roughly 350 million a year.
  2. Ingestion path: collectors or an API push readings onto a queue (Kafka, SQS or similar); a validation step normalises units, converts timestamps to UTC and rejects impossible values; writes are idempotent upserts keyed on (meter_id, timestamp) so retries and late corrections do not double-count.
  3. Storage: keep raw payloads in object storage for replay, and readings in a time-partitioned table indexed on meter_id and timestamp (Postgres with partitioning or a time-series database). Maintain hourly, daily and monthly rollups per building so dashboards never scan raw rows.
  4. Analysis layer: batch jobs compute baselines and savings as adjusted baseline minus actual consumption, normalised for weather with degree days, and recompute the affected rollups when a correction arrives.
  5. Reliability and access: detect gaps and alert on meters that stop reporting, flag rather than silently fill missing intervals, render in each building's local time while storing UTC (daylight-saving days have 92 or 100 quarter-hours), and scope every query by client for multi-tenant access control.

Follow-up

  • A meter sends corrected readings for last week. What gets recomputed, and how?
  • How would you detect a meter reporting plausible but wrong values?
  • How does the design change if facilities staff need near-real-time alerts?

If you were given a dataset with missing values, how would you approach analyzing it?

Medium · Problem-Solving Questions

Approach

  1. Profile before deciding: missing count and percentage per column, per entity and over time (df.isna().sum(), grouped by building or month), and look for disguised missing values such as 0, -1, empty strings or sentinel dates. In meter data a 0 kWh reading may be a real zero or a dropout.
  2. Ask why values are missing: completely at random, at random given other columns, or not at random (a sensor fails exactly when load is extreme). Compare rows with and without gaps on other variables; dropping rows only stays unbiased under the first.
  3. For time series, resample to a regular grid first (df.resample('15min').mean() turns absent intervals into explicit NaN rows), interpolate only short gaps (interpolate(method='time') on a DatetimeIndex, or ffill with a limit), and flag long gaps instead of inventing data.
  4. For longer gaps or modelling, impute from a profile (same weekday and time of day) or a regression on weather, or use median imputation plus a missing-indicator column. Fit any imputer on training data only to avoid leakage.
  5. Report a sensitivity check: the key result computed with drops, with imputation and with gaps excluded, plus the share of data that was imputed, so the reader knows how much the conclusion depends on the filling.

Follow-up

  • How would you tell a true zero reading from a sensor dropout?
  • What does mean imputation do to variance and correlations?
  • One building is missing an entire month. What do you report for it?

Describe your process for optimizing a slow-performing application.

Medium · Problem-Solving Questions

Approach

  1. Define slow precisely: which operation, current p50, p95 and p99 latency or throughput, and the target. Reproduce it with representative data volume, because many slowdowns appear only at production scale.
  2. Measure before changing anything: a profiler (cProfile or py-spy for Python, JFR or async-profiler for Java, the browser Performance panel for front-end code) or request traces, to see whether time goes to CPU, database, network or rendering.
  3. Fix the largest cost first. Database: EXPLAIN ANALYZE, missing indexes, N+1 query patterns, selecting only needed columns, pagination. Code: replace O(n^2) nested scans with dictionary lookups, vectorise pandas instead of iterrows or row-wise apply, batch network calls.
  4. Front end: shrink payloads by aggregating server-side, paginate or virtualise long lists, cut bundle size, and stop unnecessary re-renders (React.memo, stable props).
  5. Re-run the same benchmark to confirm the gain, add a performance check or alert so it does not regress, and name the cost of the fix: cache staleness, extra memory or added complexity.

Follow-up

  • The profile shows time spread evenly with no hotspot. What next?
  • How do you confirm the fix helped in production and not only on your machine?
  • When would you decide not to add a cache?

What considerations would you take into account when scaling a software application?

Medium · Problem-Solving Questions

Approach

  1. Start from the growth dimension and the bottleneck: more users, more data, higher request rate or more tenants. Do a rough capacity estimate and find which component saturates first (CPU, database connections, disk, a third-party rate limit).
  2. Application tier: keep it stateless behind a load balancer so it scales horizontally, move session state to a shared store, and autoscale on a load metric (AWS Auto Scaling groups or Azure VM Scale Sets).
  3. Data tier, in rough order of cost: indexes and query fixes, caching hot reads, read replicas (accepting replication lag), partitioning large tables by time, and sharding by tenant only when one primary can no longer take the writes.
  4. Move slow work off the request path: queues and workers for reports and batch analysis, with idempotent handlers, retries with exponential backoff and a dead-letter queue.
  5. Operational side: metrics, logs and traces to see the next bottleneck, load tests before launches, rate limiting, redundancy across availability zones, and cost, since every replica and cache layer adds spend and another failure mode.

Follow-up

  • Which component in your last project would fail first at ten times the traffic?
  • How do you scale writes rather than reads?
  • What do you give up by adding a read replica or a cache?

How would you handle a situation where your solution doesn't work as expected during deployment?

Medium · Problem-Solving Questions

Approach

  1. Stabilise first: check error rates and how many users are affected, then decide between rolling back and rolling forward. Rollback is the default when it is quick and safe; a feature flag lets you switch the change off without a redeploy.
  2. Communicate straight away: post in the team or incident channel with impact, current action and the next update time, and tell affected stakeholders before they find out themselves.
  3. Diagnose what differs between the tested environment and production: configuration and environment variables, secrets and permissions, dependency versions, data volume and shape, and whether a database migration ran. Read logs and metrics from the deploy timestamp onward.
  4. Plan for the case where rollback is blocked: backward-compatible migrations (expand, migrate, contract) keep old code working against the new schema; if a migration cannot be reversed, ship a tested forward fix.
  5. Afterwards, write a blameless review, add the test or staging check that would have caught it, and reduce future blast radius with canary or blue-green releases.

Follow-up

  • A migration has already run and rollback is not possible. What do you do?
  • How do you decide between a rollback and a hotfix?
  • What check would have caught this before release?

How do you manage your time when working on multiple projects?

Medium · Project Management Questions

Approach

  1. Show the system: one list across all projects with deadlines, dependencies and rough estimates, reviewed at the start of each week and each day, so nothing lives only in memory.
  2. Explain the ordering rule: work that blocks other people first, then deadline and impact, then effort. When two projects conflict, the person who owns both priorities makes the call, with the trade-off laid out for them.
  3. Protect focus time: block calendar time for deep work, batch reviews and messages, and limit how many things are in progress at once, since context switching is where time goes.
  4. Flag slips early with options (cut scope, move the date, get help) instead of absorbing them with late nights.
  5. Ground it in one real week with numbers (three projects, two deadlines, what you deferred and why), and avoid claiming you never miss a deadline.

Follow-up

  • Tell me about a time you missed a deadline. What happened?
  • Two leads each say their project comes first. What do you do?
  • How do you estimate a task you have never done before?

Describe a project where you had to coordinate with different teams.

Medium · Project Management Questions

Approach

  1. Pick a project that crossed team boundaries. The role as candidates describe it involves product managers, data analysts and energy engineers, so a story with non-engineering partners fits well.
  2. Show the coordination mechanism: a shared goal, an agreed interface (API contract, data schema, file format) written down early, one owner per decision, and a regular sync plus a shared tracker.
  3. Describe one real friction point (a dependency slipped, priorities changed, two teams read a requirement differently) and how you resolved it: with data, a renegotiated scope or an escalation with options.
  4. Show translation between vocabularies: how you explained a technical constraint to non-engineers, or turned a domain expert's requirement into something testable.
  5. End with the outcome and what you would set up earlier next time, such as agreeing the contract before either side started building.

Follow-up

  • What happened when the other team's priorities changed mid-project?
  • How did you resolve a disagreement over the interface between the teams?
  • Who had the final call on scope, and how was it reached?

What tools do you use for project management and why?

Medium · Project Management Questions

Approach

  1. Name tools you have actually used (Jira, Linear, Trello, Asana or GitHub Issues and Projects) and describe the workflow: backlog, prioritised sprint or kanban board, clear statuses and a definition of done.
  2. Explain the why: each tool serves visibility, dependency tracking or estimation. A light board suits a small team, while cross-team work needs something that shows dependencies and owners.
  3. Connect tickets to code: branch names and pull requests reference ticket keys, so anyone can trace a change from requirement to commit in Git.
  4. Cover the surrounding layer: specs and decisions in a shared doc space (Confluence, Notion, Google Docs), async discussion in chat, and how you track your own tasks inside the team's system.
  5. Show judgment about overhead: a time you simplified or changed a process, for example dropping a status nobody used or splitting oversized tickets, and what it changed.

Follow-up

  • What do you do when the board no longer reflects what is really happening?
  • How do you estimate tickets, and how accurate have your estimates been?
  • What would you change about your last team's process?

Explain how you communicate project updates to stakeholders.

Medium · Project Management Questions

Approach

  1. Tailor to the audience: leadership gets status, risks and any decision needed; engineers get technical detail; non-technical partners and clients get impact in their terms (dates, what they can use, what it means for the energy data they rely on).
  2. Use a consistent written format on a fixed cadence: status (on track, at risk, off track), progress since the last update, next steps, risks and asks, with the bottom line in the first sentence.
  3. Deliver bad news early, with options and a recommendation rather than only the problem.
  4. Back updates with evidence: a short demo of working software, a dashboard or a burn-down, rather than percent-complete guesses.
  5. Give one real example where an update changed a decision, such as a stakeholder cutting scope after an early risk flag.

Follow-up

  • Tell me about a time you had to deliver bad news on a project.
  • How would you explain a technical delay to a non-technical stakeholder?
  • How do you know your updates are being read and understood?

What strategies do you use for debugging software issues?

Medium · Technical Questions

Approach

  1. Reproduce first: get the exact input, version and environment, shrink it to the smallest failing case, and capture that case as a failing test so you know when the fix works.
  2. Ask what changed: recent commits, deploys, config, dependency versions and incoming data. For a regression with a known good commit, git bisect finds the culprit in about log2(n) test runs.
  3. Form one hypothesis at a time and test it with the cheapest experiment: a breakpoint (pdb, a Java debugger, browser DevTools), a targeted log line or an assertion, changing one variable per run.
  4. Recognise common bug classes: off-by-one errors, None or null handling, timezone and daylight-saving shifts, unit mix-ups (kW vs kWh), and non-deterministic failures that point to races or shared state and need logging or stress runs rather than a debugger.
  5. Fix the root cause rather than the symptom, keep the regression test, search the codebase for the same pattern, and write a short note on what would have caught it earlier.

Follow-up

  • How do you debug an issue you can only observe in production?
  • The bug disappears when you add logging. What does that suggest, and what next?
  • Walk through the bug that took you longest to find.

Suggested practice checklist

The plan follows the reported loop: a data and coding practical test first, then system design and debugging for the in-person conversations, then behavioral stories and project-management answers, ending in a full mock. Technical days point at the reported questions.

Day 1 — Map the loop and pick your language

  • Write the three reported rounds (Phone Screen, Practical Test, In-Person Interview) and note which question types each format covers
  • Choose the language you will speak about from Python, Java or JavaScript, and write three projects you built in it with one limitation for each
  • Write a two-minute CV walk-through and your answer about your experience with that language or tool

Deliverable: A one-page loop map, a language fact sheet with three projects and a limitation each, and a written CV walk-through.

Day 2 — Data analysis on a meter-reading dataset

  • Build or find a synthetic file of timestamped energy readings with gaps, duplicates and a few spikes
  • In Python, parse timestamps, resample to hourly and daily totals, count gaps and flag outliers; decide and state how you treat missing values
  • Repeat the summary in Excel with a pivot table, a lookup and a chart

Deliverable: A short script and an Excel workbook that produce the same daily totals, plus a written list of your missing-value and outlier rules.

Day 3 — Coding exercise: savings calculation and stream handling

  • Write a function that computes energy savings from a baseline series and a measured series, with tests for empty input, negative values and unequal lengths
  • Write down the baseline assumption and the units out loud as if explaining them to an analyst

Deliverable: A tested savings function, a written assumption list, and one solved stream-merging practice problem.

Day 4 — Design a system for tracking energy consumption

  • Outline ingestion, time-series storage, aggregation, a read API and handling of late or missing readings
  • Say what changes at ten times the volume and name the first bottleneck
  • Answer the scaling-considerations question using the same outline

Deliverable: A one-page design for an energy-consumption tracking system, with a scaling section and a failure section.

Day 5 — Debugging, performance and deployment problems

  • Write a debugging sequence you can narrate: reproduce, narrow, check recent changes, fix, add a test
  • Write a profiling-first plan for a slow application: measure, find the hot spot, change one thing, measure again
  • Write a rollback-first answer for a release that behaves differently than expected, including who you inform

Deliverable: Three short written playbooks, one each for debugging, performance and a failed deployment.

Day 6 — Behavioral stories, spoken

  • Write five STAR stories covering a wrong decision, a difficult colleague, initiative, a major challenge and a priority conflict
  • Record yourself answering each one and trim to the essentials; check that every story has a result
  • Prepare a second version of each story with a different emphasis, since several conversations may cover similar ground

Deliverable: Five recorded STAR answers plus a second version of each, with results stated.

Day 7 — Project management answers and full mock

  • Prepare answers on time management, scope changes, coordinating teams, project tools and stakeholder updates, each tied to a real project
  • Describe your most complex project, including code quality practices and how you learned something new fast
  • Run a full mock in order: a short phone-style intro, a timed data or coding task, then design and behavioral questions

Deliverable: Written project-management answers, a single project description, and notes from one full mock run.

Behavioral stories for the Carbon Lighthouse loop

Candidates report behavioral questions in the Phone Screen and again among the In-Person Interview conversations, alongside project-management questions about time, scope and coordination. For a role that works with product managers, data analysts and energy engineers, the useful stories show a decision you made, how you worked with people from other functions and what you changed afterwards. Prepare a separate real story for each prompt below, and keep a second one in reserve.

Tell me about a time when you made a wrong decision and how you corrected it.

Medium · Behavioral Questions

Approach

  1. Choose a decision that was truly yours and that had a real cost, such as a design choice, a library, an estimate or a release call. A story where the harm was trivial reads as a disguised strength.
  2. Say what information you had when you decided, then what changed it: a failing metric, a bug report, a review comment or a data point you had ignored. The point is how you noticed.
  3. Describe the correction in order: contain the damage (rollback, flag, pause), tell the people affected, fix the root cause, then record what you learned.
  4. Finish with a durable change, for example a test, a checklist item or a rule about when you ask a second person before committing. Name the change; do not just say you learned a lesson.
  5. Do not shift the blame onto a spec or a teammate. Mentioning constraints is fine, but the story needs a clear first-person statement that the call was yours.

Follow-up

  • What would you do differently if you faced the same decision tomorrow?
  • How did you tell stakeholders, and how soon after you noticed?
  • Was there a warning sign you could have caught earlier?

Describe a situation where you had to work with a difficult team member.

Medium · Behavioral Questions

Approach

  1. Describe the friction in observable terms (missed handoffs, dismissive code review comments, changing requirements) rather than judging the person's character.
  2. Show you tried to understand their side first: a private conversation, a question about their constraints, a look at whether the process was creating the conflict.
  3. Give the specific step that changed the dynamic, such as agreeing on a review turnaround, writing decisions into the ticket or splitting ownership of a component.
  4. Report the result for the work as well as the relationship, and say what you would do if the same pattern returned. If you escalated, say what you tried first and why escalation was the right next step.
  5. Avoid a story whose moral is that you were right and they were wrong. If the colleague was a product manager, analyst or engineer from another group, say how the difference in goals showed up.

Follow-up

  • What did the other person say when you raised it?
  • What would you have done if that conversation had not helped?
  • Would you work with them again, and what would you change?

How do you prioritize tasks when you have multiple deadlines?

Medium · Behavioral Questions

Approach

  1. Answer with a method and then prove it with one real instance. The method: list everything due, estimate each item roughly, note dependencies and who is blocked, and rank by the cost of delay rather than by who asked loudest.
  2. Give the instance in numbers you can defend: three deliverables, their dates, what you did first and what you deferred. If two deadlines truly could not both be met, say how you told the stakeholders before the date, with options.
  3. Name the trade-offs you offered, such as cutting scope, delivering a thinner version first or moving a date, and which one the stakeholder chose.
  4. Mention how you protect the plan: blocking focus time, flagging risk early in standup or sprint planning, and rechecking the order when something new arrives.
  5. The common mistake is saying you work harder or longer. A stronger answer shows a decision to drop or delay something, deliberately and visibly.

Follow-up

  • What do you do when two stakeholders each say theirs is the top priority?
  • Tell me about a time a deadline slipped anyway. What did you do?
  • How do you decide when something is small enough to just do now?

Give an example of a time you took initiative on a project.

Medium · Behavioral Questions

Approach

  1. Pick something you started without being asked: a recurring manual task you automated, a flaky test you fixed, a missing runbook, an analysis nobody had requested. Say plainly who had asked for nothing.
  2. Explain how you decided it was worth the time: how often the problem occurred, what it cost the team, and how you kept the scope small enough to finish.
  3. Show how you brought others along: a short proposal, a check with the owner of the area, a demo. Initiative that ignores the people who own the code tends to end badly.
  4. Close with a measurable outcome (hours saved, failures removed, a tool others adopted) and what happened after you stopped running it yourself.
  5. A good story for this role might replace a hand-maintained spreadsheet step with a script, but use whatever is true for you. Avoid claiming credit for team work; say which part was yours.

Follow-up

  • How did you know the team wanted this, and not just you?
  • What did you not do, to keep it small?
  • Did it ever cause a problem for someone else?

Have you ever faced a major challenge at work? How did you overcome it?

Medium · Behavioral Questions

Approach

  1. Choose a challenge with technical or organizational difficulty you can explain in two sentences, such as an outage, a deadline with shifting requirements or a legacy module nobody understood. Then say specifically why it was hard.
  2. List the options you weighed and why you rejected some. Showing the alternatives is what separates a challenge story from a victory lap.
  3. Describe your actions as a sequence with your own role clear, and name the people you pulled in and what you asked of them.
  4. Give the result with evidence: a metric, a shipped date or a decision that held. If the outcome was partial, say so and say what remained.
  5. End with what you now do differently. Avoid a story where the challenge was only that you worked very long hours.

Follow-up

  • What was the hardest moment, and what did you do in it?
  • What would you have needed to start differently to avoid it?
  • Who helped you, and what did you ask them for?

Can you explain your experience with [specific programming language or tool]?

Medium · Technical Questions

Approach

  1. Replace the bracket with a real choice. The role lists Python, Java and JavaScript, plus data analysis tools, so pick the one you can talk about longest and be ready to name a second.
  2. Structure the answer as what you built, how long and how recently, then depth. Depth means specifics: for Python, generators, pandas vectorization and where the GIL limits threads; for Java, collections, concurrency utilities and checked exceptions; for JavaScript, the event loop, promises and async handling.
  3. Include the practice around the language: how you test, package, lint and review, and the tools you pair with it, such as Git or a spreadsheet for a quick check.
  4. Give one limitation or past mistake with the language (a mutable default argument, a floating-point rounding surprise, an unhandled promise rejection) and what you do now. Honest limits read better than a list of buzzwords.
  5. If the tool is one you have used lightly, say so and describe how fast you became useful with it, rather than stretching the claim.

Follow-up

  • What is something about this language that surprised you or that you got wrong early on?
  • How would you structure and test a small data-processing script in it?
  • What would you use instead of it for a CPU-heavy job, and why?

How do you handle changes in project scope or priorities?

Medium · Project Management Questions

Approach

  1. Pick a project where the scope or priority genuinely changed mid-flight, such as a new requirement from a stakeholder, a reorganized sprint or a dependency that moved. Say what changed and when you learned about it.
  2. Show a repeatable response: assess the impact on time, risk and other commitments, then take options to the decision-maker (add time, cut something, deliver in phases) instead of quietly absorbing the change.
  3. Describe how you re-planned and communicated: updated the ticket or sprint board, told the people downstream, and wrote the decision down so it could be revisited.
  4. Say what you kept steady: tests, review and the parts of the design that could survive the change.
  5. Avoid the answer that you are flexible and just adapt. The point is a visible trade-off, with the cost of the change stated to the people who requested it.

Follow-up

  • What did you push back on, and how did the stakeholder react?
  • How do you stop a late scope change from breaking something already finished?
  • Describe a change you declined, and why.