Cracking The Core Java Interviews
Cracking The Core Java Interviews
My skills my Job!!
Preface
This work is my sincere effort to consolidate solutions to some basic set of problems faced by my fellow mates
in their day to day work. This work can be used by candidates preparing to brush up their skills for Job change.
This Book Is
• Collection of excerpts discussing the common problems faced by an experienced Java Developer in his
day to day work. The intent is not to provide with the concrete solution to a given problem, but to show the
approach to get the problem solved. And there could definitely be more efficient ways to solve the given
problem compared to what is mentioned in this book. The approach shown here is limited to the knowledge
of the author.
• Collection of topics in Core Java, Object Oriented Design, Concurrency, Algorithms & Data Structures and
few puzzles.
I hope this book adds value to your skills. Be a student for lifetime and enjoy new learnings!
Munish Chandel
cancerian0684@gmail.com
http://linkedIn.com/munish.chandel
January 2013
Chapter - Introduction Cracking the Core Java Interviews 4
Chapter - Introduction Cracking the Core Java Interviews 5
Table of Contents
Cracking The Core Java Interviews 2
Preface 3
Concepts 8
Core Java 41
Concurrency 86
Question: What causes a typical developer to switch his/her job so frequent, Is that bad, why that is
not the case in West ?
A thought to switch Job comes to one's mind when one finds blockage in growth opportunities in their current
organization. I could list few reasons for the same -
1. Salary disparity and scope for higher salaries in next Job is the major reason for job switch. Most service
based companies tries to maximize their profit offering lower salaries to its employees (that's beneficial for
freshers who do not have any experience), but as people acquire more skills they switch for bigger roles in
new Job. Demand and supply typically governs the salaries in India.
2. The quality of work is another reason for switch. Work quality directly relates to stress (more manual work
more stress)
3. Shift Timings and location preference also causes people to switch their jobs
To some extent this switch is fair because we can't expect someone to work for a company few thousand
dollars a year for his lifetime (As he acquires skills in parallel to take up more responsibilities). As the Industry
will mature, job shift will reduce. The IT companies in west are mature, salaries are already saturated, people
don't take much work stress, So western employees do not find many reasons for their Job switch.
Question: What is typical psychology of average Indian Developer ? What kind of chaos pollute his
mind ?
Most Indian opt for IT, not by choice but for money, because of large unemployment in India. Moreover earning
Chapter - Introduction Cracking the Core Java Interviews 7
money in IT industry is easy and effortless compared to other parallel opportunities. Many people wants to
take IT as the jumping ground for their higher studies (MBA, MS, etc). An average fresher is polluted with the
thoughts about his career growth, and is unsure about his key interests in IT field, trying various alternates in
first few years.
Question: What is the Problem with Most Indian Developers in terms of Skills ?
Majority of IT crowd does not have good hold over their primary skills (Technical, Presentation) which are
required for the work. The underlying cause for the low skills are poor quality of education and the type of work
which is fed to Indian Companies. The majority of work does not require high quality of skills on developer's
part. Many people learn by their own, build their skills and fight for better quality work. One should have a very
good hold over his primary skill set and look for work which is matching those skills.
Question: Would it help if I memorize all the questions for cracking interviews?
No, it will not. But memorizing the most common Patterns of software development will definitely help
crack not only the interview but also make your day to day work life easy. A single pattern resolves n number
of problems emerging from that pattern, and we should always look forward finding the patterns instead of
solution to a particular problem.
Question: Why do interviewers ask rocket science questions in interviews even if the new role does
not require any such skills ?
Hiring in IT industry is not regulated by any means, it is solely up to the interviewer to choose the topic for
discussion in the interview. In today's intellectual world, people like intellectual war, and interview is a good
place for that. I do not find any harm by such interview process unless interviewer hides the real picture of work
that one needs to perform after joining the new role. For sure there is one plus point to such interview process
that it will definitely tend to raise our skill set.
Question: Why people take so many offers at the time of Job change, doesn't it add to chaos ?
The main reason for doing so, is the disparity between work and salary across the companies. People feel
insecure at financial level and try their best to grab the most paying Job opportunity, and that's fair from
employee perspective. On the other hand, companies tend to maximize their profit by limiting the salary offer
as per individual's previous company's salary. So it is a game, where both the employer and the employee are
fighting to maximize their own profit. Ultimately, the Demand and Supply equation balances the fight between
employer and the employee. Saturation of salaries and work quality in coming years might hamper this.
Chapter 1
Concepts
Q 1. What are good software practices for developing Scalable, Testable and Main-
tainable Software?
SOLUTION
1. Follow good software development practices like Agile with Test Driven Development. Agile development
is all about incorporating changes in the software without much pain. TDD helps achieving agility in your
software. A very good test coverage (End to End and Unit Tests) keeps a developer away from last minute
stress at production deployment time.
2. Automate all non-productive mundane tasks related to development/deployment.
3. Take a software change request only if it is really required.
4. Keep refactoring your code base time to time, don't leave any duplicate code inside code base. Follow DRY
(don't repeat yourself) strictly. Every object must have a single authoritative representation in the system.
Software development is like the art of gardening where refactoring takes it to a next level.
5. Add an automated test case for every new bug found.
6. Document interfaces and reasons instead of implementation.
7. Use Profiling Tools to identify bottlenecks of your application. One can use jvisualVM tool bundled in JDK
to know the JVM profile of an application, though there are some commercially available easy to use tools
available in market.
8. Use pair programming when bringing someone new up to speed and when tackling particularly tricky
problems which are hard to KT otherwise. This also leads to smooth landing for the new employees.
9. Use tools to find the duplicates and then refactor to reuse the existing code with better design. IntelliJ is
one of the good tools that will take care of boilerplate stuff (but soon you will become it's luxury addict)
10. Work in small steps with frequent feedback and correction to avoid the last minute surprises (Agile).
11. Continuous Integration environment is must for rapid bug free, coordinated development.
12. Software development without Art, Fun and Creativity is boring and will bring depression, so be aware of
this warning sign. Don't leave learning, be a student for lifetime!!!
A deep understanding of basic software components is must for a developer who wants to write Scalable
Enterprise/Internet Applications from scratch using Java. Below is the matrix showing a hierarchy of
skills which are required for a senior software developer who are aiming a long term carrier in Software
Development.
Tree Traversal, Tree Insertion, Tree balancing using left & right rotation,
3 Algorithms Sorting (quick, merge, external, selection), Binary Search, BFS, DFS,
Topological Sorting using Graph, Dijkstra's algorithm
Q 4. Why should I choose Java for Software Development? What are Pros and Cons
of Java (as of JDK 1.7)?
SOLUTION
Java Pros
1. It's free of cost, download it and start creating your applications
2. Open source with quite large community base
3. Lots of available third party libraries, frameworks & IDE for fast development cycles (Spring, Hibernate,
Eclipse, IntellJ)
4. Platform independent, write once run on most modern platform (Unix, Windows, Mac, 32/64 bit Hardware)
5. Supports Object Oriented Programming, easy to model real life scenarios into object model
6. In built support for multi-threading, It can very efficiently utilize maximum of given hardware (Threads, Fork/
Join, non-blocking algorithm using CAS, etc)
7. Very good support for Internationalization
8. Memory management is automatic by use of garbage collector
9. Pure Java Byte code running on 32 bit JVM works perfectly fine on 64 bit platform
10. Its Improving year by year (JDK 1.8 will bring some functional syntax)
Java Cons
1. Is not a good fit for desktop applications because of heavy memory footprint and huge VM startup time
compared to ay C/C++ written application
2. Normal Java is not good for real time systems because of "stop the world garbage collector pauses".
3. Java does not provide very good support for functional programming as of JDK 1.7
Few of these issues might get addressed in the forthcoming releases of Java.
The Java language specifications are same for both the platform i.e. int will remain to be 4 bytes signed two's
complement, char will remain single 16-bit Unicode, long will remain 64-bit signed two's complement, and so
on. Hence any Pure Java code will not see any difference provided external native calls are not used. All that
changes is the amount of addressable memory (good) and the amount of memory per Object (not that good).
The size of the reference variables doubles from 32 bit to 64 bit, thus all the reference variable will take double
the size when running on 64 bit JVM.
Theoretically, there are no class file differences between code compiled with the 32 bit and 64 bit versions of
the same revision of Java.
For 32 bit JVM, the maximum memory is limited to 4GB, the memory limit for 64 bit JVM is very high. But more
JVM memory may cause larger System wide GC pauses, so the size of JVM should be decided keeping this
factor into account.
Please also note that 64 bit JVM requires more memory compared to 32 JVM for the same application
because now each reference starts consuming 64 bit instead of 32 bit i.e. management cost in 64 bit version is
higher than the 32 bit version. However, newer JVMs offer object pointer compression1 techniques which can
significantly reduce the space required by 64 bit JVM.
1 http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html
Chapter - Concepts Cracking the Core Java Interviews 11
There are 4 major principles that make an language Object Oriented. These are Encapsulation, Data
Abstraction, Polymorphism and Inheritance.
Encapsulation
Encapsulation is the mechanism of hiding of data implementation by restricting access to public methods.
Abstraction
Abstract means a concept or an Idea which is not associated with any particular instance. Using abstract class/
interface we express the intent of the class rather than the actual implementation. In a way, one class should
not know the inner details of another in order to use it, just knowing the interfaces should be good enough.
Inheritance
Inheritances expresses "is a" relationship between two objects. Using Inheritance, In derived classes we can
reuse the code of existing super classes.
Polymorphism
It means one name many forms. It is further of two types - static and dynamic. Static polymorphism is achieved
using method overloading and dynamic polymorphism using method overriding.
Q 7. What are the key paradigms for Developing the Clean Object Oriented Code?
SOLUTION
A logarithm1 tells what exponent (power) is needed to make a certain number. In a way it is opposite of
exponentiation. For example,
log2 (8) = 3 and 23 = 8
log10 (1000) = 3 and 103=1000
In pre modern era, when calculators were not there, logarithm tables were used for division and multiplication
of large astronomical numbers.
Notes
Logarithm was used in India in ancient times around 2 BC to express astronomical units. It is known as
Laghuganak in Hindi.
Logarithmic spirals are common in nature. Examples include the shell of a nautilus or the arrangement of
seeds on a sunflower.
In astronomy, the apparent magnitude measures the brightness of stars logarithmically, since the eye also
responds logarithmically to brightness.
1 http://simple.wikipedia.org/wiki/Logarithm
Chapter - Concepts Cracking the Core Java Interviews 13
Big O Notation1 is a mechanism used to measure the relative efficiencies of Algorithms in terms of Space and
Time. It makes us understand how execution time & memory requirements of an algorithm grow as a function
of increasing input size. In this notation, O stands for the Order of magnitude.
Constant O(1) - a program whose running time's order of growth is constant, executes a fixed number of
operations to finish the job, thus its running time does not depend on N.
Linear O(N) - a program that spends a constant amount of time processing each piece of input data and thus
running time is proportional to the N.
Logarithmic O(log n) - a program where on every subsequent iteration, the problem size is cut by half, for
example - Binary Search.
Importance of Big O
We should always keep time efficiencies in mind while designing an algorithm for a data structures, otherwise
there could be severe performance penalties for using wrong algorithm for a given scenario.
Base of Logarithm is irrelevant in Big O Notation
The base of algorithm is not relevant with respect to the order of growth, since all logarithms with a constant
base are all related by a constant proportion, so log N is used when referring to the order of growth regardless
of the base of Algorithm.
Number -> 1,10,100,1000
Log2 -> 0, 2.3, 4.6, 6.9
Time efficiency in Big O notation for few Java Collections
ArrayList (ignoring the time taken by array resize operation)
O(1) for add, size and get
O(n) for toString() method
PriorityQueue
O(1) for peek, element and size
O(log n) for offer, poll, remove() and add
O(n) for remove(Object) & contains(Object)
HashMap (with no collisions)
O(1) for get operation
O(1) for put operation
LinkedList
O(1) for removal and O(1) for add & poll method
O(n) for toString() method
1 http://en.wikipedia.org/wiki/Big_O_notation
Chapter - Concepts Cracking the Core Java Interviews 14
Q 10. How would you determine the Time Complexity of a given algorithm, are there
any general guidelines?
SOLUTION
There are few rules which can help us in the calculation of overall running time of a given piece of code.
1. Consecutive Statements
We should add the time complexity of each statement to calculate the total time complexity. For example if we
have 3 lines of code with O(1), O(log n) and O(n) complexity respectively, then the total time complexity would
be O(1)+O(log n)+O(n) = ~O(n)
In case of if-else condition, we should include the time complexity of condition and if or else part, whichever is
larger.
Total time complexity can be calculated by multiplying the Time Complexity of individual statement with the
number of iterations. for example, in the below code
Q 11. List down sorting algorithms by their time & memory complexity in Big O nota-
tion ? When do we call a sorting algorithm 'Stable'?
SOLUTION
Sorting is an algorithmic technique to put all the collection elements in certain order.1
Algorithm Average Time Complexity Worst Time Complexity Memory Complexity
Quicksort n log n n2 log n
Binary Tree Sort n log n n log n n
Merge Sort n log n n log n n
Selection Sort n2 n2 1
Bubble Sort n2 n2 1
Heap Sort n log n n log n 1
Now there are two solution possible for the first two elements
OUTPUT1 --> [(1,2) (1,3) (2,3) (3,1)] --> stable sort because order is maintained
OUTPUT2 --> [(1,3) (1,2) (2,3) (3,1)] --> unstable sort because order changed from the original
Examples of Stable Sort algorithms are : Binary Tree Sort, Bubble Sort, Merge Sort, Insertion Sort, etc
Unstable Sorting Algorithms : Heap Sort, Selection Sort, Quick Sort
Question: Do you know what Sorting algorithm JDK uses for Java's Collections.sort(List<E>) method?
Collections.sort(List<E>) uses Iterative merge sort algorithm, it requires fewer than n log(n) comparisons when
the input array is partially sorted and this algorithm is guaranteed to be stable in nature.
Q 12. Why Prime Numbers are given much importance in writing certain algorithms
like hashcode()?
SOLUTION
Prime numbers are very useful for generating hashcode, RSA algorithms, random number generators.
String class's hashcode method multiplies its hash value by prime number 31 :
A number is either prime number or a composite number (can be factorized into prime numbers). Prime
numbers are always unique and can not be divided by any other number except 1. The product of prime
number with any other number has the best chances of being unique (though not as unique as Prime number
itself) due to the fact that prime number is used to compose it. This property makes them very suitable for use
in hashing function so as to obtain fair distribution in its hashcode output and thus achieving low collisions.
Multiplying by the prime number will not tend to shift information away from the low end, as it would multiplying
by a power of 2, thus achieving a fair randomness.
1 http://en.wikipedia.org/wiki/Sorting_algorithm
Chapter - Concepts Cracking the Core Java Interviews 16
Q 13. What is left shift <<, right shift >> and Unsigned right shift operator in Java?
How are these useful?
SOLUTION
All Integer in Java are of signed type (negative numbers are represented in 2's complementary notation),
hence Java provides both signed and unsigned bit shift operators to support signed and unsigned shift of bits.
It shifts the underlying bits of an integer to left by the given distance filling the right most bits with zero always.
X = a << b means the same as X = a*2^b
a is given Number and b is the shift amount.
Here is an example of 8 bit representation of number 5. and when we left shift it's bit by 3 then the right most 3
bits are filled by zero.
And the number becomes
5*23 = 40. 00000101 00101000
The same thing happens for negative numbers which are represented in 2's complementary notation. for
example -5 becomes -40 as follow
11111011 becomes 11011000
Shifts the bits to left by specified amount maintaining the sign of underlying integer i.e. It fills the left most bits
with 0 if the number is positive otherwise with bit 1.
X = a >> b means same as arithmetic operation X = a / (2b)
Unsigned right shift Operator >>> (does not respect sign of Number)
Unsigned right shift operator >>> is effectively same as >> except that it is unsigned, it fills the left most
positions with bit 0 always. (Irrespective the sign of the underlying number)
For example,
So 10000000 >>> 3 becomes 10000 in binary
256 >> 3 becomes 256 / 2^3 = 16.
Notes
• Eight-bit type byte is promoted to int in shift-expressions. To mitigate such effects we can use bit masking
to get the result as byte for example, (b & 0xFF) >>> 2. Casting can also help achieving the same.
• Uses of bitwise operators: bitwise operators are used for few very efficient mathematical calculations
in Big O(1). Bloom Filter, fast mathematical calculations, hashing functions of HashMap are some of
applications.
Chapter - Concepts Cracking the Core Java Interviews 17
It is a number format for storing negative numbers in Binary1. This system is the most common method of
representing signed numbers on computers. An N-bit two's-complement numeral system can represent every
integer in the range −(2N−1) to +(2N−1 − 1)
The two's-complement system has the advantage that the fundamental arithmetic operations of addition,
subtraction, and multiplication are identical to those for unsigned binary numbers (as long as the inputs are
represented in the same number of bits and any overflow beyond those bits is discarded from the result).
This property makes the system both simpler to implement and capable of easily handling higher precision
arithmetic. Also, zero has only a single representation, obviating the subtleties associated with negative zero,
which exists in ones'-complement systems.
Positive numbers are represented as the ordinary binary representation in 2's complementary notation.
The most significant bit (leftmost bit) is always 0 for positive number, otherwise number is negative.
To get 2's complement of a negative numbers, the bits are inverted (using bitwise NOT operator) and then
value of 1 is added to get the final result.
That is +5.
1 http://en.wikipedia.org/wiki/Two's_complement
Chapter - Concepts Cracking the Core Java Interviews 18
Q 15. How Heap space is divided in Java. How does Garbage Collector cleans up the
unused Objects ? Why shouldn't we use System.gc() command in production code?
SOLUTION
Memory taken up by the JVM is divided into Stack, Heap and Non Heap memory areas. Stacks are taken up
by individual threads for running the method code while heap is used to hold all class instances and arrays
created using new operation. Non-heap memory includes a method area shared among all threads and is
logically part of the heap but, depending upon the implementation, a Java VM may not GC or compact it.
The Young generation - This further consists of one Eden Space and two survivor spaces. The VM initially
assigns all objects to Eden space, and most objects die there. When VM performs a minor GC, it moves any
remaining objects from the Eden space to one of the survivor spaces.
Tenured/Old Generation - VM moves objects that live long enough in the survivor spaces to the "tenured"
space in the old generation. When the tenured generation fills up, there is a full GC that is often much slower
because it involves all live objects.
Permanent Generation - The permanent generation holds all the reflective data of the virtual machine itself,
such as class and method objects.
Please note that the contents of this article are likely to change with change in Future Java Versions.
Memory Spaces
1 http://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html continued on 19
Chapter - Concepts Cracking the Core Java Interviews 19
Eden Space (heap): The pool from which memory is initially allocated for most objects.
Survivor Space (heap): The pool containing objects that have survived the garbage collection of the Eden
space.
Tenured/Old Generation (heap): The pool containing objects that have existed for some time in the survivor
space.
Permanent Generation (non-heap): The pool containing all the reflective data of the virtual machine itself,
such as meta-data of classes, objects (e.g pointers into the heap where objects are allocated) and method
objects. With Java VMs that use class data sharing, this generation is divided into read-only and read-write
areas.
Code Cache (non-heap): The HotSpot Java VM also includes a code cache, containing memory that is used
for compilation and storage of native code.
-XX:+DisableExplicitGC
Disable Sysytem.gc() which cause the Full GC to run and thus causing the JVM pauses.
-verbose:gc
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
This will print every GC details
-XX:NewRatio
The ratio between the young space and the old is set by this parameter. For example, -XX:NewRatio=2,
would make old generation 2 times bigger than the young generation (ratio between the young and tenured
generation is 1:2), or we can say that the young generation is 1/3rd the size of total heap size(young + old)
-XX:SurvivorRatio
This command line parameter sets the ratio between each survivor space and eden. For example,
-XX:SurvivorRatio=6 will make each survivor space one eighth of the young generation. (there are two survivor
space and 6 eden spaces in this case, hence 1/8)
-XX:NewSize=n
Sets the initial size of young generation, it should typically be 1/4th of total heap size. The bigger the young
generation, the less frequent the minor collection happens. (though for a bounded heap size, it may cause
more frequent major collections)
-XX:PermSize=n -XX:MaxPermSize=n
Sets the permanent generation size (non-heap) which stores Classes, methods and other metadata.
We should carefully design the object pool because they fool the garbage collector by keeping the live
reference to the unused objects, thus causing application to demand more memory.
2 http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#generation_sizing.young_gen.survivors
Chapter - Concepts Cracking the Core Java Interviews 20
• First decide the maximum heap size you can afford to give the virtual machine. Then plot your performance
metric against young generation sizes to find the best setting.
• Note that the maximum heap size should always be smaller than the amount of memory installed on
the machine, to avoid excessive page faults and thrashing.
• If the total heap size is fixed, increasing the young generation size requires reducing the tenured
generation size. Keep the tenured generation large enough to hold all the live data used by the application
at any given time, plus some amount of slack space (10-20% or more).
• Subject to the above constraint on the tenured generation:
• Grant plenty of memory to the young generation.
• Increase the young generation size as you increase the number of processors, since allocation can be
parallelized.
Notes
Question: We have a application which creates millions of temporary large StringBuilder Objects from
multiple threads. But none of such object is really required after extracting useful information from
them. Somehow we started facing frequent gc pauses. What could be the problem, and how would you
approach it?
Solution
Performance tuning GC may solve this problem to some extent. Let's first understand memory requirements
of this application. This application create lots of short lived objects - thus we would require a large young
generation for lowering the frequency of minor garbage collection. If our young generation is small, then the
short lived objects will be promoted to Tenured Generation and thus causing frequent major collection. This can
be addressed by setting appropriate value for -XX:NewSize parameter at the JVM startup.
We also need to adjust the survivor ratio so that the eden space is large compared to survivor space, large
value of Survivor ratio should help solve this problem.
We can also try increasing the Heap size if we have sufficient memory installed on our computer.
3 http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#generation_sizing.young_gen.survivors
Chapter - Concepts Cracking the Core Java Interviews 21
Question : What are the available tools to give the visual view of the different memory spaces in a
running JVM ?
There are lot of free tools available for troubleshooting memory related problem in a JVM. JConsole and
JVisualVM are two of them that come shipped with every JDK. Below is the screenshot of JVisualVM (with
Visual GC plugin) showing the visual representation of the different memory segments for a running JVM.
You can always profile an application and see the memory trends and customize the memory allocations
accordingly.
Chapter - Concepts Cracking the Core Java Interviews 22
Q 16. What is difference between Stack and Heap area of JVM Memory? What is
stored inside a stack and what goes into heap?
SOLUTION
The biggest difference between Heap and Stack section of memory is the lifecycle of the objects that reside in
these two memory locations
Memory of Stack Section is bound to a method context and is destroyed once a thread returns from the
function i.e. the Stack objects exists within the scope of the function they are created in.
On the other hand Heap objects exists outside the method scope and are available till GC recollects the
memory.
Java stores all objects in Heap weather they are created from within a method or class. Escape analysis can
be enabled in compiler to hint JVM to create method local objects in stack if the objects does not escape the
method context. All class level variables and references are also stored in heap so that they can be accessed
from anywhere. Metadata of classes, methods, etc also reside in Heap's PermGen space.
The Stack section of memory contains methods, local variables and reference variables and all os these are
cleared when a thread returns from the method call.
Question: An ArrayList is created inside a method, will it be allocated in Stack section or Heap section
of JVM Memory?
Answer : All Java Objects are created in Heap memory section, so the ArrayList will be created on the heap.
But the local reference (myList) will be created in the Stack section of memory. Once the method call is finished
and if myList variable is not escaped from this method then GC will collect the ArrayList object from heap.
As of JDK 1.6_14, escape analysis1 can be enabled by setting the appropriate JVM flag (java
-XX:+DoEscapeAnalysis) which hints the compiler to convert heap allocations to stack allocations if the method
local objects do not escape the method scope.
In the following code, if we enable the escape analysis, then the Object Foo may be created on Stack, resulting
in significant performance gain due to lesser GC activity.
1 http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html
Chapter - Concepts Cracking the Core Java Interviews 23
Q 17. What is a Binary Tree? Where and why is this used in Java Programs?
SOLUTION
Binary Tree is a tree data structure made up of nodes. Each node has utmost two children.
Why to prefer Binary Tree over any other linear data structure ?
Binary trees are a very good candidate (not the best) for storing data when faster search/retrieval is required
based on certain criteria. It does so by storing its elements in sorted order offering low time complexity for
retrieval operations compared to any other linear data structure. Any un-sorted collection can be inserted into
Binary Search Tree in O (n log n) time complexity. Though the insertion time is increased per element from
O(1) in Random Access array to O(log n) in Binary Search Tree, but we get a major advantage when we want
to search/retrieve a particular element from the tree data structure.
Worst-case Search time complexity is logarithmic in a balanced Binary Search Tree i.e. Binary tree cuts
down the problem size by half upon every subsequent iteration.
Red-black-tree is a height balanced binary tree where root is colored black and every other element is colored
either black or red with the following two rules,
1. If an element is colored red, none of its children can be colored red.
2. The number of black elements is the same in all paths from the root to the element with one child or with no
children.
It is useful for maintaining the order of elements in the collection based on the given comparator. It also provide
efficient mechanism to find the neighboring elements which are either big or small compared to given number,
because those numbers are stored physically closer in the data structure.
Interviewer's Intent - Algorithm & Data Structure, sorting, red black tree
TreeSet is a navigable set implementation based on TreeMap. All the elements are ordered using their Natural
ordering or by comparator provided at TreeSet construction time.
Chapter - Concepts Cracking the Core Java Interviews 24
NavigableSet provides us with methods like first(), last(), floor(), ceiling(), headSet(), tailSet() which can be
used to search the neighboring elements based on element's ordering.
TreeMap is Red-Black Binary Search Tree which guarantees logarithmic time for insertion, removal and
searching of an element. All the elements in this collection are stored in sorted order and the tree is height
balanced using Red black algorithm. If two elements are nearby in order, then TreeSet places them closely in
the data structure.
Uses
It is a best collection if we need to search the nearby elements of a given item based on their ordering.
Notes
• Note that this implementation is not synchronized. If multiple threads access a tree set concurrently, and at
least one of the threads modifies the set, it must be synchronized externally. This is typically accomplished
by synchronizing on some object that naturally encapsulates the set.
If no such object exists, the set should be "wrapped" using the Collections.synchronizedSortedSet method.
This is best done at creation time, to prevent accidental unsynchronized access to the set:
• If we are looking for high throughput in a multi-threaded application then we can prefer
ConcurrentSkipListSet which is scalable concurrent implementation of NavigableSet.
• Iterator returned by this class are fail-fast.
• TreeSet does not allow duplicates, it just replaces the old entry with the new one if both are equal (using
compareTo method)
• TreeSet does not preserve the insertion order of its elements.
• TreeSet provides guaranteed Big O (log n) time complexity for add(), remove() and contains() method.
Recursion is helpful in writing complex algorithms in easy to understand manner. But normally iterative
solutions provide better efficiency compared to recursive one because of so much overhead involved in
executing recursive steps.
For example, we would use the following code to calculate the Fibonacci series using recursion
Q 21. How many elements a complete binary tree could hold for a depth of 10?
SOLUTION
A binary tree is said to be complete if it is fully populated, so that each node has two child except the child
nodes.
HashMap is a hashing data structure which utilizes object's hashcode to place that object inside map. It
provides best case time complexity of O(1) for insertion and retrieval of an object. So it is a best suited data
structure where we want to store a key-value pair which later on can retrieved in minimum time.
HashMap is not a thread safe ADT, so we should provide necessary synchronization if used in multi-threaded
environment.
HashMap is basically an array of buckets where each bucket uses linked list to hold elements.
Initial Capacity
The default initial capacity of a hashmap is 16 (the number of buckets) and it is always expressed in power of
two (2,4,8,16, etc) reaching maximum of 1 << 30 (230)
In Java 1.7, A ConcurrentHashMap is a hashmap supporting full concurrency of retrieval via volatile reads of
segments and tables without locking, and adjustable expected concurrency for updates. All the operations
in this class are thread-safe, although the retrieval operations does not depend on locking mechanism
(non-blocking). And there is not any support for locking the entire table, in a way that prevents all access.
The allowed concurrency among update operations is guided by the optional concurrencyLevel constructor
argument (default is 16), which is used as a hint for internal sizing.
ConcurrentHashMap is similar in implementation to that of HashMap, with resizable array of hash buckets,
each consisting of List of HashEntry elements. Instead of a single collection lock, ConcurrentHashMap uses a
fixed pool of locks that form a partition over the collection of buckets.
HashEntry class takes advantage of final and volatile variables to reflect the changes to other threads without
acquiring the expensive lock for read operations.
The table inside ConcurrentHashMap is divided among Segments (which extends Reentrant Lock), each
of which itself is a concurrently readable hash table. Each segment requires uses single lock to consistently
update its elements flushing all the changes to main memory.
put() method holds the bucket lock for the duration of its execution and doesn't necessarily block other threads
from calling get() operations on the map. It firstly searches the appropriate hash chain for the given key and if
found, then it simply updates the volatile value field. Otherwise it creates a new HashEntry object and inserts it
at the head of the list.
Iterator returned by the ConcurrentHashMap is fail-safe but weakly consistent. keySet().iterator() returns
the iterator for the set of hash keys backed by the original map. The iterator is a "weakly consistent" iterator
that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed
upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to
construction.
Re-sizing happens dynamically inside the map whenever required in order to maintain an upper bound on hash
collision. Increase in number of buckets leads to rehashing the existing values. This is achieved by recursively
acquiring lock over each bucket and then rehashing the elements from each bucket to new larger hash table.
Notes
Question : Is this possible for 2 threads to update the ConcurrentHashMap at the same moment ?
Answer : Yes, its possible to have 2 parallel threads writing to the CHM at the same time, infact in the default
implementation of CHM, at most 16 threads can write and read in parallel. But in worst case if the two objects
lie in the same segment, then parallel write would not be possible.
Chapter - Concepts Cracking the Core Java Interviews 28
Question: Can two threads read simultaneously from the same segment in ConcurrentHashMap ?
Answer: Segments maintain table of entry list that are always kept in consistent state, thus many threads
can read from the same Segment in parallel via volatile read access. Even the updates operations (put and
remove) may overlap with the retrieval operation without any blocking happening.
Q 24. Why do we need Reader Classes when we already have Streams Classes? What
are the benefit of using a Reader over a stream, in what scenario one should be pre-
ferred.
SOLUTION
InputStream and OutputStream operates at byte level (also called byte streams) while Reader and Writer
classes operates at the character level (char streams). Reader class is essentially a wrapper over InputStream
where it delegates the I/O related work to the byte stream and performs the translation of byte to character
using the given character encoding and character set. So Reader class provides a easy mechanism to the
developer to deal with the Character stream with an option to deal with different CharacterSets.
It is possible to convert byte stream to a character stream using InputStreamReader and OutputStreamWriter.
static void writeOutput(String str) {
try {
FileOutputStream fos = new FileOutputStream("test.txt");
Writer out = new OutputStreamWriter(fos, "UTF8");
out.write(str);
out.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
Chapter - Concepts Cracking the Core Java Interviews 29
Q 25. Discuss Visitor, Template, Decorator, Strategy, Observer and Facade Design
Patterns?
SOLUTION
Similarly
Calculating taxes in different regions on sets of invoices would require many different variations of calculation
logic. Implementing a visitor allows the logic to be de-coupled from the invoices and line items. This allows
the hierarchy of items to be visited by calculation code that can then apply the proper rates for the region.
Changing regions is as simple as substituting a different visitor.
continued on 30
Chapter - Concepts Cracking the Core Java Interviews 30
@Override
public void visit(Employee emp) {
System.out.println(emp.getName());
}
}
@Override
public void accept(EmployeeVisitor visitor){
for (Employee employee : employees) {
visitor.visit(employee);
}
}
continued on 31
Chapter - Concepts Cracking the Core Java Interviews 31
Context Strategy
<<Interface>>
ConcreteStrategyA ConcreteStrategyB
<<Implementation>> <<Implementation>>
Another good example of facade design pattern could be : exposing a set of functionalities using web services
(SOA architecture). Client does not need to worry about the complex dependencies of the underlying system
after building such API.
Q 26. What is a strong, soft, weak and Phantom reference in Java? Where are these
used?
SOLUTION
Interviewer's Intent - wants to know your understanding for GC, automatic memory allocation and de-allocation.
SoftReference, WeakReference & PhantomReference are are reference-object classes, which supports limited
degree of interaction with the GC. A programmer may use these classes to maintain a reference to some other
object (referent) in such a way that the object may still be reclaimed by GC.
Reference Queues
Reference queue is used to track the objects claimed by GC. We can use the reference objects to check
whether the objects referred by these are still active or are claimed by GC.
SoftReference
If the strongest reference to an object is a soft reference then GC will not reclaim the object until the JVM is
falling short of memory, though it must be reclaimed before throwing an Out Of Memory Error. So the object will
stay longer than a weakly referenced object. It is mostly used for writing memory sensitive caches.
WeakReference
Is similar to soft reference with the only difference that it will be GC'ed in the next GC cycle if the strongest
reference to the object is a weak reference. When a weak reference has been created with an associated
reference queue and the referent becomes a candidate for GC, the reference object (not the referent) is
enqueued on the reference queue after the reference is cleared. The application can then retrieve the
reference from the reference queue and learn that the referent has been collected so it can perform associated
cleanup activities, such as expunging the entries for objects that have fallen out of a
weak collection. continued on 32
Chapter - Concepts Cracking the Core Java Interviews 32
WeakHashMap
It is a HashMap that store its keys (not values) using WeakReferences. An entry in this map is automatically
removed when there is no other non-weak references to keys. This collection can be used to store associative
objects like transient object & its metadata, as soon as the object is claimed by the GC, the associated
metadata will also be removed by the map. Other application could be in a servlet environment where as soon
as the session expire's, clear all the session data/attributes.
PhantomReference
PhantomReference are garbage collected when the strongest reference to an object is a phantom. When an
object is phantomly reachable, the object is already finalized but not yet reclaimed, so the GC enqueues it in
a reference queue for post finalization processing. A Phantom Reference is not automatically cleared when it
is enqueued., so we must remember to call its clear() method or to allow phantom reference object itself to be
garbage collected. get() method always return null so as not to allow resurrect the referent object.
Phantom references are safe way to know an object has been removed from memory and could be thought of
as a substitute for finalize() method.
Automatically-cleared references
Soft and weak references are automatically cleared by the collector before being added to the queues with
which they are registered, if any. Therefore soft and weak references need not be registered with a queue
in order to be useful, while phantom references do. An object that is reachable via phantom references will
remain so until all such references are cleared or themselves become unreachable.
Reachability levels from strongest to weakest : strong, soft, weak, phantom. Java 6 docs states that -
• An object is strongly reachable if it can be reached by some thread without traversing any reference
objects. A newly-created object is strongly reachable by the thread that created it.
• An object is softly reachable if it is not strongly reachable but can be reached by traversing a soft reference.
• An object is weakly reachable if it is neither strongly nor softly reachable but can be reached by traversing
a weak reference. When the weak references to a weakly-reachable object are cleared, the object
becomes eligible for finalization.
• An object is phantom reachable if it is neither strongly, softly, nor weakly reachable, it has been finalized,
and some phantom reference refers to it.
• Finally, an object is unreachable, and therefore eligible for reclamation, when it is not reachable in any of
the above ways.
Notes
WeakHashMap is not a solution for implementing cache, SoftReference's could be better utilized for
implementing cache.
Applications of a WeakHashMap
WeakHashMap stores its keys using WeakReference, and can be used to map transient objects with their
metadata. Let's suppose we have a socket application which creates sockets on client's request and socket
lives there for sometime. Now if we want to associate some metadata with this socket such as identity of
the user, then WeakHashMap is a ideal container for storing such associative information. Since we are not
managing the lifecycle of the socket in this case, WeakHashMap will automatically remove all the metadata as
soon as the socket dies.
Applications of SoftReference
Soft references can be used to build memory sensitive cache which automatically collects items as soon as the
cache is under high memory load, which otherwise has to be achieved by the programmer.
Chapter - Concepts Cracking the Core Java Interviews 33
Let's first get familiar with the most common problems occurring in concurrent database applications, for
example
Dirty Read
Occurs when uncommitted results of one transaction are made visible to another transaction.
Unrepeatable Reads
Occurs when the subsequent reads of same data by a transaction results in seeing different values.
Phantom Reads
One transaction performs a query returning multiple rows, and later executing the same query again sees
some additional rows that were not present the first time.
We also call above three as Isolation Hazards, and the Transaction Isolation levels are related to these three
problems.
Isolation Level Dirty read Unrepeatable read Phantom read
Read Uncommitted Yes Yes Yes
Read Committed No Yes Yes
Repeatable Read No No Yes
Serializable No No No
For most of databases, the default Transaction Isolation Level is Read Committed.
(Read Committed does not see any inconsistent state of other transaction, with a fair amount of concurrency)
Please be noted that the above four isolation levels are in decreasing order of their concurrency. So for
scalability reasons, Serializable is rarely a good choice of design, as it offers only a single thread to work at a
given time.
Differences
1. The main purpose of a Primary key is to uniquely identifies a given record in a Table, while the same is not
true for Unique Key constraint.
2. A table can have one and only one Primary Key, while there could be multiple unique keys inside a single
table.
3. Primary Key can not have Null values while Unique key column can contain a Null value
4. Primary key creates the Clustered index, but unique key creates the Non clustered index.
Chapter - Concepts Cracking the Core Java Interviews 34
Clustered Index
Clustered index physically rearrange the data that users inserts in your tables. It is nothing but a dictionary
type data where actual data remains. And thus the physical order of the rows is the same as the logical order
(indexed order). This type of index is often build over the Primary Key of a table
Non-Clustered Index
Non-Clustered Index contains pointers to the data that is stored in the data page. It is a kind of index backside
of the book where you see only the reference of a kind of data.
Clustered index usually provides faster data retrieval than the non-clustered index. Moreover clustered indexes
provides faster access to the contiguous rows because those rows are present physically adjacent in the actual
table.
References
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.ase_15.0.sqlug/html/sqlug/sqlug537.htm
http://en.wikipedia.org/wiki/Database_index#Types_of_indexes
Q 30. How would you handle lazily loaded entities in web application development us-
ing hibernate?
SOLUTION
There are two main approaches to handle problem of initializing lazily loaded objects.
1. Hibernate.initialize(<entity>) - this static factory method will Force initialization of a proxy or persistent
collection. This method should only be called inside the transaction otherwise it will throw exception. If we
are using Spring then we can write something like this
@Override
@Transactional(readOnly = false)
public TaskData findById(long id) {
TaskData taskData = taskDao.findById(id);
if (taskData != null) {
Hibernate.initialize(taskData.getTodoResources()); //TodoResources is lazy loaded object in TaskData entity
}
return taskData;
}
2. Incase of web applications, you can declare a special filter in web.xml, it will open session per request
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Depending upon the requirements, you can choose the best suited approach for your project.
Chapter - Concepts Cracking the Core Java Interviews 35
When mapping entities with each other, we describe the relation among entities using OneToOne, OneToMany,
ManyToOne or ManyToMany mappings.
OneToOne
A Person has a PAN (Card) is a perfect example of One To One association.
Unidirectional - Person can refer to PAN entity
Bidirectional - PAN entity can refer back to Person
@Entity
public class Person {
@Id private int id;
@OneToOne
@JoinColumn(name="PAN_ID")
private PAN pan;
// ...
}
@Entity
public class PAN {
@Id private int id;
@OneToOne(mappedBy="pan")
private Person person;
// ...
}
OneToMany
A Person has many Skill(s), But a skill can not be shared among Person(s). A Skill can belong to utmost One
Person. One more example could be relationship between Employee and Department where an Department is
associated with Collection of Employee(s)
Unidirectional - A Department can directly reference Employee(s) by collection
Bidirectional - Each Employee has a reference back to Department
@Entity
public class Employee {
@Id private int id;
@ManyToOne
@JoinColumn(name="DEPT_ID")
private Department department;
// ...
}
@Entity
public class Department {
@Id private int id;
@OneToMany(mappedBy="department")
private Collection<Employee> employees;
// ...
}
Employee Table would keep DEPT_ID foreign key in its table, thus making it possible to refer back to Dept.
Chapter - Concepts Cracking the Core Java Interviews 36
ManyToMany
One Person Has Many Skills, a Skill is reused between Person(s). One more example of this could be
relationship between Employee and Project. Each employee can work on multiple Project(s) and each Project
can be worked upon by multiple Employee(s). One more example could be relationship between Customer(s)
and Product(s) where One or More Customer(s) purchase many different Product(s) and Product(s) can be
purchased by different Customer(s)
Unidirectional - A Project can directly reference its Employee(s) by collection
Bidirectional - An Employee has Collection of Projects that it relates to.
@Entity
public class Employee {
@Id private int id;
@ManyToMany
private Collection<Project> projects;
// ...
}
@Entity
public class Project {
@Id private int id;
@ManyToMany(mappedBy="projects")
private Collection<Employee> employees;
// ...
}
Association or junction table is must to implement a ManyToMany relationship, this separate table connects
one line from Employee to one line from Poject using foreign keys. And each primary key of Employee and
Project can be copied over multiple times to this table.
Q 32. How would you implement ManyToMany mappings with the self entity in JPA?
SOLUTION
We need to maintain two different mappings in the same entity for ManyToMany relationship as shown below -
@ManyToMany
@JoinTable(name="table_friends", joinColumns=@JoinColumn(name="personId"),
inverseJoinColumns=@JoinColumn(name="friendId"))
private Set<User> friends;
@ManyToMany
@JoinTable(name="table_friends", joinColumns=@JoinColumn(name="friendId"),
inverseJoinColumns=@JoinColumn(name="personId"))
private Set<User> friendOf;
In the above Bidirectional Mapping, One side of relationship will maintain the User's list of friends (friends), and
the inverse side of relationship will maintain how many people have this User in their friend list (friendOf).
@ManyToMany(mappedBy="friends")
private Set<User> friendOf = new HashSet<User>();
Chapter - Concepts Cracking the Core Java Interviews 37
Q 33. What is Inner Join, Left Outer Join and Right Outer Join?
SOLUTION
INNER JOIN
This is the most common and the default join operation. This join creates a resultset by combining the column
values of two tables (L and R) based upon the predicate. Each row of L (left table) is compared with each row
of R (right table) to find all pairs of rows that satisfy the join predicates. When the join-predicate is satisfied,
column values for each matched pair of rows of L and R are combined into a result row.
Example query is shown below.
SELECT *
FROM employee INNER JOIN department
ON employee.DepartmentID = department.DepartmentID;
SELECT *
FROM employee, department
WHERE employee.DepartmentID = department.DepartmentID;
OUTER JOIN
An outer join does not require each record in the two joined tables to have a matching record. The joined table
retains each record—even if no other matching record exists.
SELECT *
FROM employee LEFT OUTER JOIN department
ON employee.DepartmentID = department.DepartmentID;
SELECT *
FROM employee RIGHT OUTER JOIN department
ON employee.DepartmentID = department.DepartmentID;
References
http://en.wikipedia.org/wiki/Join_(SQL)
Chapter - Concepts Cracking the Core Java Interviews 38
Q 34. How will you list all the Customers from Customer Table who have no Order(s)
yet?
SOLUTION
We can use Left Join in the SQL query to list all the Customer(s) which have Null Order and put a where
clause to eliminate the rows where Order is not Null, for example
Though there could be many other ways to fetch the same information from the database.
select * from Customer c where c.id not in (select o.c_id from Order o)
Q 35. How would you fetch Employee with nth highest Age from Employee Table us-
ing SQL?
SOLUTION
Each row of Employee needs to be compared to very other row to fetch the above mentioned details, thus the
Time Complexity of this operation would be quite high (O (n2))
SELECT *
FROM Employee E1
WHERE (N-1) = (SELECT COUNT(DISTINCT(E2.Age))
FROM Employee E2
WHERE E2.Age > E1.Age)
SELECT *
FROM Employee E1
WHERE (2-1) = (SELECT COUNT(DISTINCT(E2.Age))
FROM Employee E2
WHERE E2.Age > E1.Age)
Q 36. Question: What is difference between Drop, Truncate and Delete Table com-
mands in SQL?
SOLUTION
Delete is used to delete rows from a table with optional where clause, we need to commit or rollback after
calling this operation. This operation will cause all DELETE triggers to be fired on the table.
DELETE FROM Employee WHERE age < 14;
Truncate removes all rows from table, this operation can not be rolled back and no triggers are fired, thus it is
faster in performance as well.
Truncate Table Employee;
Drop command will remove a table from the schema, all data rows, indexes, privileges will be removed, no
triggers will be fired and no rollback.
Drop Table Employee;
Chapter - Concepts Cracking the Core Java Interviews 39
JPA defines three inheritance strategies namely, SINGLE_TABLE, TABLE_PER_CLASS and JOINED.
Single table inheritance is default, and table per class is optional so all JPA vendors may not support it.
JPA also defines mapped super class concept defined through the @MappedSuperClass annotation. A
Mapped Super Class is not a persistent class, but allows a common persistable mapping to be defined for its
subclasses.
Single Table Inheritance
In this inheritance, a single table is used to store all the instances of the entire inheritance hierarchy. The Table
will have a column for every attribute of every class in the hierarchy. Discriminator columns identifies which
class a particular row belongs.
Joined Table
This inheritance replicates the object model into data model. A table is created for each class in the hierarchy
to store only the local attributes of that class.
Question - We want to extract common behavior in a super class in JPA entities but we do not want to
have table for that super class. How would you achieve this ?
Answer - If we create a normal class as the super class, then as per JPA specifications, the fields for that class
are not persisted in the database tables. We need to create a super class extracting the common fields and
then annotate that class with @MappedSuperClass in order to persist the fields of that super class in subclass
tables. A mapped super class has no separate table defined for it.
References
http://en.wikibooks.org/wiki/Java_Persistence/Inheritance
Q 38. How will you handle Concurrent Updates to an database entity in JPA i.e. when
two users try to update the same entity in parallel?
SOLUTION
There are two main approaches to handle transaction concurrency using JPA 2.01
1. Optimistic Concurrency (Scalable Option) - This approach is as simple as adding a version column to
the database entity, as shown in the below code. When version column is present, JPA will increment
the version field for us upon every update to the row. Thus when two detached entities with the same
version try to update the database, one will fail (throws OptimisticLockException) because of mismatch
in version column value. This approach offer higher concurrency throughput compared to Pessimistic
Locking, because it does not serializes the thread access. This approach will work even for the detached
entities where a single database row was read in parallel by two threads, and later point in time these two
threads try to update the contents of detached database entities. This approach gives best performance for
applications with very less contention among the concurrent transactions.
2. Pessimistic Concurrency (badly-scalable) - In this approach, JPA will lock the database row (not object
in memory) when the data is read, and releases the lock upon completion of transaction. This way only
one database transaction can update the same entity at same time. In Oracle database, it's similar to the
following SQL statement -
Pessimistic approach works best for applications where contention ratio is high among the concurrent
transactions, otherwise it is a badly scalable option for handling concurrency.
Forward
1. Control is forwarded to the resource available within the server from where the call is made, the transfer of
control is made internally by the container, where client is completely unaware that a forward is happening.
2. When forward is done, the original request and response objects are transferred along with the additional
parameters if needed.
3. Forward can't transfer control to some other domain.
4. Original URL at the client side remains intact, hence refreshing the page will cause the whole step to repeat
again.
5. Session object is not lost in forward or redirect.
Redirect
1. A redirect is a two step process where web application instructs the browser client to fetch the fetch the
second URL which differs from the original.
2. Server sends Http Status Code of 301 to the client, and then client follows the instructions.
3. If someone reloads the page on browser, then original request will not be repeated. Just the second url will
be fetched again.
4. Redirect is marginally slower than forward, since it requires two requests.
5. Objects placed in request scope are not available to second request.
6. There are several ways to perform a redirect for example,
For example, database update and data display can be separated by redirect. In this case if user presses F5
button the browser then only display part will execute again and not the database update part.
Do the PaymentProcess and then redirect to the display payment info, if the client refreshes the browser, only
the displayInfo will be done again and not the payment process.
Chapter 2
Core Java
Method Signature
Method name, plus the number and type of its parameters constitute the method signature. Return type is not
part of method signatures.
Hiding Variables
Overriding works for Instance methods, In case of Class methods If a subclass defines a class method
with the same signature as a class method in super class, the method in subclass hides the one is
super class.
1 SCJP Sun® Certified Programmer for Java™ 6 Study Guide Exam (310-065) Page 106
2 http://docs.oracle.com/javase/tutorial/java/IandI/override.html
Chapter - Core Java Cracking the Core Java Interviews 42
Similarly variable names are never overridden by the sub class, but they can be hide. If the super class
contains a variable named x and subclass also contains x (irrespective of the type of variable) then the
subclass variable hides the super class variable. Remember that all non-private super class variable can
always be referenced by the subclass using super.variable.
In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods
neither hide nor override the superclass methods—they are new methods, unique to the subclass.
Notes
Question : What are different Access Levels in Java ?
Answer : Access Levels available in Java are mentioned in the below table
Constructors are called from the top to down hierarchy. For example as shown in the below code snippet, A is
super class of B. Creating a instance of new B() will invoke B's constructor which will in-turn call super() and
this constructor of A will get invoked. Call to super() is inserted by the compiler on our behalf and is not visible
to us. So instance of A will be created first, and if the constructor of A contains any method which is overridden
in sub class, the subclass version will be invoked except for the static method calls.
Compiler introduces the call to super() only if the default no-arg constructor is present in the super class, otherwise
its responsibility of the programmer to introduce such call with proper constructor arguments.
Java Source
class A {
A() {
greeting();
prints();
}
void greeting() {
System.out.println("instance method from A");
}
static void prints() {
System.out.println("Static method from A");
}
}
class B extends A {
B() {
greeting();
Chapter - Core Java Cracking the Core Java Interviews 43
prints();
}
void greeting() {
System.out.println("instance method from B");
}
static void prints() {
System.out.println("Static method from B");
}
}
Program Output
instance method from B
Static method from A
instance method from B
Static method from B
Q 42. When should we choose Array, ArrayList, LinkedList over one another for a
given Scenario and Why?
SOLUTION
LinkedList (Doubly-linked list) and ArrayList (Resizable-array) both are two different implementations of List
Interface.
LinkedList
LinkedList provides constant-time (Big O(1)) methods for insertion and removal using Iterators. But the
methods to find the elements have Big O(n) time complexity (Linear Time, proportional to the size of list)
and thus are poor performing. LinkedList has more memory overhead because it needs two nodes for each
element which point to previous and next element in the LinkedList. If you are looking for random access of
elements then ArrayList is the way to go for.
ArrayList
ArrayList on the other hand allows Big O(1) time complexity (constant time) for read/update methods. If
position of the element is known then it can be grabbed in constant time using get(index) operation. But adding
or removing elements from ArrayList (other than at end) requires shifting elements, either to make a new
space for the element or for filling up the gap. Thus if frequent insertions and removals are required by your
application logic then ArrayList will perform poorly (roughly Linear Time Big O(n)). The size, isEmpty, get, set,
iterator, and listIterator operations run in constant time. Also if more elements are needed than the capacity of
the ArrayList then a new underlying array with twice the capacity if created and the old array is copied to the
new one which is time consuming operation (roughly Big O(n)). To avoid higher cost of resizing operation, we
should always assign a appropriate initial capacity to the ArrayList at the time of construction.
Array
Array is a fixed size primitive collection which can hold primitive or Objects. Array itself is a object and memory
for array object is allocated on the Heap. Array does not provide useful collections methods like add(), addAll(),
remove, iterator etc.
We should choose array only when the size of input is fixed and known in advance and underlying elements
are of primitive type.
Chapter - Core Java Cracking the Core Java Interviews 44
public class A {
void add() {System.out.println("Add A");}
}
class B extends A {
void add() {System.out.println("Add B");}
}
class C extends B {
void add() {
System.out.println("Add C");
}
Now its possible for B and C to call their super class's add() method by using super.add() call.
But the interviewer is asking us to invoke A's add() method from Class C, which is not possible because it
violates the OOPs concept in Java. Java does not support multiple inheritance, that means C can see only a
single super class which will have just one add() method implementation. C can never see A's add() method
because otherwise how would it know which add() method to invoke - B's or A's
We also call this scenario as the Diamond Problem of Multiple Inheritance in case of C++.
The only way it is possible to invoke A's add() method from Class C is if Class B calls super.add() method in its
add() implementation as shown below.
class B extends A {
void add() {super.add();}
}
Chapter - Core Java Cracking the Core Java Interviews 45
Q 44. Why wait is always used inside while loop as shown in the below snippet ? Dis-
cuss all the probable reasons.
public synchronized void put(T element) throws InterruptedException {
while(queue.size() == capacity) {
wait();
}
queue.add(element);
notify();
}
SOLUTION
There are two main reasons that force use to use wait() method inside a while loop1.
Spurious WakeUp2
In certain rare scenarios, a thread can wakeup without any reason even when no other thread signaled the
condition. To gracefully handle those scenarios, we must recheck for the required condition before proceeding
to execute the rest of the condition dependent code.
Replacing if condition with a while loop can solve this problem without much effort. While loop will force each
resuming thread to test the condition on wakeup, and putting the thread to waiting state again if required
condition is not met.
So always remember to use wait() method from inside the while loop testing the condition that caused the
thread to awaken, as shown below.
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}
1 see Section 3.2.3 in Doug Lea's "Concurrent Programming in Java (Second Edition)" , or Item 50 in Joshua Bloch's "Effective
Java Programming Language Guide" (Addison-Wesley, 2001)
2 http://en.wikipedia.org/wiki/Spurious_wakeup
Chapter - Core Java Cracking the Core Java Interviews 46
Q 45. We have a method which iterates over a Collection. We want to remove certain
elements from that collection inside the loop in certain criteria is matched, How should
we code this scenario ?
SOLUTION
Intent here is to check if you are aware of technique of modifying the collection structure while iterating over it.
If we call collection.remove() from within the for loop then ConcurrentModificationException will be thrown by
the JVM at runtime.
import java.util.ArrayList;
import java.util.List;
Actually, the right way to handle such scenario is to use Iterator to remove the element from the underlying
Collection while iterating over it. ConcurrentModificationException is thrown because the for loop internally
creates a fail-fast iterator which throws exception whenever it finds any structural modification in the underlying
data structure (ArrayList in this case).
The correct implementation for removal method would look something like,
This question is based on the fundamentals explored in the last question. If we try to modify a Collection inside
a for loop without using an explicit Iterator then ConcurrentModicifactionException is thrown. So will not repeat
the same wrong code in this solution.
Unfortunately Iterator does not provide any add() method in its interface, so it would be hard to use Iterator in
this API to structurally modify the data structure. We are left with two options here -
1.) Use ListIterator's add() method which works only for LinkedList as the underlying data structure rather than
any Collection.
2.) Create another List and add stuff to that while we iterate over the input collection, and in the end append all
elements of this newly created List to the original Collection.
Q 47. If hashcode() method of an object always returns 0 then what will be the impact
?
SOLUTION
Hashcode is used to fairly distribute elements inside a map into individual buckets. If the hashcode returned
is zero for each element then the distribution will no more be fair and all the elements will end up into a single
bucket. Each bucket in a HashMap contains list of HashEntry objects, so in a way HashMap will act as a map
with single bucket holding all of its elements in a list. That will drastically reduce HashMap's performance to
that of a LinkedList for get and put operations.
So time complexity of get and put method will become : Big O(n) instead of Big O(1)
Although, functionally it will still behave correctly.
Chapter - Core Java Cracking the Core Java Interviews 48
Q 48. Iterator interface provides remove() method but no add() method. What could be
the reason ?
SOLUTION
Iterator interface contains three methods namely remove(), hasNext() and next().
It intentionally does not provide any add() method because it should not !
Iterator does not know much about the underlying collection. Underlying collection could be of any type (Set,
ArrayList, LinkedList, etc) and might be offering the guaranteed ordering of its elements based on some
algorithm. For example TreeSet maintains the order of its element using Red Black Tree datastructure. Now
if iterator tries to add an element at a given location, then it might corrupt the state of the underlying data
structure. And that is not the case while removing elements.
Thus Iterator does not provide any add() method.
List Iterator does provide the add() method because it know the location where it needs to add the newly
created element as List preserves the order of its elements.
Q 50. If we don't override hashcode() while using a object in hashing collection, what
will be the impact ?
SOLUTION
Then the Object's default hashcode() method will be used to calculate the hashcode, which in turn will return
the memory address of the object in hexadecimal format. So in a way the hashmap will behave like a identity
hashmap which will consider two elements equal if and only if two objects are same as per their memory
address (and not logically). For example two String Objects with same contents might be treated different by
this hashmap if they are different on heap.
Deadlock occurs in software program due to circular dependencies on shared resources by multiple threads.
This causes the partial or complete hanging of the software program and the program itself can not recover
from the dead lock situation. But still its possible using multiple ways to detect the Dead Lock in a running JVM.
1. Using Jconsole - JDK installation ships with jconsole tool which can connect to a running java process
using JMX protocol. Jconsole can tell us whether there is a dead lock in the program or not.
2. Using JMX Management package as shown below
This will list down the thread ids for the troubleshooting purpose.
DeadLock happens in multi-threaded scenario when two more threads have mutual dependencies on two or
more shared resources. Let's understand with the following code,
In the above code, two threads operate over two shared Resources r1 and r2. Resource class has two
synchronized methods (which will require the threads to obtain lock over the instance) and unfortunately r1
has a inter-dependency on r2. There is a great probability that the above code will block for ever causing a
deadlock.
Using jconsole we can detect the deadlock, below is the message shown in jconsole for this java process
Name: Thread-1
State: BLOCKED on org.shunya.power.interview.DeadLock$Resource@354949 owned by: Thread-0
Total blocked: 2 Total waited: 1
Name: Thread-0
State: BLOCKED on org.shunya.power.interview.DeadLock$Resource@661a11 owned by: Thread-1
Total blocked: 1 Total waited: 1
Chapter - Core Java Cracking the Core Java Interviews 51
Q 54. Which data type would you choose for storing currency values like Trading
Price ? What's your opinion about Float, Double and BigDecimal ?
SOLUTION
Float & Double are Bad for financial world, never use them for monetary calculations.
• All floating point values that can represent a currency amount (in dollars and cents) can not be stored
exactly as it is in the memory. So if we want to store 0.1 dollar (10 cents), float/double can not store it as it
is. Let's try to understand this fact by taking this simple example
• There is not much flexibility provided by Math.round() method for rounding the given calculation result
compared to functionality offered by MathContext. RoundingMode provides options such as ROUND_UP,
ROUND_DOWN, ROUND_CEILING, ROUND_FLOOR, ROUND_UNNECESSARY, etc
That's the reason we should always prefer BigDecimal or BigInteger for financial calculations.
Notes
Primitive type - int and long are also useful for monetary calculations if decimal precision is not required
We should really avoid using BigDecimal(double value) constructor instead prefer BigDecimal(String) because
BigDecimal (0.1) results in 0.100000...5..3 being stored in BigDecimal instance. In contrast BigDecimal ("0.1")
stores exactly 0.1
How to format BigDecimal Value without getting exponentiation in the result & Strip the trailing zeros?
We might get exponentiations in the calculation result if we do not follow some best practices while using
Bigdecimal. Below is the code snippet which shows a good usage example of handling the calculation result
using Bigdecimal.
How would you print a given currency value for Indian Locale (INR Currency)?
NumberFormat class is designed specifically for this purpose. Currency symbol & Rounding Mode is
automatically set based on the locale using NumberFormat. Lets see this example
Output
tempBig = Rs.22.12
Some precautions
Q 55. How would you round a double value to certain decimal Precision and Scale ?
SOLUTION
No one wants to loose the precision of the number as it will change the value by large amount. If you still want
to loose the precision simply divide the number by 10 to the power precision.
There are multiple ways in Java to round the double value to certain scale, as mentioned in the below example
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
The first method of rounding using BigDecimal should be preferred in most scenarios.
Chapter - Core Java Cracking the Core Java Interviews 54
Q 56. How great is the Idea of synchronizing the getter methods of a shared mutable
state ? What if we don't ?
SOLUTION
Synchronization serves two major purposes in a multi-threaded scenario, one is atomicity of the operation and
second is the memory visibility of the changes made by one thread to all other threads (Brian Goetz article on
read and write barriers)1. In case of getters the changes made to the shared variable will get reflected to the
new thread if the code block is synchronized, otherwise dirty reads may happen and the thread may see the
stale state of the shared object.
So all the methods returning the mutable protected state of the shared object must be synchronized unless the
field returned is immutable, final or volatile.
That's the reason that get() method of vector class is synchronized & must be synchronized.
Interviewer's intent is to know how good you know about Hashing Data Structure
The answer is NO. If we make the keys mutable then the hashcode() of the key will no more be consistent over
time which will cause lookup failure for that object from the data structure. Let's analyze this example.
From the above example we see that as soon as we change the key, we are not able to get the associated
object from the Map.
Never make changes to the hashmap's key, otherwise the associated object can not be fetched using get()
method. Though it will be accessible using other methods which iterate over the entire collection.
We should synchronize the code block doing any kind of iteration as stated by the Java Docs
Returns a synchronized (thread-safe) collection backed by the specified collection. In order to guarantee serial
access, it is critical that all access to the backing collection is accomplished through the returned collection.
It is imperative that the user manually synchronize on the returned collection when iterating over it:
Collection c = Collections.synchronizedCollection(myCollection);
...
synchronized (c) {
Iterator i = c.iterator(); // Must be in the synchronized block
while (i.hasNext())
foo(i.next());
}
Q 59. What are different type of Inner classes in Java ? How to choose a type with
example ?
SOLUTION
An inner class is a class defined within another class, or even within an expression. They are mostly used to
simply our code by putting closely related classes together in one source file, instead creating class burst.
Event handlers are best examples of Inner Classes.
Notes
Question : Why do we need to declare a local variable final if inner class declare within a method needs
to use it?
Local variables always live on the stack, the moment method is over all local variables are gone. Inner class
objects might be on heap even after the method is over, so in that case it would not be able to access the local
variable, since they are gone. There is also a possibility that the variable could change before the inner class
accesses it. Making the local variable final prevents these scenarios.
Q 60. When should we need a static inner class rather than creating a top level class
in Java Program?
SOLUTION
A static Class interacts with the instance members of its outer class and other classes just like any top level
class. In fact, a static nested class is behaviorally a top level class that has been nested in another top level
class for packaging convenience.
If we take a example of LinkedList.Entry class, there is no need of it being a top level class as it is only used by
LinkedList. Otherwise it will cause class burst inside a package, moreover there are other static inner classes
by the same name as well like Map.Entry
And since these does need access to LinkedList/Map's internal so it makes sense to make them static inner
classes.
Why to use it ?
1. It is a way of logically grouping the classes that are only used in one place. If a class is useful to only one
other class, then it is logical to embed it in that class and keep the two together.
2. It increases encapsulation.
3. Nested classes can lead to more readable and maintainable code. Nesting small classes within top-level
classes places the code closer to where it is used.
Examples
Iterator in most of the collection types are implemented as a inner class and Entry is implemented as static
inner class.
Chapter - Core Java Cracking the Core Java Interviews 57
For knowing the exact answer you must be knowing how Parameter Passing works in Java.
The called method can't change the caller's variable, although for object reference variables, the called
method can change the object the variable referred to.
The only way to have this possible was using some kind of setter on Integer class which could have modified
the underlying value. But Java declares all Wrapper classes as Immutable for thread-safety perspective, thus
there is no way to swap Integers in Java.
Only hashing data structures uses hashcode() method along with equals() method, though the equals() is used
by almost every class.
hashcode is useful for creating hashing based datastructures like HashMap, LinkedHashMap,
ConcurrentHashMap, HashSet. (Basically any Java collection that has Hash inside the name of it)
Hashcode is used to provide best case O(1) time complexity for searching the stored element.
TreeMap, TreeSet uses Comparator/Comparable for comparing the elements against each other, so these data
structures do not require hashcode() method. The best case time complexity offered by these datastructures
for lookup operation is logarithmic rather than constant.
Chapter - Core Java Cracking the Core Java Interviews 58
Collections framework contains two main Interfaces Collection and Map. Collection is further extended by List,
Set and Queue Interface.
Iterable Map
Collection SortedMap
SortedSet Deque
NavigableSet
Java Collections Framework Overview
There is a separate utility class named Collections which provides various static factory methods for playing
with collections (Algorithm Part)
There are multitude Implementations provided for the above mentioned interfaces, few implementations
implements more than one such Interface.
Set - A collection that does not allow duplicate elements (models mathematical set abstraction) and represents
entities such as courses making up of student's schedule, ISBN number of books, Social security Number,
PAN number, processes running on a machine, etc
List - A collection that maintains order of its elements. Lists can contain duplicate elements. ListIterator
provides precise control over where to add the new item to the collection.
Queue - Queue is a First In First Out data structure which maintains order of its original elements. Most List
implementations like LinkedList implements Queue interface as well.
Chapter - Core Java Cracking the Core Java Interviews 59
Q 64. What is Immutable Class. Why would you choose it ? How would you make a
class immutable ?
SOLUTION
Why do we need it
Immutable objects are inherently thread-safe, thus help writing multi-threading code without much worries.
Immutable questions are meant for multi-threading program. If someone is talking bout immutability then
indirectly he is talking about multi-threaded context. Immutable classes are easy to understand, as they
possess a single state, which is controlled by their constructor. Immutable objects are good candidate for hash
keys because their hashcode can be cached and reused for better performance.
Q 65. Why shouldn't we prefer mutable static variables in our Java Code ?
SOLUTION
Using mutable static variables might introduce Bugs in your software at some point in time
• Problem sharing a mutable static variable in multi-threaded environment. It's very tough to write & maintain
a thread safe code with Mutable non-private static fields.
• Problem in Single Threaded design because we have to be very careful while updating static variable,
since the next bit of code might expect some other state for the same.
• Code that relies on static objects can’t be easily unit tested, and statics can’t be easily mocked and hence
does not promote TDD.
- If you are using static keyword without final for declaring a fields then you should reconsider your design,
since the mutable static fields can be just dangerous !!
Q 66. Discuss Exception class hierarchy in Java. When should we extend our custom
exception from RuntimeException or Exception ?
SOLUTION
Checked Exceptions Represents exceptional scenario which if occurred, must dealt with in some way.
example is IOException, FileNotFoundException. We need to declare these exceptions along with the code
dealing with such scenarios. Custom checked exceptions can be created by extending your class from java.
lang.Exception Class.
Unchecked/Runtime Exceptions Represents an error in our program's logic which can not be reasonably
recovered from at run time, for example NullPointerException, ArrayIndexOutOfBoundsException. We do
not need to declare/catch such exception in the method signature because these are not expected by any
programmer. Custom unchecked exceptions can be created by extending from RuntimeException
Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to
catch. A custom error can be created by extending our class from Throwable.
Chapter - Core Java Cracking the Core Java Interviews 61
Method parameters are always passed by value in Java language irrespective of the type of variable (primitive
or objects).
Actually Java always passes a copy of the bits in the variable. So for a primitive variable, you're passing a copy
of the bits representing the value. For example, if you pass an int variable with the value of x, you're passing a
copy of the bits representing x. The called method then gets its own copy of the value, to do with it what it likes.
And if you're passing an object reference variable, you're passing a copy of the bits representing the reference
to an object. The called method then gets its own copy of the reference variable, to do with it what it likes. But
because two identical reference variables refer to the exact same object, if the called method modifies the
object (by invoking setter methods, for example), the caller will see that the object the caller's original variable
refers to has also been changed.
The bottom line on pass-by-value: the called method can't change the caller's variable, although for object
reference variables, the called method can change the object the variable referred to. What's the difference
between changing the variable and changing the object?
That's the reason we can never write a method in Java which can swap two Integers.
Q 68. How does an ArrayList expands itself when its maximum capacity is reached ?
SOLUTION
When the internal array of an ArrayList becomes full, then new array with double the capacity is created
efficiently by the ArrayList using the following method.
If it needs to shift the elements in order to add something over the existing index, then it displaces the elements using
following System method -
If we know in advance the capacity requirements for the ArrayList object, then we should always create the
ArrayList with that capacity to reduce the amount of incremental reallocation.
JVM has a string pool where it keeps at most one object of any String. String literals objects are always
created in the string pool for reusability purpose. String objects created with the new operator do not refer to
objects in the string pool.
Pool generally resides in PermGen space as of JDK 1.6 (not much documentation is found on this)
The pooling concept has been made possible because the String objects are Immutable in Java.
Chapter - Core Java Cracking the Core Java Interviews 62
In Java, every object has a built in lock (or monitor) that gets activated when Object has synchronized method
code. It is basically of two types
Instance Lock
When we enter a non-static synchronized code then JVM acquires instance level lock on the Object whose
method we are executing. Instance lock can also we acquired using the following syntax with block level
synchronization.
Notes about instance locking
• Lock is mutually exclusive, which means that only one thread can acquire it and other threads have to wait
for their turn until first thread releases it.
• Each Java object has just one lock (or monitor)
• Non-synchronized methods (& a single static synchronized method) can be executed in parallel with a
single synchronized method.
• If a thread goes to sleep then it holds any lock it has.
• A single thread can acquire multiple lock on multiple objects.
• Lock is Reentrant, meaning that same thread can acquire the same lock multiple times (231 times)
synchronized(MyClass.class){
…
}
Example
Lets take this sample example to understand class and instance level Lock.
1. One Thread can call reference.classMethod() and other thread can call reference.instanceMethod() in
parallel because class level and instance level locks do not interfare.
2. But both the threads can't call the same instanceMethod() or classMethod() in parallel, because of the
Mutual Exclusiveness of the Instance Lock and Class Lock.
Chapter - Core Java Cracking the Core Java Interviews 63
Race Condition
A race condition occurs when the correctness of a computation depends on the relative timing of multiple
threads by the runtime. In this scenario Getting the right result relies on the lucky timings.
Dead Lock
Dead lock occurs when two or more threads are blocked forever, waiting for each other to release up the
shared resource. For two threads, it happens when two threads have a circular dependency on a pair of
synchronized shared resources.
Starvation
Describes a situation where a thread is unable to gain regular access to shared resource and is unable to
make any progress
This happens when shared resources are made unavailable for long periods by "greedy" threads. For example,
suppose an object provides a synchronized method that often takes a long time to return. If one thread invokes
this method frequently, other threads that also need frequent synchronized access to the same object will often
be blocked.
Mutex
Mutex stands for mutually exclusive, only one kind of operation (READ or WRITE) is allowed at a given time
frame.
Live Lock
A thread often acts in response to the action of other threads, if the other thread's action is also in response to
another thread, then live lock may result. No progress but threads are not blocked.
Synchronizer
A synchronizer is any object that coordinates the control of flow of threads based on its state. For example,
semaphore, CountDownLatch, FutureTask, Exchanger, CyclicBarrier, etc.
Latch
A synchronizer that can delay the progress of threads until it reaches the terminal state.
Semaphore
Counting semaphore are used to control the number of activities that can access a certain shared resource or
perform a given action at the same time. Semaphores are normally used implement resource pool or to impose
a bound on a collection.
Exchanger
A two party barrier in which the parties exchange data at the barrier point.
Question : How will you Produce a Race Condition in your Java Program ?
Answer
The following Class's object, if called from two different threads, can produce a Race Condition. When two
thread will try to add value to the single shared object, chances are there that race condition will occur.
Q 72. What is float-int implicit conversion while doing calculation on mixed data type
in Java?
SOLUTION
If at least one of the operands to a binary operator is of floating-point type, then the operation is a floating-point
operation, even if the other is integral.
int i1 = 5;
float f = 0.5f;
int i2 = 2;
System.out.println(i1 * f); // Result will be a float
System.out.println(i1 / i2); // Result will be an integer
System.out.println(((float) i1) / i2); // Result will be a float
Result
2.5
2
2.5
Primitive Casting
Casting lets you convert primitive values from one type to another. Casts can be explicit (narrowing
conversions) or implicit (widening the conversions).
Compiler does implicit conversion when you try to put smaller item into bigger bucket but not the other way.
By default all literal integers are implicitly interpreted as int by the compiler. for example,
int x = 27; //Literal assignment
Q 73. Question: discuss Comparable and Comparator ? Which one should be used in
a given scenario ?
SOLUTION
Comparable and Comparator both are used for allowing sorting a collection of objects.
Comparator should be used to provide an external controllable ordering behavior which can override the
default ordering behavior (natural ordering) and when we might require different type of ordering behavior
for the same Object. Comparator is implemented like an Adaptor Design Pattern where a separate class is
dedicated for providing the comparison behavior.
Chapter - Core Java Cracking the Core Java Interviews 65
Q 74. How would you sort a Collection of Objects based on two fields in Java, Very
analogical to SQL's Order by firstField, SecondField desc ?
SOLUTION
Sorting based on multiple Object properties is easily achievable in Java Collections Framework. We just need
to redesign our Comparator to accommodate for multiple fields. Let's see how can we achieve that .
Lets assume we want to sort Person objects based on Age, and then Name (when two person has same age).
import java.util.*;
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' +", age=" + age +'}';
}
}
In the above code snippet, we can see the implementation for Person Comparator (code highlighted in red),
whenever age of two persons is equal, then return the result based on Name comparison. That's quite easy ?
Chapter - Core Java Cracking the Core Java Interviews 66
Q 75. What are the best practices for handling TimeZone in database transactions ?
SOLUTION
There are multiple ways to handle Time Zone in your Java Application which deals with database transactions -
1. While using PreparedStatement, we should always prefer setDate(int parameterIndex, Date date, Calendar
cal) method to specify the Calendar in desired time zone.
2. For Spring JDBCTemplate, we should pass Calendar (with desired TimeZone) instance instead if plain Date
object.
3. We can also set application wide TimeZone using TimeZone.setDefault(TimeZone.getTimeZone(String ID))
4. JVM wide time zone can be set by passing JVM argument -Duser.timezone=GMT
Do's -
1. Prefer JodaTime API for handling TimeZone specific calculations in your application. JodaTime provides
simple and better api's for playing with Date & TimeZone.
2. While persisting time in your application, always prefer to use GMT or any other TimeZone which is not
affected by the Day Light Savings. And always include the original timezone name while storing the date so
that you can easily re-construct the date to the same value.
3. Business rules should always work on GMT time.
4. Only convert to local time at the last possible moment.
5. TimeZones and Offsets are not fixed and may change in future, always design your application keeping this
thing in mind.
Don't -
1. Do not use javascript based Date and Time Calculations in your web applications unless absolute
necessary as time and date on client machine may be different or incorrect.
2. Never trust Client DateTime on your server application.
3. Do not compare client datetime with server datetime.
Q 76. How would you convert time from One Time Zone to another in Java ?
SOLUTION
java.util.Date class is not TimeZone aware, as it does not store any time zone specific information in its object.
This is clearly mentioned in the Java Docs for Date Class -
In Date, A milliseconds value represents the number of milliseconds that have passed since January 1, 1970
00:00:00.000 GMT.
The internal representation of the time inside Date object remains same for a given time, when we print the
date object using System.out.println(date) method then date.toString() method is invoked which prints the date
in local TimeZone of the JVM.
Thus a given time in milliseconds can be represented in different TimeZone using different TimeZone specific
Date formatters.
Notes
Always prefer to user Calendar API over Date due to various benefits of Calendar Class - Calendar handles
TimeZone information and it correctly measures the duration of a year in milliseconds keeping into account the
leap years.
instance.setTimeZone(TimeZone.getTimeZone("GMT"));
Date date2 = instance.getTime();
System.out.println("date2 = " + date2);
Answer
Both the System.out will print the same date value because Date class object is always printed in local
TimeZone and changing the TimeZone on Calendar class does not alter the underlying milliseconds value from
the epoch time (Since January 1, 1970 00:00:00.000 GMT).
Question: How will you write a method to add weekdays to a given date ?
Answer - The following method can add given weekdays to a given Date.
public Date addBusinessDays(Date date, int numberOfDays) {
int count = 0;
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
while (count < numberOfDays) {
calendar.add(Calendar.DAY_OF_YEAR, 1);
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY || calendar.get(Calendar.DAY_OF_WEEK) ==
Calendar.SATURDAY)
count++;
}
return calendar.getTime();
}
Q 77. Will WeakHashMap's entry be collected if the value contains the only strong
reference to the key ?
SOLUTION
public class Key {};
public class Value{
final public Key key;
public Value (Key key){
this.key = key;
}
}
The value object in the WeakHashMap are held by ordinary strong references. Thus care must be taken to
ensure that Value objects do not strongly refer to their own keys, either directly or indirectly, since that will
prevent the keys from being garbage collected. If it is strongly required to store the key's reference in Value
object then we can assign a Weak reference of Key in value object, as shown follow.
HashMap's initial capacity must be power of 2, and its default value is set to 16.
The reason is that, hashmap utilizes binary shift operation for calculating the modulus (%) of x/n for
optimization reasons. But the bitwise hack expects the initial capacity to be power of two.
Even if we specify a custom initial capacity, it will round it to the nearest power of two using the following code.
int capacity = 1;
while(capacity < intialCapacity){
capacity = capacity << 1;
}
Q 79. Can we traverse the list and remove its elements in the same iteration loop ?
SOLUTION
Q 80. Do I need to override object's equals() and hashcode() method for its use in a
TreeMap ?
SOLUTION
Only hashing data structures require hashcode() method for achieving Big O(1) for data retrieval.
TreeMap, on the other hand uses Comparator/Comparable for sorting/ranking its elements, equals() is only
used to search an element inside the collection using contains(object o). Its always a good practice to keep
equals() method in sync with the Comparator to have consistency in your code.
HashMap, hashtable, ConcurrentHashMap, LinkedHashMap are few of the hashing data structures which
require both hashcode() and equals() method.
Here is the rough implementation of Blocking Queue using Java Intrisic Locking aka synchronized keyword.
Q 82. Is there a way to acquire a single lock over entire ConcurrentHashMap object ?
SOLUTION
Acquiring a single lock over entire ConcurrentHashMap may not serve any purpose to us, because CHM uses
multiple internal locks to make it thread-safe. CHM's dynamic re-sizing recursively acquires lock over all of its
buckets in order to make them bigger, but that's of no concern to the API user.
If we really want a single lock for the entire collection, then we should really prefer synchronized hashmap
instead of ConcurrentHashMap.
Chapter - Core Java Cracking the Core Java Interviews 70
Q 83. How will you implement a Blocking Queue using Lock and Condition Interface ?
SOLUTION
Lock is analogical to synchronized keyword and Condition is similar to wait/notify. Here is the implementation fr
BlockingQueue that uses Lock and Condition.
queue.add(element);
notEmpty.signal();
} finally {
lock.unlock();
}
}
T item = queue.remove();
notFull.signal();
return item;
} finally {
lock.unlock();
}
}
}
Please note that the thread contention for this class will be slightly less compared to similar implementation
using synchronized keyword, because here we maintain two different Condition Queues instead of just one.
Chapter - Core Java Cracking the Core Java Interviews 71
Q 84. What is difference between intrinsic synchronization and explicit locking using
Lock ?
SOLUTION
JVM provides intrinsic synchronization through monitor locks. Each object in Java owns a monitor on which the
threads can be synchronized. JDK 1.5 introduced concept of explicit synchronization using Lock1 and Condi-
tion classes which offers advanced features over intrinsic synchronization.
1 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html
Chapter - Core Java Cracking the Core Java Interviews 72
“Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially
executed by another thread. A Runnable, however, does not return a result and cannot throw a checked excep-
tion.”
In order to convert Runnable to Callable use the following utility method provided by Executors class
Callable, however must be executed using a ExecutorService instead of Thread as shown below.
result = exec.submit(aCallable).get();
Submitting a callable to ExecutorService returns Future Object which represents the lifecycle of a task and pro-
vides methods to check if the task has been completed or cancelled, retrieve the results and cancel the task.
Q 86. What will happen when an exception occurs from within a synchronized code
block?
SOLUTION
When an exception occurs from within a synchronized code block, then JVM smartly releases all the locks
acquired by the current thread and will start unwinding the execution stack, till the exception is handled using
catch block, otherwise killing the thread.
But the same does not happen when we write explicit locking code using Lock interface. In that case we need
to release the lock manually in the finally block.
Chapter - Core Java Cracking the Core Java Interviews 73
Object.wait() and Thread.sleep() are entirely two different method used in two different contexts. Here are few
differences between these two methods.
1. wait() method releases the acquired lock when the thread is waiting till someone calls notify() while Thread.
sleep() method keeps the lock even if thread is waiting.
synchronized(monitor) {
Thread.sleep(1000); // LOCK is held by the current thread
}
synchronized(monitor) {
monitor.wait(); // LOCK is released by current thread
}
2. wait() can only be called from synchronized context otherwise it will throw IllegalMonitorStateException,
while sleep can be called from any code block.
4. waiting thread can be awaken by calling notify()/notifyAll() methods while sleeping thread can't be awaken1
(though can be interrupted)
5. Incase of sleep() Thread immediately goes to Runnable state after waking up while in case of wait(), wait-
ing thread first fights back for the lock and then go to Runnable state.
6. Major difference between yield and sleep in Java is that yield() method pauses the currently executing
thread temporarily for giving a chance to the remaining waiting threads of the same priority to execute. If
there is no waiting thread or all the waiting threads have a lower priority then the same thread will continue
its execution.
In Layman's Terms
sleep(n) - Thread is done with its time slot, and please don’t give it another one for at least n milliseconds. The
OS doesn’t even try to schedule the sleeping thread until requested time has passed.
yield() - Thread is done with its time slot, but it still has work to do. The OS is free to immediately give the
thread another time slot, or to give some other thread or process the CPU the yielding thread just gave up.
wait() - Thread is done with its time slot, Don’t give it another time slot until someone calls notify(). As with
sleep(), the OS won’t even try to schedule your task unless someone calls notify() or one of a few other wake-
up scenarios occurs (spurious wakeup).
Q 88. How would you cancel a method execution after time-out expires using Java
Future?
SOLUTION
This can be easily achieved using Future utility class provided by concurrent package in JDK 1.5
Future represents the life cycle of a task and calling cancel() on future attempts to cancel the task execution,
if not already in completed state. Thread can even be interrupted if we pass true as a parameter to cancel()
method. And this interrupt can be checked using Thread.interrupted() method inside the running task.
JAVA Source
public void timedRun(Runnable runnable, long timeout, TimeUnit unit) throws InterruptedException,
ExecutionException {
Future<?> task = executorService.submit(runnable);
try {
task.get(timeout, unit);
} catch (TimeoutException e) {
System.err.println("Timeout occurred.");
} finally {
task.cancel(true);
}
}
This task will be cancelled after 100 microseconds. Do not forget to call task.cancel(true), otherwise the thread
will continue executing the task in background.
Chapter - Core Java Cracking the Core Java Interviews 75
Naming Convention
E - element
K - key
N - number
T - type
V - value
S,U,V etc - 2nd, 3rd & 4th type
Here List<String> is not a sub type of List<Object>, hence as per inheritance rule, this is not allowed.
Q 90. What are Upper and Lower bounds in Generics? Where to choose one?
SOLUTION
Upper and Lower bounded wildcard are used in Generics to relax the
restriction on a variable.
Wildcard Guidelines
•An "in" variable is defined with an upper bounded wildcard, using the extends keyword.
•An "out" variable is defined with a lower bounded wildcard, using the super keyword.
•In the case where the "in" variable can be accessed using methods defined in the Object class, use an
unbounded wildcard.
•In the case where the code needs to access the variable as both an "in" and an "out" variable, do not use a
wildcard.
Multiple Bounds
A type parameter can have multiple bounds as described below.
<T extends B1 & B2 & B3>
1 http://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html
Chapter - Core Java Cracking the Core Java Interviews 77
"Fields declared final are initialized once, but never changed under normal circumstances. The detailed se-
mantics of final fields are somewhat different from those of normal fields. In particular, compilers have a great
deal of freedom to move reads of final fields across synchronization barriers and calls to arbitrary or unknown
methods. Correspondingly, compilers are allowed to keep the value of a final field cached in a register and not
reload it from memory in situations where a non-final field would have to be reloaded.
final fields also allow programmers to implement thread-safe immutable objects without synchronization. A
thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass refer-
ences to the immutable object between threads. This can provide safety guarantees against misuse of an
immutable class by incorrect or malicious code. final fields must be used correctly to provide a guarantee of
immutability.
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a
reference to an object after that object has been completely initialized is guaranteed to see the correctly initial-
ized values for that object's final fields.
The usage model for final fields is a simple one: Set the final fields for an object in that object's constructor;
and do not write a reference to the object being constructed in a place where another thread can see it be-
fore the object's constructor is finished. If this is followed, then when the object is seen by another thread, that
thread will always see the correctly constructed version of that object's final fields. It will also see versions of
any object or array referenced by those final fields that are at least as up-to-date as the final fields are."
Briefly speaking
Memory visibility of final fields are guaranteed by the Java Memory Model and hence are thread safe in multi-
threaded scenario. Thus we prefer to use Immutable objects in the concurrent application to avoid any memory
visibility related problems.
Notes
Question
We have a legacy application in which a thread reads a config file and starts creating beans. It does so
by first creating the object and then setting the required properties on them. All this happens without any
synchronization because everything is happening serially. Once the objects are created, other threads pick
those objects and start processing. But somehow, we got the problem that one of the client thread is not seeing
the Correct Value for a bean.
Analysis
This could be a typical memory visibility issue in a multi-threaded environment. A properly constructed bean
would have to make its fields final in absence of synchronization, otherwise other threads may see the default
values for its fields. Thus moving the bean initialization code (setters) into constructor and making the fields
final should solve this problem. Otherwise we might need to synchronize the access to this particular bean -
read articles about proper publishing of an object in multi-threaded environment.2
1 http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7
2 http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html continued on 78
Chapter - Core Java Cracking the Core Java Interviews 78
The values of final fields are populated inside an object's constructor. And if the object is constructed properly
(this reference does not escape during construction, don't start thread from within constructor, fields are final),
then the values assigned to the final fields in the constructor are guaranteed to be visible to all other threads
without the need of any synchronization. In addition, the visible values for any other object or array referenced
by those final fields will be at least as up-to-date as the final fields. Let's understand the following example,
class FinalFieldExample {
final int x;
final ArrayList<String> names;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
names= new ArrayList<>();
names.add("First");
names.add("Second");
}
In this example, suppose Thread A calls FinalFieldExample.write() method and thus creates the object. Thread
B on other hand calls FinalFieldExample.reader() method and thus access's the object. Further suppose that
Thread B calls reader() once the writer() is finished creating the object. As per new Java Memory Model (JSR
133),
• Thread B executing the reader is guaranteed to see the value of 3 for field f.x - its a final primitive variable
• Thread B is guaranteed to see the value of "First" and "Second" for field f.names because names array is
referenced by a final field, and the value assigned to such object inside the constructor boundary will be
visible to other threads.
• There is not guarantee that Thread B will see "third" inside array f.names
• There is not guarantee that Thread B will see value of 4 for field f.y
3 http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
Chapter - Core Java Cracking the Core Java Interviews 79
LinkedHashSet maintains the order of its original elements over and above the the uniqueness of its elements.
Its more efficient when we iterate over its elements because it maintains the elements in a linked list. This is
not possible with the HashSet because the in order to iterate over its elements, every bucket in a hash table
must be visited whether it is occupied or not.
Q 93. What do you think is the reason for String Class to be Immutable?
SOLUTION
String class in Java is implemented as Immutable and there are various reasons for doing that,
• Immutability brings inherent thread-safety to the usage of String class in a concurrent program. So multiple
threads can work on the same String object without any data corruption. There is absolutely no need to
synchronize the code because of String objects.
• StringPooling is possible only because of immutability because the underlying contents of the String will
never change. This helps reducing the overall memory footprint of the application using lots of String
objects.
• Hash code for Immutable objects are calculated lazily on first usage and then cached for future reference.
This gives the benefit of performance when we use Immutable Key's in any hashing data structure.
String concatenation is implemented internally through the StringBuilder(as of JDK 1.5) class and its append
method. As of Java 5, Java will automatically convert the following string concatenation
Thus no temporary objects will be created for this type of concatenation. This JVM optimization may improved
further in upcoming releases.
StringBuilder Object outside the loop and then append the data to that StringBuilder Object. That's the reason,
experts advice to use StringBuilder inside a loop. Using StringBuilder, the code should look like this :
Time Complexity : Big O (n) where n is the number of strings, 1000 in this case.
Q 95. Which Java data type would you choose for storing sensitive information, like
passwords, and Why?
SOLUTION
Normally, a character array should used for storing passwords. Here is the reason for choosing char array over
String -
• There is no way to clear a String Object from the memory, its up to GC to collect it.
• String objects are immutable and stored in a String Pool (may reside inside a PermGen space) which may
not at all be gc'd.
• Any person taking the heap dump can easily see the String literals.
• In case of an char array, we can always nullify it once we are done with the information, so not much
dependency on the GC, thus we are narrowing the time window for the life of sensitive data.
• Externalizable Interface extends the java.io.Serializable adding two methods - writeExternal &
readExternal.
• In case of Serializable, default serialization is used, while in case of Externalizable, the complete
serialization control goes to the application. Stating that means, we can not benefit from the default
serialization process when we choose Externalizable interface.
• We generally choose Externalizable when we want to save the output in our custom format which is other
than Java default serialization format like, csv, database, flat file, xml, etc
• readExternel() and writeExternal() methods are used to handle the serialization in case of Externilizabel
interface.
• In case of externalizable interface, we need to handle super type state, default values in transient variable
and static variables.
• Incase of Serialization, object is reconstructed using data read from ObjectInputStream but incase of
Externalizable, public no-arg constructor is used to reconstruct the object.
Chapter - Core Java Cracking the Core Java Interviews 81
Q 98. Where should we use GET, PUT, POST and DELETE method?
SOLUTION
All three classes (HashMap, TreeMap and LinkedHashMap) implements Map interface, and therefore
represents mapping from unique key to values. But there are different usage scenarios for each of them -
1. HashMap is a hashing data structure which works on hashcode of keys. Keys must provide consistent
implementation of equals() and hashCode() method in order to work with hashmap. Time complexity for
get() and put() operations is Big O(1).
2. LinkedHashMap is also a hashing data structure similar to HashMap, but it retains the original order of
insertion for its elements using a LinkedList. Thus iteration order of its elements is same as the insertion
order for LinkedHashMap which is not the case for other two Map classes. Iterating over its elements
is lightly faster than the HashMap because it does not need to traverse over buckets which are empty.
LinkedHashMap also provides a great starting point for creating a LRU Cache object by overriding the
removeEldestEntry() method, as shown in the following code snippet.
3. TreeMap is a SortedMap, based on Red-Black Binary Search Tree which maintains order of its elements
based on given comparator or comparable. Time complexity for put() and get() operation is O (log n).
Chapter - Core Java Cracking the Core Java Interviews 83
Q 100. How would you write high performing IO code in Java? Can you write a sam-
ple code for calculating checksum of a file in time efficient manner?
SOLUTION
Intent of the interviewer is to know if you are familiar with Java's High Performance IO Channels.
Few of the times we wish the speed of C for doing some IO intensive task in our Java program. Calculation of
CRC is one of the task which requires an efficient IO implementation in order to give good performance which
is very close to the one we see in a similar C program (though not equivalent)
An InputStream in Java can be easily converted into an FileChannel using its getChannel() method. Let's
understand how to use channels using the following Checksum Calculation Program.
while (mb.hasRemaining()) {
nGet = Math.min(mb.remaining(), SIZE);
mb.get(bytes, 0, nGet);
crc.update(bytes, 0, nGet);
}
return crc.getValue();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Java's FileChannel provide much better performance compared to the InputStream, BufferedInputStream and
RandomAccessFile methods, because it utilizes the operating system specific optimization techniques under
the hood.
Chapter - Core Java Cracking the Core Java Interviews 84
Java Channels can be used in wide variety of IO tasks. For example, an efficient implementation of Http File
Download can be written using a FileChannel, as shown below.
con.setReadTimeout(10000);
con.setConnectTimeout(10000);
Above code snippet will transfer bytes from HttpURLConnection's Stream into FileChannel using
transferFrom() method of FileChannel.
" This method is potentially much more efficient than a simple loop that reads from the source channel and
writes to this channel. Many operating systems can transfer bytes directly from the source channel into
the filesystem cache without actually copying them."
Q 101. We have an Application and we want that only Single Instance should run for
that Application. If Application is already running then second instance should never
be started. How would you handle this in Java?
SOLUTION
2.) Use a shared file lock using FileChannel and check if that temp file is already locked by some running
process or not. If yes then terminate the startup process for second instance. Let's see how we can achieve
this in the following code -
if (fileLock == null) {
System.out.println("Could not obtain lock");
closeLock();
return true;
}
lockFile.deleteOnExit();
return false;
} catch (Exception e) {
closeLock();
return true;
}
}
Chapter 3
Concurrency
Q 102. What is Concurrency? How will you implement Concurrency in your Java Pro-
grams?
SOLUTION
Concurrency is the property of an software program to run several computations in parallel. Java provides
us with the multiple mechanisms to create Threads so as to utilize the multiple processor cores of a given
hardware in order to achieve high throughput.
Java provides various ready to use utilities for writing concurrent programs, which otherwise is difficult to
implement.
an example usage of TimeUnit and Lock interface could be to try obtaining lock for 50ms as shown in below
code snippet
Such a method call can never cause a deadlock scenario because it will try acquiring lock only for 50 ms only.
What is Synchronization ?
Synchronization avoids thread interference and memory consistency errors by providing serialized access to
the shared state.
Lets examine the following program for its correctness in concurrent environment, It maintains the integer
counter.
Counter.java
@NotThreadSafe
class Counter {
private int c = 0;
public void increment() {
c++;
}
public int value() {
return c;
}
}
This program will work absolutely fine in single threaded environment but will not behave correctly in multi-
threaded environment, because
1. increment() method will not be executed atomically so data race may corrupt the counter value.
2. value() method may not return the latest value of counter because of caching in processor's registers.
Q 103. There are two Threads A and B operating on a shared resource R, A needs to
inform B that some important changes has happened in R. What technique would you
use in Java to achieve this?
SOLUTION
Object R's method wait(), notify() & notifyAll(), can be used for inter-thread communication. This will allow all
threads which hold lock over R, to communicate among them selves. You can explore a typical Producer-
Consumer problem to see how it works.
continued on 87
Chapter - Concurrency Cracking the Core Java Interviews 88
Q 104. What are the different states of a Thread? What does those states tells us?
SOLUTION
A thread in JVM can have 6 different states as defined in Thread.State enum. At any given time, thread must
be in any of these states.
NEW
This state is for a thread which has not yet started.
RUNNABLE
This state is for the currently running thread which is executing in java virtual machine, but it may be waiting for
the other resources from operating system such as processor.
BLOCKED
Thread state for a thread blocked waiting for a monitor lock. A thread in this state can be waiting for a monitor
lock to enter a synchronized block/method or reenter a synchronized method after calling Object.wait.
WAITING
A thread is waiting due to calling on one of the method -
Object.wait with no timeout
Thread.join with no timeout
LockSupport.park
A Thread in this state is waiting for another thread to perform a particular action. For example, a thread that
has called Object.wait() on an object is waiting for another thread to call Object.notify() or Object.notifyAll() on
that object. A thread that has called Thread.join() is waiting for a specified thread to terminate.
TIMED_WAITING
Thread state for a waiting thread with a specified waiting time. A thread is in the timed waiting state due to
calling one of the following methods with a specified positive waiting time -
Thread.sleep
Object.wait with timeout
Thread.join with timeout
LockSupport.parkNanos
LockSupport.parkUntil
TERMINATED
Thread state for a terminated thread. The thread has completed execution.
References
This content has been taken directly from the Java 7 Docs - Thread.State enum.
Chapter - Concurrency Cracking the Core Java Interviews 89
Q 105. Question: What do you understand by Java Memory Model? What is double-
checked locking? What is different about final variables in new JMM?
SOLUTION
Interviewer's Intent - Interviewer wants to understand if you can write concurrent code.
Java Memory Model1 defines the legal interaction of threads with the memory in a real computer system. In
a way, it describes what behaviors are legal in multi-threaded code. It determines when a Thread can reliably
see writes to variables made by other threads. It defines semantics for volatile, final & synchronized, that
makes guarantee of visibility of memory operations across the Threads.
Let's first discuss about Memory Barrier which are the base for our further discussions. There are two type of
memory barrier instructions in JMM - read barriers & write barrier.
A read barrier invalidates the local memory (cache, registers, etc) and then reads the contents from the main
memory, so that changes made by other threads becomes visible to the current Thread.
A write barrier flushes out the contents of the processor's local memory to the main memory, so that changes
made by the current Thread becomes visible to the other threads.
Thread A
-------------
data = new Data();
flag = true; <-- writing to volatile will flush data as well as flag to main memory
Thread B
-------------
if(flag==true){ <-- reading from volatile will perform read barrier for flag as well data.
use data; <--- data is guaranteed to visible even though it is not declared volatile because of the JMM
semantics of volatile flag.
}
1 http://www.ibm.com/developerworks/library/j-jtp03304/ continued on 90
Chapter - Concurrency Cracking the Core Java Interviews 90
NonThreadSafe Singleton (This will not work under current JMM), so never use it
public class Singleton
{
private Singleton() {}
private static Singleton instance_ = null; ==> A global static variable that will hold the state
will also be flushed out.. While Thread B may see a valid reference to the newly created _instance, but
because it didn't perform a read barrier, it could still see stale values of _instance's member fields.
• Since thread B is not executing inside a synchronized block, it may see these memory operations in
a different order than the one thread A executes. It could be the case that B sees these events in the
following order (and the compiler is also free to reorder the instructions like this): allocate memory, assign
reference to resource, call constructor. Suppose thread B comes along after the memory has been
allocated and the resource field is set, but before the constructor is called. It sees that resource is not null,
skips the synchronized block, and returns a reference to a partially constructed Resource! Needless to say,
the result is neither expected nor desired.
Fixed double-checked Locking using volatile in new JMM (multi-threaded singleton pattern JDK 1.5)
The following code makes the helper volatile so as to stop the instruction reordering. This code will work with
JDK 1.5 onwards only.
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}
If Helper is an immutable object, such that all of the fields of Helper are final, then double-checked locking
will work without having to use volatile fields. The idea is that a reference to an immutable object (such as a
String or an Integer) should behave in much the same way as an int or float; reading and writing references to
immutable objects are atomic.
Alternatives to DCL2
Now a days JVM is much smarter and the relative expense of synchronized block over volatile is very less, so
it does not really make sense to use DCL for performance reasons.
The easiest way to avoid DCL is to avoid it. We can make the whole method synchronized instead of making
the code block synchronized.
Another option is to use eager initialization instead of lazy initialization by assigning at the creation time
Here is the example demonstrating eager initialization
class MySingleton {
public static Resource resource = new Resource();
}
The method increment() in the above code is not thread safe, because i++ require multiple cpu instruction
cycles to compute the summation. Data race condition may happen if the shared object is incremented from
multiple threads, simultaneously.
If you want, you can write your custom AbstractQueueSynchronizer to achieve the same, but that discussion
is out of scope for this writing.
Q 107. What happens when wait() & notify() method are called?
SOLUTION
When wait() method is invoked from a synchronized context, the following things happen
• The calling thread gives up the lock.
• The calling thread gives up the CPU.
• The calling thread goes to the monitor's waiting pool.
Volatile is a mechanism for lighter weight synchronization where memory visibility of the protected state is
guaranteed to all consecutive threads.
A write to volatile variable not only flush changes of the volatile variable but all the non volatile variables
changed before write to volatile. Thus a simple flag of volatile type can serve the memory visibility guarantee of
all the other variables changed before. The following figure explain it in entirety.
Figure : Effects of volatile variables on time scale
thread-1
------------
content = new Data();
ready = true;
thread-2
------------
if(ready){
//process new content
int var = content.consume();
}
For the purposes of the Java programming language memory model, a single write to a non-volatile long or
double value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a
thread sees the first 32 bits of a 64-bit value from one write, and the second 32 bits from another write.
Writes and reads of volatile long and double values are always atomic.
Writes to and reads of references are always atomic, regardless of whether they are implemented as 32-bit or
64-bit values.
It is safe to perform read-modify-write operations on a shared volatile variable as long as you ensure that the
volatile variable is only written from single thread.
volatile variables are liable to get into race conditions because atomicity is required to solve race condition
Chapter - Concurrency Cracking the Core Java Interviews 95
Q 109. What is a CAS? How does it help writing non-blocking scalable applications?
Tell something about Atomic Package provided by Java 1.6
SOLUTION
This method (which varies in argument types across different classes) atomically sets a variable to the
updateValue if it currently holds the expectedValue, reporting true on success.
1 http://www.ibm.com/developerworks/java/library/j-jtp11234/
Chapter - Concurrency Cracking the Core Java Interviews 96
Q 110. There is a object state which is represented by two variables. How would
you write a high throughput non-blocking algorithm to update the state from multiple
threads?
SOLUTION
Non-blocking algorithms provide better throughput at low thread contention compared to the locking counter-
part. This can only be achieved in Java using CAS1 (compare and swap) utilities provided in atomic package.
AtomicReference along with Immutable object can be used to write a non-blocking algorithm maintaining a
current state of Trade Volume.
There are key points to be noted while writing non-blocking algorithm2 are:
• Immutability of TradeVolume as in below example is must to ensure proper initialization at it's assignment
time. Immutability is achieved by making all fields final and providing constructor initialization.
• compareAndSet operation must be called repetitively in a while loop till the time it returns true.
Java does not provide Atomic implementation for Double/Float as they have stated in their documentation1
“Atomic classes are not general purpose replacements for java.lang.Integer and related classes. They do
not define methods such as hashCode and compareTo. (Because atomic variables are expected to be mu-
tated, they are poor choices for hash table keys.) Additionally, classes are provided only for those types that
are commonly useful in intended applications. For example, there is no atomic class for representing byte. In
those infrequent cases where you would like to do so, you can use an AtomicInteger to hold byte values, and
cast appropriately. You can also hold floats using Float.floatToIntBits and Float.intBitstoFloat conversions, and
doubles using Double.doubleToLongBits and Double.longBitsToDouble conversions.”
First method is to use AtomicReference to hold Double value as shown in below snippet
import java.util.concurrent.atomic.AtomicReference;
Second method is to use AtomicInteger for storing Float bit values as hinted by above Java docs
import java.util.concurrent.atomic.AtomicInteger;
import static java.lang.Float.*;
1 http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/package-summary.html
continued on 98
Chapter - Concurrency Cracking the Core Java Interviews 98
Notes
Further thoughts
How would you implement AtomicBigDecimal ?
Why didn't Java provide default implementation for AtomicDouble/AtomicFloat ?
When should be prefer CAS over traditional blocking synchronization ?
References
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/package-summary.html
Q 112. Can we implement check & update method (similar to compare and swap) us-
ing volatile alone?
SOLUTION
No, this is not possible using volatile keyword alone. Volatile keyword can not guarantee atomicity of operation.
It's a lighter weight synchronization which can guarantee memory visibility only.
The only way to implement CAS is either using synchronized block (Lock Interface as well) or using java
provided hardware level CAS in it's atomic package i.e. using AtomicReference, AtomicInteger, etc
Chapter - Concurrency Cracking the Core Java Interviews 99
Q 113. You are writing a multi-threaded software piece for NSE for maintaining the
volume of Trades made by its individual brokers (icici direct, reliance ). It's highly con-
current scenario and we can not use lock based thread safety due to high demand of
throughput. How would handle such scenario?
SOLUTION
private ConcurrentHashMap<String, BigDecimal> sumByAccount;
Since the multiple threads could be simultaneously adding the value to their respective broker, the designed
code should be thread safe. Un-Thread safe version looks like :
Solution
CAS can be utilized for achieving the high throughput requirement of the underlying system in this case.
AtomicReference<BigDecimal> could be used to store the BigDecimal value atomically.
AtomicReference uses CAS to atomically compare and assign a single reference. In the above code the
compareAndSet(oldVal, oldVal.add(amount)) method checks if the AtomicReference == oldVal (by their memo-
ry location instead of actual value), if true then it replaces the value of field stored in AtomicReference with the
oldVal.add(amount). All this comparison and swapping happens atomically by the JVM. Afterwards invoking the
newSum.get() will return the added amount.
For loop is required here because it is possible that multiple threads are trying to add to the same AtomicRefer-
ence and doing so just one thread succeeds and other fails. The failed threads must try again the operation to
make the addition to BigDecimal.
Please be noted that CAS is recommended for moderate Thread contention scenarios. Synchronized should
always be preferred for high contention code blocks.
Chapter - Concurrency Cracking the Core Java Interviews 100
Q 114. Question: Calculate the time spread for 10 threads - Suppose T1 started earli-
est and T5 finished last, then the difference between T5 and T1 will give time spread.
SOLUTION
This is a typical thread synchronization problem which can be solved using various available techniques in
Java. We will discuss three main approaches to solve this problem - first one using a synchronized object,
second one using non-blocking CAS, third using existing synchronizer CountDownLatch. Algorithm for the both
is same - Two times will be recorded, first time for the thread which started earliest, and second time for the
thread which finished last. The difference of the two times will give us time window.
This version does not require the calling thread to obtain lock on the Object, thus it could be slightly faster.
public class TimeSpread {
final AtomicBoolean started = new AtomicBoolean(false);
final AtomicInteger stopCounter;
long startTime;
long stopTime;
public TimeSpread(int threads) {
stopCounter = new AtomicInteger(threads);
}
public void start() {
if (!started.get()) {
if (started.compareAndSet(false, true)) {
startTime = System.currentTimeMillis();
}
}
}
public void stop() {
if(stopCounter.getAndDecrement()==1){
stopTime = System.currentTimeMillis();
}
}
public long timeConsumed(){
return stopTime-startTime;
}
public static void main(String[] args) throws InterruptedException {
int threads = 300;
final TimeSpread timeSpread = new TimeSpread(threads);
Runnable t = new Runnable(){
public void run() {
timeSpread.start();
try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {}
timeSpread.stop();
}
};
List<Thread> list= new ArrayList<>(threads);
for(int i=0;i< threads;i++){
Thread thread = new Thread(t);
thread.start();
list.add(thread);
}
for (Thread thread : list) {
thread.join();
}
System.out.println("time spread = " + timeSpread.timeConsumed());
}
public static long time(Executor executor, int concurrency, final Runnable action) throws InterruptedException {
Notes
We can evaluate any of these three approaches for our requirement and pick one. But definitely, using
CountDownLatch seems a cleaner approach where the latch hides the boiler-plate code of the synchronization.
Q 116. There is a stream of words which contains Anagrams. How would you print
anagrams in a single bucket from that stream?
SOLUTION
Sort each word and then see if the two words are equal ? abba, baab, abab should go to the same bucket.
Simple method to check if two Strings are anagrams
public boolean isAnagram(String s1, String s2){
char[] a1 = s1.toCharArray();
char[] a2 = s2.toCharArray();
Arrays.sort(a1);
Arrays.sort(a2);
if (Arrays.toString(a1).equals(Arrays.toString(a2))){
return true;
}
return false;
}
Algorithm
1) Use a hashmap with string as key and list<string> as value where list of strings contain all anagrams of a
given key string.
2) For each word in the input array, create a key by sorting the word and put this word to that list whose key is
the sorted word. for example [aakk -> akka, akak] If it does not exist then create a new list with the sorted word
as key in map.
3) Print all strings from the list whose key is the input word(sorted string).
Source Code
import java.util.*;
Time Complexity
If we ignore the time consumed by sorting an individual string then we can say that the above approach takes
Big O(n) time complexity. Otherwise the actual time complexity would be N log N (sorting) + N (compare)
Chapter - Concurrency Cracking the Core Java Interviews 104
Functionality wise this collection is very much similar to ArrayList except the fact that CopyOnWriteArrayList is
thread-safe. It maintains thread-safety using Immutability approach, where any modification operations results
in creating a fresh copy of the underlying array.
This is ordinarily too costly, but may be more efficient than alternatives when traversal operations vastly
outnumber mutations, and is useful when you cannot or don't want to synchronize traversals, yet need to
preclude interference among concurrent threads.
The "snapshot" style iterator method uses a reference to the state of the array at the point that the iterator
was created. This array never changes during the lifetime of the iterator, so interference is impossible and
the iterator is guaranteed not to throw ConcurrentModificationException. The iterator will not reflect additions,
removals, or changes to the list since the iterator was created. Element-changing operations on iterators
themselves (remove, set, and add) are not supported. These methods throw UnsupportedOperationException.
Q 118. There are M number of Threads who work on N number of shared synchro-
nized resources. How would you make sure that deadlock does not happen?
SOLUTION
If a single thread uses more than one protected shared resource, then we should make sure that we acquire
shared resources in particular order and release them in reverse order, otherwise we might end up into a
deadlock scenario.
Q 119. Are there concurrent version for TreeMap and TreeSet in Java Collections
Framework?
SOLUTION
Java Collection Framework have ConcurrentSkipListMap and ConcurrentSkipListSet which are concurrent
replacement for TreeMap and TreeSet. These classes implement SortedMap and SortedSet interface
respectively. So if our application demands fair concurrency then instead of wrapping TreeMap and TreeSet
inside synchronized collection, we can prefer these concurrent utilities. These also implement NavigableMap
and NavigableSet interface with methods like lowerKey, floorKey, ceilingKey, higherKey, headMap and tailMap.
Time Complexity
Average time complexity is log(n) for the containsKey, get, put, remove ad the variant operations of the
ConcurrentSkipListMap
Chapter - Concurrency Cracking the Core Java Interviews 105
Q 120. Is it safe to iterate over an ArrayList and remove its elements at the same time
? When do we get ConcurrentModificationException & hidden Iterator?
SOLUTION
Iterator returned by the ArrayList (and many other collection types) is fail-fast. If the list is structurally modified
at anytime after the iterator is created, in any way except through the Iterator's own remove() method, the
iterator will throw ConcurrentModificationException and thus fails quickly and cleanly, rather than risking
arbitrary, non-deterministic behavior at an undetermined time in the future.
Structural Modification
“A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the
backing array; merely changing the values associated with a key that an instance already contains is not a
structural modification.” - Java Docs
Further, the structural modification could happen either from single thread or from multiple threads. The
behavior of ArrayList would be different in both the cases as mentioned below.
Multi-Threading Scenario
ArrayList implementation is not thread-safe because it provides no synchronization mechanism for protecting
the shared state of its fields. If multiple threads access an ArrayList instance concurrently, and at least one of
the threads modifies the list structurally, it must be synchronized externally. This is typically accomplished by
synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be "wrapped" using the Collections.synchronizedList() method. This is
best done at creation time, to prevent accidental unsynchronized access to the list :
Hidden Iterators
There are certain ArrayList methods which uses Iterators in a hidden form the API user. size() and toString()
are few of them. So care must be taken to call these methods from synchronized block in case of multi-
threaded scenario.
Chapter - Concurrency Cracking the Core Java Interviews 106
Q 121. What is ThreadLocal class, how does it help writing multi-threading code? any
usage with example?
SOLUTION
ThreadLocal class provides a simple mechanism for thread safety by creating only one object instance per
thread. These variables differ from their normal counterparts in that each thread that accesses one (via its get
or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically
private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).
Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and
the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are
subject to garbage collection (unless other references to these copies exist)
ThreadLocal is used to achieve thread-safety in our multi-threaded code by creating a copy local to a thread
and thus no more sharing of state.
When get() method is invoked the first time, ThreadLocal calls initialValue() and returns the newly created
Object, the same Object is returned on subsequent invocations by the same thread untill we clear the Object.
continued on 107
Chapter - Concurrency Cracking the Core Java Interviews 107
• Using Calendar class in multi-threading environment : Calendar.getInstance() is not safe from multi-
threading perspective and a copy of it could be created per thread and stored in ThreadLocal.
• Random Number Generator, ByteBuffers, XML parsers can utilize ThreadLocal for optimization purpose.
Notes
ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread
(e.g., a user ID or Transaction ID).
Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and
the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are
subject to garbage collection (unless other references to these copies exist).
Q 122. How would you implement your own Transaction Handler in Core Java, using
the EntityManager created in last question?
SOLUTION
Sometimes we do not want to use Spring Transaction API's and want to write our own (though very should
never do that unless we are very good at it). In the last question we discussed how we can write a ThreadLocal
EntityManager class. Now we will leverage the same class for writing our basic reusable transaction handler.
@Override
public<T> T run(UnitOfWork<T> unitOfWork) {
final EntityManager em = threadLocalSession.getUnderlyingEntityManager();
EntityTransaction tx = null;
try {
tx = em.getTransaction();
tx.begin();
T result = unitOfWork.run();
tx.commit();
return result;
Chapter - Concurrency Cracking the Core Java Interviews 108
} finally {
if (tx != null && tx.isActive()) {
tx.rollback();
}
threadLocalSession.clear();
}
}
}
Now any client code who wants to run a database specific code inside a transaction can create instance of
JPATransatomatic class, set appropriate ThreadLocalEntityManager and use it, as shown below
Q 123. What is AtomicInteger class and how is it different than using volatile or syn-
chronized?
SOLUTION
Read & write to volatile variables have same memory semantics as that of acquiring and releasing a monitor
using synchronized code block. So the visibility of volatile field is guaranteed by the JMM.
AtomicInteger class stores its value field in a volatile variable, thus it is a decorator over the traditional volatile
variable, but it provides unique non-blocking mechanism for updating the value after requiring the hardware
level support for CAS (compare and set). Under low to moderate thread contention, atomic updates provides
higher throughput compared to synchronized blocking increment operation.
You can see that no lock is acquired to increment the value, rather CAS is used inside infinite loop to update
the new value.
Chapter - Concurrency Cracking the Core Java Interviews 109
Q 124. You are writing a server application which converts microsoft word docu-
ments into pdf format. Under the hood you are launching a binary executable which
does the actual conversion of document. How would you restrict the parallel launch of
such binaries to 5 in Java, so as to limit the total load on the server.
SOLUTION
This is a typical problem of controlling the parallel access to the shared scarce resource so as to avoid the
thread starvation.
JDK 1.5 provides a class specifically designed to address this kind of problem - Semaphore
Semaphore
Counting semaphores are used to control the number of activities that can access a certain resource or
perform a given action at the same time, and it could be used for
Java Source
Notes
Before Java 1.5, we had to write the semaphore functionality from scratch using synchronization (along with
wait and notify for inter thread communication)
Semaphores can be used to convert a standard Java Collection into Bounded Collection after which the
collection would hold only certain number of elements. Once the allowed elements are In, the thread has to
wait till some other thread removes from that collection.
BoundedHashSet Example
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Semaphore;
Continued on 110
Chapter - Concurrency Cracking the Core Java Interviews 110
Chapter 4
Algorithms & Data Structures
Q 126. Given a collection of 1 million integers ranging from 1 to 9, how would you
sort them in Big O(n) time?
SOLUTION
This is a typical Integer Sorting problem with a constraint that the number range to sort is very limited in spite 1
million total entries. Integer Sorting with limited range is achieved efficiently with Bucket Sorting.
Algorithm
Create a array of size 9 and at each index store the occurrence count of the respective integers. Doing this will
achieve this sorting with time complexity of Big O(n) and even the memory requirements are minimized. In Order
to print the output just traverse the above created array.
Source Class
public class BucketSort {
public int[] sort(int[] array, int min, int max) {
int range = max - min +1;
int[] result = new int[range];
for (int i : array) {
result[i]++;
}
return result;
}
}
Test Class
public class BucketSortTest {
@Test
public void testBucketSortFor1To9() {
int[] array = {2, 1, 5, 1, 2, 3, 4, 3, 5, 6, 7, 8, 5, 6, 7, 0};
int[] sort = new BucketSort().sort(array, 0, 8);
for (int i = 0; i < sort.length; i++) {
for(int j=0;j<sort[i];j++){
System.out.println(i);
}
}}}
Program output : 0,1,1,2,2,3,3,4,5,5,5,6,6,7,7,8
Notes
Bloom Filter1 could help us achieve something similar.
Bucket sort, counting sort, radix sort, and van Emde Boas tree sorting all work best when the key size is small;
for large enough keys, they become slower than comparison sorting algorithms…
Integer Sorting Techniques : http://en.wikipedia.org/wiki/Integer_sorting#Algorithms_for_few_items
Sorting Algorithms : http://en.wikipedia.org/wiki/Sorting_algorithm
1 http://en.wikipedia.org/wiki/Bloom%5Ffilter
Chapter - Algorithms & DS Cracking the Core Java Interviews 112
Q 127. Given 1 million trades objects, you need to write a method that searches if
the specified trade is contained in the collection or not. Which collection would you
choose for storing these 1 million trades and why?
SOLUTION
HashSet is a good choice for storing this collection because it will offer Big O(1) time complexity. In order to
use HashSet we must override equals() and hashcode() method for the Trade Object. If that’s not possible then
we should created a Trade Wrapper class which overrides these methods.
Q 128. I have an Integer array where every number appears even number of time ex-
cept one. Find that number.
SOLUTION
Approach
This problem can be solved by utilizing bitwise operators in O(1) space and O(n) time complexity.
XOR all the number together and the final result would the odd number.
Output:
singleOdd = 5
Chapter - Algorithms & DS Cracking the Core Java Interviews 113
Q 129. how would you check if a number is even or odd using bit wise operator in
Java?
SOLUTION
Least significant bit (rightmost) can be used to check if the number is even or odd.
For all Odd numbers, rightmost bit is always 1 in binary representation.
Notes
We prefer bitwise operator for checking even odd because the traditional way of checking even by n % 2 ==0
is compassionately expensive compared to bitwise & operator (Big O(1) time complexity)
This can be easily checked using bitwise operators in Java. Firstly let's see how a number looks in binary when
it is power of two.
From the figure, we can see that only 1 bit is set for all numbers which are exponent of 2.
The first condition (x!=0) checks if the number is Binary presentation of 2's exponent
positive, because the second conition works only
for positive numbers.
The second condition (x & (x-1)) will return zero for a number which is exponent of two (provided the number is
positive). For example, in case of number 32,
00010000 (25)
& 00001111 (25-1)
--------------------------------
00000000 (0)
Thus through the above code, we are checking if the number is positive and is power of two.
Chapter - Algorithms & DS Cracking the Core Java Interviews 114
Q 131. What is a PriorityQueue? How is it implemented in Java? What are its uses?
SOLUTION
What is a PriorityQueue ?
It is an abstract data type similar to queue but the elements are stored in a sorted order according to some
priority associated with them, and the element with the higher priority is served before the element with lower
priority. Priority is decided using the Comparator provided at the time of its construction. If no comparator is
provided, then the natural ordering of elements is used to prioritize them.
For example, if all elements are of type Integer and no comparator is provided, then the natural order is used
resulting in highest priority to the smallest Integer value.
Given the index of an element, element's children can be accessed in constant time using an random access
array. Children of the element at index i are at indexes (i << 1)+1 and (i << 1)+2. And the parent of an element
at index j is at (j-1) >>1
PriorityQueue Usages
• A network printer where multiple people submit print jobs at the same time, While one big print job is
executing, PriorityQueue could re-arrange other jobs so that the small print jobs (with very less number of
pages) execute on priority compared to big ones.
• Emergency department in any hospital handles patients based on their severity, thus priority queue could
used to implement such logic.
Notes
Binary Heap can be used for solving algorithmic problems, like the following -
• Finding top 10 most frequently used words in a very large file in O(n)
• Finding top 1 million numbers from a given large file containing 5 billion numbers in O(n)
• You have a file with 1 trillion numbers, but memory can hold only 1 million, How would you find the lowest 1
million out of all these numbers ?
Hint - Create a binary-max-heap with 1 million capacity, so the largest number will be at the top. Now go
over each number in the file, compare it with the peek(), if it is smaller then poll() the element and add the
new one. The total complexity should be less than O (n log n). Selection Rank algorithm could also be used
to solve this problem, provided there exists no duplicate number.
Collections.sort() internally calls Arrays.sort() and thus the underlying algorithm for both of these methods is
same. The only difference is the type of input these methods accept.
Merge Sort algorithm is used by Arrays.sort() method as of JDK 6.
Q 133. There are 1 billion cell-phone numbers each having 10 digits, all of them
stored randomly in a file. How would you check if there exists any duplicate? Only 10
MB RAM is available to the system.
SOLUTION
Approach 1
Hash all these numbers into 1000 files using hash(num)%1000, then the duplicates should fall into the same
file. Each file will contain 1 million numbers roughly, then for each file use HashSet to check for the duplicates.
Q 134. What is a Binary Search Tree? Does Java provide implementation for BST?
How do you do in-order, pre-order and post-order Traversal of its elements?
SOLUTION
TreeMap in Java 6
Java provides its Binary Search Tree
implementation in TreeMap class.
8 Root Node
Post-order Traversal
• Traverse the left subtree
• Traverse the right subtree
• Visit the node
Pre-order
preOrder(node){
if(node == null)
return
visit(node)
preOrder(node.left)
preOrder(node.right)
}
1 http://en.wikipedia.org/wiki/Binary_search_tree
Chapter - Algorithms & DS Cracking the Core Java Interviews 117
In-order
inOrder(node){
if(node==null)
return;
inOrder(node.left)
visit(node)
inOrder(node.right)
}
Post-order
postOrder(node){
if(node==null)
return;
postOrder(node.left)
postOrder(node.right)
visit(node)
}
Source Code
The recursive call makes sure that subtree nodes are within the range of its ancestors. The time complexity will
be O(n) since every node will be examined once.
Q 136. How would you convert a sorted integer array to height balanced Binary
Search Tree?
Input: Array {1, 2, 3}
Output: A Balanced BST
2
/ \
1 3
SOLUTION
Algorithm
1. Get the middle element of the sorted array (start+(end-start)/2) and put this element at the root
2. Recursively repeat the same for the for the left and right child
i. Get the middle of the left half and make it left child of the root created in step 1.
ii. Get the middle of right half and make it right child of the root created in step 1.
Java Source
public class SortedArrayToBST {
static class Node {
Node left;
Node right;
int data;
}
http://cslibrary.stanford.edu/110/BinaryTrees.html#java
http://www.geeksforgeeks.org/sorted-array-to-balanced-bst/
http://leetcode.com/2010/11/convert-sorted-array-into-balanced.html
Chapter - Algorithms & DS Cracking the Core Java Interviews 119
Height of a binary tree can be easily calculated using the following recursive algorithm.
Algorithm
1. Base condition - if nod is null then return 0.
2. Calculate height of left sub tree, height of right sub tree, and then return the height of the tree as the max of
two heights+1.
Recursive Algorithm
1. Base Condition - factorial of 1 is equal to 1.
2. Recursive Condition - factorial of n = n*factorial(n-1).
Q 139. How will you swap two numbers using XOR operation?
SOLUTION
Swapping int a and b without any temporary variable can be done using XOR operator, as shown below.
a ^= b;
b ^= a;
a ^= b;
This will result in the swap in values of a and b. Please note that there is no fear of value overflow in this case.
Chapter - Algorithms & DS Cracking the Core Java Interviews 120
Q 140. You have a mixed pile of N nuts and N bolts and need to quickly find the cor-
responding pairs of nuts and bolts. Each nut matches exactly one bolt, and each bolt
matches exactly one nut. By fitting a nut and bolt together, you can see which is big-
ger. But it is not possible to directly compare two nuts or two bolts. Given an efficient
method for solving the problem.
SOLUTION
A simple modification of Quicksort shows that there are randomized algorithms whose expected number of
comparisons (and running time) are O(n log n).
Approach
Pick a random bolt and compare it to all the nuts, find its matching nut and compare it to all the bolts (they
match, the nut is larger, the nut is small). This will divide the problem into two problems, one consisting of nuts
and bolts smaller than the matched pair and the other consisting of larger pairs. Repeat and divide this until all
the nuts and bolts are matched. This is very similar to quick sort in action and achieving the result in O(n log n)
time.
References
http://www.wisdom.weizmann.ac.il/~naor/PUZZLES/nuts_solution.html
http://algs4.cs.princeton.edu/23quicksort/
Q 141. Your are give a file with 1 million numbers in it. How would you find the 20 big-
gest numbers out of this file?
SOLUTION
For more details about Selection Algorithm, please refer to below link
http://en.wikipedia.org/wiki/Selection_algorithm
Chapter - Algorithms & DS Cracking the Core Java Interviews 121
Q 142. Reverse the bits of a number and check if the number is palindrome or not?
SOLUTION
then XOR the number with the reversed number if zero then palindrome
Mirroring will change any given tree into its mirror image. For example,
This tree...
7
/\
4 9
/\
1 3
Java Source1
private void mirror(Node node) {
if (node != null) {
// do the sub-trees
mirror(node.left);
mirror(node.right);
1 http://cslibrary.stanford.edu/110/BinaryTrees.html#java
Chapter - Algorithms & DS Cracking the Core Java Interviews 122
The following mathematical expression can help us writing a method similar to Math.pow(x, n) using squaring
as a technique for achieving exponentiation. This technique greatly reduces the time complexity to O (log n)
compared to normal way of multiplying the number n times.
1 if n = 0;
1/x-n if n < 0;
x n
x.(xn-1/2)2, if n is odd
(xn/2)2, if n is even
}
}
Result
1000
256
Notes
Time Complexity of this algorithm is O (log n) where n is the exponentiation. The number of multiplications
reduces to half on each interation.
else
return x*power(x, y/2)*power(x, y/2);
}
int main(){
int x = 2;
int y = 3;
System.out.println(power(10,3));
}
But the time complexity in this case would be O (n) and space complexity O (1)
Given a class Node, we can easily construct a type safe (Generic) queue which provides two methods -
enqueue and dequeue. Internally this queue keeps two references - first one for the Head of the queue and
second one for the Tail of the queue. When we add new item to the queue, its added to the head, and when we
remove an element then its removed from the Tail (First In First Out).
T dequeue(){
if(first!=null){
T item = first.data;
first = first.next;
return item;
}
return null;
}
Here is the Generic implementation of Stack using linked Nodes. Nodes are linked like in a LinkedList and the
push and pop operations happen on the head of the Linked Nodes.
Node<T> top;
T pop() {
if (top != null) {
T item = top.data;
top = top.next;
return item;
}
return null;
}
T peek() {
return top.data;
}
Q 147. How would you implement a simple Math.random() method for a given range
say (1-16)?
SOLUTION
Generating random numbers is not that easy because there are lots of expectations from a perfect random
number generator (fair distribution, randomness, fast, etc). The scope of this question is just to write a simple
function without worrying about the fairness, speed.
In order to generate a random number, we would require a seed which provides us with the randomness.
System.currentTimeMillis() could be a good substitute for providing seed value in our case.
The value returned by the System.currTimeMillis() is very large and we need to make it fit to our bounds using
the modulus operator (x % n) which will bound the upper value to be less than n.
Q 148. How an elevator decides priority of a given request. Suppose you are in an
elevator at 5th floor and one person presses 7th floor and then 2nd presses 8th floor.
which data structure will be helpful to prioritize the requests?
SOLUTION
Generally elevator's software maintains two different queues - one for the upward traversal and another for
downward traversal along with the direction flag which holds the current direction of movement. At any given
point in time, only single queue is active for the serving the requests, though both the queues can enqueue
requests.
PriorityQueue is used for storing the user requests where priority is decided based on following algorithm.
Requests are removed from the PiorityQueue as soon as they are served. If current floor is 5th and user
presses 4th floor with upward moving elevator, then the requests are queued to the downward movement
priority queue (which is not yet active)
Chapter - Algorithms & DS Cracking the Core Java Interviews 126
Q 149. How would you multiply a number with 7 using bitwise hacks?
SOLUTION
This can be achieved by multiplying the number with 8 and then subtracting the number from the result.
If we left shift bits of a number by 23 then it would be equivalent to multiplying the number by 8.
Q 150. What is the best way to search an element from a sorted Integer Array? What
would be it's time complexity?
SOLUTION
Binary search is best when we want to search from within a sorted collection.
It narrows down the search area to half in each iteration and thus very time efficient.
int low = 0;
int high = list.size()-1;
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found
Worst case Time Complexity for Binary Search is Big O (log n)
Chapter - Algorithms & DS Cracking the Core Java Interviews 127
1 http://datastructuresblog.wordpress.com/2007/03/30/reversing-a-single-linked-list-using-stack/
2 http://crackinterviewtoday.wordpress.com/2010/03/24/reverse-a-single-linked-list-recursive-procedure/
Chapter - Algorithms & DS Cracking the Core Java Interviews 128
Q 152. How would you count word occurrence in a very large file ? How to keep track
of top 10 occurring words?
SOLUTION
There are limited number of natural language words available and all of them can be easily fit into today's
computer RAM. For example oxford English dictionary contains total of around 0.6 million words.
Java Source
public class TopOccurrence {
private final PriorityQueue<Integer> minHeap;
private final int maxSize;
public TopOccurrence(int maxSize) {…}
public void add(int data) {
if (minHeap.size() < maxSize) { // size() is Big O(1)
minHeap.offer(data); // Big O(log(n))
} else if (minHeap.peek() < data) { // peek() is Big O(1)
minHeap.poll(); // Big O(log(n))
minHeap.offer(data); // Big O(log(n))
}
}
public static void main(String[] args) {
TopOccurrence test = new TopOccurrence(3);
test.add(10); test.add(20); test.add(30); test.add(10);test.add(100);
test.print();
}
}
Notes
We preferred to choose Binary Heap over TreeSet because TreeSet provide a get method with Big O(log
n) time complexity over PriorityQueue's peek() method with Big O(1), so its a big time saver for the given
requirement.
Binary Min Heap1 is a complete binary tree2 data structure in which each Node is less than or equal to each of
its children. Heap is very efficient O(1) for finding minima and maxima from a given data set. PriorityQueue in
1 http://en.wikipedia.org/wiki/Heap_%28data_structure%29
2 http://en.wikipedia.org/wiki/Complete_Binary_Tree
Chapter - Algorithms & DS Cracking the Core Java Interviews 129
TRIE - memory is shared between multiple words with common prefix and word count can be maintained along
with the word termination mark, but it would be more time consuming than the HashMap
http://stackoverflow.com/questions/12190326/parsing-one-terabyte-of-text-and-efficiently-counting-the-number-
of-occurrences
Selection Sort4 could be used for tracking kth smallest element and then all others can be found by comparing
with the kth smallest. This would be memory efficient but not time efficient
Functionally both are same except the single difference that a hash table is one of the legacy collection class
which was introduced well before the Java Collection Framework.
Both of these classes implement Map interface and are part of Collections framework as of JDK 2. Hashtable
implements one extra interface - Dictionary which Hashmap does not.
HashMap should be preferred if thread-safety is not required, and ConcurrentHashMap should be preferred to
Hashtable if highly concurrent implementation is required.
An Iterator class provides us with 3 methods - next(), hasNext() and remove(). Every Collection in Java is
Iterable - posses an iterator to allow traversal and removal its underlying elements.
ListIterator - It is a specialized iterator for lists that allows to traverse the list bidirectionally, modify the list
during iteration, and obtain the iterator's current position in the list. It allows complete modification - remove,
add and update operations are provided.
3 http://en.wikipedia.org/wiki/Directed_acyclic_graph
4 http://en.wikipedia.org/wiki/Selection_algorithm
Chapter - Algorithms & DS Cracking the Core Java Interviews 130
Q 155. What do you understand by Token Bucket Algorithm. What are its applications
?
SOLUTION
Token bucket algorithm is used to define the upper limits on bandwidth and burstiness on the data transmission
in a software application. The token bucket algorithm is based on an analogy of a fixed capacity bucket into
which tokens, normally representing a unit of bytes or a single packet of predetermined size, are added at a
fixed rate.
Applications
1.) To provide download bandwidth limits in software applications like torrent & download managers.
2.) To control the download speed on 3G network by our cellular provider.
Implementation
1. ) Refill Strategy
2. ) Maximum Capacity of Tokens - this is the
maximum amount of tokens that a client can ask for,
otherwise an exception is thrown.
3.) Size - it is the current size of the bucket which
will keep on changing as it is refilled after specific
interval and emptied by the clients.
@Override
public String toString() {
return "Capacity : " + capacity + ", Size : " + size;
}
}
public static TokenBucket newFixedIntervalRefill(long capacityTokens, long refillTokens, long period, TimeUnit unit)
{
TokenBucket.RefillStrategy strategy = new FixedIntervalRefillStrategy(refillTokens, period, unit);
return new TokenBucket(capacityTokens, strategy);
}
Chapter - Algorithms & DS Cracking the Core Java Interviews 132
/**
* Create a FixedIntervalRefillStrategy.
*
* @param numTokens The number of tokens to add to the bucket every interval.
* @param interval How often to refill the bucket.
* @param unit Unit for interval.
*/
public FixedIntervalRefillStrategy(long numTokens, long interval, TimeUnit unit) {
this.numTokens = numTokens;
this.intervalInMillis = unit.toMillis(interval);
this.nextRefillTime = new AtomicLong(-1L);
}
@Override
public long getIntervalInMillis() {
return intervalInMillis;
}
}
Chapter 5
Object Oriented Design
Q 156. What are the key principles when designing a software for performance effi-
ciency ?
SOLUTION
1. Stateless design using REST can help achieve scalability whereever possible. In such application, minimal
session elements need to be replicated while distributing the application over multiple hosts. Users can
save their favorite URLs and thus there should be no need for the page flow, if we use REST.
2. Logging can be done asynchronously to save precious time of a method call.
3. More processes vs more threads can be configured based on the demand of the target application.
Generally it is advised to have a JVM with up to 2 GB memory because increasing memory beyond 2 GB
incurs heavy GC pauses, and if we require more processing then we prefer to have a separate process
for the JVM altogether. Multiple independent tasks should be run in parallel. Tasks can be partitioned to
improve the performance.
4. If we improve upon the concurrency of the software piece, then we can increase its scalability. This can be
achieved by reducing the dependency on the shared resources. We should try utilizing the latest hardware
optimization through JAVA as much as possible. For example we can use Atomic utilities provided in java.
util.concurrent.atomic package, or Fork & Join to achieve higher throughput in concurrent applications. We
should try holding the shared locks for as little time as possible.
5. Resource pooling and caching can be used to improve the processing time. Executing jobs in batches can
further improve the performance.
6. Picking up appropriate algorithm and data structure for a given scenario can help optimize the processing.
7. If we are using SQL in our application then we should tune the SQL, use batching whereever possible and
create indexes on the essentials table columns for faster retrievals.
8. We should tune our JVM for optimum memory settings (Heap, PermGen, etc) and Garbage collection
settings. For example if we do lot of text processing in our application with big temporary objects being
created, then we should have larger Young Generation defined so that frequent gc run does not happen.
9. Keep up to date with new technologies for performance benefits.
Using Java 1.5 onwards, this problem can be easily solved using BlockingQueue implementation, as
demonstrated below.
Chapter - OO Design Cracking the Core Java Interviews 134
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
Q 158. How would you implement a Caching for HttpDownloader Task using Decora-
tor Design Pattern ?
SOLUTION
Decorator Design pattern makes it very easy to enrich the behavior of an existing class by adding wrapper over
it, thus maintaining the loose coupling at the same time. Let's first discuss the overall design for implementing
caching to Real Http Downloader Task.
@Override
public File download(URI uri, String fileName) throws IOException {
Path path = Paths.get(fileName);
long totalBytesRead = 0L;
HttpURLConnection con = (HttpURLConnection) uri.resolve(fileName).toURL().openConnection();
con.setReadTimeout(10000);
con.setConnectTimeout(10000);
totalBytesRead = fileChannel.transferFrom(rbc, 0, 1 << 22); // download file with max size 4MB
System.out.println("totalBytesRead = " + totalBytesRead);
fileChannel.close();
rbc.close();
} catch (FileNotFoundException e) {
Chapter - OO Design Cracking the Core Java Interviews 136
e.printStackTrace();
}
return path.toFile();
}
}
@Override
public File download(URI uri, String fileName) throws IOException {
if (cache.contains(uri))
return cache.get(uri);
return delegate.download(uri, fileName);
}
}
Here we see that CachedHttpDownloader implements the same interface HttpDownloader and it has a
delegator object which holds the instance of RealHttpDownloader which if required download from the Http.
Terminology
Publication - A Publication is a written work meant for distribution to public (it has author, publisher)
Book - A Book is a specific type of publication extending the abstract Publication
Journal - A journal is also a specific type of publication which extends some properties of Publication.
Transaction - Return, Borrow and Renew are three main types of transactions happening inside a library.
Gathering Requirements
Design
Journal and Book are specific type of Publication so we can map them into Object Oriented World by making
Chapter - OO Design Cracking the Core Java Interviews 137
Publication Class as Abstract and then Book, Magazine and Journal extending the Publication.
Similarly borrow, return and renew are the type of transaction that a library user will typically be performing.
Transaction can be made an interface and Return, Borrow & Renew will implement this interface.
State Design Pattern along with generalization can be used to solve the problem.
Gathering Requirements
1. Authenticate user with PIN
2. Select account type - Current Account, Saving Account
3. Select Operation : Balance Inquiry, Withdrawal or Deposit
4. Execute any of the above operation after supplying necessary input.
5. Print the transaction if required.
Design
We can utilize state design pattern for 2nd step mentioned above to maintain the state of account selected by
the user.
Account has two states - Saving Account & Current Account. User will select one of these account for execut-
ing a transaction, and the appropriate state will be set at that moment.
3rd step can be solved using polymorphism where Balance Inquiry, Withdrawal & Deposit represents a Trans-
action which can be executed.
Prompt user if the user requires receipt or not and accordingly execute the action.
Chapter - OO Design Cracking the Core Java Interviews 139
Designing a web crawler is very complex task and can not be explained in books in entirety. We will discuss
few steps that can make a very simple Crawler running on your system.
while(!queue.isEmpty()){
ParentLink=queue.removeFirstElement(){
Page = Fetch(ParentLink)
You can Create a ThreadPoolExecutor and a CallableTask which can fetch URL from the above created Queue
and get the HTTP contents and index/crawl them. HttpClient can be used (JSoup, HtmlUnit, etc can also be
used) to fetch the contents/links from a web page. IOChannels can be utilized to download the HTML contents
from a URL in an efficient manner.
Q 162. Design Phone Book for a mobile using TRIE (also known as prefix tree).
SOLUTION
TRIE is an ordered tree data structure which store associative arrays and the keys are usually alphabets. The
position in the tree defines the key with which it is associated. The root node is generally empty (\0) and it con-
tains upto 26 children each representing a alphabet character. All descendants of a given node have a com-
mon prefix of string associated with that node. Each node contains a flag which tells if the current node is full
word or not. In the diagram on right, pink colored boxes shows the full words.
The term trie comes from retrieval \0
TRIE is a generally good data structure for
storing dictionary like data. Phone book can
be perfectly implemented using TRIE which
will save memory as well as time for prefix A B C D E ... Z
searching.
Q 163. How would you resolve task's inter dependency, just as in maven/ant.
Let's consider the following task dependencies.
Task Dependent On
3 1,5
2 5,3
4 3
5 1
Here first row states that task 3 is dependent on task 1 and task 5, and so on. If the two consecutive tasks
have no dependency, then they can be run in any order.
SOLUTION
Approach 1
It is a typical Graph traversal problem, that can be solved using Topological Sorting Algorithm1 in linear time
O(|V| + |E|),
Where
V = number of nodes
E = number of edges
2 4
5 3
1
Direct Acyclic Graph for the Task Dependencies
1 http://en.wikipedia.org/wiki/Topological_sorting
Chapter - OO Design Cracking the Core Java Interviews 143
First, find a list of "start nodes" which have no incoming edges and insert them into a set S; at least one such
node must exist in an acyclic graph.
Java Source
@Override
public boolean equals(Object obj) {
Edge e = (Edge)obj;
return e.from == from && e.to == to;
}
}
}
//while S is non-empty do
while(!S.isEmpty()){
//remove a node n from S
Node n = S.iterator().next();
S.remove(n);
//insert n into L
L.add(n);
}
}
}
if(cycle){
System.out.println("Cycle present, topological sort not possible");
}else{
System.out.println("Topological Sort: "+ Arrays.toString(L.toArray()));
}
}
}
Approach 2
We can use HashMap to solve this problem.
Q 164. How would you sort 900 MB of data using 100 MB of RAM ?
What is external sort ?
SOLUTION
Algorithm1
External Merge Sort is the answer to the above mentioned problem.
1. Read 100 MB of data in main memory and sort by some conventional method like quicksort.
2. Write the sorted data to the disk.
3. Repeat step 1 & 2 until all the data is in sorted 100 MB chunks (9 chunks) which now need to be merged
into single output file.
4. Read first 10 MB of each sorted chunk into input buffer in main memory and allocate remaining 10 MB for
the output buffer.
5. Perform 9 way merge and store the result in output buffer.
Similar Questions
Question2
There are 2 huge files A and B which contains numbers in sorted order. Make a combined file C which contains
the total sorted order.
Solution
Merge Sort technique.
Question
There are k files each containing millions of numbers. How would you create a combined sort file out of these ?
Solution
• Use a binary-min heap (increasing order, smallest at the top) of size k, where k is the number of files.
• Read first record from all the k files into the heap.
• Loop until all k files are empty.
• Poll() the minimum element from the binary heap, and append it to the file.
• Read the next element from the file from which the minimum element came.
• If some file has no more element, then remove it from the loop.
• In this way we will have one big file with all number sorted
• Time complexity will be O (n log k)
1 http://en.wikipedia.org/wiki/External_sorting#External_merge_sort
2 http://en.wikipedia.org/wiki/Merge_sort
Chapter - OO Design Cracking the Core Java Interviews 147
Q 165. How would you design minimum number of platforms so that the buses can
be accommodated as per their schedule ?
BUS Arrival Time (HRS) Departure Time (HRS)
A 0900 0930
B 0915 1300
C 1030 1100
D 1045 1145
E 1100 1400
Bus Schedule for a given Platform
SOLUTION
This problem is about finding the peak time when maximum number of buses are waiting to get into platform.
Ideally we would not like to stop a bus outside the platform so every single bus would require one platform.
So in this problem, the maximum number of buses arriving at the same time during the peak time of day will
decide the number of platforms.
Approach
Calculate the peak time of the buses from the given bus schedule, the number of buses at the peak time will
give us the number of platforms.
Step 1
Create a single array of bus timing after append A (for Arrival) and D (for departure) to each bus time.
So the above table should now become a one dimensional array like this :
[0900A, 0930D, 0915A, 1300D, 1030A, 1100D, 1045A, 1145D, 1100A, 1400D]
Step 2
Sort the above array in ascending order (Natural Order)
[0900A, 0915A, 0930D, 1030A, 1045A, 1100A, 1100D, 1145D, 1300D, 1400D]
Step 3
Now traverse the entire array and count the maximum number of Buses at peak time.
Pseudo Code
var counter, max, peakTime;
for(each time entry){
if(arrival)
counter++;
else
counter--;
if(counter > max)
max= counter
peakTime= time entry;
}
Here the max is the maximum number of platforms that should be built for accommodating all the
buses at peak time as per given time table.
Chapter - OO Design Cracking the Core Java Interviews 148
Java Source
Collections.sort(scheduleTokens);
Q 166. There is a pricing service which connects to Reuters & Bloomberg and fetches
the latest price for the given Instrument Tics. There could be multiple price events for
the same Stock and we need to consider the latest one. Design a service to show pric-
es for the Top 10 stocks of the Day ?
SOLUTION
This problems requires us to collect price feeds, remove duplicates based on InstrTic keeping the latest one,
and then finally capture the top 10 feeds based on price. Keeping in mind that we need to remove duplicates
based on Tic# and then sorting based on price - 2 different fields to act upon.
HashSet is a good option for removing duplicates from the collection, so iterate over the entire collection of
feeds and then add them to HashSet, rest will be taken care by HashSet. But we need to override equals and
hashcode based on Tic# so as to remove the duplicate TIC# entries. So our first requirement of removing
duplicates will be done after implementing this.
Now for finding top 10 feeds based on prices, we can use PriorityQueue (min heap) of fixed size 10. While
iterating over the HashSet entries we will check if the price of the feed is greater than the peek entry of
PriorityQueue, if yes then poll the entry and offer the new one. This way we will get a list of top 10 priced feeds.
Make the PriorityQueue's size configurable so that it can be adjusted as per the requirement.
Q 167. Design a parking lot where cars and motorcycles can be parked. What data
structure to use for finding free parking spot in Parking Lot program? Assume there
are million of parking slots.
SOLUTION
Approach
2. Create parking manager which will track the free parking slots using a Queue for fast retrieval, and occupied
vehicle mapping will be stored using a HashMap for fast O(1) retrieval. Whenever a slot gets free, remove it
from the HashMap and add it into Queue, and if new vehicle comes in then pick slot from the head of queue
and store the mapping in hashmap. Separate Queue & HashMap could be used for Motor Bike, Truck & Car
vehicle type.
A free list is a data structure used in a scheme for dynamic memory allocation. It operates by connecting
unallocated regions of memory together in a linked list, using the first word of each unallocated region as a
pointer to the next. It's most suitable for allocating from a memory pool, where all objects have the same size.
Free lists make the allocation and deallocation operations very simple. To free a region, one would just link it to
the free list. To allocate a region, one would simply remove a single region from the end of the free list and use
it. If the regions are variable-sized, one may have to search for a region of large enough size, which can be
expensive.
Maintain a PriorityQueue for free parking space, use hashmap for the filled spaces. In this manner it would be
easier to find the free space and to find the parked object. Assume that the parking space on the lower floor
gets more priority than the parking space on the higher floor, when a new car comes in just pick the top most
entry from the parking queue and park the object
Chapter - OO Design Cracking the Core Java Interviews 151
Q 168. Implement the classes to model two pieces of furniture (Desk and Chair) that
can be constructed of one of two kinds of materials (Steel and Oak). The classes repre-
senting every piece of furniture must have a method getIgnitionPoint() that returns the
integer temperature at which its material will combust. The design must be extensible
to allow other pieces of furniture and other materials to be added later. Do not use mul-
tiple inheritance to implement the classes.
SOLUTION
Design
Abstract Factory along with Bridge Pattern can solve this problem.
public interface Furniture {
public int getIgnitionPoint();
}
Notes
Q 169. How would you simulate a digital Clock in Object Oriented Programming Lan-
guage?
SOLUTION
The simplistic design consists of creating a second hand, which when completes 60 seconds, advances the
minute hand by 1 minute. Similarly Hour hand is advanced by 1 hour when minute hand completes its 60
minutes. This can be emulated in software by registering MinuteHand as an Observer to SecondHand, and
HourHand as a observer to MinuteHand. The only real subject in this case is the Second Hand which keeps
ticking once every second.
ClockController is the class that manages the overall state of the clock and provide us the option to start & stop
the clock.
@Override
public void increment() {
count++;
if(count>=60){
count=0;
observer.increment();
}
}
@Override
public void display(){
System.out.println("seconds = " + count);
}
}
@Override
public void increment() {
count++;
Chapter - OO Design Cracking the Core Java Interviews 155
if(count>=60){
count=0;
observer.increment();
}
}
@Override
public void display() {
System.out.println("minutes = " + count);
}
}
@Override
public void increment() {
count++;
if(count>=24){
count=0;
}
}
@Override
public void display() {
System.out.println("hours = " + count);
}
}
void display();
}
Chapter - OO Design Cracking the Core Java Interviews 156
Q 170. How would you design an elevator system for multi story building? Provide
with request scheduling algorithm & Class diagram for the design.
SOLUTION
For a single elevator system, normally two different queues are used to store the requests. One queue is
used to store upward requests and other queue used to store the downward requests. Queue implementation
used is the BlockingPriorityQueue which maintains the priority of its requests based on the floor numbers.
For upward motion, the lower floor number has the higher priority and opposite for the downward motion of
elevator. A 2 bit flag can be used to store the current direction of the elevator where 00 represents Idle, 01 for
upward motion, 11 for the downward motion.
A Bit Vector can be used to map the floor numbers, and if someone presses the floor button then the
corresponding bit can be set to true, and a request is pushed to the queue. This will solve the duplicate request
problem from outside the elevator at the same floor. As soon as the floor request is served, the corresponding
bit is cleared and the request is removed from the queue.
The actual software application for handling elevator requires lot of interaction with the hardware and is out of
scope for this book.
Q 171. Given two log files, each with a billion username (each username appended to
the log file), find the username existing in both documents in the most efficient man-
ner?
SOLUTION
Pseudo Code
Q 172. Design DVD renting system, database table, class and interface.
SOLUTION
In order to make a Online DVD rental Store we would require a database, web server (Jetty), hibernate layer to
access the database, Restful Webservices (Jersey), HTML and JavaScript for the GUI.
@Entity
@Table(name = "DVD")
class DVD {
final int charge;
final String name;
final String id;
String category;
}
class RentalFacade{
void rentDVD(DVD dvd) {}
void returnDVD(DVD dvd) {}
int calculateRent(DVD dvd) {return 0;}
@Path("/dvd")
public class MachineResource extends AbstractResource {
@GET
@Path("getAll")
@Produces({APPLICATION_JSON})
public Response getAllDVD() {
return Response.ok(fromContext(DAO_FACADE, RentalFacade.class).searchByCategory("")).build();
}
Chapter 6
Puzzles & Misc
Q 173. Why man holes are round in shape ?
SOLUTION
What we need is a solution that minimizes our maximum regret. The examples above hint towards what we
need is a strategy that tries to make solutions to all possible answers the same depth (same number of drops).
The way to reduce the worst case is to attempt to make all cases take the same number of drops.
As I hope you can see by now, if the solution lays somewhere in a floor low down, then we have extra-
headroom when we need to step by singles, but, as we get higher up the building, we’ve already used drop
chances to get there, so there we have less drops left when we have to switch to going floor-by-floor.
If it doesn’t break, rather than jumping up another n floors, instead we should step up just (n-1) floors (because
we have one less drop available if we have to switch to one-by-one floors), so the next floor we should try is
floor n + (n-1)
Similarly, if this drop does not break, we next need to jump up to floor n + (n-1) + (n-2), then floor n + (n-1) +
(n-2) + (n-3) …
We keep reducing the step by one each time we jump up, until that step-up is just one floor, and get the
following equation for a 100 floor building:
n + (n-1) + (n-2) + (n-3) + (n-4) + … + 1 >= 100
This summation, as many will recognize, is the formula for triangular numbers (which kind of makes sense,
since we’re reducing the step by one each drop we make) and can be simplified to:
n (n+1) / 2 >= 100
This is a quadratic equation, with the positive root of 13.651 (Which we have to round up to 14. This is not a
John Malkovich movie!).
A door will be left closed if even number of door toggling iterations for that particular door. For all odd number
toggling, the door state will be open.
For example,
The factors of 1 are 1 and itself. It has one factor - odd factors
The factors of 2, 3, and 5 are 1 and themselves. They have two factors - even factors
The factors of 4 are 1 and itself, as well as 2. 4 has three factors - odd factors
After analysis we can find that every number has even number factors except the number which are perfect
squares.
1 = 1x1; (both the factors are single number 1)
4=1x4, 4x4 (both the numbers are single number 4), 4x1;
9=1x9, 3x3 (both the numbers are single number 3), 9x1;
So in case of perfect squares, both the factors are same number, that trick will solve this problem.
So we can conclude that odd number of iterations will happen for all the numbers which are perfect square
numbers and those doors will be in Closed state (initially opened)
1,4,9,16,25,36,49,64,81,100
Chapter - Puzzles Cracking the Core Java Interviews 160
Q 176. What is probability of a daat, hitting closer to centre of a circle rather than cir-
cumference ?
SOLUTION
Answer is 25%
Let's understand this question using the figure shown here. Daat will hit closer to centre of circle than the
circumference when daat hits in a area whose radius is half the area of circle. The area of interest is shown in
blue color in the given figure, and total area is the blue + yellow area.
= π x (R/2)2 / (π x R2)
=1/4
=25%
Q 177. What is financial Instrument, Bond, equity, Asset, future, option, swap and
stock with example each ?
SOLUTION
Bond
A bond is a debt security under which the issuer owes the holders a debt and depending on the terms of the
bond, is obliged to pay them interest/coupon and to repay the principal at a later date, termed as maturity.
Stock
Constitutes the equity stake of its owners.
Equity
Equity is the residual claim or interest of the most junior class of investors in asset after all liabilities are paid.
Asset
Assets are economic resources. Anything tangible or intangible that is capable of being owned/controlled to
produce value and that is held to have positive economic value is considered an asset. In other words, Asset
represents value of ownership that can be converted into cash.
Capital = Assets - Liabilities
Coupling
Coupling is the degree to which each program module relies on each one of other module in the software
application.
Chapter - Puzzles Cracking the Core Java Interviews 161
Books
Design Patterns in Java - Head First
Concurrency In Practice by Brian Goetz
Effective Java 2nd Edition by Joshua Bloch
Algorithms 4th edition : http://algs4.cs.princeton.edu/home/
Cracking the Coding Interview
Technology Forums
http://www.geeksforgeeks.org/fundamentals-of-algorithms/
http://www.careercup.com
http://www.stackoverflow.com
Question : How would you implement a optimistic database locking using various techniques ?How would you
avoid non-repeatable reads ?
Hint: https://blogs.oracle.com/carolmcdonald/entry/jpa_2_0_concurrency_and
https://blogs.oracle.com/enterprisetechtips/entry/preventing_non_repeatable_reads_in
Question : What is the best way to implement PriorityQueue ?
Question : How does quick sort works ?
Question : How would you print rhyming words from a stream using PipedStreams ?
list of words -> reverse -> sort -> reverse
http://www.cs.nccu.edu.tw/~linw/javadoc/tutorial/java/io/streampairs.html#PIPED
http://www.dca.fee.unicamp.br/projects/sapiens/calm/References/Java/tutorial/essential/io/pipedstreams.html
Question : How would redesign executors framework by reducing the thread contention ?
http://today.java.net/article/2011/06/14/method-reducing-contention-and-overhead-worker-queues-multithread-
ed-java-applications
Question : How would you find nth highest salary from a table using SQL ?
"Select * From Employee E1 Where N = (Select Count(Distinct E2.Salary) From Employee E2 Where
E2.Salary >= E1.Salary)"
Question : How would you delete duplicate rows from a table ?
Question : How will you find the Lowest Common Ancestor in a Binary Search Tree ?
Question : Your are give a file with milions of numbers in it. Find the duplicate numbers in it.
Question : Quickest way to Find the missing number in an array of 1 to n. slot in array is blank, Find 2 missing
number..
Hint : Priority queue with distance from the current floor as the inverse of priority
Question : How would you traverse Binary Search tree using iterations ?
Question : what do you understand by MVC design pattern ?
Question : What is dependency Injection design pattern ?
Question : TreeMap vs ConcurrentSkipListMap ?
Question : Inline sorting of an array where max element in the array is equal to size of the array itself ? and
most of the elements are unique.
Question : InOrder traversal of a binary search tree results in Ascending order sorting of elements.
Question : Find the top 10 most frequent words in a file.
Hint: use hashmap to store word occurrence count and for every 10th occurrence update the values in a binary
heap (PriorityQueue) with the maximum count. PriorityQueue can just store the top 10 elements
http://stackoverflow.com/questions/742125/how-to-find-high-frequency-words-in-a-book-in-an-environment-low-
on-memory
http://stackoverflow.com/questions/358240/space-efficient-data-structure-for-storing-a-word-list
http://en.wikipedia.org/wiki/Bloom%5Ffilter
Question : How would you lower thread contention using Dequeue.
http://today.java.net/article/2011/06/14/method-reducing-contention-and-overhead-worker-queues-multithread-
ed-java-applications
Question: What is huffman encoding technique ?
http://en.wikipedia.org/wiki/Huffman_coding
Question : Use Stack to implement a Queue… you can use 2 stacks
Question : Use 2 stacks to implement getMin() function with O(1) complexity.
Question : BFS and DFS of a Tree
Question :3 ants are at 3 vertices of a triangle. They randomly start moving towards another vertex. What is the
probability that they don't collide?
Hint - 6/8, total scenarios = 2x2x2 =8, collision will occur for 6 (2 scenarios will not
Continued on 163
Chapter - Puzzles Cracking the Core Java Interviews 163
encounter collision)
Question :You have 2 ropes which burns in 1 hr each..how will you measure 45 min of time ?
Question :"given 1000 bottles of juice, one of them contains poison and tastes bitter. Spot the spoiled bottle in
minimum sips?"
Question : How would you detect a circular loop inside a linked list ?
Question : How would you calculate size of a linked list having circular loop in it ?
Circular Linked List - take 2 pointers
increment one by +1;
increment other by +2
they will first meet in N iterations
length of stem = n/2;
Question : There is a sorted Array of Integer but the array is rotated. How would you fix it using binary search ?
why choose binary search ?
http://leetcode.com/2010/04/searching-element-in-rotated-array.html
http://www.careercup.com/question?id=2800
http://xorswap.com/questions/77-implement-binary-search-for-a-sorted-integer-array-that-has-been-rotated
Question: How would you mirror a binary tree ?
Question : I want to implement 2 different display score boards for the IPL cricket match, one specific to IPL
another for T20. Which design pattern will rescue you in this case ?
Question : What is contract between equals() and hashcode() method ?
Question : How would you write a hashcode() method for a class having two fields ? Can we multiply hashcode
with a random number ?
Question : Explain Fork and Join with concrete example ?
http://www.oracle.com/technetwork/articles/java/fork-join-422606.html
http://www.oracle.com/technetwork/articles/java/trywithresources-401775.html
http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
http://fahdshariff.blogspot.in/2012/08/java-7-forkjoin-framework-example.html
http://www.javabeat.net/2012/06/simple-introduction-to-fork-join-framework-in-java-7/
http://www.vogella.com/articles/JavaConcurrency/article.html
Question : http://tech-queries.blogspot.in/2008/11/sort-array-containing-0-and-1.html
Question : Why wait() and notify() are at Object level rather than Thread level ?
Answer : http://javarevisited.blogspot.in/2012/02/why-wait-notify-and-notifyall-is.html
Question : Why not to choose static factory method in place of singleton design pattern ?
Question: There is an JPA entity having lazy loading items. You want to use this entity to render a view page
which will display this entity. What all options do you have to overcome the lazy loading in this case ?
http://wiki.eclipse.org/Introduction_to_Mappings_(ELUG)#Indirection_.28Lazy_Loading.29
http://java.dzone.com/articles/jpa-lazy-loading
http://www.javacodegeeks.com/2012/07/four-solutions-to-lazyinitializationexc_05.html
Question : find median of two sorted array
Hint :http://www.geeksforgeeks.org/median-of-two-sorted-arrays/
Question : When no direct method is found, the most specific method is chosen by the JVM for a method call ?
example ?
Question : What are various techniques for achieving thread safety in Java : Immutable, ThreadLocal, Syn-
chronized access, non-blocking algo using CAS.
Question : http://www.geeksforgeeks.org/find-the-two-repeating-elements-in-a-given-array/
Question : Write a print method for printing Top N numbers from an array ?
Question : Given a collection of Trades. Write an algorithm to remove duplicates based on Tic# and sorting
based on NAV.
Question : Design a vending machine.
Question : How would you implement a BoundedBuffer using Lock and Condition ?
continued on 164
Chapter - Puzzles Cracking the Core Java Interviews 164
http://www.baptiste-wicht.com/2010/09/java-concurrency-part-5-monitors-locks-and-conditions/
Question : Give an example of timed locking using explicit locking in Java.
Hint : http://codeidol.com/java/java-concurrency/Explicit-Locks/Lock-and-ReentrantLock/
Question : Fibonacci Series using various techniques - recursive, iterative, Big O(1)
Question : Left Outer Join vs Right Outer Join ?
Hint : http://en.wikipedia.org/wiki/Join_(SQL)#Inner_join
Question : Angle between Minute Hand and Hour hand of a clock ?
Question : How is a TreeSet implemented in Java ?
Question : How does google analytics works without causing a extra load on your web server ?
Hint : Javascript is used to hit a google server with the required identifier then the new site is visited.
Question: How would you avoid data corruption by a web page which allows a update a database row, and 2
users try to update the same row simultaneously.
Question : How does batch update works in Java ?
Question : Find the first common ancestor of two given nodes in a binary tree in o log n space complexity and
O(n) time complexity.
Hint - 1. do DFS, 2. during DFS if you find one of the nodes store the stack contents (path from the root) repeat
the same process for the second node. this requires 2nlogn space. 3. Now compare both of these paths from
the root, the last common node in the path is the first common ancestor. this takes logn time avg case and n in
worst case
Question : What is a BloomFilter? How is it better than hashmap in certain casess?
http://en.wikipedia.org/wiki/Bloom%5Ffilter
"Sort An Array Containing '0' And '1'
Sort An Array Containing '0','1' And '2'
http://tech-queries.blogspot.in/2008/11/sort-array-containing-0-and-1.html
Dutch flag algo."
http://en.wikipedia.org/wiki/Dutch_national_flag_problem
Discuss the numbering system.
traceroute command and nslookup
Natural ordering in search operation and stable search
TRIE
Sorting and Searching
Atomic package and CAS, non blocking algorithms
Database indexes clustered indexes, query plan etc, Outer and Inner Join
UNIX stuff cut grep ps etc, piping the output
Question : How would you implement a Trie in Java. Suppose you want to implement a Auto-suggest function-
ality using Java where user presses a letter and all the words starting with that letter are listed in the sugges-
tion box. Which datastructure would you choose for this scenario ?
Question: How would you implement ThreadPool in Java 1.4 ?
Question: How would you implement StringBuffer class, so that it doesn’t create un-necessary imtermediate
string objects upon modifications ?
Question : Write a method to count the size of a LinkedList given a Node. There could be a circular loop inside
the list, hence your method should be smart enough to handle such situation gracefully.
Hint : http://crackinterviewtoday.wordpress.com/2010/03/16/loop-in-a-linked-list/
Question : How would you design a FileSystem for showing just the hierarchy of files ? File Interface & then
File and DIR as the subclasses.
How would you map department and employee table into Java Objects ? What kind of relationship would you
put there? Lazy loading ?
Question : Which object construction mechanism you prefer in Spring DI - constructor based or setter based ?
Hint- setter based injection is preferred mechanism for injecting dependencies, but at times constructor based
injection is preferred when mandatory dependencies need to be injected.
Continued on 165
Chapter - Puzzles Cracking the Core Java Interviews 165
Question - We have list of One million numbers on which some mathematical function needs to be applied,
How would you make algorithm concurrent ?
Hint - You can use Executor framework for spawning multiple workers, and use a queue to feed the one million
input numbers. There could be another strategy where you divide the one million numbers into N parts and
feed each of these parts to one worker. You can also think of atomic package for handling such scenario.
There is an un-ordered stack of 5 elements and we have a method nextMinimum() which returns us the
subsequent next minimum element in O(1). suppose we have 2,3,1,4,5 as the elements, then first invocation
will return us 1, second 2, third 3.
Hint - maintain a queue which maintains the sorted references to the underlying stack.
What is Spring bean lifecycle ?
What is embeddable in JPA
How do you performance tune an application - By GC, by changing algorithm, using different data structure
which is more appropriate for a given scenario.
Question: Design multi-player Chess Game using Class Diagrams.
Question: Design a Restaurant Reservation system.
Solution : http://www.careercup.com/question?id=15062886
Question: Design SkyDrive.
http://www.careercup.com/question?id=14692764
http://thought-works.blogspot.in/2012/11/object-oriented-design-for-cloud-based.html
Question: Design Online Auction Site.
Solution : http://thought-works.blogspot.in/2012/11/object-oriented-design-for-online.html
Question: Design a Train & reservation system. Give class structure and design UML
Solution :
http://www.careercup.com/question?id=3220674
Question: Write a 2 Thread application where one thread prints even number and the other thread prints odd
numbers and both of them act in a synchronized manner.
Question : Security and Performance Tuning of a REST and Ajax Application
http://www.oracle.com/technetwork/articles/java/securityperf-rest-ajax-177520.html
http://www.oracle.com/technetwork/articles/javaee/jax-rs-159890.html
Question : How does Tree Balancing works ? left and right rotation ?
Question : How does ReentrantReadWriteLock works internally ?
Question : What do you understand by volatile keyword ?
http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html
Question : Why would you use Suffix Tree for searching?
Write a chapter on glossary. Mention few keywords used in Java and financial word. jargons
Can you tell me with example the Usage of ThreadLocal class ? Calendar class, JDBC transaction
management, etc.
Question : Synchronization of getClass() in case of inheritance, will lock the actual class rather than the whole
hierarchy.
Question: How would you convert a sorted integer array to height balanced binary tree. ?
Question: Discuss about non-blocking algorithms using CAS ?
https://www.ibm.com/developerworks/java/library/j-jtp04186/
Discuss the numbering system.
traceroute command and nslookup
TRIE and Sorting and Searching
Database indexes clustered indexes, query plan etc, Outer and Inner Join
UNIX stuff cut grep ps etc, piping the output
Question : What are the ways to achieve thread-safety in a concurrent program ?
Question : How will you deal with ConcurrentModificationException ?
Question : How to expose a method over JMX using MBean ?
Continued on 166
Chapter - Puzzles Cracking the Core Java Interviews 166
Thread.interrupt() puzzle.
Discuss on External Sorting
http://www.careercup.com/question?id=83696
Question : Design a solution to print employee hierarchy in Java given a employee record.
Java Software in Harmony with the Hardware - Mark Thompson
http://mechanical-sympathy.blogspot.in/2012/10/compact-off-heap-structurestuples-in.html
http://mechanical-sympathy.blogspot.in/2011/07/false-sharing.html
http://mechanical-sympathy.blogspot.in/2011/12/java-sequential-io-performance.html
Question : How would you find kth highest number in a list of n Numbers ?
http://en.wikipedia.org/wiki/Selection_algorithm
http://stackoverflow.com/questions/3628718/find-the-2nd-largest-element-in-an-array-with-minimum-of-com-
parisom
http://stackoverflow.com/questions/251781/how-to-find-the-kth-largest-element-in-an-unsorted-array-of-length-
n-in-on
Question: Design Coffee maker (Vending Machine)..provide some class diagram
Solution : http://www.careercup.com/question?id=3171714
http://stackoverflow.com/questions/7067044/java-algorithm-to-solve-vendor-machine-change-giving-problem
Command design pattern with Factory
CoffeeBuilder [ Abstract ]
Cappucino [ Concrete] ....
CoffeeMaker <---- director
Coffee <-- Product
Builder + Factory Method
Question: How do you represent the following expression in "class design": (5*3)+(4/2) ? How would an algo-
rithm that computes the value of this expression work?
http://www.careercup.com/question?id=65911
Question : How would you design Money class, which holds currency as well as amount of money ?
Hint : http://stackoverflow.com/questions/1359817/using-bigdecimal-to-work-with-currencies
http://stackoverflow.com/questions/11434938/display-curreny-value-in-india-as-rs-100-using-java
http://www.javapractices.com/topic/TopicAction.do?Id=13
How would you perform tree rotation to balance a tree.
Question : Write a function which logs/writes messages to files asynchronously . Multiple thread should be
able to write to different files concurrently e.g. if thread A want to write to a file ‘FA’ at the same time thread B
wants to write to a file ‘FB’ then both threads should be able complete operation concurrently. Threads which
wants to write messages to file shouldn’t block for file related i/o .
Sample interface.
Log{
void log(filename, message);
}
http://mentablog.soliveirajr.com/2013/02/inter-socket-communication-with-less-than-2-microseconds-latency/
http://mentablog.soliveirajr.com/2012/12/asynchronous-logging-versus-memory-mapped-files/
http://mentablog.soliveirajr.com/2012/11/inter-thread-communication-with-2-digit-nanosecond-latency/
Question : Design a price making system for a wholesale dealer, where user can subscribe/un-subscribe
online for any product to receive the real time prices. System will internally subscribe to different vendors to get
the product prices, aggregate them and return the best price to customer. Vendors may broadcast new prices
every few seconds and customers would like to see all the price updates until he un-subscribe for that product.
Dealer may also like to add some commission on every product price to remain in business and make some
profit.
Chapter - Puzzles Cracking the Core Java Interviews 167
Assume system will have limited number of vendors and products but can have high number of concurrent
customers requesting for product prices.
Primary concern for the customers to have minimal latency in the price updates.
Question : U are given binary search tree. How will you check whether it is balanced or not.
Question : U have UI and service. UI making 5000 request and service can handle only 500 request. I am okay
with slow response. But how will make sure all 5000 requests are processed
Question : U have a tree with each node has link to its parent. You are given left most child node of the tree.
How will you get right most child node of the tree.
Question : Write regular expression which checks for Any occurence of ‘A’ followed by two or more ‘B’ followed
by any occurrence of ‘A’
Question : Merge 2 sorted arrays in constant space and minimum time complexity.
http://www.cs.ubc.ca/~harrison/Java/MergeSortAlgorithm.java.html
http://thomas.baudel.name/Visualisation/VisuTri/inplacestablesort.html
Question: What will happen if in a try block we throw an exception but in the finally block we return a int value ?
public class MyFinalTest {
public int doMethod(){
try{
throw new Exception();
}
finally{
return 10;
}
}
public static void main(String[] args) {
MyFinalTest testEx = new MyFinalTest();
int rVal = testEx.doMethod();
System.out.println("The return Val : "+rVal);
}
}
Hint - the method call will return 10 instead of throwing the exception.
Question : How would you write a simple Struts 2 Interceptor which will log the request and response to an
Invocation ?
http://www.dzone.com/tutorials/java/struts-2/struts-2-example/struts-2-interceptors-example-1.html
Question : What are different scopes of a Bean in Spring framework ?
Answer : singleton – Return a single bean instance per Spring IoC container
prototype – Return a new bean instance each time when requested
request – Return a single bean instance per HTTP request.
session – Return a single bean instance per HTTP session.
globalSession – Return a single bean instance per global HTTP session.
Question : How to create a singleton bean in Spring by calling a custom initialization method (for eg
instance())?
Answer : provide factory method attribute in the bean declaration, as shown below
<bean id="mySingleton" class="org.shunya.MySingleton" factory-method="getInstance" />
Chapter - Puzzles Cracking the Core Java Interviews 168
How would you find which UNIX operating system you are running ?
Following commands can be used to know the OS details -
>uname -a
>arch
How would you clean a windows file on unix for \n and \r characters?
>dostounix <filename>
Q 182. What is the Typical Interview Coverage for Core Java Candidate ?
SOLUTION
Java Basics
OOP prinicples, overloading, overriding, exception handling, garbage collection, Immutability, Generics
Collections
New collections introduced in the latest version of JDK, internals of HashMap, ConcurrentHashMap, time
complexity of various collection methods.
Serialization
Custom serilaization using Serializable and Externalizable interfaces. Serializing legacy classes, construction
invocation in serialization.
Data structure and Algorithms
List, Queue, Binary Search Tree, Time complexity of operations, sorting, seraching, etc.
Design Patterns
Singleton, thread-safe siungleton, decorator, adaptor, strategy, builder, factory, observer, etc
Database & Hibernate
Database indexes, types of algorithms for indexes, types of indexes, SQL, SQL tuning, query plan, outer and
inner joins, relationships in database (OneToOne, OneToMany, ManyToMany), inheritance strategies in JPA,
lazy loading, handling concurrency in database transactions.
MVC Framework
MVC design patterns, Interceptors, Dependency Injection, Servlets, Filters, Struts 2, Restful Webservices,
SOA, Spring Framework etc
Misc.
Continuous Integration, Unit Testing, TDD, GC tuning, Maven , UNIX commands, Autosys Jobs, Scripting
Language, etc
Resume Should be small and crisp, no interviewer likes to read 10 pages long resume of the candidate. The
style that i follow for writing my resume contains
Summary
Clearly showing my key skills along with my currency job profile and the profile I am looking for in my new Job.
Employment
Brief description of professional experience. It should list the employer and the projects very clearly with
minimum words. Employer usually look for candidate's role and responsibilities in the project and hence these
we must provide all the necessary information.
Open Source Projects
When we gain experience then our social contribution matters a lot, specifically if we are looking for long term
career in programming. You should list down all the Open Source involvement providing the proper links to the
hosting.
Education
Academics should be mentioned in this section, highlighting details about the masters, bachelors and higher
schooling.
Skills
Detailed description about the key skills should be mentioned in this section. We should never flood this
section with the each and every bit of technology that we have worked in past. This section should contain only
those skills that you are comfortable working with and desiring to look in your new role.
In the next 3 pages i have shown my resume as the template, which you can follow if you like !
Chapter - Puzzles Cracking the Core Java Interviews 171
Q 185. What are the Interview questions that most candidates answer wrongly ?
SOLUTION
1. Is it required to synchronize the accessor of a shared mutable object in case of multi-threading ? If yes,
why ?
2. In what scenario StringBuilder should be preferred over String class ?
3. I am working on an application where millions of temporary StringBuilder objects are being created, due to
which application is facing big system wide GC pauses, how would you rectify the problem, assuming that
memory available can not be increased to great extent.
4. How Atomic updates are different from their synchronized counterpart ?
5. When do we get the ConcurrentModificationException ? What constitutes the structural modifications in a
collection?
6. Is it possible to write a method in Java which can swap two int variable ? What if we change the type from
int to Integer ?
7. What is difference between Class and the Instance level locking ?
8. Can you prove a scenario where thread starvation occurs ?
9. Is it a mendate to make all fields final inside a immutable class ? If yes, why ?
10. How to fix Double Check Locking ?
11. What is Java Memory Model ? Who should read it ?
12. What is upper bound and lower bound in generics ?
13. What happens when an exception is thrown from a try block which has no catch clause. But in finally block,
a value is returned by the method ? Discuss the scenario.