What are some good real-life examples of pipelining, latency, and throughput?
Production lines in factories, eg. for assembling cars.

In theory, a single person could assemble a whole car from scratch. But they would need to memorize a lot of different steps and it would be hard for them to find an ideal working mode. For example, they might need very different clothes and tools for assembling the engine and painting the body. What is worse, the only way of speeding up production is assembling cars in parallel. Parallelising tasks this way does not scale well in the real world (eg. think of the logistics for getting the parts to every worker as you keep growing the number of parallel workers). In software and hardware design this also applies: (Task-)Parallelism introduces significant additional complexities into a system, so we can't blindly rely on it for scaling up indefinitely.

What factories do instead is, they break the assembly process down into distinct steps and then have each worker specialize in a specific step. This allows them to quickly learn how to complete that singular step as efficiently as possible.

In software and hardware design this is also true: Finding the most efficient design for a single, self-contained step is way easier than optimizing a big system that does everything.

Now, breaking your assembly line into its parts has its caveats: You introduce additional overhead by eg. having to move the car from one assembly station to the next. So a single car might in the end still take longer to move through the assembly line than if one person did the assembly all by themselves. But we can compensate for that by making use of the fact that the steps are independent: As soon as the first car leaves my assembly station, I immediately start working on the next one, even though the previous car still has to reach the end of the assembly line before it's completed. The latency is the total time it takes for a car to pass through the complete assembly line. Throughput is how many cars the assembly line can complete per hour. Once the pipeline is full, this is determined by the time of the slowest assembly step - the clock rate of the line.

The challenge in designing such a system is to find the sweet spot for how much work we can fit into a single step. If a single step gets too big, it again gets difficult to optimize. If it gets too small, the overhead of managing the line might be bigger than the actual work required for the assembly. But we also need to ensure that all tasks are about the same size: If a worker is able to complete a task significantly quicker than the clock rate, they will be forced to idle for the rest of their time until the next car is delivered to their station. All of this applies 1:1 to software/hardware design.

Now, in our production line scenario we have a pretty ideal situation, as the different cars can all be assembled in isolation. If someone makes a mistake in assembling car A, that affects only car A but none of the others (unless the mistake somehow forces you to stop the complete production line). In hardware or software this is often untrue. For instance, deciding whether you take a branch in a CPU instruction pipeline often depends on the result of a previous operation. However, if that operation has not reached the end of the pipeline yet, we might not have that information available. So we have to delay the execution of the branch until that information becomes available (stall the pipeline). If we have a lot of those dependencies (often referred to as hazards), we might lose all our pipeline parallelism again and our throughput approaches the latency of the pipeline.