-
Notifications
You must be signed in to change notification settings - Fork 11
Questions
-
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?
- 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?