Happenings

Film Fight 2012: July

Yes, it’s a bit late, but I’ve finally written the Film Fight for July, including no fewer than 5 films…

First up, Killer Joe is the story of a murderer for hire that starts to go very wrong when payment becomes an issue. It’s full of top-notch performances, from Emile Hirsch and Juno Temple’s overly interested brother and untainted sister, to Thomas Church Haden’s deadbeat father. It is Matthew McConaughey as the titular character, however, who is a revelation. As soon as he makes his displeasure known, he can convey an intense threat with silence or terse politeness. Even amongst the weight the movie tries to convey, it still finds time to pack in a rich vein of dark humour, which makes the brutal moments all the more effective. Very good. (See my Killer Joe Twitter review).

Despite a trailer that suggested an amount of slapstick and lightness, The Angels’ Share is a surprisingly well-rounded movie about struggling through adverse conditions and becoming a better person. It’s a small film (as opposed to large or complex), that doesn’t try to be anything that it is not. It has a good measure of real-good feeling without every becoming overbearing. Despite some of the lead’s flaws, you still want him (and his band of friends) to succeed in the little caper that makes up the final act. Worth seeing. (See my The Angels’ Share Twitter review).

Seeking A Friend For The End Of The World never quite lives up to its promise. A world that is going to end, where people have become nihilistic and fatalistic, contrasted by a man who remains true to his old-fashioned romantic nature is a great premise for a comedy. Indeed, the first half delivers a number of very funny moments and ideas (like the assassin’s people have hired so they don’t have to wait until the end of the world), without ever looking like it’ll be a classic. Sadly, the second half switches gears to be quite a straight-forward love story. Introducing that element isn’t bad by itself (and you’ll see it coming anyway), but it isn’t enough to keep the film interesting. It’s a sweet film, but not a great one. (See my Seeking A Friend For The End Of The World Twitter review).

The Dark Knight Rises had an incredibly tough act to follow, and was never likely to better its predecessor; and it doesn’t. What it does do, however, is put a fantastic ending on the best series of comic book-based films we have yet to see. As with all of Nolan’s recent films, The Dark Knight Rises manages to be both an epic, action-driven story, with enough interesting character to push things through. Tom Hardy, as Bane, continues a streak of excellent performances with a very different take on the character. He’s an imposing and focussed brawler, rather than the monstrous brute we’ve seen previously. Anne Hathaway also delivers a great take on Catwoman, that is very much in fitting with Nolan’s vision of Gotham. The worst of the film comes from moments that feel rushed, where the 3 hour soft-limit on mainstream movies makes a number of sequences seem extremely compressed. On the flip-side, it also makes for some very tight storytelling. All-in, a very worthwhile film.  (See my The Dark Knight Rises Twitter review).

Finally, King of Devil’s Island is the story of a boy who doesn’t fit in at a young offender’s institute, set in Norway in the early 1900s. It shows the brutal environment in which he and his fellow inmates live, and the harsh punishments they face. It does this competently, with a great deal of careful direction and some beautiful scenerey. However, it does not do anything new. You’ll have seen films that tell this story before. While it’s certainly a good telling of the tale, it lacks some of the impact that similar movies have had simply because it isn’t fresh enough. Well done, but not provocative. (See my King of Devil’s Island Twitter review).

A difficult month to pick a winner, but I think that Killer Joe‘s performances edge out Batman’s big storytelling.

Film Fight 2012: June

Well, for various reasons, I only made it to the cinema once in June so this is not much of a fight…

Prometheus seems to have riled up a lot of people. Many seem to be annoyed it’s not Aliens, whilst others seemed to think that nothing much happened. It’s certainly not Aliens (and that’s not a bad thing), but an awful lot happened. You see, the thing about Prometheus is that it has absolutely no interest in spoon feeding any of the many answers that are either in the film or hinted at extremely strongly. I’m fine with that. Ambiguity, whether a little or a lot (and this film deals with both), can be a great way of giving a fantastical premise a dose of reality; things are rarely cleanly explained in the real world. Everything that needed to be answered was, to some degree. This film deals in questions that are far above the scope of most action-adventure films,  about that nature of existence and the things that we will never know. Beyond the narrative itself, the action set pieces were surprisingly good, giving a sense of scale, desperation and pace when needed, and the performances more than did the job. It was not perfect: that final scene was entirely gratuitous, and I would’ve ended the film about 10 minutes earlier. However, it seemed to me like it was the film that it needed to be: not an Alien film, something different. Something more ponderous, and interesting. A very good film. (See my Prometheus Twitter review).

Well, it’ll be no surprise that Prometheus is the winner this month.

How To Do Support Well

There are many aspects of professional software development that I had to learn the hard way i.e. by smashing off every branch of the mistake tree and landing on my arse. That’s a perfectly fine way of figuring things out.

Surprisingly, though, that’s not how I learned to do development-support well, which is sometimes called level 3 support. It was something I picked up extremely early in my career, and I’ve yet to learn a better method (not through lack of trying).

I’m going to share the method I was taught in just a second, but a quick clarification of terms. What is development-support? A typical BigCo has 3 kinds of support staff:

  • User-support (sometimes called level 1) deals with any user level queries, like forgotten passwords, usernames, simple account queries etc. They run the day-to-day of the system, but are not necessarily very technical. When they get asked a question that they can’t answer, they escalate it to…
  • Application-support (level 2). These people tend to be technical, but not necessarily developers. They’re in charge of making sure all the servers are running, backups are taken, settings are configured correctly, and that the system is running smoothly. They may perform these tasks directly, or they may co-ordinate with more specialised staff, like system administrators or DBAs. If there is something really wrong with the application itself, they’ll escalate to…
  • Development-support (level 3). These are almost universally people who actively write code for the system in question and, thus, are expected to be able to debug through more complicated and unusual issues arising from the application.

So, with that explanation in hand, back to how I was trained to do development-support and why I think it’s the best way of doing it…

In my first job after university, I was involved in web application with a complicated permission model. Every user had a role that gave them a set of default privileges they were allowed to perform. The domain I was working in is not important, but imagine that someone with a Doctor role might be able to perform treatments, write prescriptions, give medical advice to patients etc whilst someone with a Nurse role can perform minor treatments but not write prescriptions. That’s relatively straightforward.

The complication we had was that for any given item in the system (in our example, a Patient) individual people could be stripped of a privilege normally associated with their role. For example, Doctor X might not be able to give a prescription to Patient Y (perhaps they’re related?).

These minor tweaks to the default permission model were rare enough that they were not the expected norm, but common enough that the role/privilege model had to be maintained; there was no opportunity to simplify.

The single biggest cause of support calls making it to the level 3 development-support team were, inevitably, around the privilege model. Doctors didn’t understand why they could write prescriptions for 99% of patients, but one or two would cause them issues, and that those one or two would be different for every doctor.

The model I was taught for addressing these issues was this:

  1. Give the person asking a support question an answer as quickly as reasonably possible. If it’s gotten as far as you, for whatever reason, then don’t pass the buck if you can: answer the question. A general, all-encompassing solution might not be necessary: just figure out how to get the person asking the question a satisfactory answer quickly.
  2. Train the level above you to solve this class of problems. In a structured support model, like the one detailed above, development-support should only be getting asked about things that the other levels cannot complete through lack of understanding, training, or some impediment. It’s the duty of development-support to provide these things and, in doing so, removing the burden from themselves so they can focus on writing more code.
  3. Make solving the problem trivial. If a question is being asked enough, it’s time to take action. Write sufficient tooling to make solving similar problems simple; or change the information that is displayed so that the answer is obvious and the question itself is removed.

Look at this model through the privilege problem I described. Step 1, when asked why Doctor X cannot give a prescription to Patient Y, might involve manually joining some database privilege tables to see that they’ve had that privilege removed for some reason (“Patient Y is the wife of Doctor X”). That should satisfy the immediate need. Step 2 would be completed by explaining the database structure and queries to application-support so that they’d be able to do what you did for any future queries of a similar nature. Finally, step 3 could be solved in several ways. You could provide a more robust tool so that either support can merely type in “Doctor X” and “Patient Y” and be immediately told about the privilege constraints, or you could expose the information directly to the user. When Doctor X tries to write a prescription for Patient Y, they’d be immediately told they cannot do so for the known reason.

This is a pretty straightforward model to follow, yet I’m consistently surprised to see many teams stopping at step 1 where they’re left to absorb all complex queries indefinitely. I’m not saying it’s perfect, all that it would fit every scenario, but I’ve found it works very well for me.

The Detail of IntelliJ

Having only really dabbled with it before, I’ve been pleasantly surprised now that I’m using IntelliJ IDEA almost full-time. It’s not that it has a single feature that is mind-blowingly ahead of the competition; it’s all the little details that just make it a pleasure to use.

My first “That’s Really Nice” moment was when working with some Spring beans and it understood all of the links between the code and the config. If I hadn’t added a referenced bean, it would tell me. If I type in a bean’s class attribute, it knows that it maps to a Java class and can auto-complete that for me. If you pull in a property file using Spring’s PropertyPlaceholderConfigurer support, it parses the property file so it can auto-complete placeholder usages, give you a hint as to the current value (so you know you have the correct property), and tells you when you’ve typed in a placeholder it doesn’t yet recognise (usually because you forgot to add it to the property file).

The embedded language fragment support, though, is really something else. If you have a Java class that contains a String with some SQL in it, Eclipse will treat it as a String and that’s that. IntelliJ goes a step further. Sure, it’s a String, but it can understand that it’s SQL (or JPQL, HQL or whatever) and do syntax checking for you. It’ll auto-complete keywords for you. Heck, if you tell the IDE about your data-source (presumably a relational DB in this case), it’ll store a bunch of metadata about that data source, and use that to aid you too; by extending the auto-complete to table names, for example.

There are a bunch of other great features in there but, as I say, it’s not the big, shouty features that make it great. It’s the attention to detail in making coding that much easier that makes it such a pleasant experience to work with. I can’t see myself going back any time soon.

Scrums Do Not Make You Agile, And Other Mistakes

In “Avoiding False Metrics“, Seth Godin has a few things to say about the ways in which otherwise sensible people fool themselves into believing they are benefiting, when really they’re playing a crummy numbers game:

At the local gym, it’s not unusual to see hardcore members contorting themselves to fool the stairmaster machine into giving them good numbers. If you use your arms, you can lift yourself off the machine and trick it into thinking you’re working yourself really hard.

Of course, you end up with cramped shoulders and a lousy workout, but who cares, the machine said you burned 600 calories…

We can all see the problem here: people want a result, and will try to take the quickest way of getting there, even if doing so negates the entire exercise.

I can’t speak about other industries, but it’s my perception that software engineering is particularly prone to this way of thinking. Lazy software engineers constantly take tools and processes that are supposed to help us build better systems, apply them in the most perfunctory way and think that’s the improvement made. When we do this, we’re no better than the gym goers fooling the machines and themselves. A few examples…

  • Using a Continuous Integration build server does not mean you are doing continuous integration. Too many people think that merely having the CI server is enough. It is not. If you’re making use of a CI server like Jenkins, that’s great: it’s good to know that your code base is broken as close to the point that it happens as possible. But what do you then do about it? A properly run, continuously-integrated project makes getting the codebase back to a clean/green build the highest priority because if you are merging into a broken codebase, you are not integrating: you’re merely piling up damage. If the next person to commit causes a fault and doesn’t know about it immediately because the build had been left broken, they’re not going to fix it when it’s most critical to do so.

    Beyond just having a build server, there is a lot more to successful continuous integration. For example, what’s your branching-and-merging strategy? Do you feature-branch at the start of a sprint? That’s almost certainly not CI. Do you create release branches for going into production and merge fixes back to trunk? Also not pure CI, but possibly an acceptable flavour if you’re managing it well.

    My point is that CI is not just having a build server: it’s having everyone on your team focussed on the goal of a single, consistent, tested, and reliable codebase.

  • Coverage does not mean that you have useful tests. Code coverage can be an insidious metric in the wrong hands. Too many people who do not understand it feel that getting coverage to an arbitrary point is, in and of itself, the goal. It is not. The goal is to have every part of your project covered by meaningful and robust tests in order that you can be sure any regressions are found as early as possible.

    By increasing useful coverage, more issues can be found earlier, whereas if we mindlessly write tests to bump up the number, well, that can have the opposite effect. Code designed to merely cover, and not actually test, is often brittle in the face of change. By being about moving a number rather than implementing a check, it’s not tied to the needs of the project in the same way as a real test, and creates greater difficulty when refactoring occurs.Code designed to cover without testing also gives a false sense of security. You might think that your code is being tested and that you’ll be warned about regressions, but if your tests are there just to bump coverage stats it’s more likely you’ll get nothing from them.

    Again, the point is that coverage is merely an indicator: it’s the red light on your dashboard telling you there is a problem. The solution is to find the root cause and fix it, not to cover the dashboard in green lights so you can’t see the red any more.

  • Similarly, static analysis tools do not necessarily mean you will have high quality code. Some think that getting your Sonar bugs down to zero is, in itself, worthwhile. It is not. It’s only by fixing the underlying issues in your code that you get any real gains, and these underlying issues are not always what Sonar is telling you about.

    Far too often I’ve seen people get a series of “This Method Is Too Long” Checkstyle errors, and immediately just break lumps of code out into smaller functions. This is not necessarily the right approach. Rather than taking it at face value (“Method is too long? I must need a bunch of smaller methods!”), consider that your abstraction might be incorrect. You might indeed need smaller, better structured methods, but you might equally need to take a long hard look at your class and decide if it’s doing too much. Maybe you need a much deeper refactoring.

    Remember: static analysis tools tell you about symptoms. It’s your job to hunt for the real cause, rather than merely treating the symptoms.

  • On the human side, scrums do not make you agile. Scrum is an extremely important and easily implemented concept in the agilist’s toolbelt, and some think by merely getting everyone together for a short meeting every day to get status updates that they will see benefits. They will not.

    Many teams lose the benefits of having a scrum by simply not understanding the necessary structure and strictures, or really understanding the lessons they learn. By reducing it to a box-ticking exercise (“Everyone said what they’re working on, and what they are going to work on so it must be okay”), they negate the whole point.

    Following a semblance of the process is important: every update should be headline only, protracted conversations should be broken out, and everyone in the scrum should largely care about what everyone else is saying. If you fail on any of these points, then you’re simply wasting everyone’s time and missing the point.

    As with most good practice, the point of a scrum is to minimise the delay between a problem being identified and it being solved. This might be by someone hearing an update and saying “what about this?”, or maybe being able to help with an identified blocker. It’s not, however, going to happen when sprawling updates, unnecessary information, and long conversations cause half the audience to tune out.

Perhaps it’s because we’re used to using machines to take shortcuts in otherwise challenging and tediously manual work that we feel we can apply these shortcuts without too much critical thinking. This is a mistake that will only compound itself.