daddy, bring the mojo back

Posted by anton
on Sunday, February 24, 2008

i noticed an interesting phenomenon – when talking to a few recent grads or those that are about to graduate, i realized that a lot of the smarter ones are disillusioned about programming.

i find it interesting, because i went through the same transition. having done some pretty cool practical stuff at school, i got quickly bored at my first job, thinking that there was not much new and interesting stuff for me to do.

at one point i recall flipping through the Pragmatic Programmer book right after it came out and dismissing it as something that was too obvious to pay attention to.

i view it as a key telling sign now. this was my own attitude at the time, and i see it again and again in new hires fresh out of college.

being a smart kid, you (perhaps subconsciously) try to assert your own superiority, and perhaps being somewhat defensive, you are all too quick to nod in agreement and move on the moment you think you grasped something.

it turns out that when i go back and re-read some of the books i thought were full of obvious stuff, i discover something that i have learned much later through my own mistakes.

maybe this is the cursed fate of these books – you either read them when it is too late and you wish you read them earlier, or you read them too early and you wonder what all the fuss is about.

what i personally found helpful in this case was the “beginner’s mind” stance – embrace the fact that you know nothing; be humble and view everything that comes your way as a learning opportunity.

which brings me to an opposite learning dysfunction. my first year of university had cryptography, compiler theory, computer languages, two semesters of discrete math, data structures and algorithms, theory of computation, etc, etc (and this was just the CS stuff). it was simply too much for my little brain, so i employed FIFO / LRU eviction approach – without practical application these concepts were promptly forgotten after i passed the exams.

only years later i painfully learned that all of that stuff was actually relevant and important and used in practice. i went back to grad school to patch up the fundamentals and re-learn all of it again at my own pace.

this time around, having done practical stuff, and having established a much broader picture of the CS field, i could finally see how it all connected, and how this knowledge was used in practice.

maybe all of the above is irrelevant to everyone else and could be attributed to my own learning disabilities. however, having worked in corporate IT for past 10+ years, i think there are lessons to be learned for everyone, since those that come out of school have to spend their first year or two learning on the job.

most schools teach computer science which is not the same thing as software engineering. the problem is that the industry needs more software engineers – those that can build everyday quality software and make sure it runs and actually does what the business wants it to do.

sometimes the stuff that you learn in school is directly counterproductive – you work alone and get your own grade; most of the time your work is over once a particular problem or concept is implemented; no one evaluates the quality of design, no one cares whether your stuff is maintainable, or uses version control, or has repeatable builds, etc.

it is up to organizations to make sure that new hires get trained – a mentor/buddy, a stack of books, a pile of wiki entries to get started. it is an investment that requires time and management support.

as for the new hire – be a professional in your field, strive to join the 5% and have fun doing it. otherwise you will be one of those 9 to 5 folks cracking “it is case of mondays” jokes and doing the same thing year after year (well, maybe not, but this is my own personal hell scenario). the field is changing so fast, that you have to keep learning to stay relevant. think of it as climbing the escalator that is going down – the moment you stop climbing, you are falling behind.

there is so much cool stuff out there that is IT-related, and each year it is only getting more interesting. what we need right now is more good engineers with business aptitude to bring in a much needed rigor and professionalism to the field of business software. there is a lot of stuff to do, and hopefully we’ll be able to communicate it to the newcomers.

JUnit Joys

Posted by anton
on Thursday, January 31, 2008

i have been wrestling with some legacy code recently. beating it over the head with a copy of Working Effectively with Legacy Code did not do much, so i started writing tests to see how it worked.

after a few minutes of waiting for eclipse + junit4.3.11 combo to load, i furiously coded a bunch of tests, and then realized that i could not make them fail. essentially it boiled down to the following:

assertEquals(1.0, 1.1);

...which quietly and happily passes. wtf?!! these are two doubles, just compare them and let’s move on with our lives!

then after a bit of thinking i recalled that most of my tests that involved doubles were written on projects that were still on jdk < 1.5, when method above simply won’t even compile, alerting me to the fact that junit expects assertEquals(double, double, delta), where delta is the precision you need.

why they couldn’t simplify my life by creating a couple of Double instances and calling equals() on them is beyond me. this is what i would want most of the time anyway.

since i was running tests under jdk1.5, autoboxing kicked in and now we have two Doubles on our hands. fine, this should not be a big deal, simply call double1.equals(double2) and be done with it – what’s a big deal?

but nooooooooo, check out this little bundle of joy:

private static boolean isEquals(Object expected, Object actual) {
    if (expected instanceof Number && actual instanceof Number)
        return ((Number) expected).longValue() == ((Number) actual).longValue();
    return expected.equals(actual);
}

what the hell?!! you correctly detect that this instance of Double is an instance of Numeric, then take its long value and throw fractional part out. quietly. so all my tests never even squeak. why?!!!

an obvious approach is to suck it up and appease the api:

assertEquals(1.0, 1.1, 0);

this will work. but damn! my eyes!!

TestNG

we all know that junit is legacy, and version 4 was an afterthought, so let’s see what testng does. the api is the same, and under jdk1.5 my primitives get autoboxed into Doubles and assertEquals(Object, Object) gets called:

public static void assertEquals(Object actual, Object expected, String message) {
    if (expected == null && actual == null)
        return;
    if (expected != null && expected.equals(actual)) {
        return;
    } else {
        failNotEquals(actual, expected, message);
        return;
    }
}

voila! this is exactly what i expected. and guess what – it actually works and correctly fails the original test.

Lessons

  • man, this alone would scare me away from junit in favor of testng
  • make sure your test fails before it ever works!
  • what really frightens me is how many more of these quiet autoboxing errors are lurking out there. what previously would be caught by the compiler now silently works in unpredictable ways
  • yet another thing to be aware of when upgrading your app from jdk1.[34] to jdk1.5+

Note

this junit bug has been fixed in junit4.4 and up

Ruby

interestingly enough, on a few skunk works projects this year i cobbled together a bunch of existing libraries with ruby glue and used (j)ruby’s Test::Unit (which conveniently comes with ruby distro) and rspec for testing the result.

it definitely makes sense for a project that is written in (j)ruby that uses many existing java libraries; it might be a bit of a mindset shift for a java project that is looking for simplified testing. for now i am keeping an eye on projects like JtestR

1 default version of junit that ships with eclipse 3.3