Hi HN,<p>I'm about 3 years into my career as a Software Developer. I've realized my day to day has almost nothing to do with architecture or programming. It is mostly about problem solving with constraints--creative solutions to bespoke problems (<i>not</i> programming problems). For example, we had a feature that streamed one of our large models to prevent Out Of Memory exceptions, but it was extremely expensive. The goal was to reduce the cost of this feature while maintaining reliability in the service, so no Out Of Memory exceptions. We ended up turning off the feature, deploying a larger machine, which fixed the Out Of Memory exception for most cases, and if it still failed, only then do we initiate the streaming of the resource.<p>I would've never thought of this. My initial plan was to root cause the high memory, which might've been a rabbit hole even if timeboxed, and I don't think I would've had a solution at the end. I suppose I was trying to "fix the high memory issue" instead of "reducing cost", which was what I was <i>actually</i> tasked with doing.<p>My take-a-aways were:
1. If it can be solved with more money, it saves you time.
2. To prove something is or isn't necessary, run an experiment.<p>I think these are lessons I can learn over time but I'd like to actively work on it.<p>I've heard these can help:
1. Solve lots of problems (where do I find these kinds of problems?)
2. Read post-mortems
3. Read editorials
4. Read about different architectures<p>Or is it something that just comes with experience?<p>Thanks for the help!
1. Reading helps. I find that reading the "manual" of a tech stack helps even more. Reading it slowly brings the best results, and if all else fails, reading the source. Under time pressure, my previous tendencies were to "Stack Overflow" and keep pasting stuff until it works. For simpler problems that worked, but for complex problems it didn't. Reading has helped a lot.<p>2. You can solve lots of problems and it might help. Over the course of time, my problem-solving skills improved slightly by the amount of problems I was solving. My problem-solving skills improved a lot just by polishing my problem-solving method. At the start of anything I take 15-30 minutes to write down the tasks I need to do and coordinate with others to check if it's the right set of things. I write, down to the classes, that I think I need to work on. For debugging, it's polishing the red-green-refactor cycle, for harder bugs I write the actual layers I need to peel (os/db/language version? database layer all good? weird logs? check disk? check I/O? network? skim through mailing lists? iperf? database? etc.).
When tackling a problem and coming up with a solution, think first about how would you test that your solution will work. Software Engineering is unfortunately far away from being able to prove the correctness of a solution, but having a good plan of how to demonstrate the robustness is a promising step towards good engineering.<p>But yes, most of it comes with experience. Software engineering is mostly dealing with complexity. And the realisation that you will never know enough to completely control it.
My main method is to change the "input". I understand it as to talk with the user/customer/colleague the necessary time to make the problem as simpler as possible.<p>It's rarely feasible in an entreprise because you're not supposed to discuss the "what" but only the "how".
A lot comes with experience.<p>But I actually think that there is an "unconventional" way to foster the thinking behind it. Read/learn about philosophy. A lot of philosophy is basically breaking down/questioning assumptions. Some forms of philosophy are semantics-circle-jerking. But the thinking behind is very useful in a engineering setting. You get into the habit of detaching yourself and taking a step back from "conventional" understanding.<p>Also read "Surely you're joking Mr. Feynman" or see the video "The pleasures of finding things out" with Feynman. If you adopt that way of looking at the World around you, then you will quickly be a lot better at looking at problems from different perspectives than the one directly obvious.