Final Review B: Questions

RFb.1.

One of the downsides to locking-based systems is priority inversion. Explain what this is.

RFb.2.

What is an advantage of using Java's ConcurrentHashMap class (from java.util.concurrent) rather than using a simple HashMap with a lock obtained for each access (such as would be constructed with Collections.synchronizedMap(new HashMap()))?

RFb.3.

Explain the function of the semicolon operator in ALGOL 68. What happens with the statement “INT a = (print(3); 5)”?

RFb.4.

Aside from declaring two different names, how are the following two ALGOL 68 variable declarations different?

INT first sym = 3;
REF INT second sym = LOC INT := 3;
RFb.5.

In D, what is a pure function?

RFb.6.

What is displayed by the following D code? And what would be displayed if the word lazy were omitted?

void repeat(int n, lazy int val) {
    for (int i = 0; i < n; i++) {
        writeln(val);
    }
}

void main() {
    int x = 1;
    repeat(3, x *= 2);
}
RFb.7.

What distinguishes functions and operators in APL? Give an example of each.

RFb.8.

Write an APL expression that computes the 100th harmonic number — i.e., 1/1 + 1/2 + 1/3 + ... + 1/100. Recall that APL's ‘ι’ function takes an integer n and produces a vector of integers from 0 to n − 1.

Final Review B: Solutions

RFb.1.

In systems where threads can be given different priorities, locking can undermine the priority system whenever a high-priority thread desires a lock held by a low-priority thread: Either the system must temporarily grant the low-priority thread a high priority so that it can finish its work with the lock, or else the high-priority thread will be stalled while the low-priority thread completes its work.

RFb.2.

Both prevent conflicts between threads attempting simultaneously accessing the HashMap. However, the single-lock HashMap will lead to reduce performance, since it will permit only one thread at a time to access the HashMap, whereas a ConcurrentHashMap will allow simultaneously access when the requests don't conflict (such as when the requests map to different buckets of the hash table).

RFb.3.

This is the go-on operator: Given “AB”, the value of A is computed before B, and the overall value of the expression is the value of B.

For instance, the expression “print(3); 5” represents first computing the value of print(3) then the value of 5, and the overall result is 5.

RFb.4.

The declaration of first sym creates a constant: first sym cannot later be changed. By contrast, second sym is a variable whose value can later be changed with a statement such as “second sym := 4”.

RFb.5.

A pure function is one that basically has no side effects: It does not perform I/O, access any memory beyond its own local memory and what is accessible through its arguments, or call non-pure functions.

RFb.6.
2
4
8

Without lazy, this program would print 2 three times.

RFb.7.

A function operates on numeric vectors as parameters and produces a numeric vector as a result, whereas an operator operates on functions as parameters and produces a function as a result. Examples of function include ‘÷’ for division and ‘↓’ for dropping items from a vector; examples of operators include ‘/’ for folding/reducing a function (for example, ‘+/’ creates a function that will sum the values of an vector) or ‘¨’ to apply a function to each item of a vector.

RFb.8.

+/÷1+ι100