Compiled languages produce machine code that can be directly understood by a processor (after they are compiled). C/C++ is an example where you write your code, compile and the processor can run it directly. Assembly can also be sort of considered a compiled language but the compiler is so simple that it is often referred to as an assembler. If you want to run the code on a different architecture you will need a different compiler as the machine code produced is specific to a certain architecture. Your x86 compiled code will not run on a ARM based system for example.
Interpreted languages are very different. The code is kept in a form that cannot be executed directly by a processor but instead has to be given to an interpreter program (a program that takes in interpretable code of a certain type) which then performs the logic declared by the code. There is an advantage to interpreters, the program file is no longer platform specific as it was with compiled files although each platform does require an interpreter to run it. The three main classes of interpreter are high level, virtual machine and emulator.
A high level interpreter is like Python that directly interacts with the high level language file (python variables are stored in hashtables with the variable name as the index, why it is very slow). Although some kind of pre-processing can be done (compiled python file which turns each line into a series of op-codes for speed) the very nature of these languages is very difficult if not impossible to translate to machine code. These interpreters are very slow and only really suitable for convenience use (macros, scripts) rather than actual programs. Programs that offer to bundle these languages as an executable program file often do so by bundling the interpreter with them and calling the interpreter to run the program file.
Virtual machines are a step up. These only interpret pre-compiled bytecode code files (like Java). Unlike compilers, the compiled code files are platform independent so will work on any platform with the virtual machine. As these languages are much more like compiled languages, the virtual machine can efficiently translate the bytecode directly into machine code when loading a file allowing for very high performance. The programs can even execute faster than compiled code as the live compiler has usage information that standard compilers do not have and so can make more efficient optimizations (Java does this). These programs can be statically compiled into a program file similar to how the code is generated during runtime but less intelligently but doing so defeats the purpose of using such a language (platform independence).
The final type are emulators. These are like virtual machines but instead of taking bytecode, they take machine code for another platform and execute the logic as if it could run natively but slower. The main complexity with emulators is the difference in architectures (some logic cannot be recreated directly, only virtually). There is also the problem with context (what context should the machine code run in?) since it might have external dependencies that are system level (require operating system functionality). These problems mean that emulators are generally used to run entire systems, operating system included, rather than individual programs like other interpreter types. The most common emulators are used for old video games (that run on consoles no longer produced) or to debug micro processors. Emulators can be fast and use optimizations present in virtual machine interpreters but often the architecture complexity prevents such optimizations forcing them to be very slow (multiple instructions per instruction run). The most common problem is the dynamic code generation problem which is caused by the instruction read being able to access any address which prevents emulators from compiling foreign machine code into native machine code.