There is a lot of futzing that goes on after the idealisms are found to be less ideal and contracts between components are never quite what they seem (consider logic interfacing/impedance etc). And when it comes to analogue things, it gets pretty wild. At that point you have to break the abstraction and know exactly what you are doing. This is a typical failure mode of the Arduino ecosystem; the abstraction only goes so far and then you're shit out of luck.
On top of that concerns like decoupling and power routing/distribution are never straightforward. So you have an ESP8266 and you connect it to a sensor and an actuator. When your sensor fires, the actuator causes voltage sag, which causes the sensor to flip back to the existing state. etc etc.
Another good example is the ubiquitous LM358. The designer needs to know about the electrical interface and constraints of both the input and the output. The input does not have compliance across the full supply line and the output can only push and pull current on certain load curves leading to weird things like distortion. The abstraction of the black box of the IC is broken then.
It's a very complicated subject which is very hard to abstract away. For ref I was an RF design engineer for several years and designed PCBs before that. I moved into software because it paid more and was much much easier (hint)