JMS: JMS is Java Messaging Service. It's a way to implement asynchronous messaging in Java.
Difference between JMS and RPC: In Remote Procedure Call, the remote procedure is executed and the caller awaits a response from the remote procedure. In JMS, the message sender sends a message and continues processing without awaiting a response from any receivers.
Advantage of JMS: Typically senders and receivers are decoupled from each other, so the system has more availability as a whole since there are more than one points of failure.
Monday, April 21, 2014
Tuesday, January 28, 2014
The interviews...
Hashmap in Java: Hashmap is an unsynchronized map that implements hashing to locate bucket locations in the backing Entry<K,V> array. The hashcode of an object is used in the hash(int h) method to determine the location for get and put operations. It accepts null values and keys. Typically a put will replace an old value in the bucket location if the new key and the old key are equal according to their equals() method. However, if two keys that aren't equal via .equals() result in the same hashcode, the object will be stored in a linkedlist-like structure (Entry.next). This is collision. If collision occurs, the objects can still be found. When get is called, the hashcode is determined as normal, and then the proper value is found by comparing keys of the entries with .equals(). Remember, the Entry an object that encapsulates key, value, next, and hash. We call .equals on the key because we don't know the value yet at this point in the get.
Substring: Works by using the original character array, and calling a String constructor that uses an offset defined by the parameters in the String.substring() method. As of Java 1.7, the memory leak where the reference to the original array was stored in the new string has been fixed... The array is now copied.
Differences between Java 6 and 7: Main differences are: Strings used in Switch statements, the <> (Diamond) operator, try with resources, and multiple catch statements. Also, New IO 2.0.
ThreadLocal<T>: ThreadLocal is used to generate a variable value that is local to the thread that is using it. Each thread that reaches code blocks with ThreadLocal variables in it initialize their own copy of the variable. The generic type argument is used in the return value of ThreadLocal's get() method. ThreadLocal<T> has one method to be overriden in the case that it is defined as an anonymous inner class, and it is initailValue(). There seems to be a memory leak with this however, so the best way to initialize it is new ThreadLocal<T>(); then set it with value, and then get the value.
Substring: Works by using the original character array, and calling a String constructor that uses an offset defined by the parameters in the String.substring() method. As of Java 1.7, the memory leak where the reference to the original array was stored in the new string has been fixed... The array is now copied.
Differences between Java 6 and 7: Main differences are: Strings used in Switch statements, the <> (Diamond) operator, try with resources, and multiple catch statements. Also, New IO 2.0.
ThreadLocal<T>: ThreadLocal is used to generate a variable value that is local to the thread that is using it. Each thread that reaches code blocks with ThreadLocal variables in it initialize their own copy of the variable. The generic type argument is used in the return value of ThreadLocal's get() method. ThreadLocal<T> has one method to be overriden in the case that it is defined as an anonymous inner class, and it is initailValue(). There seems to be a memory leak with this however, so the best way to initialize it is new ThreadLocal<T>(); then set it with value, and then get the value.
Sunday, January 26, 2014
These interviews...
Volatile keyword: The volatile keyword in java is a keyword only allowed for variables. It ensures that the value of that variable is never cached; it is always read from main memory (reads and writes are atomic). For example, updating a long or double on some JVMs are two step processes, i.e., writing 32 bits twice. If after the initial write the variable is read by a different thread, problems could occur and instability results. The volatile keyword ensures that writes happen-before reads in Java's memory module. Volatile is not a replacement for synchronized, though it can in some situations. Synchronized requires lock on object or method, or can be blocked by awaiting this lock. Volatile does not obtain or release locks on objects, so it has less overhead.
Race Conditions: The standard result of two threads interleaving operations due to the chance that they both read a condition and entered a block of code where only one thread should have gone. An example would be having a hashmap, and checking for a key. If the key was not found by thread 1, it enters an unsynchronized code block that adds the key and the corresponding value to the hashmap. However, if the CPU is lost from thread 1 and switches to thread 2, that key doesn't exist and now there are two threads about to insert potentially different values into the same bucket.
Thread vs Runnable: In general, you don't want to lose a class's ability to inherit behavior from a superclass, which you can lose by extending Thread. Also, class extension is usually done to broaden functionality in a subclass, which, if Thread is only being extended to start a new Thread, is a waste. Thread cannot be started once it's ended, and Runnable can, so Runnable is more efficient. You would have to make a new Thread every time you wanted to run it (additional overhead). Runnables can be executed by Executors repeatedly.
Avoiding NullPointerException: If comparing two strings, for example, dereference the known string literal, i.e., ("dude".equals(string1)) rather than (string1.equals("dude")). If calling toString() results in the same as calling String.valueOf(), use String.valueOf() because it will return null. Use null-safe libraries, like those from Apache-commons. Return Collections.EMPTY_LIST instead of null when possible.
Race Conditions: The standard result of two threads interleaving operations due to the chance that they both read a condition and entered a block of code where only one thread should have gone. An example would be having a hashmap, and checking for a key. If the key was not found by thread 1, it enters an unsynchronized code block that adds the key and the corresponding value to the hashmap. However, if the CPU is lost from thread 1 and switches to thread 2, that key doesn't exist and now there are two threads about to insert potentially different values into the same bucket.
Thread vs Runnable: In general, you don't want to lose a class's ability to inherit behavior from a superclass, which you can lose by extending Thread. Also, class extension is usually done to broaden functionality in a subclass, which, if Thread is only being extended to start a new Thread, is a waste. Thread cannot be started once it's ended, and Runnable can, so Runnable is more efficient. You would have to make a new Thread every time you wanted to run it (additional overhead). Runnables can be executed by Executors repeatedly.
Avoiding NullPointerException: If comparing two strings, for example, dereference the known string literal, i.e., ("dude".equals(string1)) rather than (string1.equals("dude")). If calling toString() results in the same as calling String.valueOf(), use String.valueOf() because it will return null. Use null-safe libraries, like those from Apache-commons. Return Collections.EMPTY_LIST instead of null when possible.
Saturday, January 25, 2014
Those interviews...
Shallow Copy vs Deep copy, Cloning: Shallow copy is the Object.clone() implementation. If an object being copied has a reference to another object, aside from primitive types and immutable classes, then only the reference is copied. The object that the reference points to is not cloned. A deep copy is where the clone method is overridden for the copied object and all objects it holds references to, else code would not be able to call Object's protected clone() method on those objects. The object returned now has copies of all objects inside of it with copies of any objects inside those, and so on. Primitive values and immutable objects are copied normally.
Marker Interfaces: Serializable, Clonnable, Remote, Test... Interfaces that "mark" the class as available for some function to the compiler. The marker interface usually has no methods to override and is used really to classify code in certain ways. It is possible to mark a class as implementing ThreadSafe, for example, when the class has passed all programmer checks for thread safety. It seems though that using annotations to do this is a better, more readable option.
Annotations: @Documented, @Override, @SuppressWarnings, @Deprecated
Annotations have no direct effect on the compiler or the code it is trying to compile. However, annotations can inform the compiler to make checks on certain things, like in the case of @Override where, because of the annotation, the compiler can check to make sure the overriding method has implemented the superclass method properly. @SuppressWarnings({"unchecked", "deprecation"}) suppresses the two categories of warnings. The compiler warnings have no effect on runtime performance of the application, but do crop up to warn the programmer of unintended or faulty behavior can occur given the situation, typically when using raw collections instead of typed ones.
Thread Safe code: Writing thread safe code can be done in a few ways. Marking a method "synchronized" will make threads unable to call that method at the same time. Using immutable objects or synchronized objects like vector, hashtable, String, etc. Copying variables to the local scope and using those local variables is another way to achieve thread safety in code.
Marker Interfaces: Serializable, Clonnable, Remote, Test... Interfaces that "mark" the class as available for some function to the compiler. The marker interface usually has no methods to override and is used really to classify code in certain ways. It is possible to mark a class as implementing ThreadSafe, for example, when the class has passed all programmer checks for thread safety. It seems though that using annotations to do this is a better, more readable option.
Annotations: @Documented, @Override, @SuppressWarnings, @Deprecated
Annotations have no direct effect on the compiler or the code it is trying to compile. However, annotations can inform the compiler to make checks on certain things, like in the case of @Override where, because of the annotation, the compiler can check to make sure the overriding method has implemented the superclass method properly. @SuppressWarnings({"unchecked", "deprecation"}) suppresses the two categories of warnings. The compiler warnings have no effect on runtime performance of the application, but do crop up to warn the programmer of unintended or faulty behavior can occur given the situation, typically when using raw collections instead of typed ones.
Thread Safe code: Writing thread safe code can be done in a few ways. Marking a method "synchronized" will make threads unable to call that method at the same time. Using immutable objects or synchronized objects like vector, hashtable, String, etc. Copying variables to the local scope and using those local variables is another way to achieve thread safety in code.
Subscribe to:
Comments (Atom)