...and people are still using java?
Last week I was at the LASER 2009 summer school on Software Testing. It was pretty interesting and one brief talk captured my attention. The speaker, Martin Nordio, asked the audience if they knew Eiffel and only a few hands were raised. So he asked if they knew Java instead. Everyone raised his hand. To show to the audience they were wrong in assuming they knew about Java, he showed 6 samples of source code written in Java and asked the audience what the program did and bet that no one would have the right 6 answers.
Let's do the same here. I'm going to give you the exercises and will post the answers in my next blog entry.
1. What is the value of b at the end of this code:
2. What is the value of b at the end of this code:
3. What is the value of b at the end of this code and tell us if this executes normally or with an exception:
4. What is the value of b at the end of this code and tell us if this executes normally or with an exception:
5. The previous sample was too long, what does this return:
6. If you have answered properly to the above questions, then you are definitely quite an expert. To prove it, tell us the value of b at the end of the call as well as the return value:
PS: Feel free to post your answers as comments to this blog entry.
I've not used Java for a long time, since the university ... but I'll try
what's my score ? :-)
Only next week, otherwise it would be too easy to figure out the actual answers by getting the scores of everyone.
not that puzzling
The only one of these that seems surprising to me is #4, and the part that's surprising is that it actually compiles. Once you assume that break is allowed in a finally block there's really only one sensible thing for it to do, however.
I think there are a lot of things Java can be criticized for, but I'm not sure that "finally does what it's advertised to do" is really one of them. :-)
BTW: If you want to see some more puzzles like these, pick up Java Puzzlers by Joshua Bloch and Neal Gafter.
This is why I program in Eiffel every day, there are definitely less surprises with the language. Nevertheless it would be interesting to know if someone can manage to fill a book containing similar puzzlers for Eiffel. I have my doubts though :-)
> there's really only one sensible thing for it to do, however.
Well, then please tell the other readers what (you think) it is.
Sorry for the late reply. This site didn't email me about your reply, and I'm not a regular reader. I just stumbled upon this page again while searching for something else.
It's been years since my original comment, so I don't recall what my original answers were. I went and came up with a new set of answers, and only after writing them down verified that they were correct. Here are the answers:
<li>b=2<li>b=2, no exception<li>b=2, exception<li>b=4, no exception<li>returns 2<li>returns 1, b = 2
Again, none of these are really that surprising.
Take a look at #6, which is set up as the hardest problem, but is actually one of the most obvious ones here: b starts as 0, is incremented and then its value, 1, is returned. Finally, b is incremented again, so b's value is now 2. I'm not even sure where the "catch" is supposed to be. I assume that the author was somehow expecting that this later increment would somehow affect the value returned. This requires a confused understanding of what "return" does. The return statement is not returning "b", it is returning the value b evaluates to at the moment of the return statement's execution. If b's value changes later that is irrelevant to what is returned.
The "catch" with #5 is slightly more tricky, but not much if you know what finally means in Java. A finally block executes when the associated try statement is exited by any means: normal completion, return, exception, etc. If the finally clause completes normally (that is, all of its statements execute without any flow control out of the block) then whatever caused the exit from the try block will continue as before. However, if there is flow control out of the finally block, then it takes over. Normally this would be a return or a new exception, but it makes sense that a break would do the same thing as it is also flow control out of the finally block. There's nothing inconsistent about this behavior.
Note that I'm not saying that Java is without its warts. It has a lot of them. None of them are really exemplified by these puzzles, however.
1. 2 2. 1 3. 2 w/ex 4. 3 w/ex 5. 1 6. b=2, returns 0
Hint. Difference in ++variable and variable++. :)
Actually it was not my intent to play with the subtleties of b++ vs. ++b. You can treat all occurrences as `b = b + 1'.
Beside the fact that I only see "b++" in the code, I think the difference between "b++" and "++b" is only valuable in compound statements like assignments, subscripting, complex evaluations or the like, that is not the case.
Undefined. I didn't see foo() get called once :)
Is this Java?
Your 'exercises' are very badly worded. For a start, is this even Java code? You don't happen to mention it and certainly, the first four examples won't compile.
What do you mean by 'at the end of this code'? At the end of each of these functions, we can assume there is no value for b as it is out of scope. You should instead add some printlns so we can tell you exactly what will be the output of each program.
Also, what do you mean by 'executes normally or with an exception'? Neither 3 nor 4 declare Exception in their throws declaration so it is not possible for the checked exception to be propagated. Either the code fails to compile, or the answer is obvious because the Exception will be caught.
Please could you compile your code then re-post the corrected questions?
The body of the routine is clearly Java code, I've omitted the rest otherwise it would make the code quite unreadable and you could assume I've added a throws Exception statement to all the routines declaration.
By `at the end', I mean just before leaving the routine whatever it means in Java.
How about ?
1 - 2, 2 - 2, 3 - 2, 4 - 4, 5 - 2 (which I think is the point), 6 - B = 2, return = 1
I program java pretty constantly, however I never use the finally block.
I can't help finding out the answers. The way Java defines exception handling clauses, return and break is simply unguessable. That's not for human beings :) It would be interesting to post this in Java forum.
b is always 2.
b = 2, b = 2, b = 2 w/ exc, b = 3 w/ exc, return 1, b = 1 return 1.
I tried, but who would write such code? (ok I know those are just dummy samples )
who would write such code?
Real programmers that's who. Probably not so blatant as in these stripped down toy examples.
Imagine a code base on the order of 1e6 lines with thousands of finally blocks maintained by newbie developers distributed world wide under schedule pressure, doing maintenance work with insufficient training, mentoring, peer review or oversight, tasked with solving a subtle problem that they don't even realize is subtle.
I am thrilled to say I've never had to use Java, so I have no idea. :-)
For Eiffel "puzzles", I still (try as I might) don't know how to use agents in any effective way (nor am I sure I need to know agents to be effective). Also, I find the usage of certain classes to be semi puzzling without any documentation or examples.
What's Java? ;)
So, largely, yes, while developer with some experience can predict the result of these examples, the last three cases demonstrate really awful style that should normally never be used. Hence it may make sense to think that in a really good language such code should be rejected by compiler. From the other side, all really difficult problems (the last 3) are caused by altering of the execution flow in the 'finally' section, something that likely should never be done. Eclipse compiler in such cases normally prints warnings that can be configured to be treated errors.
Lamest criticism of Java I've seen in a while
Nice troll. Gimme a break, this is a silly way to judge a language. You can write obfuscated C in any language -- just as you can write spaghetti code in any language. If developers are so silly as to write such code, if the culture at your company accepts such code, you've got a much bigger problem than your choice of programming language. I would expect and hope that a code review would flag this as unacceptable coding idiom.
Hopefully serious software engineers know that if you've written the code in a hard-to-understand way, and there's a just-as-good way to write it that makes it obviously correct, the latter is preferable. Surely you've seen the Kernighan quote about finding/fixing bugs being twice as hard as writing the code in the first place, so if you're writing the code with 100% of your cleverness, you are by definition not clever enough to debug it.
Let's get quantitative: What fraction of the bugs encountered in real Java programs do you expect arise because of the features of the Java programming language you've highlighted? My guess: the fraction is so small that it is effectively immeasurable; it's basically negligible.
For the record: I got 1-5 right and had no clue on 6. I would expect any halfway decent Java programmer to get 1-3 right and would never write code like 4-6 (and would make fun of anyone who did).
Bottom line: This post is juvenile language-bashing. Why is it that people who are so smart, become so immature when they start arguing over which programming language is The One True Language?