Wednesday, August 3, 2011

Reminder: hashcode is not a key

I just wanted to share a reminder not to treat Object.hashCode() as a key. This seems very basic, but I have seen experienced developers get tripped up over this method. A number of people seem to think that hashCode can be relied on to return unique integers for each object value, especially for strings. Oops.

My latest BlackBerry app: TempoBeat

main

My latest BlackBerry app is out. Presenting: TempoBeat, an electronic metronome app. I paid quite a bit of attention to the user interface with this app, since I wanted something that works well with both a keyboard and a touchscreen. The controls can be manipulated by touch, but I also included a number of keyboard shortcuts for non-touch BlackBerry model. It has a bunch of features or characteristics typical of metronomes: tempo, beats per measure, volume control etc. This being a BlackBerry app, I added one more feature that truly belongs on a BlackBerry: you can use the iconic BlackBerry LED to blink the beats, in colors of your choice.

Tuesday, May 24, 2011

My blog will make you stupid

Apparently, my blog will make you stupid. It's no good fleeing to another blog, though: they all make you stupid. That is, if you agree with Nicholas Carr's book, "The Shallows: What the Internet is Doing to Our Brains". The thesis of the book is that our use of the Internet is changing our brains, affecting deep learning, long term memory and our ability to focus.

I first heard about this book at a No Fluff Just Stuff developer's conference, where more than one panelist at one session cited this book with respect. Clearly, I thought, this is not a book for Luddites if a bunch of technophiles are reading it. This book is not a reaction against modernity. In fact, I'd say that it is trying to preserve an aspect of human progress now threatened by the Internet. I'll get to that in a moment.

Thursday, April 14, 2011

NoSQL: triumph of application over data

NoSQL databases are the rage now, aren’t they? Not too long ago, NEJUG hosted a presentation by Tim Berglund called "NoSQL Smackdown." Before giving his tour of several NoSQL databases, Tim tried to give his definition of "NoSQL." After showing the difficulties of defining NoSQL as a series of negatives (no SQL, no relations, no transactions), he merely settled on a vague definition. Basically, he says, NoSQL is merely a set of different approaches in data models, querying and scaling that trade off things like performance and the 3 guarantees of the CAP Theorem.

In other words, there is no such thing as a canonical NoSQL database. Most emphasize key/value or document-oriented storage, but then you have something totally different like Neo4j, a graph database. NoSQL fans like to emphasize scalability, but some candidates don’t really scale. You can’t even say that NoSQL means no SQL, because you have something like GemFire, which does allow you to use SQL. Nevertheless, allow me to give you my own definition of NoSQL. Ready? Here goes:

NoSQL databases are databases for people who don't care about data.

Thursday, February 24, 2011

The pain of enterprise Java development

Java enterprise development can be painful. Now, it's true that Java is not as concise as some other languages. It's also true that the Java ecosystem is full of famously complex tools and frameworks such old-style EJBs, JSF and Maven. Still, I believe that for us Java enterprise developers, much of the pain is self-inflicted. Let me suggest a few things we do to ourselves, often unnecessarily. These are generally justified as a Best Practice (spoken in a deep, authoritative voice) or something that decouples something or other. I think it says something about our mindset, and I don't necessarily mean in a bad way.

Tuesday, January 25, 2011

The trouble with being conventional

"Convention over configuration" is a popular paradigm in developer circles these days. Instead of explicit instructions over every detail or action, you would follow the framework's conventions and get most of the work done implicitly and for free. Ruby on Rails made this idea really take off, and we see it in action in many frameworks. The popular build tool Maven also adopts convention over configuration, and in the process demonstrates how not to do it.

I've had a pretty rough time getting comfortable with Maven. This was a green field Java project: we were starting absolutely from scratch. There were no legacy build processes to support, so we were ready to follow Maven convention everywhere. Nevertheless, it has been a long, painful (one colleague said "character building") journey. Why did it have to be so hard?

Tuesday, January 18, 2011

Chasing abstractions

We Java enterprise developers love abstractions in code. I suspect the typical software geek comes up with new abstractions more often than he changes his underwear. I admit to writing code with premature abstractions, such as using a strategy pattern where I end up never using a different strategy. We code defensively, afraid that lack of flexibility will hinder future changes. But beyond the code that we actually write, Java enterprise developers also love abstractions in third party libraries. We chase abstractions, in search of that fantasy land where if we adopt this or that framework we need not change our code to accommodate the hypothetical need to change the underlying implementation. The result is comic levels of abstractions upon abstractions.

Wednesday, December 1, 2010

OOPs: mangling your database with objects

A developer once showed me a frightening sight: a page and a half of dense SQL, consisting mostly of join clauses. What was frightening was not so much the performance of this query -- it was a utility query, so the long query time was not important -- but the fact that he was actually proud of that query. How did a production DB schema get into such a state? The problem, in a word, was Hibernate. I'm a fan of Hibernate, so I'm not saying that there's something wrong about Hibernate. Rather, Hibernate lets you too easily do things that you should have second thoughts about. To borrow a metaphor, this tool comes with live chainsaws attached.


Monday, November 22, 2010

DVCS vs Subversion smackdown, round 3

That title is probably a little pretentious, since the topic of rival version control systems has probably gone a few zillion more rounds than that. The context here is that in a previous blog post I argued that the recent rise of DVCS (Git, Mercurial) is less due to their essential D (distributed) nature, but the accidental weaknesses of Subversion, the dominant centralized VCS. The weaknesses I mentioned are:
  • Poor merging
  • Lack of offline commits
Since the Subversion folks are busy rectifying these weaknesses, I questioned whether DVCS is really the wave of the future. That was round 1. Round 2 came when my colleague Pete came galloping to the defense of DVCS, and I would also include the comments in response to my blog post. This is round 3, the response to the responses.


Tuesday, November 16, 2010

I am a Torch bearer

I am a Torch bearer. More specifically, I am now a proud owner of a BlackBerry Torch 9800. This came as a surprise to me, actually, since I had no plans to buy one. The Torch is an AT&T phone: even after unlocking it, the Torch's 3G radio does not work on my T-Mobile network (wrong frequency). I own a Torch because my MissingLight app became a Regional Selection in RIM's 2010 BlackBerry Super Apps Developer Challenge, and the  prize for that honor is a new Torch. I'm not complaining.

Friday, October 29, 2010

Beware the magic flush

It often surprises me what a good Java profiler can tell me about Hibernate performance issues. Recently I was studying a performance issue that seemed straightforward. There were lots of objects, lots of writes and lots of queries. Preliminary profiling showed one particular Hibernate query dominating the operation. That's not surprising, I thought: it's a frequently made query, and it's probably slow. I'll just find a way to speed it up, maybe with an index.

As it turns out, it was a simple, quick query. There was little hope of speeding that query up much. But further profiling showed that very little time was spent actually doing the DB query. So what was Query.list() doing that was taking so long? It was the implicit flush. The Hibernate session keeps track of objects that you have loaded, looks for modified objects and writes those modified objects to the database when flushed. A final flush happens upon transaction commit. Additionally, Hibernate by default behavior flushes dirty objects to the database before making a query, to ensure that the query is made on data that reflects all updates made to that point. If you have lots of persistent objects loaded, each flush can be expensive because with each query:
  • Hibernate has to check all persistent objects in the session for changes 
  • Hibernate will write any updated objects to the database. This can be wasteful: 
    • The updates may not be complete yet, so these intermediate writes are unnecessary
    • Spreading the DB writes across reduces Hibernate's opportunities to batch SQL statements for performance compared to writing everything at the end of the transaction.
The fact that flushes can happen during queries is significant. If you realize that an operation that interleaves object modifications and queries, you might consider the potential for significant speedup just by preventing that interleaving. For example, you could make all the queries up-front before adding, modifying or deleting any persistent objects so the only flush would be the final pre-commit flush.

DVCS for all the wrong reasons

A lot of virtual ink has been expended arguing the superiority of the distributed version control systems (DVCS) like GIT or Mercurial over Subversion, the dominant open source "traditional" VCS. Representing a substantial paradigm switch, DVCS software is hip and adoption is growing. I will argue that DVCS adoption is driven not by the essential superiority of distributed VCS (the D in DVCS) but by the temporary, accidental weaknesses of Subversion.