Many software systems are complex not because they are large, but because they have many interconnections.
Interconnections make it difficult to understand pieces in isolation, or to carry them from one project to the next.
The inability to cleanly separate out components makes it difficult to divide a task between several programmers.
Complexity can only be managed by means of abstraction, by eliminating information that a programmer must know.