The Employee View of Agile Interviews

| 5 Comments | No TrackBacks

I found two interesting blog posts via Twitter, http://blog.thirstybear.co.uk/2010/02/don-just-interview-new-developers_03.html and http://www.davenicolette.net/agile/index.blog/1947137/the-new-interview/ both covering a new and perhaps more agile (hey! buzzword!) way of doing interviews. The key point is to audition the candidate rather than to just ask questions. Doing actual pair programming and seeing how people how actually work to solve a concrete programming tasks is much more valuable than to give them a random task, ask if they remember some obscure part of a spec everybody looks up anyway or not least, see what certifications they have. Would you like to work for a company that put more faith in your certifications than your current abilities?

Both posts cover this from the viewpoint of the potential employer but I can see just as much value for the employee. When interviewing for a new job you rarely get an accurate view of how the company really is through the interview. The reality really dawns on you a couple of months into the job. My (somewhat limited) experience with interviews is that they are very rarely used to dig deep enough, both from the standpoint of the employer and the employee. But we should! Hiring the wrong people is expensive for the company and choosing to work for the wrong company is just waste of time for an employee. Or worse.

The Questions to Ask

If I where to look for a new job I would milk the interview for all it's worth and use it to see what kind of company I'm dealing with.

  • If they're not doing pair programming in the interview, will they do it in real life?
  • How serious are they about their agility?
  • Do they check what I remember or do they make an effort to find out how I work?
  • Are they interested in the buzzwords I know or the process I use to develop software and solve problems?
  • Are they interested in finding out about the real me?
  • If at all possible: pair program with the people I'm going to be working with

I would perhaps even go as far as asking them why they're are hiring they way they are, regardless of how, and use the answer to decipher their way of thinking about people and the craft of software development. I mean: would you choose to work for a company which isn't really interested in finding out the real you but rather just hire the résumé you?

Some other questions I would consider asking to find out more about the company:

  • What kind of computer hardware and software are developers using (this can seem like useless geek obsessions, but it tells me something about how they value the productivity of their developers. Best answer: you get to choose :-))
  • How does the company (top to bottom) ensure continuous improvement?
  • How does the company measure the productivity of their developers? (trick question).
  • How far up the management chain does the agile principles really go? Think Toyota Production System-like environment.
  • For a consulting firm: how much/often do you spend time inside the mother ship opposed to on-site at clients?

The Time it Takes

Doing interviews in this fashion takes time and I have heard stories (at Hashrocket I think) of week long pair programming sessions with the entire team and one "no" from one team member is all it takes to turn down the candidate. This probably works better in the US with their system of two weeks notice, but not so well in Norway with (normally) three months mutual notice. But for sure: one hour of questions doesn't tell you enough. Practice trumps talking, talking trumps résumés - to paraphrase the kanban saying.

Learning Ruby With Ruby Koans

| No Comments | No TrackBacks

I'm learning Ruby these days and after reading the excellent book The Ruby Programming Language I found myself in need of actually writing and reading some code. I tried starting a pet project in Ruby but the, uhm, distractions of two young children made it difficult to get that off the ground and I also quickly realized that I needed some more training before I could get productive on that project.

So enter Ruby Koans written by Jim Weirich and Joe O'Brien of EdgeCase. This little git repo guides (and forces you) through a series of test files with (at first) failing unit tests where you read code and make failing tests pass one after another. It starts out easy with variables and true false and the likes and end up with open classes, message passing and modules.

If you tolerate some zen puns and need a quick intro to ruby and testing in ruby, it's worth a look. The beauty for me was the ease of doing one pomodoro of Ruby Koans each morning and the mental context needed to do that was very small.

Systems Thinking applied to software development

| 2 Comments | No TrackBacks

I have watched some talks by John Seddon on Systems Thinking and where he feels Lean has failed. Seddon's focus is service organizations in public and private sector like health-care and customer support and sales for various products. But how would systems thinking apply to software development? Have we got it all wrong? I'm going to try and map some of the ideas of Systems Thinking over to existing software development methodologies and practices and see where we end up.

Systems Thinking in a nutshell

Systems Thinking is about seeing the organization as a system and studying it as a system from the view of the customer. Some core ideas summarized:

  1. The only plan for changing an organization is to get knowledge
  2. Study demand going into the system
  3. Differ between failure demand (bug reports, wrong feature and other sources of rework) and value demand (new features/contracts/projects).
  4. Study the variability and predictability of the failure demand. Only what is predictable is preventable. Take steps to prevent failure demand
  5. Peoples behavior is a product of the system in which they work. If you want to change the people, change the system
  6. Train people to handle the incoming requests and let them pull help on the things they don't know how to solve.
  7. Don't standardize the work
  8. Give the workers the means to control the work and the power to change it.
  9. Measure the actual value delivered to customers.
  10. The best way to learn counter-intuitive truths is to see and experience them for yourself

The goals are of course to deliver maximum value (the right features at the right time to solve the right problems) to customers in the shortest time frame possible. Sounds familiar? Read on for more in-depth discussion on each of the items in the list.

Linkdropping on NoSQL, Lean and Systems Thinking

| 4 Comments | No TrackBacks

I thought I would round up a collection of links that interested me the past few weeks on various topics. First off: NoSQL databases:

Then over to Lean and Kanban. Henrik Kniberg and Mattias Skarin just published a new book on InfoQ titled "Kanban and Scrum - making the most of both". If you´re not familiar with Henrik Kniberg´s work, I also suggest "Scrum and XP from the trenches". Erling Wegger Linde´s "A Kanban brown bag recipe" is also worth a read.

And in the spirit of Lean: There is a video of talk by John Seddon of Vanguard titled "Cultural Change is Free". Mainly about systems thinking in the public sector, but private sector aren´t infallible either. Seddon often criticize Lean for being wrong in many places, but I often feel he is criticizing a wrongful implementation of lean ideas, much the same as scrum is often criticized for the misgivings of wrongful implementations. Or rather he is criticizing the tool focus of a lot of lean consultants not the lean principles themselves. And he stresses the differences between the Toyota Productions system and other kinds of organizations. You could also check out is talk "Re-thinking Lean service" on InfoQ which deals with the same topic in a slightly different packaging.

Posting to Movable Type From Emacs

| No Comments | 1 TrackBack

I stumbled across weblogger.el which is an xml-rpc interface for posting to several blog engines, including Movable Type which I use. And I thought: Hey, why use that somewhate crappy online editor for writing blog posts when one can use a fairly OK operating system to do the job (aka Emacs).

Setup

Download weblogger.el from the above link and also the requisite xml-rpc and load them in .emacs in the usual manner.

Run weblogger-setup-weblog and fill in the correct values for configuring the blogging engine. For Movable Type the URL endpoint is http://your.blog.url/mt/mt-xmlrpc.cgi. The user name is your usual username, but the password is the special API password which can be found and set on the bottom of the user page in the admin interface. After that it's just C-c C-n for a new entry. The setup will fetch all existing entries automatically so you can cycle through and edit too.

Caveats

It seems the current version of weblogger.el doesn't handle drafts properly against MT 4. The first version saved as a draft is published instantly :-/. Later saves keep the draft status. Also, the familiar C-c C-s for saving the buffer actually publishes. So you're going live pretty soon.

A MacOS X Keyboard Layout for Programming

| 3 Comments | No TrackBacks

I have previously created my own keyboard layout for windows and Linux in order to have a layout where the often-used keys in programming are more accessible than in the standard Norwegian layout. And when I recently got a (shiny) MacBook pro, I wanted to have the same keyboard layout for the Mac also. Consistency is key across machines, so the layout is the same as in the original progn keyboard layout (most braces and slashes available on home row or the row above). Downside is if decide to update it, I have to update three copies. Oh well...

In the windows and Linux I ended up mapping caps-lock to alt-gr and binding a lot of new key combinations using that modifier. I chose a similar although slightly different model for the Mac. I choose to use the caps-lock key as another alt key (set in the keyboard system preference) and then map keys to alt+for easier access. This means I loose the keys already bound on the alt key, but I keep the original keyboard layout easily accessible, and switching is a breeze. On the positive side, I don't mess with key bindings in either the Terminal app, Aquamacs (when fn is set to be meta) nor IntelliJ IDEA. Here's the finished new bindings: keyboard.png
Home row is the most important one, with often used characters, and the braces on homerow+1 on the right hand. Pointy brackets and pipe on the left hand.

Recipe

Here's how I created the new keyboard layout for mac running 10.6 Snow Leopard (I think it'll work on Leopard (10.5) as well, but haven't tested it). Finding an existing layout in the .keylayout XML format was quite difficult but I found an extended Norwegian layout which had some often used keys already mapped nicely, like «» and some others. So I used that as a base.

  1. Download Ukulele from the web page and install it.
  2. Either start from scratch defining keys in Ukelele or start modifying an existing keyboard layout.
  3. Open the character viewer (System preferences -> Language & Text -> Input Sources and select Character and keyboard viewer
  4. Drag characters from the character viewer while holding down the desired modifier key.
  5. Save under a suitable name. Be creative :-).
  6. Copy to "/Library/Keyboard Layouts" for access for all users or "~/Library/Keyboard Layouts" for just your user.
  7. log out and log in, and you should be able to choose the new keyboard layout from System Preferences.

I called my keyboard layout progn, like the others I have created and you can download it if you want to use it for further tweaking. I made it available under the same creative commons license as this blog, so remixing is allowed provided you make the re-mixed versions available to the world wide intertubes.

Doing do-release-upgrade on an offline ubuntu mirror

| No Comments | No TrackBacks
I have an offline mirror of the ubuntu package repositories for use on a network not connected to the internet. This works like a charm for updating packages on individual machines, but when it comes to doing a 'do-release-upgrade' to the next release, like these days I'm trying to upgrade to 9.10 Karmic Koala, we need some tricks to make this work. Firstly, sync your mirror so all the new packages of the new release are locally available. What you probably find is that the upgrade manager/do-release-upgrade software can't seem to find a new available automagically. So how do we accomplish this?

  1. update-manager and do-release-upgrade reads the file /etc/update-manager/meta-release to find the location of the meta-release file. This points to the internet location changelogs.ubuntu.com normally. And if you just mirror the package repos, the meta-release file isn't included. So we need to fetch it first: 'wget http://changelogs.ubuntu.com/meta-release'.
  2. Store it, for instance on the root of the internal mirror or some other convenient location, and put the url to it in the "URL" value in the /etc/update-manager/meta-release. If you're upgrading to a LTS release, fetch the meta-release-lts file too and repeat the process.
  3. Edit the meta-release file you just downloaded and substitute the external mirror address with the url for the internal mirror so all package locations match up. For me this was replacing 'archive.ubuntu.com' with 'explorer/mirror' since the internal mirror is available at http://explorer/mirror/ubuntu/. Make sure the file is readable via http (or file permissions if using file access to repo).
  4. Run update-manager or do-release-upgrade and the upgrade should work as you were using an internet mirror.

Hacking on munin 1.4

| No Comments | No TrackBacks

I have been doing the ol' open source thing lately and helping out some old colleagues from Redpill-Linpro hacking on the much-awaited 1.4 version of munin (out today) which has tons of new features and not to mention tons of new plug-ins for just about all kinds of hardware and software out there. The changelog is longer than most I've seen in a while, and that's definitely a good thing. I've been doing mostly html+css work on 1.4 but I am planning to dig deeper into the core in the future and help out with some much needed re-factoring of the Perl code. And hopefully contribute some tests as well. It's good to write Perl again.

Planned plugins

I thought I work on some new plugins as well when I get spare time, namely

  • SNMP plugin for Synology NAS
  • SNMP plugin for Qnap NAS
  • SNMP plugin for IBM Bladecenter H (if it has some good data available)
  • SNMP plugin for IBM Storage DS3000 series

And I also going to see if the NetApp at work spits out something more useful not covered in the existing netapp plugins.

If you need monitoring and graphing of key metrics from your servers, network hardware, storage hardware and software servers (jmx plug-ins new in 1.4 too), you should give munin a spin.

Creating Craftsmen And a Craftsmanship company

| 2 Comments | No TrackBacks

How does one go about creating software craftsmen in a company and more how does one create/transform a company to make this possible? These are the questions and thoughts I found myself with after attending an open space session at Smidig 2009 (the Norwegian Agile conf).

Perhaps the most known craftsmanship consulting firms are Obtiva and 8th Light, both located in Illinois USA (one on Chicago and the other in Round Lake). They are, as far as I know, created specifically to a have a master and apprentice model and takes this to extremes. Their craftsman exchange is a fine example of this, where senior consultants got to piggyback the other firm's people on real world projects for a week, just to learn from them on how they build software and how they run their company. They also hire programmers with the title of apprentice and one account of being an apprentice at 8th Light is found in this blog. Not bad to commit JRuby code while formally being and apprentice. I especially noticed the part about being specific (coding) challenges and the getting feedback from not just one but all masters in the firm. I suspect the amount of condensed learning is formidable. But does this approach work when you trying to transform a "normal" consultancy firm into something more craftsmanship friendly?

Let's examine some other tools to use, more tuned in to (Norwegian) consulting firms and companies that do not have this in place now, but rather have their hands full with competing and hanging on to clients. What should one do?

Organic interest groups
Mike Cohn explained in Oslo XP meetup talk recently Google's model of special groups within the company forming horizontally across projects. A talk on the same subject at JavaZone 2009 in Oslo discussed the same idea employed in KnowIT ObjectNet, a consulting firm in Oslo, Norway. They even have a cooperation with the Simula Research center on finding out what actually works best.The important bits are:

  • Voluntary membership based on interest (Google, KnowIt)
  • Each person can join many groups (KnowIt)
  • Organic growth bottom-up is preferred, but it should be allowed to transform into more formal groups over time. (Cohn)
  • Given a mandate to change practices (google, KnowIt)
  • Communicate the results
This is a key issue. People need to have a forum to evolve their skills outside of the current customer project, which in many cases isn't well suited for that, deadlines and all. Learning a new language, which in my mind brings with it a lot of benefits especially when learning one from another paradigm than one is used to, is best done outside the creation of enterprise code under time pressure. Besides, one needs room to experiment and fail. Demanding some kind of output from the work is important to keep it in check and make the group prioritize and work toward a goal, not to mention to disseminate the knowledge gained to non-members and even the development community at large.

Reports, internal or external talks or patterns & practises changes are some types of outputs. In the concrete case of KnowIt, the groups were allowed to bring in outsiders which in one case created a cooperation with the Norwegian Scala user group ScalaBin. A good example of an activity that is of value to the entire community, not just the company itself. And I would argue that a good software development community is an important factor in creating good companies and good developers.

This should work well for consultancies in my opinion. People need some time off the project to keep in touch with the company and what better way than to spend it doing research on a hot topic that may bring in future clients? KnowIt also found that you need some hot topics to keep the juices flowing in the developers, but the company could put more regular topics to good use to. And it all depends on the people you have on board.

Coaching
A new programmer fresh out of college, needs guidance to avoid stepping into balls of mud and re-inventing the wrong wheels. How do we accomplish this? Several thoughts emerged on the open space at smidig 2009. Pair programming
is an excellent way of transfering knowledge from one head to another. There are a number of factors that need to be in place for it to function properly, but done right can produce great results. For a consultancy it requires that a customer allows junior programmers to be put on the project team and the (at least perceived overhead) of mentoring them.

Concrete feedback and guidance while working on real-world problems was mentioned by several people and the rationale was that learning isn't as rapid or valuable in constructed problems. You need wet feet to really appreciate the boots you're getting. Code reviews can also be used to make novice programmers see the errors of their ways and seeing how it should have been done.

Quality
Never compromise on quality. If a customer ask you to deliver the same features, only a little bit faster, say no. Plain old no. If you're doing it faster, you're cutting corners. You may not think you are, but you are. This requires backbone from both developers in the trenches and managers negotiating contracts.  

Don't do overtime (at least not as a rule). You need sustainable pace. Burned-out developers make poor craftsmen and they need a life outside work. Besides, who has the energy to learn Clojure or contribute on open source projects if they spend all their time and energy on work? You need time off. Use it
.

Learning and teaching
At the core of it all is learning. Becoming a craftsman requires lifelong learning.The principle of Kaizen (from Lean) embodies what I think is the right path: small incremental learning each and every day, improving a small part of the workplace, your skills or your team. Big steps are much harder to do and get right.

 Some other points regarding learning: some for the developer and some are for the company.

  • Realise how little you know and be open to learn from everyone you meet.
  • Always challenge your beliefs.
  • Always buy the books you want (and read them)
  • Keep up with the trends
  • Seek new challenges
For the company:
  • Allow consultants the time to develop
  • Nurture a culture of learning and improve the company in small increments, not just the people. Kaizen all the way.
  • Allow for mistakes and but ensure learning from them, both individually and as a group.
And remember: you can't expect to change other people, you can only change yourself.

A craftsman shares his knowledge with others and tries to make the community around him grow with him. Give talks at conferences, user groups or inside you company. As a company, encourage developers to give talks, give them time and resources to do so. Follow up on it. Spread the word. Nothing forces you to know your stuff quite like giving a talk on it to an audience. Scary but rewarding.

Tools
A craftsman needs to know the tools of the trade and to use the right tool for the right job. This is mainly a skill one gets through experience. But the right kind of experience - a varied one. This is the consultants world and consultants are in better shape than most in-house developers when it comes to this. But learning a new paradigm or language will take you far in my opinion. Just the act of learning a totally different language, even though you just use if for toy projects, refreshes your perspectives on your "day-job" language. Especially if your job language is C# or java and you learn a dynamic language or a functional one. The perspective you attack problems with in your job language will change and change for the better.

Knowing your IDE or other developer tools is essential, as is knowing and tweaking you platform. This means also that companies must let developers have full control over their development machine. The opposite actually still occurs. And not to mention: the developers need the sexiest hardware money can buy and plenty of screen real-estate.

People skills
A craftsman need people skills. She needs to understand the customer and make the customer understand her. She needs to be a team player and know when to shut up and when to speak up. She must be responsible, honest and brave. How to achieve all this? Can introvert geeks manage these things? Well, some people will have to work more on it than others, but I feel the environment we operate in and the feedback we get, can develop many of the skills. Keywords are giving developers responsibility to make technical decisions, to work independently, embrace, encourage and reward team efforts, not individual efforts. Challenge their fears and push the limits of their comfort zone a bit, within reason. Careful not to push to hard :-)

And besides: The primary output of a software project is people, not customer value and software (paraphrasing Ward Cunningham). You are the sum of the work laid down. As an ending note: the book
Apprenticeship PatternsGuidance for the Aspiring Software Craftsman by Dave Hoover and Adewale Oshineye is out on O'Reilly now and discuss a lot of this in depth (although I haven't read it yet).

This blog post is getting to long as it is. Feel free to continue in the comments if you have something to add.
 


A SyntaxHighlighter brush for Lisp

| 1 Comment | No TrackBacks
I use SyntaxHighlighter for highlighting code snippets on this blog and I found out that it didn't come with a brush for the 2.0 version highlighting lisp code. So I wrote my own. I found a SyntaxHighlighter 1.5 brush through google and I converted that to a 2.0 brush and it's now in a state that sort of works. At least it highlights some code :-) I used that as an excuse to try out qunit as well and write some unit/integration tests for the code. Qunit is cool. There's not much code in the brush itself as it leans heavily on the core SyntaxHighlighter stuff. So the tests are testing the framework also. But hey, I'm not picky.

It's all to be found on github:knuthaug/sh-lisp.Patches/pulls via github is more than welcome. I plan to dig out my copy of "Ansi common Lisp" and go through the lists of functions, keywords and macros a bit more in detail. Some more tests are in order to. One question which comes to mind is if it's best to do one that does common lisp and emacs-lisp, or one brush for each dialect?

Here's the code for brush:
SyntaxHighlighter.brushes.Lisp = function(){

    var funcs     = 'lambda list progn mapcar car cdr reverse member append format';
    var keywords  = 'let while unless cond if eq t nil defvar dotimes setf listp numberp not equal';
    var macros    = 'loop when dolist dotimes defun';
    var operators = '> < + - = * / %';

    this.regexList = [
     { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' },
     { regex: new RegExp('&\\w+;', 'g'), css: 'plain' },
     { regex: new RegExp(';.*', 'g'), css: 'comments' },
     { regex: new RegExp("'(\\w|-)+", 'g'), css: 'variable' },
     { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' },
     { regex: new RegExp(this.getKeywords(macros), 'gm'), css: 'keyword' },
     { regex: new RegExp(this.getKeywords(funcs), 'gm'), css: 'functions' },
    ];
    
}

SyntaxHighlighter.brushes.Lisp.prototype = new SyntaxHighlighter.Highlighter();
SyntaxHighlighter.brushes.Lisp.aliases   = ['lisp'];