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

Dies ist eine alte Version des Dokuments!


Aufgabe 1

  • a) 1 und 4
  • b) 2 und 4 (???) (einerseits bessere Lastverteilung, andererseits mehr Overhead / Synchronisationsaufwand)

Aufgabe 2

  • a)
AtomicInteger curThreads = new AtomicInteger(0);
  • b)
boolean manageThreads(String linkUrl) {
  if (curThreads.incrementAndget() <= maxThreads) {
      CrawlThread t = new CrawlThread(linkUrl);
      t.start();
  }
  else {
    curThreads.decrementAndGet();
    return false;
  } 
} // END OF manageThreads
  • c)
public void run() {
  process();
  curThreads.decrementAndGet();
}
  • d)
synchronized(visitedUrls) {
  if(!visitedUrls.contains(linkUrl)){
    doVisit = true;
    visitedUrls.add(linkUrl);
  }
}

Aufgabe 3

Nicht gefragt, hier aber erwähnt:

Beschränktheit: Da der Erreichbarkeitsgraph endlich ist, ist das Petri-Netz beschränkt.

Lebendigkeit: Nicht lebendig, da im Zyklus [1, 0, 0, 1], [0, 1, 3, 1] und [0, 2, 0, 1] (rechts im Erreichbarkeitsgraphen) nicht mehr herauskommt und in diesem t1 nicht mehr schaltet.

Aufgabe 4

  • a) 3

Nein ist nicht möglich, s wird bereits mit anderen Werten belegt, bevor das Programm parallel ausgeführt wird. Die Sichtbarkeit der in Zeile 25 festgelegten Werte ist gewährleistet (genauer [nicht VL-Stoff]: Es existiert im Allgemeinen eine Happens-Before Ordnung zwischen Code vor start() und dem Thread-Code.)

  • b) 3

Ja, „Geralt“ ist eine mögliche Ausgabe. Die Sichtbarkeit der Veränderungen der Threads ist nicht garantiert.

  • c) 4

Nein, da die Threads wieder gejoint wurden. Das Programm ist somit nicht mehr parallel. Die Sichtbarkeit ist im (einzigen) Haupt-Thread gewährleistet (genauer [nicht VL-Stoff]: Es existiert im Allgemeinen eine Happens-Before Ordnung zwischen Thread-Code und Code nach .join()).

Was bringt hier, dass s als volatile deklariert ist? volatile wirkt sich nur auf die Referenz selbst aus, diese wird aber nie geändert, könnte also genauso gut finaln sein.

Aufgabe 5

  • a)
def insert: (List[Int], Int) => List[Int] = (ls, v) => ls match {
  case Nil => List(v)
  case x::xs => {
    if (v <= x) {
      v :: x :: xs
    }
    else {
      x :: insert(xs, v)
    }
}

Alternativ:

def insert: (List[Int], Int) => List[Int] = (ls, v) => {
    val p = ls.partition(_ <= v)
    p._1 ::: v :: p._2
}

Alternativ:

def insert: (List[Int], Int) => List[Int] = (ls, v) =>
    (for (l <- ls if l <= v) yield l) ::: (v :: (for (l <- ls if l > v) yield l))
  • b)
def sort: List[Int] => List[Int] = ls =>
  ls.foldRight(List[Int]())((v, sortedList) => insert(sortedList, v))
// Alternativ zu "List[Int]()":
// Nil: List[Int]
// Aber unbedingt mit Typangabe, sonst schlägt Scala's Type Inference fehl
  • c)
def sortAllWith: (List[Int] => List[Int]) => List[List[Int]] => List[List[Int]] =
  sortFun => ls => for (cur <- ls) yield sortFun(cur)

Aufgabe 6

  • a)
def testInside: (Ellipse, Ellipse) => (Double, Double) => Boolean =
  (e1, e2) => (x, y) => isInside(e1, x, y) && isInside(e2, x, y)
  • b)
def tupleStream: Stream[Double] => Stream[(Double, Double)] = s =>
  (s.head, s.tail.head) #:: tupleStream(s.tail.tail)
 
  // alternativ
  (s(0), s(1)) #:: tupleStream(s.drop(2))
  • c)
def monteCarlo: (Ellipse, Ellipse) => Int => Int = (e1, e2) => count => {
 
  // Stream aus Punkten
  val pointStream = tupleStream(randomStream)
 
  pointStream.take(count).par.filter(p => testInside(e1, e2)(p._1, p._2)).length
  // .count wirft einen komischen Fehler von Scalas Type Inference System
  // "missing argument list for method count" => .length oder .size benutzen
}