Structure and Interpretation of Computer Programs
Design Patterns: Elements of Reusable Object-Oriented Software
Code Complete
Refactoring: Improving the Design of Existing Code
The Pragmatic Programmer
Applied Cryptography by Schneier
Mythical Man Month by Brooks
The main exceptions will be programming books which focus on versions of programming languages which have gone though extreme changes between released versions. Like (say) GTK+, Visual Studio, etc
But 40-year old books on C, COBOL, and Pascal will be very useful, likewise books on algorithms like (say) Binary Trees, etc.
A lot of it tackles flaws in Java itself, and assumes that OO in geeral has the same problems. For example passing an object instead of multiple parameters into a function. It's one of the suggestions that our team just agreed to reject for Kotlin/Dart because we could set default values.
Uncle Bob is generally one of the best in explaining why problems happen, though you have to step aside and think whether the solution he proposes is the best.
- Beej's Guide to Network Programming (1994 originally I believe). Fantastic intro to networking programming via the Unix interfaces.
- The C Programming Language (1988 for 2nd edition). There has been change, but not a crazy amount.
- Mastering Regular Expressions (2006). Never look at a regular expression with fear again!
- Patterns of Enterprise Application Architecture (2002). Some of the patterns are antiquated but a lot of them are fantastic for modern development. Some of them are core to a lot of development now but we just don't think of them.
Often called PAIP. Uses Common Lisp to build classic symbolic AI programs, but has lots of good general advice on building big programs.
The vocabulary might seem foreign today but the concepts are as crucial as ever in the world of modern microservices.