Question | Mean Score | StdDev | Question | Mean Score | StdDev | |
---|---|---|---|---|---|---|
1 | 9 | |||||
2 | 10 | |||||
3 | 11 | |||||
4 | 12 | |||||
5 | 13 | |||||
6 | 14 | |||||
7 | 15 | |||||
8 | Total |
Assume the following class definition:
public class Main {
// insert startup code here
}
Also assume that we begin our Java application with class Main. Which of the following could be the missing "startup code" -- the first code to be executed by Java?
System.out.print("Args are ");
for (int i = 0; i < args.length; i = i + 1){
System.out.print(args[i]
+ " ");
}
}
System.out.println("Main called....");
}
if (args.length == 0) {
System.out.println("No
arguments provided.");
}
}
System.out.println("Args are " + args);
}
System.out.println("Starting up....");
}
return args[0];
}
The correct answer is a. The first code called by a Java application must be a public static method named main that takes one parameter -- an array of String -- and returns nothing.
Answer b is incorrect because Java is case-sensitive and the method name begins with a capital M.
Answer c's main method is not static. That is, this main method belongs to instances of the Main class (created with new Main()), not to the class itself. Java apps always start with a static method, and may never create an instance of the startup class.
Answer d's main method takes a single String, rather than an array of String -- String[] -- as is required.
The main method in answer e doesn't take any parameters.
The method in answer f returns a String; Java requires that its startup method be void.
Assume that the following classes are defined in the following packages:
class | package |
---|---|
Point |
java.awt |
Double |
java.lang |
CalculatorGUI |
Calculator |
Wire |
cs101.util |
Foo |
Bar |
Also assume that you are writing code in the Calculator package. Which of the following statements is true?
The correct answer is b. An import statement doesn't change what you can access, it only changes how you can name it when you're accessing it. The import statement referred to in b allows you to refer to java.awt.Point simply as Point. You could refer to it as java.awt.Point even without an import statement. This is the problem with both choic a and choice e: you can use the long form of the name even without an import. Choice c is incorrect because you never need to import java.lang; you can always use the short form of names in the java.lang package. Choice d is incorrect because you are (by assumption) already in the Calculator package; you shouldn't have to import the package you're in! And choice f suggests importing a class so that you can refer to a package; this is backwards.
Assume the following class definition:
public class AlarmClock implements Runnable {
private Thread spirit; private int hours; private int mins;
public AlarmClock( int hours, int mins ){ this.setTime( hours, mins ); this.spirit = new Thread( this ); this.spirit.start(); }
public setTime( int hours, int mins ){ if ( ( hours > 0 ) && ( hours <= 12 ) && ( mins >= 0 ) && ( mins < 60 ) ) { this.hours = hours; this.mins = mins; } }
public void run () { while( true ){ try { Thread.sleep(1000); } catch( InterruptedException e ) {} this.mins = this.mins + 1; if ( this.mins == 60 ) { this.mins = 0; this.hours = this.hours + 1; if ( this.hours == 13 ) { this.hours = 1; } } System.out.println("The time is " + mins + " minutes after " + hours + " o'clock." ); } }
}
After we create an AlarmClock instance --
AlarmClock myClock = new AlarmClock( 12, 30 );
-- how many animacies (Threads, execution paths) can be active in that object simultaneously?
The correct answer is e. When a new AlarmClock is created, one animacy is created and started by the constructor. In addition, since both run and setTime are public methods, either may be called from the outside an arbitrary number oftimes. There is no limit on how many methods may be active in this object simultaneously.
Assume the following class definition. (This is the same code as the previous question's.)
public class AlarmClock implements Runnable {
private Thread spirit; private int hours; private int mins;
public AlarmClock( int hours, int mins ){ this.setTime( hours, mins ); this.spirit = new Thread( this ); this.spirit.start(); }
public setTime( int hours, int mins ){ if ( ( hours > 0 ) && ( hours <= 12 ) && ( mins >= 0 ) && ( mins < 60 ) ) { this.hours = hours; this.mins = mins; } }
public void run () { while( true ){ try { Thread.sleep(1000); } catch( InterruptedException e ) {} this.mins = this.mins + 1; if ( this.mins == 60 ) { this.mins = 0; this.hours = this.hours + 1; if ( this.hours == 13 ) { this.hours = 1; } } System.out.println("The time is " + mins + " minutes after " + hours + " o'clock." ); } }
}
Which of the following statements is true?
The correct answer is c. The changes to hours and mins are interdependent, and it is important to do both at once -- or neither. That is, the change should be atomic -- nothing should be able to get in the middle. A problem could arise in this code if, for example, the time were 6:59 and there was a call to setTime( 11, 30 ). The run methodsetTime might decide that mins would become 60, set it to 0 instead, then start to increment the hours from 6; in the meantime, the call to setTime might set hours to 7; run might set hours to 1; and setTime might set mins to 30. The time would then be 7:30 instead of either 11:30 or 7:00.
There are several other ways in which the concurrency problems in this class could play out. However, none of the other choices in this question reflect concurrency problems. There is nothing left to happen in the constructor after starting the Thread, so choice b is not a problem. Choice d is a feature, not a bug. (When the clock ticks at 3:15, hours doesn't need to be changed.) Choice e is a nice example of code reuse, certainly not a concurrency problem. (The same thread executes the constructor and (its call to ) the setTime method; no concurrency!) Similarly, choice f does not refere to a concurrency situation; the sleeping Thread might be interrupted, but nothing bad comes of this and no second Thread need be involved.
Assume the following class definition. (This is the same code as the previous question's.)
public class AlarmClock implements Runnable {
private Thread spirit; private int hours; private int mins;
public AlarmClock( int hours, int mins ){ this.setTime( hours, mins ); this.spirit = new Thread( this ); this.spirit.start(); }
public setTime( int hours, int mins ){ if ( ( hours > 0 ) && ( hours <= 12 ) && ( mins >= 0 ) && ( mins < 60 ) ) { this.hours = hours; this.mins = mins; } }
public void run () { while( true ){ try { Thread.sleep(1000); } catch( InterruptedException e ) {} this.mins = this.mins + 1; if ( this.mins == 60 ) { this.mins = 0; this.hours = this.hours + 1; if ( this.hours == 13 ) { this.hours = 1; } } System.out.println("The time is " + mins + " minutes after " + hours + " o'clock." ); } }
}
Which of the following modifications would not change the behavor of the code above?
The correct answer is d.
The difference between calling this.spirit.start() -- which ultimately calls this.run() -- and calling this.run() directly is that a Thread's start() method causes that other animacy to call the run method, rather than the calling animacy. That is, this.run() means I do the work; this.spirit.start() means I ask someone else to.
There are no three-way comparison statements in Java; choice b is simply illegal.
Choice c would mean that the run method would throw an exception, which should be declared, and would change the behavior of the code. Remember, an uncaught exception causes all execution to be exited -- the run method would no longer be running -- until the innermost enclosing (matching) catch statement is encountered. The code as written catches the exception, allowing run to continue.
Choice d uses a set of calls to System.out's print method instead of a single call to its println method. This is essentially functionally equivalent.
Choice e is syntactically incorrect -- the code won't compile -- because the parentheses around the if boolean condition are mandatory.
Choice f won't compile either, because a Thread's start method is void; you can't assign void to a name (this.spirit) of type Thread!
Assume the following class definition:
public class ChocolateChipCookie {
public static String owner; public static final int numChips; public int width;
}
Which of the following statements is true?
The correct answer is e. Attributes marked static belong to the class -- the recipe object -- while those not marked static belong to instances of -- cooked with -- the class, but not to the class itself. Type or final markings have no bearing on this issue.
The following code is drawn from the file ButtonHandler.java in the Documentation Project.
public class ButtonHandler implements Runnable { private Thread spirit; private Calculator gui; private CalculatorState stateObj = new CalculatorState(); private ButtonObj[] buttonObjs = new ButtonObj[Calculator.LAST]; public ButtonHandler( Calculator realGUI ) { ... }
public void run () { while (true) { int buttonID = this.gui.getButton(); // line missing here!! } } }
This is the complete file except for (1) the package statement, (2) the body of the constructor, and (3) the missing line in the run method.
Which of the following is the missing line from the run method?
The correct answer is b. The array buttonObjs maps from buttonID to the smart button object ( of type ButtonObj)that handles button buttonID. Each ButtonObj has a handleButton() method that actually does the work.
Choices a and f are incorrect because this -- the ButtonHandler instance -- doesn't have a handleButton method.
Choice c is incorrect because buttonID is of type int, and doesn't have anymethods.
Choice d is incorrect because this.stateObj is of type CalculatorState and doesn't have a handleButton method.
Choice e is incorrect because the handleButton method is not static and so belongs to individual ButtonObjs but not to the class itself.
public class Car {
public String noise() { return "Vroom, vroom!"; }
public void run () { while ( true ) { System.out.println( this.soundOff() ); } }
public String soundOff () { return this.noise(); }
}
public class RoadMachine extends Car {
private String startup = "Ba";
public String noise() { return "Zoooooooooooom!"; }
public void run () { while ( true ) { System.out.println( this.start() + this.soundOff() ); } }
public String start () { return this.startup; }
}
Which of the following statements is true?
The correct answer is f. Creating a new RoadMachine() won't print anything. Calling its start() method will return a String -- "Ba" -- but it won't print anything, either. This means that e, not a, is the correct behavior for new Roadmachine().start().
new RoadMachine().run() will print BaZoooooooooooom! (Remember the outside-in rule: Method lookup always starts from the outermost part of the object.)
Casting new RoadMachine() to type Carwon't change its behavior; it just changes what methods you can call.
Which of the following statements is true?
The correct answer is d.
Which of the following could be a legal Java constructor method for a class named Classification?
The correct answer is d. Answer a is missing the (possibly empty) parameter list. Answers b and c have returns, not allowed in a constructor. Answer e invokes the superclass constructor in its second line; such an invocation must be the first line of code in a constructor. Answer f has a misplaced extends statement; this goes on the class declaration, not the constructor declaration.
The following code is excerpted from the Calculator interface. It has been reformatted to fit this exam.
public interface Calculator { // buttonID constants. // The numbers 0 through 9 should serve as buttonIDs // for the respective buttons.
/** No operation in progress. */ public static final int NO_OP = -1; /** Calculator division. */ public static final int OP_DIV = 10; /** Calculator multiplication. */ public static final int OP_MUL = 11;
...
/** Calculator clear button. */ public static final int CLEAR = 16; /** One more than the biggest button index. */ public static final int LAST = 17; /** * Get the next Button pressed. The return value will be an int * between 0 and 9 (if the button was a number) or one of the * Calculator constants. * * @return the next button to be handled. */ public int getButton();
... }
Which of the following statements is true?
You may assume that a modification "would change the meaning of the interface" if either (a) the interface definition would no longer be legal Java and (b) some proper uses of the interface (i.e., uses as it is intended to be used) would no longer work (without modification) after the change. You may also assume that no change beyond the one(s) specified in the answer would be made.
The correct answer is a. All methods in an interface are implicitly abstract; making this explicit has no effect. Methods in an interface may not be static; choice b wouldn't compile. (Even if it would, it would change the meaning of the declaration: static things belong to classes (or interfaces), not to their instances.) Change c would mean you'd have to modify every call to getButton(), since it would now return a doubleinstead of an int. Choice d wouldn't compile; a method needs a return type. Choice e would require rewriting calls to getButton(), too, since they would need to supply an argument. Choice f is illegal in an interface; this declaration of getButton() is no longer abstract. It has a method body, though that body doesn't do anything; this is different from not having a method body.
Continuing with the same code from the Calculator interface....
public interface Calculator { // buttonID constants. // The numbers 0 through 9 should serve as buttonIDs // for the respective buttons.
/** No operation in progress. */ public static final int NO_OP = -1; /** Calculator division. */ public static final int OP_DIV = 10; /** Calculator multiplication. */ public static final int OP_MUL = 11;
...
/** Calculator clear button. */ public static final int CLEAR = 16; /** One more than the biggest button index. */ public static final int LAST = 17; /** * Get the next Button pressed. The return value will be an int * between 0 and 9 (if the button was a number) or one of the * Calculator constants. * * @return the next button to be handled. */ public int getButton();
... }
Which of the following statements is true?
Again, you may assume that a modification "would change the meaning of the interface" if either (a) the interface definition would no longer be legal Java and (b) some proper uses of the interface (i.e., uses as it is intended to be used) would no longer work (without modification) after the change, and that no change beyond the one(s) specified in the answer would be made.
The correct answer is a. It is important that OP_DIV and OP_MUL have different values (otherwise you couldn't tell them apart), but if their values are never used directly -- i.e., they are always accessed using these names -- then the particular values assigned to them don't matter. After all, it's not like you're going to be computing OP_DIV + OP_MUL. (This would not qualfy as a "proper use" of the interface!)
Choice b would mean that we couldn't tell the difference between OP_DIV and OP_MUL -- a big problem!
Choice c would not compile; even if it would, it would mean that individual OP_MUL fields belonged to each instance, not to the interface itself.
Choice d doesn't compile either; interface fields are required to be both static and final. (It would also mean that someone could change the value of OP_MUL out from under you!)
Choice e would change OP_MUL from an int to a double; this would obviously require modifying some potential "proper uses" of the code. For example, you can't use a double as the comparison value in a switch statement.
Choice f wouldn't compile: a field can't be abstract. (It's not really clear what this would/could mean.)
Which of the following statements is true of System.out.println?
The correct answer is b. System is a class (in package java.lang, so its full name is java.lang.System, but you can just call it System.) It has a static field, out, of type java.io.PrintStream. Every java.io.PrintStrream has a (non-static) println method. Note that the long form of the method name is java.lang.System.out.println!
Consider the following code, which implements a simple flip-flop:
public class Toggle { protected boolean currentValue = true; public boolean flip () { this.currentValue = ! this.currentValue; return this.currentValue; } }
Now consider the following statements.
Toggle switch = ... // * This is the starred line! if ( switch.flip() ) { System.out.println("First case"); } else if ( switch.flip() ) { System.out.println("Second case"); } else { System.out.println("Last case"); }
Assume that the first (starred) line assigns some (existing) Toggle instance to the name switch, but that we don't know whether switch.currentValue is true or false at the time of this assignment. Further assume that nothing other than the single sequence of execution appearing in this question affects the value of switch.currentValue.
Which of the following statements is true?
The correct answer is a. At most one clause of a cascaded if/else/else... statement will be executed -- the first one ot be true. If the value of switch.currentValue is false immediately after the starred line, the first call to switch.flip() will return true. This will cause "First Case" to be printed, and the if statement will exit. None of the else clauses will even be tested.
The class java.awt.Component has a method
public void paint( Graphics g );
This method is called by the Java runtime in an event-driven style whenever something happens that requires that the Component update its on-screen appearance. For example, the paint method is called when the Component is first made visible or whenever an overlapping (occluding) window is moved away.
Which of the following statements is true?
The correct answer is b. Note that this question is about event-driven programming, though its example is drawn from java.awt.
The idea behind event-driven programming is that someone else calls your event handler methods with the appropriate information. In this case, your component's paint method is an event handler. You can specialize the way in which it handles paint events by defining your own specialized paint method. (Since you're overriding java.awt.Component's paint method, your method should also take a Graphics as its only parameter.) Since paint is an event handler, you don't call it: the Java runtime does. When Java calls the paint method, it supplies the appropriate Graphics.