Skip to content

Index Research (Jul 2021 – Apr 2025)

Analyst → Associate, Software Engineer II. Owned a client-reporting application and its daily-operations modules.

Ownership, production support, security, tech debt

STAR: a production incident (have one ready; this is the most common senior behavioural question)

  • S: Fill in: a daily run or monthly report failed / was late / was wrong.
  • T: Restore service for operations before the client deadline, then stop it recurring.
  • A: Triage: what changed (deploy, data, upstream feed), logs and the failing step; mitigate first (rerun, fix data, roll back); communicate status to operations on a timeline; then the root cause and a permanent fix (a validation, a test, an alert).
  • R: Fill in: delivered on time / delay of X; the fix that stopped it happening again.
How do you prioritise between BAU operations requests, production issues and feature work?

Production issues affecting clients first. Then deadlines with external commitments (monthly reports). Then automation of the most frequent manual BAU tasks, because each one frees time forever. Make the trade-off visible to the manager/PO instead of silently juggling.

What security work did you do?

Fill in. Typical: fixing vulnerable dependencies flagged by scanners (Sonar, Black Duck/Snyk), upgrading libraries, removing unused packages (the Sybase driver), access control on endpoints, secrets out of config.

How did you work with the operations team?

Sat with them to watch the manual task, wrote down the steps, found the repetitive parts, built a tool for the 80% and kept a manual path for the rest, then iterated on their feedback. Measured success by time saved. Fill in one example.

Database schema redesign, caching, backend optimisation

STAR

  • S: The schema limited scale: onboarding a new client was hard and monthly reports to a large client base were slow or unreliable. Fill in: the actual limitation (e.g. per-client tables or columns, duplicated data, missing keys, a wide table that locked during the month-end run).
  • T: Redesign it so new clients onboard by configuration, not code, and reports deliver reliably.
  • A: Fill in. General shape: model clients and their report configuration as rows (not tables/columns), normalise the duplicated data, add indexes for the report queries, migrate data with a script and reconcile old vs. new outputs, cache reference data, and optimise the slow queries/batch steps.
  • R: Onboarding became easy; reports delivered reliably every month. Fill in: time per run before/after, onboarding time before/after.
How did you migrate the data without breaking production?

Expand → migrate → contract: add the new tables alongside the old; backfill; dual-write or switch reads behind a flag; reconcile (row counts, checksums, comparing report output old vs. new); switch; remove the old after a safe period. Always have a rollback.

How do you find a slow query?

Measure first: slow query log / APM; EXPLAIN (or EXPLAIN ANALYZE) the query; look for full scans, missing indexes, bad join order, functions on indexed columns, N+1 patterns from the ORM. Fix with an index (matching the WHERE and ORDER BY), rewriting the query, batching, or caching. Measure again.

What did you cache and how did you keep it correct?

Fill in. Reference data that rarely changes (client configs, index metadata) is ideal: cache with a TTL and evict on update. Never cache without a story for invalidation.

Java 8 → 11 → 17 and iBatis → MyBatis; Sybase removal

STAR

  • S: The app was on Java 8 with iBatis (abandoned since ~2010) and an outdated Sybase package, slowing releases and failing security scans.
  • T: Lead the upgrade to supported versions without disrupting monthly reporting.
  • A: Stepwise: 8 → 11 first (the big break), then 11 → 17. Updated build plugins and libraries, fixed removed APIs, moved iBatis SQL maps to MyBatis mappers, removed the Sybase package and its dependencies, ran the full regression and compared report output before and after.
  • R: Faster, more secure releases on a supported JDK. Fill in: duration, number of modules, issues found.

What breaks, by step (know these)

Step Common breakages
8 → 9/11 Module system: internal APIs (sun.misc.*) restricted; Java EE modules removed in 11 (JAXB, JAX-WS, javax.activation, CORBA) so add them as dependencies; Nashorn deprecated; old Lombok/Mockito/ASM/byte-buddy versions fail on new bytecode; class loader changes (no more URLClassLoader cast on the system loader)
11 → 17 Strong encapsulation (JEP 403): illegal reflective access is an error, not a warning, so old libraries need upgrades or --add-opens; Security Manager deprecated; Spring Boot 2.5+/Spring 5.3+ needed; Gradle/Maven plugin versions
Beyond 17 Spring Boot 3 requires Java 17 and moves javax.* → jakarta.*

Features gained (they may ask "what did you use from 11/17?")

  • 9–11: List.of, Map.of, var (10), Optional.isEmpty, String.isBlank/strip/lines/repeat, the new HttpClient (11).
  • 14–17: switch expressions, text blocks, records, pattern matching for instanceof, sealed classes (17), helpful NullPointerExceptions.
iBatis vs. MyBatis vs. JPA/Hibernate?

iBatis and MyBatis are SQL mappers: you write the SQL, they map results to objects. MyBatis is iBatis 3, renamed and maintained, with annotations, dynamic SQL (<if>, <foreach>), and Spring integration. JPA/Hibernate is an ORM: you map entities and it generates SQL, with caching and lazy loading. MyBatis wins for complex reporting queries and full SQL control; JPA wins for CRUD-heavy domain models. The migration was mostly moving SQL maps to mapper XML/interfaces and fixing result maps.

Why upgrade in two steps instead of 8 → 17 directly?

11 is an LTS and isolates the biggest break (modules, removed Java EE). If something fails, you know which step caused it. Each step is releasable on its own.

Lucene search for end-user feedback

What Lucene is: a Java library for full-text search. Elasticsearch and Solr are servers built on it.

Concept Meaning
Inverted index Map from each term to the list of documents (postings) containing it; that makes search fast
Analyzer Tokeniser + filters (lower-case, stop words, stemming) applied at index and query time; must match
Document / Field A record and its named parts; fields can be indexed, stored, or both
Scoring BM25 by default (term frequency, inverse document frequency, length normalisation)
Segments Index is written as immutable segments, merged in the background; a reader sees a point-in-time view
Why Lucene instead of SQL LIKE '%term%'?

LIKE with a leading wildcard cannot use a B-tree index (full scan), has no ranking, no stemming, no typo tolerance. Lucene gives relevance-ranked results in milliseconds. For a single app with moderate data, embedding Lucene avoids running an Elasticsearch cluster.

How did you keep the index in sync with the database?

Fill in. Options: update the index in the same code path that writes feedback (simple, but a crash between the two leaves them out of sync), reindex periodically, or reindex everything at start-up if small.

Cypress/Cucumber BDD proof of concept

  • Cucumber: scenarios in Gherkin (Given / When / Then) that non-developers can read; step definitions bind them to code.
  • Cypress: runs end-to-end tests in a real browser, with automatic waiting and time-travel debugging.
  • Why a PoC: to show operations-readable acceptance tests running in CI. Fill in: what happened next.
Unit vs. integration vs. end-to-end tests: how much of each?

Test pyramid: many fast unit tests, fewer integration tests (real DB via Testcontainers, real HTTP), few slow E2E tests for critical user journeys. E2E is valuable but flaky and slow, so keep it to the paths that would hurt most if broken.

New ETF platform (FastAPI, PostgreSQL, AWS)

  • S/T: A new platform replaced a legacy ETF system. Fill in: your part (APIs, data loaders, a migration).
  • FastAPI talking points: async (ASGI), request/response validation from type hints (Pydantic), automatic OpenAPI docs, dependency injection with Depends.
Why Python/FastAPI there when the rest is Java?

Fit for the team and the work: data-heavy, quick iteration, the data/quant ecosystem (pandas, NumPy). FastAPI gives typed, documented APIs with little code. The cost is two stacks to maintain.