The Secrets of Consulting: A Guide to Giving and Getting Advice Successfully by Gerald Weiberg.  Helped me understand why technical problems are rarely just technical.
Working effectively with legacy code by Michael Feathers . Practicing some of the techniques in this helped me get my foot in the door in a job long ago where one of the interview scenarios was "This is broken, go ahead and fix it.". I recommend reading this for anyone working on a code base that's been around for a while.
As someone who has had to fix plenty of legacy code, I have truly appreciated the people who have left me at least some working test suites to run - or just look at - and cursed many others. At the same time, I have generally been handed over code bases with tens or hundreds of thousands of lines, some of which had no useful tests.
If it is irresponsible to try to refactor or fix a codebase without first understanding all of it, it may be even more irresponsible to expect that those who follow in our footsteps will be able to do that, even if they are "gods of programming".
The reason why this is so was hammered home very strongly in Peter Naur's "Programming as Theory Building".
Unless a code base is trivially small or simple, leaving it without meaningful tests instantly creates legacy code. I'll close with an excerpt from the back cover of "Working Effectively with Legacy Code.
> Is your code easy to change? Can you get nearly instantaneous feedback when you do change it? Do you understand it? If the answer to any of these questions is no, you have legacy code, and it is draining time and money away from your development efforts.
Fair enough. I did write a book on the other parts, though.
Get dozens of book recommendations delivered straight to your inbox every Thursday.