Exam 1: Midterm

Solutions and Commentary

Part of the homework for CS:2820, Fall 2015
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Grade Distributions

Exam Scores

                      X
                      X
Mean   = 4.70         X
Median = 4.2          X
                      X X
                    X X X   X
                    X X X X X X X
            X X X   X X X X X X X X       X
  ______X_X_X_X_X___X_X_X_X_X_X_X_X_X_____X_______
     0 . 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 10

Machine Problem Scores (MP1)

Mean   = 3.67
Median = 4.1          X X
                      X X
      Y             X X X      (Y - did not submit
      Y             X X X
      Y             X X X       statistics only include
      Y             X X X       those who submitted solutions.)
      Y   X         X X X
      Y   X   X X X X X X X
  ____Y_X_X___X_X_X_X_X_X_X__
     0 . 1 . 2 . 3 . 4 . 5

Homework Scores (HW1 to HW5)

                                                  X
                                                  X   X
Mean   = 12.31                                    X   X
Median = 12.5                                     X   X   X X   X
                                                  X   X   X X   X
                                                X X   X X X X X X
                                                X X   X X X X X X
  ____________________X_______X_______X___X_____X_X_X_X_X_X_X_X_X____
     0 . 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 10. 11. 12. 13. 14. 15

Total Scores

                                          X         X
Mean   = 19.92                            X   X X X X   X
Median = 20.4                           X X X X X X X   X
                        X           X X X X X X X X X   X
  ________________X_____X_____X___X_X_X_X_X_X_X_X_X_X_X_X___X_X______
     0 . 2 . 4 . 6 . 8 . 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30
Grade scale???       D           C           B           A      

Solutions and Commentary

  1. Background: The distributed solution for MP1 contains this code to call the lineEnd() method that outputs an error message if the remainder of the line is nonblank:
    SyntaxCheck.lineEnd( sc, "gate " + kind + " '" + g.name + "'" );
    // Bug: the above triggers wasteful computation
    

    A question: Identify the wasted computation? (1 point)

    ______ Concatenating the components of the error message ______________
    
    ______ when most calls to lineEnd() do not report an error. ___________
    

    1/11 did well. 1/5 had vague answers worthy of partial credit. Most earned little or no credit. The most common useless answer was to quibble with the content of the error message. Those + operators are very expensive. Each one creates a new object and then copies the entire contents of its operands into that object.

  2. Background: The distributed solution for MP1 contains this code:
    if ("gate".equals( command )) { ...
    

    a) Why not if (command == "gate") ... ? (1 point)

    ______ the == operator compares object identity but we want ___________
    
    ______ to compare the values of two different objects _________________
    

    Almost half the class did well. Many of the students who earned partial credit would have profited by spending a bit more time thinking through an explanation before trying to write anything down. About 1/9 of the class earned no credit.

  3. b) Why not if (command.equals("gate")) ... ? (1 point)
    ______ if command is null, this will throw an exception _______________
    
    _______________________________________________________________________
    

    Over half the class got this right. Only 1/8 got partial credit for answers that implied some degree of understanding without clearly stating the issue.

    This was supposed to be part b) of problem 2, but it got its own number thanks to a typographical error.

  4. Background: In the distributed solution for MP1, as each input for gate g is used, that input is deleted from g.inputlist. This code is in the initializer:
    g.inputList = new LinkedList <String> ( inputs );
    

    A question: Why not g.inputList = inputs;? (1 point)

    _____ we need to make a copy of the list to permit deletion ___________
    
    _____ from one gate's list from changing other gates' lists ___________
    

    1/3 got this right. About 1/2 earned partial credit for answers that varied from unclear to confused but were on the right track. 1/8 earned no credit.

  5. Background: Consider these two Java statements:
    List <C> x = new List <C> ();      List <C> x = new LinkedList <C> ();
    

    A question: One of these is illegal, which one and why? (1 point)

    ______ The left one is illegal because class List is either ___________
    
    ______ an abstract or interface class and cannot be instantiated ______
    

    almost 1/2 got this right. About 1/8 got partial credit for poor explanations.

    Among the wrong answers, many said that the answer on the right was illegal because an object of class LinkedList could not be assigned to a variable of class List. In fact, not only is this legal, but a similar assignment was used in the posted solution to MP1 (where an ArrayList was assigned to a List); we discussed this in class when that solution was distributed.

  6. Background: Consider these two ways to print strings a and b:
                                       System.out.append( a );
    System.out.println( a + b );       System.out.append( b );
                                       System.out.println();
    

    A question: Which approach does more work? (1 point)

    ______ The left one does more work, it creates a temporary object _____
    
    ______ copies a and b to it, passes it to println(), then discards it _
    

    Only 1/6 of the class got this, and only 1/16 got partial credit. To make things clearer, note that any time you have an operator in an expression, there is an implicit temporary variable. Therefore, without changing the computation we are doing, we can rewrite the left code as:

    String temp = a + b;
    System.out.println( temp );
    

    This is not the end of the story. What does the + operator do? It creates a new string and then copies the values of its left and right operands into that string. So, we can rewrite the above as:

    String temp = new String(); // creates an empty string
    temp.append( a );
    temp.append( b );
    System.out.println( temp );
    

    Note in the above that the text of strings a and b is copied to temp before the text of temp is copied to System.out. That is, each character is copied twice. In contrast, the right solution copies each character exactly once.

    Several students had very strange mental models of how System.out.append() relates to System.out.println(), suggesting that a sequence of appends followed by println was somehow very expensive. In fact, System.out.println() is equivalent to System.out.append('\n'), and when println() is called with a string, this is equivalent to appending each character in the string to the output file, followed by appending a newline.

    Note, the exam referred to System.output but this was a typo, as was announced during the exam.

  7. Background: Consider these two method calls:
    System.output.println( s );        System.output.println();
    
    A question: Do these call the same method? Explain! (1 point)
    ______ they difer because the classes of the parameters and ___________
     
    ______ their number are all part of the "logical" method name _________
    

    Another way of saying this is that the method println is overloaded and refers several different methods that differ in the number and classes of their parameters.

    Almost 1/2 got this right. 1/5 earned partial credit for poor explanations.

    Many of the poor explanations focused on explaining what println() does, but the question can be answered without reference to that. The answer would have been largely the same if the calls were to o.method() and o.method(p). Furthermore, among those who focused on explaining println(), many were simply wrong in their guesses about what it does.

  8. Background: Consider the following two fragments (some fields and methods omitted):
    class C {                          class D {
    	private int i = 0;                 private static int i = 0;
    	static int getI() {                int getI() {
    		return i;                          return i;
    	}                                  }
    }                                  }
    
    a) What is illegal about class C? (1 point)
    ______ a static method cannot access a non-static class member ________
    
    _______________________________________________________________________
    

    1/3 got this right. About 1/3 earned partial credit, typically for giving a reason that implied something sensible without quite saying it. Some, for example, explained how to repair the problem without giving any hint of what the problem was that they were repairing.

    Among those earning little or no credit, there was real confusion about the relationship between the private and static attributes.

    b) Class D is legal. What is foolish about it? (1 point)

    ______ to call getI() you need an instance of D, but getI() ___________
    
    ______ does not depend on any instance variables ______________________
    

    1/15 of the class got this right, and only a few got partial credit. This was by far the hardest problem on the exam.

    Many students focused on the fact that declaring i to be private was silly because the getI() method is as good as making it public. In fact, because there is no putI() method, making it private is quite sensible -- it makes i read-only from outside the class.

    Many said that, somehow, the private and static attributes were somehow in conflict, but in fact, these have entirely unrelated meanings. Declaring a private field of a class makes it invisible outside that class, regardless of whether it is static, and declaring a static field makes it statically allocated at a fixed memory location outside any object of that class regardless of whether it is private.

    c) Give Java code to output D.i to System.out. (1 point)

    ______ System.out.println( "" + new D().getI() ); _____________________
    
    _______________________________________________________________________
    

    1/7 did well. Another 1/15 explained the problem correctly (the need to create an instance of D) but then failed to do so. Over 1/3 earned partial credit by a call to D.getI() as if getI() was a static method -- it was not!

    Among those earning little or no credit were those who simply wrote code to print D.i as if field i was not declared to be static. Several students wrote new methods that could be added to class D to return the value of i without printing it. Others wrote code that could be included somewhere inside class D to print the value of i despite the fact that the assignment was to print D.i, a notation that generally implies an outside view. In most cases, this code was not accompanied by any hint as to where it was supposed to be put.

A final comment: Most students ripped through this exam very quickly and turned it in at least 10 minutes before the deadline. It is clear from the answers that many wrote down the first thing that occurred to them without stopping to ask simple questions like: What does this problem really ask for? Does my answer address the question? Is this really that trivial a question? I suspect that many students who earned partial credit on some of these questions could have earned more credit had they stopped to think a bit before writing their answers down.