Principle #1 in coding

The following has been proved over and over again in software engineering, a.k.a. Principle #1 in coding

The peculiarness of a bug is in inverse proportion to the bug’s stupidness

Just bumped into two stupid things this afternoon. Let’s start with the first one. Pay attention to the following snippet of Scala code

val r: Runnable = new Runnable {
  override def run(): Unit = {
    Thread.sleep(1000)
    throw new Exception("I choose to die!")
  }
}

new Thread(r).start()

while(true) {
  Thread.sleep(1000)
  Console.println("Seems everything is OK!")
}

Well, the purpose of the above code is quite obvious since it is made to stand out – to show that the parent thread will not be affected by an exception thrown from its child thread. But it is very easily overlooked in a large complex program (yes you guessed it, I mean services) where threads are spawned hiddenly and crashed without showing any trace, and you are left wondering why your program is running but not doing things it is supposed to do. Even more annoying is – when you submit a task into an executor pool for periodical execution, and at some time point the task throws an exception, the executor pool would stop further executions without even a warning.

The second thing is about the following iterator interface

trait Iterator[A] {
  def hasNext: Boolean
  def next: A
}

Can’t be more classic. We all know that hasNext is there to guard the internal boundary, making sure the caller does not get null objects by blindly calling next. The caveat is – are you always required to call hasNext before calling next? I initially did not think it is the case, but my colleague has a different idea, which means even if you get freshly new iterator and it contains lots of meaningful objects underneath, it throws you a null if you don’t do hasNext first.

Leave a Reply

Your email address will not be published. Required fields are marked *