It is indeed important to separate the situation at schools from the situation at universities. Our CS curriculum contains many courses where the foundations of computer science are taught, including the maths behind it, such as discrete structures, languages and automata, program correctness, besides courses in imperative programming, object-oriented programming, functional programming, parallel programming, software engineering, networks and computer architecture. etc. The emphasis is very much on what is happening under the hood. Prospective students often ask us what programming languages we teach, and we invariably answer that that is really unimportant. We teach programming paradigms, and the ability to learn new languages. Once you know how to program in one structured imperative language, learning another is largely a matter of learning syntax. What is far more important is learning how to cast a problem into imperative-programming (or OO, or functional) terms.
Many schools here in the Netherlands do not teach CS, and those that do, often struggle to find good, qualified teachers. We also find that for those students who did follow CS at school, their maths grade is a far better predictor of success in CS at university than their CS grade at school. The CS taught at school does not really prepare them for CS at university. This is why we organise outreach events for school kids, to show them what CS is really all about. We recently had a contest for school children in which they had to solve a series of problems (such as cracking a Caesar Shift code) by designing Turing machines for the task. This levelled the playing field, because none had ever done this, and they cannot cut and paste solutions from anywhere. It also teaches them a structured approach to solving problems. The day was a great success, and they thoroughly enjoyed the challenge. We will make the course material and web-tools available to schools, and are looking into other ideas.