
- Steve Wozniak’s autobiography
- The Phoenix Project
- The Innovators: How a Group of Hackers, Geniuses and Geeks Created the Digital Revolution by Walter Isaacson
Software Engineering
About C++: The Design and Evolution of C++ and The C++ Programming Language, both by Bjarne Stroustrup, the creator of C++. The first one is a snapshot of his philosophy during early years of C++ and is useful to understand the motivations etc. It provides insight. The second one, after the necessary introduction to the language, shows how he uses C++, or expects to be used, which is interesting in its own way.
About algorithms: Algorithm Design by Kleinberg and Tardos. This gives the much needed insight instead of maths equations, data structure implementations or a catalog of what to apply where, which are all good, but are useless without insight.
Mechanical Engineering (ME is a large field, and I will limit to these two books.)
Stephen Timoshenko's two volume Strength of Materials is a seminal work, and still relevant, on a topic that is at the core of mechanical and civil engineering.
Shigley's Mechanical Engineering Design deals with designing machine parts, which is in a sense an applied strength of materials topic, and the book addresses that part quite effectively, though not as comprehensively as Timoshenko's. More importantly, the book gives enough motivation and insight for the design process, without which engineers would just be "design monkeys" that use latest CAE packages.
It was never that. Take any textbook on software engineering and the focus was never the code, but on systems design and correctness. I'm looking at the table of contents of one (Software Engineering by David C. Kung) and these are a few sample chapters:
...
4. Software Requirement Elicitation
5. Domain Modelling
6. Architectural Design
...
8. Actor-System Interaction Modeling
9. Object Interaction Modeling
...
15. Modeling and Design of Rule-Based Systems
...
19. Software Quality Assurance
...
24. Software Security
What you're talking about was coding, which has never been the bottleneck other than for beginners in some programming languages.1. Programming
2. Computer Science
3. Software engineering
Programming is, well, the act of writing code both in general and in a particular language. For this, find one or two books or courses on the languages you're using. Work through them, type up most, if not all, their sample programs yourself. Don't just copy/paste, don't download a copy of their source code. Typing it in helps a lot to internalize the information. Then create variations. I'm learning Rust, as an example, and have been writing up the programs in The Rust Programming Language, then I change their structure, make them generic, or modify other elements to see if I actually understand what's happening.
Computer science is more fundamental. For that, many of the algorithms & data structures books mentioned are great to study. It's good practice to implement both (algorithms & data structures) in whatever languages you're using, even if they already have them built in. Then switch out your implementation for the language standard version (if present) so you learn both the fundamentals (how they're built and used) and the standard (how they're used in your language). Pay attention to things like algorithm analysis, it gets cast aside here sometimes but it really is helpful especially in something like rendering. If you understand the relative costs of different choices you will get much more efficient programs, but also study how your actual system behaves. Sometimes an on-paper faster algorithm is slower in practice due to how the CPU and RAM actually work (like scanning a vector for something may be faster in practice than a faster-on-paper hash table or map data structure). You can go deeper and study theory of computation and other areas, but that's not going to be necessary yet.
Software engineering is, reductionist definition, about three things: working with others, working with your future self, organizing programs and systems. Two books I like on the non-technical side: The Mythical Man-Month by Fred Brooks and The Psychology of Computer Programming by Gerald Weinberg. Some parts of both are dated, but they're still relevant to today and thinking about how teams work and systems develop over time. On the more technical side: Learn how to test in your languages, and read Refactoring by Martin Fowler. Learn to use version control, even for toy projects. Create git repos and get in the habit of committing early and often (like with working with any file on the computer you should save early and often so you don't get burned by a crashed editor, committing early and often saves you from when you make a major change and realize you want to undo it).
---------------------
You can study programming without studying CS proper, but at some point you are likely to start running into decision points that will be hard for you without knowing the tradeoffs that CS (even just the introductory portions) teaches. Same thing with software engineering, it's not technically necessary for programming, but once you start working at scale (large projects or more than just a handful of people) it pays to understand that area.
Computer architecture course. - you need to understand the machine you are programming. Something like Meltdown/Spectre will make sense to you.
Learn assembly programming & C, does much for your confidence, you understand how your programs get turned to 10101
Take a programming language course, understand the difference programming languages. When people start talking about the new XYZ language, you can quickly evaluate it based on the paradigm and decide if you should get on it or not.
Operating System course. - The OS coordinates resource allocations to your program, you can begin to understand the discussion such as why fork() takes longer than a thread. You will make many wise decisions.
Algorithm & Design - You can write better program.
Software Engineering - You can deliver better softwares.
Automata Theory - you can understand machines more, sometimes complex logic is best representated as a simple machine. This becomes useful if you are parsing (compiler, NLP, etc)
Distributed Systems - if you have ever uttered the word microservices or plan to.
The below 3 maths are the main maths of computer science, most cutting edge work today employ some or all of them.
Linear Algebra, Discrete Maths, Probs & Statistics
It's not hard to see that agile models are pretty closely related to Boehm's spiral model. The spiral model is (afaik) more general, with the agile models focusing more on specific processes/practices.
http://www.amazon.com/Software-Engineering-Practitioners-Rog...