PUBLIC OBJECT

Many Correct Answers

Let’s copy a file with bad Java I/O:

  private void copy(File source, File target) throws IOException {
    try (InputStream in = new FileInputStream(source);
         OutputStream out = new FileOutputStream(target)) {
      while (true) {
        int b = in.read();
        if (b == -1) break;
        out.write(b);
      }
    }
  }

Whoops, it’s super slow. Reading a byte at a time, a 100 MiB file takes 7 minutes to copy on my MacBook Pro! Let me show off my skills and optimize this:

  private void copy(File source, File target) throws IOException {
    byte[] buffer = new byte[2];
    try (InputStream in = new FileInputStream(source);
         OutputStream out = new FileOutputStream(target)) {
      while (true) {
        int count = in.read(buffer);
        if (count == -1) break;
        out.write(buffer, 0, count);
      }
    }
  }

Nice. Only 4 minutes. But I can do even better! As I grow the buffer, the time to copy a 100 MiB file steadily drops. The optimal result is 55 ms using a 128 KiB buffer.

Logarithmic X, Logarithmic Y

This curve shows a broad range of good answers. Everything between 16 KiB and 16 MiB completes in under 100 ms!

Correct Working

Buffer sizing is a nice example because it’s easy to measure, but many other problems have broad ranges of good solutions. This has been in my mind ever since Kyle tweeted it:

There is not one right answer! Many product owners seem to think there’s one right and true answer in every decision, but this isn’t usually true. Everything can be built a million ways, many within the margin of error of “great”.

Correct Living

Many small problems each have many correct answers. The recurring 2020 question of ‘what to watch on TV?’ comes to mind. Nothing’s worse than spending an hour browsing Netflix without picking something! (Also I admit surprising myself by how much I liked Floor is Lava.)

It’s true for the decisions that shape our lives too: where to live, work, and what family to build. We can’t do A/B tests on whom to marry or how many children to raise! But I see people leading fulfilling lives in every circumstance.

Being Decisive

There’s wrong answers too and often they’re the default. In the buffer example above, not picking has the worst outcome.

Hilt, Anvil, Guice, or Koin? Injecting dependencies makes code modular and testable. Not doing DI because you can’t pick a framework is bad news.

What should your app’s max profile picture size be? If you set no limit, your users will upload gigabyte-sized images. These hang your UIs, fill your servers, and saturate your network! The default of no limit is unwise.

How much money should I invest each week? The default, $0, is a rainy day tragedy. But there’s a wide range of better choices, from $20 to $200.

Making decisions is difficult and feels risky and so I often put it off! But making a decision – even an arbitrary one – is worthwhile. I particularly like starting with a ‘good enough’ decision, then refining later when I have more information.