11 August 2012

Moving Furniture: The Scrum Way

As a housewife, my wife
Wants the bed in one room swapped with the couch/futon/bed in another
So that  she can more comfortably sit and watch the Olympics on TV in the sunnier, warmer room.

With 3 programmers in the room, it was inevitable that we would choose an Agile approach to this requirement. The User Story above was our first step, and was duly agreed to by said wife as Accurately Describing What She Wanted and its Business Value.

Given the constraint that both rooms involved are too small to contain both pieces of furniture simultaneously, we realised that we would need a temporary variable as a swap space. I'm pretty sure that, barring some major advance in our understanding of Quantum Mechanics, pieces of furniture can't be swapped by being XOR'd through each other.

We broke the Story down into some Tasks:

  1. Remove the bed from Room 1 into the Swap Space.
  2. Remove the Futon from Room 2 into the Swap Space.
  3. Move the Futon Base (a finger-eating piece of folding woodworkery) from Room 2 into Room 1 and position it in its final position.
  4. Move the Futon from the Swap Space into Room 1 and position it on its Wooden Base.
  5. Move the bed base from the Swap Space into Room 2 and position it in its final position.
  6. Move the mattress from the Swap Space into Room 2 and place it on its base.

Seemed like a reasonable breakdown at the time. We did some estimations and figured we could fit it all into a single Sprint.

Here's how it played...

Task-1 went quite smoothly. Mattress and bed base moved to the Swap Space.
Task-2 also went well. Please bear in mind that the futon and mattress are large, floppy and heavy items, so not all that easy to move about.
Martin and I -- Pair Moving -- make an attempt at Task-3. Space is very constrained, so moving the Futon-base into Room 1 involves a brief detour into Room 3. Halfway there we suddenly realise that -- because the base is asymmetric -- we have to turn it around in the Swap Space before it can be Deployed into Production.
We complete Task-4, only to realise that we were entirely wrong about which way round the base has to go. We've moved it into the room the wrong way round. And the room is too small for us to turn it around short of Interesting Topological Manoeuvres.

So we back out again, via Room 3, back into the Swap Space where there is sufficient room to turn the base around.
Some discussion ensues. We realise that we should have had better Unit Tests in place for this Task. Finally we manage to complete the Task.
It's a tight fit, but the Futon/couch will serve our User perfectly as she wished.
Sadly there's an unforeseen bug. A small drawer unit now blocks the doorway, making for extremely poor UX. Not our problem, though. We've met our spec and implemented the Story. People will simply have to leap over the drawer-unit for the time being. Changes will have to be the subject of a subsequent Sprint.

Happily I can report that the rest of the Sprint went quite as anticipated. We were even able to implement a small Improvement Task by orienting the bed in Room 2 in a much more User Friendly fashion.

I do wish Furniture Topology was amenable to Version Control, though. It would have made our Task-4 issues a bit simpler to resolve. But then, perhaps we should have abandoned the Sprint at that point.

Still not quite sure how all the Scrum ceremony helped, though.

03 April 2012

JSP/JSTL: Versions and Standards

It baffles me. So many developers who use  infrastructure standards like servlets and JSP, but don't have any idea what versions of these they're coding to. They are blissfully unaware of whether they're targetting HTML4.01, XHTML-1 or HTML-5, CSS 2.1 or CSS 3, Servlet 3, 2.5 or 2.4...

Maybe I'm just funny that way - I think that managing dependencies in a tight, controlled way really matters! Otherwise things quickly spiral out of control, and you end up with that classic Design Pattern, "Big Ball of Mud".

On the other hand, I freely confess that I keep forgetting which pieces belong together. It's such a confusopoly.

So, mainly as a Note To Self, here's a quick lookup:

JSP/Servlet/JDK Versions

Servlets JSP JSTL Java EE Tomcat Min. JDK
3.02.21.2 57.x1.6
2.52.11.2 56.x1.5
2.42.01.1 1.45.5.x1.4

The list goes on, but if you still have systems in production running those archaic versions, you're probably in deeper trouble that mere version-confusion anyway!

06 February 2012

Work Wanted

This is a small call for help. I am looking for work, and need your help.

Contract or permanent. Preferably (but not exclusively or even at all) telecommute. I can code, design, architect software, consult in any of these (and dev process/team issues) and teach a variety of Java, OO Design and web development topics, and would be happy to do any/all of these. I additionally have some experience doing system administration work. I work in Linux/Unix environments and know next-to-nothing about Windows.

I've done web stuff, and loads of backend "heavy lifting" coding where reliability, scalability, etc. are important. I am not good at quick'n'dirty. Skeptical of the value of buzzwords and big-arse frameworks.

Check out my "business" website for more details about me and what I've done in the past.

R (as they say) "highly neg".

If you have anything suitable, or know of anything that fits, please drop me a line.

I will be in Cape Town and environs next week, so an ideal time to get together and chat about possibilities and opportunities.

11 November 2011

Android Nails Sandboxing

So I'm learning to programme the Android platform. Despite constantly typing it as "Androind" finding programming fun again after many years of regarding it as somewhere between tiresome drudgery and only mildly interesting in sporadic parts.

It's early days, yet, but I do think that Android's architects had one flash of brilliant insight: Using Unix user and group permissions to sandbox applications. Brilliant! We've had this mechanism since forever, and let's be honest, it's never been all that useful except in the very early years of Unix when we actually did have to put multiple users on a single computer. And even then, most users didn't understand it. Questions about umask and file permissions are among the commonest of Unix confusions I've run across for the past 25-odd years.

Warping the idea to mean that every application is a unique user is a flash of inspiration.

09 November 2011

QOTD


'the idea of immediate compilation and "unit tests" appeals to me only rarely, when I’m feeling my way in a totally unknown environment and need feedback about what works and what doesn’t. Otherwise, lots of time is wasted on activities that I simply never need to perform or even think about. Nothing needs to be "mocked up."'

Donald Knuth 25 April 2008

(Okay, so I'm late to the party. As always.)

06 August 2011

Design using Other Peoples' APIs

Where you are dependant upon somebody else's API, decouple from that API at the earliest possible opportunity so that the remainder of your system works in terms of your own abstractions rather than that somebody else's. This shields you from the random, spurious, and often unwarned changes they may make. It also enables you to place guards against the various stupidities they may likely perpetrate in the name of fashion or unthinkingness, and ensures that you are - as much as possible - forced to deal only with your own stupidities and unthinkingess.

This injunction includes decoupling from your own APIs where those are non-core to the subsystem under design.

05 June 2011

Housekeeping Note - Server Change

Explaining why I've been so quiet lately: Migrating data and upgrading the software that runs the blogs and farm site (plus a bunch of other stuff) to a new server.  Yay upgrade!  Boo problems!  Just in time, too, it would seem, since the old server started mysteriously and frequently rebooting for no good reason, so I'm pretty sure that its been down more than its been up for about ten days now. :-(

Sorry if its all been very dodgy.

If anybody notices anything noticably untoward, please let me know -- I think I've moved everything over successfully, but not yet 100% sure, but, with the old server dying, I just want everything off it as soon as possible, so haven't had time to test all my new configuration properly.

23 May 2011

Web Site Passwords

"Signing up" for yet another something-social-facebook-wannabe website, I was struck by a random Thought Particle.


Why do all these websites ask me to enter a password twice?

No, seriously! I know the stock answers. Hell, I've written such web-signup forms myself, more times than I care to think about.

Am I that likely to misspell a password? And who would care, when all I have to do is click a link that says something like, "I forgot my password!" to get a new password sent to me. Or a reminder. Or my original password. Or some other way of recovering from my "spelling error".

So, tell me again, why are we typing these things twice inthe first place?

11 May 2011

The Magic Key to Hiring Software Developers

Over the past several months and a half I seem to have run across a lot of Development Managers1 who repeatedly and quite consistently make poor-ranging-to-terrible hiring decisions about prospective developers.

One company I know about has had such terrible luck in hiring developers that they're looking at outsourcing all their development needs. And they're a software house! But you can hardly blame them for feeling demoralised and dispirited after numerous bad hires. Or can you...?

I recently met a programmer - let's call him Arthur2 - who was looking for some Java training. He has experience developing in C, and was looking for a basic Java foundation course, but he needs it to be spread out over evening and weekends. I found this to be admirable! A programmer investing in broadening his skills in his own time and at his own cost!

I don't normally take on that sort of part-time training, but decided to try and assist a fellow Seeker In Pursuit Of Excellence, and engaged Arthur further on ways we might be able to work together. Especially challenging, since I am not even within 500km of the same city as Arthur.

As the emails and telephone conversations flowed back and forth, I soon developed a sense the something was amiss. It took a while, but Arthur eventually told me that he needed the training "urgently and quickly". The penny dropped...

It took me back to a day some 8 or 10 months ago when, whilst helping a client with some recruitment interviews, I came across a candidate-programmer who clearly was unable to program at all. A fellow who allegedly held advanced degrees, and could certainly talk a good project, but who evaded and avoided any and all questions about actual programming. Asked anything about how he would design a programme for a variety of small and typical programming problems, he ducked and he dived, twisted, turned and blathered. Clearly he was unable to write code at all.

It is my working hypothesis that Arthus has talked his way into a Java development position, but is unable to code in Java. By his own admission he knows nothing of object-oriented design. I further conjecture that he may be unable to programme at all, and is not so much seeking a Teacher, but rather wants someone to whom he can effectively sub-contract his daytime work.

There are two mysteries wrapped up in these incidences.


How do such "developers" get hired in the first place?

Clearly the managers hiring them never, ever ask them to write code at any point in the recruitment process.

I have seen a good number of articles of late urging companies who are hiring software developers to make sure that candidates write code live, sometime during the interview process. Isn't this obvious? If you want to hire a bus driver, isn't it logical to put them behind the wheel of a bus and see how they handle the job? Why do we apply a different standard for testing the competence of software developers?

The actual form of code, and the depth of testing can vary, and need not be done all at once. You might simply ask for a whiteboard sketch of a solution in initial interviews. It may not always be necessary to sit candidates down with an IDE and some of your senior developers. Even the most superficial competence checking will quickly revela any bullshit artistry, and I firmly maintain that all people are possessed of exquisitely sensitive bullshit recognition skills.

In a sense, though - for me, anyway - there's a weirder question...


How does someone completely lacking competence in a skill have the chutzpah to talk their way into the job at all?

I can't imagine applying for a job as a Bus Driver. Sooner or later someone's going to expect me to actually drive an actual bus. And I can't. What makes people think they can get away with it just because the job ad says "Java Developer"?

Moral of the story? Just repeating what so many others have already said, in the hope that we can get the word out better. And we do have to get more hiring managers to pay attention, because evidently a whole lot of them are not paying attention yet. If you're hiring a developer, have them write code in front of you. If you really don't have the skills to judge their comptence, and you're starting with a completely new technology so that you lack any already-hired developers who do have the necessary technical skills, then get an outside consultant in to help. Or something.

But please stop hiring bullshit artists who claim to be software developers.


They're giving the rest of us a bad name.


Update: Also beware of technical Trainers who are unable to show you any of their code. Another smell of bullshit artistry!

[1] People acting in the role of Dev Manager, at any rate.
[2] I don't know anyone named Arthur, so I'm reasonably sure I'm not subconsciously picking on anyone.

20 April 2011

shrtn: A URL-shortener

Everyone should have their own personal URL shortener, shouldn't they?
I figured that this wouldn't take more than a couple of hours to write. And, indeed, the core functionality didn't take much more time than that. But then we start designing our way round the shortcuts and quick-and-dirty hacks we've used to "get things going quickly", writing unit-tests and comments explaining our thinking, adding some JSP pages so that we can exercise the whole mess, brewing a couple of batches of beer in between times... let's just leave it at a little bit longer!


Why?

Indeed! Why would anybody want Their Very Own Personal URL Shortener?


First: I don't really trust all the "cloudy" hype going around right now. For a start, I have no good reason to trust bit.ly, is.gd, goo.gl or any of the other several-dozen public shorteners. Not that I have much reason to distrust them, but really, I don't know them or the people behind them from a bar of soap. And why should I, like a sheep, participate in generating value[1] for someone who gives me little or nothing in return aside from a shorter, opaque URL that requires an extra network round-trip? And let's not forget that these entities have a nasty tendency to vanish, sometimes rather abruptly. Companies get bought and the acquiring company borgs the product, or sees no value in it, or any of a thousand other corpthink accidents may happen.

Then, too, what sort of assurance do I have that I'll ever be able to get my data (and if I shorten a reference, it's my reference) out of their service ever again? Granted that Google does make some effort in that direction (or at least nods benignly while their engineers do it), but, like the actions of the kakistocracy throughout history, things are only good until a single bad apple rots the barrel.


Second: I don't have PHP deployed on my servers and have no wish to add to the system-administration burden I already have to deal with, so I distinctly want something written in Java...


Third: A whole lot of the URL-shortening services out there don't give any analytics. At least not of those that I can self-host. I think that the analytics angle is compelling. Conventional web analytics - like Google Analytics - are only accessible to the people who created and host the content under analysis. They know where their audience came from, when and how, but nobody else does. If I refer people to some web-stuff[2] I'd like to get an idea of how many people I influenced - how many people followed my recommendation. It is a measure of my own reputation and influence, so highly personal[3]. URL-shorteners give us a way to measure, with a reasonable degree of accuracy and assurance, the influence we have in persuading others to follow our webby blatherings.

I will confess that Google's shortening service is pretty good, and has some nice-ish analytics, but I still think it's in our own best interest to keep at least some stuff out of Google's (or anybody's) mitts. Just on general principles.


An Unexpected Bonus

As it turns out, this is a really, really nice project to use for teaching a JSP/Servlet course, so I'll be reversing it into my Java web-dev course. It covers all the principles I like to get across, from container-managed security through session management and clever use of error-pages, to exploiting the underlying infrastructure properly (instead of hoping that some crapulatious web framework will substitute for your own lack of knowledge or understanding.)


Where?

I'll be releasing the code under the GNU Affero General Public License (probably via Google Code). Just have some tidying-up to do first (like getting license notices in place.) The first deployment is very feature incomplete - there's quite a bit I'd still like to add to the app - and some downright dodgy implementation details that need replacing in time, but for now its working for me.


Drop me a line if you're desperate to have it work for you and can't wait...

[1] At least I assume they get some value out of hosting their shorteners, otherwise why would they do it?
[2] I despise the word "content", despite using it quite frequently.
[3] And, YES, ego-gratifying[4].
[4] Or ego-destroying, as the case may be.

15 April 2011

SEO Fail

So. I've been working quite hard at getting course material together... mainly for OO Software Analysis Design courses and a Design Patterns course. The motivation comes from years and years of teaching Other Peoples Courses and experience a deep and abiding dissatisfaction with the material I am handed to work with. I strongly suspect that my students sense this...

Not Good!

So - after a very, very long time umming and aahing over it - I've put my own course materials together. Blatantly stealing tricks and tips from the HeadFirst books, plans include incorporating video and even music. Dare I say I've done a whole lot better than the usual run-of-the-mill courseware? Order of magnitude? But that would be presumptuous, wouldn't it?

Along the way I realised that I needed to pay a whole lot of attention to my (business) website. The old one sucked. Bad! Not at all descriptive of what I'm now doing or trying to achieve in the OO design and architecture space. So I spent a little time reading up on the website of that famous search engine about how best to structure my site and its content for searching. How to better market what it is I do. I read all about "not using Black Hat SEO" techniques. I paid strict attention to their advice! And I went forth and restructured... but only in a good way! What you see is what the googlebot gets. No tricks!

The result?

Falling from a page-rank of nearly fuck all, I now have a page rank of... zero. Thanks, Google! I guess I'll take my advertising business over to Microsoft, now.

I can only speculate what might have brought this on. Perhaps I got listed on some directory site that Google's software considers Bad News. That's the most likely thing I can think of... Or did I just use words like "software design and architecture" a time or two too many? Perhaps it was the word "Java"...

Unfortunately - like The Borg - there's no Human Person one can contact at Google to say, "Hey! I'm really a Person. What went wrong here and how do I fix it?" Pretty much I'm screwed. Where my site was ranking very well for searches on stuff like "software design training", "Java training"  and "software architecture course" last week, this week I'm nowhere to be seen. Instead you'll see listing from schmucks offering the same-old same-old. The same tired, half-hearted training crap that led me to start developing my own course material in the first place!

So what's a Real Human to do? I guess I'll just have to live with it. After all, my reputation amongst intelligent human beings is top-notch... not something I have to worry about. So do I need to get upset over how some software see me?

Probably not.

15 February 2011

Test-First for Mental Health

I've been thinking recently about how a Test-First approach to development is good for our emotional well-being and psychological balance, and I believe this may be the most important reason to adopt test-driven  development.

Consider how we would traditionally develop software using a conventional Test-Last approach. We read our requirement spec (whatever form that takes), perform some design work -- as much as we feel we need to go forward with some confidence, and we start cutting code. Time goes by. Our codebase grows. We're doing some informal testing as we go along to feel confident that the code under development does what we think it should be doing...

And here's Important Point Number One: "the code does what we (the developers!) think it should be doing". Not what the business thinks it ought to be doing. See? We're inherently unsure -- even if only subconsciously -- whether we're doing work that actually serves the business. And unsureness is insidious and destructive to our well-being. We feel much better about ourselves as developers when we know that we're producing useful stuff that really has value. So here's the first way that having tests defined up-front helps us preserve our mental balance: With a reasonable set of tests1, defined together with our business partners, there's no bullshit involved; no trying to convince ourselves of the (probably shaky) value of our ever-growing codebase. We have an external, automated, objective, easily understood yardstick of value.

But there is, I think, a deeper psychological value to the Test-First approach.

So much of the time -- I will thumbsuck something like 99% of the time -- our code is broken. The system we're working on doesn't work. This is inherent in the fact that it takes us time to design and write software, and the continual not-workingness can be powerfully demoralising. Especially when we (finally, right towards the end of the project lifecycle) start formal testing, and our tester (often users) start coming back with bug after bug after bug after bug, and all that beautiful code we're so proud of is labelled "Less Than Satisfactory" -- usually in much stronger language than that.

Herein lies the secret destructiveness of Test-Last. Our code is always broken, and we can never do more than run after the brokenness trying to patch it up, until, at last, demoralised and exhausted, we move on to the next job or project.

Contrast this with a Test-First pattern.

We first write a bunch of tests. Sure it takes some time, can often be pretty tedious, and is frequently little more than a first-pass best-guess at what the code is supposed to do. Almost certainly we will add more tests as our code grows and evolves and begins to tell us the shape it wants and needs to be. But at least we start with a battery of (automated!) tests. And we start with the expectation of them all failing. This is by definition! We haven't written the necessary code, yet. A short time later we may have enough of the boilerplate in place that we can at least compile everything and actually run our tests, but we still expect them all to fail because our methods all read

throw new UnsupportedOperationExcetion( "TODO" );

So we run our tests, and they all fail. And we're happy about that! Everything went as we predicted. We feel in control.

As we go along replacing those stubbed-out methods, some of our tests begin to go green. We're making visible progress towards a well-defined end goal. We gain an ever-increasing feeling of confidence and accomplishment. We have tangible, objective evidence that we're making progress. Even when we make some of the "test bar" revert somewhat to red -- because we add new tests, or because we do some large-scale refactoring that breaks stuff -- we still feel good about it, because we know that our self-built safety-net is working! We've actually decreased the likelihood of things going wrong, so we know we're enhancing the quality of our product. (And every good developer I've ever worked with has an inner Proud Craftsman lurking in their soul.)

So it seems to me that Test-First builds our confidence and self-esteem as we go along, whereas Test-Last contains an inherently destructive, soul-sapping subversiveness to it.

I think this value outweighs the sum of all the other benefits (many though they are) of Test-First.

[1] Note that I make no distinction, here, between Unit Tests, Functional Tests, or System Tests (which would probably involve real databases, external systems, and so forth, albeit serving test data to our system-under-test.) I don't really care what form of Test-First is most useful to your team and situation. It's the principle that counts!

08 February 2011

Fusion Cuisine: Slicing and Dicing Courses to Suit Different Palates

Ever been faced with setting up training for some of your developers, but the courses offered by the usual suspects fail to cover the technologies your team uses? Or cover technologies that you don't use? Or lack the depth you're looking for in particular areas? Or too much depth...?

I was recently faced with a request from a client who want to put some of their junior developers through an Intro to Java course. The developers in question come from various other programming backgrounds, and already understand OO concepts and normal development disciplines. The "obvious" choice is the Sun/Oracle SL-275 mainstay course which I have been teaching (on and off) for something like 15 years, now.


But! A good part of SL-275 – and of my own Intro to Java course – delves into developing applications using the Swing GUI toolkit, used to construct desktop applications. This particular client is a company that only does web-applications, so learning a bunch of Swing concepts does them little good. I was happily able to propose that, instead of using Swing for that portion of the course, we could substitute some Servlet and JSP concepts and development. This arrangement serves them much better, as it also equips their developers with knowledge they will be able to immediately put to productive use. Fortunately I have lately put in a lot of work on a Servlet/JSP course, so I'm able to cycle some of that material into the Java Intro course.


It's not as simple as it sounds, though!

The Swing portion of "Intro to Java" also serves some other pedagogic purposes. It reinforces some of the OO groundwork covered earlier in the course by driving home the differences between inheritance, containment and usage. (At least it does the way I teach it!) Swing also provides a good platform for introducing listeners (Observer Pattern in the GoF book), Java's anonymous-inner class mechanism, and the exception-handling framework, along with a bunch of other bits-and-pieces that are useful for new-to-Java developers to learn, like converting between Strings and numbers.

So the challenge, now, is to make sure that I can adequately cover the same territory, and serve the same purposes, using servlets and JSPs. Not too hard, really, but it should make for a fun course where we can do a lot more hands-on, practical development work than the stock SL-275 allows.

The other tricky bit to watch is making sure that the level of detail doesn't overwhelm new-to-Java developers with too many web-application specifics. It is important to keep the focus on "Introduction to Java", and not lose sight of the real objective in a welter of webapp configuration and deployment.

Just a single, simple example of where and when customised courses can much better match the client's needs than any standardised, templatised training provided by a 4-week-per-month manual-pusher.
Contact me for a course customised to your organisation's needs!

18 January 2011

2011 Course Planning

Whew! Looks like March is going to be a busy month. I've planned no less than 3 courses back to back, so hard work ahead...

I'll be kicking off with the 5-day "Intro to Java" course on 7-11 March. It seems like Cape Town's demand for Java developers is insatiable. I've had requests from a couple of clients for this course simply because they just can't find good Java devs for their expanding teams, and they're going to be hiring developers with good OO experience from other (non-Java) environments and training them up for Java development as an alternative. Now, I know that any good developers loves learning new stuff, so I think these clients are doing a Good Thing by offering skills-development as part of their hiring process. My job is to give them the best possible Java Platform course, and I have great plans for delivering just that!

Next up will be the newly developed 5-day "Web Application Development with Servlets and JSP". If you've last looked at JSP technology a few years ago, possibly run away in terror at the sight of all the horrible in-page logic that made scriptlet-based JSPs such a nightmare for maintenance, then you really owe it to yourself to get up to speed with scriptlet-free, tag-based JSP development. The course includes topics on the new, new Servlet-3.0/JSP-2.2 enhancements that use annotation-based configuration.

And last, but not least, will be my much-acclaimed 4-day "OO Analysis and Design" course – thus fitting neatly into the 4 working days that remain after the Human Rights Day public-holiday.

I'm planning to run all the courses in Cape Town. (still looking for a great venue, so please drop me a line of you know of something extraordinary.)

Drop me a line if you're interested in any of these. Miss this opportunity at your own risk – I will probably not be scheduling courses in Cape Town again before August!

I'm offering an Early Bird discount of 20% to anybody who confirms a reservation before the end of January!

07 December 2010

Amazon Route 53: Trustworthy?

As a "user" of Amazon's Web Services (I've kicked the tyres on S3, but not much more than that) I received an email from Amazon punting their new DNS service, dubbed "Amazon Route 53".

I wonder though, in the wake of their termination of WikiLeaks, whether I would trust any part of my DNS infrastructure to Amazon. Suppose I did something to piss off the US governement - hosted a DNS entry for WikiLeaks, perhaps? at, say, http://wikileaks.mikro2nd.net/ - and some US government official notices (pretty unlikely, I know, but...) and whispers into Amazon's ear, would I, too, lose use of this critical infrastructure without review, recourse or refund?

So, no! I don't think I'll be using Amazon Route 53 much...

18 October 2010

HTTP Response codes & msgs as Java enum

Just in case it saves someone else the tedious typing... Capitalisation of messages duplicates the inconsistencies in RFC2616. Don't ask me...

    public enum HttpResponse {
        HTTP_100( 100, "HTTP/1.0 100 Continue\r\n\r\n" ),
        HTTP_101( 101, "HTTP/1.0 101 Switching Protocols\r\n\r\n" ),
        HTTP_200( 200, "HTTP/1.0 200 OK\r\n\r\n" ),
        HTTP_201( 201, "HTTP/1.0 201 Created\r\n\r\n" ),
        HTTP_202( 202, "HTTP/1.0 202 Accepted\r\n\r\n" ),
        HTTP_203( 203, "HTTP/1.0 203 Non-Authoritative Information\r\n\r\n" ),
        HTTP_204( 204, "HTTP/1.0 204 No Content\r\n\r\n" ),
        HTTP_205( 205, "HTTP/1.0 205 Reset Content\r\n\r\n" ),
        HTTP_206( 206, "HTTP/1.0 206 Partial Content\r\n\r\n" ),
        HTTP_300( 300, "HTTP/1.0 300 Multiple Choices\r\n\r\n" ),
        HTTP_301( 301, "HTTP/1.0 301 Moved Permanently\r\n\r\n" ),
        HTTP_302( 302, "HTTP/1.0 302 Found\r\n\r\n" ),
        HTTP_303( 303, "HTTP/1.0 303 See Other\r\n\r\n" ),
        HTTP_304( 304, "HTTP/1.0 304 Not Modified\r\n\r\n" ),
        HTTP_305( 305, "HTTP/1.0 305 Use Proxy\r\n\r\n" ),
        HTTP_307( 307, "HTTP/1.0 307 Temporary Redirect\r\n\r\n" ),
        HTTP_400( 400, "HTTP/1.0 400 Bad Request\r\n\r\n" ),
        HTTP_401( 401, "HTTP/1.0 401 Unauthorized\r\n\r\n" ),
        HTTP_402( 402, "HTTP/1.0 402 Payment Required\r\n\r\n" ),
        HTTP_403( 403, "HTTP/1.0 403 Forbidden\r\n\r\n" ),
        HTTP_404( 404, "HTTP/1.0 404 Not Found\r\n\r\n" ),
        HTTP_405( 405, "HTTP/1.0 405 Method Not Allowed\r\n\r\n" ),
        HTTP_406( 406, "HTTP/1.0 406 Not Acceptable\r\n\r\n" ),
        HTTP_407( 407, "HTTP/1.0 407 Proxy Authentication Required\r\n\r\n" ),
        HTTP_408( 408, "HTTP/1.0 408 Request Time-out\r\n\r\n" ),
        HTTP_409( 409, "HTTP/1.0 409 Conflict\r\n\r\n" ),
        HTTP_410( 410, "HTTP/1.0 410 Gone\r\n\r\n" ),
        HTTP_411( 411, "HTTP/1.0 411 Length Required\r\n\r\n" ),
        HTTP_412( 412, "HTTP/1.0 412 Precondition Failed\r\n\r\n" ),
        HTTP_413( 413, "HTTP/1.0 413 Request Entity Too Large\r\n\r\n" ),
        HTTP_414( 414, "HTTP/1.0 414 Request-URI Too Large\r\n\r\n" ),
        HTTP_415( 415, "HTTP/1.0 415 Unsupported Media Type\r\n\r\n" ),
        HTTP_416( 416, "HTTP/1.0 416 Requested range not satisfiable\r\n\r\n" ),
        HTTP_417( 417, "HTTP/1.0 417 Expectation Failed\r\n\r\n" ),
        HTTP_500( 500, "HTTP/1.0 500 Internal Server Error\r\n\r\n" ),
        HTTP_501( 501, "HTTP/1.0 501 Not Implemented\r\n\r\n" ),
        HTTP_502( 502, "HTTP/1.0 502 Bad Gateway\r\n\r\n" ),
        HTTP_503( 503, "HTTP/1.0 503 Service Unavailable\r\n\r\n" ),
        HTTP_504( 504, "HTTP/1.0 504 Gateway Time-out\r\n\r\n" ),
        HTTP_505( 505, "HTTP/1.0 505 HTTP Version not supported\r\n\r\n" );

        private final int intValue;
        private final String msg;

        private HttpResponse( int intValue, final String msg ){
            this.intValue = intValue;
            this.msg = msg;
        }

        public int intValue(){
            return intValue;
        }

        public String responseString(){
            return msg;
        }

        public static HttpResponse forResponseCode( int responseCode ){
            for( HttpResponse v : values() ){
                if( responseCode == v.intValue() ) return v;
            }
            throw new IllegalArgumentException();
        }
    }

13 October 2010

A Lesson from Vegetable Gardening for Hiring (and Keeping) Better Software Developers

Right now I'm in the midst of Busy Season in the Veggie Garden: Spring Planting Time. Even busier than harvest time. You see, you can almost always delay a harvest by a few days or a week without serious consequences. But you can't delay sowing seed without reaping serious consequences 4 to 6 months down the line. Veggie gardening is all about strategy.

Just the other day I heard about a successful and growing Cape Town company planning a hiring spree for Java developers. They'll be looking for quite a number of Java developers at all skill and experience levels.

But they face two key problems:
  1. There is an extreme scarcity of Java developers at any and all levels in Cape Town and surrounds.
  2. They'll be competing against a very large number of other employers looking for large numbers of Java developers. I have, over the past couple of months, heard of numerous companies searching for 10, 12 and more "skilled Java developers".
If you're in Cape Town you can probably take a reasonably accurate guess as to who those companies are. And they're not finding any developers, are they. Let alone really excellent developers...

This is great news for Java devs: Salaries are pretty competitive, even if not quite up to Jo'burg levels just yet.

Hell for employers, though.

Strategy is about Time

My main problem this Planting Season is that I don't have any compost for the garden. The key to making great compost is adding plenty of water, and the key to great veggie crops is building the soil by adding compost, year after year after year. But we're (still) in a drought, so no water. Successful crops are going to be a serious challenge this Summer...

CEOs, CTOs and Development Managers who get it know that investing in their developers' skills, knowledge and experience is investing in their own success and the success of their business. And the secret is that it can't be done overnight. It takes long-term commitment to helping their developers build their skills. And intelligent developers reward real, honest commitment to skills- and career-development with loyalty.

And developers talk to each other. In their mailing lists and user-group meetings, on Facebook and Twitter, word-of-mouth ensures that developers have a pretty good idea of who is doing the interesting software, who is providing a stimulating development environment. In short, who the good employers are. (Especially in Cape Town! The software world in CT really is a very small village.)

Compost making and soil-building is a strategic practise for farmers and gardeners everywhere, whether they are organic growers (like me) or not, soil-building is of vital strategic importance. Without healthy soil we have nothing.

Likewise, CEOs, CTOs and Dev Managers of companies for whom software development is a strategic business activity have a vital interest in developing their developers.

Planning to Hire Developers Any Time Soon?

If you are planning to attempt to hire developers (particularly Java developers; particularly in or around Cape Town) within the next 6 months, ask yourself the following 3 questions:
  1. How are you going to source the best and brightest devs when they're almost unreachable at any price?
  2. How are you going to make your company more attractive to those devs than all the competition you face?
  3. How are you going to keep developers from job-hopping when they get that email from a competing employer or headhunter offering them a huge raise?
If you have good answers to all of those, then please don't call me!

If you'd like help creating fertile ground for interesting minds who can help drive your software development to greater successes, call me.


05 October 2010

Duck Typing Developer Styles: 4 Ducks

Developers can be categorised along two orthogonal dimensions: coding-skills and design-skills. This post explains how to locate a developer according to this scheme, and describes how best to manage each development-style.


Tame Ducks are easy to manage, get on with the job, etc. They produce decent working code, but won't come up with the most innovative solutions. Great maintenance coders.

Wild Ducks are your innovators who will break new ground, but it's hard to get them to follow rules, comply with standards, etc. Give them the tough stuff to code.

Lame Ducks: deal with a Lame Duck by making Duck Sandwich. Sandwich the Lame Duck between a Wild Duck and a Tame Duck. They will either learn and gain competence, so becoming a Tame Duck in time, or they will Ship Out through fear of revealing their lack of knowledge.

QUACKS: talk a good project; strong tendency to bullshit their way through design by resorting to TLAs like SOA. XML and xDD. Deal with them by - again - making Duck Sandwich. The Wild Duck has exquisitely sensitive bullshit-detection capacity which, combined with their cultivated lack of tact and intolerance for freeloaders, will leave the Quack with no place to hide. The Tame Duck is there to back up the Wild Duck's assertions as to the Quack's actual performance. The Quack will almost certainly soon move on.

(Where do I fit in? ;-)

Credit: I first heard this Duck-Typing Scheme from an important mentor in my career, Nat Lunn, sometime around 1990, and so I must credit the whole story to him. Thanks, Nat!

13 September 2010

Setting up a PPTP VPN with KDE NetworkManager

Filed under "Notes to Myself". If this helps someone else out there, Good!

The problem: to VPN into a closed Microsoft-dominated network.

After 6 weeks of hacking at it, the client's network administrator finally managed to get the VPN set up on their office server (some version of Windows is involved, so no wonder it is an opaque and difficult process taking weeks and involving numerous reboots. I am frequently moved to wonder whether people actually enjoy the pain that results from using Microsoft software... I can't think of any other reason to use it.)

So it helps to have the admin tell you:
  • the gateway address for the VPN
  • your username and password
More importantly for a n00b to VPNs (i.e. me) it help to get told that
  • the VPN protocol is PPTP (MS proprietary AFAICT) and
  • that it requires some (MS peculiar) encrytion scheme (MPPE) to be used.
Surprise, surprise! Only took a day to figure these things out.

The rest of the trouble comes from Kubuntu Linux insisting on using the fucked-up awful NetworkManager. I could not find reliable/working information on setting up the correct config by hand, so was forced to rely on NM. Also tried Kvpnc, but could not make it work for the client network configuration.

NM insists on setting the default route for all network traffic to be via the VPN client network. Not what I want. I need on-going access to my own local network resources as well as the VPN resources (as well as my own internet connection) as I am developing stuff that relies on local resources to work. After starting the VPN, my machine's routing table looks like

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
41.133.194.199  192.168.1.254   255.255.255.255 UGH   0      0        0 eth0
41.133.194.199  192.168.1.254   255.255.255.255 UGH   0      0        0 eth0
192.168.0.23    0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
192.168.1.0     0.0.0.0         255.255.255.0   U     1      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0
0.0.0.0         0.0.0.0         0.0.0.0         U     0      0        0 ppp0
(192.168.1.0/24 is my own local net; 192.168.0.0/24 is the client's network.)

Note that last line. There's the troublemaker. I don't want all traffic routed to the VPN by default. I tried every possible combination of settings in the KNetworkManager applet, especially those that claim to prevent the VPN from overriding the automatic routing. I tried manually setting all the VPN info (IP address, netmasks, etc.) but that fails to work either.

Ultimately I resorted to a workaround. Accept the crappy routing that NM sets up for me, then fiddle with the routing tables by hand:
$ sudo route del -net 0.0.0.0 ppp0
$ sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.1.254 dev eth0
These 2 lines get me a sensible default route outta here, and
$ sudo route add -net 192.168.0.0 netmask 255.255.255.0 dev ppp0
gets me a route to all the client-network resources (albeit without any DNS lookups for their subdomain; this I can live without, since there are only a small handful of machines I need access to.)

The resulting routing table:
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
41.133.194.199  192.168.1.254   255.255.255.255 UGH   0      0        0 eth0
41.133.194.199  192.168.1.254   255.255.255.255 UGH   0      0        0 eth0
192.168.0.23    0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
192.168.1.0     0.0.0.0         255.255.255.0   U     1      0        0 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 ppp0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 eth0

Can't say it's pretty, but it works.

03 August 2010

Measuring Progress in Software Development

Background

I am about to take on the leadership of a new, still-in-formation developer team, on a project - the first of several - of critical importance to the client. This means that everything is up for negotiation: team structure, development methodology, coding styles, frameworks to be used,... everything!

Initially my role was confined to that of Consulting Architect, but, by force of circumstance, has evolved to Architect and Team Leader pro tem for a few months while the client gets their dev team properly resourced and settled-in. Naturally I'm trying to help that along as best I can.

Methodology

The client initially planned to use a BDUF (Big Design Up Front), waterfall approach to the project. The requirement is extremely well-known and quantified, in a very well understood business domain.

I have never believed in my tummy that BDUF is in any sense realistically or practically achievable, though, even long before the Agile Movement tore the idea to shreds. It is impossible to foresee every detailed design element, no matter how hard you work at it. On the other hand, some Agile proponents seem to say that no up-front design is necessary... Perhaps my hearing is playing tricks with me. I cannot agree with them, either.

So call me a proponent of SDUF: Some Design Up Front.

And on the Process front, I don't think there's a lot to argue about when we contrast a waterfall/sequential process with an agile/incremental process. For me the critical difference lies in how we report and feed-back progress and how frequently we do this. And what we do about the feedback we receive - how flexibly we accommodate direction changes from customers, business sponsors, unit-tests,... to change the still-in-the-pipeline development and requirements without completely trashing the budget and time-to-market constraints. An also-essential aspect of agile development is "to reflect on what has gone before, and to adjust what we do to make
things better." [Ron Jeffries]

Waterfall possibly still does have a place in some circumstances. I can't honestly say that I've ever actually been party to such circumstances, though I've certainly been on projects where some of our business partners thought they needed hard, contractual milestones with no going back. (In reality we always "went back" anyway, when necessary, after some amount of renegotiation.)

Metrics

A very greenfield situation, this, which some people would immediately call a "wonderful opportunity", but which I very much see as a "two-edged weapon"...

The question that has been most on my mind is, "What should we measure?"

I am a very firm believer in the old saw, "Tell me how you Measure me, and I'll tell you how I Behave."

Measure a sales-person by the number of sales, and you'll get a high order volume of the easiest-to-sell products, regardless of whether they represent the best margins or quality-of-business for the company. Measure the same sales-person by margin-value of product, and you'd best hope that your high-margin products are ones that lots of people want to buy. Measure them by the number of sales calls they make and you'll have lots of calls that don't result in sales.

Here is where I believe that some Scrum proponents are going wrong... We take Features and break them up into Tasks - the developers' unit-of-work. And they measure Task completions using a burn-down chart of Tasks completed versus time. This can easily result in a situation where many Tasks are being completed, but not so many Features. A situation where Features reach an 80%-complete state, and then get stuck, for any of a variety of reasons, all of which amount to "Nobody wants to complete those Tasks" because they're boring,... or they're "just" test Tasks,... or they're difficult (because not well understood), or...

The solution is really simple. Just measure Feature completion instead of Task completion. Then the team only gets rewarded when Features or User Stories get completed. We only get beer and Pizza when the Business gets value.

But is this enough? Can we go further? Is there a way to tie developer reward directly to delivered Business Value?

In the situation I'm headed into, Business Value should be pretty easy to quantify: The product to be built is one that will directly generate revenue for the company, so we can very easily quantify how much Business Value the software is generating. (Successful completion of the product will also deliver a huge  strategic Business Value by enabling new revenue streams, but that's also quite easy to quantify, and, indeed, is the prime reason the client is taking on this quite substantial investment in the first place...)

Are there ways to close the loop? To feed-back to the dev team on how much business-value their efforts are generating without making money too much of an up-front issue? Then, too, I have a reservation: Developers can have notoriously short memories, and the sort of value we're talking about here is only delivered on longer time-scales... Maybe it's good to have both long-time-loop feedbacks as long as we also have the short-timespan feedback in place as well... Waterfall's failures are largely a result of too little feedback taking too much time for us to correct project course when we need to.

My instinct is that moving towards a continuous deployment process (the step beyond continuous integration) might help to shorten this feedback loop, which is completely the point of "agile" thinking, but I'm still not really clear on how we might implement it.

29 July 2010

Refresher Training is Good, Too!

Some while ago I was teaching a course -- Java Web Application Programming, as it happens --  to a group of quite-experienced web developers working in a large corporate environment. Needless to say, we all thought that this was yet another case of the Training Department getting their act together waaaay too late...

We soon discovered, however, that some of the core concepts and technologies of Java Web Application development were, at best, only poorly understood, even by the most experienced developers in the group. Many of the details of the HTTP protocol were unknown to them, as was the development of custom Tag Libraries -- a key component for developing clean, maintainable Java Web applications without in-page scripting. They had not thought much about the consequences of placing large (multi-megabyte) objects in the application Session... (this is in a clustered web-container environment!)

This is not a criticism of those developers! They had, for years, been delivering absolutely critical business functionality. This is merely an observation that technologies move on; sometimes developers need a little help to catch up, since their management usually neglects to allow time for self-study catch-up on new evolutions in the technology.

More important, it is an observation that Development Managers, Team Leaders and Project Managers shouldn't assume that their developers are completely up-to-date on the technologies they're using for day-to-day development.

Replicated from http://coco.co.za/wiki/KeyTechnologyTrainingStory

21 June 2010

Nedbank Service Fail


<span style="font-style: italic;">Rant ahead. Feel free to leave now.<br /><br />No, really! This is just whining in public about the unbelievably crapulatious service Nedbank dishes out to its customers.</span><br /><br />A service I recurringly buy, and have repeatedly bought for... oh, probably more than 5 years, now... using the self-same <span style="font-weight: bold;">Nedbank</span> credit-card... came up for renewal yesterday. Mysteriously the transaction failed, so the vendor sent me an email to let me know. Very odd! As I say, it has worked fine for years. The card has not expired - the only reason transactions have failed before now.<br /><br />Oh well, off to pay the invoice manually. Using the same card, naturally. (It's the Business card, you see, so simpler for tax and accounting than using a personal card.)<br /><br />Next thing, I find my browser redirected to some foreign website "bankserv.co.za" for "verification". <span style="font-style: italic;">Oh yeah?!</span> There's a crappy, pixelated copy of a Nedbank logo at the top. <span style="font-style: italic;">That sure looks convincing!</span> And they're asking me for all sorts of account details, including my CVV number, ID number, and some arbitrary and mysterious field labeled only "Personal".<br /><br /><span style="font-style: italic;">What sort of phishing operation is this?</span><br /><br />Actually it turns out to be an alleged "Fraud Prevention" thing called 3-D Secure. I've only heard of it because I know people who have had the pain of implementing payment solutions that use it.<br /><ul><li><span style="font-weight: bold;">Question</span>: Why did Nedbank not <span style="font-style: italic;">bother</span> to communicate to their customers that they would be requiring this much-changed payment process?</li><li><span style="font-weight: bold;">Question</span>: Why do Nedbank not do it on <span style="font-style: italic;">their own website</span>, instead sending me to some website who's identity is a complete unknown to me?</li><li><span style="font-weight: bold;">Question</span>: Is this not the most incredibly stupid thing to do in a web where phishing and identity theft is rife?</li></ul>Later, a call to Nedbank's unbelievably crappy customer "service" centre illuminated a whole lot of these details. The bottom line is that:<br /><ol><li>Nedbank <span style="font-style: italic;">absolutely require</span> us to use this 3-D Secure thingie.</li><li>The shitty 3-D "secure" thingie absolutely requires that I enter my cellphone number to complete their process. Unfortunately, where I live, cellphone reception simply does not exist, so <span style="font-style: italic;">not an option</span>.<br /></li><li>So: I have no way to complete their crappy process, and</li><li>Nedbank has no other process.</li></ol><span style="font-weight: bold;">Fail!</span><br /><br />The 3-D Secure form did not even have a field labeled "Cellphone number". How is anyone supposed to guess at this?<br /><br />Then, too, there is no way to opt out. They claim that the 3-D Secure process is to "verify my
identity". This despite the fact that they have all my FICA docs on
record. They have my other business account details on record (because
that's how they get paid every month) and they manage to successfully
send me statements every month, and a new card every couple of years.<br /><br />And the process <span style="font-style: italic;">absolutely requires</span> that I be reachable by cellphone. What if I don't have or want one? What if I have one but can't get reception? Has anybody pointed out to the shit-heads at Nedbank that <span style="font-weight: bold;">SMS is not a secure nor reliable channel of communication</span>?<br /><br /><ul><li><span style="font-weight: bold;">Question</span>: Why would I <span style="font-style: italic;">jump through all these hoops</span>, put up with really shitty service and all this pain from Nedbank when Standard Bank (my other, other bank) have been trying to give me a business credit-card for years, only to be turned down (because why would I want <span style="font-style: italic;">another</span> credit card?)</li><li><span style="font-weight: bold;">Question</span>: <span style="font-style: italic;">How quickly can I close this Nedbank account?</span></li><li><span style="font-weight: bold;">Question</span>: Did anybody at Nedbank <span style="font-style: italic;">bother to turn their brains on</span> when thinking about this process, or were they - as usual - operating with their heads stuck so far up their own arse that they could see out their own throat?</li></ul><br />Oh! I paid the invoice using my personal credit-card (Standard Bank.) Payment went through flawlessly, painlessly and instantly with no hoops to jump through.

09 June 2010

About Email

A short note on How I Handle Email communication.

Lately I've had a few people express their unease over my handling of emails, so I thought I'd write - once and for all - about how I deal with email. One of these was phoning me, worried, because I had not responded to her email within 15 minutes of her sending it. Another was complaining because emails I have sent him have never appeared in his inbox. It turned out that his ESP (email service provider) was having a Bad-Config Day.

Please remember that it is eMail. Not eInstantAnswer. Not eGuaranteedDelivery. Not eRegisteredMail. And humble though it is, I find it (still!) indispensable.

Share and Enjoy!
Related Posts Plugin for WordPress, Blogger...