Wednesday, August 05, 2015

Distributed Systems: Another Great Jeff Dean Quote

During the first year of a typical Google datacenter, there will be five rack-wide outages, three router failures large enough to require diverting processing away from connected machines, and eight network scheduled maintenance windows, half of which cause 30-minute random connectivity losses. At the same time 1 to 5 percent of all disks will die and each machine will crash at least twice (2 to 4 percent failure rate).

Dean, J. (2009), Designs, lessons and advice from building large distributed systems.

Friday, July 31, 2015

The Waterfall Model was a straw man argument from the very beginning

Over the years, I've read a lot of books on software engineering. Agile books in particular like to refute the "Waterfall Model". Every time I read about the Waterfall Model, I think to myself: I'm sure there must be companies out there that have tried this approach, but I have a hard time believing some software book would seriously propose it as the best way to write software. It must be the boogie man of software engineering methodologies.

I was reading The Practice of Cloud System Administration: Designing and Operating Large Distributed Systems, and I came across this quote:

Royce’s 1970 paper, which is credited with “inventing” the model, actually identifies it so Royce can criticize it and suggest improvements. He wrote it is “risky and invites failure” because “design iterations are never confined to the successive step.” What Royce suggests as an alternative is similar to what we now call Agile. Sadly, multiple generations of software developers have had to suffer through waterfall projects thanks to people who, we can only assume, didn’t read the entire paper (Pfeiffer 2012) [p. 175].

I think this quote lends credence to my theory that the "Waterfall Model" has been a straw man argument from the very beginning. I know that there were companies that used it, and that there are companies that still do. However, I think this proves that no one ever wrote a book that proposed that the "Waterfall Model" was the best way to write software.

Monday, July 06, 2015

Tetris Over SSH

I wanted to try out Google Compute Engine, but I wanted to build something other than a simple web app. Hence, I setup a virtual server that runs tetris when you log into it, and I gave everyone the credentials :)

$ ssh -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no tetris@104.154.80.84 # Password: tetris

Here's the code. I set it up so that gotetris is the login shell, and the user doesn't have permissions to modify any files. Hence, it should be relatively safe to share with the world ;)

Friday, May 29, 2015

Go

I finished reading "A Tour of Go", "Effective Go", and the entire language specification.

They were very well-written. My brain hurts ;)


Tuesday, May 26, 2015

Tetris Written in Go

I implemented a console-based version of Tetris in Go.

In general, it was a pleasant experience. I made use of the termbox-go library for console graphics, and it was enjoyable as well.

I've been reading a lot of blog posts recently about Go, and I think this blog post is the one that captures my opinions best. It's also a treasure trove of useful links to various other blog posts and tidbits.

Anyway, as I said, it was a fun experience :)


Saturday, May 16, 2015

Go: A Surprising Edge Case Concerning append and Slice Aliasing

In Go, the append function reallocates the underlying array if there's no more room. Hence, if you have two slices that point to the same array, after you append to one of the slices, the other slice may or may not point to the same array. This can lead to some unexpected behavior:

package main

import "fmt"

func main() {
 // Create a slice of length 1 and capacity 2.
 a := make([]int, 1, 2)

 // b "aliases" a
 b := a

 // If I set something in a, you see it in b.
 a[0] = 1
 fmt.Println(a[0], b[0]) // Prints 1 1; they're equal.

 // append returns a new slice, but with the same array.
 // Hence, if I set something in a, you still see it in b.
 a = append(a, 2)
 a[0] = 2
 fmt.Println(a[0], b[0]) // Prints 2 2; they're equal.

 // I'm doing the same thing as last time. However, this time,
 // append has to allocate a new array because there's not enough
 // space. Hence, if I set something in a, you don't see it in b.
 a = append(a, 3)
 a[0] = 3
 fmt.Println(a[0], b[0]) // Prints 3 2; they're *not* equal.
}

Having multiple aliases to the same mutable data can lead to some subtle behavior and lots of bugs if you're not careful. It's perhaps even more surprising to the naive reader since a and b don't look like pointers. In fact, they're not. They're slices which are a value type that have a pointer within them.

Immutable data structures (like lists in Lisp) don't have these issues. However, you lose some of the performance that a raw array can provide.


Saturday, May 02, 2015

Books: Getting More: How You Can Negotiate to Succeed in Work and Life

I finally finished Getting More: How to Negotiate to Achieve Your Goals in the Real World. It was one of the most influential books I've ever read. It has impacted every area of my life!