May 08, 2009

Flash card Friday



It's Flash card Friday, on time. Without further ado, here are the lessons learned this week:
  • Bounded wildcards should not be used for fields

    I've mentioned PECS before, and this relates to it. Maybe you've be tempted by the sweet sugar that is bounded wildcard generics. You need to be careful though. So far, I've only found one good usage area for them, and that is method arguments. It would however, in my opinion, be a mistake to use them for:

    • Return values. They clutter the API in unnecessary ways, and it's not Java 5 compatible.
    • Field or variable types. Try it. You'll run into trouble.

    Of course, I may be wrong about these things, so let me know if you disagree.

  • Google App Engine datastore not suited for massive amounts of data

    This week, I developed a small GAE application that scrapes a website for apartment listings. In no time I had found thousands of entries, each saved as an entity in the GAE datastore. Awesome.

    Then I found myself in a bit of a pickle. The datastore API only permits fetching of at most 1000 entities per fetch call. Ok, I thought, so I guess I can just get the next 1000 after that. Nope, the offset also has a limit of 1000. But, I can actually iterate over the query object! Great? Well, unfortunately, the time one is allowed to spend in datastore API calls is quite limited, so the iteration times out in a few seconds.

    I'd love to hear how people manage large amounts (>10k) of entities in the GAE datastore.

  • Good ideas often bring additional benefits

    Something I've noticed when watching skilled coders refactor is that their changes often include additional benefits. Their explanations often sound something like this:

    - Well, if we do it this way instead, then we don't need this list at all. And also, those classes can make use of this thing now, so we can remove that old thing.

    or

    - If we change this method signature we will get a cleaner API. That other class can then make use of this instead, further decreasing our dependence on that other sucky API.

    Note the sentences in italics. These are the extra perks you get when you're doing a good job refactoring your code. In fact, if your refactoring doesn't bring any extra benefits, maybe you should rethink it.

    Note: It's not a coincidence that my examples described refactoring making code leaner. That's the way it should be done :)

May 07, 2009

Thoughts on inspiration



Back in the day, when I was a naïve youngster, I used to think that good ideas came from thinking. Don't get me wrong, that's definitely part of the recipe. It's only that, just thinking doesn't get you very far. Lately, I have realized something:
Inspiration does not come from within.
I get inspired by talking and listening to other people. By watching a good movie. By reading an interesting article. By observing. Those are the times I get good ideas.

Occasionally I find myself in the mood for starting a new project, be it small or big. I sit and try to come up with a good idea - it could be something to code, something to sell, or something to do. Rarely that thinking amounts to anything. If you experience the same thing, I have one tip. Stop thinking. Go catch a movie. Grab a beer with a friend. You'll know a good idea when you have one. Meanwhile, relax. Watched water does not boil.

April 28, 2009

Flash card Friday: 3.5 weeks late



Haven't done the flash card Friday for a while now. Been busy with stuff. But now it's finally time to get the words of wisdom rolling again. Here's a fresh batch of goodies for y'all:
  • When testing a number of components in a failing setup, it is most likely that two of them are incompatible with each other

    Sometimes you're testing a setup with three different databases, three different app servers and three different operating systems. Testing all 27 combinations takes time. Often when something fails, it is because two components were not compatible with each other. We can therefore make sure we test all pairs of components instead. That way, we will only have 9 test cases. This reduces the time it takes for us to run the tests, while still retaining relatively good coverage. This technique is called all-pairs testing.

  • Introducing tests that fail is a good thing

    We have been introducing more and more high-level automated tests at work lately. Some days ago I was working on a particular test that kept failing, and I was becoming aggravated. The actual feature I was testing had been in the product for quite a while. Damnit, I thought, I'm wasting a bunch of time on getting a test working for something that already works.

    As it turns out, the feature I was testing actually had a bug, and my failing test was simply exposing the bug. So, having tests that fail is a good thing. Aggravating none the less though.

  • Balsamiq mockups are awesome

    Lately, at work, we've been improving our user interface a lot. This process often involves communicating ideas from/to the product owner. Roughly a month ago, a team member introduced us to Balsamiq. It's a tool for creating user interface mockups in no time. The mockups end up looking like cartoon drawings, without any flashy features such as fancy colors, fonts, and styles.

    A good thing about this is that users don't get hung up on the details, such as font sizes and millimeter placement of buttons, but can instead focus on the actual functionality of the GUI. The tool is also dead simple to use, and a mockup for nearly any interface can be created in five minutes. It integrates nicely with JIRA & Confluence too. Do check it out.

  • Drive requirements top down

    When adding new features to a system, it might help to start from the user interface. This is the user's view of the system, and we should strive to root all requirements in user needs. Starting out with the UI sketches helps drive the useful requirements. It might turn out that the really cool backend feature actually wasn't needed at all, because there is no real use case for it.

  • Be careful with the minimized tag form in XHTML

    The XHTML specification states that elements with non-empty DTD definitions should not use the minimized form (e.g. <div />). This is interesting, as it's perfectly valid XML. I have however run into problems when collapsing divs without content. Note that line breaks cannot have any content, so they may be collapsed to <br />. See the XHTML specification, section C.3, for more info.

  • Beware of the OOM

    I recently learned that a Java program that runs out of memory actually can exit without an OutOfMemoryError (OOM) exception. This is due to the fact that the JVM does not have enough memory to allocate the exception. Tomcat solves this in an interesting way. At startup they allocate memory that can be freed should an OOM occur. That way, there is enough memory to shut down gracefully. Odd solution, but I guess it works.

  • JSON JSP tags

    JSON is a wonderful thing, and sees many uses today, sometimes far away from JavaScript. If you're looking to get data from your server-side model into your client-side JavaScript data model for your dynamic interface, and are using JSP to render your view, then you should definitely check out the json-taglib project. It offers a simple set of tags to generate JSON objects and arrays from your server-side model. That's it.

    Now, you may be using richer frameworks for dealing with client-side JavaScript data models. If so, I'd love to hear about them.

April 17, 2009

Dreams



Last night I had a dream. I usually don't remember my dreams, but this one I recall vividly. It involved people in current time, teenagers I think, somehow traveling to the future, possibly to a parallel dimension. There, they are chased by bad guys. A good guy then stages their death in a parking garage and takes them to an underground safe house. There, a metal elevator door is surrounded by a crowd of people, waiting for it to arrive. When it does, they instead gather around, revealing that they were not random people, but also good guys. The teens are instructed to strip all their clothing and step into the elevator. I particularly remember one ranking good guy touching the inner wooden panel of the elevator, saying something I don't remember, but looking as if he had never touched a wooden wall previously in his life. As if it was a relic from a lost age.

The elevator is eventually activated, and the old metal doors close with a creaking sound. Through a small round window in the side of the elevator shaft the cage is seen descending. A mechanical noise is heard, and then everything goes quiet. The good guys look at each other as if they'd accomplished something great.

Back in the present, I just have this image of someone, possibly the teenagers, looking at a signal map of some kind. I remember that they looked at a point with a bunch of small arrows out of it, each with a number. They didn't know which one led anywhere. I however somehow knew that -11 led to the other world - probably something I learned at the beginning of the dream.

I woke up from this dream with an odd feeling. I can't really describe it, but it's a combination of joy, meaninglessness, sorrow, and mainly, respect. People in different times and places had once helped each other, but would never meet again. Gazing at the stars above, they could only remember the time they had shared. That was their memento.

It's strange how dreams can affect you. Walking to the subway, I somehow felt different, if only for a while. I knew the world was the same as yesterday. People looked the same. The car exhausts smelled the same. Yet it was different for a moment. There's so much more to the human mind than we think.

Have you experienced something like this? Please share your own dreams.

April 14, 2009

Quick and dirty redundancy, anyone?



I spent this weekend out in the archipelago with my girlfriend. I brought my camera, and ended up shooting quite a lot of pictures, it being a nice day and all. Pretty soon, my memory card was all filled up with 12MP JPG+RAW files.

Now, some people would call me a pack rat. I simply don't like throwing things away. Especially not pretty (or so I tell myself) pictures. So I thought to myself, where should I store these pictures? Quickly, as the techie I am, I came up with some different alternatives:
  • Stash them on my servers

    This is perhaps the most natural alternative for a geek. "Just rsync the stuff to your server!" Yeah. This is a good idea, if it weren't for two things. 1) Servers require work and maintenance. 2) My current servers have like 40GB of disk space left. Replacing the drives takes time and money. Thus, goto 1.

  • Keep them on the memory card and get a new one

    As stupid as this may sound, it's actually an appealing idea. Modern memory cards hold data for centuries, and the interface is very standard. Thus no irretrievable data later on. The practicality of just popping one card out and popping a new one in shouldn't be underestimated either. The downside is that it's ridiculously expensive to do this, in comparison to a hard drive based approach.

  • Put them on my brand new USB drive (WD passport)

    Recently, I bought a USB hard drive. Kind of ashamed to say it's my first one. (What, I've used my RAID1-configured servers in the past, don't judge me.) This drive is a Western Digital Passport drive, and it's unbelievably cute. Come to think of it, I've actually been carrying it around my jacket breast pocket for half a week without even thinking about it. That's how small and light it is. And it runs off the USB power, so all you need is a USB cable.

    Anyway, an alternative would be to store the images on the external drive. However, having experience with IBM DeathStars and the like, I'm aware of the potential flakiness of mechanical drives. And this leads us to the topic at hand.
What if you could plug any number of USB drives into your computer, and then run a command that made sure that all files on all connected drives were stored redundantly. A post-write kind of redundancy, if you will. That way, you could write your data to the drives when ever you want to, and at a certain point plug them all into your laptop and add the redundancy. In a simple implementation, if a drive fails, you'd have to plug all drives into your computer to recover all data. I don't know if this would be useful, and I don't know if such a solution already exists. In either case, let me know what you think.

April 07, 2009

Don't ask for more than you need



The other day I was browsing a site for photography, when I came across an item (Swedish) without a description. Instead, there was a short text instructing me to e-mail the site administrators, kindly notifying them that the item was missing a description.

Another time I was browsing another site (I think it was some page at sun.com) when a small popup inquired for some feedback. Did I like the site. It would be great if I left a comment, notifying them of my site experience.

These are just two examples of when a different interface would work better, in my opinion. A simple one-button interface can actually be good. The photography site could simply have had a button saying "Report this". Sun's site could have had a button with the descriptive text "Click if you like the page." And possibly also "Click multiple times for better feedback."

Simplicity should never be underestimated. In fact, this concept already has a lot of traction. Digg is a typical example. Facebook's Like links for the facetweets are of the same kind. Morale of story: a simpler interface might gain you more user feedback.

April 03, 2009

Flash card Friday



It's flash card Friday. For some reason, this week didn't really yield any good lessons learned. I have half an item written down, but I'll include it in next week's batch instead.

Meanwhile, some words of wisdom:

You are not your job. You are not how much money you have in the bank. You are not the car you drive. You are not the contents of your wallet. You are not your fucking khakis. You're the all-singing, all-dancing crap of the world.

Except for the last thing. But seriously. At the end of they day, what are you accomplishing? What really matters to you? Might be hard to answer, but it's worth thinking about. To quote Tyler Durden again, this is your life, and its ending one minute at a time.

How's that for a dip into the platitudes? Please return your seat backs to their full upright position.