My strongest believe is that everyone who devotes his life to Software Engineering, should have a CS degree.
Why? Well, it's a different question, so I would postpone my answer for now.
Instead, in the following post I would like to emphasize the subjects (and hence the tools) one should acquire during his studies.
These tools are essential in creating a "shared" language between us the engineers.
These tools are essential in being the solid ground of our day to day architectural and lingual abstractions.
These tools are essential in being the means of our research capabilities, logical deduction, advantages and disadvantages of each method we apply and etc...
In my opinion, those are the topics one should concentrate on:
- Data Structures - Any course that involves Data Structures, from basic to more complex Data Structures.
- Algorithms - Graph Algorithms, Dynamic Algorithms, Greeding Algorithms, Aproximate Algorithms, Computational Geometry and etc...
- Operating Systems - Everything that involves Operating Systems from theory to practice. If there is a lab on OS, take it!
The importance of understanding the bits and bytes of the biggest abstraction we work against every day is priceless.
- Artifical Intelligence - Searching techniques, Logic deduction, Decision tees, Learning technique such as Markov Chains, Neural Networks, Bayesian Networks and etc...
- Programming Languages - No, it isn't "Programming in Java"; These courses involve the principles of Software Languages, which are crucial for identifying the right tools for the job.
Imperative and Declarative Languages; OOP, AOP, Functional and Logical Languages; The more principles you learn (and the more languages you see) the more you will understand how to apply these languages and when.
In addition, I recommend taking a few "narrowing" courses, courses that are deepening your expertise in a specific field.
Some examples are: Natural Language Processing, Computer Vision or Distribute Programming.
It's worth noting that, in my opinion, practical principles of "constructing" software should be learned differently.
Those skills are better acquired by enrolling into an apprenticeship program, by reading classical books and essays, by rubbing elbows with others or by deliberately practicing.
If you are interested in such practical experience, please apply for the Mentorship/Apprenticeship program we enrolled in our Software Craftsmanship Group.