Explain the architecture of a Spark job and how you would identify and resolve data skew issues causing executors to run out of memory.