Gaps are typically tied to specific models and solution methods. The gap reflects the difference between the best known bound and the objective value of the best solution produced by a particular algorithm. How that is computed depends in part on whether you are minimizing and maximizing, in part on whether you want the gap as a fraction of the best solution or best bound, and in part on how you avoid dividing by zero. I believe expressing the gap as a fraction of the best bound is the more common approach, but I hesitate to say that it is universally adopted.
If $\hat{f}$ is the objective value of the incumbent (best known feasible solution) and $\bar{f}$ is the best known bound for the objective function, CPLEX computes the gap as $$\frac{|\hat{f}-\bar{f}|}{|\bar{f}| + 10^{-10}}$$ (and converts it to a percentage in the node log).
Regarding the difference between lower and upper bound, in a minimization problem the best known solution (whether known to be optimal or just the current incumbent) gives you the upper bound, and for a maximization the best known solution gives you the lower bound. So this is no different from the previous case.
If you have an exact solution, the value of that solution is also the best known bound, and so the difference between a "random solution" (incumbent) and the exact solution (best bound) is again covered by the above.