Tuesday, December 22, 2009

Java inner class peculiarity

I recently ran across an obscure Java factoid that will probably never come in handy. I found it when researching PMD rules.

Suppose I have an inner class as follows:

1 package com.examples;

3 public class Outer {

5   public void test() {
6     Inner ic = new Inner();
7   }

9   public class Inner {
10     private Inner() {
11     }
12   }
13 }


Even though the constructor for the inner class Inner is private, a package-access constructor is created by the compiler as a side-effect when you call the private constructor at line 6 in the test method.

There are a couple of ways to verify this. First, you can just look at the generated class file Outer$Inner.class. You'll find two lines, one for the private constructor that you have written, and another which is a "synthetic"* constructor:

..
private Outer$Inner(com.examples.Outer arg0);
..
synthetic Outer$Inner(com.examples.Outer arg0, com.examples.Outer.Inner arg1);


If you are not convinced, you can run through the constructors using reflection, as shown in this example class:

1 package com.examples;
2 import java.lang.reflect.*;

4 public class InnerTester {
5   public static void main(String[] args) throws ClassNotFoundException {
6     InnerTester.printConstructors("com.examples.Outer$Inner");
7   }
8   public static void printConstructors(String str) throws ClassNotFoundException {
9      Class c = Class.forName(str);
10     Constructor[] cs = c.getDeclaredConstructors();
11     for (int i = 0; i < cs.length; i++) {
12       System.out.println(cs[i].toString());
13     }
14   }
15}

Running this program produces two lines of output:

com.examples.Outer$Inner(com.examples.Outer,com.examples.Outer$Inner)
private com.examples.Outer$Inner(com.examples.Outer)


If you comment out line 6 in Outer.java and recompile it, the output of this program is just one line:

private com.examples.Outer$Inner(com.examples.Outer)


You can look at the class file, Outer$Inner.class, and check that the package access constructor is gone, there, too.

There's a rule warning against calling a private constructor of an inner class like this, because the constructor is effectively given package access. PMD suggests using a factory method instead of creating the instance directly in the outer class, or just making the constructor public, to solve the problem.

I can't imagine any situation in which this would be a problem unless you're using reflection to call constructors.


* The Sun tutorial on Java reflection has a brief discussion of synthetic (compiler-generated) constructors.

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.

Monday, August 31, 2009

two databases, one column

I feel fortunate that I don't experience a "WTF?!" moment on a daily basis. Although sometimes, it does feel like I'm in Groundhog Day, perpetually experiencing the same WTF?!s over and over again. Today was such a day.

The application that I'm working on talks to two databases. In one database, there's a table called user with columns like id, firstname, lastname, ssn, and so on. The information in some of the rows in this table has also been stored in the second database. This is done for reasons of efficiency, so that when querying the second database, we don't always have to dip into the first database to get user information.

This seems perfectly reasonable to me, except for the way that it was done. Way back in the stone ages of our application, someone decided to store all the user information in a single column in the second database. It is stored as a set of key-value pairs in a CSV string, in a column called user, like this: "user=3378,first=John,last=Smith,ssn=123456789,..."

Since I first encountered this, I've been cursing scratching my head about why someone would decide to store all of this information in a single column. It makes queries more difficult to read and write, because it requires regular expressions to extract single items like the social security number from the user column. I can imagine this is also a performance hit.

In addition, whoever decided on this format did not replicate the user table column names for the keys in the CSV string. So the user.firstname column in database 1 maps to first in the CSV, user.lastname maps to last, and so on. This makes life more difficult when searching the code base for all queries related to a particular piece of user information. I recently fixed a bug caused by this mapping difference.

I'd love to have a conversation with the person who decided to do things this way. It would either be enlightening, or just plain crazy.

Saturday, August 15, 2009

networking

I just laid down some serious cash out of my own pocket to go to a professional conference. I should do this more often, I guess. It's difficult to justify it based on results. Does the conference pay for itself, in the long run? I have my doubts. But I expect it will considerably improve my mood, at least for a little while, and I can really use that.

Before going, I should to do some reading about how to network effectively. Without feeling (or acting) like a leech.

Wednesday, August 5, 2009

please talk louder, I can't hear you

The personnel manager of my company is seated in an office near my cubicle. This morning, when I arrived, she was engaged in what turned out to be a lengthy conversation with her assistant. The conversation was loud, and large pieces of it drifted into my consciousness. Quite a lot of it was of a personal nature. At times the conversation would become muted, at which point I surmised they were talking about something (possibly work related) that they didn't want others to hear about. This was an indication to me that they were aware of the fact that people sitting nearby could hear every word of what they were saying.

Later, around 10 am, the guy in the cubicle adjacent to me began having a loud and detailed telephone conversation about his car loan. This went on for about five or ten minutes.

Then at around 2 pm, a guy further away began having a rancorous phone conversation, apparently with a car mechanic, about the unsatisfactory service he'd received. Despite the fact that he is two rows away from me, I could hear every word.

In between all this was the incessant chatter from two nearby cubicle dwellers who can't seem to stop free associating about non-work related topics for a large part of the day.

I think my number one complaint about my current job is the incessant noise due to inconsiderate coworkers who have different standards about what constitutes appropriate workplace discussion and the volume thereof.

I am a programmer, working at a software company. That means I spend long hours thinking in front of a computer. Ideally, I'd be sitting in an almost noise-free environment, with infrequent interruptions. For example, right now I am at home typing at my computer. There's a bit of noise from the apartment across the hall - I sometimes hear a child making, well, child noises. Sometimes there's car noise from the parking lot. Overall, it's pretty quiet, and there's no sound of people talking. At home, this is true all day long.

Normally, I am a very focused person, and I find I can frequently block out the conversation noise at work. After about a year at my current place, that no longer seems to work. I've noticed that several coworkers use headphones. I don't like headphones; they eventually begin to hurt my ears. Further, I do not focus well with background music drilling into my brain non-stop. I work much better with quiet, and it's frustrating being forced to take steps to block out noise which should not be there in the first place. Because these people are not even having work-related discussions. They are just blabbing about personal stuff during work hours.

The company culture overall encourages this. I'm within earshot of a couple of more senior people who have loud phone conversations (work related or personal) from within their offices. These are not cubicle dwellers, but they still find it necessary to leave their doors wide open when talking on the phone. What's amazing to me is that these people do actually sometimes close their doors when on the phone. Presumably this means something particularly private is being discussed. Don't they realize that no one wants to hear their non-private discussions, either? Just be considerate and shut the door when having a conversation, for crying out loud!

In my list of grievances at my current job, this ranks pretty high. The noise is bothersome, but just as aggravating is the apparent lack of consideration by numerous employees. Sometimes it seems like these people are deliberately talking loudly as a way of showing how important they are. Or maybe they're just thoughtless blowhards. Either way, I wish they'd STFU. But I guess that's not going to happen, so I need to put my ass in gear and start looking for a new job.

Saturday, August 1, 2009

how much time will it take?

I'm one of just a few developers working on a poorly supported software product. The product was barely maintained for the last several years, since it was first released. Many moons ago, it was decided to give the product a complete overhaul, front end and back. Meantime, the main caretaker of the product wisely decided to leave for greener pastures. He was tasked to add as many new features as he possibly could before leaving, and he did so.

He pretty much had free rein over the product while adding enhancements and rewriting code. So far as I can tell, there was no extra pair of eyes checking to see what he did. Management trusted this developer to do everything in the "correct" way. The problem with that lack of oversight is that you are trusting a developer to do everything the way you expect without much (or any) feedback. In many cases, even the product owner doesn't know what to expect, so this imputes impossible, magical abilities on a developer. Naturally, some things are not working correctly, and additions have to be made.

Next thing you know, I've been assigned to finish up the work that was started by the departing developer. There are areas of the application that are incomplete. The code base is quite large, and the application is complicated. I don't know what things work or don't work until I happen to run across them while debugging some other problem.

I've been asked to supply an estimate for how much more time will be required to take this project to completion. So far, I have equivocated, saying that it is very difficult to make that estimate at this point. I am still unfamiliar with a lot of the code base. No one knows how many bugs are in the current iteration of the product. I don't have a specification for what needs to be done, or a checklist of things that have been changed or are still needed.

Truth is, it looks to me like there is still a lot of work ahead, but I can't tell how quickly that can be done. It's even harder to make an estimate because one developer keeps getting pulled away to put out fires in another development effort, so progress is even more unreliable than it usually is in software development.

How do you make an estimate in a case like this? I have a gut feeling for how much more time is needed, but I can't justify it. I'd like to take a few days to run through every feature in the product and see just what is and isn't working. At least then I'd have an idea of how much stuff is still broken. But management would not approve that. I'm supposed to spend every minute developing or bug fixing.

So I can't come up with any justifiable estimate. Meantime, management decides to supply their own deadline. I believe this date was pulled out of thin air; it certainly is not realistic. I don't understand why you'd pull a deadline out of a hat and not expect to be disappointed. I've seen this happen with another project. They kept rescheduling the deadline for months. It makes no sense.

Saturday, July 25, 2009

fragile (code) - handle with care


I'm working on a "legacy" software system. Legacy means different things; in this case I mean it has been around for a few years. The original developers are long gone, and there are numerous sections which are a mystery. Even more annoying, the code produces mystery entries in the database. There are columns with fields that have dual, hidden meanings. There are extra rows for undocumented special cases.

One of my colleagues, let's call him "Mr Eager-Beaver," recently decided he'd had enough, and removed some lines of code which had been adding apparently extraneous information into the database. He's not an idiot, so he tried doing this on a test system first, and found that nothing went wrong. So he argued for committing the change, and so it was.

Unfortunately, the application is extremely large and complex. Being finite, I'm sure you could design a suite of tests which check every possible feature in the application. However, the company motto is "we will test no code before its time." The end result is that we actually have a very limited suite of tests for this application. Further, from a QA perspective, you can't just go in and hit a few pages, click a few buttons, and declare a code change has done no damage.

So ever since this change was committed, we've been uncovering bugs related to it. In a few dusty corners of source code, the application expects to find the missing information in the database, but doesn't, and barfs.

It wouldn't be so bad if these bugs were easy to find, or if they could all be dumped on the original hero who did the refactoring. No; what happens is that you have no idea what is causing the bug until, after several hours of research, the realization dawns on you: "Oh, this is due to Eager-Beaver's code change!" At that point, you can fix the thing pretty easily, and there's no point in reassigning the bug to him.

So far I have had two such bugs assigned to me. Eager is actually a pretty decent guy, so while I do get an urge to come over and give him a good metaphysical ass-kicking when I finally discover the source of the bug, I don't. I can only hope he's been assigned his own fair share of these bugs. And that he'll be as nice to me, whenever he uncovers some code crime of my own.

Saturday, July 18, 2009

stack overflow

stack overflow

I've never had much need to write recursive functions in my programming career; I've written one perhaps two or three times, all told. Hence, I haven't paid them much attention, and still don't really know much about them.

It turns out that interviewers are quite keen on asking questions about recursion; perhaps this is because there's a heavier focus on them in CS classes than there is a use for them in reality?

The first time I encountered a question about recursive functions during an interview, it kind of threw me. Why ask a question about something so rarely used? My response was that, yes, I've written them, but rarely, and I try to avoid it when possible because I find them confusing - I have a fear of writing something that will result in an infinite recursion in some subtle case. It was during this interview that I learned that recursive functions can lead to stack overflows. Thereby proving that interviews can be useful, at least as learning experiences.

Well, today I caused my very own stack overflow by creating a recursive function, albeit unknowingly! I had created a Java class which extended another class, which mostly had getters and setters. The intention was to eventually implement these methods in the child class, but meantime I had the child class override the parent's methods, and just had them return the results of the super class methods. For example, I had the getFoo() method call the superclass method, super.getFoo(), and so on. Only, in one case, I inadvertantly left out super and had the getBar method return getBar - so the method called itself recursively. When I ran the code, I immediately saw this huge stack trace in the output. At the top it said "Exception in thread ... java.lang.StackOverflowError. This was followed by 1024 repeated lines giving the method which had generated the error.

I don't recall ever experiencing this in my entire career, and I could immediately see what had gone wrong, so I found it very entertaining (perhaps I am too easily amused).

Wednesday, July 15, 2009

the blame game

bug
There are a couple of developers where I work who are in the habit of making public announcements when other people's bugs are found. They'll write it in a bug report: "I found these lines of code written by X", followed by the egregious offending lines of code. Or they'll announce it in a meeting: "Yesterday, I was working on a bug that had been assigned to me, but it turned out to be a problem introduced by Y's implementation of the foo feature."

Is this normal, common, or in any way productive? In my view, it is counter-productive: there's an element of public humiliation in it, where there doesn't need to be. And it does no good that I can see; rather it engenders a hostile and competitive work environment, whereas I prefer a cooperative one.

I am probably too thin-skinned about this, but it really grates on me. My gut reaction is to want to retaliate by publicly pointing out every bug made by these finger-pointers.

However, I see no reason to publicly call someone out on such a thing. Instead, I apply my default behavior to everyone equally. If I find something wrong in someone else's code, I fix it, and in the bug report, I'll write something like "the problem was in the implementation of foo in class Blah, where == was used instead of the equals method." If the person is still at the company, usually I'll walk on over to them, point out the problem, and ask if they agree with my solution, or if they want to fix it themselves. I don't do this to rub their noses in it, but because that's the way I'd like to be treated - I want to know when I've made a mistake, and be given a chance to correct it.

To be fair, the finger-pointers do, on rare occasions, point out bugs of their own making. So maybe they're just applying their own standards to everyone. Still, it seems like the standard (and friendly) behavior is to point out a bug, but not call attention to the bug creator. I wonder what motivates those who insist on playing the blame game.

Saturday, July 11, 2009

how can you be so sure?


I'll preface this story by saying that I don't think I'm unusual in my confidence level. I am comfortable and generally feel confident with what I know, and am not so confident when straying into areas where I have less experience.

That being said, when the code suddenly stops working the way I think it should, my confidence level drops like a stone. Sometimes, I'll immediately assume that there's some hidden rule, unknown to me, causing the strange behavior.

Yesterday, as I was stepping through the code with a debugger, I saw something happen which just isn't supposed to happen. I had an object of type Apple, which extends class Fruit. (Needless to say, class names have been changed to protect the innocent). Both classes had a getSize() method. When that method was called, the getSize() method of the Fruit class was being exercised, not the corresponding method of the Apple class. It went something like this:

  Fruit fruit = doSomethingComplicated();
  int sz = fruit.getSize();
  ..
}
protected Fruit doSomethingComplicated() {
  ...
}

Way down the call stack, doSomethingComplicated() was creating an instance of Apple, so fruit.getSize() should use the getSize() method of Apple, not Fruit. Yet I could see that the Fruit getSize() method was being called.

Just as I noticed this problem, and was thinking "whoa, what's that about??", a coworker came over and I explained what I was seeing to her. She seemed pretty sure that it was simply not happening, even though I could show her by stepping into the debugger that indeed, it was happening. Basically, I believed what my eyes were telling me, and she didn't.

She was right, and I was wrong. I had failed to notice that midway down the call stack, a new instance of Fruit class was being returned, not the original instance of Apple that I had seen created at the bottom of the call stack. I don't feel too bad about not noticing this, since it had escaped the eyes of my coworker too, even after we had stepped through with the debugger a couple of times.

What makes me feel bad is that I had such uncertainty about the way inheritance works in Java that I wasn't sure the behavior I saw was completely insane; in contrast, my colleague seemed convinced that something was totally wrong.

I really need to put some study time into relearning some of the basics, in addition to training on new material, to achieve that level of confidence!

Wednesday, July 8, 2009

females are better at documentation? c'mon...


was this code written by a man or a woman?
long code comment

I recently became aware that there's a stereotype that women write more "touchy-feely and considerate" code than men, interspersing it "with helpful comments and directions, explaining why they wrote the lines the way they did and exactly how they did it..."

I have my doubts about this sweeping generalization. Nevertheless, today I received some recognition from a colleague for the helpfulness of my written documentation in three places: directly in the code where I documented why a change was made, in version control when I checked in my code changes, and in my bug reporting comments. He told me that all of this information greatly reduced the amount of time that it took him to resolve an issue.

I don't think my documentation skills are due to some natural ability as a woman. I have a PhD, and as Terri points out at CU-WISE blog, documenting your research is a key skill ingrained during graduate school, if you don't already have it.

I guess I should be happy about being complimented for something, but I'd have been happier if it had been about my excellent coding skills. This was akin to being praised for tidy penmanship.

Tuesday, July 7, 2009

engineer vs bugzilla

bugzilla logo by Dave Shea
In my view, a good bug report contains an ordered list of steps to take to reproduce the bug. I realize this is not always possible (e.g. the bug is intermittent, and QA does not have the time or resources to nail it down).

In reality, I rarely see a sequence of steps in a bug report where I work. I haven't quite figured out why. I think that QA is often just poking around the application, trying things out. They do a sequence of steps, and suddenly something goes wrong. However, they haven't recorded the series of steps as they went along, so the reports go something like this:
Widget on the fribble panel sometimes vanishes. See attached screenshot. May have clicked the foo button three or four times in rapid succession before that happened, not sure, was doing some other tests at the time.
This kind of bug report makes life difficult for me. It means I have to spend a lot of time trying to figure out just how to reproduce the bug, time that could be better spent doing actual development work.

I suppose I could just mark such bugs as invalid, or reassign them back to QA, with a request for reproducible steps. I haven't done this, yet, at least not without a good faith effort to try to reproduce the bug. I get the feeling that QA doesn't take it well when you send bugs back to them in this way.

In my view, QA and development should all be one big team, trying to make the software work. In reality, it sometimes feels like the two departments are at war. Is that common in the industry? Is there a way to stop it?

Tuesday, June 30, 2009

people that you meet

The crowd at the conference
photo by Stephan Ridgway by use under cc license

Recently, I was having a discussion with an unemployed software developer. I will refer to him as X (just so we're clear, "X" is not his real name).

X had a few words to say about taxes and the attempts to nationalize health insurance; he was against both. I didn't get to dig much deeper because we were in the midst of discussing something else, but I did disagree with him immediately on the latter point, since I am perfectly happy to try nationalizing health insurance. He later mentioned to me that while he was unemployed, a huge part of his health insurance was being covered by the government-run stimulus plain. He seemed to be happy about that.

X told a story about a guy he knows who is on disability, who gets all of his health care provided for by the government, and who, in addition, is taking off for a three-week vacation. I wasn't quite sure what the moral of his story was. But it sounded a lot like he was ranting about how such people cheat the government and steal his tax money.

X is taking a few weeks of vacation in August. He indicated that he was planning on drawing unemployment compensation while he's on vacation. I urged him not to, pointing out that it's illegal and unethical.

While discussing these things, I tried to keep polite when disagreeing. My natural tendency in such situations is to avoid conflict, neither disagreeing or agreeing, and to move the conversation along away from hot-button issues. And later, I try to avoid getting into discussions with the person. Possibly I'm overly non-confrontational (<sarcasm>is that because I'm female?</sarcasm>), but I don't see any point in getting into random arguments with strangers. I'm not sure what to do in this case. I met X at a professional meeting, and was hoping that he'd be a good networking contact, but I think I was mistaken. This most recent conversation gave me a pretty big "ick" factor. How picky should you be with your networking contacts, anyway?

Saturday, June 27, 2009

how to stay current

Another method that I use to attempt to stay current is to attend professional meetings. These can be pretty informal; for example, a few developers may organize a meetup without any agenda. I've also attended Java User Groups on and off for a long time. The ones I've attended have been pretty crowded (perhaps 100 people), and there's always a speaker with slides. I like those because I can get an introduction to new technologies that I don't have the opportunity to use on the job.

With these kinds of meetings, normally you don't have to pay cash money - but you are paying with time. Overall, I think it has been worth it to attend most of the meetings I've been to. I try to attend something at least once a month. It keeps me on my toes, keeps me motivated.

I've even gone so far as to pay my own way at a professional conference! This can get pretty expensive, but again, I think it's worth it. For one, I got pretty psyched about Java development after my last conference - it was highly motivational. Of course, the feeling didn't last indefinitely, but I think it had an overall positive effect on me. Part of that effect came from hanging out with a number of enthusiastic developers, people who really seem to care about doing their work well. For another, the speakers were really good! While the free meetings I've attended have had reasonably good speakers, in comparison these people really blew me away.

I'm going to try to go to one of these meetings at least once a year. Hm, I'm just reviewing the schedule for this year's OSCON... it looks so cool! I wish my company would pitch in something for events like this.

Thursday, June 25, 2009

how to stay current

It's hard to put in extra hours outside of work, studying and practicing to get better at my job. I've become kind of rusty.

Here's one trick that helps. I skim technology articles and keep an eye out for an unfamiliar term. I keep track of the terms on a whiteboard, and research them when I have time, maybe read the wiki page about it. I can do this while eating breakfast, two birds with one stone.

It has been helpful in building up my jargon vocabulary, which hopefully will make me sound more confident and authoritative. Or at least help me understand wtf an interviewer is asking about.

Here are some items from my whiteboard:
  • common closure principle Your classes should never change. But sometimes they have to. In those cases, your system should be designed so that related changes will only affect classes within the same package.
  • command patterns
  • runtime weaving
  • dynamic proxies

Tuesday, June 23, 2009

interview practice

boy in suit
photo by david wiley, by use under cc license.
I've done enough interviews over the last few years to learn that you can never practice for them too much. But I rarely spend time thinking about broader professional questions while I have a job. When I'm employed, I'm usually in one of two modes: impossibly overworked with no time for training, or deliriously enjoying pure non-work fun during a slow down.

However, since I've been thinking about starting a job hunt, it seems reasonable to put in some preparation. I'll use this page to post links to resources that I'm finding handy.
  • five essential phone screen questions by Steve Yegge. These great questions are motivated from the interviewer's side of things.
  • get that job at google by Steve Yegge, again. This blog post discusses interview preparation for a broad range of questions. What he describes would take months or possibly years to get through if you didn't already have a CS degree. But it helps to know what to expect and cram as much of this as possible.

Monday, June 22, 2009

about me

I came to software development from another discipline. I had done a whole lot of programming in my previous field, but it was a means to an end. When I decided it was time to do something else, I looked at my skill set, and decided programming was my best bet. It was reasonably lucrative, and I wouldn't need to go back to school. All I needed to do was find a job.

I had never done object-oriented programming professionally; all of my previous work had been done in a couple of procedural languages. I had read that OOP was how all modern development was done, so I set myself to learning Java.

It took a while, but eventually I found a job as a Java developer, at the tail end of the dot-com boom. During my first year at that job, I spent a lot of my spare time studying the craft of programming in this new language. I was pretty motivated. Even though I wasn't exactly passionate about Java development, I enjoyed it and I wanted to get good at it. I was looking to become highly skilled in my field. I was surrounded by people who didn't seem to care one way or the other about professionalism. That attitude kind of surprised me.

Then the economy went south, and I became another unemployment statistic. I took the first job I could find at a shop that didn't have much truck with modern software development. My Java skills went rusty, and I became depressed and cynical about my "career" as a developer. I stopped studying or doing anything outside of work to improve my skills - what did it matter? I was not encouraged to do so, and any financial reward coming from such practice was a vague hope at best. I had become one of those employees who don't really care about professionalism.

A couple of job hops later, I've begun to feel a little more interested in my career. I'm doing Java development, once again, and it's a lot more fun than using mumbledy-mumble which I worked with in my last job. I've begun reading some technical books when I'm at home. I'm hoping to take a step up with my next job. I can see that probably won't happen unless I can blend in a little more with the people holding CS degrees.

I'm not sure exactly what I want. My motivation to improve started out, mainly, with a desire to earn a better salary. I'm guessing that there are some holes in my knowledge that need to be filled before that will happen. But I also want to do more challenging work. I think I'm a pretty solid developer, but I'm getting tired of doing the same old stuff over and over again. That may mean I'll have to leave this field behind. But maybe I can breathe some new life into my career; it's worth a try, anyway.

Sunday, June 21, 2009

any women out there?


I'm a female software engineer.

I follow a few blogs that are written by male software developers. Today, I had a vague interest in reading something written by a woman who does software development. I follow Female Science Professor's blog, and I was looking for something similar, something written by a software developer. So I went to google and typed in the four search terms "female", "software", "developer", "blog", like this: female software developer blog.

A bunch of results came back, but the first page did not contain a single blog written by a female software developer. At the bottom of the page I saw this:

Tip: These results do not include the word "female". Show results that include "female".

Which was kind of a weirdly ironic experience. So I plussed the term female, and still couldn't find what I was looking for. Mostly I found business news, articles pertaining to concerns about the lack of women in programming, and a bunch of job postings.

Well, I couldn't really complain. I am a female software engineer, and I don't blog about my work. I know why, too. I don't want to be harassed. And I don't want my employers or coworkers to know every detail about what I think.

But I'll give this a try, and attempt to be as anonymous as possible. Maybe in doing so, I'll find some gals out there who are blogging up a storm, so many that I can just nuke this blog and go back to lurking. Let's see.