28
Core Java 1 of 28 Core Java Table of Content -------------------------------------------------- General 4 What will happen if you call return statement or System.exit on try or catch block ? will finally block execute? 4 Can you override private or static method in Java ? 4 What does the following Java program print? 4 What do the expression 1.0 / 0.0 will return? will it throw Exception? any compile time error? 5 Strings 6 What is a StringBuilder and what are its use cases? What is the difference between appending a string to a StringBuilder and concatenating two strings with a + operator? How does StringBuilder differ from StringBuffer? 6 How are strings represented in memory? 6 Suppose we have a circular reference (two objects that reference each other). Could such pair of objects become eligible for garbage collection and why? 6 Multi Threading 8 Volatile 8 The Java volatile Visibility Guarantee 8 Example 8 Can we make array volatile in Java? 9 What are the practical uses of volatile modifier? 9 What is false sharing in the context of multi-threading? 9 False Sharing 10 Caching on Modern CPUs in less than 100 words 11 False Sharing 11 Countermeasures to False Sharing 12 False Sharing vs. @Contended: A Microbenchmark 13 What is the difference between preemptive scheduling and time slicing? 15 Number the bits, used to represent Unicode, ASCII, UTF-16, and UTF-8 characters? 15 Single Producer & Single Consumer 15

Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 1 of 28

Core Java Table of Content

--------------------------------------------------

General 4

What will happen if you call return statement or System.exit on try or catch block ? will finally block

execute? 4

Can you override private or static method in Java ? 4

What does the following Java program print? 4

What do the expression 1.0 / 0.0 will return? will it throw Exception? any compile time error? 5

Strings 6

What is a StringBuilder and what are its use cases? What is the difference between appending a string

to a StringBuilder and concatenating two strings with a + operator? How does StringBuilder differ

from StringBuffer? 6

How are strings represented in memory? 6

Suppose we have a circular reference (two objects that reference each other). Could such pair of

objects become eligible for garbage collection and why? 6

Multi Threading 8

Volatile 8

The Java volatile Visibility Guarantee 8

Example 8

Can we make array volatile in Java? 9

What are the practical uses of volatile modifier? 9

What is false sharing in the context of multi-threading? 9

False Sharing 10

Caching on Modern CPUs in less than 100 words 11

False Sharing 11

Countermeasures to False Sharing 12

False Sharing vs. @Contended: A Microbenchmark 13

What is the difference between preemptive scheduling and time slicing? 15

Number the bits, used to represent Unicode, ASCII, UTF-16, and UTF-8 characters? 15

Single Producer & Single Consumer 15

Page 2: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 2 of 28

Data.java 15

Producer.java 16

Consumer.java 17

Application.java 18

Collections 20

Fail Fast Vs Fail Safe Iterator 20

What is Concurrent Modification ? 20

Fail fast Iterator 20

How Fail Fast Iterator come to know that the internal structure is modified ? 20

Fail Safe Iterator 20

HashMap vs ConcurrentHashMap 21

Thread -Safe 21

Synchronization Method 22

Null Key 22

Performance 22

Arrange the following in the ascending order (performance) 22

LinkedList vs ArrayList 22

When to use LinkedList and ArrayList 23

What is CopyOnWriteArrayList ? How it is different from ArrayList in Java? 24

BlockingQueue 24

How TreeMap Works!! 24

How TreeMap works in java ? 24

Why and when we use TreeMap ? 25

What is the runtime performance of the get() method in TreeMap and HashMap ,where n

represents the number of elements ? 25

One liner 25

What is "natural ordering" in TreeMap ? 25

Why do we need TreeMap when we have sortedMap ? 25

Preferred Data Structure: HashMap or TreeMap ? 25

What happens if the TreeMap is concurrently modified while iterating the elements ? 26

Which copy technique (deep or shallow ) is used by the TreeMap clone() method ? 26

Why java's treemap does not allow an initial size ? 26

Page 3: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 3 of 28

IdentityHashMap 26

WeakHashMap 26

RedBlackTree (RBT) Data Structure 27

Java Memory Model / GC 28

JRE vs JVM 28

Page 4: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 4 of 28

Core Java --------------------------------------------------

General

What will happen if you call return statement or System.exit on try or

catch block ? will finally block execute?

This is a very popular tricky Java question and it's tricky because many programmer think that finally

block always executed. This question challenge that concept by putting return statement in try or catch

block or calling System.exit from try or catch block. Answer of this tricky question in Java is that finally

block will execute even if you put return statement in try block or catch block but finally block won't run

if you call System.exit form try or catch.

____________________________________________________________________________

Can you override private or static method in Java ?

Another popular Java tricky question, As I said method overriding is a good topic to ask trick questions in

Java. Anyway, you can not override private or static method in Java, if you create similar method with

same return type and same method arguments that's called method hiding.

____________________________________________________________________________

What does the following Java program print?

public class Test {

public static void main(String[] args) {

System.out.println(Math.min(Double.MIN_VALUE, 0.0d));

}

}

This question is tricky because unlike the Integer, where MIN_VALUE is negative, both the MAX_VALUE

and MIN_VALUE of the Double class are positive numbers. The Double.MIN_VALUE is 2^(-1074), a

Page 5: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 5 of 28

double constant whose magnitude is the least among all double values. So unlike the obvious answer,

this program will print 0.0 because Double.MIN_VALUE is greater than 0.

____________________________________________________________________________

What do the expression 1.0 / 0.0 will return? will it throw Exception?

any compile time error?

This is another tricky question from Double class. Though Java developer knows about the double

primitive type and Double class, while doing floating point arithmetic they don't pay enough attention to

Double.INFINITY, NaN, and -0.0 and other rules that govern the arithmetic calculations involving them.

The simple answer to this question is that it will not throw Arithmetic Excpeption and return

Double.INFINITY.

Summary:

If divided by zero, the Arithmetic Exception, whereas divided by 0.0 (double/float) then Infinity is the

result.

____________________________________________________________________________

Page 6: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 6 of 28

Strings

What is a StringBuilder and what are its use cases? What is the

difference between appending a string to a StringBuilder and

concatenating two strings with a + operator? How does StringBuilder

differ from StringBuffer?

StringBuilder allows manipulating character sequences by appending, deleting and inserting characters

and strings. This is a mutable data structure, as opposed to the String class which is immutable.

When concatenating two String instances, a new object is created, and strings are copied. This could

bring a huge garbage collector overhead if we need to create or modify a string in a loop. StringBuilder

allows handling string manipulations much more efficiently.

StringBuffer is different from StringBuilder in that it is thread-safe. If you need to manipulate a string in

a single thread, use StringBuilder instead.

____________________________________________________________________________

How are strings represented in memory?

A String instance in Java is an object with two fields: a char[] value field and an int hash field. The value

field is an array of chars representing the string itself, and the hash field contains the hashCode of a

string which is initialized with zero, calculated during the first hashCode() call and cached ever since. As

a curious edge case, if a hashCode of a string has a zero value, it has to be recalculated each time the

hashCode() is called.

Important thing is that a String instance is immutable: you can’t get or modify the underlying char[]

array. Another feature of strings is that the static constant strings are loaded and cached in a string pool.

If you have multiple identical String objects in your source code, they are all represented by a single

instance at runtime.

____________________________________________________________________________

Suppose we have a circular reference (two objects that reference each

other). Could such pair of objects become eligible for garbage collection

and why?

Yes, a pair of objects with a circular reference can become eligible for garbage collection. This is because

of how Java’s garbage collector handles circular references. It considers objects live not when they have

Page 7: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 7 of 28

any reference to them, but when they are reachable by navigating the object graph starting from some

garbage collection root (a local variable of a live thread or a static field). If a pair of objects with a

circular reference is not reachable from any root, it is considered eligible for garbage collection.

____________________________________________________________________________

Page 8: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 8 of 28

Multi Threading

Volatile

The Java volatile keyword is used to mark a Java variable as "being stored in main memory". More

precisely that means, that every read of a volatile variable will be read from the computer's main

memory, and not from the CPU cache, and that every write to a volatile variable will be written to main

memory, and not just to the CPU cache.

Actually, since Java 5 the volatile keyword guarantees more than just that volatile variables are written

to and read from main memory. I will explain that in the following sections.

The Java volatile Visibility Guarantee

The Java volatile keyword guarantees visibility of changes to variables across threads. This may sound

a bit abstract, so let me elaborate.

In a multithreaded application where the threads operate on non-volatile variables, each thread may

copy variables from main memory into a CPU cache while working on them, for performance reasons.

If your computer contains more than one CPU, each thread may run on a different CPU. That means,

that each thread may copy the variables into the CPU cache of different CPUs.

When a thread writes to a volatile variable, then not just the volatile variable itself is written to main

memory. Also all other variables changed by the thread before writing to the volatile variable are also

flushed to main memory. When a thread reads a volatile variable it will also read all other variables

from main memory which were flushed to main memory together with the volatile variable.

Example

public class SharedObject { public int counter = 0; }

Imagine too, that only Thread 1 increments the counter variable, but both Thread 1 and Thread 2 may

read the counter variable from time to time.

If the counter variable is not declared volatile there is no guarantee about when the value of the counter

variable is written from the CPU cache back to main memory. This means, that the counter variable

value in the CPU cache may not be the same as in main memory.

Page 9: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 9 of 28

____________________________________________________________________________

Can we make array volatile in Java?

This is one of the tricky Java multi-threading questions you will see in senior Java developer Interview.

Yes, you can make an array volatile in Java but only the reference which is pointing to an array, not the

whole array. What I mean, if one thread changes the reference variable to points to another array, that

will provide a volatile guarantee, but if multiple threads are changing individual array elements they

won't be having happens before guarantee provided by the volatile modifier.

____________________________________________________________________________

What are the practical uses of volatile modifier?

One of the practical use of the volatile variable is to make reading double and long atomic. Both double

and long are 64-bit wide and they are read in two parts, first 32-bit first time and next 32-bit second

time, which is non-atomic but volatile double and long read is atomic in Java. Another use of the volatile

variable is to provide a memory barrier, just like it is used in Disrupter framework. Basically, Java

Memory model inserts a write barrier after you write to a volatile variable and a read barrier before you

read it. Which means, if you write to volatile field then it's guaranteed that any thread accessing that

variable will see the value you wrote and anything you did before doing that right into the thread is

guaranteed to have happened and any updated data values will also be visible to all threads, because

the memory barrier flushed all other writes to the cache.

____________________________________________________________________________

What is false sharing in the context of multi-threading?

false sharing is one of the well-known performance issues on multi-core systems, where each process

has its local cache. false sharing occurs when threads on different processor modify variables that reside

on same cache line as shown in the following image:

Page 10: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 10 of 28

False sharing is very hard to detect because the thread may be accessing completely different global

variables that happen to be relatively close together in memory. Like many concurrency issues, the

primary way to avoid false sharing is careful code review and aligning your data structure with the size

of a cache line.

____________________________________________________________________________

False Sharing

Normally, Java programmers are not too concerned about the hardware on which their beautiful

software runs as long as provides loads of memory. Most of the time this is a good thing as software

should solve a business problem rather than satisfying a machine. The JVM does a decent job hiding the

underlying platform but as we know, abstractions are leaky. Sometimes we have to peek under hood,

especially when we're concerned about performance. One such topic is false sharing, were a very

performance-critical component might not perform as well as we'd expect.

Consider this class:

Page 11: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 11 of 28

public final class X { public volatile int f1; public volatile int f2; }

On Oracle JDK 1.8, instances of this class are laid out in memory as shown below:

Note: I have determined the layout on OpenJDK 1.8.0-b132 (64-Bit) using JOL, see also my

accompanying project on false sharing on Github.

We have declared all fields as volatile indicating that these fields may be used by different threads and

we want to ensure writes are visible to all of them. As a result, the runtime will emit code to ensure that

writes to a field are visible across CPU cores. But how does this work?

Caching on Modern CPUs in less than 100 words

CPUs don't care about classes or objects; they are concerned with reads and writes on memory cells.

To efficiently operate on data, it is fetched from main memory into a CPU cache at the granularity of a

cache line. A cache line is a block of memory in the CPU cache, say 64 bytes. If data in a cache line is

modified, each core sends messages across the memory bus according to a well-defined cache

coherence protocol (the most common one being the MESI protocol) so all cores can reconcile.

False Sharing

In this example I assume a hypothetical CPU with one cache layer (L1 cache) where each cache

belongs to one core. What happens if one thread, running on Core0 is constantly writing to X.f1

(depicted in red below) and another thread on Core1 is constantly reading from f2 (depicted in green

below)?

Page 12: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 12 of 28

Core0 knows that it does not own the cache line "n" exclusively, so it has to broadcast an "Invalidate"

message across the bus after changing the cache line to notify other cores that their caches are stale.

Core1 is listening on the bus and invalidates the corresponding cache line. Consequently, this

produces a lot of unnecessary bus traffic although both cores operate on different fields. This

phenomenon is known as false sharing.

Countermeasures to False Sharing

This is a rather unsatisfying state of affairs: Although each thread operates on different fields, we

produce a lot of unnecessary bus traffic which is ultimately caused by the memory layout of our Java

objects. If we were able to influence the memory layout we can avoid false sharing. It turns out there

are a few ways around this problem. A word of warning though: The following techniques depend on

the JVM implementation or the underlying hardware so take my words with a grain of salt. The

techniques are taken from the JMH example class JMHSample_22_FalseSharing and a presentation

on @Contended which inspired me to write this blog post. I'll just describe three of them shortly here

as the example class of JMH documents these and more techniques already very clearly:

Field padding within class: The idea is to stuff enough fields between f1 and f2 so that they end up on

different cache lines. Depending on the JVM implementation this may not work as a JVM

implementation can lay out fields in memory as it sees fit.

Field padding across class hierarchy: A JVM implementation might be cleverly rearranging fields

though so field padding will not work. However, if f1 and the padding fields are placed in a dedicated

class, and f2 is placed in a subclass of it, currently no JVM implementation will rearrange the padding

fields across the class hierarchy. This is quite quirky and fortunately, there is a better solution in Java

8.

@Contended: @Contended has been introduced to Java 8 with JEP-142. With this annotation, fields

can be declared as contended. The current OpenJDK implementation will then pad the field

appropriately, inserting a 128 byte padding after each annotated field. 128 bytes is twice the typical

Page 13: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 13 of 28

cache line size and were chosen to account for cache prefetching algorithms, specifically algorithms

which fetch two adjacent cache lines. Consideration of @Contended by the JVM must be explicitly

enabled -XX:-RestrictContended. As it is likely that cache line size or cache prefetching algorithms will

change over time, the JVM flag -XX:ContendedPaddingWidth (previously known as -

XX:FieldPaddingWidth) allows to control the padding size. If this all sounds a bit scary to you, you are

not alone. In the introductory post on the OpenJDK mailing list the annotation was controversially

discussed. It is likely that you'll almost never encounter the annotation in an application but parts of

the JDK such as ForkJoinPool already take advantage of it.

To properly pad f1, annotate it with @Contended:

import sun.misc.Contended;

public final class X {

@Contended

public volatile int f1;

public volatile int f2;

}

Which will result in the object layout below:

False Sharing vs. @Contended: A Microbenchmark

To demonstrate the effects of false sharing, I have written a small JMH microbenchmark which is

available on Github. Below is the result of this benchmark comparing false sharing and the

@Contended approach using three reader threads and one writer thread. It has been run on an Intel

Core i7-2635QM with 4 physical cores.

Page 14: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 14 of 28

While write throughput is roughly equivalent (mean throughput 373 ops/µs for false sharing and 371

ops/µs for the solution with @Contended), the mean read throughput is around three times higher with

@Contended (2338 ops/µs) than with false sharing (813 ops/µs). This clearly demonstrates the influence

of false sharing in this scenario.

However, don't worry: @Contended is definitely not meant to be sprinkled across the entire codebase.

In fact, it should be used very, very sparingly and people wanting to use @Contended probably already

use one of the previously-mentioned field padding approaches. In JDK 8, @Contended is just used in 5

classes (Thread, Striped64, ConcurrentHashMap, Exchanger and ForkJoinPool). There are limited

circumstances where false sharing is really a problem and bottlenecks should be identified before-hand.

But that may be the topic of another article some day...

____________________________________________________________________________

Page 15: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 15 of 28

What is the difference between preemptive scheduling and time

slicing?

Differences between preemptive and time scheduling are:

- In Preemptive scheduling the highest priority task executes until it enters the waiting or dead stated or

a higher priority task comes into existence.

- Time slicing, a task executes for a predefined time period and then the pool of ready tasks. The

scheduler then determines which task should execute next, based on priority and other factor.

____________________________________________________________________________

Number the bits, used to represent Unicode, ASCII, UTF-16, and UTF-8

characters?

- Unicode requires 16 bits

- ASCII require 7 bits. but it is usually represented as 8 bits.

- UTF-8 represents characters using 8, 16, and 18 bit patterns.

- UTF-16 uses 16-bit and larger bit patterns.

____________________________________________________________________________

Single Producer & Single Consumer

Data.java

package org.karanki.play.coding.single_producer_consumer;

public class Data {

volatile private String data;

private volatile boolean completed;

public String getData() {

if(data == null) {

throw new UnsupportedOperationException("Empty Data found");

}

String retunedData = data;

data = null;

Page 16: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 16 of 28

return retunedData;

}

public void setData(String data) {

this.data = data;

}

public void setCompleted() {

completed = true;

}

public boolean isCompleted() {

return completed;

}

}

Producer.java

package org.karanki.play.coding.single_producer_consumer;

import java.util.UUID;

public class Producer implements Runnable {

volatile private Data data;

public Producer(Data data) {

this.data = data;

}

@Override

public void run() {

synchronized (data) {

for(int i = 1; i <= 10; i++) {

String uuid = UUID.randomUUID().toString();

System.out.println("Producing :: " + uuid);

data.setData(uuid);

Page 17: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 17 of 28

data.notify();

try {

Thread.sleep(200);

} catch (InterruptedException e1) {

e1.printStackTrace();

}

try {

data.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("Producer Done!!!");

data.setCompleted();

data.notify();

}

}

}

Consumer.java

package org.karanki.play.coding.single_producer_consumer;

public class Consumer implements Runnable {

volatile private Data data;

public Consumer(Data data) {

this.data = data;

}

@Override

public void run() {

Page 18: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 18 of 28

synchronized (data) {

while(!data.isCompleted()) {

System.out.println("Consuming :: " + data.getData());

data.notify();

try {

Thread.sleep(200);

} catch (InterruptedException e1) {

e1.printStackTrace();

}

try {

data.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("Consumer Done!!!");

}

}

};

Application.java

package org.karanki.play.coding.single_producer_consumer;

public class Application {

public static void main(String[] args) {

Data data = new Data();

Page 19: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 19 of 28

Thread producer = new Thread(new Producer(data));

Thread consumer = new Thread(new Consumer(data));

producer.start();

consumer.start();

}

};

____________________________________________________________________________

Page 20: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 20 of 28

Collections

Fail Fast Vs Fail Safe Iterator

What is Concurrent Modification ?

When one or more thread is iterating over the collection, in between, one thread changes the

structure of the collection (either adding the element to the collection or by deleting the element in

the collection or by updating the value at particular position in the collection) is known as Concurrent

Modification

Fail fast Iterator

Fail fast iterator while iterating through the collection , instantly throws Concurrent Modification

Exception if there is structural modification of the collection . Thus, in the face of concurrent

modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic

behavior at an undetermined time in the future.

Fail-fast iterator can throw ConcurrentModificationException in two scenarios :

Single Threaded Environment

After the creation of the iterator , structure is modified at any time by any method other than

iterator's own remove method.

Multiple Threaded Environment

If one thread is modifying the structure of the collection while other thread is iterating over it .

How Fail Fast Iterator come to know that the internal structure is modified ?

Iterator read internal data structure (object array) directly . The internal data structure(i.e object

array) should not be modified while iterating through the collection. To ensure this it maintains an

internal flag "mods" .Iterator checks the "mods" flag whenever it gets the next value (using hasNext()

method and next() method). Value of mods flag changes whenever there is an structural modification.

Thus indicating iterator to throw ConcurrentModificationException.

Fail Safe Iterator

Fail Safe Iterator makes copy of the internal data structure (object array) and iterates over the copied

data structure.Any structural modification done to the iterator affects the copied data structure. So ,

original data structure remains structurally unchanged .Hence , no ConcurrentModificationException

throws by the fail safe iterator.

Page 21: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 21 of 28

Two issues associated with Fail Safe Iterator are :

1. Overhead of maintaining the copied data structure i.e memory.

2. Fail safe iterator does not guarantee that the data being read is the data currently in the original

data structure.

According to Oracle docs , fail safe iterator 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.

____________________________________________________________________________

HashMap vs ConcurrentHashMap

Thread -Safe

ConcurrentHashMap is thread-safe that is the code can be accessed by single thread at a time .

While HashMap is not thread-safe.

Page 22: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 22 of 28

Synchronization Method

HashMap can be synchronized by using synchronizedMap(HashMap) method . By using this

method we get a HashMap object which is equivalent to the HashTable object . So every modification

is performed on Map is locked on Map object.

ConcurrentHashMap synchronizes or locks on the certain portion of the Map . To optimize

the performance of ConcurrentHashMap , Map is divided into different partitions depending upon

the Concurrency level . So that we do not need to synchronize the whole Map Object.

Null Key

ConcurrentHashMap does not allow NULL values . So the key can not be null in ConcurrentHashMap

.While In HashMap there can only be one null key.

Performance

In multiple threaded environment HashMap is usually faster than ConcurrentHashMap . As

only single thread can access the certain portion of the Map and thus reducing the performance .

While in HashMap any number of threads can access the code at the same time.

____________________________________________________________________________

Arrange the following in the ascending order (performance)

HashMap , Hashtable , ConcurrentHashMap and Collections.SynchronizedMap

Hashtable < Collections.SynchronizedMap < ConcurrentHashMap < HashMap

____________________________________________________________________________

LinkedList vs ArrayList

LinkedList and ArrayList both implement List Interface but how they work internally is where the

differences lies. Main difference between ArrayList and LinkedList is that ArrayList is implemented using

re sizable array while LinkedList is implemented using doubly LinkedList. ArrayList is more popular

among Java programmer than LinkedList as there are few scenarios on which LinkedList is a suitable

collection than ArrayList. In this article we will see some differences between LinkedList and ArrayList

and try to find out when and where to use LinkedList over ArrayList.

Page 23: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 23 of 28

All the differences between LinkedList and ArrayList has there root on difference between Array and

LinkedList data-structure. If you are familiar with Array and LinkedList data structure you will most likely

derive following differences between them:

1) Since Array is an index based data-structure searching or getting element from Array with index is

pretty fast. Array provides O(1) performance for get(index) method but remove is costly in ArrayList as

you need to rearrange all elements. On the Other hand LinkedList doesn't provide Random or index

based access and you need to iterate over linked list to retrieve any element which is of order O(n).

2) Insertions are easy and fast in LinkedList as compared to ArrayList because there is no risk of resizing

array

and copying content to new array if array gets full which makes adding into ArrayList of O(n) in worst

case, while adding is O(1) operation in LinkedList in Java. ArrayList also needs to update its index if you

insert something anywhere except at the end of array.

3) Removal is like insertions better in LinkedList than ArrayList.

4) LinkedList has more memory overhead than ArrayList because in ArrayList each index only holds

actual object (data) but in case of LinkedList each node holds both data and address of next and

previous node.

When to use LinkedList and ArrayList

● LinkedList is not as popular as ArrayList but still there are situation where a LinkedList is better

choice than ArrayList in Java. Use LinkedList in Java if:

● Your application can live without Random access. Because if you need nth element in LinkedList

you need to first traverse up to nth element O(n) and than you get data from that node.

● Your application is more insertion and deletion driver and you insert or remove more than

retrieval. Since insertion or removal doesn't involve resizing its much faster than ArrayList.

● ArrayList has constant time search operation O(1) .Hence, ArrayList is preferred when there are

more get() or search operation .

● Insertion , Deletion operations take constant time O(1) for LinkedList. Hence, LinkedList is

preferred when there are more insertions or deletions involved in the application.

That’s all on difference between ArrayList and LinkedList in Java. Use ArrayList in Java for all there

situation where you need a non-synchronized index based access. ArrayList is fast and easy to use, just

try to minimize array resizing by constructing arraylist with proper initial size.

____________________________________________________________________________

Page 24: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 24 of 28

What is CopyOnWriteArrayList ? How it is different from ArrayList in

Java?

CopyOnWriteArrayList is a thread safe variant of ArrayList in which all mutative operations like add , set

are implemented by creating a fresh copy of the underlying array.

It guaranteed not to throw ConcurrentModificationException.

It permits all elements including null. It is introduced in jdk 1.5

____________________________________________________________________________

BlockingQueue

BlockingQueue implements the java.util.Queue interface . BlockingQueue supports operations that wait

for the queue to become non-empty when retrieving an element , and wait for space to become

available in the queue when storing an element .

It does not accept null elements.

Blocking queues are primarily designed for the producer-consumer problems.

BlockingQueue implementations are thread-safe and can also be used in inter-thread communications.

This concurrent Collection class was added in jdk 1.5

____________________________________________________________________________

How TreeMap Works!!

Treemap class is like HashMap which stores key- value pairs . The major difference is that Treemap sorts

the key in ascending order.

Treemap is sorted according to the natural ordering of its keys, or by a Comparator provided at map

creation time, depending on which constructor is used.

This implementation provides guaranteed log(n) time cost for the containsKey, get, put and remove

operations. Algorithms are adaptations of those in Cormen, Leiserson, and Rivest's Introduction to

Algorithms.

How TreeMap works in java ?

TreeMap is a Red-Black tree based NavigableMap implementation.In other words , it sorts the

TreeMap object keys using Red-Black tree algorithm.

Page 25: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 25 of 28

Why and when we use TreeMap ?

We need TreeMap to get the sorted list of keys in ascending order.

What is the runtime performance of the get() method in TreeMap and

HashMap ,where n represents the number of elements ?

TreeMap implementation provides guaranteed log(n) time cost for the containsKey,get,put and

remove operations.

One liner

TreeMap : log(n) HashMap : Constant time performance assuming elements disperses properly.

What is "natural ordering" in TreeMap ?

"Natural" ordering is the ordering implied by the implementation of the Comparable interface by the

objects used as keys in the TreeMap. Essentially, RBTree must be able to tell which key is smaller than

the other key, and there are two ways to supply that logic to the RBTree implementation:

1.Implement Comparable interface in the class(es) used as keys to TreeMap, or

2.Supply an implementation of the Comparator that would do comparing outside the key class itself.

Natural ordering is the order provided by the Comparable interface .If somebody puts the key that do

not implement natural order then it will throw ClassCastException.

Why do we need TreeMap when we have sortedMap ?

SortedMap is a interface and TreeMap is the class implementing it .As we know one can not create

objects of the interface . Interface tells us which methods a sortedMap implementation should

provide .TreeMap is such an implementation.

Preferred Data Structure: HashMap or TreeMap ?

HashMap is faster while TreeMap is sorted .Thus we choose them according to their advantage.

If you do not want to sort the elements but just to insert and retrieve the elements then use HashMap

.

But if you want to maintain the order of the elements then TreeMap should be preferred because the

result is alphabetically sorted .While iterating HashMap there is no ordering of the elements ,on the

other hand , TreeMap iterates in the natural key order.

Page 26: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 26 of 28

What happens if the TreeMap is concurrently modified while iterating the

elements ?

The iterator fails fast and quickly if structurally modified at any time after the iterator is created (in

any way except through the iterator's own remove method ). We already discussed the difference

between Fail-fast and Fail safe iterators .

Which copy technique (deep or shallow ) is used by the TreeMap clone() method

?

According to docjar , clone() method returns the shallow copy of the TreeMap instance . In shallow

copy object B points to object A location in memory . In other words , both object A and B are sharing

the same elements .The keys and values themselves are not cloned .

Why java's treemap does not allow an initial size ?

HashMap reallocates its internals as the new one gets inserted while TreeMap does not reallocate

nodes on adding new ones. Thus , the size of the TreeMap dynamically increases if needed , without

shuffling the internals. So it is meaningless to set the initial size of the TreeMap.

____________________________________________________________________________

IdentityHashMap

IdentityHashMap is a class present in java.util package. It implements the Map interface with a hash

table , using reference equality instead of object equality when comparing keys and values.In other

words , in IdentityHashMap two keys k1 and k2 are considered equal if only if (k1==k2).

IdentityHashMap is not synchronized.

Iterators returned by the iterator() method are fail-fast , hence , will throw

ConcurrentModificationException.

____________________________________________________________________________

WeakHashMap

WeakHashMap is a class present in java.util package similar to IdentityHashMap. It is a Hashtable based

implementation of Map interface with weak keys. An entry in WeakHashMap will automatically be

removed when its key is no longer in ordinary use. More precisely the presence of a mapping for a given

key will not prevent the key from being discarded by the garbage collector.

It permits null keys and null values.

Like most collection classes this class is not synchronized. A synchronized WeakHashMap may be

constructed using the Collections.synchronizedMap() method.

Page 27: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 27 of 28

Iterators returned by the iterator() method are fail-fast , hence , will throw

ConcurrentModificationException.

____________________________________________________________________________

RedBlackTree (RBT) Data Structure

Red Black algorithm is a complex algorithm . We should read the pseudocode of Red Black algorithm in

order to understand the internal implementation .

● A red-black tree is a type of self-balancing binary search tree.

● Red-black trees are used to implement associative arrays.

● Red-black trees make use of tree rotations.

● Insertion, deletion, and searching take O(log n) time in a red-black tree.

Red Black tree has the following properties :

1. As the name of the algorithm suggests ,color of every node in the tree is either red or black.

2. Root node must be Black in color.

3. Red node can not have a red color neighbor node.

4. All paths from root node to the null should consist the same number of black nodes

____________________________________________________________________________

Page 28: Core Java - Koti Karanki's trail · Core Java 2 of 28 Data.java 15 Producer.java 16 Consumer.java 17 Application.java 18 ... Arrange the following in the ascending order (performance)

Core Java 28 of 28

Java Memory Model / GC

JRE vs JVM

Java Runtime Environment contains JVM, class libraries, and other supporting files.

It does not contain any development tools such as compiler, debugger, etc.

Actually JVM runs the program, and it uses the class libraries, and other supporting files provided in JRE.

JRE = JVM + Java Packages Classes (like util, math, lang, awt, swing etc) + runtime libraries.

If you want to run any Java program, you need to have JRE installed in the system.

JRE is the box and JVM is the content of the box.

In simple words JRE = JVM + rt.jar

where rt.jar contains lang, util, awt, swing, math etc. libraries or compiled .class files used to run our

program.

____________________________________________________________________________