Do you need to clean it up? In cases where some thread pool is used, the ThreadLocal must be cleaned at the end of the operation the Thread is executing because the same Thread might be reused later."}},{"@type":"Question","name":"What is a TreeSet and when would you use it?","acceptedAnswer":{"@type":"Answer","text":"The TreeSet is a Set that maintains the natural ordering of the elements (if the elements are 'Comparable' or if a 'Comparator' is provided to the TreeSet). And also the basic operations (add, remove, contains) have a log(n) time cost. Usually used when we want to use a Set, but need to keep the elements ordered for later iteration or other usage."}},{"@type":"Question","name":"What is the output of the following code snippet, and why?
The reason for this result is the String constant pool that Java maintains. In the first case each string is treated as a constant and stored at the String constant pool. When defining a string like this, the JVM first tries to find an item with the same value in the pool, so that's why the 2 references are the same (the constants are reused from the pool).
In the second case a new instance is created for each string, so they are different by reference.
In the third case, the 2 strings are compared by value (not reference) and by value they are equal.
"}},{"@type":"Question","name":"
Each of the two examples contains 2 cases of string concatenation, which way of string concatenation is better in each example, and why?
Example 1
/* case 1.1 */ String a = s + s + s; /* case 1.2 */ String a1 = new StringBuilder(s).append(s).append(s).toString();
Example 2
String b = \"\"; StringBuilder b1 = new StringBuilder(); for(int i = 0; i < 20; i++) {
/* case 2.1 */ b += s;
/* case 2.2 */ b1.append(s);
} b1.toString();
","acceptedAnswer":{"@type":"Answer","text":"
In the first example, the string concatenation will be the same. The Strings in Java are immutable, meaning that the naive string concatenation with + in case 1.1 will be far from optimal because for each concatenation a new string is created.
So, in that case the Java compiler does some optimization at compile time, changing the + chaining to a StringBuilderappend. At the end, the compiled code would be completely the same.
In the second example, the data is more dynamic, in a for loop, so the Java compiler is not able to optimize it by changing the + to a StringBuilding.
Hence, for case 2.1 a new String is created on each +=, meaning that the StringBuilder.append case 2.2 will be much faster.
"}},{"@type":"Question","name":"What does the synchronized keyword mean and where would you use it?","acceptedAnswer":{"@type":"Answer","text":"The synchronized keyword in Java defines a thread-safe operation and can be used on: instance methods, static methods and code blocks. The synchronization (thread-safety) is achieved by allowing a thread to acquire and release an intrinsic lock. While the thread owns the intrinsic lock, the other threads that will try to acquire it, will be blocked."}},{"@type":"Question","name":"What's the difference between StringBuilder and StringBuffer?","acceptedAnswer":{"@type":"Answer","text":"StringBuffer is a synchronized type, while the StringBuilder is not. The StringBuilder was created as a replacement for the StringBuffer used in a single thread, making the StringBuilder usually faster."}},{"@type":"Question","name":"What's the synchronized version of a HashMap?","acceptedAnswer":{"@type":"Answer","text":"The synchronized version of the HashMap is the HashTable."}},{"@type":"Question","name":"What's the difference between a HashSet and a LinkedHashSet?","acceptedAnswer":{"@type":"Answer","text":"They are both Sets, but the LinkedHashSet maintains a doubly-linked list of the items, preserving the insertion order."}},{"@type":"Question","name":"What is a deadlock?","acceptedAnswer":{"@type":"Answer","text":"Deadlock is a situation where two or more threads are waiting for each other, thus, becoming blocked forever."}},{"@type":"Question","name":"What are generics in Java?","acceptedAnswer":{"@type":"Answer","text":"Generics are a mechanism that enables types to be parameters of the class, interface or method definition. This mechanism allows reusing of the same code with different inputs, while providing compile-time checks."}},{"@type":"Question","name":"
What is the problem with the following example and does it compile?
class Animal<T> {
T animal;
Integer age;
public Animal(T animal, Integer age) {
this.animal = animal;
this.age = age;
} } new Animal(123, 123);","acceptedAnswer":{"@type":"Answer","text":"The problem is that the constructor is used without the type defined in the class definition. This leads to some warnings, but the code will still compile."}},{"@type":"Question","name":"Why are exceptions expensive in Java?","acceptedAnswer":{"@type":"Answer","text":"The most expensive part of the exceptions is the stacktrace that is created when the Exception is constructed."}},{"@type":"Question","name":"What are default methods?","acceptedAnswer":{"@type":"Answer","text":"Default methods are methods defined on an interface. They were introduced in Java 1.8. Before Java 1.8, interfaces could only have abstract methods, meaning that interfaces only provided the contract (the signature of the method) and the actual implementation (functionality) had to be provided in a class implementing that interface. With the default methods, the functionality (implementation) can be provided on interface level."}},{"@type":"Question","name":"What types of Exceptions exist in Java (and what is the difference)? Name few common Exceptions of each type.","acceptedAnswer":{"@type":"Answer","text":"
In Java there are 2 type of Exceptions, checked and unchecked.
The checked exceptions are checked at compile and they must be either handled in a catch block, or they must be specified in the throws section of the method. The checked exceptions are subclasses of the Exceptions class and some of the most common exceptions of this type are: IOException, SQLException, ClassNotFoundException etc.
The unchecked Exceptions are not checked at compile time and don't have to be handled in a catch block or declared in the throws section of the method. The unchecked Exceptions are subclasses of the RuntimeException and some of the most common exceptions of this type are: IllegalArgumentException, NullPointerException, IllegalStateException.
"}},{"@type":"Question","name":"
Given the following example code, which overrides are valid and which one aren't (with explanation)?
private abstract static class C1 {
public abstract void m1() throws Exception;
public abstract void m2() throws IOException;
public abstract void m3() throws Exception;
} private static class C2 extends C1 {
@Override
public void m1() throws IOException {}
@Override
public void m2() throws Exception {}
@Override
public void m3() {}
}
","acceptedAnswer":{"@type":"Answer","text":"Overrides of m1() and m3() are valid. In the case of m1(), the override in C2 defines an Exception which is a sub-class of the one declared on the parent. This is defining a more precise exception than the parent, and it's completely legal. In the second case, m2() throws a more general exception, and this is an illegal override."}},{"@type":"Question","name":"What is the difference between an Application server and servlet container?","acceptedAnswer":{"@type":"Answer","text":"The application server provides the whole JavaEE support, while the servlet container provides only the Servlet specification. The servlet container (most commonly used implementation is Tomcat) can also run some of the JavaEE technologies if they are installed separately or with some framework providing some of them."}},{"@type":"Question","name":"What is JDBC?","acceptedAnswer":{"@type":"Answer","text":"JDBC stands for Java Database Connectivity and represents an API in Java for accessing SQL-based database systems. To make the JDBC API work with a specific database management system, a JDBC driver must be present on the client side. The driver acts as an adapter that converts the Java instructions to instructions that the DBMS understands."}},{"@type":"Question","name":"What is JPA and how is it different from JDBC?","acceptedAnswer":{"@type":"Answer","text":"JPA stands for Java Persistence API and represents an API for managing relational data in the application by mapping operations between Java objects and some relational database. The difference from JDBC is that JDBC defines how the client connects to the DBMS, while JPA defines how the data is managed."}},{"@type":"Question","name":"What are static methods and fields? What is wrong with using a static method in a class like new Class().someStaticMethod()?","acceptedAnswer":{"@type":"Answer","text":"Static methods and fields are class members. This means that they belong to the class, and not to an instance of the class. So, an instance of the class is not needed to gain access to these static members. The static fields are usually used for constants and the static methods for utility classes."}},{"@type":"Question","name":"Why is Java said to be 'write once, run everywhere'?","acceptedAnswer":{"@type":"Answer","text":"Java is said to be 'write once, run everywhere' thanks to the bytecode which acts as the intermediate step between the source code and the machine code. This allows the Java Bytecode to be executed on any hardware that has a proper JVM installed."}},{"@type":"Question","name":"What is the parent class that every other class extends from?","acceptedAnswer":{"@type":"Answer","text":"The parent class of every other class is the Object.class."}},{"@type":"Question","name":"Primitive vs Object types?","acceptedAnswer":{"@type":"Answer","text":"
Primitive types are the most basic types that Java supports. They are predefined as reserved keywords by the language and use a small amount of memory to represent a unit of data. Some primitive types are int, long, byte, double etc.
The other Object types are types that have classes (which extend Object.class) and can be instantiated with the new keyword (if there's an appropriate constructor). The object types are usually complex types, a composition of properties and methods that take up a bigger chunk of the memory.
"}},{"@type":"Question","name":"What is Auto-boxing and Unboxing, and does it impact performance?","acceptedAnswer":{"@type":"Answer","text":"
Autoboxing is the process of automatic conversion (by the Java compiler) from the primitive type to the corresponding object type (wrapper class of the primitive type). Unboxing is the reverse process, the conversion from the object type to the primitive type. Some primitive-object type pairs are (int, Integer), (long, Long), (double, Double) etc.
Since there's additional work required to execute them, both autoboxing and unboxing have an impact on the performance, so the developer should be careful and identify the points where autoboxing/unboxig happens to take care of some optimizations if needed.
"}},{"@type":"Question","name":"
Identify the Autoboxing and the Unboxing in the following example:
List<Long> list = new ArrayList<>(); list.add(1L); long l = list.get(0);
","acceptedAnswer":{"@type":"Answer","text":"
list.add(1L) causes autoboxing
Long l = list.get(0) causes unboxing
"}},{"@type":"Question","name":"Where would you use LinkedList and where an ArrayList?","acceptedAnswer":{"@type":"Answer","text":"
LinkedList is used in cases where we have a lot of add, remove and sequential iteration but not a lot of random access ( list.get(n) )
ArrayList is used when there is a lot of random access used ( list.get(n) ), but not a lot of add, remove.
"}},{"@type":"Question","name":"
What does the following code usually output? And why usually?
With casting the values (Integer), a boxing of the primitive values to the object wrapper is done. Since this boxing has some performance impact, the JVM keeps a cache of the object wrappers in some range (for Integer the default range is [-127, 127]). This means that in the example (Integer)127 == (Integer)127 , the wrapper object for 127 is taken from the cache and that's why they are same by reference. In the example (Integer)128 == (Integer)128 , the value is false because the wrapper object is not cached (it is out of the default range), and the result is false because they are different by reference.
This is the usual case because the range is a JVM property that can be changed.
"}},{"@type":"Question","name":"What are Reflections?","acceptedAnswer":{"@type":"Answer","text":"Reflections are a mechanism in Java allowing to inspect or modify the application code at runtime. One of the most common usage of the reflection API is retrieving information for a certain class at runtime. Some runtime information that can be retrieved for a class is: class name, fields, methods, super classes, implemented interfaces etc. The usage of the Reflection API adds some performance overhead, so the usage of it should be limited, and if possible, avoided."}}]]}]