I think I learned it through a couple of venues. I am still thinking this one out, and definitely plan to write a post about it.
1. designing "big" enterprise software from scratch, on paper, and then building a toy implementation.
I would say 95% of the actual work that goes into a big enterprise codebase are error handling, logging, changing requirements, covering the 80000 different user cases, while the architecture itself (a message bus, a pub sub pattern, a cache) can actually be written out in a few hundred lines of code.
This toy implementation can then be used to run multiple experiments: what happens if the message bus gets choked out? what happens if messages get reordered? how do you change a message schema?
These are rare and intense efforts in real life, but you can cosplay them with a few docker containers.
2. reading big existing enterprise codebases.
This is a skill that is not often taught, and people starting to read big codebases from "main.go" are usually doomed to fail, as they will hit the "big wall of enterprise indirection". Instead, try to get the codebase to compile, skim all the files at random until you think you recognize something, set a breakpoint in your debugger and run some part of the test suite or the real thing if you are adventurous. Then, try to mess with it some.
Once you found your marks, try to understand where all the big blobby nebulous enterprise nonsense comes from, and why it is there. Often, it helps to look at the source control history to see when it was introduced, and if design documents relevant to the change can be found.
I try to "read" a big unfamiliar codebase every couple of months. It could be kubernetes, or nginx, or webpack, or typescript, or react. You learn a lot about real world production code.
The amount and quality of opensource projects out there is nothing short of incredible these days. When I was coming of age in the early 2000s, it was linux, GNU, apache and a few other autotools driven monstrosities, with a CVS repository and a crusty mailing list.
3. learn to write RFCs
I started practicing writing relatively late (in fact, my blog just got started a few weeks ago), but learning to communicate clearly about design is vital. I have always done a tremendous amount of whiteboarding, and do most of my development on paper with boxes and arrows. I think this also develops a sense of "architecture" vs "code".
1. designing "big" enterprise software from scratch, on paper, and then building a toy implementation.
I would say 95% of the actual work that goes into a big enterprise codebase are error handling, logging, changing requirements, covering the 80000 different user cases, while the architecture itself (a message bus, a pub sub pattern, a cache) can actually be written out in a few hundred lines of code.
This toy implementation can then be used to run multiple experiments: what happens if the message bus gets choked out? what happens if messages get reordered? how do you change a message schema?
These are rare and intense efforts in real life, but you can cosplay them with a few docker containers.
2. reading big existing enterprise codebases.
This is a skill that is not often taught, and people starting to read big codebases from "main.go" are usually doomed to fail, as they will hit the "big wall of enterprise indirection". Instead, try to get the codebase to compile, skim all the files at random until you think you recognize something, set a breakpoint in your debugger and run some part of the test suite or the real thing if you are adventurous. Then, try to mess with it some.
Once you found your marks, try to understand where all the big blobby nebulous enterprise nonsense comes from, and why it is there. Often, it helps to look at the source control history to see when it was introduced, and if design documents relevant to the change can be found.
I try to "read" a big unfamiliar codebase every couple of months. It could be kubernetes, or nginx, or webpack, or typescript, or react. You learn a lot about real world production code.
The amount and quality of opensource projects out there is nothing short of incredible these days. When I was coming of age in the early 2000s, it was linux, GNU, apache and a few other autotools driven monstrosities, with a CVS repository and a crusty mailing list.
3. learn to write RFCs
I started practicing writing relatively late (in fact, my blog just got started a few weeks ago), but learning to communicate clearly about design is vital. I have always done a tremendous amount of whiteboarding, and do most of my development on paper with boxes and arrows. I think this also develops a sense of "architecture" vs "code".