Some things, like improved limits, apply globally across your classes, regardless of which version you're using. For example, the increased SOQL and DML limits that have occurred over time apply to all versions of code, so you get the benefits without upgrading.
Other things, such as JSON encoding and null instanceof behavior, are version-dependent. If you change your version on some code, you're accepting those changes to behavior. I don't know of a single, comprehensive list of breaking changes, although they are far and few between. The point is, make sure you're testing your code after changing versions.
Generally speaking, if the fix wouldn't disrupt normal behavior and applies to the entire transaction (e.g. limits), then it is applied across all versions. Conversely, if the fix could cause code to break unexpectedly, then it is versioned, and you must choose to use the minimum version required for the fix to apply.
Bugs may be hot-fixed when they are major issues that shouldn't be version specific, such as the LastViewedDate SOQL bug that occurred at some point (note: it's kind of a low priority because there's a valid workaround, but other Known Issues may be fixed much faster). Bugs may be fixed at any build, not necessarily a release, while new features are (almost) always deployed in a new release.
As a side note, you should generally just use the latest version instead of the second latest version (unless you're an ISV, in which case you need to pay attention to the version skew that happens each release). Using the latest code helps identify bugs. If you run into a bug, report it, then downgrade your code version to avoid the bug until it's fixed. If nobody ran the latest version of code, it would result in bugs going unnoticed longer.