Ask HN: Top 10 Timeless Software Books That ChangedLife as Software Engineer?

100 points by burhanrashid52 ↗ HN
Few months month ago, Someone asked on Twitter “Do you read programming books? If yes, why?”. You can read my answer in the tweet,

Here are mine, in order of how a developer starts their journey, from basic to scaling problems:

1. Code: The Hidden Language of Computers (Pure Basic: Starting with Binary) 2. Working Effectively with Legacy Code (Dealing with an ugly codebase) 3. Refactoring Improve the design of the existing codebase (Making changes safely without breaking the code) 4. Test-Driven Development (TDD) (Once you’ve learned all the above, you always start writing tests first) 5. Head First Design Principles (Terminology and concepts for maintainable and extendable design) 6. Algorithms to Live By (Algorithms are fundamental ideas before we write any code) 7. Git Pro (Software cannot run without a Version Control System (VCS). We use it every minute of our working day) 8. Your Code as a Crime Scene (Finding problems in the code using code history) 9. Data-Intensive Applications (Databases are everywhere) 10. Software Engineering at Google (Addressing the biggest scaling problems)

Honorable Mentions: 1. Clean Code (Writing code that is easy to understand by other developers) 2. The Soft Skills (Coding alone is not enough to be a great software engineer) 3. Peopleware (Managing software teams).

Also, I am planning to write a short book summarizing all the important points from these above books. If you are interested in getting one or want to be part of an early reader, please email me at burhanrashid5253@gmail.com.

71 comments

[ 3.9 ms ] story [ 149 ms ] thread
The Pragmatic Programmer - I read this book when I was programming professionally for maybe 5 or so years, so I already had my basics covered, but reading this book really expanded my horizons on what it means to create software profesionally. I read, maybe, 100 books about programming since and before then, but no other book changed my thinking that much like this one.
Totally agree. If I had only one book to give new engineers, it'd be this one.
Did you get this booklist from ChatGPT?
I don't think so as he got at least one title wrong: Head First Design Principles should be Head First Design Patterns.
I got that book when it came out, and I quite enjoyed it. Their presentation of material was quite different at the time.
Right, because ChatGPT is never wrong.
It is very often wrong, but (at least ChatGPT4) outputs proper names correctly. Principles/Patters may seem similar for someone who hasn't been around long enough to see the whole hype cycle of "Gang of Four" seminal work.
No, I did not. Making grammar mistakes is blessing now a days :)
The Linux Command Line

by William Shotts

Glad to see this mentioned. Still keep it on my desk. This book strikes the perfect balance between reference and introductory reading.
Hacking: The Art of Exploitation (ISBN 1-59327-007-0), Jon Erickson

Really helped me bridge the gap with low-level, debugging, and C approx half a lifetime ago.

I enjoyed this one too. I remember reading about the NOP sled and it blowing my mind
Still have this book from over a decade ago. Never read it. Is it still relevant?
'A philosophy of software design' by John Ousterhout, great book which provides good understanding of what complexity in software means. Very concrete and short.
Yes, this book is excellent. And it's an antidote to some common advice that really isn't very good.
Yeah I feel the same. Its more of a philosophy. Its good to learn but hard to implement in this fast pace development process. It make sense if you have big team which job is to assess the quality of the code
I liked the books emphasis on "interface" vs "implementation", and how this affects complexity.

But one tidbit I did like from the book was along the lines of "if every use case involves the same action, it would be simpler to incorporate that action". (e.g. Something like if ".delete()" were to fail if the file didn't exist, and if every invocation would be like "if .exists() { .delete() }", then it'd be simpler to have a method without the "fail if file didn't exist" requirement).

That sounds like DRY, don’t repeat yourself. Taken to another level I try to think of this as instruction elimination. Where can I eliminate the most instructions, still pass all my tests, and then compare execution speeds?

Instruction elimination and DRY are basically the same things in practice but the former produces a more aggressive and utility focused mindset. I find when I think about large applications with instruction elimination mindset I am constantly churning on refactoring as requirements increase but the code size grows so very slowly that there is less to maintain and test automation continues to be measured between less than 7 seconds and up to 2 minutes depending upon the scenario and number of machines involved.

Thanks for the list, here it is again:

1. Code: The Hidden Language of Computers (Pure Basic: Starting with Binary)

2. Working Effectively with Legacy Code (Dealing with an ugly codebase)

3. Refactoring Improve the design of the existing codebase (Making changes safely without breaking the code)

4. Test-Driven Development (TDD) (Once you’ve learned all the above, you always start writing tests first)

5. Head First Design Principles (Terminology and concepts for maintainable and extendable design)

6. Algorithms to Live By (Algorithms are fundamental ideas before we write any code)

7. Git Pro (Software cannot run without a Version Control System (VCS). We use it every minute of our working day)

8. Your Code as a Crime Scene (Finding problems in the code using code history)

9. Data-Intensive Applications (Databases are everywhere)

10. Software Engineering at Google (Addressing the biggest scaling problems)

Honorable Mentions:

1. Clean Code (Writing code that is easy to understand by other developers)

2. The Soft Skills (Coding alone is not enough to be a great software engineer)

3. Peopleware (Managing software teams).

>4. Test-Driven Development (TDD) (Once you’ve learned all the above, you always start writing tests first)

I've seen like bilion discussions about TDD and I still dont understand why is it so overhyped.

Additionally it sucks that for some people you either do TDD or dont write tests at all (what the f...., indeed)

This whole red-green step in TDD makes complete no sense when you're writing new code.

The only value provided by TDD when writing new code is that you're forced to think from caller/user perspective, so it makes your API design better, that's it.

I don't use the proscribed TDD process very often, but I use the TDD mindset all the time to great effect.

Listing out the tests you're going to write before you write the code (even mentally) can be considered a continuation of the requirements-gathering process. And thinking about how you're going to test your code before you write it will, in my experience, improve the design. (Particularly, it seems to encourage the single-responsibility principle, as code that's doing too much or combining layers of abstraction is really hard to test.)

>Listing out the tests you're going to write before you write the code (even mentally) can be considered a continuation of the requirements-gathering process.

But this is not TDD.

I've worked in HW industry where cost of bugs is high and we analyzed specs during brainstorming session as 3-5 ppl and brainstormed test cases that we want to test.

It worked well because this way we we're finding way more things to test than when doing it alone.

But still, this is not TDD. We weren't doing TDD.

>(Particularly, it seems to encourage the single-responsibility principle, as code that's doing too much or combining layers of abstraction is really hard to test.)

Whether your code is easily testable will be challenged by writing tests regardless of the moment of writing test - before or after writing impl.

So no benefit from TDD over non-TDD approach.

> But this is not TDD.

That's true. Did you miss the part where I mentioned the "TDD process" versus the "TDD mindset"?

> Whether your code is easily testable will be challenged by writing tests regardless of the moment of writing test - before or after writing impl.

I don't want to derail the conversation, but when I'm working on projects alone then my test coverage is 100%. (Line and branch coverage.) But surely that slows me down, right? And I must have a million test cases? No, quite the opposite actually. Writing code that way is just a skill though, the same as juggling, that becomes easy with enough practice. (Along with the right practices and tools.) However, I don't aim for 100% (or even a particularly high percentage, to be honest) when I'm working on projects with other people, because the only way it's possible is if the code was designed for it from the get-go.

I encourage junior developers to learn and try to use TDD for a while because it can be useful sometimes and improve the way they write code. But I would never require them to do it.

For me TDD really helps when I am trying build business logic but its hard to follow when you want to test the UI logic Because the UI test work behave differently than the actual application
> This whole red-green step in TDD makes complete no sense when you're writing new code.

Only viewed in isolation - the point of red-green is test calibration: be certain that your new experiment is actually measuring the thing that you think it is measuring.

Red-green isn't the only way to achieve this, of course, but it is a smooth way to achieve this.

The only scenario I can think of is some crazy programming language / unstable compiler where such a thing would be needed when writing new code.

Do you have any example where going red-green found issues when writing new code?

> I've seen like bilion discussions about TDD and I still dont understand why is it so overhyped.

My guess: because it picked up a lot of momentum from the OO "patterns" community, and that gave it a lot of immediate reach and credibility.

Beck and Cunningham already had an audience of their own, and TDD also promoted Martin Fowler's ideas (pulling in his audience), and Robert Martin jumped aboard early as well (pulling in his audience).

The cynic in me notes that the Smalltalk community needed something to do, as it had by then become clear that Java was going to win that market.

'Elements of Programming' by Stepanov and McJones

'Software Fundamentals' by Hoffman and Weiss,

'Writing Solid Code' by Maguire,

'Code Complete' by McConnell

Wow!! All this new to me. Never heard of them. Will check that out.
Code Complete is one of the best books for beginners to improve their general, non-language-specific skills, IMO, though it does have language snippets as examples, and even though it is somewhat dated. The principles in it are timeless, though.

I have read both the 1st and 2nd Editions, many years ago. IMO Edn. 1 is better.

_The Mythical Man-Month_ by Fred Brooks is a short, easy read and remains packed full of timeless truths. His separate essay “No Silver Bullet” is included as an appendix and clarifies which problems to attack. A combination of improvements in tools, languages, and practices over the decades since have led to dramatic improvements since that essay, but, still, the problems of understanding and communication remain.
Always heard about this book so I got the anniversary edition. Amazing book.
How is it different from peopleware ? To me its feel the same.
In another thread I mentioned Peopleware: productive projects and teams. Even the best programming book in the universe won’t help if the environment, leadership and team don’t support your efforts. this book is about that and how to give creative knowledge workers the environment and tools they need and then get out of their way and keep others out of their way as well.

A great read whether you’re wearing a programmer hat or a manager hat.

Yeah…half of approaches the book talk about is inperson offices which is changing is right now.
And the mythical man month was written in the age of mainframes, yet remains relevant.
"Programming: Principles and Practice Using C++" by Bjarne Stroustrup, the creator of C++.

I learned programming first time from this book and I think I'm so lucky that I've done it. The book is about philosophy and the mindset of programming more than introducing some tools or techniques, so we can consider it as "timeless".

I’ve heard about this book but didn’t read because I didn’t got chance to work on a C++ project.
'Expert C Programming: Deep C Secrets' by Peter van der Linden
i would say cleancode is a counter example as most devs that read and like it just go through a phase of being unbearable and confused before figuring out their error and giving up. my absolute mind changer book was joe Armstrong's programming for a concurrent world, even without wanting to go into beam development this will change the perspective of devs in a profound and fruitful way.
Agreed on Clean Code. I remember nothing practical from that book. Its principal value is that it looks nice on my shelf.

Watching Bob Martin's talks, he just likes ranting about computers and doesn't give actionable advice. However, he was one of the first "tech" authors I was exposed to, so I guess the the book itself is good for marketing. Maybe it's accessible enough for beginners. But now the book is certainly worthless as a reference or refresher to me.

Agreed, mythical man month should be on all software book lists.

I would also include: Design Patterns: Elements of Reusable Object-Oriented Software

I didn’t read mythical man month because it felt similar to peopleware.

The classic design pattern book is very jargon heavy. Not for someone who is just starting out.

all i can say is ... no

i would be interested in stopping you writing your book - i really do not think you have any idea about software development

Can you edit and reformat the text by adding breaks?
For me, two books that changed how I thought about software were (and I may date myself here):

1. Advanced Programming in the UNIX Environment[0]

This changed writing software from being about the code I was writing to being about the underlying systems my code was interacting with. My favorite little feature I learned about was the ability to pass open filehandles between processes (not threads, but processes), which I later used for open connection caching in Usenet systems.

2. Object Oriented Perl[1]

The mind-bending part of this book for me was when Conway explains about using structures other than hashes (dicts) as Perl objects. Arrays were interesting, scalars slightly more so, but then functions ... as objects. This one chapter brought clarity to functional programming that I never got from any other explanation.

All the other books listed here are on the list two, but these were two books about specific mechanics of software development that were worth so much more outside of their respective languages.

(edited to add links)

[0] https://www.pearson.com/store/p/advanced-programming-in-the-... [1] https://www.manning.com/books/object-oriented-perl

On a similar note, the book crafting interpreters on build programming language changed my perspective on the day-to-day code I read.
Not a book, but an article: Herb Sutter's "What's in a Class?" completely changed the way i thought about OO programming and still holds up today.

<http://www.gotw.ca/publications/mill02.htm>

PS: plus anything by C++ guru Scott Meyers.

For me, "Hackers and Painters," by far.