Statistics from Java "death" contest - a mini quiz for developers
A few months ago, we launched a new project called Java "Death Match" on a small site. After the test release, more than 20,000 developers participated in the quiz. Site 20 multiple-choice based on Java. We got the test statistics of many developers, today, we are very happy to answer some of these data and to share with you.
We got answers from 20 61 872 topics, about 3094 answers each question. Each Java "death" test will be drawn at random from five topic 20 topics, and each topic and then have 90 seconds to answer. Each question has four possible options. Some people often complain that these problems to us too hard. Therefore, our test is called Java "death" contest is not without reason, oh! Test results from the statistical data, we can know what is the most difficult problem, which is the easiest. In this blog, I want to share five selected from our most difficult quiz questions with you, and then solve them together.
On average, about 41% is correct, the result can be a little difference in the answers given by the developer. Index for each question and its answer statistical results can be obtained from here. Statistical data used in this blog was July 26 to get. From here you can try our Java "death" competition test.
1, Java "Death Match" in the most difficult problems
Let's begin the most difficult nut to crack. This problem is provided by Alexandru-Constantin Bledea from the Romanian capital Bucharest. Indeed, this issue is a trick question, only about 20% of the participants answer this question, which means blind option can increase the probability that you answer correctly. This question is about Java generics.
Title to the effect:
Where is this code wrong?
a. compile error because there SQLException was thrown
b. Throws ClassCastException, because an instance of SQLException not RuntimeException
c. there is no error, the program prints the stack trace throws SQLException
d. compilation error because we can not be converted into a RuntimeException type SQLException
Well, what we get information from the title? The title relates to the generic type erasure, as well as some exceptions. It should be recalled some knowledge:
RuntimeException and SQLException are inherited from the Exception, but in this code RuntimeException are unchecked exception, SQLException is abnormal subjects.
2.Java generic not materialized. This means that at compile time, generic type information is "lost", and seem to have been replaced by the generic parameter as it defines the type, or when there is no defined type, generic parameter is replaced with Object. This is everyone talking about the type of "erased."
Fondly do we hope to produce a seventh line compilation error, because we can not be converted into SQLException RuntimeException, but this did not happen. T will happen is replaced Exception, so we have:
throw (Exception) t; // t is also an Exception
pleaseThrow method expects an Exception, and T is replaced by Exception, so the cast is erased, as if I did not write this code is the same. This is something we can be corroborated from the following bytecode:
private pleaseThrow (Ljava / lang / Exception;) V throws java / lang / Exception
LINENUMBER 8 L0
LOCALVARIABLE this LTemp; L0 L1 0
// Signature LTemp ;
// Declaration: Temp
LOCALVARIABLE t Ljava / lang / Exception; L0 L1 1
MAXSTACK = 1
MAXLOCALS = 2
We look at, if the code does not involve generics, then the compiler generates bytecode is what we see in front of ATHROW have the following code:
1, CHECKCAST java / lang / RuntimeException
Now, we can be sure that the code did not relate to the type of conversion, so we can rule out the following two options:
"Compilation error, because we can not be converted to type SQLException RuntimeException"
"Throws ClassCastException, because an instance of SQLException not RuntimeException"
So after all, we throw a SQLException, and you hope that it will be the catch block catches, then print its stack trace information. However, contrary to expectations.
This code is deceptive, it allows the compiler and as we become confused. This code allows the compiler that the catch block is not accessible. For the uninformed observer, the code does not SQLException. Therefore, the correct answer is: Compile failed because the compiler does not think SQLException thrown from the try block of code - but in fact it can really throw!
Alexandru thanks again to share this with us! We can use another cool way to view errors in the code and how it actually throws SQLException This method is: Modify the catch block, change it to receive a RuntimeException. So you can see information about the SQLException stack. (Actually SQLException also did not catch snippets capture, but was captured and virtual machine prints the exception stack information.)
2, the key question is whether to use the toString ()
This question is only 24% accuracy rate, it is the degree of difficulty in this 20 runner-up title.
Title to the effect: print the results of this program is?
a.m1 & new name
b. above are wrong
c.m1 & m1
d.new name & new name
This question is actually much simpler, as long as we see the twelfth row, directly printed m1 and m2, and instead m1.name m2.name. This code cunning is that when we want to print an object, Java using the toString method. "Name" attribute is added to our own, and if you forget this, the rest are judged correctly, you may mistakenly choose m1 & new name this answer.
This line of code name properties of both objects are assigned the value "m1".
m1.name = m2.name = "m1";
Then callMe method to set the name attribute m2 object into a "new name", then the code is finished.
However, this snippet will actually print out the following information, including the name of the class and their hash code:
MyClass @ 3d0bc85 & MyClass @ 7d08c1b7
Therefore, the correct answer is "None of the above"
3, Google Guava class library Sets
Title to the effect:
This question is nothing wrong in what?
a. not compile
b is no problem.
c. may cause memory overflow
d. may result in an infinite loop
The question really is not particularly necessary on Guava sets library expertise, but to make the vast majority of developers confused. Only 25% of participants are given the correct answer, and the blind choose the proper rate is the same.
So what can we learn from this code see it? We have a method that returns a collection, this set contains a person's circle of friends. The method has a loop, it checks bestfriend property a person object is null. If not null, the bestfriend added to the results collection. If a person objects do have a bestfriend, then this person's bestfriend, repeat the process, so we can have a collection of add person objects to bestfriend, until there is a person, it does not bestfriend, or it's bestfriend already in our result in the collection. This last part a little subtle, we can not add a duplicate set of elements to the Set, namely person objects, so this method does not cause an infinite loop.
The real problem is that the code is likely to cause memory exhaustion abnormal (out of memory exception). This cycle is actually no borders, so we can constantly add person objects to the set until the memory is exhausted.
Incidentally, if you want to learn more about Google Guava, you can see we write this blog: the lesser known yet useful features about it
4, using two braces to initialize
Title to the effect: this code where the wrong place?
a. No error
b. is possible to obtain a null value
c. the code will not compile
d. prints incorrect results
This question is one of the least of the issue of code, but enough to confuse most of the developers. This question is only 26% of respondents answered correctly.
Few developers know this simple syntax to initialize a constant collection, although this syntax will cause some side effects. But in fact, this syntax is not a good thing too little known. After lamenting, you see that we add to the list an element, and then print the list. Under normal circumstances, you expect to see the printed result is [John], but with two braces to initialize is another set of initialization process. Here, we use an anonymous class to initialize a List, when you want to print NAMES, actually printed is null, this is because the initialization process has not been completed, then the list is empty.
Initialization on the use of a container of two braces, can be found here (right here).
5, the container for runtime Map bizarre events
This is another contribution to community problems are Barak contributors from Israel Yaish. Only 27% of respondents able to answer this question.
Title to the effect: What is the output of this code is
a. not compile
b. cast exception
c.  true
d. [ "bar", "ber"]
Well, look at the code. compute method to find a value in the map by key. If this value is null, then insert (key, value), and returns the value. Since the beginning, this list is empty, "foo" value does not exist, v is null. Then, we insert a map to the "foo" and "foo" point to new ArrayList