Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About Morgan Stanley hiring for Java roles
Morgan Stanley is a global financial services firm focused on investment banking, sales and trading, wealth management and investment management. Its India offices in Mumbai and Bengaluru are large technology and analytics hubs. It hires for software engineers, QA engineers, data engineers, quantitative analysts and risk or finance analysts.
For Java roles, this Morgan Stanley practice set focuses most on OOP in Java (7), Strings and Exception Handling (5), Java 8+ Features and Streams (4), Java Basics and JVM (4). It has 5 easy, 20 medium, 5 hard questions, so you can start easy and work up to the harder ones.
Company type
Banking & finance
Headquarters
New York, USA
Main India offices
Mumbai, Bengaluru
Morgan Stanley Java interview process
Online assessment (coding + aptitude)
Technical round 1
Technical round 2
Hiring manager round
HR round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for Morgan StanleyStart 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
How do you create a custom exception and when should you?
Extend RuntimeException for unchecked or Exception for checked, and provide constructors that accept a message and a cause so the root stack trace is kept. Create one when a domain error needs specific handling, such as InsufficientBalanceException, which a Spring @ControllerAdvice can map to an HTTP 422 response. Do not create exceptions for normal control flow.
02
Code builds a large CSV report with String += inside a loop and it is very slow. Why and what is the fix?
Each += creates a new String and copies all previous characters, so building n rows is O(n squared) in time and creates huge garbage. Use a single StringBuilder with append() inside the loop, ideally with an initial capacity, or write rows directly to a BufferedWriter for very large output. This turns minutes of work into milliseconds.
03
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.
04
Show runtime polymorphism with a simple Java example.
A parent reference calls the child's overridden method at runtime.
abstract class Shape {
abstract double area();
}
class Circle extends Shape {
double r = 2;
double area() { return Math.PI * r * r; }
}
class Square extends Shape {
double s = 3;
double area() { return s * s; }
}
Shape sh = new Circle();
System.out.println(sh.area()); // Circle area
05
Implement the Builder pattern for a User class with many optional fields.
A builder avoids long constructors.
public class User {
private final String name; private final int age;
private User(Builder b) { name = b.name; age = b.age; }
public static class Builder {
private String name; private int age;
public Builder name(String n) { name = n; return this; }
public Builder age(int a) { age = a; return this; }
public User build() { return new User(this); }
}
}
Usage: new User.Builder().name("Asha").age(25).build(). Lombok @Builder generates this.
06
Describe a situation where you had to deliver under a tight deadline.
Situation: a bulk upload feature had to go live in four days for a client launch. Task: build it safely in time. Action: I split it into must-have and later items, used an ExecutorService to process rows in parallel, wrote focused tests for validation and kept the product owner updated daily. Result: we shipped on time, it handled 50,000 rows in under two minutes and we added the extras next sprint.
07
What is the difference between reduce() and collect()?
reduce() combines elements into a single immutable value using an identity and an associative function, such as summing numbers. collect() is a mutable reduction that accumulates into a container like a List, Map or StringBuilder, which is far more efficient for building collections. Using reduce to build a list creates many intermediate copies, so use collect for containers.
08
Is it good practice to catch Exception or Throwable?
Usually no. Catching Throwable also catches Errors like OutOfMemoryError that the app cannot recover from, and catching Exception hides bugs by treating all failures the same. Catch the most specific exceptions you can handle. A broad catch is acceptable only at a top boundary, such as a global handler or thread entry point, where you log and return a safe error.
09
What are transaction isolation levels and which problems do they prevent?
Read Uncommitted allows dirty reads. Read Committed prevents dirty reads and is the default in PostgreSQL and SQL Server. Repeatable Read also prevents non-repeatable reads and is the MySQL InnoDB default. Serializable prevents phantom reads too but reduces concurrency. Choose the lowest level that keeps data correct, and use explicit locking for specific hot rows.
The JVM runs bytecode and handles memory, garbage collection and JIT compilation. The JRE used to be the JVM plus core libraries needed to run programs. The JDK adds development tools such as javac, jar, javadoc and jshell. Since Java 11, vendors ship only the JDK, and jlink can build a slim custom runtime for deployment.
11
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.
The simplest safe options are an enum or the holder idiom.
public class Config {
private Config() {}
private static class Holder {
static final Config INSTANCE = new Config();
}
public static Config getInstance() {
return Holder.INSTANCE;
}
}
The JVM loads Holder lazily and class initialisation is thread safe. An enum singleton also resists reflection and serialization attacks.
13
Implement equals() and hashCode() for an Employee class with id and email.
Use the same fields in both methods.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee e)) return false;
return id == e.id && Objects.equals(email, e.email);
}
@Override
public int hashCode() {
return Objects.hash(id, email);
}
Pattern matching for instanceof (Java 16) avoids an explicit cast.
14
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.
15
Tell me about a time you found and fixed a difficult production bug in a Java application.
Situation: our order service crashed with OutOfMemoryError every few days. Task: find the root cause without long downtime. Action: I enabled heap dumps on OOM, analysed the dump in Eclipse MAT and found a static HashMap used as a cache that was never cleared. I replaced it with a bounded Caffeine cache with expiry and added a heap usage alert. Result: no crashes in six months and memory stayed flat.
16
Exceptions are being swallowed with empty catch blocks in your codebase. How would you fix this?
Empty catches hide failures and make production issues invisible. I would find them with static analysis like SonarQube, then decide per case: handle the error properly, rethrow wrapped with context, or at least log with the stack trace. I would add a global exception handler for APIs and a team rule in code review and lint config to block new empty catch blocks.
17
Using streams, find the employee with the highest salary in each department.
Group by department with a maxBy downstream collector.
Map<String, Optional<Employee>> top = employees.stream()
.collect(Collectors.groupingBy(
Employee::department,
Collectors.maxBy(Comparator.comparingInt(Employee::salary))));
To get values without Optional, wrap with collectingAndThen(maxBy(...), Optional::get), which is safe because each group has at least one element.
Constructor chaining is calling one constructor from another. this(...) calls another constructor in the same class and super(...) calls a parent class constructor; either must be the first statement. If you write neither, the compiler inserts super() automatically. Chaining avoids duplicate initialisation code, for example a no-arg constructor calling this("default", 0).
Actuator adds production endpoints such as /actuator/health for liveness and readiness probes, /actuator/metrics and /actuator/prometheus for Micrometer metrics, plus info, loggers and thread dumps. Expose only what you need with management.endpoints.web.exposure.include and secure sensitive endpoints with Spring Security. Kubernetes uses the health groups to decide restarts and traffic routing.
20
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;
}
21
Clients report duplicate orders when they retry after a timeout. How do you prevent it?
Make the create order API idempotent. The client sends an Idempotency-Key header; the server stores the key with the result in a table with a unique constraint or in Redis. A retry with the same key returns the saved response instead of creating a new order. Database unique constraints on business keys add another safety net.
22
How does @Transactional work and what are its common pitfalls?
@Transactional is applied through a proxy that opens a transaction before the method and commits or rolls back after. Pitfalls: calling a transactional method from the same class bypasses the proxy, so no transaction starts; by default rollback happens only for unchecked exceptions; it works on public methods; and long transactions with remote calls hold connections. Use propagation and readOnly where suitable.
23
You need to add a new payment method to a system that has a big if-else on payment type. How would you redesign it?
This breaks the Open/Closed principle. I would create a PaymentProcessor interface with a pay() method and one implementation per type, such as UpiProcessor and CardProcessor. A factory or a Spring map of beans keyed by type picks the right one. Adding a new method then means adding one new class without touching existing tested code, and each processor can be unit tested alone.
24
Users report the app is slow for the first few minutes after every deployment. Why might this happen?
This is usually JVM warm-up. Code runs in the interpreter until the JIT compiles hot paths, and caches, connection pools and class loading are also cold. Fixes include warm-up traffic before adding the instance to the load balancer, pre-initialising pools, class data sharing (AppCDS) to reduce start time, or newer options like CRaC or GraalVM native image when fast start is critical.
25
You have to process tasks in order of priority. Which collection do you use?
Use PriorityQueue, a binary heap where poll() always returns the smallest element by natural order or by a Comparator, such as Comparator.comparingInt(Task::priority). Insert and poll are O(log n) and peek is O(1). For multiple threads use PriorityBlockingQueue. Iterating a PriorityQueue does not give sorted order; only repeated poll() does.
26
What is the Liskov Substitution Principle? Give an example of breaking it.
LSP says any subclass object must be usable wherever the parent is expected without breaking behaviour. A classic violation is Square extends Rectangle: setting width also changes height, so code that sets width 5 and height 4 and expects area 20 fails. Another is a subclass throwing UnsupportedOperationException for a parent method. The fix is a better hierarchy or composition.
27
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.
The heap stores all objects and is shared by threads; it is managed by the garbage collector. Each thread has its own stack holding frames with local variables and partial results. Metaspace (native memory since Java 8) stores class metadata. There are also the program counter register and native method stacks. StackOverflowError comes from the stack and OutOfMemoryError usually from heap or metaspace.
29
What is dependency injection and why is constructor injection preferred?
Dependency injection means the container creates objects and supplies their dependencies, instead of classes creating them, which reduces coupling and helps testing. Constructor injection is preferred because dependencies can be final, objects are never half-built, required dependencies are obvious and unit tests can pass mocks without Spring. Field injection with @Autowired hides dependencies and is harder to test.
30
Tell me about a time you made a codebase more readable.
Situation: our reporting module had nested loops 200 lines long that new joiners feared. Task: make it maintainable without changing output. Action: I added snapshot tests on real report files, then refactored into small methods using streams, groupingBy and records for intermediate data, and reviewed each step with a teammate. Result: the module shrank by 40 percent and later changes took a day instead of a week.
Tips to crack the Morgan Stanley Java interview
Revise core Java, OOP, multithreading and SQL, which are often expected for Morgan Stanley technology roles.
Learn basics of wealth management and trading, such as order types, portfolios and market risk.
Prepare examples showing attention to detail and controls, which matter in a regulated financial environment.
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; Morgan Stanley interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the Morgan Stanley Java interview?
Candidates usually go through 5 stages: Online assessment (coding + aptitude); Technical round 1; Technical round 2; 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 Morgan Stanley Java interview?
This practice set leans on OOP in Java (7), Strings and Exception Handling (5), Java 8+ Features and Streams (4), Java Basics and JVM (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Morgan Stanley interviewers ask you to walk through real work.
Are these the exact questions asked at Morgan Stanley?
No. These are curated practice questions that match the skills and difficulty usually tested in banking & finance interviews like Morgan Stanley's. They are not a leaked or verified list of past questions.
Where does Morgan Stanley hire Java professionals in India?
Morgan Stanley has large teams in Mumbai, Bengaluru. Openings and locations change often, so check the Morgan Stanley careers page and filter by city and experience.