Software can be roughly divided into systems software and applications software, with practitioners called systems programmers and application programmers, respectively.
The dividing line is fuzzy, but the basic concepts are:
| Applications Software | Systems Software |
|---|---|
| Deals with abstractions like customers, products, orders, balance sheets, employees, and players in a game. | Deals with concepts extremely close to the hardware level, like registers and memory locations. |
| Solves problems of interest to humans, usually in application areas like health care, game playing, finance... | Controls and manages computer systems |
| Concerned with anything high-level | Concerned with data transfer, reading from and writing to files, compiling, linking, loading, starting and stopping programs, and even fiddling with the individual bits of a small word of memory |
| Is almost always device or platform independent; programs concentrate on general-purpose algorithms | Deals with writing device drivers and operating systems, or at least directly using them; programmers exploit this low-level knowledge |
| Is often done in languages like Java, C#, Perl, Python, Ruby, Lisp. JavaScript, or ML, that feature automatic garbage collection and free the programmer from low-level worries | Is often done in assembly language and C, where programmers have to manage memory themselves. |
| Is done in languages that generally have big fat runtime systems | Generally feature extremely small run-time images, because they often have to run in resource constrained environments |
| If done properly, can be very efficient — good garbage collection schemes allow much more efficient memory utilization than the usual memory micro-management common in C programs | If done properly, can be very efficient — you can take advantage of the hardware |
Be well rounded — know how to do both!
This list isn't intended to be complete, just informative
Wikipedia has articles on systems programming and system software