We looked at memory of various sorts in Part 5 of this series. The '328 is a typical MCU in that it has some flash (32K) as well as some RAM (2K). It also has a bit of EEPROM (1K). That's not a lot, but plenty for a simple embedded system that typically doesn't have to do much.
To compare with early microcomputers, a loaded Apple ][+ had 12K of ROM (somewhat comparable to flash) and 48K of RAM. This is a flip from what we see in MCUs that typically have far more flash than RAM. The big difference is that all of the program code typically goes into the flash on the MCU, whereas the ROM on the Apple ][+ (and general purpose computers in general) have enough to get a program loaded into RAM and execute it.
It's interesting that CircuitPython on the new ARM based boards pretty much goes back to this earlier model: flash holds the CircuitPython runtime which loads your Python code from the flash filesystem (accessed as a USB drive) into RAM, where it's executed.
Speaking of the ARM chips, the lastest MetroM4 board has a SAMD51 MCU with 512K of flash and 192K of RAM, plus additional external flash.
When you write a program using the Arduino environment and load it onto a board, it gets stored in flash. RAM is used for your variables and the program stack.