There are an alarming number of common problems when programming Atmel microcontrollers, often arising from subtle differences between devices. Many of these involve the programming of the fuse HI and fuse LO bytes. In the full ATMEGA8 datasheet, they are documented on page 223.

Warnings: Take great care when programming the fuses: If the SPI interface is disabled, then programming via SPI bus (ie when programming in circuit) is disabled. If you don't have a suitable stand alone programmer you are locked out.

Similarly, if you disable the Reset signal in order to gain an extra IO pin, you can't program in circuit any more.

General gotchas

Take care when setting clock sources via the fuse bits, since wrong settings can lead to no clock at all. The default clock is an internal oscillator running at a low frequency, which is enough to get started. Sometimes you may find that the device can be programmed in an external programmer, but the in-circuit programming fails once you set the fuse bits. The difference is that the programmer uses a 4MHz crystal oscillator, whereas you may well be trying to use a faster external crystal. The datasheets aren't very clear here, but typical fuse bytes for an ATMEGA8 running with an external crystal are:

High byte D9 
The default setting, ie the Reset pin is reset, not an IO, SPI programming is enabled, 
CKOPT=1 (higher power, crystal oscillator more likely to start)

Low Byte EE 
Default brownout and startup time, fast external crystal

For many devices the JTAG interface is switched on by default (it is used for production testing). With JTAG enabled, some IO pins will seem to behave strangely - in fact they are not under your control at all.

On the ATTINY45, PB4 can't be used unless you select an internal clock.

USARTs: some devices have 1, some 2. The examples given in the documentation for the two USART devices show a general register name, not the specific name, eg UCSRB rather than UCSRB0 or UCSRB1. To avoid poblems, check the names. Also, avoid setting more than one bit eg:

UCSRC = (1<<URSEL) | (3<<UCSZ0);   <-- AVOID

Use

UCSRC = (1<<URSEL) | (1<<UCSZ1)| (1<<UCSZ0);  <-- THIS MAKES MISTAKES LESS LIKELY

USARTs again: In some devices, eg ATMEGA162 some registers are shadowed behind others. eg Baud rate and USART control. You must have the top bit set when writing to UCSR1C and clear when writing to the baud rate register UBRR1H. Miss this one and the baud rate is a lot lower than expected. Look at the pulse width with an oscilloscope.