The 60-second brief
Wells Fargo is a bank. Its Software Engineers build and maintain the systems behind consumer banking, corporate liquidity and wealth management: backend microservices, payment platforms, data pipelines and web front-ends. Reported work includes moving legacy platforms onto Azure and implementing payment standards such as ISO20022. The reported interview questions follow that stack. They cover Java and Spring Boot internals, SQL and ACID transactions, payment-system consistency, rate limiting for banking APIs, and data security during migrations and in pipelines.
Wells Fargo candidates report 6 rounds · ≈ 4-6 weeks. The stages below are what candidates describe, not a published process.
What a Software Engineer does at Wells Fargo
The must-have skills listed for the role are Java with Spring Boot or a full-stack JavaScript/TypeScript setup (Angular or React), relational databases (SQL, Oracle, PostgreSQL) and Git. The nice-to-haves are Azure, Docker, Kubernetes, message brokers such as Kafka and ActiveMQ, and CI/CD tooling. This explains why the reported questions go into Java garbage collection and JVM memory areas, the equals/hashCode contract behind a HashMap, the Spring Boot lifecycle and dependency injection, ACID and normalization, and asynchronous service communication through Kafka.
Candidates describe the live interviews as weighted more toward conceptual technical discussion and project walkthroughs than toward competitive-programming puzzles. They also say interviewers often give hints when a candidate gets stuck. Prepare to explain how something works and why you chose it, not only to produce an answer. Some candidates also report being interviewed by engineers outside their own stack, so your fundamentals should hold up without the vocabulary of your usual framework.
Separately, some candidates report a cohort-based hiring process for certain roles, especially campus and contract positions, with group presentations and breakout rooms before individual interviews on the same day. Candidates do not tie this to a particular stage of the six, so ask your recruiter whether your role uses it.
The Wells Fargo interview process
Wells Fargo candidates report 6 rounds · ≈ 4-6 weeks. The stages below are what candidates describe, not a published process.
Online Application
Candidates describe this stage simply as submitting the application. Treat the resume as material for every later round, because candidates report that interviewers question past projects in depth: the architecture, the technologies, the challenges and the business impact. List the must-have skills you actually have (Java/Spring Boot or a JavaScript/TypeScript framework, a relational database, Git), and name any nice-to-haves you have used for real: Azure, Docker, Kubernetes, Kafka, ActiveMQ, CI/CD. Some locations reportedly give weight to academic record, so keep your transcript details accurate and ready.
What it evaluates
- Whether the resume shows the must-have stack for the role: Java with Spring Boot or a modern JavaScript/TypeScript framework, a relational database, and Git
- Whether every listed project is one you can explain in terms of architecture, technology choices, the hardest problem and the outcome, since later rounds reportedly probe projects in depth
- Whether nice-to-have tools such as Azure, Kafka or Kubernetes appear only where you used them, rather than as keywords you cannot discuss
How to prepare
- Map each resume bullet to a skill from the role's must-have or nice-to-have list, and cut any bullet you could not defend through two follow-up questions
- For each project on the resume, write three lines: the architecture in one sentence, the hardest technical problem, and a measurable result
- If you mention cloud migration, messaging or CI/CD, write down the specific service, broker or pipeline you worked with, because those topics come up in reported design and fundamentals questions
Automated Assessment
Candidates report that the automated assessment runs on HackerRank. Candidates report that some teams read assessment submissions manually in later rounds to judge coding style and attention to detail. So passing the tests is only part of the job: the code should also read cleanly and handle edge cases. The reported coding questions include counting palindromic subsequences, implementing an LRU cache, counting inversions with merge sort, building a queue from two stacks, and explaining HashMap collision handling. These questions are not tied to the assessment itself, but they show which categories to drill before it.
What it evaluates
- Whether the submission passes hidden cases such as empty input, a single element, all-equal elements and the largest allowed values
- Whether the chosen approach fits the stated input bounds, for example O(n log n) inversion counting instead of the O(n^2) pair check on large arrays
- Whether the code is readable enough to hold up if a later interviewer opens it: clear names, short comments at the non-obvious steps, no dead code
How to prepare
- Practise in HackerRank's editor with the language you will use, including reading input from stdin and printing exact output formats
- Drill the reported coding categories: an LRU cache with a hash map and a doubly linked list (O(1) get/put), inversion counting during merge sort (O(n log n)), a two-stack queue (amortised O(1)), and interval DP for counting palindromic subsequences (O(n^2))
- Before each submission, reread the loop bounds and base cases, then add a one-line comment above every step a reviewer would have to reverse-engineer
Recruiter Screening Call
Candidates describe the recruiter screen as a call to align on role expectations, location preferences and basic qualifications. Use it to learn two things that shape the rest of your preparation. The first is which stack the team works in (Java/Spring Boot backend, Angular or React front-end, or data pipelines). The second is what the later rounds cover. Candidate reports describe a hybrid work arrangement, so settle location and in-office expectations on this call rather than at offer time.
What it evaluates
- Whether your location and work-arrangement expectations match the role's
- Whether your stack, degree and experience line up with the basic qualifications in the posting
- Whether you can summarise your most relevant project clearly and briefly to a non-engineer
How to prepare
- Prepare a short walkthrough of one project that names the stack, your specific role and one measurable result, in terms a non-engineer can follow
- Have your answer on location and hybrid schedule ready, and ask which office and in-office pattern the team uses
- Ask which technologies the team uses and what the next rounds cover, then weight the plan below toward that answer
Core Interview Phases
Candidates describe this stage as technical and behavioral interviews that often lead into a Superday. Candidates do not tie specific questions to this stage, but the reported questions by category show what the technical conversations can draw on. Reported core Java and OOP questions include the four OOP principles applied to a real project, threads versus asynchronous code and race conditions, garbage collection and JVM memory areas, the Spring Boot lifecycle and dependency injection, and REST versus SOAP. Reported database questions include complex joins and window functions over transaction history, ACID, normalization trade-offs, ETL data quality and encryption at rest. Candidates also report being questioned in depth on past projects, and SQL and database concepts are reported as tested across almost all technical rounds.
What it evaluates
- Whether you explain mechanics as well as definitions, for example how a HashMap chains colliding keys and why equals and hashCode must agree for a custom key
- Whether your SQL is correct and explainable: join types, where a window function is evaluated relative to WHERE, and which index would serve the query
- Whether your account of a past project holds up when pushed a level deeper, on the decision you made and the alternative you rejected
- Whether you use a hint to move forward, since candidates report that interviewers often give one
How to prepare
- For each core Java topic (GC and memory areas, HashMap internals, thread safety, Spring dependency injection), write a short explanation that includes one example of it going wrong, such as a mutable HashMap key or a check-then-act race
- Write one transaction-history query that uses a join, a subquery and a window function, then explain the order in which it is evaluated
- Rehearse your main project to two levels of follow-up: what you built, and why you chose it over the obvious alternative
- Practise saying out loud what you are stuck on, so that a hint can land on the specific gap
Superday Interviews
Candidates describe the Superday as back-to-back technical and behavioral panels with several team members. Because the panels run back to back, the main risks are consistency and stamina: the same project facts told to several interviewers in a row, and technical answers that still go past the happy path late in the day. Reported design questions, not tied to a specific round, include real-time transaction processing, a rate limiter for public banking APIs, asynchronous microservice communication through Kafka or Redis, data consistency across databases in a payment system, and migrating an on-premises application to Azure. Reported behavioral questions, also not tied to a specific round, include resolving a technical conflict, working to a tight deadline with unclear requirements, and taking code-review feedback.
What it evaluates
- Whether technical answers go past the happy path, for example duplicate requests and partial failure across services in a payment flow
- Whether your stories stay consistent across several panels on the same day: team size, timeline and your own role
- Whether behavioral answers have a clear situation, your own actions and a result, told as a conversation rather than recited
How to prepare
- Rehearse one payment design end to end: idempotency keys on the write API, an outbox or saga instead of a distributed transaction, and reconciliation for the cases that still slip through
- Design a rate limiter for a public API: token bucket versus sliding window, where the counters live, the key (client, account or IP), and what the caller receives when limited
- Fix the facts of each story on one page before the day, and check every retelling against that page
- Run a mock block of back-to-back sessions so you know how your answers hold up in the third hour, not only the first
Final Offer Phase
Candidates describe the final stage as waiting for the offer, and they report administrative delays here, including HR and compensation approvals that can stretch the overall timeline. Candidate reports describe negotiation as possible but structured, with compensation set by role level and location. So confirm the level and location before you discuss numbers. Use the wait to keep practising rather than pausing, in case the process adds another conversation.
What it evaluates
- Whether level, location and hybrid schedule are confirmed before you compare or negotiate numbers
- Whether your follow-ups are polite and spaced out, rather than read as pressure during a delay candidates report as common
- Whether any competing offers or market data you cite are specific and verifiable
How to prepare
- Ask the recruiter which level the offer is at and which location it assumes, and write both down
- Prepare the data you would negotiate with, such as a competing offer or a level-matched market figure, and know which part of the package you care about most
- Set a follow-up cadence with the recruiter, and keep your coding and SQL practice going until the offer is signed
Questions Wells Fargo candidates report
These are the prompts PracHub has collected for this role and company. They are a record of what candidates describe being asked, so treat them as the shape of the conversation rather than a script Wells Fargo works from.
Data structures and algorithms
Ask which resource the problem actually takes away, because it is not always time. If the input does not fit in memory, the set you were going to build is gone and the bound that matters is space. If the data arrives once and cannot be revisited, anything needing a second pass is out whatever its complexity, and a constraint banning modification of the input removes the in-place trick that would otherwise be free. Naming the scarce resource first cuts the candidates down to a handful, and it stops you optimising a dimension the problem was never short of.
- Explain the difference between a stack and a queue, and implement a queue using two stacks.
- Write a function to count all the palindromic subsequences in a given string.
- Design and implement a Least Recently Used (LRU) Cache.
- How does a hashmap handle collisions internally, and what is the significance of the equals and hashCode methods in a custom class key?
System design and architecture
The design is the data model and the interface; the boxes follow from them. Write the entities, the key each row is stored under, and then, for every read the product needs, the path from a key to the rows returned. Do the same for each write, including whatever else must change in the same operation. Most designs fail here rather than at scale, when a read the feature depends on turns out to need a scan or a fan-out across every partition. The strongest answers state the queries first and let the storage choice fall out of them.
- Walk through the high-level architecture of a distributed system that requires real-time transaction processing.
- How would you design a rate limiter to protect public-facing banking APIs?
Behavioural and engineering judgement
Most engineering disagreements worth asking about are not settled by evidence, because both positions are defensible on what is known at the time: a schema shape, an abstraction one of you thinks is premature, fixing versus rewriting. The useful move is to say what would settle it, and what you do when nothing will. A common tiebreaker is which option is cheaper to undo, so you take the reversible one and set a date to look again. Weak answers argue who turned out to be right. Strong ones explain how the call got made while it was still undecidable.
- Describe a challenging project you worked on. What was your role, and how did you measure success?
- How do you handle constructive feedback from a peer or a manager during a code review?
Other topics
Most prompts in this group are underspecified, and the honest answer is conditional. Find the variable that flips the decision, such as read-heavy against write-heavy or data that fits in memory against data that does not, name it, then answer for the case you picked. A weak answer states a preference as though it held everywhere. A strong one gives the rule and the point where the rule changes. Say the assumption out loud and commit to it: an assumption can be corrected by the person asking, while an answer hedged in every direction at once gives them nothing to correct.
- What is the difference between multi-threading and asynchronous programming, and how do you prevent race conditions?
Practice exercises with worked solutions
The prompts above tell you what gets asked. These are PracHub exercises written to drill the same skills, with the reasoning spelled out so you can check your own answer instead of guessing whether it was good enough.
Explain why the owner filter ignores the listing index
The only index on resource is (tenant_id, status, updated_at DESC, resource_id DESC). A new endpoint returns one user's resources across all statuses, newest created first: WHERE tenant_id = $1 AND owner_user_id = $2 ORDER BY created_at DESC LIMIT 20. On a tenant with 2M rows it takes 900 ms and EXPLAIN shows a sort above a large scan. Explain precisely why the existing index cannot serve it, give the index that can, and state which of these the new index still will not help: owner_user_id alone across tenants; the same query ordered by updated_at. PostgreSQL 16.
How a strong candidate works it
- Separate the two jobs an index does. For filtering, a composite btree is seekable only on a left prefix, so with no predicate on status the scan can at best range over tenant_id and test owner_user_id per row; PostgreSQL 16 has no btree skip scan to jump the unconstrained column.
- For ordering, the index is sorted by (status, updated_at) within a tenant and not by created_at, so the LIMIT cannot stop early: every matching row is read and then sorted. That is the 'Sort Method: top-N heapsort' line, and it is why the plan reads 2M rows to answer with 20.
- Derive the replacement from the access path — equality, equality, then the ordering column: CREATE INDEX CONCURRENTLY ON resource (tenant_id, owner_user_id, created_at DESC). The scan seeks to the (tenant, owner) range and walks 20 entries in order, so the Sort node disappears along with the row-read.
- Treat INCLUDE (title, status) as conditional, not free. An index-only scan still visits the heap for any row whose page is not marked all-visible, so on a table taking 1.2k writes/second the win depends on autovacuum keeping the visibility map current, and the wider index costs more on every insert.
- Answer the two negatives explicitly. owner_user_id alone is not a left prefix of the new index, so it degrades to a full scan of the index at best. Ordered by updated_at, the query still seeks on the (tenant, owner) pair but must sort, because only created_at is ordered within that pair.
- Measure both sides with EXPLAIN (ANALYZE, BUFFERS) and compare estimated against actual rows at the lowest node — a 2M-versus-200 misestimate there is usually what chose the plan, and adding an index will not fix a statistics problem.
Expected result (25 min): With (tenant_id, owner_user_id, created_at DESC) the plan is an Index Scan with no Sort, roughly 20 rows and a handful of buffers, sub-millisecond. owner_user_id alone still scans; ORDER BY updated_at seeks on the pair and then sorts that owner's rows.
Check yourself
- Actual rows at the leaf node is on the order of the LIMIT, not the tenant's row count.
- No Sort node appears above the index scan.
- Buffers read stays constant as one owner's row count grows; if it grows with it, the ORDER BY is not being satisfied by the index.
- pg_stat_user_indexes shows idx_scan climbing on the new index and not on the listing index for this endpoint.
Follow-ups
- 90% of rows are status='active'. Would a partial index WHERE status = 'active' change your answer, and for which of the three queries?
- A dashboard runs this for 40 owners in one page load. What changes about the design?
- How do you roll this index out on a table taking 1.2k writes/second, and what does it cost on every insert from then on?
Find version gaps and relay lag with window functions
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.
How a strong candidate works it
- 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.
- 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.
- 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.
- 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.
- Interpret rather than report: no gaps plus a normal p95 of published_at - created_at points at the consumer; gaps or a fat lag tail point at the relay; rows still 'pending' with attempts > 0 point at neither, because they never left the database.
- Be explicit that the partial index on (created_at, event_id) WHERE status = 'pending' does not serve any of these — they read published rows. Name the index a recurring monitor would need, and say why a query run twice a year may not deserve one.
Follow-ups
- 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?
- The consumer claims it never received event 4,812,006. What do you look at, in what order?
Merge partitioned event streams into one ordered feed with bounded lateness
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.
How a strong candidate works it
- 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.
- 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.
- 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.
- 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.
- Choose the late-event policy from what the projection is keyed on. The projection upserts on (aggregate_id, aggregate_version) and discards a version it has already applied, so a late event is safe to apply out of order and correctness never depended on the merge at all. Apply it, recompute the affected feed page, and count lateness so the 30-second budget can be re-derived from data rather than folklore.
- Say what the merge does not buy: ordering is guaranteed within one aggregate by the log's partitioning, and no watermark makes the cross-aggregate order authoritative. Two events from different aggregates in the same millisecond have no true order, so the feed's order is a presentation choice that must be stable rather than correct.
Expected result (35 min): A 64-way min-heap merge at O(n log P) with a deterministic (occurred_at, event_id) comparator, a watermark of the per-partition minimum less 30 seconds gating emission, a stated buffer of 120,000 events and roughly 120 MB, idle markers so a silent partition cannot freeze the watermark, and a late-event policy justified by the projection's idempotency on (aggregate_id, aggregate_version).
Check yourself
- Feeding the partitions in an adversarial interleaving produces the same output sequence as feeding them in timestamp order.
- Silencing one partition stalls output without the idle marker and does not stall it with the marker.
- Applying a late event twice leaves the projection byte-identical, which is what permits the out-of-order path to exist.
Follow-ups
- 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?
- One partition is ten minutes behind because its producer is slow. Do you stall the feed or emit without it?
Choose what to break when replication lag reaches forty seconds
Reads are served from two replicas: 14k requests/second, about 85% absorbed by cache, so roughly 2.1k reads/second reach the database. Writes go to the primary at 1.2k/second. A tenant's backfill drives replication lag from under 100 ms to 40 seconds and it is still climbing. Sessions that have just written are pinned to the primary. Decide, endpoint class by endpoint class, whether to serve stale, fail, or route to the primary, and justify each choice with the load it adds to the primary. Then state what you would have built beforehand.
How a strong candidate works it
- Establish blast radius before cause, because mitigation and diagnosis have different deadlines. The decisive arithmetic is what happens if the database reads move to the primary: 2.1k reads/second on top of 1.2k writes/second roughly triples its operation count, on the node already absorbing the backfill that caused this. Reads and writes are not equal in cost, so treat that as an argument against a blanket move rather than as a capacity model - but it is enough to rule out routing everything to the primary.
- Classify endpoints by what staleness costs, not by how important they feel. Reads whose staleness is invisible - listings, search, counters - stay on the replica and return the watermark so the client can tell. Reads that immediately follow that same session's write keep their primary pin, which is a small bounded slice of traffic rather than the whole 2.1k/second. Reads that feed a decision with a side effect - authorisation, quota, the read half of a read-modify-write - must not be stale at all, because a 40-second-old permission row is the stale-permission failure wearing a different costume; those go to the primary or fail.
- Shed instead of queueing. If the must-be-fresh class alone exceeds the primary's headroom, refuse its lowest-value slice with 503 and a retry-after. A request queued behind a saturated primary holds a connection for a client that has already given up, and the retry storm that follows is what turns degradation into an outage. Bound the connection pool per role so the read fallback cannot consume the write path's connections - that bulkhead is the single decision that determines whether writes survive the next ten minutes.
- Attack the cause in parallel, since it is the one thing that can be stopped. The backfill is the load generator. A backfill that reads replication lag as its throttle signal and pauses above a threshold would have made this a non-event, with batch sizes small enough that each batch's write volume is a fraction of what a replica can apply per second. That is most of the answer to what should have existed beforehand.
- Name the mechanism you would prefer over session pinning. Capture the write position at commit and require the read path to be at or past it: compare the primary's pg_current_wal_lsn() at commit time against the replica's pg_last_wal_replay_lsn(), and fall back to the primary only for the specific request that is ahead of the replica. Session pinning is the cheap approximation and it over-pins - every read in the window goes to the primary whether or not it needed to, which is a share of the cost being paid right now.
Expected result (35 min): Staleness-invisible reads stay on the replica and return a watermark. Reads following the session's own write keep a bounded primary pin. Reads that gate a side effect go to the primary or fail, with the lowest-value slice shed as 503 plus retry-after if headroom runs out. Connection pools are bounded per role so the read fallback cannot starve writes. The backfill is throttled on measured replication lag. The durable fix is a commit-position token compared against the replica's replay position, replacing blanket session pinning.
Check yourself
- The traffic routed to the primary under the plan is stated as a rate, not as a category.
- No element of the plan increases the write path's connection usage.
- The backfill throttle references a measured lag value and has an explicit resume condition.
- Every endpoint left on a replica returns something with which a client can detect staleness.
Follow-ups
- Lag returns to normal in nine minutes. Which mitigation do you remove first, and which one stays permanently?
- A user reports their change did not save, and the write committed. Trace the path that produces that report and name the signal that would have shown it before the report arrived.
- The replica is 40 seconds behind but otherwise healthy. Do you take it out of rotation? What does that do to the other replica's lag?
Read latency spikes on a sixty-second sawtooth
The cached listing read path serves about 14k reads/second at an 85% hit rate. p99 sits at 35 ms for 57 seconds, jumps to 900 ms for 3, and repeats. During each spike the primary shows several hundred identical listing queries starting within the same millisecond, all carrying one large tenant's id. Cache entries use a 60-second TTL. Give the mechanism, the ordered checks, the fix, and the correctness hazard your fix must not introduce.
How a strong candidate works it
- Match the period to a configured number before theorising about load. A spike every 60 seconds against a 60-second TTL is an entry expiring, and you confirm it by correlating spike timestamps with the entry's write time rather than with the traffic curve. If the period had matched a cron or a GC interval instead, this is a different investigation.
- Establish the concurrency of the miss. Several hundred identical queries in one millisecond means the miss path has no coalescing: every request that arrives between expiry and repopulation recomputes. The herd size is that key's arrival rate times its recompute time, so at 1.2k reads/second for the hot key and a 250 ms recompute you expect about 300 concurrent misses, which matches what is observed.
- Add single-flight on the miss path so one caller per key recomputes under a short-lived lock while the rest wait for its result. Prefer stale-while-revalidate where the read tolerates it: return the expired value immediately and refresh asynchronously, which removes the latency spike rather than serialising it into a queue of waiters.
- De-synchronise the keys. Write TTLs with jitter, for example 60 seconds plus or minus 10%, so a deploy or a mass invalidation does not align every key on the same second and turn a per-key herd into a fleet-wide one.
- Name the hazard the fix must not introduce. Serving a stale listing is acceptable only because the API reports the projection watermark, and a reader that loaded the old value before a write can repopulate the entry after the invalidation, so the bounded TTL is what actually caps staleness rather than the delete. Keep read-after-write pinned to the primary for the writing session regardless.
- Verify on miss concurrency, not hit rate. The hit rate barely moves, because the herd is one miss multiplied; the number that must change is distinct origin queries per key per minute.
Follow-ups
- The same sawtooth appears on a key that is invalidated on write rather than expired. Is that the same bug?
- How does your answer change if the recompute takes 4 seconds instead of 250 ms?
- What exactly does a client see during a stale-while-revalidate window, and how does the watermark let them tell?
Tell callers you do not own that their integration breaks
A field in a write endpoint's response must change shape. You own the endpoint; you do not own the four internal callers or the outbound webhook consumers who read it. Describe a deprecation you were responsible for: what you shipped first, how you established who was actually reading the field, the window you gave and what set its length, what you did about the consumer who never moved, and how you decided removal was safe. Name the signal you used, not the announcement you sent.
How a strong candidate works it
- Establish the reader set empirically rather than from a wiki of owners: per-field usage counters keyed by principal, or access logs attributed to a consumer. State the blind spot of whichever you pick, since a consumer that reads the field only on a monthly job will not appear in a week of logs.
- Ship additive first. Populate the new field alongside the old one so no reader is forced to move, which is also what keeps a rolling deploy safe, because old and new instances answer the same requests at the same time and a rollback must still find the old shape present.
- Set the window from the slowest legitimate consumer's release cadence, not from your calendar, and decide separately what to do for a consumer with no release process at all, such as an external webhook endpoint you can only email.
- Convert silence into evidence before you rely on it: a short, low-traffic removal window that makes a still-dependent consumer fail visibly and loudly while you are watching, rather than at three in the morning after you have moved on.
- State the removal criterion as a measurement with a duration attached, such as observed reads at zero across a full billing cycle, and keep the change reversible for one release after removal.
Follow-ups
- How would you detect a consumer that reads the field only during a monthly export?
- One caller refuses to move and has a commercial relationship behind it. What changes in your plan and what does not?
- After removal, what makes the change irreversible, and how long before you cross that line?
Where candidates lose points
Treating the HackerRank assessment as pass/fail and submitting code that passes the samples but misses edge cases or cannot be read
Candidates report that some teams read assessment submissions manually in later rounds. Before you submit, trace the empty input, a single element and duplicates, check the loop bounds, and add a one-line comment at each non-obvious step. If you run out of time, a correct and clearly commented slower solution is safer than a clever one that fails hidden cases.
Answering core Java and Spring questions with textbook definitions instead of mechanisms
Reported questions ask how things work: HashMap collision handling, garbage collection and JVM memory areas, the Spring Boot lifecycle, how dependency injection improves testability, and preventing race conditions. For each, be ready with the mechanism and one failure. For example, a key whose hashCode changes after insertion can no longer be found. Since Java 8, a crowded bucket becomes a tree once it passes a threshold. A check-then-act on shared state needs one atomic operation or a lock. Constructor injection lets a test pass in a fake.
Designing a payment or transaction system as boxes and arrows, with no plan for retries, partial failure or cross-database consistency
Reported design questions ask directly about data consistency across databases in a payment system and about real-time transaction processing. State the failure first. A client retries after a timeout, and one service commits while another does not. Then give the mechanism: an idempotency key on the payment API, an outbox or saga with compensating steps instead of a distributed transaction across services, and reconciliation for what still slips through. Say which step you would not retry automatically.
Preparing algorithms and neglecting SQL, then stumbling on a multi-join window-function query or an ACID question
SQL and database concepts are reported as tested across almost all technical rounds. Practise writing a transaction-history query with joins, a subquery and a window function by hand. Know that window functions are evaluated after WHERE and GROUP BY, so filtering on one needs a subquery. Be able to explain each ACID property with a concrete failure it prevents, and when denormalizing is worth the integrity cost.
Telling project and behavioral stories that sound recited, or that change between Superday panels
Superday panels run back to back, and candidates report being questioned in depth on past projects. Write down the facts that must not change between tellings: team size, timeline, your own role and the measured result. Prepare four or five STAR stories you can adapt, and tell them as a conversation. Stop to check whether the interviewer wants more depth on the technical side or the people side.
Algorithms first, for a candidate whose problem-solving has gone rusty
For someone who has spent the last few years shipping features and reading other people's code, and who has not solved a timed problem from a blank file in a long time. Five days rebuild the primitives and the patterns that sit on them, working from invariants rather than remembered solutions, and the last two attach that back to the rest of the loop.
Day 1 — Assessment-style coding: reported data-structure problems
- Implement an LRU cache with a hash map plus a doubly linked list, and test eviction order, updating an existing key, and capacity 1
- Implement a queue with two stacks and explain why each element moves at most once, which makes the operations amortised O(1)
- Count inversions in an array during merge sort in O(n log n), and check the result against a brute-force O(n^2) count on random inputs
Deliverable: Three working solutions with complexity notes, and a list of the edge cases each one was tested against.
Day 2 — DP and hashing, written as a HackerRank submission
- Count all palindromic subsequences of a string with interval DP in O(n^2), after asking whether identical subsequences at different positions count separately
- Write a short explanation of HashMap collision handling (bucket chaining, treeified buckets, resizing) and the equals/hashCode contract for a custom key, including what breaks if the key is mutated after insertion
- Solve two problems in HackerRank's editor, reading stdin and matching the exact output format, and comment each non-obvious step before submitting
Deliverable: A tested palindromic-subsequence solution, a HashMap explanation you could give out loud, and two submissions a reviewer could read cold.
Day 3 — Core Java, OOP and Spring Boot fundamentals
- Explain the four OOP principles, each tied to a class or module from a real project, and write a thread-safe singleton, stating why the approach you chose is safe
- Explain garbage collection (GC roots, reachability, generations) and the JVM memory areas, then contrast multithreading with asynchronous code and name one race condition and its fix
- Build a small Spring Boot service with POST, PUT and GET endpoints and constructor injection, and write one test that swaps in a fake dependency
- Practise the Java Streams and Kafka consumer/partition topics from the question bank
Deliverable: A working Spring Boot service with a test that uses a fake dependency, plus short explanations of GC, concurrency and the four OOP principles.
Day 4 — SQL and databases
- Write a transaction-history query with multiple joins, a subquery and a window function, then state where the window function is evaluated relative to WHERE and LIMIT
- Work through the worked SQL exercise on composite indexes and sort elimination, then do the window-function drill on version gaps and running totals
- Explain ACID with one concrete failure per property, and normalization versus denormalization with a case where each is the right call
- Describe an ETL pipeline with data-quality checks, and how you would protect sensitive customer data with encryption at rest and access controls
Deliverable: Two hand-written SQL queries with their evaluation order explained, and one-paragraph answers on ACID, normalization and pipeline governance.
Day 5 — System design for payments and banking APIs
- Design a payment system that stays consistent through failover: an idempotent write API, an outbox or saga across services, and reconciliation
- Design a rate limiter for public-facing banking APIs, choosing the algorithm, the counter store, the limiting key and the rejected-request response
- Explain asynchronous service communication through Kafka: partitions, consumer groups, at-least-once delivery and how the receiver deduplicates
- Work the worked design exercise on replication lag, then sketch cursor pagination for a large dataset
Deliverable: Two design sketches (payments, rate limiter), each listing the failure it handles and the trade-off it accepts.
Day 6 — Cloud migration, security and production debugging
- Outline a phased migration of an on-premises application to Azure: run old and new paths side by side, compare their outputs, keep a rollback path, and secure the data while it moves
- Explain TLS at the level of the handshake, certificates and what it does and does not protect, and explain CI/CD in terms of the risk it removes from deployment
- Work the debugging drill on the sixty-second latency sawtooth, then write the ordered checks you would run for a slow production response
- Optionally, work the coding exercise on merging partitioned event streams to practise ordering reasoning in messaging systems
Deliverable: A one-page migration plan with a rollback step, and a written ordered checklist for diagnosing slow production responses.
Day 7 — Behavioral stories and a Superday rehearsal
- Write four or five STAR stories covering a technical conflict, a challenging project and how you measured success, a tight deadline with unclear requirements, code-review feedback, and getting unblocked without help from your tech lead
- Prepare a specific answer to why you want to work at Wells Fargo rather than a technology-first company, tied to the kind of work described for the role
- Run a mock day of back-to-back sessions (one coding, one design, one behavioral) and check that your project facts stay the same across all three
- Write down the facts that must not change between tellings: team size, timeline, your role, the result
Deliverable: A one-page story sheet with fixed facts per story, and notes from a mock back-to-back session.
Frequently asked questions
Is this an official Wells Fargo interview guide?
No. It is independent research and practice material for the Software Engineer role at Wells Fargo. The rounds and questions reflect what candidates have reported, not a process Wells Fargo has published, and they change over time. Confirm the current format and scope with your recruiter.
How technical is the Wells Fargo Software Engineer interview?
Candidates report questions on computer science fundamentals, OOP and core Java, database design and SQL, and practical system architecture. They say the coding assessment runs on HackerRank, while the live interviews lean more toward conceptual discussion and project walkthroughs than toward competitive-programming puzzles. Prepare to explain how things work and why you chose them.
What is the typical timeline from the online assessment to an offer?
Candidates report roughly four to six weeks across six stages, with some reports ranging from three weeks to two months. The early stages (the HackerRank assessment and the recruiter call) tend to move quickly. Scheduling the Superday and the final HR and compensation approvals are where candidates report delays.
Does Wells Fargo offer remote work options for Software Engineers?
Candidate reports describe a hybrid arrangement, with engineering teams working part of the week from an assigned office. Arrangements can vary by team and location, so settle the office and in-office schedule with your recruiter at the screening stage.
How should I prepare for the behavioral portion of the interview?
Prepare four or five STAR stories you can adapt, covering teamwork, conflict resolution, unclear requirements, code-review feedback and delivering results. For each story, write down the facts that must not change (team size, timeline, your role, the measured result) so the story holds up across back-to-back panels. Tell each story as a conversation rather than a script.
Which language and technologies should I prepare in?
The role's must-have skills are Java with Spring Boot or a full-stack JavaScript/TypeScript setup (Angular or React), relational databases and Git. The nice-to-haves are Azure, Docker, Kubernetes, Kafka, ActiveMQ and CI/CD. The reported fundamentals questions are Java-heavy (garbage collection, HashMap internals, Spring dependency injection), so if you are a backend candidate, prepare in Java unless your recruiter says otherwise.
What is the Superday?
Candidates describe it as a block of back-to-back technical and behavioral panels with several team members, and say the core interview stage often leads into it. Prepare for stamina and consistency: your project facts should match across every panel. Ask your recruiter how many panels your Superday includes and what each one covers.
What if I get stuck during a live technical question?
Candidates report that interviewers often give hints and care more about your problem-solving process than a flawless answer. Say exactly what you are stuck on, state the part you are confident about, and build on the hint instead of starting over.
Keep practising
- Software Engineer question bank — cross-company practice.
- Interview preparation framework
- All interview guides