Skip to content

Questions

Tijs van der Storm edited this page Jan 10, 2013 · 8 revisions

Software Construction Theory Questions 2012-2013

First Test

  • Explain the difference between white-box and black-box frameworks.

  • Formulate the Law of Demeter in the context of Java/C# and explain why obeying the Law of Demeter is considered a good thing.

  • If you would have to manually enforce a class invariant, where should you put the assertion checks?

  • Read the following code of a simple expression interpreter.

    enum Type {add, mul, val};

    class Expr {
        Type type;
        Expr lhs, rhs;
        int n;
       
        int eval() {
            switch (type) {
              case add: return lhs.eval() + rhs.eval();
              case mul: return lhs.eval() * rhs.eval();
              case val: return n;
            }
            return -1;
         }
    }

This code is not open for extension. Explain why and sketch an alternative implementation so that it is.

  • Write down a grammar for statements, including assignment, if-then-else, and while. You may assume there are non-terminals for variables (Var) and expressions (Exp).

  • What is domain-specific AVOPT? Explain why this can be an advantage of DSLs?

  • Describe two advantages and two disadvantages of DSL embedding.

  • Define "object protocol".

  • Who's to blame if a pre-condition fails? And who's to blame if a post-condition fails?

  • The following code is not open for extension. Explain why, and sketch an alternative implementation using inheritance and virtual method dispatch.

	class Console {}
	class Canvas {}
	class Printer {}
    
	abstract class Shape {}
	class Circle extends Shape {
	    public void drawConsole(Console c) { System.out.println("console circle"); }
	    public void drawCanvas(Canvas c) { System.out.println("canvas circle"); }
	    public void drawPrinter(Printer p) { System.out.println("printer circle"); }
	}
	class Rectangle extends Shape {
	    public void drawConsole(Console c) { System.out.println("console rectangle"); }
	    public void drawCanvas(Canvas c) { System.out.println("canvas rectangle");}
	    public void drawPrinter(Printer p) { System.out.println("printer rectangle");}
	}
  • Explain the difference between scanner/tokenizer/lexer on the one hand, and a context-free parser on the other hand.

  • Explain the difference between an external DSL and internal (embedded) DSL. Give an example of each category.

  • Explain polymorphism in a few sentences.

  • What is the effect of pre conditions and post conditions in subclasses? In other words, how are contracts affected by inheritance?

  • Write down a grammar for expressions, including addition, multiplication, and condition (i.e.: "x ? y : z"). You may assume there is a non-terminal for variables called Var.

  • What is defensive programming?

  • What is the opposite of defensive programming?

  • Why should methods called in assertion not have any side-effects?

  • What is the actual invariant in a subclass? In other words, how does inheritance affect class invariants?

  • Briefly describe three of the five principles underlying the Law of Demeter.

  • In a few sentences, define DSL. Give 3 examples.

  • What is domain analysis?

  • Briefly describe three strategies for implementing a DSL.

  • List two kinds of tools that can help to build a DSL?

Second Test

  • A lot is wrong with the code below. Identify at least 3 problems (i.e. code smells). Briefly indicate how you would resolve these issues. NB: this is not about bugs.
    public void print(String x) {
        String temp[];
        int n = 0;
        for (int i = 0; i < x.length(); i++) {
            if (x.charAt(i) == '\n') 
                n++;
        }
        temp = new String[n + 1];
        String s = "";
        int j = 0;
        for (int i = 0; i < x.length(); i++) {
            if (x.charAt(i) == '\n') {
                temp[j] = s;
                s = "";
                j++;
            }
            else {
                s += new Character(x.charAt(i)).toString();
            }
        }
        temp[j] = s;
        s = "";
        for (int i = 0; i <= j; i++) {
            s += temp[i];
            if (i < j) {
                s += "<br>";
            }
        }
        System.out.println(s);
    }
  • What is meant by implementation decision? Give an example.

  • Parnas describes two criteria for modularizing a software system. One of them is information hiding. Explain why he thinks this criterion is better than the other.

  • Why does a modular design create option value?

  • Why does hierarchy in a complex system facilitate evolution?

  • Below is an ADT implementation of an expression type.

    class Exp {
      private class Const extends Exp { 
        int value; 
        Const(int value) { this.value = value; }
      }

      private class Add extends Exp { 
        Exp lhs, rhs;
        Add(Exp lhs, Exp rhs) {
          this.lhs = lhs;
          this.rhs = rhs;
        }
      }
      
      static Exp const(int) { return new Const(n); }
      static Exp add(Exp lhs, Exp rhs) { return new Add(lhs, rhs); }

      static int eval(Exp x) {
        if (x instanceof Const) {
          return ((Const)x).value;
        }
        return eval(((Add)x).lhs) + eval(((Add)x).rhs);
      }
    }
  • Explain if this code is open for extension when: adding a expression type (e.g. Mul, Div etc.) or adding a new operation (e.g. print, check etc.).

  • The following code is an OO version of the expression type.

     abstract class Exp { abstract int eval(); }
     class Const extends Exp { 
       int value;
       Const(int value) { 
         this.value = value;
       }
       int eval() { return value; }
     }
     class Add extends Exp { 
       Exp lhs, rhs;
       Add(Exp lhs, Exp rhs) { 
         this.value = value;
       }
       int eval() { return lhs.eval() + rhs.eval(); }
     }

Explain why this is not an ADT implementation.

  • Explain when this OO implementation is open for extension: when adding an expression type (e.g. Mul, Div etc.) or adding a new operation (e.g. print, check etc.).

  • Explain the concept of "wicked problem" in the context of software development.

  • What is the difference between abstraction and design patterns?

  • Define "abstraction" in one or two sentences and give an example in programming.

  • Briefly describe Parnas' two sets of criteria for modularizing a software system.

  • What is information hiding?

  • What is the relation between complex systems and hierarchy, according to Herbert Simon?

  • The following code represents an ADT implementation of a Stack data structure.

    class Stack {
      private class Empty extends Stack { }
      private class Push extends Stack {
        int value;
        Stack stack;
        public Push(int n, Stack s) {
           value = n;
           stack = s;
        }
      }
      
      static Stack empty() { return new Empty(); }
      static Stack push(int n, Stack s) { return new Push(n, s); }
      static Stack pop(Stack s) { 
        if (s instanceof Push) {
          return ((Push)s).stack;
        }
        throw new IllegalOperation();
      }
      static Stack top(Stack s) { 
        if (s instanceof Push) {
          return ((Push)s).value;
        }
        throw new IllegalOperation();
      }
    }
  • Explain why this is called an Abstract data type.

The following code represents an object-oriented implementation of a stack.

    interface IStack {
      int top();
      IStack pop();
      IStack push(int n);
    }
    
    abstract class Stack implements IStack {
      IStack push(int n) { return new Push(n, this); }
    }
    
    class Empty extends Stack {
      IStack pop() { throw new IllegalOperation(); }
      int top() { throw new IllegalOperation(); }
    }
    
    class Push extends Stack { 
      private int value;
      private IStack stack; 
      Push(int n, IStack s) { 
        value = n; 
        stack = s; 
      }
      IStack pop() { return stack; }
      int top() { return value; }
    }
  • Sketch how a "length" method could be added in both the ADT and the OO versions.

  • Similarly, sketch the addition of a NoPop class in both the ADT and OO versions. This class implements a variant of a stack that ignores "pop" requests.

  • Illustrate the "expression problem" using an expression interpreter example.

  • Describe three of the characteristics of wicked problems in a few sentences each.

  • Describe the concept of design patterns in a few sentences and give an example.

  • How is it possible to do Object-Oriented Programming in Java?

  • Explain data abstraction.

  • What are the three purposes of modularity?

  • What is design structure matrix, and what is it used for?

Clone this wiki locally