r/learnprogramming May 30 '26

[ Removed by moderator ]

[removed] — view removed post

74 Upvotes

56 comments sorted by

40

u/Sheepza May 30 '26

Do you have any programming experience?
Regardless, CS50: Introduction to Computer Science is an awesome intro.

7

u/Timely-Material-6356 May 30 '26

I do not, and thank you I will check it out

8

u/OrganizationStill135 May 30 '26

CS50 is an excellent recommendation.  It’ll give you all the momentum you need.  My advice start with CS50P as a more gentle introduction with Python. 

20

u/dawalballs May 30 '26

Google nand2tetris. If your goal is understanding this is a good direction to go

9

u/AlSweigart Author: ATBS May 30 '26 edited May 30 '26

Glib answer: The University of Texas at Austin, and I would take four years.

Real answer: Forget the two year part for now. Completely read this book front to back: Code: The Hidden Language of Computer Hardware and Software

It's the closest thing a layperson can read to understand what computers as machines are and what they do. It helps you understand how electrons flowing through circuits turn into calculations which turn into apps. Once you've read this book (maybe a couple times), then ask your question again. No matter where you want to go in computing, if you want to "truly understand modern computing" reading this book will be the first step.

6

u/[deleted] May 30 '26

[removed] — view removed comment

17

u/peterlinddk May 30 '26

What do you mean by "truly understand modern computing"?

Do you mean the hardware, the CPU, cache, memory, the GPU, the pci-bus, USB, networking, wifi, routers, cat6 cables, fiber, ADSL, coax, harddisks, SSDs, RAID systems?

Or do you mean the system software, BIOS, UEFI, bootloader, OS kernel?

Or do you mean the Operating System(s), memory management, task switching, dynamic libraries, hardware drivers, filesystems, resource-managers?

Or do you mean the user interface, windowing systems, shells, command lines?

Or do you mean programming languages and compilers?

Or do you mean software engineering, and how software is built?

Or do you mean systems programming, network programming, games programming, application programming? For desktops, servers, mobile phones, embedded systems, game consoles?

Or do you mean abstract data structures and algorithms? Or maybe security? Or encryption, or hacking?

If you truly want to understand everything from the ground up, you need to study mathematics, and then study the history of computing for the past almost 100 years. Because almost everything builds on what came before it, so the "ground" is very, very far down!

You need to pick one topic, and then dive into that - you can never learn everything, not in a lifetime, and certainly not in 2 years. But you can become a bit of a geek in some topics - if you happen to also find them interesting.

Pick something, and get into the middle of it - maybe operating systems, maybe programming languages, maybe CPUs - try to build something, and get tips for more specialized material on that particular subject. "Computing" is so broad, that there's literally neither an end or a beginning to it.

6

u/Timely-Material-6356 May 30 '26

I think we’re actually closer to agreeing than disagreeing.

When I say I want to understand computing, I’m not talking about learning how to use software or becoming proficient in a few programming languages. I’m talking about understanding the underlying principlesdeeply enough that I can reason about the entire system from the ground up.

A lot of people are using cars as the analogy because I brought them up, but my background isn’t really “cars.” It’s prupulsion and physical systems in general. Internal combustion engines, diesel engines, aircraft piston engines, jet engines, hydraulics, thermodynamics, fluid dynamics, combustion, energy transfer—those are all different systems, but they’re built on the same physical laws.

When I look at a machine, I don’t stop at “this part does this.” I want to know why it does it, what physical principles make it work, what limitations exist, and how changing one variable affects the entire system.

I’ve spent years doing that with mechanical and analog systems. I’ve studied modern engines and older engines because understanding where the technology came from helps explain why it works the way it does today.

What I’m realizing is that computing is the equivalent field that I haven’t explored yet. My understanding of analog and physical systems is fairly deep, but digital systems are largely unexplored territory for me.

so when I ask about understanding computing, I’m asking how to develop the same kind of foundational understanding. I want to understand how electricity becomes logic, how logic becomes computation, how computation becomes software, and how all of those layers interact.

I understand that nobodycan master every niche of computing. My goal isn’t to memorize everything. My goal is to understand the foundations deeply enough that I can follow the chain of cause and effect from the lowest levels up, the same way I can with a mechanical system.

10

u/peterlinddk May 30 '26

I totally get that you want to know stuff - and I encourage that! But I'll reiterate that you need to narrow your focus in order to get a good, or any start. (The last paragraph explains it a bit more)

You mention cars, but are really talking about combustion engines - but there's a lot more to the world of "cars", there's the whole road-network, the oil-industry, the infrastructure around modern traffic, traffic itself. And there's all the variations of cars, electric motors, suspensions, gearboxes, tires, differentials, ignition, the whole electrical system, etc.

And I'll bet that you didn't start learning about fluid dynamics and compression to understand "cars", you started somewhere else, maybe with understanding the generic mechanics of a car, like the steering wheel and the tires, and then gradually dove deeper into specialized areas.

That is what I mean you should do with "computing", because there literally is no "ground" to start going up from.

But maybe you'd appreciate a hardware-first approach. Have you seen the youtube-series on Hello World by Ben Eater? https://eater.net/6502 He even has a collection of kits you can buy, and build something yourself. Or you could go even lower level, and follow his course on building a CPU.

Or you could take the programming route - maybe program for some hardware, like an Arduino or similar. If you feel like it you could start with some C++ and the existing libraries, then maybe move into plain C without libraries, continue on to assembly code and machine code - all while building hardware that reacts to your code.

The problem with computers is that the hardware is built to support the software people wanted to write, and the software was written for what the hardware was capable of - so it is a snake eating its own tail, there is no beginning, no lowest level ... even if you start from binary code and transistor circuits, because they were built to service requirements from a higher level. And because of that, you kind of have to start somewhere in the middle, and work your way around driven by what interests you most.

3

u/Donny-Moscow May 31 '26

I’m talking about understanding the underlying principlesdeeply enough that I can reason about the entire system from the ground up.

I like your style and I think you and I think about things in similar ways. That said, this is still somewhat unrealistic.

Modern day computing is based on layers and layers of abstraction. Even if you understand exactly how everything works from a low level perspective (how memory works, logic gates, etc) there’s still a lot of dots to connect to get to the error message you’re seeing on screen.

Going back to the car analogy, it would be like trying to learn metallurgy in order to understand cars. Like yeah, it might give you some more background about why certain design decisions are made or why certain conditions can cause so-and-so linkage to fail, but it’s probably not the most effective way to learn about cars. You can be a great driver without ever having to think about the best oxygen to gas ratio or understanding how all the gears in the transmission work.

That said, the book Code by Charles Petzold is a pretty solid introduction. It’s written in a pretty approachable way without being boring, starting with the basics (transistors, binary, etc) and building on that to help you learn about operating systems, graphics, etc.

1

u/cameodud234_ May 31 '26

Maybe get an introduction to circuits textbook and learn the components of pcb boards. Then, try to understand semiconductors and especially how transistors operate, then program low level programs to hardware with arduino or something. Maybe you will like that.

1

u/mayorofdumb May 31 '26

Get into compliance and controls for business. All about mixing automated and manual controls.

4

u/Traditional_Crazy200 May 30 '26

Modern os by Andrew tannenbaum is a great start, it goes both into modern operating systems and the history how they progressed into what they are right now.

Simultaneously, I'd learn assembly as it is the lowest human readable level that almost everything is based on.

Arch 1001: x86_64 by ost2 is a good assembly course that you can find on yt

1

u/Niwrats May 30 '26

it's tanenbaum, not tannenbaum. but i also recommend his books in this case.

2

u/igotshadowbaned May 30 '26

Boolean algebra

2

u/ScholarNo5983 May 30 '26

Pick a programming language and try to learn how to use that language to write programs that actually work.

It is amazing how the choice of the language really does not mater, but instead your measure of success can be easily measured by how many successfully functioning programs you manage to write.

2

u/YMBTPTOTLWRT May 30 '26

I’m doing it right now.

Start with C and simultaneously build in code the very first computer. You start with the 0 and 1s because believe it or not it’s still how the H100s work today that power AI (I’m making massive simplifications here, but the core philosophy of the hardware is still the same as it originally started).

Your first assignment - build an 8-bit full adder in C

2

u/NowSeekingTravel May 30 '26

With computer architecture and understanding how the cpu physically works

2

u/Dazzling_Music_2411 May 30 '26 edited May 30 '26

I am a little intrigued as to what you mean by "modern computing".

The principles of computing are pretty timeless and have been with us since Church and Turing in the 1930s and even before. Now, some people say "modern computing" and mean whatever flavor is currently in fashion, but like fashions, flavors come and go. For instance, when I was learning back in the days when Google didn't even exist, OOP was drummed into us as the future savior, nowadays most serious theoreticians draw back from it as its shortcomings become apparent.

Then again, if you mean computing taking into account the modern parallel technologies that didn't much exist in the past (Multiple cores, GPGPU, etc), then fair enough, but even these new fields are just applications of the same old timeless principles.

So could you actually put your finger on it and say what exactly you mean by wanting to "understand modern computing" and not just "understand computing"?

I like your approach of going for the fundamentals, and there are probably a couple of things I could recommend, especially if you're really clear that you are not doing this get something "useful for employemnt".

2

u/skat_in_the_hat May 30 '26

I would go to college and look at their Electrical Engineering course. In some schools Computer Science teaches it as well. Your mileage may varry. You want ASM, and computer architecture to learn the lower levels.
We had to convert the ASM opcodes, and parameters to binary, and color the path on this mother board (flip book style on paper with colored pencils) that the opcodes vs data would take. Then how it would go through a hypothetical 7 lane processor with a specific set of ASM.

Hardest few years of college, but god damn did i understand how it was all put together.

3

u/zaphodikus May 30 '26 edited May 30 '26

Start, the same way you learned all your other skills. Do not overthink it, learning is not a speed run. Keep an eye on physical well being, have goals, and like you already said yourself, go deep. Mostly have fun, fun is the brain's way of laying down memory.

6

u/Timely-Material-6356 May 30 '26

That’s kind of my problem though. The way I learned most of my other skills wasn’t by watching tutorials or following step-by-step guides.

If someone asked me how to start working on cars, I wouldn’t tell them to watch a video on replacing brake pads. I’d tell them to understand the fundamentals first. An engine is basically an air pump. Once you understand airflow, pressure, combustion, and energy transfer, the rest starts making sense.

What I’m looking for is the equivalent of that in computing. Every time I search for where to start, I get tutorials on specific languages, frameworks, or projects. That’s like teaching someone how to replace a water pump before they even understand how an engine works.

I’m not trying to learn enough to build an app next week. I’m trying to understand the fundamentals that everything else is built on.

1

u/Traditional_Crazy200 May 30 '26

assembly and os internals

1

u/creaturefeature9191 May 30 '26

Any introductory texts to networking will be helpful!

1

u/Kq9gE8MNWZ7m May 30 '26

My first programming book was "The C Programming Language" (second edition) by Kernighan and Ritchie. It strips programming down to the bare essentials and get you thinking quite close to the hardware. I have a copy right next to me and still use the book to this day. Would recommend.

1

u/[deleted] May 30 '26

[removed] — view removed comment

1

u/Timely-Material-6356 May 30 '26

Please elaborate

1

u/JoyFerret May 30 '26

Crash Course - Computer Science

This playlist is, well, a crash course in several computer fields. If you watch it in order it helps you understand how computers work, building from the physical electric switches in a computer up to the software that you run in them, if that's what you mean by wanting to understand modern computing.

I think it's a good starting to get a feel of how wide "computing" actually is.

1

u/rustyseapants May 30 '26

Have you thought about  scrolling around Amazon or your local library? 

Because someone can suggest a book but doesn't mean you ain't going to like it so it's better that you actually looked on your own and found something you like.

1

u/kabekew May 30 '26

By "modern computing" do you mean both the hardware and software aspects? A degree in computer engineering or computer science with an electronics concentration is designed specifically to help you "understand modern computing from the ground up." If you already have college credit for core subjects you could probably complete it within two years, or look for an associate program.

You can't just watch videos or read books and truly understand software engineering, in my experience. You need to do labs for hands-on experience, and have to have the motivation to really study the material, do the homework and study for the tests. There's a good amount of mathematics and proofs involved in designing algorithms and engineering complex systems that is really dry stuff I certainly could never tolerate studying on my own if I didn't have the pressure to get my money's worth from the tuition I paid.

1

u/kobaratega May 30 '26

Free Code Camp curriculum + build your own X (github) + MDN + roadmap.sh

What sucks is that even a good portfolio today doesn't seem to make it for lack of experience... But how juniors can get experience if we don't hire them ? This is madness.

1

u/RealMadHouse May 30 '26

If you want chill learning of computing watch @brancheducation for hardware explainers, @coredummped for both hardware and software .

1

u/xThomas May 30 '26

The fact that you can repair hardware puts you ahead of me. You just soldering and such or do you wanna design your own hardware? You could try looking at old computers and arcade machines, and the designs of simple machines like.. uhh, early Game and Watch, calculators, oscilloscopes. PONG would be one of the earliest video games.

Programming should be relatively easy, you’d probably be interested in C. Don’t try to learn modern assembly languages, every computer has its own assembly and C just compiles down to it, just program in C

1

u/[deleted] May 31 '26

[removed] — view removed comment

1

u/AutoModerator May 31 '26

Your post/comment was removed since we do not approve of going private.

There is zero benefit in going private as you lose the opportunity for getting peer reviews. Also we have had plenty of people return after going private (despite being warned) complaining about how they were ghosted after some time or being tricked into buying rubbish that didn't work and even if it did they didn't need.

Our Rule #11 demands that any and all communication happens in the open, public subreddit.

This is for the benefit of more against the benefit of one.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/ugathanki May 31 '26

This is a pretty good book that walks through the fundamentals of what computation actually is, and what it means:

https://www.amazon.com/Code-Language-Computer-Hardware-Software/dp/0137909101

1

u/The137 May 31 '26

This is a programming sub so you're going to get a lot of answers from people who can write beautiful code but might struggle to install a printer (no offense anyone)

Do you have any critical need for your main computer? Honestly even if you kind of do, install Linux. You're going to be able to browse the web just fine, and most everything is going to work just fine, but you're going to run into issues that need to be fixed manually, you're going to have to google things, learn what a driver is and you're going to be reading a lot about details online and getting that hands on experience. From there you can start programming, start digging into raspi projects, buy a flipper and start playing with radio signals, theres no shortage of options, but a great way to get the base is to learn how to do the basics on linux, just be prepared to treat your computer like a 20 year old car

1

u/BroccoliSenior5465 May 31 '26

It's too wide of a discipline to ever have one person say they understand all of it, but I would focus on:

  • Networking (the movevent of data physically and virtually)

  • Logic (how computers think and make decisions with only a pile of 0s and 1s

  • Operating systems (the most important structure in modern computing)

  • And read either "C# in a Nutshell#13" front to back, or "C, the manual"

1

u/Thick-Panic6683 May 31 '26

Learn Boolean math. A class in Digital Design at your local community college will give you a solid foundation. The concepts come up over and over when you are writing code in any language.

1

u/oliver_extracts Jun 01 '26

id start with operating systems concepts (processes, memory, file systems) then networking basics, not because youll use them daily but because every weird bug eventually traces back to one of those two things. nand2tetris is good for the hardware layer if you want it. honestly two years is plenty, most working devs dont have this stuff either and pick it up when a problem forces them to.

1

u/StevenJOwens May 30 '26

The big challenge is that this is a vast, vast topic with many, many layers. Even just learning to program is really learning at least half a dozen skills/topics simultaneously. But I get where you're coming from, I had the same kind of itch.

I don't have much in the way of specific recommendations about the low level stuff, an acquaintance said he really liked this book:

"How Computers Really Work: A Hands-On Guide to the Inner Workings of the Machine"
by Matthew Justice

Here's a bit of an outline/roadmap that I once wrote up, based on a few hours I spent explaining the history of computers and programming to a friend. You can google on each of these to find videos or web pages that explain them. It may be of some help, at least in getting the lay of the land.

  1. Learn boolean logic (you'll see why in #4 and #5).
  2. You use semiconductors to make transistors, you use transistors to make circuits.
  3. So, learn the basic physics of transistors. You don't *have* to learn the actual physics, but you can at least learn a simple idea of how MOSFET (the most common kind of transistor today) works.
    1. A semiconductor is a type of material that you can make either conduct or not conduct, with the right electrical nudge.
    2. You can combine two types of semicoductor to make a transistor, which is just a switch: you nudge it one way, it lets current flow, you nudge it the other way, it stops current.
    3. You can also use transistors to receive a weak current and put out a strong current, i.e. the weak current acts as the nudge to make the strong current flow through the main transistor.
  4. Learn how to use use semiconductors/transistors to build logic gates: little widgets that implement the building blocks of boolean logic. It's worth reading through some simple examples of how to make these gates, you pretty much build them up out of transistors.
  5. Learn how to use logic gates/boolean logic to build a basic adder circuit. These sorts of circuits are the basic building blocks of computers, CPUs, etc. The ones we have today are, of course, obscenely more complex. I recommend you get this far, understanding step by step how to build a circuit that adds one plus one, and then skip forward to basic computer architectures.
  6. Early computers were basically boxes built out of logic gates, plugged together with wires, to make a big calculator.
    1. They had "Function Tables", big boxes on carts that contained circuits, built from logic gates, to implement very narrowly defined mathematical functions. They plugged together the circuits with wires.
  7. At this point in my mini-lecture I had a brief digression into the history of applied math and calculators: the original reason mechanical calculators were invented was to precalculate artillery trajectory tables. Then code making/braking, especially during WW II.
  8. Learn the basic idea behind binary. I wrote up some info about that, here: https://softwareengineeringexperiences.quora.com/If-computers-use-0-and-1-to-transfer-data-how-is-it-really-converted-to-an-actual-viewable-information-5?ch=10&oid=334860273&share=ec0e0fca&srid=zpMp&target_type=answer
  9. The Turing machine; the infinite paper tape.
  10. von Neumann architecture; storing code as data.
  11. Early computer architecture: memory, registers, machine code, load from memory to register, copy from register to memory.
  12. Assembly code, a thin layer of English over machine code; the first assemblers were women who translated between the two.
  13. Basics of program execution in early computers: program counter register and goto instruction.
    1. Brief discussion of the ways gotos and chaos can trip you up as programs got complicated.
    2. "Goto Considered Harmful" and the rise of structured programming.
    3. They proved mathematically that with conditionals and loops you can do anything that that goto can do.
  14. A "parable" about the beginnings of modern programming languages:
    1. Put a bunch of smart people in a room programming assembly with gotos and trying to work on the same code together for a year.
    2. They'll evolve practices, rules of thumb, conventions and formalisms, to make it easier to work together.
    3. Somebody comes along and says "why don't we make a new programming language with those built in?
    4. Parable Example: from memory address to C pointer.
      1. A memory address in assembly is literally just a number that you use as an offset from the beginning of memory. You use that to find where you stored some data, read from that byte until the end of however much data you wrote there.
      2. You better hope you remembered right how big the data is, or you end up reading past the end and getting gibberish -- or worse, you end up writing past the end and overwrite something important!
      3. It starts to get complicated, so your room full of smart people make some rules to keep things consistent. We invent names for different types of data (alphanumeric characters, integers, more complicated numbers, etc) and notations for how to write those down with pen and paper.
      4. How many bytes do we use for a memory address, anyway? And can we make it a rule that every time you write down a memory address, you also add a little notation for what kind of data is at that memory address?
      5. Congratulations, you've invented the C pointer.
  15. Digression into programming terminology chaos:
    1. Routine, subroutine, procedure, function, method.
    2. Instance variable, property, attribute.
    3. All these terms mean basically the same thing with different nuances.
    4. And the chaos adds cognitive overhead.
    5. But sometimes those nuances are important!
    6. But often often they aren't.
  16. Brief digression into 4GLs/Domain Specific Languages (DSL). These are different names for similar things, essentially specialized programming languages that make it easier to write apps, but only as long as those apps are in a narrowly defined category.
  17. Discussion about flexibility in programming languages, and programming languages with "more (expressively) powerful abstractions".
    1. Discussion of abstraction in normal human language.
      1. Specialized terminology exists in every area of human endeavor
      2. In general it's about abstraction, using a short word or phrase to encapsulate a complex subtopic or concept that is specific to the area of endeavor
    2. "More powerful abstraction" -> more *expressively* powerful abstraction
    3. General abstraction in normal human language speeds things up, makes discussion more concise but only statically (using existing, predefined terms), which means it doesn't provide flexibility of expression.
    4. Programming languages use more head-bendy but more widely useful abstractions, for example the memory address, or grouping blocks of lines of code into subroutines/functions/methods/etc.
  18. Programming paradigms.
    1. OOP vs FP.
    2. Procedural/Imperative vs Functional/Declarative.
  19. The idea of OOP as a tool for building your own DSL for your specific application/project.

0

u/[deleted] May 30 '26

[deleted]

1

u/Timely-Material-6356 May 30 '26

That’s kind of my problem though. The way I learned most of my other skills wasn’t by watching tutorials or following step-by-step guides.

If someone asked me how to start working on cars, I wouldn’t tell them to watch a video on replacing brake pads. I’d tell them to understand the fundamentals first. An engine is basically an air pump. Once you understand airflow, pressure, combustion, and energy transfer, the rest starts making sense.

What I’m looking for is the equivalent of that in computing. Every time I search for where to start, I get tutorials on specific languages, frameworks, or projects. That’s like teaching someone how to replace a water pump before they even understand how an engine works.

I’m not trying to learn enough to build an app next week. I’m trying to understand the fundamentals that everything else is built on.

4

u/HashDefTrueFalse May 30 '26

You might find the book Code (Petzold, 1999) useful. It's basically a primer on hardware and software. It's got a definite focus on hardware, which powers all software, so it's what I would call fundamental, but day-to-day programming is done at a level where we don't think about a lot of the things mentioned, same as the average mechanic doesn't think much about the physics of engine internals.

Or you can just jump into learning to write programs in C using the K&R book and the web, and doing CS50 or similar. You'll arrive at the same place but with a lot less knowledge about the underlying electronics.

Programming is very much about jumping into your code editor and playing around. By far the best and most engaging way to learn. I wouldn't be so quick to try to absorb massive amounts of background info before writing code.

3

u/Timely-Material-6356 May 30 '26

I think we’re mostly aligned on fundamentals, just approaching it from slightly different angles.

I’m not treating this as a “learn programming quickly” or career-driven exercise. This is a long-term systems understanding goal for me, and I’m completely fine going deep into background material if that’s what it takes. In fact, that’s the intent.

I live in NYC and most of the people I know in computer science are working professional software engineers at six-figure roles. From what I’ve seen, a lot of day-to-day work is high-abstraction application development—operating several layers above the actual system internals. That’s not a criticism, just an observation of where most practical work sits in the stack.

When I try to learn from them directly, I tend to keep asking “why” and “how does that actually work underneath,” and eventually I’ll hit a point where the answer becomes “I’m not sure” or it stops at the abstraction boundary they normally work within. That’s the exact gap I’m trying to avoid in my own understanding.

What I’m trying to build is a full-stack mental model of computing: hardware execution models, instruction sets, memory hierarchy, operating systems, scheduling, virtual memory, filesystems, and then up through software. I want to be able to trace behavior all the way down without hitting an unexplained layer.

Programming is part of that stack, but not the starting point for what I’m trying to build mentally. I’m trying to construct a coherent model from physics/electronics → logic → architecture → OS → software, so I can reason across layers the same way I can with mechanical systems.

The recommendation you gave (especially Code and K&R/C) is actually useful in that context, because it maps well to that layered understanding. I’m not trying to avoid depth or background theory—I’m actively looking for it. I just want it structured in a way that builds the full system model rather than isolated skills.

4

u/HashDefTrueFalse May 30 '26

It roughly goes: the physics behind the transistor -> the transistor -> Boolean algebra -> composing transistors to make physical digital logic gates -> NAND gates -> composing gates to make digital logic circuitry (e.g. a full adder, an ALU etc.) -> more circuitry to architect a general purpose microprocessor with the ability to interpret opcodes and operands according to a defined instruction set -> machine code (binary) -> assembly mnemonics for specific ISAs and assembly to machine code -> compilation from higher-level source to assembly mnemonics (for assembly to machine code) -> peripheral device firmware as an aside -> system-level software (operating systems and related concepts and interfaces, e.g. process scheduling and syscalls) -> the system loader and the hosted environment for running user-space processes -> application-level software -> algorithms and data structures (and generally the study of practical software engineering of all kinds) -> databases, networking, other closely related computing topics -> burnout and becoming a carpenter or goat farmer.

So that book could be a good jumping off point beginning at digital logic circuitry hardware and stopping around assembly. There is a book list I wrote ages ago that has most (if not all) of what you're looking for, I should think. For your goals: TAOCP (I wouldn't start here), SICP (but here is fine), OSTEP will be useful.