Sunday, December 20, 2009

classes that override equals should override hashCode

I was talking to a developer the other day who admitted to me that he had only recently found out that in Java, if you override the Object equals method, you should override the hashCode method also. He had been introduced to this practice by a checkstyle rule.

This surprised me for a couple of reasons. This developer is not a newcomer to Java, and it's the kind of thing I'd expect an experienced developer to know. I know about it myself from my first forays into Java. It's documented in the API for Object:
Note that it is generally necessary to override the hashCode method whenever this method [equals] is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

But I suppose it's the kind of thing you might miss learning if you come into Java from another object-oriented language, and don't do a thorough job of learning the peculiarities of Java.

The other thing that surprised me was the fact that he admitted it at all. Developers rarely confess to ignorance. I guess that admitting a weakness is just too dangerous in this highly competitive field. I tend to be pretty open about my own gaps in knowledge, but I suspect it doesn't help me any, and in some cases it may hurt. Have you ever said "gee I didn't know X" and gotten a snooty look down the nose from someone? Not the kind of experience you want to repeat!

Friday, December 11, 2009

debugging tools

I recently talked to a developer who admitted that he preferred using print statements to debug than any of the newer debugging tools, like what's available in Eclipse. This is the kind of statement that would probably knock my socks off if it weren't for the fact that almost nothing surprises me anymore!

I disagreed, but didn't argue it with him. Print statements are the worst, last option, in my world. There are just a few times when they are appropriate - for example, if you want to grep through values in a large loop. And of course in some cases print statements are the only option (on a production machine, for example).

But really, who doesn't just love a debugger? It's useful for 99% of the problems I have to solve.

Saturday, November 21, 2009

declaring and initializing an array in java

array initialization in java
array initialization in java Originally uploaded by rocannon1980

Yesterday I had a little adventure in coding when trying to initialize and declare a Java array "on the fly", so to speak. The problem is illustrated by the screenshot; here's the code:

public class TestMe {
  public static void main(String[] args) {
    HashMap<String, String[]> hm = new HashMap<String, String[]>();
    // Declare and initialize array. This is legal.
    String[] test1 = {"x", "y"};
    // Another way to declare and initialize this array, also legal.
    String[] test2 = new String[]{"x", "y"};
    // why doesn't this work??? Causes syntax error.
    hm.put("x", {"x", "y"});
    // This *does* work - use of "new" operator
    hm.put("x", new String[]{"x", "y"});
  }
}

The line which produces a syntax error in this code is hm.put("x", {"x", "y"});. The syntax error reads:
Multiple markers at this line
  - Syntax error on token "}", delete this token
  - Syntax error on token "{", delete this token
  - The method put(String, String[]) in the type HashMap is not applicable for the arguments (String, String, String)


Here, the compiler did not take the use of curly braces to be the shortcut syntax for declaring and an initializing the array.

I had started out by using the shortcut syntax, and when I saw the compiler error I thought I was losing it. It took some stumbling around to figure out that I could use the new operator to get the compiler to understand what I meant. Strange!

I can't imagine this kind of question would ever come up on an interview, but you never know. I hope that I'll remember it from now on; it's the kind of thing that's easy to forget.

Saturday, November 14, 2009

why is obsessive better than well-rounded?

Trick question: it's not.

I recently saw another editorial by someone who thinks good software developers should always have at least one side project going (won't link, there are plenty of articles like this around). If you're not involved in an open source project, or playing around with a new language, or developing your own little application, you just can't be up to snuff.

This seems to be a popular criterion. When I was interviewed for my current job, I was asked if I ever coded outside of work. I said that I did, although I freely admitted that my little projects rarely went anywhere - and they never turned into full-blown applications that were in use by anyone.

I did not mention that I tend to spend a lot more time experimenting with new projects when I'm unemployed...

I suppose for some small population of developers, coding night and day is fine. But it's ridiculous to suggest that these are the only people who should be coding, or that they're the only ones who are any good.

Many good developers have broad interests, hobbies, or even families *gasp*! They are very productive without coding all the time. Aside from that, software development is not a healthy activity in the long term (unless you're lucky enough to work with a Treadputer). Sitting in one spot, staring fixedly at a monitor for hours at a time is bad for you. Why does the "elite" development community laud people who do this, and point the finger of shame at people who do not?

I've known some developers who had their own little side projects. This was never a distinguishing marker of whether they were any good at coding, or whether they were even good to work with. Some were good, some were bad, some were a giant pain.

So in general, personally, I don't consider it admirable to be a constant coder, and I try not to get into that rut, although there's certainly a lot of pressure to do so.

Unfortunately, I have very little interest in the work I do on the job right now. There are a bunch of other development tasks with which I'd prefer to be experimenting. If I want to do anything about that, either I have to work on my own time, or sneak in time during the work day. I'm trying to do both.

This evening I sat down and started on a coding project that has intrigued me for a little while now. Took me an hour to do the installation and configuration work. That succeeded in dulling my enthusiasm, and I wonder if I'll continue work on it... It's one of the reasons I generally get nowhere with my side projects.

Friday, November 13, 2009

do you really want to wait your life away?

Recently I heard one of my chatty cubicle neighbors complaining about how long it was taking for some computer related task to finish - he was falling asleep just waiting.

It's the nature of working with computers that sometimes a job involves a long wait. I can't stand waiting. I get impatient if something takes more than just a few seconds, let alone minutes. It might be tempting to surf the internet while waiting, but given that most companies track your internet access these days, I rarely do this[1]. So here's what I do to avoid waiting.

If it looks like a task is going to take a long time, I try to make sure that I can't narrow it down to something which will run much more quickly. If I'm debugging a problem that occurs during a long-running process, I'll try to get the problem to occur during a simplified process that takes as little time as possible.

If there's no way around it, and I have to deal with a long-running process, I multitask. "Luckily" I usually have a healthy queue of things that need to be done. And usually there are a few items on that queue that don't require a lot of focus, and can be done in a fairly short amount of time. When I'm slowed down, I open a second instance of my IDE to work on one of those tasks.

I don't enjoy multitasking, and it is an oft-quoted observation that context switching is expensive. But if you have to wait for something, and you're staring at the screen with toothpicks propping up your eyelids, you're context switching anyway. Instead of just napping while I wait, I'd rather use the time to do something productive (whether my job entails doing things that are ultimately productive is a whole other can of worms).

[1] The truth is, I've seen coworkers surfing the net frequently, and I doubt there's any heavy-handed policy against it. But for some reason, it still goes against the grain, so I just don't do it.

Tuesday, October 20, 2009

For fun, I've been looking into Java's memory management tools, jhat and jmap.

Jmap works fine. I'm running Linux, so I find the Java process that I want to analyze by using ps -ef |grep java. Then I run jmap -dump:format=b,file=java_pid.hprof pid where pid is the Java process id. This generates a heap dump. You can repeatedly do this to get snapshots of the heap over time. Neat! Some of the heap dumps are quite large, over 1G in size.

Once you've got the heap, what can you do with it? You can use jhat - at least in theory. According to the jhat documentation, "jhat enables you to browse heap dumps using your favorite webbrowser." Sounds cool! But when I attempt to run it, I always get an OutOfMemoryError:

me@me:~/heaps$ ~/jdk1.6.0_10/bin/jhat java_pid403M.hprof
Reading from java_pid403M.hprof...
Dump file created Sun Oct 18 10:17:15 PST 2009
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Hashtable.rehash(Hashtable.java:356)
at java.util.Hashtable.put(Hashtable.java:412)
at com.sun.tools.hat.internal.model.Snapshot.addHeapObject(Snapshot.java:153)
at com.sun.tools.hat.internal.parser.HprofReader.readInstance(HprofReader.java:728)
at com.sun.tools.hat.internal.parser.HprofReader.readHeapDump(HprofReader.java:474)
at com.sun.tools.hat.internal.parser.HprofReader.read(HprofReader.java:226)
at com.sun.tools.hat.internal.parser.Reader.readFile(Reader.java:79)
at com.sun.tools.hat.Main.main(Main.java:143)

The smallest heap dump that I have is 400M, and it produced this error. Not so cool, really. What to do - run jmap on the jhat process?

I tried doing what I've done in the past when running into an OutOfMemoryError - reset the JVM's max heap size. The documentation says you can pass flags to the JVM running jhat by using "-J". Almost as if they knew you'd need it, they give the example of passing in the max heap size as 512MB with "-J-Xmx512m". So I tried using "-J-Xmx1024m", and the process continued further, but failed in the end:

me@me:~/heaps$ ~/jdk1.6.0_10/bin/jhat -J-Xmx1024m java_pid403M.hprof
Reading from java_pid403M.hprof...
Dump file created Sun Oct 18 10:17:15 PST 2009
Snapshot read, resolving...
Resolving 8502679 objects...
Chasing references, expect 1700 dots....................
[ a whole lot more dots, but not 1700, and then ]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Hashtable.rehash(Hashtable.java:356)
at java.util.Hashtable.put(Hashtable.java:412)
at com.sun.tools.hat.internal.model.Snapshot.addHeapObject(Snapshot.java:153)
at com.sun.tools.hat.internal.parser.HprofReader.readInstance(HprofReader.java:728)
at com.sun.tools.hat.internal.parser.HprofReader.readHeapDump(HprofReader.java:474)
at com.sun.tools.hat.internal.parser.HprofReader.read(HprofReader.java:226)
at com.sun.tools.hat.internal.parser.Reader.readFile(Reader.java:79)
at com.sun.tools.hat.Main.main(Main.java:143)

Disappointing! I wonder if anyone uses jhat at all, or if it's just a nice toy for very small heap dumps.

In fact, if you search the internet for "jhat OutOfMemoryError" you will find some very interesting links to follow up on... I'd like to get jhat working, just to see what it does. But meantime, I've also stumbled across the Java performance blog, and I'll soon be trying out the Eclipse Memory Analyzer.

Sunday, September 27, 2009

is this in my job description?

OK, my job doesn't actually have a description. I work at a company which doesn't believe in that kind of thing. My job title is "software engineer", and I imagined I'd be doing software-engineer-y things when I signed on. And usually, that's the case.

Last week, though, I had to spend a couple of days doing things that would normally be done by a business analyst. It was made particularly onerous by having to wade through enormous amounts of legalese, the kind of thing that makes my head vibrate (in a bad way). In addition, I was forced into more-than-usual contact with one of the testers that I don't get along with so well.

The fact that I was assigned to do this work isn't a signal of any kind. I'm pretty sure it was just expedient. There just aren't any BA's at my company. Given that, I think the work that I wound up doing should have fallen into the product manager's hands, but he's already overloaded with other work, and tries to avoid involvement in my product when possible. Of course, I am also overloaded with work, but the buck stops with me, it seems.