Abstraction is "the process of taking away or removing characteristics from something in order to reduce it to a set of essential characteristics."
As developers, we use abstractions all the time.
To say something:
using Maven to abstract the complex process of getting parts that conforms our application + compilation process (among others).
using a proxy class that takes responsibility of certain aspects of our application.
creating bash scripts to automate repetitive tasks.
Abstractions are the best way to deal with complexity.
But, as mentioned in the Law of Leaky Abstractions (http://www.joelonsoftware.com/articles/LeakyAbstractions.html)
"...(Abstractions) save us time working, but they don't save us time learning.". Even if you know how an abstraction works, take your time to learn what it is doing behind the scenes.
The truth is that sometimes we have to rely on this kind of powerful abstractions. JVM creating bytecode is a huge one, in example, and nobody will even try to find an alternative to that.
So we have to be careful when picking the abstractions we are going to use.
To comprehend risks of relying on things out of our control, or even worst, of our understanding.