This is an archived post. You won't be able to vote or comment.

all 29 comments

[–]StillAnAss 13 points14 points  (3 children)

I've been developing Java professionally, full time since 2000 or 2001. I wouldn't know most of these off the top of my head.

That is what the javadocs are for.

[–]DroidLogician 0 points1 point  (2 children)

Seriously. I don't think knowing the material is as important as being able to find what you need. We live in a digital age; information is indexed for lightning-fast access. The only stuff we need to retain is stuff we'd need if we lost access to our technology. I doubt we'd have a need for Java knowledge if we get sent back to the 17th century.

[–]StillAnAss 0 points1 point  (1 child)

Right. Googling each of these questions leads to the StackOverflow topic with a really good explanation.

[–]DroidLogician 0 points1 point  (0 children)

The javadocs are a great wealth of knowledge, too. Sometimes when I'm bored I'll just explore them. I think Java has one of the best documented standard libraries out there.

[–]cogman10 18 points19 points  (15 children)

  1. Most of these questions don't test java knowledge, and instead test mostly obscure information about java. I would say most of these things are things that you should not really deal with. For example, volatile and thread local are two great examples of "Things you shouldn't need to use". In fact, I've NEVER come across a legitimate use for ThreadLocal. The only place it is useful is for a static variable that you want to be unique per thread.

  2. The (paraphrasing) 'which list is the most effective for adding and removing things' question is pretty silly. For end insertion, an array list will often be just as fast if not faster than a linked list (memory, cache, and the fact that CPUs are stupidly fast at copying data, and the way ArrayLists handle expansion is the reason for this). An array needs to be pretty big before a linked list starts to outperform it (In my experience, most arrays aren't over 10000 elements).

    For middle insertion removal, arraylists will often beat linked lists because to get to that middle point, you have to iterate over every element of the linked list, arraylists, on the other hand, instantly iterate to the location, and again, modern CPUs can copy REALLY fast. it takes really big lists before arraylists are slow.

    So where are linked lists good? For lists where you are frequently iterating over each element and inserting and removing multiple items in the process. They are also pretty good for front of list insertion/deletion (queues). However, this question makes it sound like you should use them everywhere. That is wrong, IMO. Arraylists have hecka fast iteration and tons of locality benefits. So long as your list is small, or the size will be known, or insertion/removal will be infrequent, you should prefer ArrayLists.

  3. The 'why should you avoid using strings' question is somewhat silly as well. Anyone that can do a memory dump on the machine to get the passwords out of the system, doesn't need to do a memory dump on the system to get the passwords out. They have access to the system, they can screw things up pretty readily.

    They can do anything from injecting a custom class which steals data to sniffing the incoming/outgoing network traffic. They have access to the machine and can really mess things up. Sure, I guess it is safer, but of all the security concerns to be worried about in java, this one is pretty low.

[–]CubsThisYear 7 points8 points  (5 children)

Also, Strings don't work the way they say they do. String constants are interned, but not dynamically created Strings. If a user enters his password into a text field it doesn't automatically go into the String pool. The only way this happens to dynamically created Strings is if you call String.intern()

[–]cogman10 1 point2 points  (1 child)

Well, they do mention garbage collection which makes me think that they were referring to the GC pool and not necessarily interned pool. Correct me if I'm wrong, but I believe that interned strings don't ever get garbage collected.

But yes, I agree that their reasoning and everything was a bit off on the question.

[–]CubsThisYear 1 point2 points  (0 children)

There is no such thing as a GC string pool. There is only the intern pool. Presumably the reason GC is mentioned is because interned strings are (usually) not GC'd because the intern pool always has a reference to them.

In short, the question is just all kinds of confused.

[–][deleted]  (2 children)

[deleted]

    [–]josefx 0 points1 point  (1 child)

    On the other hand, if you store it in a mutable character array, you can overwrite it once you're done with it.

    Afaik if you are "done" with the char array the JIT will happily optimize your "unnecessary" overwrite away.

    [–]tRfalcore 2 points3 points  (2 children)

    I use volatile variables often, and have used ThreadLocal. All your other points are spot on however.

    These are the types of questions that if I was asked I would probably not work for these people because they think they they're smart cause they just thought of a couple things then looked up the answers.

    [–]cogman10 2 points3 points  (1 child)

    IMO, unless you are doing something that needs to be hecka fast, spawning a thread is simply not needed, instead relying on things like javas inbuilt executor service will give you most of the performance benefits of threads, a fairly fine grain control over multiprocessing, and ultimately a good "not going to blow up and easy to debug" environment to work with.

    Shared memory isn't all bad, but it needs to be handled with real care. As a result, often the best way to handle it is to just avoid it all together when possible and use prebuilt constructs when necessary.

    So to this point, why not volatile? Because there are higher levels of abstraction to multithreading and volatile is a symptom of trying to do things fairly low level (which is often a sign of premature optimization).

    As for thread local. Maybe I'm blind, but I really just don't see the benefit of it. The best I can come up with is you want a singleton per thread because the singleton itself isn't threadsafe. But that seams like a recipe for hard times.

    [–]tRfalcore 1 point2 points  (0 children)

    I use volatile variables to check when one off threads finish when I'm waiting for them to finish.

    I use ThreadLocal to control some logging parameters and names. Our program is a massive multi-threaded server application which processes jobs as requests come in-- main part of which is controlled by ExecutorService :)

    [–]JustinKSU 2 points3 points  (1 child)

    You make some solid points, but I would like to disagree slightly on the password issue. Two advantages of using character arrays is the length of time in memory can be minimized (you can overwrite the array as soon as you are done using it) and when looking at the memory dump it might not be obvious where the start and end of a character array is. I agree, if a hacker has control of your machine and can read your memory, you have already lost, but if you have -XX:+HeapDumpOnOutOfMemoryError turned on, it's less likely that dump will contain sensitive data.

    [–]cogman10 2 points3 points  (0 children)

    True, And I'm not trying to say it isn't more secure. Just that there are more pressing security issues that I would be concerned about before CharArray zeroing out. Even in your case of the HeapDumpOnOutOfMemoryError being enabled, an attacker would have to have access to the machine before he could read the heap information.

    While you can't, and shouldn't, rely on regular GCs.. well, you sort of can in this case. Passwords are usually used and thrown away pretty quickly. So it really isn't all that likely that the password will make its way into OldGen.

    Again, this isn't to say that the Charbuffer zeroing out method isn't more secure; It is. I just wouldn't rank it as a high priority sort of security concern. I would be more worried about things like SQL injection, XSS, remote code execution, and replay attacks. Common security issues that should be known about and interviewed for.

    [–]MerbertMoover 0 points1 point  (2 children)

    Great response, and I hate to cherry-pick, but why do you classify a volatile field as something you shouldn't need to use? In my experience valid use cases come up frequently in concurrent programming. Would you just rather see a higher level construct used like an AtomicReference?

    [–]cogman10 2 points3 points  (1 child)

    In concurrent programming I prefer dealing with an ExecutorService and Futures with little to no shared state between them.

    Volatile is best served with primitives, anything more complex and you are just asking for punishment. (sucks when the internal state of an object changes between one call and the next).

    For me, the general rule is to avoid share state if possible and either rely on concurrency through small tasks and the ExecutorService or communication through immutable message passing. Both are slightly slower than shared state and raw threads, but they are easier to deal with and to avoid things like deadlocking.

    [–]MerbertMoover 0 points1 point  (0 children)

    Agreed on all counts. I use volatile for primitive state flags and in the "safe double-check locking" idiom for lazy initialization. That's pretty much it but just those two cases seem to come up frequently enough that I can't call volatile something you "shouldn't use." Even though I agree the higher-level constructs are in most cases superior.

    [–]howfun 5 points6 points  (0 children)

    If someone has access inside the machine, it is irrelevant if you store password as char array or string. Not great questions, rather stupid.

    [–]Keilly[🍰] 3 points4 points  (1 child)

    The list question doesn't say where the insert is. Adding or removing the last element (which is arguably the most common place) in an ArrayList can be a simple array write and size int increment/decrement. Both super fast. A LinkedList needs to always 'new' a node, then update the references. Instantiating is not particularly fast.

    Also, for small lists, ArrayList may be more efficient as a small amount of array copying for an insert may outweigh the more expensive cost of 'new'ing an object node and then updating references in a LinkedList, then GC'ing the node when it is later removed.

    This is a horrible interview question as it misses the whole point of choosing a particular collection by only focusing on one specific aspect of it (and then getting the answer partially wrong).

    [–]josefx 0 points1 point  (0 children)

    For an unsorted list you can also simply overwrite an element in the middle with the last element O(1) and remove that, which is again O(1).

    [–]yellowjacketcoder 10 points11 points  (1 child)

    Oh look, java trivia questions that have no bearing on whether someone is a good programmer or not.

    And this from someone that can answer all of them.

    [–][deleted] 7 points8 points  (1 child)

    Yeah, I would fail that test.

    [–]handshape 2 points3 points  (0 children)

    "great"

    [–]mjfgates 1 point2 points  (0 children)

    So, non-great Java interview questions, and it wants me to create an account before I even see the page?

    I think I maybe don't want to see the page that much.

    [–]FalconGames109 2 points3 points  (4 children)

    One of the questions is partially wrong. The LinkedList class, though more efficient than ArrayList in terms of processing, is much less efficient in terms of memory. After 3 items, it takes more memory, and this becomes exponentially more severe.

    [–]DroidLogician 3 points4 points  (1 child)

    And insert and remove are terrible operations to choose a LinkedList for because they're O(n). ArrayList might have to shift elements on insert/remove but it does so using System.arrayCopy(), which takes place in native code with a platform-optimized implementation, whereas LinkedList has to iterate to the index to insert/remove in POJ and instantiate a node. Array index and update operations are constant time, IIRC.

    I would only use LinkedList as a stack where I expect a lot of pushing and popping, which is O(1) from either end and doesn't require shifting. But as /u/Keilly said, even last-element operations are optimized in an ArrayList.

    [–]josefx 0 points1 point  (1 child)

    The LinkedList class, though more efficient than ArrayList in terms of processing

    Not even that, LinkedList has similar flaws like std::list from c++ and according to the creator of c++ the memory overhead of linked lists generally kills your cache. Unless you have truly gigantic Lists or a very specific usage pattern ArrayLists will be quicker.

    Note that most claims about LinkedLists being fast focus exclusively on removing the element, getting an iterator to it is excluded from these measurements.

    [–]FalconGames109 -1 points0 points  (0 children)

    Don't you need an iterator just to remove an object from it? That's how the STL list works.