Du befindest dich hier: FSI Informatik » Prüfungsfragen und Altklausuren » Prüfungen im Bachelor-Studium (1. - 5. Semester) » pfp » Lösungsversuch   (Übersicht)

Dies ist eine alte Version des Dokuments!


Lösungsversuch

Aufgabe 1 - Wissensfragen

a)

  • volatile
  • synchronized

b)

  • p(n) ist der parallele Anteil
  • B_p ist der Speedup

c)

  • Entzug von Betriebsmitteln
  • globale Ordnung der Betriebsmittel

d)

  • Filteroperationen
  • Abbildungsoperationen (z. B. map)

Aufgabe 2 - Schreibtischlauf

Achtung! Diese Aufgabe ist nicht vollständig!

a)

Ausgabe (MyThread1) Ausgabe (MyThread2)
Möglichkeit 1 y = 0 x = 1
Möglichkeit 2 y = 1 x = 0
y = 1 x = 1
y = 0 x = 0

Begründung: print des einen Threads kann vor Setzen des neuen Wertes im anderen Thread geschehen. Compiler kann außerdem unabhängige Code-Zeilen umsortieren, weshalb auch y = 0 / x = 0 möglich ist!

b)

Ausgabe (Main-Thread)
Möglichkeit 1 counter = 2
Möglichkeit 2 counter = 3

Begründung: counter wird garantiert 2x synchronisiert, also korrekt inkrementiert. Der zweite Zugriff auf counter in MyThread1 ist aber nicht mehr korrekt synchronisiert, da eine andere Marke verwendet wird. Deshalb kann es hier zu einer Lese-Ändere-Schreibe-Wettlaufsituation kommen.

c)

Ausgabe (MyThread1) Ausgabe (MyThread2)
Möglichkeit 1 T1 = done. T2 = done.
T1 = done.

Begründung: value ist nicht volatile, durch Sichbarkeitsprobleme kann es hier zu einem Deadlock kommen, nämlich gerade dann wenn MyThread2 nichts von der Änderung in MyThread1 mitbekommt.

Aufgabe 3 (Petri-Netze)

a)

b) Keine Zyklen, aus denen man nicht mehr heraus kommt!

c)

Aufgabe 4 (Java - Counting)

  import java.util.concurrent.*;
  import java.util.concurrent.atomic.AtomicIntegerArray;
 
  public class Counting {
	final byte[] array;
	int threads;
	final AtomicIntegerArray globalCounts;
	final CyclicBarrier barrier;
 
	Counting(byte[] array, int threads) {
		this.array = array;
		this.threads = threads;
		this.globalCounts = new AtomicIntegerArray(256);
		this.barrier = new CyclicBarrier(threads + 1);
 
	}
 
	AtomicIntegerArray count() throws Exception {
		int step = array.length / threads;
		int start = 0;
		for (int i = 0; i < threads ; i++) {
			Thread cntThr;
			if ((start + step < array.length) && (i != threads - 1)) {
				cntThr = new CountingThread(start, start + step);
			} else {
				cntThr = new CountingThread(start, array.length);
			}
			cntThr.start();
			start += step;
		}
		barrier.await();
		return globalCounts;
	}
 
	class CountingThread extends Thread {
		private int begin, end;
		CountingThread(int begin, int end) {
			this.begin = begin;
			this.end = end;
		}
 
		public void run() {
			try {
				// local counting phase -- already implemented
				int[] count = new int[256];
				for (int i = begin; i < end; i++) {
					count[array[i] + 128]++;
				}
				// add values of count to globalCounts 3
				for (int i = begin; i < end; i++) {
					globalCounts.addAndGet(i, count[array[i] + 128]);
				}
				barrier.await();
			} catch (Exception e) { /* handle exception */ }
		}
	}
  }

Aufgabe 5 (Scala - Listenoperationen)

a)

  def flatten : List[(Char, Char)] => List[Char] = {
      case Nil => List()
      case t :: ts => List(t._1, t._2) ::: flatten(ts)
  }

b)

  def countPar : List[Char] => List[(Char, Int)] = cs => {
      for (c <- cs) yield (c, cs.par.filter(_ == c).size)
  }

c)

  def distinct : List[(Char, Int)] => List[(Char, Int)] = cs => {
      cs.foldLeft(List[(Char, Int)]())((ls, c) => if (ls.contains(c)) ls else c :: ls)
  }

Aufgabe 6 (Scala - Lauflängenkodierung)

a)

  def decodeTupel: ((Char, Int)) => Stream[Char] = {
      case (c, 1) => Stream(c)
      case (c, k) => c #:: decodeTupel(c, k - 1)
  }

b)

  def decode: Stream[(Char, Int)] => Stream[Char] = {
      case null => Stream()
      case ts => decodeTupel(ts.head) #::: decode(ts.tail)
  }