cswork / libraryOpen practice workspace

Interview guides · Citizens

Citizens Software Engineer Interview Guide

Citizens Software Engineer interview guide: reported rounds, security, coding and behavioral questions with answer approaches and a 7-day plan.

The 60-second brief

Citizens appears in these reports as a banking and financial-services employer. The Software Engineer role is described as building and maintaining applications for its banking and financial services. Candidates describe the daily work as gathering requirements with product managers, quality assurance staff and other engineers, implementing features, reviewing code, testing, resolving production issues, and following a change from requirements through deployment and maintenance. The requirements candidates describe list at least one language (Java, Python and C# are the examples), Agile and DevOps ways of working, SQL and NoSQL databases, and AWS or Azure as a plus. Front-end skills (JavaScript, React, Angular), design patterns and awareness of security practice are listed as nice to have. Reports mention no specific team, product line or internal technology beyond these.

This guide is for engineers applying to the Software Engineer role at Citizens; candidates describe a typical background of 2-5 years in software development. It covers every question candidates report: five security fundamentals, six behavioral prompts, four case-study prompts and three coding prompts. It also covers the two reported rounds, the stack the requirements list, and a seven-day plan. It cannot tell you which team you will meet or which exact question you will be asked, so it trains breadth across the reported question types.

Candidates report two rounds, Preliminary Assessments and In-depth Discussions, over about 2-4 weeks. The reported questions are grouped by type (security, behavioral, case study, coding) and are not tied to a particular round.

Focus areas

  • Confidentiality, Integrity, Availability (CIA)
  • TLS (Transport Layer Security)
  • Authentication vs Authorization

Overview

The reported technical questions are about security fundamentals rather than a particular framework: symmetric versus asymmetric encryption, how digital certificates are validated, TLS 1.1 against TLS 1.2, encryption versus hashing, and the CIA triad with authentication versus authorization. For a role that maintains banking and financial-services applications, that is a sensible place for questions to cluster, and it is where a general software engineer is most likely to be under-prepared. Each of these is a definition-plus-example question, so the preparation is to hold a short, correct answer for each and to know how they connect: hashing and signatures serve integrity, encryption serves confidentiality, and TLS uses certificates, asymmetric key exchange and symmetric bulk encryption together.

Beyond security, candidates report two classic coding prompts (reverse a linked list, find two numbers that add up to a target) and a prompt about explaining your thought process on a coding challenge on a platform like HackerRank. The case-study prompts are about process: how you work through a given software issue, how you would redesign a legacy system to improve efficiency, and what you would do when a critical bug is found in production. These map onto responsibilities candidates describe for the role, such as troubleshooting production issues and working through the full development lifecycle, so answer them with a sequence of steps you have actually used.

The behavioral set is conventional: a challenging project, prioritising under tight deadlines, a conflict with a team member, what motivates you, handling feedback, and learning a new technology quickly. Candidates also describe the second round as discussions with team members and stakeholders about technical capability and cultural fit, so have stories ready that show collaboration with product managers, QA and other engineers, not only your own coding.

On the stack, choose one language from the examples the requirements give (Java, Python or C#) and be ready to write the coding prompts in it without autocomplete. Review SQL and the difference between relational and NoSQL storage, and read up on whichever of AWS or Azure you have used. If you have front-end or design-pattern experience, prepare one example each, since they are listed as nice to have.

The Citizens interview process

Candidates describe two stages. Reports do not say which question belongs to which stage, so prepare every question type for both.

Preliminary Assessments

Candidates report that the Preliminary Assessments stage may include coding challenges or technical interviews. The reported coding prompts (reverse a linked list, find two numbers that add up to a target, narrate a HackerRank-style challenge) and the five security fundamentals are the technical material to practise. Treat it as a stage where working code and clear spoken technical answers both matter: write the code in your chosen language without autocomplete, say the approach and its complexity aloud as you go, and keep each security answer to a definition, a concrete example and one trade-off.

What to demonstrate

  • Working code on a coding challenge, since the stage may include one
  • Spoken technical answers, since the stage may be a technical interview
  • Command of security fundamentals such as encryption, hashing and TLS, which candidates report as technical questions

How to prepare

  • Write the linked-list reversal (iterative, with prev, current and next pointers) and the two-sum problem (one pass with a hash map) in Java, Python or C# from a blank file, with empty and single-element inputs handled.
  • Practise narrating a coding challenge on a HackerRank-style editor: restate the problem, name the brute force, choose the data structure, state complexity, then test with your own cases.
  • Record short spoken answers to the symmetric versus asymmetric, certificate validation, TLS 1.1 versus 1.2 and encryption versus hashing questions, and check each against a reference.

In-depth Discussions

Candidates report In-depth Discussions with team members and stakeholders, covering technical capabilities and cultural fit. That format is conversational: expect to explain your own work in depth, discuss how you collaborate with product managers, QA and other engineers, and talk through the case-study and behavioral prompts candidates report. Prepare stories from your resume in enough detail to survive follow-up questions, and bring a few questions of your own about the team and its work.

What to demonstrate

  • Depth of your technical experience as you describe it, including the technologies you have used
  • Collaboration and communication with team members and non-engineering stakeholders
  • Fit with the team and its way of working, as the stage is reported to cover cultural fit

How to prepare

  • Build a story bank for the six behavioral prompts (challenging project, deadline prioritisation, conflict, motivation, feedback, learning a technology quickly), each anchored in a real project from your resume.
  • Prepare a legacy-redesign answer and a production-bug answer from your own experience: what you measured first, how you limited risk, and how you verified the fix or the migration.
  • Write three questions for the team about code review, testing and release practice, and about how requirements move from product managers to engineers.

Where candidates lose points

Calling hashing one-way encryption, or saying encryption and hashing are interchangeable

Keep the contrast precise: encryption is reversible with a key and protects confidentiality; a hash has no key, is not meant to be reversed, and supports integrity checks and password storage. For passwords, add that a slow salted hash (bcrypt, Argon2 or PBKDF2) is used rather than a fast general-purpose hash, and that signatures combine a hash with asymmetric keys.

Describing TLS as encrypting all traffic with the server's public key

Explain the hybrid design: the certificate and asymmetric operations authenticate the server and establish a shared secret, and a symmetric cipher then protects the bulk data because it is far faster. Draw the handshake once on paper so you can say where the certificate is checked and where the session key appears.

Answering the certificate-validation question with only 'check that it is signed'

List the checks: the signature chain up to a root the client already trusts, validity dates, a hostname match against the certificate's names, key usage, and a revocation check through CRL or OCSP. Add that the server must prove it holds the private key during the handshake.

Typing the linked-list reversal or two-sum solution in silence, or losing the next pointer

Say the plan and complexity first (reversal in O(n) time and O(1) space; two-sum in one pass with a hash map, O(n) time and O(n) space), save the next node before re-pointing, and test with an empty list, one node and duplicate values before declaring it done.

Telling behavioral and case-study stories entirely in 'we', with no personal decision and no result

For every story, write down what you personally decided, what you did, the outcome and what you would change. For the production-bug and legacy-redesign prompts, give an ordered sequence: assess impact, mitigate or roll back, find the cause, fix, add a test, then review how it happened.

Questions & practice

Write a function to reverse a linked list.

Medium · Coding / Algorithms

Approach

  1. Use the iterative three-pointer reversal: prev = null, curr = head. While curr is not null: save next = curr.next, set curr.next = prev, advance prev = curr and curr = next. Return prev as the new head. This runs in O(n) time and O(1) extra space.
  2. Walk through the edge cases out loud: an empty list returns null, a single node returns itself, and two nodes check the pointer swap. The original head's next must end up null, or the list contains a cycle.
  3. Mention the recursive version: reverse the rest of the list, then set head.next.next = head and head.next = null. It is O(n) time but uses O(n) call stack, so a long list can overflow (CPython's default recursion limit is 1000).
  4. Test by building a list from an array, reversing it, and reading it back. Cover length 0, 1, 2 and an odd length, and reverse twice to check that you get the original back.
  5. For a doubly linked list, swap each node's prev and next pointers and return the last node visited.

Follow-up

  • Reverse only the nodes between positions m and n in one pass.
  • Reverse the list in groups of k nodes, leaving a final short group as it is.
  • Check whether a linked list is a palindrome using O(1) extra space.

Given a list of integers, find the two numbers that add up to a specific target.

Medium · Coding / Algorithms

Approach

  1. Clarify the contract first: return indices or values; is exactly one answer guaranteed; can the same element be used twice; are there duplicates or negative numbers; is the input sorted?
  2. State the brute force (check every pair, O(n^2) time, O(1) space), then improve it with a hash map from value to index. For each x, look up target - x before inserting x. This is O(n) time and O(n) space.
  3. Explain why lookup comes before insert: it stops an element pairing with itself and still handles duplicates correctly, for example [3, 3] with target 6 returns both indices.
  4. Give the alternative for sorted input: two pointers from both ends, moving left up when the sum is too small and right down when it is too large. That is O(n) after an O(n log n) sort with O(1) extra space, but sorting loses the original indices unless you sort (value, index) pairs.
  5. Cover the edge cases: no valid pair (return an empty result or raise, as agreed), fewer than two elements, and integer overflow of target - x in Java or C# (use long).

Follow-up

  • Return every unique pair that sums to the target, without duplicate pairs.
  • Extend it to three numbers summing to a target. What complexity can you reach?
  • How would you solve it if the numbers arrive as a stream or do not fit in memory?

Explain your thought process while solving a coding challenge on a platform like HackerRank.

Medium · Coding / Algorithms

Approach

  1. Read the statement and the constraints before coding. Constraints set the target complexity: around 10^5 elements rules out O(n^2) (about 10^10 operations) and points to O(n log n) or O(n), and value ranges tell you whether 32-bit integers overflow.
  2. Work the sample by hand, then write your own small cases from the constraints: minimum size, maximum values, duplicates, negatives, and an empty or all-equal input.
  3. Get a correct brute force first if the better idea is not clear, then optimise by choosing the data structure that fits the access pattern (hash map for lookups, heap for repeated min or max, prefix sums for range totals).
  4. Handle the platform details: read stdin exactly as the input format specifies, use fast input for large inputs, and run custom test input before submitting.
  5. Read the hidden-test results as a diagnosis: a timeout means the complexity is wrong, and a wrong answer on hidden cases usually means a missed edge case or overflow. Be ready to narrate one real problem you solved this way.

Follow-up

  • Your solution passed the sample but failed hidden tests. What did you check, and in what order?
  • With several problems on a timer, how do you decide when to submit a partial solution and move on?
  • Walk me through the complexity of the last assessment problem you solved.

Find version gaps and relay lag with window functions

Medium · window functions · event tables · frame semantics

outbox_event holds event_id, aggregate_type, aggregate_id, aggregate_version, event_type, payload, status ('pending','published','dead'), attempts, created_at, published_at. A projection is missing rows and you must decide whether the relay skipped events or the consumer dropped them. Write three queries over the last seven days: one listing every aggregate_id whose published aggregate_version sequence has a hole, one giving per-day counts with a running total, and one returning the newest published event per aggregate. For each, say where the window function is evaluated relative to WHERE and LIMIT. PostgreSQL 16.

Approach

  1. Gaps: compute lead(aggregate_version) OVER (PARTITION BY aggregate_id ORDER BY aggregate_version) in a subquery, then filter next_version <> aggregate_version + 1 in the outer query. Window functions are evaluated after WHERE, GROUP BY and HAVING and before the outer ORDER BY and LIMIT, so the predicate cannot sit in the same WHERE clause and PostgreSQL 16 has no QUALIFY.
  2. Say what the seven-day filter does to the answer: it truncates every partition, so the first row per aggregate has no predecessor inside the window and a hole spanning the boundary is invisible. Widen the window, or join to resource.version as the authority for the true maximum.
  3. Running total: SELECT date_trunc('day', created_at) AS d, count() AS n, sum(count()) OVER (ORDER BY date_trunc('day', created_at) ROWS UNBOUNDED PRECEDING). An aggregate inside a window call is legal because grouping runs before windowing. The grouping key is unique per row here so ROWS and RANGE agree, but write the frame anyway — over ungrouped rows with tied timestamps the default RANGE frame pulls in every peer row and the total jumps.
  4. Newest per aggregate: DISTINCT ON (aggregate_id) ... ORDER BY aggregate_id, aggregate_version DESC is the cheap PostgreSQL-only form when an index matches that order; row_number() OVER (PARTITION BY aggregate_id ORDER BY aggregate_version DESC) = 1 is the portable form and needs a subquery for the same evaluation-order reason as the gap query.

Follow-up

  • Relay failover redelivers events. Does a duplicate break the gap query, and how would you detect one from this table alone?
  • Turn the gap check into a continuous monitor rather than a query someone runs after an incident. What does it watch?

Stop tag and share joins from fanning out a page

Medium · join fan-out · semi-joins · many-to-many

resource_tag is (resource_id, tag_id) with PK (resource_id, tag_id); resource_share is (resource_id, shared_with_user_id, permission). The tagged-and-shared listing inner-joins resource to both, filters tenant_id, tag_id = ANY($2) and shared_with_user_id = $3, orders by updated_at DESC and takes 50. Pages come back with fewer than 50 distinct resources and the total in the header is far too high. Explain the row multiplication, rewrite both the page query and the count query so each is correct, and name the index each one needs. PostgreSQL 16.

Approach

  1. Do the arithmetic against the predicates that are actually there. An inner join emits one row per matching child row, and both joins are filtered: tag_id = ANY($2) admits only the requested tags, shared_with_user_id = $3 admits one user's share rows. So a resource holding three of the requested tags and shared with $3 once yields three rows, not one — the multiplier is its count of matching tags times its share rows for that single user, and that second factor is 1 unless the table admits duplicate (resource_id, shared_with_user_id) pairs. LIMIT 50 then limits rows rather than resources, and COUNT(*) counts pairs — the header is the product, not the population.
  2. Reject DISTINCT as the fix. It deduplicates after the product has been built, so the planner must materialise and sort the fanned-out set before the LIMIT can apply, and it leaves any SUM or AVG in the same select list wrong.
  3. Rewrite both filters as semi-joins, keeping resource as the only row source: AND EXISTS (SELECT 1 FROM resource_tag rt WHERE rt.resource_id = r.resource_id AND rt.tag_id = ANY($2)) and the same shape against resource_share. A semi-join stops at the first match per resource and preserves the driving index order, so ORDER BY updated_at DESC, resource_id DESC LIMIT 50 still stops after 50 rows.
  4. Count with the same predicates and no join at all: SELECT count(*) FROM resource r WHERE r.tenant_id = $1 AND r.status = 'active' AND EXISTS (...) AND EXISTS (...). Nothing multiplies a resource, so the number is the population.

Follow-up

  • The filter changes from 'any of these tags' to 'all of these tags'. Rewrite it and state what it costs relative to the ANY form.
  • A resource can be shared with the same user twice under different permissions. Does your count change, and should it?

Explain the difference between asymmetric and symmetric encryption and provide examples of their applications.

Medium · Technical / Domain Questions

Approach

  1. Define symmetric encryption: one shared secret key both encrypts and decrypts (AES-GCM, ChaCha20-Poly1305). It is fast and suits bulk data, but the key has to reach both sides securely, and n parties need n(n-1)/2 pairwise keys.
  2. Define asymmetric encryption: a key pair where the public key encrypts or verifies and the private key decrypts or signs (RSA, elliptic-curve schemes such as ECDH, ECDSA and Ed25519). It solves key distribution and enables signatures, but it is far slower and RSA can only encrypt a message smaller than its modulus.
  3. Give the hybrid pattern as the main application. In TLS, an ECDHE key exchange plus a certificate signature authenticate the server and agree a session key, and AES-GCM then encrypts the traffic. PGP and S/MIME wrap a random symmetric key with the recipient's public key.
  4. List symmetric-only uses (disk and database encryption at rest, envelope encryption with a KMS data key) and asymmetric-only uses (SSH key login, code signing, JWT signing with RS256 or ES256).
  5. Avoid the common slip: signing uses the private key and verification uses the public key. Encrypting with a private key is not how signatures are explained in modern schemes.

Follow-up

  • Why not encrypt a large file with RSA directly?
  • What is forward secrecy, and why does an ephemeral Diffie-Hellman exchange provide it when static RSA key exchange does not?
  • Where would you keep the symmetric keys for data at rest, and how would you rotate them?

How are digital certificates validated in a secure communication process?

Medium · Technical / Domain Questions

Approach

  1. Start from the handshake: the server sends its leaf certificate plus intermediates, and the client builds a chain up to a root CA already in its trust store. The root is trusted because it is pre-installed, not because of anything the server sends.
  2. For each link in the chain, verify the signature with the issuer's public key, check the notBefore and notAfter dates, and check that each issuer has basicConstraints CA:true and respects any pathLenConstraint.
  3. Check that the leaf is fit for the purpose: extendedKeyUsage includes serverAuth, and the requested hostname matches a Subject Alternative Name entry (the CN fallback is deprecated; a wildcard covers exactly one label).
  4. Check revocation through CRLs or OCSP, ideally with an OCSP response stapled by the server, and mention that many clients soft-fail when the responder is unreachable.
  5. Finish with proof of key possession: a valid chain only proves the identity binding. The server must also prove it holds the private key, by signing the handshake (the ServerKeyExchange in TLS 1.2 with ECDHE, CertificateVerify in TLS 1.3). Mutual TLS repeats this for a client certificate.

Follow-up

  • How would you get internal services to trust certificates issued by a private CA?
  • What does certificate pinning buy you, and what goes wrong when the pinned key rotates?
  • What does Certificate Transparency add on top of chain validation?

Compare TLS 1.1 with TLS 1.2 in terms of security features and performance.

Medium · Technical / Domain Questions

Approach

  1. Place the versions: TLS 1.1 (RFC 4346, 2006) and TLS 1.2 (RFC 5246, 2008). RFC 8996 formally deprecated TLS 1.0 and 1.1 in 2021, and major browsers had already stopped supporting them, so the practical answer is to disable 1.1.
  2. TLS 1.1's main fix over 1.0 was an explicit per-record IV for CBC ciphers, which closed the predictable-IV weakness BEAST exploits. It still has only CBC-with-HMAC and RC4 suites and no AEAD.
  3. TLS 1.2 adds AEAD cipher suites (AES-GCM, later ChaCha20-Poly1305), replaces the fixed MD5/SHA-1 PRF with a suite-specified PRF (SHA-256 based by default), and adds the signature_algorithms extension so handshake signatures can use SHA-256 or stronger.
  4. On performance, the full handshake is two round trips in both versions and both support session resumption. The difference comes from the cipher: AES-GCM with AES-NI hardware does encryption and authentication in one parallelisable pass, which is usually faster than AES-CBC plus HMAC. The big handshake saving (one round trip) only arrives with TLS 1.3.
  5. Mention configuration risk: even TLS 1.2 is weak with bad suites, so restrict it to ECDHE key exchange with AEAD ciphers and disable RSA key exchange and CBC suites where clients allow.

Follow-up

  • What does TLS 1.3 remove or change compared with 1.2?
  • How would you find which clients still negotiate TLS 1.1 before switching it off?
  • What is a protocol downgrade attack, and how does TLS_FALLBACK_SCSV defend against it?

What is the distinction between encryption and hashing?

Medium · Technical / Domain Questions

Approach

  1. Encryption is reversible with a key and protects confidentiality. Hashing maps any input to a fixed-length digest, uses no key, cannot be reversed, and is used for integrity checks and fingerprints. Encoding such as Base64 is neither.
  2. Name the properties a cryptographic hash needs: preimage resistance, second-preimage resistance and collision resistance. SHA-256 and SHA-3 are fine today; MD5 and SHA-1 have practical collision attacks.
  3. Passwords should never be encrypted or stored as plain SHA-256. Use a deliberately slow, salted password hash (Argon2id, scrypt, bcrypt or PBKDF2). The per-user salt defeats precomputed tables, and the work factor slows brute force.
  4. A bare hash proves integrity only if the digest itself is trusted. To prove who produced the data, add a key: an HMAC with a shared secret, or a digital signature with a private key.
  5. Give a deciding example: a card or account number that must be shown again later needs encryption or tokenization. Hashing it is weak anyway, because the input space is small enough to brute-force.

Follow-up

  • Why is salted SHA-256 still a poor choice for password storage?
  • What is a length-extension attack, and why is HMAC used instead of hash(key || message)?
  • How would you support exact-match lookups on an encrypted column?

Discuss the CIA triad and explain the difference between authentication and authorization.

Medium · Technical / Domain Questions

Approach

  1. Define each leg with a control. Confidentiality means only authorised parties can read data (TLS in transit, encryption at rest, access control). Integrity means changes are prevented or detected (MACs, signatures, database constraints, append-only audit logs). Availability means the service works when needed (redundancy, failover, backups, rate limiting).
  2. Apply all three to one example, such as a funds-transfer API: TLS and per-account access checks for confidentiality; idempotency keys, signed requests and an audit trail so a transfer is never applied twice or silently altered; replicas, health checks and rate limits for availability.
  3. Authentication establishes who the caller is (password plus MFA, OIDC login, client certificates); a failure maps to HTTP 401. Authorization decides what that identity may do (RBAC, ABAC, OAuth 2.0 scopes); a failure maps to HTTP 403. Authentication always comes first.
  4. Point out common confusions: OAuth 2.0 is a delegated-authorization framework and OpenID Connect adds the authentication layer, while an insecure direct object reference is an authorization bug where a logged-in user reads another user's record.
  5. Name a tension between the legs. An aggressive account lockout protects confidentiality, but it lets an attacker lock real users out, which hurts availability.

Follow-up

  • How would you enforce object-level authorization so that one customer cannot read another customer's account by changing an id?
  • When a user's role is revoked, what happens to the JWTs that are already issued?
  • Which leg of the triad does a ransomware attack hit, and which controls address it?

Given a specific software issue, outline your problem-solving process.

Medium · Problem-Solving / Case Studies

Approach

  1. Pin down the symptom before touching code: expected versus actual behaviour, who is affected, when it started, how often it happens, and what changed around then (deploy, config, dependency version, data volume).
  2. Reproduce it, ideally as a minimal failing case or test. Gather evidence in a fixed order: error logs with a correlation id, then metrics around the start time, then traces for one failing request.
  3. Narrow the cause one variable at a time: git bisect between a good and a bad commit, toggle the feature flag, swap one component, or compare a failing input with a passing one. Write down each hypothesis and the result that ruled it in or out.
  4. Fix the root cause rather than the symptom, add a regression test that failed before the fix, and confirm the fix against the same metric that showed the problem.
  5. Close the loop: a short write-up of cause, fix and the alert or test that would have caught it earlier. Use a concrete story, for example intermittent 500s traced to connection-pool exhaustion under a retry storm.

Follow-up

  • What do you do when you cannot reproduce the issue outside production?
  • How do you decide between shipping a workaround now and continuing to look for the root cause?
  • How did you tell that the change you found caused the issue rather than coinciding with it?

How would you approach redesigning a legacy system to improve efficiency?

Medium · Problem-Solving / Case Studies

Approach

  1. Define efficiency in numbers before designing anything: p95 latency, batch runtime, infrastructure cost, or deploy lead time. Then profile to find where the time or cost actually goes, because a rewrite that misses the hotspot gains nothing.
  2. Lock in current behaviour with characterization (golden-master) tests on real inputs, so every later change can be checked against what the legacy system really does, including its odd edge cases.
  3. Prefer incremental replacement over a big-bang rewrite: put a facade or router in front (strangler fig pattern), move one capability at a time, and send shadow traffic to compare old and new outputs before cutting over.
  4. Plan the data move explicitly: change data capture or dual writes, a backfill, reconciliation counts and checksums, then the cutover. Keep a feature flag and a rollback path for every step.
  5. State the trade-offs: incremental migration runs two systems for a while and adds sync complexity, but each step is reversible, while a rewrite stops feature work and carries the most risk.

Follow-up

  • How would you handle a database that both the old and the new system need to write to during the migration?
  • How would you justify the work to stakeholders who see the legacy system as working?
  • How do you know the migration is finished and the old system can be switched off?

If a critical bug was found in production, what steps would you take to resolve it?

Medium · Problem-Solving / Case Studies

Approach

  1. Assess severity and blast radius first: which users and transactions are affected and whether data is being corrupted or only requests are failing. Open an incident, name an owner, and start regular status updates to stakeholders.
  2. Mitigate before diagnosing: roll back the last deploy, turn off the feature flag, fail over or shed load. Restoring service comes before understanding the bug.
  3. Diagnose with evidence: line up the error start time against the change timeline (deploys, config, migrations, upstream incidents), then use logs, metrics and traces to confirm the cause.
  4. Ship the fix through the normal pipeline with a regression test, expedited but still reviewed, and verify it in production metrics. Repair any bad data (for example duplicated postings) with an audited, reversible script.
  5. Run a blameless postmortem with a timeline, root cause and owned action items, such as the missing alert, test or deploy guard.

Follow-up

  • The bad release included a schema migration, so a plain rollback is unsafe. What do you do?
  • How do you find and repair records the bug already wrote incorrectly?
  • What do you tell affected customers while the fix is still in progress?

One log partition stops advancing while the others drain

Easy · poison message · head-of-line blocking · consumer lag

Search results for a subset of tenants are hours stale; the rest are current. The projection consumer reports lag of zero on 15 of 16 partitions and 400,000 on one. Its error rate is flat and its CPU is idle. outbox_event has no pending rows older than a second, so the relay has published everything it holds. Identify the mechanism, give the ordered checks, and state what you do in the first ten minutes versus what you change permanently.

Approach

  1. Read the lag distribution first. A slow consumer lags everywhere; zero on fifteen partitions and 400,000 on one is not throughput. Idle CPU on the stuck partition means the consumer is not advancing its offset at all, which points at one message it cannot get past rather than at a rate problem.
  2. Exonerate the producer before touching the consumer. No pending outbox rows older than a second means the relay published, so the event exists in the log. This separates never sent from sent and never applied, which are different code paths and usually different owners.
  3. Read the message at the stuck offset and the handler's log lines for its event_id. A flat error rate with no progress has two explanations and you must distinguish them: the handler is throwing and the retry loop is swallowing it, or the handler is blocking on something and never returning. Idle CPU with no error lines favours the second.
  4. Mitigate before diagnosing further. Move the offending event to a dead-letter store and commit the offset past it. Adding consumers does nothing here, because a partition is consumed by exactly one member of the group, and the blast radius is every aggregate hashed to that partition, not only the aggregate that produced the bad event.

Follow-up

  • The dead-lettered event carried aggregate_version 7 and the projection had applied 6. What must the replay do differently if 8 and 9 landed in the meantime?
  • How do you show staleness to the user while the partition is behind, given the API already returns the projection's watermark?

Suggested practice checklist

The plan follows the reported question types: security fundamentals first, then coding, case studies, the stack, and behavioral stories, ending with a mixed run-through.

Day 1 — Encryption fundamentals: symmetric, asymmetric, hashing

  • Write a one-page table covering symmetric ciphers (for example AES), asymmetric algorithms (RSA, elliptic-curve), general hashes (SHA-256) and password hashes (bcrypt, Argon2, PBKDF2): key or no key, reversible or not, one application each.
  • Answer the symmetric versus asymmetric question aloud, with an example for each, then explain hybrid use: asymmetric to agree or wrap a key, symmetric for the bulk data.
  • Answer the encryption versus hashing question aloud, including why passwords are hashed rather than encrypted and where signatures fit.

Deliverable: The one-page table plus two recorded spoken answers (symmetric versus asymmetric, encryption versus hashing).

Day 2 — TLS handshake and certificate validation

  • Draw the TLS 1.2 handshake (ClientHello, ServerHello, certificate, key exchange, Finished) and mark where the certificate is checked and where the symmetric session key comes into use.
  • Write the certificate validation checklist: signature chain to a trusted root, validity dates, hostname match, key usage, revocation through CRL or OCSP.
  • From a reference such as the TLS 1.2 specification, write the differences between TLS 1.1 and 1.2 (cipher suites, hash and signature algorithms, authenticated encryption modes) and note that both older versions are now deprecated and that TLS 1.3 exists. Look up how session resumption affects handshake cost for the performance half of the question.

Deliverable: A handshake diagram, a validation checklist and a spoken TLS 1.1 versus 1.2 comparison that cites its reference.

Day 3 — CIA triad, authentication and authorization

  • Map each CIA property to concrete controls: encryption for confidentiality, hashes, signatures and checksums for integrity, redundancy and failover for availability, and give one example of each failing.
  • Write the difference between authentication and authorization with web examples: logging in versus checking permission on a resource, a 401 versus a 403 response, and where each check lives in an API.
  • Practise a spoken answer that joins the day's material to the earlier days, for example how a login over TLS touches all of confidentiality, integrity, authentication and authorization.

Deliverable: A CIA-to-controls table, an authn versus authz example sheet and one recorded answer to the CIA question.

Day 4 — Coding: linked list, two-sum and narrating a challenge

  • Write the linked-list reversal iteratively in Java, Python or C# with no autocomplete, then write the recursive version and state its stack cost.
  • Write two-sum with a hash map in one pass, state the brute-force O(n^2) alternative, and decide what to return when no pair exists or values repeat.
  • Solve one more problem on a HackerRank-style editor while saying your reasoning aloud: restate, brute force, data structure, complexity, tests.

Deliverable: Three working solutions in one language, each with a one-line complexity statement and a list of edge cases you tested.

Day 5 — Case studies: problem solving, legacy redesign, production bugs

  • Write a reusable sequence for a software issue: reproduce, narrow the cause, form a hypothesis, test it, fix, add a regression test, and say what you would check first and why.
  • Write an incident sequence for a bug found in production: assess customer impact, mitigate or roll back, communicate, fix the cause, then review.
  • Outline a legacy-redesign answer: measure where the inefficiency is, pick a small seam to replace first, keep behaviour pinned with tests, migrate in steps with a rollback, and define the metric that shows the improvement.

Deliverable: Three written step sequences (issue, production bug, legacy redesign), each rehearsed aloud once.

Day 6 — Behavioral story bank

  • Write one story each for the challenging project, deadline prioritisation, conflict, feedback and learning a technology quickly prompts, with the decision you made, your own actions, the result and what you would change.
  • Write a short, honest answer for what motivates you, with two supporting episodes.
  • Say each story aloud and cut anything that is background rather than decision.

Deliverable: Six written story outlines, one per reported behavioral prompt, each marking your personal decision and a verifiable result.

Day 7 — Stack check and mixed run-through

  • Add a short note on when you would pick NoSQL over a relational store.
  • Run a mixed mock: explain the CIA triad and authentication versus authorization, solve two-sum aloud, give your production-bug sequence, and tell the conflict story.
  • Write three questions to ask the team, and list the one topic you still feel weakest on for a final review.

Deliverable: Completed SQL practice, a recorded mixed mock covering four question types, and a list of three questions plus the weakest topic.

Behavioral stories for the Citizens discussions

Candidates report these prompts as a set, and also report that the second round is discussions with team members and stakeholders about technical capability and cultural fit. For this role, stories about working with product managers, QA and other engineers on shipped software, reviewing code, and fixing production issues fit the work candidates describe. Build each answer around a decision you personally made and a result you can verify.

Describe a challenging project you have worked on. What was your role, and how did you contribute to its succe

Medium · Behavioral / Leadership

Describe a challenging project you have worked on. What was your role, and how did you contribute to its success?

Approach

  1. Pick a project from your own work where you owned a defined piece, such as a service, a migration or a release, and can name the decisions you made. Open with the scope, the constraint and your role in two sentences, then spend the answer on decisions.
  2. Say what made it hard, technical (a legacy integration, a data migration, a performance problem) or organisational (changing requirements, a dependency on another team), and the options you weighed before choosing one.
  3. Separate I from the team: what you designed, wrote, reviewed or unblocked yourself. The common failure is a tour of the architecture in which nothing is attributable to you.
  4. Close with a result you can verify (defects found before release, a deadline met, an incident avoided) using only figures you actually know, and say what you would change if you ran it again. Mention testing and code review where they were part of how you reduced risk.

Follow-up

  • What was the hardest trade-off in the project, and who disagreed with your choice?
  • How did you test or review the change before it reached production?
  • What would you do differently if you ran the project again?

How do you prioritize tasks when faced with tight deadlines?

Medium · Behavioral / Leadership

Approach

  1. Name your method first, then prove it with one real case. A workable method: list everything due, separate what must ship from what can slip by customer or business impact and risk, order by dependencies, then agree the cut line with whoever owns the priorities.
  2. Tell one concrete story: the deadline, the items you cut or deferred, and who you told. Negotiating scope with a product manager is a stronger answer than simply working longer.
  3. Show what you protect. Cut features or polish before cutting tests and review on paths that touch customer data or account actions, and say why.
  4. Show early communication: you raised the risk when you saw it and offered options (reduce scope, move the date, add help) rather than announcing a miss on the last day. Finish with how deferred items were tracked afterwards.

Follow-up

  • Two stakeholders each say their item is the top priority. How do you decide?
  • Tell me about a time a deadline slipped anyway. What did you do?
  • Which checks would you never skip under time pressure, and why?

Tell me about a time you had a conflict with a team member. How did you resolve it?

Medium · Behavioral / Leadership

Approach

  1. Choose a disagreement about substance, such as a technical approach, review feedback or ownership of a task, with real stakes, and avoid a story that is about personality. State the other person's position fairly, in words they would accept.
  2. Walk through your steps in order: you spoke to them directly and privately first, clarified the shared goal, then brought evidence (a benchmark, a small prototype, the spec or a design note) rather than opinion.
  3. Say how it was resolved: a compromise, their approach winning, or yours, and involve a lead or tiebreaker only if direct discussion failed. Name the outcome for the project and for the working relationship afterwards.
  4. The sinking mistakes are casting the other person as the villain, claiming you have never had a conflict, or telling a story where a manager decided and you simply complied.

Follow-up

  • What if you had later found that the other person was right?
  • What did you change about how you handle disagreement after that?
  • How would this differ if the conflict was with a product manager or QA colleague rather than another engineer?

What motivates you to perform your best work?

Medium · Behavioral / Leadership

Approach

  1. Name two or three motivators you can back with episodes, for example hard debugging, shipping something users depend on, learning from stronger peers or owning a system end to end. Each claim needs a concrete moment when you were at your best.
  2. Connect them to the work candidates describe for the role: building and maintaining banking applications, code reviews, testing, production troubleshooting and cross-team collaboration. Link motivators to those activities without asserting what the employer values.
  3. Describe the environment that brings out your best (clear ownership, quick feedback, a review culture) in terms of behaviours, not slogans.
  4. Avoid answers that are only about pay, only about passion without an example, or so generic that they fit any company. Briefly say what drains your motivation and how you manage it.

Follow-up

  • Tell me about a time you were not motivated by a task. What did you do?
  • What kind of team environment do you do your best work in?
  • What would make you want to leave a role?

How do you handle feedback and criticism of your work?

Medium · Behavioral / Leadership

Approach

  1. Pick specific, substantive feedback that was uncomfortable to hear, such as pushback in a code review, a performance review point or a lesson from an incident. A disguised strength ("I care too much") will not hold up.
  2. Show your process: you listened, asked for a concrete example, restated it to confirm you understood, decided what to change, and then made a visible change such as smaller pull requests, a test checklist or earlier design reviews.
  3. Close the loop: you went back to the person to check the change worked, and you can point to a result such as fewer review rounds or fewer escaped bugs.
  4. Include or be ready for a case where you disagreed with feedback: you tested it against evidence and either adopted it or explained your reasoning politely. The sinking mistakes are sounding defensive or saying you take feedback well with no example.

Follow-up

  • Tell me about feedback you disagreed with. What did you do?
  • How do you give feedback to a colleague in a code review?
  • What feedback are you working on right now?

Discuss a time when you had to learn a new technology quickly. How did you approach it?

Medium · Problem-Solving / Case Studies

Approach

  1. Choose a case where a deadline forced the learning, name the technology and say where you started (for example, a framework similar to one you knew, or a language you had never used). This makes the scale of the jump clear.
  2. Describe a method, not just effort: scope what the task actually needs, read the official documentation and existing code, build a small throwaway spike, pair with someone experienced, and ask targeted questions only after you have tried something.
  3. Show how you checked your understanding: you wrote tests, had an experienced colleague review the result, and handled failure cases, which matters more in code that touches customer data or accounts.
  4. Finish with what shipped and what you left behind, such as notes or a short runbook. A story that ends at 'I watched tutorials' with no delivered artifact is the usual weak answer. If you can, pick an example close to the listed stack (Java, Python, C#, AWS, Azure, React or Angular).

Follow-up

  • How did you decide how deep to go in the time you had?
  • What mistake did you make while learning it, and how did you catch it?
  • How would you ramp up on a codebase written in a language you have never used?