DEV Community

Cover image for Java interview prep: 15 Java interview questions

Java interview prep: 15 Java interview questions

Cameron Wilson on November 09, 2019

Not all interviews will focus on algorithms and data structures — often times an interview will focus solely on the language or technology that you...
Collapse
 
bertilmuth profile image
Bertil Muth

Good summary. One small typo: in Q9, you accidentally switched to lower case for the system class (-> System). In Q3, one could argue that upper case variable names are discouraged (even though it‘s valid syntax).

Collapse
 
mustabelmo profile image
Mustapha Belmokhtar

A good remark, I think the same goes for the string class.

Collapse
 
bertilmuth profile image
Bertil Muth

Yes.

Collapse
 
aminmansuri profile image
hidden_dude • Edited

Q14: memory usage

A big one in web applications is to prefer streaming over storing everything in RAM.

For example:

str = readEntireFileIntoString()

vs

outputStream.write(readAnotherLine())

Huge huge differences in RAM usage (O(N) vs O(1) ). Streaming is by far preferable.

In XML for example, SAX parsers are far preferable over DOM parsers because the later store everything in RAM. If your file is huge you'll hog a lot of RAM.

Another source of horror is careless use of relations in Hibernate. If you're careless you can end up storing the entire database for each object and hogging the RAM like mad.

Collapse
 
aminmansuri profile image
hidden_dude

I mention these.. because sadly, I've seen them in the wild.

Collapse
 
elmuerte profile image
Michiel Hendriks

Q15 is a trick question. The best way to implement it is: not at all. Singleton is the only design pattern which is also an anti-pattern.

I often ask this question during interviews: if they know design patterns, know singleton, and what they think of it. If they don't mention it being an anti-pattern. I ask them if they can explain why I think it's an anti-pattern.

The answer is rather simple. The whole purpose of a singleton is to introduce global state, and global state is bad.

Collapse
 
aminmansuri profile image
hidden_dude

Well, global state appears in the real world. Like configurations files, db connection parameters, etc..
One advantage of using factory methods + singletons is that if for whatever reason you don't want it to be a singleton any more, there's no obligation that it continue to be a singleton.

I'm not sure that making sure its a single instance in the VM is the most overriding principle. I haven't had much need for that guarantee. More important is the abstraction of returning an object that represents some configuration. Which over time could become several objects (for example when you make your app multi-tenant)

Collapse
 
elmuerte profile image
Michiel Hendriks

Of course global state appears in the real world. Just like memory leaks, concurrent modifications, and a whole lot of other bad things.

Configuration files and DB connection parameters do not have to be global state. You should pass them along as context or local state. Within a context (like Spring's ApplicationContext) you can have a single instance of an object. It is much like a singleton, except that it is possible to have a completely different instance of that object in a different context. Via the context you can get the proper instance of that object.

Depending on a global state is also problematic with unit testing.

It is simply best to avoid using singletons. However it is not always possible without creating a bigger mess. The prime example would be logging.

Thread Thread
 
aminmansuri profile image
hidden_dude

I see. I guess that's the heart and soul of the IOC / Hollywood principle. Rather than have your methods calling global classes for something, they should have those set for them so its easier to test.

Collapse
 
aminmansuri profile image
hidden_dude

Q4: avoiding finalize()

Besides the issue of non-determinism of the finalize().. a bigger reason to avoid the finalize() method is that modern garbage collectors are copy collectors. Meaning that if 80% of your objects are garbage, only 20% gets processed by the system. The other 80% simply disappears with no further processing.

This is a huge advantage over other schemes. Because with copy collectors processing garbage is almost free. However, if you add finalizers all over the place, then the GC needs to go through all the finalizers() hence you lose all the advantages of copy collection in terms of speed. This ends up being a huge performance hit.

Collapse
 
aminmansuri profile image
hidden_dude

Q13: HashSet vs TreeSet

You claim HashSet is thread safe. But the Javadocs say otherwise:

"Note that this implementation is not synchronized. If multiple threads access a hash 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.synchronizedSet method. This is best done at creation time, to prevent accidental unsynchronized access to the set:

Set s = Collections.synchronizedSet(new HashSet(...));
"

For multi-threading I highly recommend java.util.concurrent rather than synchronizedSet(). But no, its very dangerous to use HashSet in multithreaded situations. In fact, in the past there were cases where HashSet's cousin, HashMap hung even when there were only reads across threads.

The main difference is that HashSets use a hash table implementation whereas the TreeSet uses some binary tree implementation. There are many differences such as the ones you mentioned. Other differences include:

  • Hash tables use an O(1) algorithm except when hashes collide when it can degrade to O(N) if we're not careful. Of course, they aren't immune to memory paging
  • Balanced binary tree implementations (such as red black trees used in Java) are O(logN) so they have very good performance as well but less than Hash tables
  • Hash tables are contiguous in memory so they can take advantage of spatial locality in the CPU
  • Binary trees are not contiguous so the memory may be all over RAM meaning that its unlikely that reading one node would lead to reading the next one. So you'll probably get a lot more cache misses (even though you may get some advantages in terms of temporal locality in the cache)
Collapse
 
aminmansuri profile image
hidden_dude

In practice I've used TreeSet as an alias of "ordered list with no repetitions". HashSet I've used to check what has been processed vs what still needs to be processed.

But often I just end up using a Map instead. They're often more useful.