Download public class

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Java Puzzlers
OOP 2009
Optional Tirgul #2
Josh Bloch & Neal Gafter
http://www.javapuzzlers.com
http://video.google.com/videoplay?docid=9214177555401838409
What are puzzlers?
• Short Java programs
• They appear simple, but it is hard to guess
what the outcome of the program is:
– some do not compile
– some throw exception when executed
– some hang
– some print incorrect result
– some have varying or unpredictable output
Example: Oddity
public static boolean isOdd(int i) {
return i % 2 == 1;
}
Method result is:
1. true all the time
2. false all the time
3. true half the time, false half the time
4. true quarter of the times
Example: Oddity
public static boolean isOdd(int i) {
return i % 2 == 1;
}
Method result is:
1. true all the time
2. false all the time
3. true half the time, false half the time
4. true quarter of the times
Example: Oddity
public static boolean isOdd(int i) {
return i % 2 == 1;
}
Method result is:
true quarter of the times – half of integers are
negative, for all negative integers i % 2 returns -1,
therefore isOdd returns false. To fix the problem,
return i % 2 != 0
Time For A Change
public class Change {
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
}
What is the outcome?
1. prints 0.9
2. prints 0.90
3. prints 0.9000000000000000
4. prints something else
In The Loop
public class InTheLoop {
public static final int END = Integer.MAX_VALUE;
public static final int START = END - 100;
public static void main(String[] args) {
int count = 0;
for (int i = START; i <= END; i++)
count++;
System.out.println(count); What is the outcome?
}
1. prints 100
}
2. prints 101
3. prints nothing
4. throws an exception
Real life bug
public class IdGenerator {
public synchronized long getNewAndReserve(int interval) {
long value;
if (low + interval >= MAX_VALUE) {
high = getNewHighValue();
low = 0;
}
value = getNewId(high, low);
low += interval;
return value;
}
}
A Strange Saga of Suspicious Sort
public class SuspiciousSort {
public static void main(…) {
Random rnd = new Random();
Integer[] arr = new Integer[100];
for (int i = 0; i < arr.length; i++)
arr[i] = rnd.nextInt();
Comparator<Integer> cmp = new Comparator<Integer>() {
public int compare( Integer i1, Integer i2) {
return i2 - i1;
}
What is the outcome?
};
1. arr is always entirely sorted
Arrays.sort(arr, cmp);
2. arr is usually entirely sorted
}
3. arr usually not entirely sorted
4. throws an exception
Real life bug
public class Node implements Comparable {
private long id;
…
public int compareTo(Object obj) {
if (obj instanceof Node) {
Node tmp = (Node) obj;
return (int)(id - tmp.id);
}
return -1;
}
What
is
the
outcome
}
of
new Node(12884902889L).compareTo(
new Node(4294968297L ) )
(1) 1 (2) 0 (3) -1 (4) other
News: nearly all binary searches and
merge-sorts are broken (2006)
int mid =(low + high) / 2;
The sum overflows to a negative value, and the
value stays negative when divided by two. This
bug can manifest itself for arrays whose length
(in elements) is 230 or greater (roughly a billion
elements).
http://googleresearch.blogspot.com/2006/06/e
xtra-extra-read-all-about-it-nearly.html
Null and Void
public class Null {
public static void greet() {
System.out.println("Hello world!");
}
public static void main(String[] args) {
((Null) null).greet();
}
}
What is the outcome?
1.
2.
3.
4.
Prints “Hello World”
Does not compile
NullPointerException
Something else
Confusing constructor
public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
}
private Confusing(double[] d) {
System.out.println(“Double array");
}
public static void main(…) {
What is the outcome?
new Confusing(null);
1. Object
}
2. Double array
}
3. Does not compile
4. NullPointerException
What’s The Point
class Point {
protected final int x, y;
private final String name;
public Point(int x, int y) { this.x = x; this.y = y; name = makeName(); }
protected String makeName() { return "[" + x + "," + y + "]"; }
public final String toString() { return name; }
}
public class ColorPoint extends Point {
private final String color;
public ColorPoint(int x, int y, String color) { super(x, y); this.color = color; }
protected String makeName() { return super.makeName() + ":" + color; }
public static void main(String[] args) {
System.out.println(new ColorPoint(4, 2, "purple"));
}
}
What is the outcome?
1. [4,2]:purple
2. [4,2]
3. Something else
Indecision
public class Indecisive {
public static void main(String[] args) {
System.out.println(decision());
}
static boolean decision() {
try {
return true;
What is the outcome?
} finally {
return false;
1. prints true
}
}
3. does not compile
}
2. prints false
4. throws an exception
Hello, Goodbye
public class HelloGoodbye {
public static void main(String[] args) {
try {
System.out.println("Hello world");
System.exit(0);
} finally {
System.out.println("Goodbye world");
}
}
}
1. Hello world
What is the outcome?
2. Hello world
Goodbye world
Shades of Gray
class C {
String Z = "White";
1. Prints “Black”
}
2. Prints “White”
class X {
static class Y {
3. Does not compile
static String Z = "Black"; 4. Something else
}
static C Y = new C();
}
public class ShadesOfGray {
public static void main(String[] args){
System.out.println(X.Y.Z);
}
}
What is the outcome?
It’s Absurd, It’s a Pain,
It’s a Super-class
public class Outer {
class Inner1 extends Outer {}
class Inner2 extends Inner1 {}
}
Why doesn’t it compile?
It’s Absurd, It’s a Pain,
It’s a Super-class
public class Outer {
class Inner1 extends Outer {
public Inner1() {
super(); //invokes Object() constructor
}
}
class Inner2 extends Inner1 {
public Inner2() {
super(); //invokes Inner1() constructor
}
}
}
It’s Absurd, It’s a Pain,
It’s a Super-class
public class Outer {
class Inner1 extends Outer {
public Inner1() {
super();
}
}
class Inner2 extends Inner1 {
public Inner2() {
this.super();
}
}
}
Outer
Inner1
Inner2
It’s Absurd, It’s a Pain,
It’s a Super-class
public class Outer {
class Inner1 extends Outer {
public Inner1() {
super();
}
}
class Inner2 extends Inner1 {
public Inner2() {
Outer.this.super();
}
}
}
It’s Absurd, It’s a Pain,
It’s a Super-class
More on that:
• Scope ambiguities between outer and super
• On the Interaction of Method Lookup and
Scope with Inheritance and Nesting (pdf)
The Moral
• Careful design is great.
• Testing is great.
• Formal methods are great.
• Code reviews are great.
• Static analysis is great.
But none of these things alone are sufficient to
eliminate bugs: they will always be with us.
We must program carefully, defensively, and
remain ever vigilant.
Josh Bloch
Related documents