The goal of this course is to introduce basic knowledge to understand how modern distributed systems operate. Our focus will be on distributed algorithms and on practical aspects that should be considered when designing and implementing real systems. Some topics that will be covered are causality and logical clocks, synchronization and coordination algorithms, transactions and replication, and end-to-end system design. Although students will need to learn various distributed algorithms, this is not only a theoretical course. Thus, computer based assignments will be used extensively so that students will gain practical experience designing and implementing real systems. In addition the course will explore recent trends exemplified by current highly available and reliable distributed systems.