Archive for the ‘Software Development’ Category

Code Reviews

Mario and Mike posted their thoughts on code reviews, so I figured we should turn this into a full blown meme.

Have the Review

This is the most important step — far too much code sneaks through without any sort of review. If you know a code review is coming, I guarantee you will spend more time cleaning up your code.

Don’t be too Formal

One of the first projects I worked on many years ago had a formal code review process. We had specific forms to fill out, and huge lists of categories for things like “type of issue”. There were far too many choices, so nobody ever knew what to pick. In the end, having too many choices led to useless data. Plus, we all dreaded code reviews.

See it Run

I always ask the programmer to show the feature in action before we see the code, so we all understand what we are reviewing.

Break It

I try really hard to find ways to make the code fail. I’d rather find errors now than after deployment.

Avoid Duplication / Learn from Others

Without reviews, programmers work in relative isolation from each other. As a result:

  • They don’t learn from their peers, because they may not be aware of other approaches to similar problems in the code base
  • Code is duplicated, for the same reason

Having routine reviews is the best way I know of to ensure programmers really see and learn from each other’s code, and avoid writing the same thing over and over again.

Simplify

If I can think of ways to simplify code, I’ll offer those suggestions in a code review. Try to imagine looking at this code a year from now without the original programmer present. Like it or not, each line of today’s code will become tomorrow’s legacy code.

Setting Java Version on Leopard

Today I learned something new about Leopard. On the command line, my default JDK was 1.5. I was about to edit a symlink under /System/Library/Frameworks/JavaVM.framework/Versions to change to 1.6, but instead learned about the Java Preferences app.

In Spotlight, find “Java Preferences” and launch it. Or, find it directly under Applications/Utilities/Java. It looks like this:

Java Preferences

Just drag and drop to rearrange items in the lists. The JDK at the top of the list becomes your default.

Ant

While this worked, Ant still used the old Java 1.5. I fixed this by adding a line to ~/.bash_profile:

export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home

Fixing a Broken Atom Feed

File this under “mistakes and bugs” — my Twittch.com Atom feed was invalid. For each feed entry, I generate a unique ID roughly following these guidelines. I did not, however, include the date in the Tag URI, making my feed invalid.

With only five comics published, I decided to make the feed 100% correct rather than leave it alone, which means changing the unique IDs for each entry. This will confuse newsreaders, as shown here in Google Reader:

Now each feed entry ID looks like this:

tag:twittch.com,2009-04-18:5

The date portion indicates when the tag: URI was “minted”, so it will always be 2009-04-18. Sorry for any confusion this causes in your newsreader.

Not a Memory Leak

Yesterday, I posted this picture from the Snake game on my G1 phone:

I received this comment from Alex:

Snake with open/close is a memory leak . As a weather has nothing to do with Android just bad app.

Duplicating the Bug

Here is how I duplicate the bug:

  1. Start playing a game
  2. Change the phone orientation, i.e. open or close the keyboard drawer
  3. Push the trackball up to resume the game

Just repeat steps 2-3 a few times until it crashes, it usually takes a few tries. Is this a memory leak, as Alex suggests?

Diagnosing the Bug

  1. First, install the free Android SDK. Google provides excellent instructions, so I won’t explain it here.
  2. Configure your G1 phone for USB debugging. From the home screen, go to Menu -> Settings -> Applications -> Development, and select USB debugging.
  3. Now connect your G1 phone to your computer via the USB cable.
  4. Run ddms to start the Dalvik Debug Monitor. You’ll find ddms in the tools directory where you installed the Android SDK.
  5. Make Snake crash and find the stack trace in the Log.

As you can see, this is an ArrayIndexOutOfBoundsException, not a memory leak. Here is the complete stack trace:

java.lang.ArrayIndexOutOfBoundsException
    at com.example.android.snake.TileView.setTile(TileView.java:150)
    at com.example.android.snake.SnakeView.updateApples(SnakeView.java:434)
    at com.example.android.snake.SnakeView.update(SnakeView.java:405)
    at com.example.android.snake.SnakeView.setMode(SnakeView.java:336)
    at com.example.android.snake.SnakeView.onKeyDown(SnakeView.java:279)
    at android.view.KeyEvent.dispatch(KeyEvent.java:718)
    at android.view.View.dispatchKeyEvent(View.java:3154)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:734)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:734)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:734)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1589)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1084)
    at android.app.Activity.dispatchKeyEvent(Activity.java:1856)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1560)
    at android.view.ViewRoot.deliverKeyEvent(ViewRoot.java:1616)
    at android.view.ViewRoot.deliverTrackballEvent(ViewRoot.java:1508)
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1201)
    at android.os.Handler.dispatchMessage(Handler.java:88)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:3739)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
    at dalvik.system.NativeStart.main(Native Method)

Avoiding Bugs Like This

I find that most Android bugs occur when Activities pause and resume. Changing screen orientation is a great way to crash many applications. That’s because orientation changes trigger lifecycle events. These events will occur at inopportune moments, such as when you receive phone calls or the user hits the Home button.

Applications that do not properly react to onPause(), onResume(), and other such methods will eventually fail.

You can use the UI/Application Exerciser Monkey to stress test your application. In the emulator, you can simulate incoming phone calls, which will pause the current Activity. You should also open and close the keyboard — repeatedly — while your application is performing tasks.

In summary, you need to brutalize your applications. Try really, really hard to break them. Android is a challenging environment because you must carefully manage threads, react to a complex series of lifecycle events, and deal with limited resources.

Android Bouncing Ball Demo

I just added a new demo to my Android Game Examples project. This sample reacts to the accelerometer to control a ball. As you rotate the screen, the ball falls towards the earth. When it bounces off the edge of the screen, the phone vibrator kicks in for a few milliseconds.


Android Bouncing Ball on G1 from Eric Burke on Vimeo.

I’m doing this to learn how to write games. The source code demonstrates a few things:

  • Using the phone’s accelerometer
  • Activating the phone’s vibrator
  • Simulating gravity and acceleration
  • Painting graphics using Android’s SurfaceView
  • Writing a super simple “game loop” that updates physics in a background thread safely

Ban Software Patents

Remember in 2006 when patent troll Firestar sued Red Hat for patent 6,101,502?

These patents are bullshit.

On one side, you have an object model. On the other, you have a relational database. When programmers must bridge two different data models, we eventually write little code generators to help us automate the conversion and avoid mundane boilerplate code. In this case, the conversion is called ORM, or Object-Relational-Mapping. The concept is obvious, and is the kind of things programmers do all the time.

Unfortunately, people can patent these obvious ideas and sue each other, punishing companies and individuals who have the audacity to create successful products.

Now, another troll is suing Red Hat for patent 6,163,776. Guess what this patent is for? Yep, just like the last one, this is another ORM patent.

As far as I can tell, both of these patents cover the exact same technology. If the concept of ORM was unique — and it is not — there still shouldn’t be two patents for the exact same thing.

Dropbox, Live Mesh, Git

Back in December I blogged about Live Mesh. I was initially confused by the Vista installation experience, but Live Mesh worked OK on Leopard. After receiving some helpful comments from some Microsoft employees, I decided to give Live Mesh another shot.

Ever since then, I’ve used Live Mesh on two computers: my MacBook Pro at home and my Vista machine at work. My needs are pretty simple. I have a folder on each computer where I keep some e-books, plain text files with TODO lists and comic ideas, and various other important documents. Up until today, Live Mesh has kept these directories perfectly in sync. Just drop a file in, and a few moments later it shows up on the other computer.

Last night, however, I pushed it too far. I created a Git repository in my Live Mesh folder here on my Mac. When I arrived at work this morning, Live Mesh complained about a huge number of so-called “conflicts”. The conflict resolution was utterly confusing and I screwed it up completely. Every time I finished, it reported new conflicts. This was a disaster, everything was hosed.

So this evening, I disabled Live Mesh, went into Time Machine, and restored the files. This is the first time I’ve used Time Machine for a real recovery, and it worked flawlessly. Everything is back to normal.

Live Mesh Fail

Why would Live Mesh report conflicts? I can understand if these computers were sitting side-by-side and I was rapidly adding, removing, and renaming files. But this was not the case. Both computers were in sync, and I was updating on one computer only. This should have been a unidirectional sync without any conflicts. I guess this is what they mean by “beta”.

Live Mesh exists for one purpose: to share data between computers. Corrupting data is unthinkable. When conflicts do arise, the resolution procedure needs to be easy, and it is not.

Dropbox

So this evening I installed Dropbox, and I will use this instead of Live Mesh. The installation was effortless, even easier than the Live Mesh Leopard installer. Copying my documents and e-books went as expected, all simple drag-and-drop operations.

Next up, Git.

Git on Dropbox

Rather than creating a repository and working copy in the Dropbox directory, this time I wanted to create a Git bare repository in Dropbox. Based on this excellent article, I was able to accomplish this in a matter of minutes. Here are the steps:

  1. I already had a Git repository in ~/Documents/livemesh/myproject. Before doing anything, I ensured everything was committed.
  2. cd ~/Dropbox
  3. git clone --bare ~/Documents/livemesh/myproject myproject
    (this created a bare repository in ~/Dropbox/myproject)
  4. cd ~/dev
  5. git clone ~/Dropbox/myproject myproject
    (this made my Git working copy in ~/dev/myproject)

Now I can do my day-to-day work in ~/dev/myproject. After committing any new edits, I can type git push to send my changes to Dropbox. On the other computer, I can receive changes by typing git pull.

So far Git has been far easier than I imagined, therefore I am kicking myself for not learning it sooner. Since I’m rambling, I’ll point you to git-osx-installer, which makes Git installation trivial on OSX.

Graphics Help!

I need to apply some sort of transformation matrix to convert a rectangle as shown here:

The web is full of examples that show rotation, translation, and scaling. But I’m not sure how to do the above transformation, or even what it is called.

Can someone help me figure this out? Maybe just point me to a web page that shows some example equations along with a few pictures. The Wikipedia Transformation Matrix article shows a lot of the math, but without pictures, I’m not sure which of the equations are applicable.

To Slide…or Not To Slide?

Each month, the folks I work with have a Java Lunch. A volunteer gives a 1-hour tech talk on something Java-related, but we’ve also had talks on ANTLR, Ruby, Groovy, and many other technologies. These lunches are fun, informative, and a good way to get free pizza.

I signed myself up to present in November — I plan to show some advanced Swing concepts. There are many reasons to give a presentation:

  • Giving a presentation to your peers is one of the best ways to learn something.
  • A speaking engagement provides a hard deadline, forcing you to get something done.
  • Presentations can be a good way to spread some knowledge.
  • Public speaking is a great career move.

But I already know Swing really well…and I don’t really need a deadline for this. Here is my real motivation:

  • I want to improve my presentation skills.

I want to push the envelope a bit and expand my repertoire beyond PowerPoint with bullet points. I want to learn how to give dynamic presentations that make people say “damn, that kicked ass!” (yep, I stole that from Kathy Sierra). I want them to feel this way because they learned something within the 1 hour time constraint.

Mistakes to Avoid

I think I am a good speaker, but I certainly can improve. Here are some mistakes I (have made and) plan to avoid:

  • Do not include an introduction slide. This wastes precious time because people in this audience already know who I am and what the topic will be.
  • Do not include an “outline” slide. With only 60 minutes, why waste 5 minutes describing what I am about to talk about? I’d rather use my time talking about Swing.
  • Absolutely do not include a “History of Swing” slide. Technology history lessons put people to sleep.
  • Don’t make everything “beginner level”. Far too many technical presentations cater to rookies and are boring. This is particularly true when the audience is a group of consultants who know Java inside and out.

Things That I Would Like to Do

  • Show working code snippets throughout the presentation.
  • Show real working Swing examples.
  • Keep the pace up. We only have an hour.

The goal of a 1-hour presentation is not to teach people details. It is to spark people’s imagination, show them what is possible, and to give people a kick in the pants (or perhaps point them in the right direction) if they are interested in pursuing the technology further.

No Slides?

One idea is to skip the slide show completely. Instead of slides, I could show a series of small Swing examples: real, running programs. After showing each example, I can switch over to an IDE, pointing out the most important code snippets. Small fonts can be an issue, but IDEA makes it easy to zoom in.

Other OCI employees have given presentations in this style and it works very well.

Bullet Points

Most presentations fall into this category, and I refuse to do it this way any more. I will not have a series of slides with bullet points.

Lots of Slides

This is an option I never considered until seeing Archaeopteryx: A Ruby MIDI Generator, via Alex’s blog.

That presentation does show some working code along with a real demo. But the bulk of the presentation consists of hundreds of slides. Giles burns through the slides at a frenetic rate, and the results are phenomenal. I have never seen or given a presentation remotely like this.

What Should I Do?

I feel like I should take one of two avenues. Either go all demo+code, or go the “super fast paced slide show” approach. I must admit, the super fast slide show approach appeals to me for these reasons:

  • It is completely different than what people are used to
  • If done well, it can be extremely entertaining
  • It’s a big challenge
  • It may avoid awkward context switching as I constantly switch back and forth between code examples and demos

That last bullet is important to me. A lot of speakers spend too much of their hour stumbling back and forth between demos, the command prompt, and their IDE. Perhaps if I put everything into a fast-paced, well scripted Keynote presentation, I can avoid these context switches.

What do you think? I just placed an order for slide:ology, perhaps that will inspire me.

Subversion Auto Props, OSX, Google Code

Some notes for myself, configuring Subversion to work well with Google Code:

  1. On OSX, the Subversion client config file is named ~/.subversion/config
  2. Uncomment this line:
    enable-auto-props = yes
  3. Add these values to the [auto-props] section:
    *.css = svn:mime-type=text/css
    *.html = svn:mime-type=text/html
    *.jpg = svn:mime-type=image/jpeg
    *.png = svn:mime-type=image/png
    *.txt = svn:mime-type=text/plain
    *.svg = svn:mime-type=image/svg+xml