Printing an hourglass pattern
The biggest performance boost you could make would be to issue fewer print() and println() calls.  Each call involves a lot of overhead for locking, which you normally don't think about.  Coalesce everything down to one single print() for optimal performance.

The number of variables isn't that bad.  The problem is, rather, that i, j, k, and n are cryptic and headache-inducing.  The headache remedy would be to introduce a helper function and rename the variables to be more meaningful.  Note that in assigning meaning to the variables, you'll want to reverse one of the i loops to be a countdown, so that i serves the same role in both loops.

public class Triangle {
    public static void show(int maxWidth) {
        // Top
        for (int width = maxWidth; width &gt; 1; width--) {
            System.out.println(repeat(" ", maxWidth - width).append(
                               repeat("* ", width)));
        }

        // Middle and bottom
        for (int width = 1; width &lt;= maxWidth; width++) {
            System.out.println(repeat(" ", maxWidth - width).append(
                               repeat("* ", width)));
        }
    }

    private static StringBuilder repeat(CharSequence block, int n) {
        StringBuilder sb = new StringBuilder(block.length() * n);
        while (n --&gt; 0) {
            sb.append(block);
        }
        return sb;
    }

    public static void main(String[] args) {
        show(5);
    }
}


You could try writing one loop to handle both the top and bottom triangles.  Unfortunately, this clever solution is not as elegant as it could be, due to the need to skip 0.

    public static void show(int maxWidth) {
        for (int i = -maxWidth + 1; i &lt; maxWidth; i++) {
            int width = Math.abs(i) + 1;
            System.out.println(repeat(" ", maxWidth - width).append(
                               repeat("* ", width)));
        }
    }