Today's programs and calculations operate not on one computer at a time, but rather on groups of processors or machines working together in concert.  But ensuring efficiency and cooperation among the threads of a program is a deeply subtle, and fascinating, problem.  This course aims to provide the techniques required to master efficient distributed programming, avoiding the many pitfalls that arise when computations share their resources.