Interview guides · Bank Of Tokyo-Mitsubishi UFJ
Bank Of Tokyo-Mitsubishi UFJ Software Engineer Interview Guide
Bank Of Tokyo-Mitsubishi UFJ Software Engineer interview guide: reported rounds, coding and debugging questions, behavioral prep and a 7-day plan.
The 60-second brief
Bank Of Tokyo-Mitsubishi UFJ, shortened to MUFG in candidate reports, is a financial group, and the Software Engineer role candidates describe sits on its digital side. The work covers backend services that carry high-volume transactions, internal financial tools, and customer-facing web and mobile platforms linked to customer acquisition, digital marketing and customer lifetime value (LTV). Candidates describe a mix of building new services, tuning performance, debugging complicated existing code and making older banking systems work alongside newer digital architecture. The role is described as working with product managers, digital marketing specialists and UI/UX designers, and taking part in code reviews, architecture discussions and production troubleshooting. Java, Python and JavaScript/TypeScript appear as example languages, together with web architecture, API design and database management.
This guide is for engineers preparing for the Software Engineer loop at MUFG. The requirements candidates describe mention roughly 3 to 5+ years of experience across the software development lifecycle, so the preparation here assumes you already ship production code. It covers the four reported rounds, the coding, design, debugging and performance questions candidates report, the behavioral prompts about working with designers and product managers, and a seven-day plan that sequences them.
Candidates report four stages over about 3-5 weeks: an HR call, technical rounds on coding, debugging and problem-solving, functional discussions on domain knowledge and cross-team work, and a final behavioral interview.
Focus areas
- Technical Interviewing
- Code Debugging
- Financial Domain (Banking/FinTech Systems)
Overview
The coding scenarios candidates report are tied to digital platforms and financial data: building a feature from a vague business request, parsing a large file of customer transactions into aggregated metrics, designing an API endpoint for a high-volume marketing frontend, and writing tests for a new module. Related reported scenarios include tracking engagement for a campaign, writing the aggregation logic behind a customer LTV figure, and validating transaction payloads from a third-party API. Preparation therefore means practising the whole path from an ambiguous request to clarifying questions, a stated data model, modular code and edge cases (malformed rows, duplicates, currency and rounding, empty input), not only memorising algorithms.
Debugging and performance are the most repeated theme in the reports. Candidates describe being handed faulty code and asked to find the flaw, being asked about a CPU spike on a production server, a slow web service, a lagging database query for user profile data, and memory leaks in a language of their choice. One tip in the reports says candidates often fail technical rounds because writing new code comes easier than diagnosing broken code. Build a repeatable sequence you can narrate: reproduce, narrow the scope, measure, form one hypothesis at a time, fix, then verify with the same measurement. Know the tooling for the language you pick, for example heap dumps and thread dumps for Java, cProfile and tracemalloc for Python, and browser DevTools heap snapshots for JavaScript.
The functional and behavioral stages revolve around working with UI/UX designers, product managers and digital marketing teams: balancing technical debt against a campaign date, disagreeing with a product manager, missing a deadline, and explaining why you want to join the digital transformation work. Reports also advise tying technical answers back to customer experience and retention, and note that interviewers vary, with some formal or reserved. Prepare stories with real numbers and decisions you made, and practise explaining the frontend-to-API contract in plain language, since the role is described as sitting between engineering and non-technical stakeholders.
The Bank Of Tokyo-Mitsubishi UFJ interview process
Candidates report four stages: HR Screen, Technical Rounds, Functional Discussions and Behavioral Interview. One summary describes three to four rounds in total, so ask the recruiter to confirm the exact sequence for your team.
HR Screen
Candidates describe this stage as an opening call with HR about your background and how it fits the role. No technical exercise is reported for it. Treat it as the point where your experience gets matched to the stack the role lists (Java, Python or JavaScript/TypeScript, web architecture, API design, databases) and where logistics are settled.
What to demonstrate
- Background and role fit, as the stage is described
- Whether your experience level matches the 3 to 5+ years the requirements mention
- Clear, concise communication about your own work
How to prepare
- Write a short spoken walk-through of your CV that ends on one project with web or API work, and be ready to say what you built and what you owned.
- Prepare a specific reason for a bank's digital engineering work, drawn from the role (high-volume transaction backends, customer-facing web and mobile platforms), rather than a general reason for a large company.
- Ask the recruiter to confirm the number of rounds, what each covers, and whether coding is done live, so your preparation matches.
Technical Rounds
Candidates report several technical rounds focused on coding, debugging and problem-solving scenarios. The reported material is scenario-based: turning a business requirement into working code, designing an API endpoint, writing tests for a module, debugging a faulty snippet, and diagnosing CPU, latency or memory problems. Think aloud, state assumptions, and outline your approach before you write code; candidate tips recommend exactly that. This is where the coding, design and debugging practice questions in this guide are rehearsed.
What to demonstrate
- Working, readable code written during a live session
- A systematic debugging and troubleshooting method
- Choice of data structures and handling of edge cases
- Performance reasoning for slow queries, CPU spikes and memory growth
How to prepare
- Practise the transaction-parsing script end to end in your chosen language: stream the input, aggregate per customer and per day, skip and count malformed rows, and print the results.
- Rehearse the production CPU spike answer as a numbered runbook (confirm the symptom, find the hot process or thread, profile, link to a deploy or traffic change, fix, verify) and the memory leak answer with the profiler for your language.
- Outline the high-volume API endpoint on paper: request validation, idempotency, rate limiting, pagination, caching, error responses, and how you would test it at unit and integration level.
Functional Discussions
Candidates describe this stage as a discussion of functional domain knowledge and cross-functional collaboration. Reported topics include how frontend interfaces call backend APIs, how you negotiate technical trade-offs with design and marketing teams, and building features that improve customer retention and LTV. Questions here are conversational and experience-based, so prepare concrete projects instead of definitions.
What to demonstrate
- Understanding of how web frontends and backend APIs fit together
- Ability to work with UI/UX designers, product managers and marketing teams
- Judgment when a product requirement hits a technical limit
How to prepare
- Prepare a project where you worked with a designer, including one trade-off you negotiated, such as payload size, loading and error states, or what could be real-time versus cached.
- Write a short explanation of how your backend supports quick iteration by a marketing team: stable API contracts, feature flags, configuration instead of redeploys, and instrumented events.
- Learn to explain LTV logic in plain terms: which events count, over what window, how you would aggregate per customer, and what data quality problems would distort it.
Behavioral Interview
The final stage is described as a behavioral interview about cultural fit and professionalism. Candidates report prompts such as optimizing a slow application, working with UI/UX designers, balancing technical debt against a campaign, disagreeing with a product manager, missing a deadline, and why you want to join the digital transformation work. Reports also say interviewers can be formal or reserved, so rehearse in a steady, professional register.
What to demonstrate
- Cultural fit and professionalism, as the stage is described
- Clear communication with non-technical stakeholders
- Resilience and learning after a missed deadline or a disagreement
How to prepare
- Write one story per reported prompt with the situation in two sentences, your decision, the cost or risk, and a result you can back with numbers from your own work.
- Practise delivering each story aloud in a calm, structured way, including a version that stays clear if the listener gives little feedback.
- Prepare an honest answer on why a bank's digital work, naming a specific type of problem from the role such as legacy integration or high-volume transaction services.
Where candidates lose points
Starting to code the ambiguous feature request without asking anything first
For the feature-from-scratch and engagement-metrics scenarios, spend the first part of the answer on clarifying questions: who the users are, what counts as success, which data exists, what the deadline is. Then state assumptions, outline the modules and cover edge cases before you write code.
Debugging by guessing and editing lines until the output looks right
Reproduce the failure first, read the code path step by step, form one hypothesis at a time, and say what each check would rule out. Narrate a chain of reproduce, narrow, measure, fix and verify. Reports describe fault-finding in provided code as a common stumbling point, so rehearse it on other people's code.
Answering CPU spike, latency or memory leak questions with a list of tool names and no sequence
Give an order of operations: confirm the symptom in metrics, find the process or thread, profile or take a heap or thread dump, compare against recent deploys or traffic, then fix and measure again. Name the tools for your own language and what each output tells you.
Describing an optimization story without a baseline or a result
Open with a before number and finish with an after number from the same test, and say what you did to be sure the change caused the gain. If you do not remember exact figures, state the ranges you can stand behind.
Telling cross-team stories where the designer or product manager is the villain
Tell each story with the other person's goal stated fairly, your evidence, the options you offered and the outcome, including what you would change. The reported prompts on designers, product managers and deadlines are all about collaboration, not about being right.
Questions & practice
How would you approach building a new feature from scratch given ambiguous business requirements?
Medium · Technical Coding and Scenarios
Approach
- Turn the vague ask into a one-paragraph problem statement: who uses the feature, what action it enables, and which metric shows it worked. List the open questions, get answers where you can, and write down every assumption you make where you cannot.
- Pin down non-functional constraints before designing: data volume, latency target, who owns the data, authentication, and audit or retention rules that a banking system may carry. Turn each requirement into acceptance criteria written as testable given/when/then examples.
- Define the API contract first, then the data model, then the UI. Keep schema changes additive so a requirement that changes later does not force a destructive migration.
- Ship a thin end-to-end slice behind a feature flag to a small audience, measure it against the agreed metric, then iterate. Say the trade-off out loud: building in flexibility now costs time, while YAGNI risks rework, and a short decision record captures which way you went and why.
Follow-up
- Halfway through the build, the business owner changes a core requirement. What do you do with the work already done?
- Two stakeholders disagree on what success means for the feature. How do you settle it before you build?
- How do you decide you have asked enough clarifying questions and should start coding?
Write a script to parse a large dataset of customer transactions and output aggregated metrics.
Medium · Technical Coding and Scenarios
Approach
- Stream the file instead of loading it: iterate with csv.reader or csv.DictReader over the open file handle (or pandas read_csv with chunksize). That is one pass, O(n) time, with memory proportional to the number of groups rather than the number of rows.
- Aggregate in a dict keyed by customer id (or by a (customer, month) tuple) holding count, sum, min and max. Derive the mean from sum/count. An exact median or p95 cannot be computed in constant memory per group, so either keep the values or use an approximate sketch such as t-digest.
- Parse money with Decimal or integer minor units, never float (0.1 + 0.2 != 0.3 in binary floating point). Never sum across currencies without converting first, and bucket dates in an explicit timezone.
- Validate each row: missing fields, bad numbers, negative amounts or refunds, and duplicate transaction ids (deduplicating needs a set of seen ids, which costs memory). Write rejected rows to a separate file with a reason and report counts instead of crashing on the first bad line.
- If the distinct keys no longer fit in memory, hash-partition rows into files by customer id and aggregate each partition, or sort externally by key and do a single group-by pass. Past that point, load the data into SQL or a distributed engine and run GROUP BY there.
Follow-up
- A new file arrives every day. How do you make the job incremental and safe to rerun without double counting?
- The business now wants each customer's exact median transaction amount. What changes in memory and runtime?
- How would you test this script, and which malformed inputs would you include?
Diff a projection against the primary without per-row point reads
Hard · reconciliation · range hashing · throttling
The listing projection has drifted and some rows show a stale version. The primary holds 40,000,000 resource rows across 12,000 tenants while serving 1,200 writes and 14,000 reads per second. The obvious repair, reading each resource row and comparing its version against the projection, is correct and would eventually finish. Explain precisely why it is unacceptable here, then give a diff that finds the differing rows, state its complexity, and make it safe to run against a live primary. Replication lag is usually under 100 ms and is not bounded.
Approach
- Quantify the naive cost rather than calling it slow: 40,000,000 point reads at even 0.5 ms each is over five hours serialised, and the only lever is concurrency, which is exactly what you cannot spend. The primary's pool is sized for the write path, and 40,000,000 random reads evict the buffer cache that sustains the 85 percent cache hit rate, so the audit degrades the system it is auditing.
- Replace random access with one ordered pass per side. Both sides can be read in (tenant_id, resource_id) order, which is a sequential scan on each and a merge join in O(n) time and O(1) memory. For a dense diff that is the whole answer, and it reads the primary once instead of 40,000,000 times.
- For the expected sparse case, compare range hashes instead of rows: partition the key space, compute per range an order-independent aggregate over hash(resource_id, version), compare aggregates, and descend only into ranges that differ. With d differing rows and branching factor B, at most d ranges mismatch per level, so the drill-down examines O(d log_B(n/d)) ranges and reads full rows only in mismatching leaves.
- Aggregate with a sum modulo 2^64 or a multiset hash, never XOR. XOR is order-independent but self-cancelling, so two rows wrong in the same way, or a row duplicated on one side, leave the range aggregate matching and the range is declared clean.
Follow-up
- The diff reports 900 stale rows. How do you decide between patching those rows and rebuilding the projection from resource_revision?
- Same job, but the projection lives in a search index that cannot be scanned in key order. What changes?
Denormalise tenant onto revisions and backfill it live
Hard · denormalisation · online migration · backfill
resource_revision (revision_id, resource_id, version, actor_user_id, change_kind, patch, request_id, created_at) has 400M rows and no tenant column; tenant_id lives only on resource. Two reads need it: a tenant-scoped audit feed ordered by created_at DESC, and an offboarding purge. Both join back to resource today. Justify adding tenant_id to resource_revision against those two reads, name the anomaly the copy introduces and the constraint that prevents it, then give the ordered migration for a live table taking 1.2k writes/second — the lock each step takes, how the backfill is batched, and where each step stops being reversible. PostgreSQL 16.
Approach
- Justify from the access path rather than from taste. Without the column, the audit feed either scans resource_revision by created_at and discards other tenants' rows, or resolves the tenant's resource_ids first and probes with them — both proportional to the tenant's whole history rather than to one page. With (tenant_id, created_at DESC, revision_id DESC) it is a seek that stops at 50 rows, and the purge becomes a ranged delete instead of a join.
- Name the cost exactly: a second copy of a fact can disagree with the first. Make the disagreement unwritable rather than documented — add UNIQUE (resource_id, tenant_id) on resource so it can serve as a foreign-key target, then FOREIGN KEY (resource_id, tenant_id) REFERENCES resource (resource_id, tenant_id) on the revision table. A revision can then only ever carry its parent's tenant.
- Step one, expand: ALTER TABLE resource_revision ADD COLUMN tenant_id BIGINT NULL, with no default, so it is a catalogue change and no rewrite. It still needs ACCESS EXCLUSIVE for an instant, and that instant queues behind the longest open transaction on the table while every later query queues behind it — set lock_timeout to 2s and retry rather than wait.
- Step two, dual-write: deploy the writer that populates tenant_id on every new revision while reads still use the join. Reversible by redeploying the previous build, because nothing reads the column yet.
Follow-up
- The backfill is half finished and a rollback is required. What state is the table in, and what does the previous build do with a half-populated column?
- How do you verify the backfill actually finished, given rows are still being inserted while it runs?
Replace offset paging on the resource feed with keyset
Easy · keyset pagination · composite index · sort order
resource holds resource_id, tenant_id, owner_user_id, title, body_ref, version, status ('draft','active','archived','deleted'), created_at, updated_at, deleted_at, with an index on (tenant_id, status, updated_at DESC, resource_id DESC). The listing endpoint returns active resources for one tenant, newest update first, 50 per page, today with LIMIT 50 OFFSET n. Tenants reach page 400 and rows are created while they read. Write the keyset query, define what the cursor carries and how it is encoded, and say which part of the index each predicate uses. Assume PostgreSQL 16.
Approach
- Name the two failures separately. OFFSET 20000 makes the server produce and discard 20,000 rows, so page cost grows with depth rather than with page size. Independently, any write that changes how many rows sort above the offset moves the window between two fetches, and the direction decides which anomaly you get: an insert lands at the head of updated_at DESC and pushes already-returned rows down past the boundary, so they are returned a second time; a delete above the offset, or a row whose updated_at is bumped above the cursor, pulls rows up and one is never returned at all. Nothing in the response reveals either.
- Write the seek: WHERE tenant_id = $1 AND status = 'active' AND (updated_at, resource_id) < ($2, $3) ORDER BY updated_at DESC, resource_id DESC LIMIT 50. The row-value comparison is one index range rather than a disjunction, and both columns are NOT NULL, which is what makes that comparison well defined.
- Map each predicate onto the index: tenant_id and status are equality on the leading columns, (updated_at, resource_id) is the range, and the ORDER BY matches the index order so no Sort node appears and the scan stops after 50 rows. The DESC in the definition only matters for mixed directions — a plain ascending btree on the same columns is read backwards for this query.
- Put both sort columns in the cursor and nothing the client can tamper with into another tenant: base64 of (updated_at, resource_id), validated server-side, with tenant_id taken from the principal.
Follow-up
- The client asks for 'jump to page 400'. What do you offer instead, and what does the honest version cost?
- Sort order becomes user-selectable across four columns. How many indexes is that, and which would you refuse to add?
Design an API endpoint that handles high-volume requests from a digital marketing frontend.
Medium · Technical Coding and Scenarios
Approach
- Clarify the traffic shape first. A read-heavy endpoint (serving campaign content or offers) and a write-heavy one (impression and click events) need different designs. Ask about peak QPS during a campaign launch, the latency target, and whether losing a request is acceptable.
- For reads, run a stateless service behind a load balancer and scale horizontally. Cache non-personalised responses at a CDN with Cache-Control headers, cache per-user lookups in an in-memory store, and paginate with a keyset cursor instead of OFFSET.
- For writes, validate and return 202 Accepted quickly, then append to a durable queue or log and process asynchronously. Offer a batch endpoint so the browser can send several events per request, and require a client-generated event id or Idempotency-Key so retries are deduplicated rather than double counted.
- Protect the service: per-client rate limiting with a token bucket, 429 with a Retry-After header, request size limits, input validation, authentication, and a CORS policy scoped to the frontend origins.
- Name the metrics you would watch (p99 latency, error rate, queue lag) and the degradation plan: shed or sample non-critical analytics under load, but never drop anything that affects money or customer records.
Follow-up
- Traffic jumps tenfold at a campaign launch. What saturates first, and how do you prepare for it?
- The browser retries after a timeout even though the first request succeeded. How does your design avoid counting the event twice?
- How do you version this endpoint without breaking frontend clients that are already deployed?
Walk me through your process for writing unit and integration tests for a newly developed module.
Medium · Technical Coding and Scenarios
Approach
- Start from the module's public contract. List its behaviours, the input equivalence classes and boundaries (empty, zero, maximum, null, malformed) and its error paths, then write one unit test per behaviour in Arrange-Act-Assert form, each with a single reason to fail.
- Keep unit tests fast and deterministic by injecting dependencies. Replace the database, HTTP clients, the clock and randomness with fakes or stubs at the boundaries you own, and assert on outcomes rather than on internal call sequences where you can.
- Use integration tests for the wiring that unit tests cannot cover: real SQL against a database in a container with migrations applied, serialization, transaction boundaries, and the HTTP contract with neighbouring services (consumer-driven contract tests cover that last case). Keep them fewer than unit tests, following the test pyramid.
- Isolate test data. Each test creates what it needs and cleans up through a rolled-back transaction or truncation, no test depends on run order, and async results are polled with a timeout instead of fixed sleeps.
- Run unit tests on every commit and integration tests in the pipeline before merge. Treat branch coverage as a signal, not a target; mutation testing shows whether the assertions catch real changes. Every bug fix adds a regression test that fails before the fix.
Follow-up
- How do you test logic that depends on the current time or on a third-party API that is slow or rate-limited?
- An integration test fails one run in twenty. What do you do with it?
- What would you deliberately not test in this module, and why?
Here is a snippet of malfunctioning code. Walk me through how you would debug it.
Medium · Debugging and Performance
Approach
- Restate what the code is supposed to do, then get one concrete failing input with its expected and actual output. Read the snippet top to bottom out loud before touching anything.
- Reproduce with the smallest input that fails and trace it by hand, writing variable values per iteration. Check the usual suspects: off-by-one loop bounds, a wrong comparison operator, integer division, None/null handling, mutating a collection while iterating over it, Python's mutable default argument (def f(x=[])), and Java's == comparing String references instead of equals().
- Form one hypothesis at a time and confirm it with a breakpoint, a log line or an assert before you change code. Change one thing, rerun, and explain why the output moved.
- After the fix, run the edge cases (empty input, a single element, duplicates, very large values that could overflow) and write a test that fails on the old code and passes on the new. Then look for the same pattern elsewhere in the snippet.
Follow-up
- The bug only shows up intermittently under load. How does your approach change?
- You cannot attach a debugger in the environment where it fails, only logs. What do you add?
- What would stop this class of bug from reaching review again: types, a lint rule or a test?
How do you troubleshoot a sudden spike in CPU usage on a production server?
Medium · Debugging and Performance
Approach
- Scope it before going deep: one host or the whole fleet? Line up the spike's start time with deploys, config changes, request rate and scheduled jobs. If customers are affected, mitigate first by rolling back, scaling out or shedding load, then investigate.
- On the host, use top or htop to find the process and top -H -p <pid> to find the hot threads. Read the CPU split: high user time means application code, high system time points to syscalls or context switching, high steal means a noisy neighbour on a VM, and high iowait is not really a CPU problem. Compare load average with the core count.
- Profile inside the process. On the JVM, take several jstack dumps a few seconds apart and match the hot thread id from top -H (converted to hex) to the nid field; use async-profiler or JFR, and check GC logs, since frequent full GCs from heap pressure show up as CPU. For Python use py-spy; for anything native, Linux perf with a flame graph.
- Know the common causes: an infinite loop, regex catastrophic backtracking, a tight retry loop without backoff, GC thrashing, lock spinning, a bot or traffic surge, an O(n^2) path that larger data suddenly exercises, or a cache that expired and forced recomputation.
- Close the loop: fix the root cause, show the profile is flat again under a load test, add alerts on CPU saturation and latency, and write up the trigger separately from the cause.
Follow-up
- CPU is high but the request rate has not changed. What does that rule in or out?
- Only one of ten identical hosts is spiking. Where do you look?
- CPU looks normal but latency has doubled. How does your investigation change?
How do you identify and resolve memory leaks in your preferred programming language?
Medium · Debugging and Performance
Approach
- Pick one language and define the problem in it. In Java, a leak means objects that stay reachable when they should not. The symptom is heap usage after full GC climbing over time until OutOfMemoryError or constant GC, which is different from high but stable usage, and different from off-heap or native growth where RSS rises but the heap does not.
- Detect it by trending heap-after-GC from GC logs or metrics, then capturing heap dumps (jmap -dump:live,format=b,file=heap.hprof <pid>, or -XX:+HeapDumpOnOutOfMemoryError). Compare two dumps taken some time apart in Eclipse MAT, using the dominator tree, retained size and the path to GC roots to find what is holding the growth.
- Name the typical causes: unbounded static maps or caches (replace with a bounded cache with eviction), listeners or callbacks never unregistered, ThreadLocal values not removed in pooled threads, unclosed streams or connections (use try-with-resources), and map keys with a mutable hashCode or a missing equals.
- If Python is your language, compare tracemalloc snapshots (take_snapshot, then compare_to grouped by line) and inspect holders with gc.get_referrers or objgraph. Common culprits are module-level caches, functools.lru_cache with maxsize=None, and lru_cache on methods, which keeps self alive.
- Verify the fix with a soak test that shows a flat heap-after-GC baseline over hours, and add an alert on that trend so the next leak is caught before the process is killed.
Follow-up
- RSS keeps growing while the Java heap stays flat. What would you check next?
- The leak only appears in production after several days. How do you get evidence without taking the service down?
- How would you find a memory leak in a browser single-page application?
Suggested practice checklist
The plan follows the reported rounds: scenario coding, API design and testing, debugging, performance, then the functional and behavioral stages, with a full run-through on the last day.
Day 1 — Map the loop and choose your language
- Write the four reported stages in order (HR Screen, Technical Rounds, Functional Discussions, Behavioral Interview) and note the question types each one covers.
- Pick one language from Java, Python or JavaScript/TypeScript for coding and debugging answers, and list its profiler, heap analysis and test tools.
- Write a short CV walk-through for the HR call that ends on your strongest web or API project.
Deliverable: A one-page loop map, a chosen language with its tooling list, and a written CV walk-through.
Day 2 — Scenario coding: ambiguous features and transaction data
- For the feature-from-scratch question, write the clarifying questions you would ask, the assumptions you would state and a module outline for a campaign engagement tracker.
- Write the transaction-parsing script: stream a CSV, aggregate per customer and per day, count and set aside malformed rows, and print the summary.
- List edge cases for the script (empty file, duplicate transaction ids, negative amounts, currency, rounding, out-of-order timestamps) and add a test for each.
Deliverable: A question and assumption sheet, a working aggregation script, and a test per listed edge case.
Day 3 — API endpoint design and test strategy
- Outline the high-volume marketing endpoint: request validation, idempotency key, pagination, caching, rate limiting, error taxonomy and versioning.
- Write unit and integration tests for the endpoint's core logic, separating pure logic tests from tests with a real database or HTTP layer.
- Write a spoken answer on your process for testing a newly written module, from the first test to the integration checks.
Deliverable: An endpoint spec, a test suite split into unit and integration layers, and a rehearsed spoken answer on test process.
Day 4 — Live debugging and memory leaks
- Take three faulty snippets (an off-by-one, a mutated shared default argument or shared state, an unclosed resource) and diagnose each aloud, step by step, before touching the code.
- Reproduce a deliberate memory leak in your chosen language, such as a growing cache or retained listeners, and find it with a heap profile or snapshot.
- Write down your debugging sequence in five steps that you can say in order.
Deliverable: Three diagnosed snippets, one profiled leak with the fix, and your five-step debugging sequence.
Day 5 — Performance: CPU, latency and slow queries
- Write a runbook for a CPU spike on a production server, from confirming the metric to profiling, rollback and verification.
- Take a slow query on a user-profile style table, run EXPLAIN, add the right index and compare the plans before and after.
- Write your slow-application story with baseline, tools, change and measured result.
Deliverable: A CPU runbook, before and after query plans, the keyset paging exercise, and a written optimization story.
Day 6 — Functional discussions and cross-team stories
- Write the designer collaboration story, naming one trade-off you negotiated and its result.
- Write the technical debt versus campaign story, including what you refused to cut and how the debt was repaid.
- Write the product manager disagreement story with the evidence you brought and the options you offered.
- Explain aloud how a frontend calls your API and how you would keep it flexible for marketing changes.
Deliverable: Three written stories and a spoken frontend-to-API explanation you can say without notes.
Day 7 — Behavioral close and full run-through
- Write the missed-deadline story, with the date you flagged the risk and the practice you changed.
- Write a specific answer to why you want to join MUFG's digital work, using one concrete example from your experience.
- Run a full rehearsal in order: HR walk-through, one coding scenario, one debugging question, one cross-team story, the missed-deadline story and the why-MUFG answer, then note your weakest answer.
Deliverable: A missed-deadline story, a why-MUFG answer, and a notes page with your weakest answer from a full spoken run.
Behavioral stories for MUFG
The behavioral and functional stages are described as covering cultural fit, professionalism and cross-functional work. The reported prompts cluster around four things for this role: optimizing something that was slow, working with UI/UX designers, trading technical debt against a campaign date, and handling disagreement or a missed deadline with product partners. Prepare stories where you made the decision and can give real numbers.
Describe a time you had to optimize a slow-performing application. What tools did you use and what was the out
Medium · Debugging and Performance
Describe a time you had to optimize a slow-performing application. What tools did you use and what was the outcome?
Approach
- Choose a project where you owned the diagnosis, with a baseline you can state, such as p95 response time, page load, query time or job runtime before you touched anything.
- Name tools by layer and say what each showed: a browser performance panel or Lighthouse for a slow page, a sampling profiler or flame graph for CPU time, EXPLAIN ANALYZE or the slow query log for the database, tracing or APM for service calls.
- Explain how the evidence led to the change (for example removing an N+1 query, adding an index, caching a stable result, batching calls), why you ruled out the alternatives, and how you checked for regressions.
- Close with the measured result under the same test conditions and what you kept in place afterwards, such as a dashboard or alert. Give only numbers you can defend; an invented improvement figure sinks the story.
Follow-up
- How did you know the bottleneck was there and not somewhere else?
- What did the optimization cost in complexity, and what would make you roll it back?
- How did you confirm that your change, and not a traffic or data change, caused the improvement?
Tell me about a time you had to work closely with UI/UX designers to deliver a web product.
Medium · Functional Domain and Behavioral
Approach
- Pick a real feature where design decisions and engineering constraints collided, such as a data-heavy screen, a multi-step form or a mobile and web variant, and say in two sentences what was being built and for whom.
- Show how you worked together before code: reviewing mockups early, agreeing on loading, empty and error states, and sharing the API response shape so the design matched what the backend could return.
- Describe one concrete trade-off you negotiated, for example a live-updating widget replaced by a refreshed summary, with the reasoning, what the designer gave up and what the user gained.
- Finish with the outcome and the habit you kept, such as design reviews in the sprint or a shared component library. The mistake that sinks it is casting the designer as an obstacle or yourself as someone who only implemented specs.
Follow-up
- What did you do when the design could not be built as drawn?
- How did you handle accessibility or responsive behaviour with the designer?
- How did you check that the shipped interface worked for users?
How do you balance technical debt with the need to ship features quickly for a marketing campaign?
Medium · Functional Domain and Behavioral
Approach
- Open with the principle: classify debt by what it costs each week and what it risks, instead of treating all of it as one pile. A shortcut in a log message is different from one in input validation or money-handling logic.
- Describe the shape of your decision for a fixed campaign date: ship the thinnest slice that works, put it behind a feature flag, and write the shortcut down as a ticket with an owner and a trigger for paying it back.
- State what you refuse to trade away, such as correctness of transaction amounts, security checks and test coverage on the main path, and what you will defer, such as refactors, duplicated code and non-essential polish.
- Give a real example with the repayment: what you deferred, how you told the product manager the risk in plain terms, and when and how the debt was cleared. Answering that you always refactor first, or always ship, is the weak version.
Follow-up
- How do you persuade a product manager to fund the cleanup after the campaign ends?
- What would make you push back on a deadline instead of taking on the shortcut?
- How do you stop temporary shortcuts from becoming permanent?
Describe a situation where you disagreed with a product manager's technical approach. How did you resolve it?
Medium · Functional Domain and Behavioral
Approach
- Lay out the other person's goal fairly before your concern. A product manager choosing a technical approach usually has a delivery or customer reason, and naming it shows you understood the decision.
- Explain what you objected to and the evidence you brought, such as a prototype, a load estimate, an incident from the past or a data model issue, instead of general preference.
- Show that you offered options with costs, for example the approach as asked, a reduced version, and your alternative, each with time and risk, and that the decision was made openly by the right person.
- Report the outcome honestly, including a compromise or the case where the product manager's approach turned out fine. Treating it as a win-lose contest, or escalating before talking it through, is what sinks the story.
Follow-up
- What would you have done if the product manager still disagreed after seeing your evidence?
- Did the decision turn out right, and what did you learn about working with that person?
- How do you raise a technical limit early so that it does not arrive as a late objection?
Why are you interested in joining the digital transformation efforts at MUFG?
Medium · Functional Domain and Behavioral
Approach
- Build the answer on three parts: what draws you to the type of work described for this role (modernising web and mobile platforms next to older systems, backend services that carry high-volume transactions), a piece of your experience that fits, and what you want to learn.
- Use a specific example from your background, such as migrating a legacy module, exposing an old system through an API, or improving a customer-facing flow, and connect it to the kind of problem the role describes.
- Say something honest about working in a bank: the weight on reliability and security, and why that appeals to you or how you have already worked under review and change-control requirements.
- Research the role from the job posting and public material, and mention only what you can verify. Echoing phrases such as 'digital transformation' without a concrete reason, or saying the draw is size or stability, is the weak version.
Follow-up
- What kind of project do you expect to work on first, and how would you get up to speed on existing systems?
- How do you work when approvals and procedures are longer than you are used to?
- Why a bank instead of a technology company?
Tell me about a time you failed to meet a project deadline. What did you learn?
Medium · Functional Domain and Behavioral
Approach
- Choose a real miss, with a cause you can describe plainly: an estimate that ignored a dependency, scope that grew, or a risk you saw late. A story that is secretly a success does not answer the question.
- Say when you realised the date was at risk, when you told your manager or stakeholders, and what you offered them: a reduced scope, a new date with reasons, or extra support.
- Describe what you did to limit damage and finish, such as cutting features, splitting the release or pairing on the blocking piece, and what the final delivery looked like.
- End on a changed practice with evidence it worked later, for example breaking work into smaller milestones, adding buffer for integrations or flagging risk at the first slip. Blaming others, or answering that the lesson was to work longer hours, sinks it.
Follow-up
- When did you first know the deadline was at risk, and what did you do that day?
- How did the stakeholders react, and what would you say differently now?
- What do you do now to keep estimates honest on a similar project?