To take the B-tree example: I've run across a number of people who I feel are more apt to blame "the database" for being slow; "it can't handle the load" being one of the excuses I've heard used as a "reason" to switch to an entirely newer database that "scales" better. The real reason that the DB isn't scaling is that the queries being run aren't properly indexed (i.e., there exists a B-Tree that has the column being queried, but that B-Tree nonetheless cannot effectively answer the query without reading millions of extraneous rows) and a fundamental understanding of how a B-Tree works is missing. (I find this most often arises on B-Tree indexes indexing multiple columns, e.g., for an index over (a, b), people mistakenly believe the index can effectively answer range queries on b without specifying a.)
To take the abstraction example: in a project I currently maintain, the codebase is incapable of doing anything other than being an HTTP server: the incoming JSON is handled at the lowest levels interacting with the storage systems, and those same storage layers generate the response JSON. (Though each is filtered and mangled a myriad of ways in between, but it's all dicts and lists, from top to bottom.)
> the opportunities for non-CS majors to pick up programming skills via electives or non-classroom projects are huge.
You're not wrong that these opportunities exist, but in my experience, while they do indeed teach people how to code software, they do not teach people how to engineer software. A math/physics major may only need their simulation to run on their input, but building stable server-side systems that won't wake you up in the middle of the night is a different thing altogether.