Microsoft has brought a lot of their bad reputation as far as software quality on themselves. The Win9x line was terrible. But NT/2K and XP is quite stable. I don't think I've had a crash since I started using Win2K almost 2 years ago. Some apps crash, but you can just end the process without affecting other programs.
All the blogs and articles I read from MS devs suggest that the culture is very focused on reliablity. I am mostly exposed to this area of Microsoft - the developer bit. I don't much care for the business aspect of it. But inevitably, since they are a public company, that business case plays a role. To fix a small bug, we think, one small change... what's the problem in fixing it? But when that software is used by millions, you need to spend a lot of time/resources/money testing whether it broke something else.
I agree with your comments on security. Features came first before security. Before the internet really went big, it wasn't as critical as it is now. Just as they completely ignored the internet they seemed to also have ignored security in their products until it bit them in the arse. I think now that's also changing. Let's see what comes of their initiative.
Regarding theoretical courses... It just seems to me that the prof's do a piss poor job of getting anything through. I've taken 2 classes before and am taking one now. In each of them, I didn't get anything out of it. The point is to be able to apply that theory to practical uses. I'm clueless about that. And most people I've spoken to also feel the same. I find that it is more tuned for maths majors. In my view, if I could use those three classes to learn design basics, that would be more worthwhile. I don't plan to be a great research scientist, just to write some code.
The JUnit thing was for one project in one class. It was great because we had not been exposed to that. I actually didn't understand what it was trying to accomplish until after another student explained it to me. It wasn't anything formal.
I haven't actually read a design book. But I have scanned through some at the library. I think maybe before I make more dumb comments I should actually read one ;-) But they somehow didn't appeal too much because as you said they looked quite theoretical. And as I said before, it seems to me that it is one area where guidance is required. You need someone with prior experience to help.
Regarding exceptions... I didn't say they are inefficient (Actually technically they are very inefficient performance wise and should only be used in exceptional situations). They're probably the best way to deal with errors... much better than error return codes etc... I'm saying that you shouldn't need to have try/catch blocks everywhere.
There is a series of interviews with Anders Hejlsberg on artima.com regarding the design of C#. There was one interview focused on exceptions. This is what he said at one point...
"Surely in any kind of event-driven application like any kind of modern UI, you typically put an exception handler around your main message pump, and you just handle exceptions as they fall out that way. But you make sure you protect yourself all the way out by deallocating any resources you've grabbed, and so forth. You clean up after yourself, so you're always in a consistent state. You don't want a program where in 100 different places you handle exceptions and pop up error dialogs. What if you want to change the way you put up that dialog box? That's just terrible. The exception handling should be centralized, and you should just protect yourself as the exceptions propagate out to the handler."
I'm talking about that "centralization" of exception handling. How dyou design that for your app? I suppose the relation is to "magic" numbers vs constants. With constants you can make one change somewhere and it propogates to all areas of code. In the CDPlayer app, there are try/catch blocks everywhere in the UI. So if I need to change anything, I got to look everywhere.
BTW, check out the interview... http://www.artima.com/intv/csdes.html. It's a series - there are about 7 as of now. I think there is a similar one with James Gosling as well.
Assertions are great. That's basically what JUnit does. It's a framework for testing built around assertions. The way I think about them is... assertions are for programmers, exceptions are for users. If you are coding and you have an assertion that fails, the program will halt and tell you where the error is. But you don't want the user to see that. You want an exception and a nice user friendly message.
Definitely good prog practice. Even better is to have a class invariant. That's basically a method in each class that checks that the data is in a valid state. So, if your class keeps track of age. You know it can't ever be negative. So, check for that and if ever it is negative, return false. Then have assertions on this invariant, in all methods.