Showing posts with label Learning to Code. Show all posts
Showing posts with label Learning to Code. Show all posts

Tuesday, May 12, 2009

Some Programming Languages to Consider Learning

Learning a new programming language can affect the way you think.  While most modern languages are Turing Complete and can theoretically all accomplish the same things, that’s not practically true.  Each language has its own strengths of expressiveness.  For instance, trying to write dynamically typed code in C++ is possible, but a pain in the neck.  You would have to implement your own type system to do so.  Each language makes certain things easy and other things hard.  Learning different languages then exposes you to different approaches.  Each approach provides a different way of thinking and a set of tools supporting that way of thinking.  What follows are some of the languages I’ve learned and what I think they provide.  This list is limited to languages I’ve studied in at least a little depth.  There are many more languages out there that may be useful.  If you have additional suggestions, please make them in the comments.



  • C – This is coding very close to the metal.  Learning it promotes an understanding of memory, pointers, etc.

  • Lisp/Scheme – Once you get past your parenthesis-phobia, it’s a very elegant language.  The big learnings here are treating code as data, metaprogramming (writing programs that themselves write programs), and recursion.  Lisp is also a dynamically-typed language.

  • Clojure – A variant of Lisp that runs on the JVM.  In addition to what you can learn from Lisp, it adds persistent data structures and transactional memory.  Persistent data structures are ones that *never* change.  Once you have a “pointer” to one, it will never change underneath you.  This makes parallel programming much simpler.  Clojure also is more of a functional language than Lisp/Scheme.  It is not purely functional, but allows for the functional style to be followed more easily.

  • Smalltalk – Much of modern programming originated in this language.  Modern GUIs are based on the Xerox Parc Smalltalk systems.  Object Oriented programming was first popularized in Smalltalk.  Extreme Programming, Agile, and Design patterns all found their initial formulations in Smalltalk.  In addition to learning about OO programming, Smalltalk is great to understand message passing.  This gives object-oriented code a different feel than the function call semantics of C++/Java/C#.  Smalltalk is also a dynamic language.

  • Perl – Perl was once known as the duct tape of the internet.  It ran everything.  It has since been surpassed (at least in blogosphere popularity) by other scripting languages like Ruby and Python.  The biggest thing to learn from Perl is regular expressions.  They are built into the core of the language.  Other languages support them but often as a library.  Even those that do support them in the syntax do not usually utilize them so pervasively.

  • C#/Java – These languages both solve the same problems in almost the same ways.  They are a great place to learn object-oriented programming.  It is built in from the ground up.  The OO style is one of function calls and strong interfaces (which distinguishes it from Smalltalk).  These languages also have the largest accompanying libraries.

Wednesday, December 24, 2008

10 Programming Languages Worth Exploring

Now that I've completed the final class toward my Masters Degree I have the time to explore some things of my own choosing.  One thing I intend to do is to learn a new programming language.  This article I discovered via Reddit is a good place to start.  It lists 10 languages worth learning.  These are the up-and-coming languages, not the current hot topics like Python or Ruby.  Interesting items on the list include Squeak, Haskell, Clojure, and PLT Scheme.

Tuesday, December 23, 2008

Stroustrup on What's Wrong With CS Programs

Similar to thinking of Joel Spolsky (and me), Bjarne Stroustrup (the inventor of C++) says the way we teach CS today is broken.  That is, it is at odds with the needs of the industry.  Having just completed a Masters in CS I can say first hand that this is true.  Some of what I learned was applicable to my work at Microsoft, but I could see the tension in the higher-level classes especially between the needs of preparing someone for research and preparing them for industry.  Research is not about programming.  It is about thinking in new and innovative ways about problems.  Industry needs good programmers and the best solutions to problems.  CS research students often ignore the best solutions to problems because those have already been discovered and you can't get published writing about the same thing again.  Industry prefers the proven solutions. 


Stroustrup bemoans the use of Java in so many programs today.  He doesn't attack Java per se but rather the emphasis on the libraries.  Students don't learn to solve fundamental problems (like sorting) because the library can do that for them.  It is easy to become an expert in Java rather than an expert in programming, something Rovert Dewar states well in this interview.  When the Java (or C# or Ruby) language wanes in popularity, it is the underlying CS skills that translate, not the intimate knowledge of the Java collections hierarchy.  I have a more fundamental problem with higher-level languages for learning.  It is important to learn how the machine works because someday everyone will be stuck with a leaky abstraction and will have to solve the deeper problem.  Without an understanding of what is below the byte code (or code), doing so can become very difficult.  It is easy to code oneself into a corner without knowing it if the understanding of the underlying system is missing.


He also talks about the lack of quality in the code written by students.  Too many projects are littered with magic constants, not well factored, etc.  This probably comes from the fact that code written for classes is thrown away.  Most of my professors never even asked for our code let alone actually read it.  A TA in my OS class actually said they didn't care about memory leaks.  In a freaking OS class of all things!!! 


The takeaways:



  • Learn a lower-level language.  Joel Spolsky says everyone should learn C.  I'm inclined to agree.  It's not too hard to learn and it is as close to the metal as you usually want to get.

  • Learn to express your ideas in more than 1 language.  Each is a little different.  Learning other languages gives you tools to think about problems in new ways.  This also ensures your knowledge is about the algorithms, not the base class libraries.

Thursday, August 7, 2008

The Company You Work For Matters

In an episode of Stack Overflow Podcast, Jeff Atwood made an interesting point.  He spoke of the difference between companies that deliver code as their product (like Microsoft) and companies who use code to support other business interests (the IT department inside Weyerhauser for example).  In a company whose business model is to make and sell software, making the software incrementally better supports the business function and is thus rewarded.  In an IT department, once the project crosses a certain threshold, the returns on making it better diminish rapidly.  Improving the code is often discouraged.  All this has been said before.  Joel Spolsky has talked on this subject as have I. 

What Jeff added to this conversation was a practical application.  He rightly pointed out that you need to be aware of the type of person you are and the type of company you are working for.  If you love to code, you really don't want to work in an IT department.  Sure, someone will pay you to code, but you'll be frustrated by the limitations on your work.  If you enjoy programming, you want to work for a company whose job it is to produce software.  On the other hand, if you are willing to program but it's just a job, you don't want to work in a software house.  An IT department will be a better fit and you will find your career better served by working there.  In an software house, you'll be asked to give more of yourself and be more creative than you might otherwise like to.

Thursday, March 6, 2008

Hello World Podcast

MacBreak Tech has a recent podcast talking about learning to program.  They begin with the question "how do I start programming games" and break it down.



  1. Pick a project.  Don't learn for learning's sake.  Learn to accomplish something.  It will give you a structure to hang your learning on.

  2. Pick a language.  They suggest Python, Basic, and Flash.  Those aren't bad places to start.

  3. Book or class?  Think about your learning style.  Classes force the pace.  Books are often better than reference material.  They make a cohesive whole out of all the parts.

  4. Borrow code.  Think about starting by modifying something someone else has already done.

Of course, the podcast is a little Mac-centric.  They don't mention Visual Basic or C#, but most of the content is applicable to any language.  If you have an MP3 player and are wondering where to start, try this podcast.


 

Wednesday, January 9, 2008

Do We Need A New Kind of CS Degree?

Joel Spolsky suggests that we should have something called a BFA in Software Development.  That is, a Bachelor's in Fine Arts focused on creating software.  I think he's onto something.  I've called for something similar in the past.  Presently there are two sorts of degrees that seem to be offered in the market.  There are what I call IT degrees that are designed to help a person operate in the information technology field.  They teach database programming, visual basic, web design, etc.  They don't generally teach hard-core programming.  There are also the traditional CS degrees which are geared toward doing research in computer science.  Their roots in the math departments of old show and there is a strong emphasis on proofs and mathematical modeling.  There is a need for a 3rd option.  What Joel calls the BFA in Software Development and what I called Software Craftsmanship is a degree that teaches someone the art of programming.  The graduate from a CS school knows how to prove the correctness of a for loop and can characterize an algorithm as NP-complete, but doesn't have much practical experience.  There is a certain class of person that shys away from the math required for a CS degree today but who would make a great programmer.  Mot of the time these people take a few classes and then quit school to fend for themselves on the open market.  If we offered a program that taught better programming techniques focusing on different sorts of languages, longer-term projects, more design patterns/oo, debugging, testing, etc., I think we would find the uptake to be solid.  There are a lot of people that want to program but don't want to do research.  They also don't want to be a DBA in the back end of some giant corporation.  Today, there is no program at the college level for a person like this.

As a counterpoint, several professors are claiming that today's CS programs aren't mathematical enough.  I see their point.  There are places that need more formal methods.  The lack of a BFA in Software Development is probably partially at fault here.  CS programs are becoming watered down because students don't want the formal methods.  Perhaps splitting the CS degree into CS and SD would help create a pipeline of those who are trained in formal methods and also create a pipeline of those who are trained in creating working software in an efficient manner. 

The authors also attack the use of Java as the first programming language.  Joel also wrote an excellent post about this a couple years back.  This is something I can support.  Java is too easy.  It's a fine language for writing production code, but it doesn't force the programmer to understand the underlying computer.  It hides too much of what is really going on.  This means that when the abstraction leaks, those who have only learned Java don't know what to do.  They don't understand pointers and memory.  They haven't had to write low-level programs of their own and don't understand how those parts might be doing things.  They don't interact closely with the OS and don't understand what it might be doing which is causing problems.  Anyone who learns to program in C or C++ can learn Java (or C#).  The reverse is not true.

Tuesday, October 23, 2007

What Self-Taught Programmers Are (Often) Missing

Some self-taught programmers can hold their own with the best coders out there.  Others, although smart people, are fundamentally less good at programming.  While there is variation among classically trained coders too, they are on average better than their self-taught peers.   Why is that?  Why can't self-taught programmers become as good in similar numbers?  There are a lot of reasons for this I'm sure, but here is one item that I believe has a large effect.  Self-taught programmers often have very little exposure to good programming. 

It is not uncommon for a self-taught programmer to work largely alone or with others with similar training.  Programmers don't tend to read a lot of others' code.  If they do, they read the small snippets they find on Google or Live.  They don't read whole programs.  Admittedly, it is hard to do this.  What gets lost without reading full programs is the way they are laid out.  Reading a sample on the web demonstrates how to call an API, but doesn't show how to organize code into a larger cohesive whole. 

I often compare programming to writing.  Someone who just knows the syntax of a language and tries to program is like someone who knows grammar and tries to write.  Technically, it will be correct, but it might not be much fun to read.  Good writing is more than just proper words in proper sentences.  It is the way the story flows that separates a good book from a poor one.  It is similar in programming.  It is the way the objects and functions interact that separates good programming from poor.

Think about a good writer.  How did she learn to be a good writer?  Practice.  But also exposure to other good writing.  Someone who is a good story teller usually exposes herself to other good stories.  I suspect that most good writers are, or were, avid readers too.

What does this tell us about becoming a better programmer?  Like a good writer, it is important that one is exposed to good examples.  In college, this comes in class.  You are exposed not to large programs--although that happens sometimes--but rather to the ideas that make good programs.  Exposure to algorithms, data structures, OS principles, design patterns, etc. all contribute to building up a repertoire to draw upon and emulate.  Self taught programmers often don't get this exposure.

This leads to a simple solution.  If you are a self-taught programmer, get exposure to the ideas of others.  This can be done either in the classical manner by reading books on databases, compilers, operating systems, patterns, etc. or by reading the code of programs that implement these ideas.  If you work in software development, read the modules written by the senior team members.  Don't read for syntax, but try to understand how the big pieces work together.  If you don't, go look at sizeable open source projects.  Become familiar with how the pieces fit together.

Wednesday, September 12, 2007

Practice, Practice, Practice Makes Perfect

I was sent a link to this article as a followup to my post about learning to program over a long period of time.  The article isn't about programming but rather about comedian Jerry Seinfeld.  When he was young and working to be a comic, he had a particular technique for learning that applies to the act of learning to program.  Jerry knew that to be a good comedian, he had to practice a lot.  The more he practiced writing comedy, the better he would become.  Similarly, the more you practice programming, the better programmer you'll become.  Jerry employed a technique for reminding him to practice.  He kept a calendar and every day he practiced, he would mark that day off the calendar.  After a while he would have a long streak with no breaks.  Then the incentive to not slack off but instead to continue the streak was high.  This technique can be employed in programming.  While you don't necessarily need to program every day (although that wouldn't hurt), you do need to practice regularly.  Pick a program you want to work on.  Now break that up into small steps each taking a few hours or perhaps a day to accomplish.  After you have the list, it is just a matter of ensuring that every day (or two or some other regular basis), you accomplish one.  Don't just program when you feel like it.  Force yourself to do it regularly.  If you wait until you get the urge, you may have long gaps and your growth will be slow.

Tuesday, September 4, 2007

You Can't Learn To Program In A Hurry

A friend turned me on to this essay from Peter Norvig entitled Teach Yourself Programming in Ten Years.  In it the author attacks the idea of the "Teach Yourself C++ in 21 Days" kind of books.  They make it look easy to learn to program.  Unfortunately, it isn't.  You can't become a good programmer in a month.  In fact, you can't become a good programmer in a year.  You don't need to go to college to learn how to program but it helps.  Learning on your own is a lot of work.  Learning to program is like learning anything of value.  It takes a lot of practice.  The essay quotes research indicating it takes a decade to master any significant skill. 


Norvig gives some good advice on those who want to become programmers.  Most of it, like just get out there and program, is great advice but is also common.  A few though, are less commonly stated and deserve repeating.  Among these are:



  • Work on other people's programs.  Learn a program written by someone else.  This will teach you how other people have solved problems and will teach you how to write maintainable software.

  • Learn a half dozen languages.  Learn languages that have different approaches to programming.  Each new sort of language will open your horizons and help you see problems in different ways.  Solving a problem in C will lead you in different directions than solving the same problem in Smalltalk.  Unless you know both languages, you'll likely fail to see one of the solutions.

  • Understand what's going on below your language.  Modern programming languages are so high level that it's easy to forget that there is a real machine running the code.  However, as Joel Spolsky says, all abstractions leak.  That is, there will always come a time when you have to understand the layer below the abstraction to solve a bug.  If you understand how memory works, how drives work, what makes a processor stall, etc. you'll be better off.  I see this often in those we interview.  They understand a programming language but they don't understand the operating system.  If you don't know the difference between a thread and a process or if you cannot describe how virtual memory works, you'll be at a loss when things go wrong.

There is advice here for many people.  If you are learning to program, the application is obvious.  Not so obvious is that if it is going to take you a long time and a lot of practice, you're going to have to put in work on yoru own time.  You won't learn to be a good programmer without spending your evenings/weekends doing so.  However, there are other things we should take away from this.  If you are a manager and you are trying to grow young programmers or new programmers, you need to give them explicit time and opportunity to program.  No one can just take some classes or read some books and become a programmer.  For those who are experienced programmers, it is a good reminder to read the code of others.  If you work at a big company, you can look at the code of those around you.  Seek out those who are more skilled than yourself and examine how they solve problems.  If you are at a smaller company, seek out open source projects.  See how they do what they do.


Here's a piece of advice that the essay doesn't mention:  rewrite your programs.  Each time you'll have a better understanding of the problem domain and thus you should be able to solve the problem in a more efficient way.  You'll learn how much you've improved when you see your old code and you'll learn to approach the problem in a new way.


Read the whole essay.

Friday, August 24, 2007

Why Algorithms Matter

New programmers often don't appreciate the power of algorithms.  They have one criteria for a piece of code:  does it calculate the right answer?  If it does, they go with it.  Every CS program has at least one class on algorithms.  However, if you are a self-taught programmer, you may not have been exposed to the ideas.  This article stems from a conversation with a friend who is trying to learn programming on his own.  This is a simple introduction to the concepts of algorithms and an explanation for why you might care about them.  Most of the time the programs we write deal with small enough data sets and fast enough processors that our choice of algorithms doesn't make a material difference.  However, with a large enough number of items the choice of a poor algorithm can make a tremendous difference.

Here is an example.  When I was first programming, I wrote a Java servlet to access a database of all the DVDs we were testing.  This was very early on and there were only a few hundred DVDs in print.  The servlet had one page which would display each of the DVDs along with some vital information in a table format.  I used simple string functions to build up the HTML describing the table.  With 200 discs, everything worked fine.  We were buying all of the DVDs available at the time and eventually our database grew to encompass over a thousand discs.  Somewhere along the line, I noticed that bringing up the "all discs" page was taking a really long time.  It took something like 3 minutes to display the page.  I did some investigation and figured out the problem.  Each time I concatenated another piece of text or table markup, the entire string was copied to a new location along with the new information.  The same string was being copied tens of thousands of times.  The solution was to move to using a StringBuffer object instead of the built-in strings.  StringBuffer utilizes a better algorithm than does string.  The time to render the page dropped from 3 minutes to 30 seconds.

Before beginning, we should define what we mean by algorithm.  An algorithm is a set of instructions for accomplishing a task.  Everything we write in software is an algorithm of some sort but we usually reserve the term for the parts of our programs that accomplish particularly interesting tasks.  More often than not, the reference is to reusable tasks like searching, sorting, etc.  These algorithms are language and platform agnostic.  That is, the concepts will be equally valid on virtually all programming languages, operating systems, and processors.

If we're going to compare the performance characteristics of different algorithms, we'll need some benchmark to measure them against.  We could just run the algorithms and see how long they take, but this only tells us how they behave on that particular data set.  Instead, we use something referred to a "Big-O" notation* to describe the runtime characteristics on a function.  This describes how the behavior of the function (measured in time in all cases in this article) is affected by the size of the data set.  For each value we add, how does the performance react?  If we know how long it takes to do something to a sample set of size 1, can can then compare the time it takes for bigger sample sets.  The notation is as follows:  O(1), O(n), O(n^2), etc.  O(1) indicates that the time is constant--that is, it is unrelated to the size of the input.  O(n) says the time it takes increases linearly with the size of the input.  O(n^2) indicates that the time grows as a square of the number of items.  An algorithm which is in the class O(n) will run faster than one in the class O(n^2).  For example, if it took 25 instructions to do the work for 1 item, an O(n^2) algorithm would take 250,000 instructions for 100 items.  An O(n) algorithm would take just 2,500.

Let's look at some example algorithms and how they affect running time.

Searching for a Phone Number

Think about looking up someone's phone number in a phone book.  How do you do that?  We could just start on page 1 and look at each entry to see if it is the person we are looking for.  This will take a while.  If we consider just pages, not actual names, we'll have to examine and average of half the pages before we find the number we're looking for.  In the worst case, we'll have to look at each page.  My phone book has 969 pages in the residential listings.  That means it will take us an average of 485 pages to find the name we want.  If we're looking for Fred Zylstra, it's going to take us 969 pages.  This is an O(n) algorithm.  This is how many programmers search for an item in a list but this isn't how anyone actually searches in the phone book.  We open to a page in the middle and if what we're looking for is higher in the alphabet, we turn half way toward the front of the book.  If it is lower, we turn half way toward the end.  We keep repeating this process until we find the name.  This algorithm will find the name we're looking for by examining at most 10 pages.  This is O(log2(n)).  Here is a graph of the two functions:

phonebook

The green line is the linear algorithm.  The red line represents the way most people actually search.

Calculating Fibonacci Numbers

This one is slightly less real world but it demonstrates well the advantage of algorithms.  Fibonacci numbers are a series of numbers where each number is the sum of the two previous numbers.  Formally, F(n) = F(n-1) + F(n-2) where F(0) = 0 and F(1) = 1.  These numbers get large really quickly.  The 10th number is 55.  The 30th number is 832,040.  The 100th is 354,224,848,179,261,915,075.  There are two ways to calculate a Fibonacci number.  This sequence is often used when teaching recursive programming.  The recursive algorithm looks something like this:

UInt64 CalcFibonacciRecursive(UInt64 number)
        {
            if (number == 0) return 0;
            if (number == 1) return 1;
            return CalcFibonacciRecursive(number - 1) + CalcFibonacciRecursive(number - 2);
        }

There is also a non-recursive algorithm.  It looks like this:

UInt64 CalcFibonacciIterative(UInt64 number)
        {
            if (number == 0) return 0;
            UInt64 value = 1;
            UInt64 F2 = 0;
            UInt64 F1 = 1;
            for (ulong i = 1; i < number; i++)
            {
                value = F2 + F1;
                F2 = F1;
                F1 = value;
            }
            return value;
        }

The recursive solution looks a lot more elegant but how does it perform?  let's try calculating F(40).  I tried higher numbers but even F(50) takes minutes to calculate

Algorithm Elapsed Time (ms)
Recursive 5523
Iterative <1

 

The race isn't even close.  Why the big difference?  Let's examine what is going on here.  To calculate the 5th Fibonacci number using the recursive algorithm, we have to calculate F4 and F3.  To calculate F4, we have to calculate F3 and F2.  But wait.  We already calculated F3 directly.  Unfortunately, we end up doing it again.  Here is the complete tree of actions for calculating F5.  Notice all of the redundant work.

fibonaccitree

If you look closely, you'll see that this is basically a binary tree.  Each time we increment the number by 1, we double the amount of the work we have to do.  We have to do 2^n amount of work.  Thus, the recursive algorithm is O(2^n) whereas the iterative algorithm is O(n).  Here is the graph:

fibonacci

Summary

As you can see, the choice of algorithm can have a drastic effect on the running time of your program.  This is why it is wise to have some familiarity with algorithms when you are programming.  Determining the Big-O value for an algorithm can be complex.  Luckily, any algorithm book will tell you the classification of an algorithm so you can look it up instead of having to dust off your math skills.  Spend some time studying an algorithm book or just do some web searches when you go to use one.  Pay attention to these values.  They will be important some day.

I tried to make this easy to understand but if something isn't clear, please ask.  I'll be happy to explain.

 

*Big-O notation is actually a misnomer.  What computer scientists call Big-O notation is more properly called Big-Theta notation.  Big-O describes the upper bound, but that bound doesn't have to be close.  We could just call all of our algorithms O(2^n).  While accurate, this doesn't help us much.  Rather we'd like to know what the lowest Big-O value is which still describes the function.  That is Big-Theta.

Monday, July 30, 2007

More Resources For Teaching Children To Program

As I've stated before, I have a young son who I have been trying on and off to teach to program.  I still owe you a post talking about what I've found does and does not work.  In the mean time, I ran across this article which give several good resources.  It mentions many of the standbys including Lego Mindstorms, Logo, Scratch, and Basic but also a few I haven't looked into before.

Monday, May 14, 2007

Three Types of CS Programs

In my mind there are three different types of programs you might find when looking for CS or CS-related degrees.  When choosing a school to attend, it is important to understand what their focus is going to be.  If what you want out of a program doesn't align with what they are teaching, you'll run the risk of dissatisfaction.  I'll call the three school Computer Science (CS) , Software Craftsmanship (SC), and Information Technology (IT).

The first type of school is probably the oldest.  Most degrees will be offered with this title although some are offered as Computer Engineering.  The focus of these programs is to prepare you for research.  They'll cover a lot of the theory behind computing (predicate algebra, complexity theory, computational theory, etc.) and the practical classes will often be more survey than in depth practice.  Many times you'll find these schools don't focus much on the quality of the coding you are required to do.

The second type is the hardest to distinguish.  I use the term Software Craftsmanship instead of Software Engineering because schools like Seattle University offer Software Engineering degrees that are similar to, but not quite the same as what I have in mind.  That program appears to be more about software development systems management than programming.  This school is teaching you to go into the industry.  They teach what is needed to be a systems programmer.  The focus will be on knowledge that can be applied.  This means a little less math and a little more programming.  This sort of program doesn't ignore things like algorithm complexity (because that is useful), but perhaps does so in a manner that is more programming-centric rather than math-centric.  Operating systems, compilers, graphics, etc. are all classes you should expect to take.  One school which set out explicitly to be of this sort is Northface University (now called Neumont).

The third type of program I call an IT degree.  This is most often offered by community colleges, commuter colleges (like City University), and low-end state colleges.  It's not exclusive to these sort of schools, however.  These programs are designed to be practical, but in a different way than the software craftsmanship.  The focus is on those skills needed to work in an IT shop.  That means, the sort of place where you implement back-end line of business software and/or support it.  They teach a lot of SQL, Web development, networking, etc.  Usually these schools will teach operating systems and algorithms, but not at a very deep level.

It is my assessment that most schools teach either CS or IT and that a very large number of students take the wrong sort.  No that many students start into school and want to do research in computer science.  Most want to apply it.  If you want to work at a software development shop, the best fit is a school designed to teach software craftsmanship.  Unfortunately, not many schools offer this.  Why is this the case?  I suspect it has to do with the roots of computer science.  When computers were new, the first programs offered in academia were offered in math departments.  This is responsible for the math-bias of most CS programs.  Professors are rewarded for publishing research, not for implementing working programs.  This means that they teach what they study.  I.e. they teach for research because that is their focus.

Most people graduating with a CS degree are not really ready to contribute to business.  They don't understand testing.  They aren't very good at debugging.  They have never been required to write maintainable code nor to maintain someone else's code.  There's a steep learning curve in your first job.  It doesn't have to be this way.  We could spend more time teaching people the art of systems software creation and less time teaching them how to prove that their for loop will exit.

I tend to think more programs should offer a software craftsmanship focus because that is what most people attending the schools will be doing when they graduate.  I'm sure there are many who disagree though.  If you are one of them, let me know what I'm failing to take into account.

Thursday, April 26, 2007

Teaching Your Team To Program

The world of testing is becoming a lot more technical than it once was.  While there is still a need for strong exploratory testing, the need for test automation is increasing dramatically.  Test automation requires programming at some level.  Good test automation requires skilled programmers.  Thus the need for test developers is increasing.  As I've said before, learning to program is hard.  As a manager of a team of non-programmers (or semi-literate programmers), is there a way to train them to become what you need?  Is it better to just go hire programmers and teach them to test?  As I've said elsewhere, I think it is easier to teach a programmer to test than to teach a tester to program.  This post, however, is about doing just that:  developing programmers out of an intact test team.  Here is my advice on how to do that.

First, don't expect everyone to make the transition.  For some it will be impossible.  For others, there will be little interest.  Remember, you still need manual testing.  You don't want your whole team to convert.  Look for the ones that show interest and aptitude.  To find the ones who really show interest, you have to make it clear you don't expect everyone to move.  You have to make it clear that this isn't a promotion.  If getting promoted (or keeping your job) requires learning programming, everyone will want to.

Provide opportunity to learn.  Expecting people to know how to program before you give them the opportunity to do so will guarantee failure.  If you only give programming assignments to those who already know how, you won't develop any new programmers.  Learning programming on your own time is something only a few will be able to accomplish.  It is hard.  Instead, find some tools you need written or features you need added to existing tools and offer the chance to work on them.  See who grabs the opportunity and push them.

Give them time to learn.  Beginning programmers won't be productive.  It will take them 10x as long to do something as an experienced coder.  That's okay.  You have to budget for that time.  The payoff will come later.  It is important that management guard that time also.  I've seen many times when management hands out an opportunity but then quickly piles up the non-programming work so there is no time to learn.  If you ask someone to write a tool, make sure they have long, uninterrupted blocks of time to focus on it.  As an upper-level manager, hold your leads accountable for providing this time.

Provide mentors.  Books and blog posts only cover so much.  There are a lot of little details and corner cases they don't discuss.  New programmers need someone they can approach to ask questions.  Getting stuck on a problem for 2-3 hours is healthy.  Being stuck for 2-3 days is discouraging.  If you have test-developers on your team, utilize them.  If you don't, talk to the dev manager about using his people in this role.

Make it an assignment.  Hold the aspiring programmers accountable for their output.  Learning to program shouldn't be extra credit.  When things get busy, extra credit falls by the wayside.  Instead, make it part of their commitments for the period.  Discuss the assignment during your 1:1s.  If they don't get it done (whatever done means) by review time, hold it against them.  It has to be treated like any other assignment.  If they didn't get their test pass done, you would care.  They need to know you'll care if they don't learn how to program.

Give real assignments.  Don't ask them to write something you're going to throw away.  Have them working on production code.  Pick a simple tool.  Better yet, have them augment an existing one.  The assignments should also be in the same language as the application.  Teaching them to program Visual Basic in Visual Test isn't training them to understand your product.  Their utility will be limited if they can't interact with the developers.  Finding mentors will also be harder.

Finally, give them an escape hatch.  Programming isn't for everyone.  If someone determines it isn't for them, let them go back to exploratory testing or whatever they were doing before.  Forcing someone to learn something they don't want to is doomed.

Wednesday, April 25, 2007

Teaching Yourself To Program

Following up on my last post, I'll give some instruction for those testers who want to become programmers.  As I said, last time, don't expect to learn everything you need to at work.  The forces in play will almost certainly conspire to keep you from being able to.  If you desire to expand your horizons and become a programmer (either staying in test or moving to dev), here are some ideas that can aid you in your journey.

Look for opportunities to program.  Take advantage of them when they appear.  There's always an extra tool that needs to be written.  There's always a feature that would be really nice to have added to an existing tool.  If you want to get support for your learning, this is your best chance.  If you can do it and show the benefit to the team, you'll often be rewarded by more opportunities.  The only way to get good at programming is to program.  Practice every chance you get.  I've seen plenty of aspiring developers ignore chances to develop tools at work.  The ones that do rarely--if ever--make the leap.

Start small.  When you are starting out, it is usually easier to add functionality to an existing program than to write something from scratch.  This is because you have a structure to work with.  When you are learning to program, you don't know how to put all the pieces together.  You'll learn that, but starting out it can be hard.  Working on something similar to an already-existing feature can be a good place to start.

Learn the language of your application.  While Ruby, Python, or Visual Basic may be appealing and even easier to learn, unless they are the language the application you are testing is written in, you'd be best not to spend your time learning them--yet.  Eventually, yes, but they won't really help you get where you want to go.  There are two reasons for this.  First, the most effective test automation is done in the native language of the application.  Anything else doesn't align quite right and will make reaching the corners hard.  Second, the people you can learn the most from--the application's developers--can only help you if you speak their language.

Ask a lot of questions.  Potential candidates often ask what working at Microsoft is like.  I invariably tell them that it is a very supportive environment.  When you ask a question, you always get a detailed answer and usually a history lesson about why it is that way.  I suspect that we're not alone in that respect.  Most developers enjoy what they are doing and want to share that joy.  If you ask them a question about how their program works or even about some project you are doing (that test tool you are writing) and the problem you are stuck on, they'll often be happy to help.  Be careful not to take too much of a person's time and be especially careful not to ask the same question twice, but don't be afraid to ask.  Part of learning on your own is asking questions of those more skilled than you.  My rule of thumb is to spend a few hours trying to solve any problem.  If you still don't have an answer, go ask someone.

Be prepared to put in the work.  The job you were doing before you decided to go down this route didn't go away.  You'll still need to do it.  Learning to program isn't simple.  It will take time.  The combination is going to take a lot of time.  Be prepared to show up early or stay late to work on your project.

Don't quit.  There will be times when you get too busy to learn.  There will be bugs that stump you for a long time.  Don't lose track of what you are doing.  Don't get out of the habit.  Don't take on projects and then let them languish for months.  You have to keep going.

Put in time outside of work.  Read.  Either online or on dead trees.  A lot.  Practice.  A lot.  Pick up a side project and work on that.  Open source make a good place to start.  Just working on something of your own does too.  Work on programming a game or writing a tool.  It's not even important that you finish so long as you are working.  If you want to become a developer, it should be because you enjoy programming.  Use this joy to your advantage.  What you learn on the side will help make the stuff you do at work make more sense and go faster.

Friday, April 20, 2007

It's Difficult to Grow a Test Developer

A lot of testers begin life as software test engineers.  That is, they execute tests but don't do any (or much) programming.  The dream of many testers is to become a test developer or a developer.  Reciprocally, the dream of many test managers is to grow their testers into test developers.  Is this a realistic dream?  It can be, but probably isn't in most cases.

It's very hard to become a self-taught developer.  When we look out at the computer landscape we see plenty of self-taught programmers so it looks easy.  However, for each one that succeeds, many more fail.  Why is that?  Two reasons I suspect.  First is that some people are just not cut out to be programmers.  Second, and perhaps more important, is that it is really hard.  Becoming a good programmer* requires a lot of knowledge.  That means a lot of reading (online or books) and a lot of practice.  It turns out that it is a lot easier to desire to be a programmer than to put in the work to become one.

I covered the first point in my post entitled You Can't Teach Height.  Studies show that a good number of people, even those interested in programming, cannot grok it.  My suspicion is that this has to do with the abstract nature of programming.  This isn't to say that they can't program at all but they can't program well and as the difficulty goes up, more and more drop off.

The second reason is the one that gets a lot of people.  I've seen many try to make the leap and only a few succeed.  Those that did had to put in a lot of work on their own time.  Those that didn't often weren't willing to put in time outside of work.  Anyone desiring to go from tester to test dev with just the time they spend on the job is probably going to be disappointed.  It takes a whole lot of effort to become a competent programmer.  I laid out my recommendations in one of my earliest posts.  I call for learning not just the syntax but also the essentials of computer science.  You can program without these but if you don't pick them up you'll never be great.  Learning them, however, takes a lot of time and effort. 

Most of the time employers won't give you that time.  They want you to be productive and anyone learning to program is not productive.  The simplest things take a long time.  There is almost always a more competent programmer on the team somewhere and if work needs to be done, it will be given to him.  It's not that most managers discourage learning to program.  They'd like it to happen.  They just won't often budget enough of your time to actually do it.

Now that I've said how hard it is, are there things that testers can do to increase their odds?  What about test managers?  I'll cover the issue from both perspectives in future posts.

 

* It is important to note what I'm talking about here.  It's not too hard for someone to teach themselves enough C# to write an ASP.Net page or enough perl to parse some log files.  That, however, is a far cry from being able to write a test harness, analyze performance, or automate the testing of a COM object.

Tuesday, March 13, 2007

You Can't Teach Height, But Can You Teach Programming?

There's an old basketball saying--attributed to Frank Layden of the Utah Jazz-- that "You can't teach height."  No matter how much skill you have, if you are short, you'll be at a disadvantage on the court.  You can teach someone to be a better player, but you can't make them any taller.  Recently, there's been a meme running around the blogosphere asking whether there is an analogy to height in programming.  Is there something about programming that puts it out of reach for many people? 

Some people can learn to program.  Some can't.  There's a good paper called "The Camel Has Two Humps" by Saeed Dehnadi and Richard Bornat which claims this to be the case.  The authors explain that in CS classes there are two groups of people:  those who can program and those who can't.  "Between 30% and 60% of every computer science department's intake fail the first programming course."  Many methods have been tried over the years to overcome this deficiency but to date no one has made serious progress here.  The authors speculate that this is because some people just can't handle the meaninglessness of programming.  They point out that the teaching of formal logic suffers from the same problems.  If you don't want to read the whole paper, Jeff Atwood has a good synopsis.

Are the authors correct in their analysis?  Is it this lack of meaning that causes people to not be able to program?  I'm not so sure.  My guess is that it is the abstract nature of programming that stops people from being able to program.

Most people who take math long enough eventually hit a wall.  There is some point when you can just no longer grasp what is being taught.  No matter how much you study, you'll never become proficient at that level of math.  For some people this comes early with algebra.  For many others it is geometry or trig.  A large number of people hit the wall with calculus.  Still others at differential calculus.  For me, Discrete Math is something I've never been able to master.  Often times people will do fine in math one semester and struggle to even pass the next.  Why is this?  I think it is because math is increasingly abstract.  The further you get in math, the more abstract it is.  As things get more abstract, they become harder to follow.  This isn't true just in math but even in fields as distant as philosophy.  Following Nietzche is a lot harder than reading Rawls which is harder than Orwell's 1984.  Why?  Because each is written more abstractly than the one before it.

Programming is also increasingly abstract.  Linear programming in BASIC (old-school, not VB) is something most people can accomplish.  Functions are the next rung on the ladder.  After that comes pointers.  Some people just can't grok them.  I've conducted many an interview where the interviewee wrote down foo(bar), erased it, wrote foo(*bar), then finally foo(&bar).  Next is classes.  Not every C programmer can comprehend interfaces and class hierarchies.  Fewer still can create good ones.  Templates (or "generics" as they are now called) throw many people for a loop.  It's amazing how much harder it is to write a function with a T than an int.  At each of these stages, you'll lose some people.

I'm reminded of a time when a friend of mine who is not a programmer tried to create a random home page for his browser.  He wrote some javascript which contained a series of nested if...then...else statements.  Someone else suggested he consider using the switch statement.  I wrote this:

list = new Array(

            "http://www.slashdot.org",

            "http://www.arstechnica.com",

            "http://my.yahoo.com",

            "http://www.flipcode.com",

            "http://www.powerlineblog.com",

            http://www.realclearpolitics.com);

a = Math.floor(Math.random() * list.length);

document.location=list[a];

The difference is more than just a more thorough understanding of the language syntax.  I think it is indicative of a use of higher level abstraction.  If..then is a brute force method.  It is very concrete.  We all understand this.  On the other hand, an array is more abstract and using the array object to get information about itself is not quite as intuitive as counting by hand and hard-coding it.

What is the implication of all this?  If true, you can't teach everyone to program.  As you climb the programming language ladder, people will drop off.  Anyone who can program and has read Worse Than Failure will realize that some people just don't get it.  It isn't that they are stupid, they just aren't wired for this task.  At 5'10", I'm not wired for basketball.  Spending time teaching someone who isn't wired right to program beyond their talent-level will be an exercise in frustration for all involved.

This affects the way we should interview.  If people cannot program, hiring them with the expectation that we will teachthem is fraught with danger.  The short of it is that we need to ask programmers to program during interviews (seems obvious doesn't it?).  Scott Hanselman has a great post on this.

I'll end on a slight tangent.  I wonder if this can explain some of the complaints about VB.net over Visual Basic 6.0.  Moving to .Net added classes and a lot more complexity.  In essence, it added more abstractness to the language.  If my hypothesis is right, this would make a certain number of people who were comfortable with VB 6.0 no longer capable of grokking the updated version.

Wednesday, February 28, 2007

Teaching My Son To Program

A few months back I read the article, "Why Johnny can't code" by David Brin.  He talks about the trials he had teaching his son to BASIC.  Just yesterday, I came across this article by Nat Torkington entitled, "Why Johnny Can't Program."  This one talks about his adventures teaching programming to youngsters.  He didn't use BASIC but rather Logo and Lego Mindstorms.  The comments there are a good source for other suggestions.  Some suggested languages aimed at kids like KPL or Squeak.  Others suggested that Ruby or Python were the way to go.  I think this latter group probably doesn't have young children.

My son is almost seven and insists that he's going to work at Microsoft when grows up.  Makes a father proud.  He enjoys math and for a while I've thought about how to introduce him to the concept of programming.  I thought about Basic, but after reading Nat's article, I thought better of it.  "Hello World" probably doesn't appeal to the average 7 year old.  Something with visuals might be more interesting to start with.  Many of the suggestions were too complex for a first language.

I decided to start small and settled on Logo as my introductory language of choice.  Logo also happens to be the first language I used back in 4th grade.  I recall finding it being taught without much context but I enjoyed it.  I thought I'd give it a shot.  After some looking around, I chose the free MSWLogo.

Tonight I introduced it to him.  He picked it up quickly and really enjoys it so far.  We'll see how long it holds his attention.  I suspect we'll have to move on from Logo before too long.  If things go well, I'll return to this topic in the future.

If you have suggestions on language or techniques that have worked for you, please send me mail or leave a comment.

Thursday, January 20, 2005

Language Choices

It has been asked several times which language is better for a test developer at Microsoft, C# or C++?  The answer really depends on what group you will be working in.  Different groups require different skills.  It is my perception that C++ is by far the dominant language today but that will not always be the case.  I have friends that are SDE/Ts who work exclusively in C#.  I'm sure there are some on the VB.Net team who do all of their work in VB.  There are probably some on the Office team who use VBA for most of their work.

For now most things are being written in C++ because of the extra runtime speed and the availability of libraries and APIs in the language.  In theory C# could become as fast as or faster than C++.  It has the ability to dynamically compile and thus take advantage of processor and system features not available to the least-common-denominator approach of a traditional compiler.  Most likely, in the real world, it will never quite catch up.  The C# team is working hard to minimize the difference between the two.  See Rico Mariani’s blog for some posts on the subject.

This isn't to say that C# won't become the dominant language though.  Hand-tuned assembly is often faster than C code and C code can be faster than C++.  Those advantages didn't stop C++ from becoming the dominant language, however.  Why is that?  It is because C++ is faster to code in.  It offers native support for object-oriented coding and abstract data types.  These increase the efficiency of the programmer.  This increase in efficiency is accepted at the price of code that runs a bit slower.  C# offers a similar bargain.  Coding efficiency is up but performance is down.  As processors continue to increase in speed, the need for that extra ounce of speed will be less and less advantageous and the increased coding efficiency relatively a greater and greater advantage.  When the APIs for coding Windows applications become managed with Avalon and WinFX, the usefulness of C# will be magnified.

Over the long term, I expect that C# will become a dominant language.  Will it fully displace C++?  That is hard to say.  Certainly not in the near term.

I must end this by saying that I am no expert on C#.  I've done some coding in it but nothing too serious.  There are others on blogs.msdn.com that know a lot more about the subject.

Thursday, January 6, 2005

So You Want to Be a Test Developer

            So you have an interest in becoming a test developer, eh?  You’ve come to the right place.  In this paper I will lay out what I think is the best path to take to becoming a test developer or really any sort of developer.  Test developers are really just developers who happen to report in the test org. Becoming a good test developer requires learning not only a programming language but also what to do with it.  You’ll need to learn not only C++ but also about operating systems, algorithms, object-oriented programming, etc.  Becoming a test dev won’t be easy.  It is going to take a lot of reading and a lot of practice.  If you stick with the regimen, you’ll be a real developer.  You’ll have much of what someone would have if they had acquired a CS degree.  If not, well, you’ll be where you are today. 

Starting With a Language

            The place to start is obviously with a language.  If you don’t know how to program, you won’t be much of a programmer.  It is important to know, however, that knowing a language is just the beginning.  Too many people equate knowing C/C++ with knowing how to program.  Sadly, this is not the case.  Think of an author as an example.  Learning the English vocabulary and the rules of grammar will make you a proficient English speaker.  That does not, however, make you a great writer.  Mark Twain wasn’t a great writer because he knew how to diagram sentences.  Knowing what to say is even more important than knowing how to say it.  It is the same way with a programming language.  You can know C/C++ forward and backward and still be a bad programmer.

            The first decision you should make is what language to use to start your journey.  As you progress, you will probably pick up other languages but you have to start somewhere.  You should start with a language that encourages you to do the right things.  C# is an easy language to begin with.  C is simple and easy to learn.  C++ is its more complex big brother.  Most system-level work is done in C++.  That’s probably where you want to start.  If something like VB or Perl strike your fancy, you can use them but know that you’ll be limited in where you can utilize your skills.

            To learn C++, I recommend starting with a book.  The two best ones I know of are C++ Primer by Stanley Lippman and Thinking in C++ by Bruce Eckels.  I prefer these over the “24 Hours” or “21 Days” sort of books.  They may claim to teach you C++ quickly but they won’t.  C++ is huge.  It will take some time to master.  Pick one and read it cover to cover.  Do the exercises if you are that sort of person.  These are both thick books.  Don’t be intimidated.  They’ll both cover everything you need to move onto the next phase of programming.

Don’t stop there though.  You need to put this into action for it to make sense.  Come up with a project and start implementing it.  The project can be anything.  Implement a tool you’ve been itching to have, write a game, whatever.  I started by trying to implement the game of Robo Rally.  I never finished.  You might not either.  The point isn’t to complete the project.  It is to come to an understanding of how the parts work together.  Books teach us to program in discrete little packets.  Each packet makes sense atomically.  The point of writing a real program is to understand how these packets interact.

If you want to become wiser in the ways of C++, there are several other books you might want to read including Effective C++ by Scott Meyers and Inside the C++ Object Model by Stanley Lippman.  Neither book is essential but both will help make you a better programmer.

Going Beyond Language

            As I said, learning a language is just a first step.  Once you are here, you are proficient in some language (C++ most likely).  You are conversant in a language.  You are still a terrible writer.  The next step is to learn what makes a good program. 

This is where things get more complicated.  Learning pointers is hard but understanding algorithms is harder.  If your math is weak, you’ll struggle with some of these concepts.  Fear not.  None of this is rocket science.  It just may take you a bit longer.  If necessary, put down the book you are reading, read some math, then come back.  This should help you get further.  If you run into a roadblock, learn more math and continue until you get through.

There are three major subjects you need to come to understand.  The first is data structures and algorithms.  The second is operating systems and processors.  Finally, there is object-oriented programming.  Once you have these three areas understood, you’ll be well on your way to becoming a good programmer.

Algorithms are what make your programs run fast or slow.  When you are dealing with only a small amount of data, the algorithm you use doesn’t matter too much.  However, when you are dealing with hundreds of thousands or millions of items, the algorithm can matter a lot.  It is important to understand the types of algorithms available and to understand how to measure their efficiency.  Different ways of sorting would be an example of algorithms.  Data structures are ways to organize large amounts of data and maintain accessibility.  Examples are linked lists, trees, hash tables, etc.  Two books which are used a lot for this are Introduction to Algorithms by Thomas Cormen and Algorithms in C++ by Robert Sedgewick.

Understanding how processors and operating systems work will help you understand why the language and the OS do what they do.  Many things that C/C++ do make more sense once you understand how the underlying system works.  Understanding the OS and being able to read assembly language will come in invaluable when it comes time to debug.  The best OS book I know of is Operating System Concepts by Abraham Silberschatz.  It is accessible and covers the critical topics.  For processor/assembly topics, look to Computer Organization and Design by David Patterson. 

Finally, there is object-oriented programming.  Learning about OO techniques will help you understand how to write a program that is maintainable and extensible.  The best place to start is with Design Patterns by Gamma et al.  I suggest using to book to understand how patterns work in general, not to memorize every pattern.  A good book showing the application of patterns and good OO design techniques is Design Patterns Explained by Alan Shalloway.

Where to Next? 

            So you read all 5,000 pages and you still want more?  What can you study next?  The tree branches from here.  There are lots of possibilities.  Some good places to look are for general programming are debugging and good programming practices.  You can also start going down a specific path such as windows programming, graphics, ATL/COM programming, etc.

            Programmers spend an inordinate amount of time debugging the code they just wrote or even code written by others.  Debugging is an art, not a science.  The only way to get good at it is practice.  There are some books you can read which will give you a jump start though.  The best of these is Debugging Applications by John Robbins.

            Learning how to become a better programmer also takes practice but there are a few books written which give you some good pointers.  I won’t list them all here.  Everyone raves about Code Complete by Steve McConnell.  I don’t.  I find it long-winded.  A better book is The Practice of Programming by Brian Kernighan and Rob Pike.  Another book which is really useful is Refactoring by Martin Fowler.  He explains how to take old code and make it better.  Like Design Patterns, I find the first several chapters more useful than the reference that makes up the bulk of the book.  Finally, go find a copy of your groups coding standards document.  Often times these are chock full of good techniques.  They will usually tell you what sort of things to avoid and what good practices to emulate are.

Formal Training

            If you decide that self-driven book learning isn’t for you, are there alternatives?  Yes.  I prefer the classic CS education over professional certificate programs, workshops, or even IT degrees.  To that end, I have found a few programs I believe are worthwhile.  Each of these will allow you to get a full degree or just take some classes.  All are based online.

 

Regis University – Offers a Bachelor of Science in Computer Science.  http://www.regis.edu/regis.asp?sctn=onl

 

Colorado State University – Offers a Master of Computer Science program.  http://www.cs.colostate.edu/cstop/csacademics/csdegrees/onlinemcs.html

 

University of Illinois at Urbana-Champaign – Offers a Master of Computer Science degree.  Students participate in on-campus classes via newsgroups and online videos.  http://online.engr.uiuc.edu/


Bibliography:

Cormen, Thomas.  Introduction to Algorithms.  Thorough introduction to algorithms.  The content is often advanced.

Eckels, Bruce.  Thinking in C++.  Focuses a lot on STL which isn’t used much at Microsoft.  You can download a free copy here:  http://mindview.net/Books/DownloadSites.

Fowler, Martin.  Refactoring.  How to spot good and bad code and what to do about the bad stuff.

Gamma, Erich, Richard Helm, Ralph Johnson, John Vlissides.  Design Patterns.  The first few chapters are the most useful.  They will help you understand how OO designs should work.

Kernighan, Brian, Rob Pike.  The Practice of Programming.  Tips and techniques for being a good programmer from one of the authors of the C language.

Lippman, Stanley.  C++ Primer.  Great introduction to C/C++.

Lippman, Stanley.  Inside the C++ Object Model.  The how and why of C++.

Meyers, Scott.  Effective C++.  50 tips for writing C++.  Each tip is explained.  Along the way, you learn a lot of C++.  Skip More Effective C++ though.

Patterson, David.  Computer Organization and Design.  Covers the MIPS processor not the Intel but the concepts are the same.  Don’t get bogged down in the measurements chapter.

Robbins, John.  Debugging Applications for .Net and Windows.  Great book explaining how to debug programs on windows.  Focuses on the Microsoft programming environment but the general techniques are applicable everywhere.

Sedgewick, Robert.  Algorithms in C++.  Sedgewick has a series of Algorithms books covering everything from C to C++ to Java to Pascal.  The latest versions come in two volumes.

Shalloway, Alan.  Design Patterns Explained.  How to use design patterns in design.

Silberschatz, Abraham.  Operating System Concepts.  Good introduction to how operating systems work.

 

If you have suggestions for additional books, subjects, etc.  Please post them in the comments below.

Wednesday, January 5, 2005

Advice for CS Students

Joel Spolsky (of JoelOnSoftware fame) is well-spoken and often has a lot of good advice for programmers.  This recent essay gives advice to college students on what to study.  His advice consists of:

  1. Learn how to write before graduating.
  2. Learn C before graduating.
  3. Learn microeconomics before graduating.
  4. Don't blow off non-CS classes just because they're boring.
  5. Take programming-intensive courses.
  6. Stop worrying about all the jobs going to India.
  7. No matter what you do, get a good summer internship.

If you want to find out his reasons, read the whole article.