CS 334: Final Details

  • The CS 334 Final will be a Self-Scheduled Exam. You can take the exam any time during the self-scheduled exam period.

  • Please see the full rules for self-scheculed exams from the Registrar about the process.

  • You must take the exam in one of the lecture rooms in Hopkins. Other arrangements can be made through OAE.

  • You will have 2.5 hours to complete the exam.

  • It is closed-book and covers material from the entire semester.

  • You should be familiar with the languages we have discussed but you will not need to write any code beyond perhaps a simple class definition or method in Scala/Java.

  • You may not discuss any aspect of this exam with anyone except me until after the entire exam period is over. This includes students enrolled in the class, other students, other faculty, etc. If asked about the exam, the only acceptable response is "I'm not allowed to discuss it."

A Brief List of Course Topics

These are many of the big ideas we discussed during the semester. This list isn't meant to be exhaustive but may at least serve as a starting point for thinking about the material.

Foundations & Theory

  • Undecidability the Halting Problem and what it means for what languages/tools can do.
  • Grammars & parsing: parse trees, precedence, ambiguity; the pipeline from source text to an executable program.
  • Lambda calculus: bound vs. free variables, β-reduction, translating language features down to λ.

Functional Programming

  • Lisp: cons cells, recursion over lists/trees, evaluation model.
  • ML / Higher-order functions: map/filter/reduce, currying, anonymous functions, pattern matching, algebraic data types.
  • Functional idioms: working without mutation, expression-oriented thinking.

Types & Type Systems

  • Static typing & polymorphism: parametric polymorphism.
  • Type inference: Hindley-Milner–style: generating and solving constraints.
  • Subtyping: definitions across languages; function subtyping with covariant return / contravariant argument.

Runtime & Memory Model

  • Scoping: static vs. dynamic; access links,
  • Activation records: basic parts, access links.
  • Closures: what they capture and how they're represented.
  • Parameter passing: by-value, by-reference, by-value-result (in / in-out / out modes).
  • Storage management: stack vs. heap; garbage collection techniques (mark-sweep, copying, reference counting and its limits); definition of "garbage."
  • Tail recursion: what makes a call a tail call; why TCO lets recursion run in constant stack space.

Control Flow

  • Exceptions: raising and handling; how handlers are located on the call stack vs. lexical scoping.
  • Lazy evaluation & parallelism: evaluation strategies and when they matter.

Modularity, ADTs, and Object Orientation

  • ADTs vs. objects: type-case style (datatypes + pattern matching) vs. OO style (abstract class + methods); adding a new form vs. adding a new operation.
  • Big OO ideas (the through-line across Smalltalk, Scala, C++, Java):
    • Encapsulation: hidden state, public operations.
    • Dynamic dispatch: the method actually invoked depends on the runtime class of the receiver, not its static type.
    • Subtyping: when can a value of type S be used where T is expected?
    • Inheritance: code reuse and incremental specialization. Single inheritance (Smalltalk, Java) vs. multiple inheritance (C++, Scala traits); the diamond problem and how each language resolves it (C++ virtual bases, Scala linearization, Java's interfaces-only restriction).
  • Language-by-language instantiation: how do the above work in Smalltalk, Scala, C++, Java?

Concurrency

  • Deterministic parallelism: splitting independent work across cores to go faster while preserving the same answer on every run.
  • Non-deterministic concurrency: multiple activities make progress and interact, and the order of those interactions is not fixed.
  • Threads and synchronization (shared-memory model):
    • Race conditions and atomicity: what goes wrong when interleavings of unsynchronized reads/writes break invariants
    • Synchronization primitives: locks / synchronized, the cost of safety is contention, blocking, and the risk of deadlock.
  • Actors: message-passing model and implementation