I'm a novice, but I found a list of the principles here: http://www.triz40.com/aff_Principles_TRIZ.php

I'll go through 10 of them, name the principle, then try to think of ways to apply to software. I might stretch some definitions (which is OK for creativity) but I'll not to do that too much.

1. Segmentation. Divide an object into independent parts.

Functional decomposition. Single responsibility principle. Unix approach of having several small, composable tools that do one thing and do it well.

2. Taking out. Separate an interfering part or property from an object, or single out the only necessary part (or property) of an object.

Remove a heavy computation from a mobile app and do it on the server. Cutting a new release and building a new binary to change one minor thing is slow, so separate things out into a config file that you can change.

3. Local quality. Change an object's structure from uniform to non-uniform, change an external environment (or external influence) from uniform to non-uniform.

Optimize your code with template specializations (such as in C++), so that it is non-uniform across parameterized types. Sense CPU model at runtime and run code that uses available CPU features.

4. Asymmetry. Change the shape of an object from symmetrical to asymmetrical.

Choose a master/slave relationship over a peer relationship. Use public/private key crypto instead of, well, symmetric.

5. Merging. Bring closer together (or merge) identical or similar objects, assemble identical or similar parts to perform parallel operations.

Use vector operations (single instruction, multiple data). Do something as a batch job instead of piecemeal (maybe for greater efficiency). When filtering a list, AND together two predicates instead of chaining together two filters.

6. Universality. Make a part or object perform multiple functions; eliminate the need for other parts.

Use crypto checksum (SHA1, MD5) both to ensure integrity of object and for content-addressability in the same system. System V init system puts name and ordering into filenames (/etc/rc2.d/S10foo runs before S20bar), avoiding the need for a separate place to declare the (full) ordering.

7. Nested doll. Place one object inside another; place each object, in turn, inside the other.

Programming languages that support nested functions. Hierarchical filesystem. Many wire formats contain length-delimited fields that can be jumped past if not needed right now (protocol buffers use these for strings and embedded messages).

8. Anti-weight. To compensate for the weight of an object, merge it with other objects that provide lift.

This one is tough because it's so physical. Perhaps you can compare storage space and weight, say data compression reduces "weight".

9. Preliminary anti-action. If it will be necessary to do an action with both harmful and useful effects, this action should be replaced with anti-actions to control harmful effects.

Employ techniques like guard pages or address space layout randomization to protect against exploits. Or change to a safe language. Rate-limit download/installation of non-urgent software updates to avoid slamming production servers' network and availability.

10. Preliminary action. Perform, before it is needed, the required change of an object (either fully or partially).

Remove a function in your code and replace it with a lookup table. Pre-fetch data (network or disk). Speculative execution in a CPU. Image computer's drive with a canned OS image so you're copying bytes instead of running a series of installers.