I came into a software engineering career from a B.S. in Mathematics. I had no idea how thinking like a mathematician dominated my approach to engineering until I figured out that not everyone develops software the same way - that was 25 years into my career.
To me, the key leap of understanding in a mathematics education is realizing that mathematical proof isn't about clever, convincing arguments that have a high probability of being true. Mathematical proofs are truth preserving operations that require you to understand and document all the assumptions needed to guarantee that truth is preserved throughout. It's about understanding exactly what you know and, more importantly, what you don't know but that you need to be true in order to guarantee truth. And "guarantee" here does not mean "very very very high probability." It means "exactly zero exceptions, given that the explicitly documented assumptions hold." A mathematics education goes on to give lots of practice identifying these assumptions in various ways and in various domains.
This line of thinking has served me well as an engineer. I almost never go as far as formal methods or using full mathematical rigor. But I do try to understand the assumptions I'm making and whether those assumptions are likely to hold in the application domain. For example...
I assume reading from disk repeatedly (vs. preloading into RAM) is fast enough for my use case, but I need to test that assumption. Write a quick test... it's fast enough on my laptop's SSD. But I'm going to deploy to spinning disks and I'm doing a lot of seeking - better test there as well. Nope, too slow. If build a simple index of the data, is it fast enough? Write a quick test... yep, so I don't need to deal with cache eviction strategies. Oh, but I'm assuming the tests I wrote are representative, so I need to give myself a couple of orders of magnitude of headroom to be pretty sure.
This is not mathematical rigor, but it's leveraging a lot of that kind of thinking. My entire design/code/debug lifecycle is constructed around identifying and testing assumptions like this.
When I realized this came from my background in math, I started trying to figure out how some of the people around me were doing things when they had little or no math background (i.e., not enough to have a ton of practice comprehensively identifying assumptions). Some had come to a very similar process, just not through math (many with graduate degrees in biology or experimental physics also had a pretty direct route to similar enough thinking). Some were much more intuitive about things - I don't think I could develop anything that way, but they were very good at their job. I think this is part of why UI/UX work was always so frustrating for me - the assumptions run so deep that simplifying through intuition is constant, and testing (e.g., through user facing experiments) is expensive.
I'd love to see deeper studies into the range of cognitive practices employed by various software engineers and how that differs across educational backgrounds and application domains. How does that differ from graphic designers, accountants, EEs, mechanical engineers, etc?
To me, the key leap of understanding in a mathematics education is realizing that mathematical proof isn't about clever, convincing arguments that have a high probability of being true. Mathematical proofs are truth preserving operations that require you to understand and document all the assumptions needed to guarantee that truth is preserved throughout. It's about understanding exactly what you know and, more importantly, what you don't know but that you need to be true in order to guarantee truth. And "guarantee" here does not mean "very very very high probability." It means "exactly zero exceptions, given that the explicitly documented assumptions hold." A mathematics education goes on to give lots of practice identifying these assumptions in various ways and in various domains.
This line of thinking has served me well as an engineer. I almost never go as far as formal methods or using full mathematical rigor. But I do try to understand the assumptions I'm making and whether those assumptions are likely to hold in the application domain. For example...
I assume reading from disk repeatedly (vs. preloading into RAM) is fast enough for my use case, but I need to test that assumption. Write a quick test... it's fast enough on my laptop's SSD. But I'm going to deploy to spinning disks and I'm doing a lot of seeking - better test there as well. Nope, too slow. If build a simple index of the data, is it fast enough? Write a quick test... yep, so I don't need to deal with cache eviction strategies. Oh, but I'm assuming the tests I wrote are representative, so I need to give myself a couple of orders of magnitude of headroom to be pretty sure.
This is not mathematical rigor, but it's leveraging a lot of that kind of thinking. My entire design/code/debug lifecycle is constructed around identifying and testing assumptions like this.
When I realized this came from my background in math, I started trying to figure out how some of the people around me were doing things when they had little or no math background (i.e., not enough to have a ton of practice comprehensively identifying assumptions). Some had come to a very similar process, just not through math (many with graduate degrees in biology or experimental physics also had a pretty direct route to similar enough thinking). Some were much more intuitive about things - I don't think I could develop anything that way, but they were very good at their job. I think this is part of why UI/UX work was always so frustrating for me - the assumptions run so deep that simplifying through intuition is constant, and testing (e.g., through user facing experiments) is expensive.
I'd love to see deeper studies into the range of cognitive practices employed by various software engineers and how that differs across educational backgrounds and application domains. How does that differ from graphic designers, accountants, EEs, mechanical engineers, etc?