Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About PhonePe hiring for Java roles
PhonePe is an Indian digital payments and financial services company, majority-owned by Walmart, known for UPI payments, insurance and investment distribution, and the Pincode commerce app. Its engineering teams build high-scale payments systems. It hires for software engineers, SDETs, data analysts, data engineers and data scientists.
For Java roles, this PhonePe practice set focuses most on JDBC, Hibernate and JPA (7), Multithreading and Concurrency (6), Strings and Exception Handling (5), Collections Framework (4). It has 2 easy, 21 medium, 7 hard questions, so you can start easy and work up to the harder ones.
Company type
Fintech
Headquarters
Bengaluru, India
Main India offices
Bengaluru, Pune
PhonePe Java interview process
Online coding assessment
Machine coding round
DSA or problem solving round
Design or hiring manager round
HR round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for PhonePeStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
When would you choose ArrayDeque over Stack and LinkedList?
Stack is a legacy synchronized class built on Vector, so it is slow and exposes index methods that break stack rules. LinkedList allocates a node per element. ArrayDeque is a resizable circular array with no per-element allocation, so push, pop, offer and poll are fast amortised O(1). Use ArrayDeque for both stacks and queues in single-threaded code; it does not accept null.
02
Flatten a list of lists of integers and compute the sum of squares of the even numbers.
flatMap then use a primitive stream to avoid boxing.
int result = lists.stream()
.flatMap(List::stream)
.filter(n -> n % 2 == 0)
.mapToInt(n -> n * n)
.sum();
mapToInt returns an IntStream, whose sum() is simpler and faster than reduce on boxed Integers.
03
Implement a producer-consumer using BlockingQueue.
Records, final in Java 16, are concise classes for immutable data. record Point(int x, int y) {} generates private final fields, a canonical constructor, accessors, equals(), hashCode() and toString(). You can add validation in a compact constructor and add methods. Use them for DTOs, API responses and map keys. They cannot extend another class and are not suited to JPA entities, which need mutability.
05
Group a list of orders by city and sum the amount per city.
Use groupingBy with a summing collector.
Map<String, Double> totals = orders.stream()
.collect(Collectors.groupingBy(
Order::city,
TreeMap::new,
Collectors.summingDouble(Order::amount)));
TreeMap keeps cities sorted. For money, store amounts as long paise or BigDecimal and use Collectors.reducing with BigDecimal::add.
06
Which JVM flags would you set to start a production service with a 4 GB heap, G1 and a heap dump on OOM?
Never expose stack traces; they leak internals. In Spring Boot use a @RestControllerAdvice with @ExceptionHandler methods that map domain exceptions to status codes, such as 404 for not found and 400 for validation. Return a consistent body, ideally RFC 7807 ProblemDetail, with a code, message and trace id. Log full details on the server with the same trace id.
08
Your Spring Boot service takes 40 seconds to start in Kubernetes and pods get killed. How do you fix it?
First set a startupProbe so Kubernetes waits for startup before liveness checks begin. Then reduce start time: remove unused starters, enable lazy initialisation where safe, avoid heavy work in @PostConstruct, give enough CPU at start and consider AppCDS. For very fast startup, a GraalVM native image built with Spring AOT can start in under a second, with some trade-offs.
09
What is the first level and second level cache in Hibernate?
The first level cache is the persistence context itself; it is per session or EntityManager, always on, and returns the same object for repeated finds by id in one transaction. The second level cache is shared across sessions and optional, backed by providers like Ehcache or Infinispan through JCache. Use it for read-mostly reference data, and be careful about stale data in clustered setups.
10
What is optimistic versus pessimistic locking in JPA?
Optimistic locking adds a @Version column; on update Hibernate checks the version and throws OptimisticLockException if another transaction changed the row, so you retry. It suits low contention. Pessimistic locking uses SELECT FOR UPDATE through LockModeType.PESSIMISTIC_WRITE, blocking others until commit; it suits high contention on the same rows, like seat booking, but can reduce throughput.
11
A getter returns an internal List and callers modify it, causing bugs. How do you fix this?
This breaks encapsulation. Return an unmodifiable view with Collections.unmodifiableList(list) or a copy with List.copyOf(list), so callers cannot change internal state. Also copy the list passed into the constructor or setter. If the class should be fully immutable, store List.copyOf in a final field. Expose specific methods like addItem() when controlled changes are needed.
12
You need a cache that evicts the least recently used item when full. How would you build it in Java?
Extend LinkedHashMap with accessOrder set to true and override removeEldestEntry to return true when size exceeds capacity. Each get moves the entry to the end, so the eldest is the least recently used. It is not thread safe, so wrap it with synchronization for shared use. In production prefer Caffeine, which offers size and time based eviction with high concurrency.
13
What are virtual threads and when should you use them?
Virtual threads, final in Java 21, are lightweight threads managed by the JVM and mounted on a small pool of carrier OS threads. When one blocks on I/O, it unmounts so the carrier can run another. You can run millions of them, which suits thread-per-request servers doing lots of blocking calls. They do not speed up CPU-bound work, and you should not pool them.
14
Your application hangs and CPU is near zero. How do you find out why?
Low CPU with a hang suggests threads are blocked, often a deadlock or waiting on a slow resource. Take several thread dumps with jcmd pid Thread.print. The JVM reports detected deadlocks at the end of the dump. Otherwise look for many threads BLOCKED on the same lock or WAITING on a connection pool or socket read, then fix lock order, add timeouts or increase the pool.
15
How would you write a simple thread safe rate limiter in Java?
A token bucket with synchronized refill is simple and correct.
class RateLimiter {
private final long capacity, refillPerSec;
private double tokens; private long last = System.nanoTime();
RateLimiter(long cap, long rps) { capacity = cap; refillPerSec = rps; tokens = cap; }
synchronized boolean tryAcquire() {
long now = System.nanoTime();
tokens = Math.min(capacity, tokens + (now - last) / 1e9 * refillPerSec);
last = now;
if (tokens >= 1) { tokens--; return true; }
return false;
}
}
Across servers, keep the bucket in Redis.
16
What is the N+1 select problem in Hibernate and how do you fix it?
N+1 happens when you load N parent entities with one query and then a lazy association triggers one extra query per parent, giving N+1 queries. Fix it with a JOIN FETCH in JPQL, an @EntityGraph on the repository method, or batch fetching with @BatchSize or hibernate.default_batch_fetch_size. Detect it by enabling SQL logging or using a query count assertion in tests.
17
An API needs to find the price band for any amount, for example the nearest lower slab. Which structure fits?
TreeMap is ideal because it keeps keys sorted and offers navigation methods. Store slab start amounts as keys and the band as value, then floorEntry(amount) returns the largest slab not above the amount in O(log n). ceilingKey, headMap and tailMap help with similar range queries such as tax slabs or delivery charges.
18
What is the difference between intermediate and terminal operations in streams?
Intermediate operations like filter, map, sorted and distinct return a new stream and are lazy; nothing runs until a terminal operation is called. Terminal operations like collect, forEach, reduce, count and findFirst trigger processing and produce a result. Laziness lets streams fuse steps into a single pass and short-circuit, so findFirst on filtered data stops early.
19
Write a custom unchecked exception and a Spring handler that returns HTTP 404.
Define the exception, then map it centrally.
public class NotFoundException extends RuntimeException {
public NotFoundException(String msg) { super(msg); }
}
@RestControllerAdvice
public class ApiErrors {
@ExceptionHandler(NotFoundException.class)
public ProblemDetail notFound(NotFoundException e) {
return ProblemDetail.forStatusAndDetail(
HttpStatus.NOT_FOUND, e.getMessage());
}
}
20
Your service throws OutOfMemoryError: Java heap space in production. How do you investigate?
First capture evidence: enable -XX:+HeapDumpOnOutOfMemoryError and check GC logs to see if heap grows steadily, which signals a leak, or spikes, which signals a large request. Analyse the heap dump in Eclipse MAT or VisualVM and look at the dominator tree for big retainers like static maps or caches. Fix the leak or bound the cache, then increase -Xmx only if the real workload needs it.
Transient: a new object not yet linked to a persistence context. Managed (persistent): attached to the context, so changes are tracked and flushed automatically through dirty checking. Detached: was managed but the context closed or it was evicted; changes are not tracked until merge(). Removed: scheduled for deletion on flush. persist, merge, detach and remove move entities between these states.
volatile guarantees visibility and ordering: a write to a volatile field is immediately visible to other threads, and it prevents reordering around that access under the Java Memory Model. It does not make compound operations like count++ atomic, because that is a read, modify and write. Use it for flags such as a stop signal, and use AtomicInteger or locks for counters.
23
How do you handle a situation where you made a wrong technical decision?
Situation: I chose eager loading for a reporting entity to save time, and later pages became slow. Task: own and fix it. Action: I told my lead, measured the impact, switched associations to lazy with targeted fetch joins and added query count tests. Result: performance recovered within a sprint and I now review fetch strategy in every design discussion.
24
Read a large text file line by line efficiently and count lines containing ERROR.
Stream the file lazily so it never loads fully into memory.
Path p = Path.of("app.log");
try (Stream<String> lines = Files.lines(p)) {
long errors = lines
.filter(l -> l.contains("ERROR"))
.count();
System.out.println(errors);
}
try-with-resources closes the file handle. BufferedReader.readLine() in a loop is an equally good option.
25
Run two tasks in parallel with CompletableFuture and combine their results.
Use JOIN FETCH or an entity graph.
public interface OrderRepository extends JpaRepository<Order, Long> {
@Query("select distinct o from Order o join fetch o.items where o.customerId = :cid")
List<Order> findWithItems(@Param("cid") Long customerId);
@EntityGraph(attributePaths = "items")
List<Order> findByStatus(String status);
}
Both load orders and items in one query.
27
Write a sealed interface with records and a switch that computes area.
The switch needs no default because the type set is closed.
sealed interface Shape permits Circle, Rect {}
record Circle(double r) implements Shape {}
record Rect(double w, double h) implements Shape {}
static double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.r() * c.r();
case Rect(double w, double h) -> w * h;
};
}
28
A file handle leak causes Too many open files errors after a day. What is the likely cause?
Streams, readers or connections are opened but not closed on all paths, especially when an exception is thrown before close(). Check with lsof or jcmd which files are open. Fix by wrapping every resource in try-with-resources so it always closes, and make sure Files.lines() and Files.list() streams are closed too, since they hold file handles.
29
Map a one-to-many relation between Order and OrderItem in JPA.
Make the child own the foreign key and keep both sides in sync.
@Entity
class Order {
@Id @GeneratedValue Long id;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
List<OrderItem> items = new ArrayList<>();
void addItem(OrderItem i) { items.add(i); i.setOrder(this); }
}
@Entity
class OrderItem {
@Id @GeneratedValue Long id;
@ManyToOne(fetch = FetchType.LAZY) Order order;
}
30
A log file shows a NullPointerException only for some users. How do you debug it?
Start with the stack trace; since Java 14 helpful NPE messages name exactly which variable was null. Reproduce with the failing user's data, which often has an optional field missing. Fix the root cause by validating input at the boundary, using Optional for values that may be absent and annotating with @NonNull. Add a unit test for that data case so it does not return.
Tips to crack the PhonePe Java interview
Practise machine coding problems and focus on clean, extensible object-oriented design within the time limit.
Understand how UPI transactions work at scale, including idempotency, retries and reconciliation.
For analyst roles, prepare cases on transaction success rates, merchant adoption and fraud detection metrics.
Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
Practise the hard questions on this page aloud; PhonePe interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the PhonePe Java interview?
Candidates usually go through 5 stages: Online coding assessment; Machine coding round; DSA or problem solving round; Design or hiring manager round; HR round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.
Which topics should I prepare for the PhonePe Java interview?
This practice set leans on JDBC, Hibernate and JPA (7), Multithreading and Concurrency (6), Strings and Exception Handling (5), Collections Framework (4). Revise those first, then practise explaining one or two of your own projects end to end, because most PhonePe interviewers ask you to walk through real work.
Are these the exact questions asked at PhonePe?
No. These are curated practice questions that match the skills and difficulty usually tested in fintech interviews like PhonePe's. They are not a leaked or verified list of past questions.
Where does PhonePe hire Java professionals in India?
PhonePe has large teams in Bengaluru, Pune. Openings and locations change often, so check the PhonePe careers page and filter by city and experience.