What No One Else Will Tell You 🙂

Professor Norm Matloff
Department of Computer Science
College of Engineering
University of California, Davis


In the Department of Computer Science, two undergraduate majors are offered, Computer Science and Engineering (CSE) in the College of Engineering, and Computer Science (CS) in the College of Letters and Science. (Note that although majors are offered in both Colleges, the Department of Computer Science itself is in the College of Engineering.)

At almost any university and in almost any undergraduate major, the standard way to proceed through the major is to read the university catalog for course requirements, and take the courses one by one in a robot-like manner. One then graduates, holding a diploma but otherwise being in many senses illiterate in one’s claimed field of expertise. The purpose of this document is to avoid such a sad and wasteful situation.

We will take a look here at the broad field of computer science — what its major components are, why each component is important, how the various courses relate to each other, and so on. And, since computer science is a professionally-oriented major, we will discuss employment issues as well.


A top-to-bottom view of computer science might consist of the following levels, with typical questions from each:

Theory: How many operations are needed, and how much memory space is needed, to accomplish a given task? This view is taken independently of a specific machine or specific programming language.

Software: How may operations for a task be expressed? How can software be written so as to minimize development time and defects (“bugs”), and maximize future maintainability of the code? This view is generally machine-independent, but often is influenced by awareness of the general nature of the hardware.

Hardware: What are “gates “, and how can they be used to build digital machines? What makes one computer faster than another? How can multiple simultaneous operations be designed so as to increase speed? How do computers communicate to the outside world, especially in computer networks.

Electronics: How can gates themselves be built from the transistor level? How can the entire digital system most efficiently be laid out onto a chip?

The CSE and CS undergraduate majors can be roughly described by these levels in the following ways:

Theory X X
Software X X
Hardware X X
Electronics X

In other words, both majors include courses in theory, software and hardware. In addition, the CSE major also includes courses in electronics.

A better understanding can be obtained by categorizing the individual courses according to content at these levels:

Pure theory ECS 20, 120, 122A, 130
Theory and software ECS 60, 122B
Pure software ECS 30, 40, 140A/B, 153, 160, 170
Mainly software, some hardware ECS 142, 150, 152B, 163, 165A/B, 168, 175,177, 178
Equally software and hardware ECS 50, 151A/B, 158, EEC 172
Mainly hardware, some software ECS 152A
Hardware ECS 154A/B, EEC 180A
Electronics EEC 100, 180B
Heavily mathematical ECS 130, 175, 177, 178

All three areas — theory, software and hardware — are important. If you take the point of view, for instance, that the only area which really counts is software, or if you only concentrate on hardware, you will have lost the game before you even have started. Instead, it is imperative that you develop a broad, balanced understanding of computation in all three areas. In addition, you should develop an appreciation for the manner in which the three areas interact.

For example, contrary to what you may have thought previously, there is no sharp distinction between software and hardware in the computer industry. Consider a company like Sun Microsystems. Hardware designers must take software factors into account in their designs, and software developers need to understand the hardware on which the software will run. Thus hardware and software designers of computer systems work in concert. The role of theory is often under-appreciated. Though the benefits of theory courses may at first seem unclear, good insight into theory courses can be of tremendous help in other courses. To illustrate this, consider the following anecdote.

ECS 20 teaches a proof technique called “mathematical induction ” (some students have also been exposed to this concept in high school). Some students can mimic its use well enough to get partial credit on exams, yet not really understand it. Consequently, these same students have trouble with an important programming technique, “recursion”, which is similar to induction. They can mimic it, but can not write original programs.


Most students (and probably most faculty) tend to have certain images of the jobs which the CS and CSE curricula lead to. Many CS and CSE majors tend to view themselves as “Computer Programming” majors, preparing for careers as programmers. Some other CSE majors see themselves as future hardware designers. Yet these images do not necessarily jibe with reality.

First of all, there are far fewer jobs in hardware design than in software development. (A rough way to understand this is that there are only a few major types of CPUs, sound cards and the like, yet tens of thousands of software packages.)

Yet it still would be wrong to view the CS and CSE majors as leading mainly to jobs in programming. In fact, fewer than 50% of CS/CSE majors actually become programmers. Many end up in other types of computer-related work, such as customer support, system administration, software testing and so on. These jobs often require knowledge of computer systems themselves, such as the physical structure of computer networks, as well as the software which interfaces the hardware, such as the operating system and device drivers, This systems-level knowledge will be at least as important as programming skills, often much more important.

If for example you get a job as a system administrator and you only know programming, you will be lost when some user complains to you, “Hey, my machine won’t boot up!” Systems administrators also need to know enough about the hardware and low-level software to make intelligent decisions as to what kinds of machines to purchase, how to maintain a network, and so on. They will typically do some amount of programming too, but you can see that programming is only a small portion of the technical knowledge they need.

This is not meant to discourage you from seeking a career in programming. On the contrary, in my opinion the best jobs are in programming, and if you enjoy programming, you should work toward this kind of career. In order to do so, you should make every effort to acquire practical job experience while you are in school; see the section, “ACQUIRING PRACTICAL EXPERIENCE,” below for details.

Even if you are aiming for a career in programming, it is vital to develop a thorough knowledge of computer systems as well as programming skills. When you interview for jobs, you WILL be asked both types of questions, i.e. programming and systems.


No question about it—grades are important. Good grades will help you get scholarships and summer jobs. Grades will certainly comprise a major selection criterion if you apply for graduate school. Most large companies stress grades when you apply for your first job after graduation.

But what will count the most when you look for jobs after graduation is your ability to speak intelligently about computer systems to the employers who interview you. Your grades will get you an interview, but your performance in the interview is what will get you (or lose you) the job. So it is crucial that you keep sight of “the big picture” as you make your way through your undergraduate curriculum. Getting good grades is NOT enough.

Concepts should be learned for the long term, not just “temporary storage” for a final exam. It may surprise you to know that when interviewing for a job, you probably will be given an informal test of your technical knowledge. You should be able to engage in an intelligent discussion of, for example, how an operating system manages user files, what a network socket is, and so on. Trying to do a “cram review” of all your coursework before an interview is obviously impossible. Instead, the best way to prepare is to continally sift the concepts through your mind as you take the courses, keeping in mind the fact that you will need to know this material later on, not just for a final exam.

If I were to ask you right now where Brazil is, you would immediately answer that it is in South America. You would not have to go to a book and look up this fact. You would simply know it, without reviewing your old school notes. You treat this as basic information, that everyone knows; in fact, if you encountered someone who did not know it, you would think there is something wrong with him/her.

The same principle holds for computer science. After you graduate, if an employer asks a question in a job interview such as “How does a program get loaded into memory for execution?”, the employer will think there is something wrong with you if you can’t intelligently discuss this. And it is something you should be able to discuss at any time, without having to review your old course notes the night before the interview.

Some years ago a Ph.D. student failed to answer a very easy question on input/output systems in his final oral examination. When I mentioned this to an undergraduate the next day, he knew the correct answer immediately and said, “I don’t see how the Ph.D. student could have missed that. I always thought it was interesting that those systems worked that way.” Again, the point is that this undergraduate knew the answer without having engaged in any prior review; he just knew it offhand, just as he would have known where Brazil is without review. It is no coincidence that this undergraduate later went on to great success in the computer industry, reaching a high-level management position in Sun Microsystems and later starting his own firm.


Programming ought to be an enjoyable, intellectually challenging and even aesthetic activity, like art. But as you may already know, the debugging process can be frustrating and extremely time-consuming. In order to make that process go as smoothly as possible, you should make full use of software tools.

First of all, make sure to use a debugging tool, such as ddd/gdb. You can learn about this at


Second, make FULL use of whatever editor you are using. For example, most sophisticated editors (for instance emacs, joe and the elvis version of vi) allow you to create subwindows within the editing screen. This allows you to look at different parts of a program file at the same time, making it easier to fix bugs involving problems in the way in which those different parts interact with each other. A good editor will also have lots of shortcuts which save you typing; this may sound like a small thing, but it allows you to reduce fatigue and to concentrate much better on the task at hand–debugging–instead of being distracted by lots of typing. Advice on this is available at


Third, make sure you know UNIX well. The UNIX operation system is used in our coursework, and at least half of our graduates who get technical positions work in UNIX environments. You should put UNIX to work for you, for example by devising various shortcuts in the form of UNIX shell “aliases” to reduce typing. Make use of the shell’s “history” feature, so that for example you can easily modify a previous command you submitted, rather than re-typing the whole long line from scratch. You should know basic UNIX commands for files, directories, processes and so on thoroughly, and make full use of this knowledge. See


Finally, install Linux on your PC at home. Linux is a full version of UNIX designed for PCs. This is extremely valuable, because (a) it allows you to work in the comfort of your own home, and not tying up a phone line with a modem connection (b) in your installation and use of Linux, you will learn important practical things (e.g. working as “root,” setting up disk partitions and so on) that you will not learn in your coursework. Linux is actually easy to install; detailed, “handholding” directions for beginners are available at


Some of the items mentioned above will be covered to some extent in your courses. But remember that you should make use of them in your everyday programming activities, not just when your instructor tells you to. For example, the reason for learning how to use a debugging tool is NOT because there might be a question about debugging tools on the final examination in ECS 30 or 40, but instead because you want to save yourself time and frustration in the debugging process.


While great effort has been made to include a strong practical component to the curriculum, there is no substitute for real experience. There are many things which cannot be learned in a course, and moreover, it is very important to shed the “partial credit” type of thinking which one finds in classroom settings. Therefore, note carefully that the best way to maximize your chances of getting a good job after graduation is to get industrial experience while you are in school — via co-ops, summer jobs or internships.

Students are strongly encouraged to seek computer-related summer employment, internships, co-ops, and part-time work on campus. Of these, co-ops are the best; these typically are six months in duration, combining a summer with a one-quarter leave of absence from the university (“PELP”). Also, the best types of work, in terms of getting access to a widest variety of jobs after graduation, are those that involve actual programming.

You should make every effort to seek these positions, starting your search during the Winter Quarter of your sophomore or junior year. You should keep informed by frequently checking the ucd.cs.jobs newsgroup, by contacting the Internship and Career Center and by direct contact to employers (especially if you know someone at a given firm).

In order to maximize your chances of getting student jobs like these, you should try to take work-related courses e.g. ECS 150, 152AB, 160, 165AB, 175) as early as possible.


You have probably heard quite a lot about the importance of communication skills with regard to employment. It’s all true!

First of all, during job interviews almost all employers equate verbal ability with intelligence. They may not be conscious of this attitude, and it may not be justified, but the fact remains that this is the way things work. The talkative, outgoing applicant will always be hired in preference to the passive, silent applicant, if they are otherwise equally qualified. (In fact the verbal applicant will often be hired even if the passive one is better qualified.)

The same principle applies for promotions to management positions. This was described quite well by a UCD CS graduate now serving as vice president of a major computer company, who said that they prefer people who are “verbally aggressive without being obnoxious.” Written communication skills are important in the computer industry, which requires writing reports, proposals, etc.

Courses in Rhetoric and English can help improve communication skills, but the biggest single factor is the student’s attitude. The student who likes to read for recreation, who takes pains to develop clear and interesting writing skills, and so on, will become an excellent communicator.

People with good technical skills also need to be aware of recent trends in society, economics, politics, etc. to qualify for higher, more responsible positions. The curricula are designed to provide the student with technical knowledge but also to expose and encourage life-long awareness of societal issues. Yet again the major determinant here is the student’s own outlook; those who have a basic interest in these matters will find that such knowledge comes naturally.


Most faculty choose the teaching profession because they fundamentally enjoy interacting with students. In short, we like to talk. :-). Don’t hesitate to seek advice from faculty, even those who are not officially designated as advisers; we are happy to help you.