markhneedham/blog huggingface dataset:
Pair Programming: In interviews
Date: 2010-02-25 08:03:12

I came across a couple of quite interesting blog posts recently which described http://blog.thirstybear.co.uk/2010/02/don-just-interview-new-developers_03.html[some approaches] http://www.davenicolette.net/agile/index.blog/1947137/the-new-interview/[to interviewing] which suggest a more empirical approach to interviewing whereby the interview is treated more like an audition for the person being interviewed.

I like this idea and it's something that we do when recruiting developers in a pair programming interview.

The general idea is that we pair with the candidate as they go through a coding problem. It's perhaps a little different from a normal pairing session in that the interviewee is more than likely driving for the majority of the session.

Sometimes we might also have another interviewer observing the pairing session and giving input where necessary.

While many people may not have specifically pair programmed before nearly everyone has worked with someone else at one computer on a problem so I haven't ever found that a candidate finds it too much of a leap because they're used to working alone.

One of the really cool things about a pair programming interview is that it's much closer to what a real situation on a project would be like which I think helps you to gain a more accurate picture of the skill level and potential of the interviewee.

As an interviewer you get the chance to see how quickly the interviewee will pick up new ideas, to an extent how well they work with other people and first hand experience of their level of expertise when it comes to coding.

From my experience of other types of interviews it can be quite difficult to tell exactly how much knowledge someone has in a specific topic but in a pair programming you can just see for yourself so it works out quite well in that sense.

It's certainly not fool proof and I quite like the way that Hash Rocket have taken this idea to the next level and http://blog.obiefernandez.com/content/2009/09/10-reasons-pair-programming-is-not-for-the-masses.html[get people to come there and pair program with them] for a week before they get hired.

This seems like the next logical step and I guess if you have the ability to do this and candidates are prepared to give up their time then it's a really useful approach.

As http://blog.knuthaugen.no/2010/02/employee-view-of-agile-interviews.html[Knut Haugen points out], the interview process is as much an opportunity for the employee to work out if they actually want to work for the potential employer and I think having the opportunity to pair with some of the people who work there is a great chance to assess this.

http://www.davenicolette.net/agile/index.blog/1947137/the-new-interview/[Dave Nicolette] suggests that the pairing part of the interview process is considered the only meaningful part of the interview process in the team he's coaching and while I'm not I'd go that far I do think it's a very valuable approach and one I'd recommend even if you don't pair program all the time on your team.
Capistrano, sed, escaping forward slashes and 'p' is not 'puts'!
Date: 2010-11-18 18:40:37

http://twitter.com/priyaaank[Priyank] and I have been working on automating part of our deployment process and one task we needed to do as part of this is replace some variables used in one of our shell scripts.

All the variables in the script refer to production specific locations but we needed to change a couple of them in order to run the script in our QA environment.

We're therefore written a sed command, which we call from https://github.com/capistrano/capistrano[Capistrano], to allow us to do this.

The Capistrano script looks a little like this:

[source,ruby]
----

task :replace_in_shell do
	directory = "/my/directory/path"
	sed_command = "sed 's/^some_key.*$/#{directory}/' shell_script.sh > shell_script_with_qa_variables.sh"
	run sed_command
end
----

Unfortunately this creates the following sed command which isn't actually valid syntactically:

[source,text]
----

sed 's/^some_key.*$//my/directory/path/' shell_script.sh > shell_script_with_qa_variables.sh
----

We decided to use 'gsub' to escape all the forward slashes in the directory path and to work out which parameters we needed to pass to 'gsub' we started using irb.

Executing gsub with the appropriate parameters leads us to believe that 2 backslashes will be added:

[source,ruby]
----

ruby-1.8.7-p299 > "/my/directory/path".gsub("/", "\\/")
 => "\\/my\\/directory\\/path"
----

This is because there IRB is implicitly called 'inspect' on the result which shows a different string than what we would actually get.

While writing this blog post I've also learnt (thanks to http://twitter.com/ashwinraghav[Ashwin]) that 'p' is not the same as 'puts' which is what I originally thought and has been driving me crazy as I try to understand why everything I print includes an extra backslash!

The following code:

[source,ruby]
----

p "/mark/dir/".gsub("/", "\\/")
----

is the same as typing:

[source,ruby]
----

puts "/mark/dir/".gsub("/", "\\/").inspect
----

We were able to change our Capistrano script to escape forward slashes like so:

[source,ruby]
----

task :replace_in_shell do
	directory = "/my/directory/path"
	sed_command = "sed 's/^some_key.*$/#{directory.gsub("/", "\\/"}/' shell_script.sh > shell_script_with_qa_variables.sh"
	run sed_command
end
----
Team Communication: Learning models
Date: 2010-11-27 10:50:27

One of the problems I've noticed in several of the 'agile' communication mechanisms (such as the standup or dev huddle) that we typically use on teams is that they focus almost entirely on verbal communication which only covers one of our learning styles - the auditory learning style.

== The Learning Models

The http://www.businessballs.com/vaklearningstylestest.htm[VAK learning style model] describes a simple model covering the different learning styles that people have:

* *Visual* - seeing and reading.
 ** Involves the use of seen or observed things, including pictures, diagrams, demonstrations.
* *Auditory* - listening and speaking.
 ** Involves the transfer of information through listening: to the spoken word, of self or others.
* *Kinesthetic* - touching and doing.
 ** Involves physical experience - touching, feeling, holding, doing, practical hands-on experiences.

My own learning style is predominantly visual so I tend to find that a well drawn diagram will help me understand something far more quickly than a colleague spending 10 minutes explaining something using only words.

If the latter happens then I either find myself totally zoning out or mentally trying to sketch out what the speaker is saying.

In a team environment this would translate into ensuring that we use the whiteboard when trying to explain problems.

Sometimes just going to the whiteboard isn't enough and we need to cater to the kinesthetic learning model which in software development terms would involve walking through the code.

I've never been involved in a team session where we went through a part of the code base together but I've heard from colleagues that it can be very helpful in some situations.

I think it's important that we http://www.markhneedham.com/blog/2009/08/24/learning-thoughts-on-doing-so-more-effectively/[know what our favoured learning style is] so that we can guide any discussion in such a way that it plays to our strengths.

== In terms of software development

Although people tend to have different learning models my general observation is that we can move through the models from auditory to visual and finally kinesthetic depending on the complexity of what's being explained.

I think it also partly depends on the experience of team members. For example, I'm now able to understand many more discussions which are purely verbal where previously I'd have needed a diagram or someone to show me what they meant in the code.

I think it's important to look at the implicit feedback we're getting from colleagues when explaining something to see whether or not the model we've used has been effective.

If it hasn't then at least we know we have some other approaches to try which might be more successful.
Local port forwarding
Date: 2010-11-29 19:42:13

A colleague and I ran into an interesting problem today which we wanted to use local port forwarding to solve.

In our environment.rb file we have a Solr instance url defined like so:

[source,ruby]
----

SOLR_CONFIG = {
  :service_url => "http://some.internal.address:9983/solr/sco_slave_1"
}
----

It's defined like that because our colleagues in Chicago have setup a Solr instance on a test environment and all the developers hit the same box.

In Pune everyone has Solr configured on their own box so we really wanted to configure that url to be 'localhost' on port '8983'.

Several other colleagues have just changed their environment.rb file and then remember not to check that in.

I always forget about that type of thing though so I wanted to find a work around.

We started by putting the following in /etc/hosts:

[source,text]
----

127.0.0.1		some.internal.address
----

Having done that we needed to forward anything coming in on port 9983 to 8983 to complete the forwarding.

I think there's a proper way of doing this using iptables but we didn't want to shave the yak and hence used http://search.cpan.org/~acg/tcpforward-0.01/tcpforward[this tcpforward perl script]:

[source,text]
----

./tcpforward -k -l some.internal.address:9983 -c 127.0.0.1:8983
----

If anyone knows a better way or the proper way to do this I'd be interesting in hearing about that but for now this does the job!
Rails: A slightly misleading error
Date: 2010-11-16 21:17:00

We recently created a new project to handle the reporting part of our application and as with all our projects we decided not to checkin any configuration ".yml' files but rather '.yml.example' files which people can then customise for their own environments.

So in our config directory would look something like this when you first checkout the project:

* config
 ** database.yml.example
 ** some.yml.example

+
</ul> And we'd need to copy those files to get '.yml' versions, changing any parameters that we need to for our local environment. The disadvantage of this approach is that you have an extra step on using a project for the first time, a step that I've been meaning to automate. Several people ran into a somewhat confusing error message when running our rake file after forgetting to create these '.yml' files which looked like this: ~~~text > rake db:migrate (in /Users/mneedham/SandBox/project) rake aborted! uninitialized constant ActiveRecord (See full trace by running task with --trace) ~~~ Running with --trace didn't reveal our mistake but interestingly launching 'script/console' did! ~~~text script/console Loading development environment (Rails 2.3.5) /Users/mneedham/SandBox/project/config/environment.rb:4:in `initialize':Errno::ENOENT: No such file or directory - /Users/mneedham/SandBox/project/config/some.yml /Users/mneedham/SandBox/project/vendor/rails/railties/lib/rails/backtrace_cleaner.rb:2:NameError: uninitialized constant ActiveSupport::BacktraceCleaner /Users/mneedham/SandBox/project/vendor/rails/railties/lib/console_with_helpers.rb:5:NameError: uninitialized constant ApplicationController ruby-1.8.7-p299 > ~~~ This is the environment.rb file in which we were loading that yml file: config/environment.rb ~~~ruby \.... require 'yaml' some_file = File.join(File.dirname(__FILE__), "some.yml") \... ~~~ It's a relatively simple mistake to make so I was surprised that rake didn't tell us that the file didn't exist rather than failing when trying to require ActiveRecord.
Distributed Agile: Communicating big design decisions
Date: 2010-11-10 19:58:33

Although we mostly split the work on my project so that there aren't too many dependencies between the teams in Chicago and Pune, there have still been some times when we've designed major parts of the code base in Pune and have needed to communicate that to our Chicago colleagues.

I've never seen this situation so it's been interesting to see which approaches work in trying to do this effectively and allowing the people in the other location to have input as well.

== Explanation on specific email threads

While it's useful to communicate the approach being taken by email we've found that it makes more sense to have a specific email thread for that conversation rather than tagging it onto something else.

It's surprisingly easy for emails to get lost amongst the hundreds of others that people receive each day but at least if the important messages are all under an email with a clear title then it's much easier to deal with.

While discussing this with http://twitter.com/#!/dexterous[Saager], he suggested that an effective approach he's used previously is to include details of design decisions taken in commit messages and then point people towards those particular commits.

Of course however skilful we may be in communicating via email it does help to talk on a conference call as well - that medium seems to work better for explaining the reasoning behind decisions, especially if there's a disagreement in the approach.

== Commit early

As much as we can explain design decisions in emails or conference calls it's still not as useful for people as seeing the actual code which is something we didn't totally appreciate until recently.

We're now trying to ensure that we check in more incrementally when making big design changes.

This should help to tighten the feedback loop and ensure that we get the benefit of the design skills of people onshore as well as offshore.

Something which I initially considered as a disadvantage with checking in incrementally is that you will most likely get suggestions/criticism about what you've done even if you had already planned to address some of those areas anyway.

As a colleague correctly pointed out, the intention is generally good and it's not the end of the world if someone suggests something you could have done better anyway.

== In summary

These types of things seem obvious looking back at them now but I guess it isn't so obvious to me because you never have to think about them at all when anyone interested in the code is sitting in the same room as you as it's been for me when working onshore.

I'd be interested to hear any other approaches that have worked well for others working in a distributed fashion.
From unconsciously incompetent to consciously incompetent
Date: 2010-11-19 20:20:19

One of the cool things about software development is that despite writing code for 5 years professionally and just under 10 altogether, there are still a phenomenal number of things that I don't know how to do.

The learning opportunities are vast!

One of the areas which I've known I don't know that much about is Unix command line tools such as awk and sed.

Since the majority of projects that I've worked on have involved using Windows as the development environment I've never had extended exposure to the types of problems we get on a project which require their use.

I've finally got the opportunity on my current project and my colleague http://twitter.com/priyaaank[Priyank] and I have been looking to use those tools wherever we can.

We've learnt how to do some very basic commands with both the tools and although those few command have been very useful for allowing us to quickly manipulate text files we didn't quite realise how little we knew until coming across Eric Pement's 'http://sed.sourceforge.net/sed1line.txt[useful one-line scripts for Sed]' article.

I knew that Sed and Awk were powerful tools but I had no idea that you could do this many things with them.

I'm now reading the http://www.amazon.com/sed-awk-2nd-Dale-Dougherty/dp/1565922255/ref=sr_1_1?ie=UTF8&s=books&qid=1290197725&sr=1-1-spell[sed and awk book] so that I can close this gap in my knowledge and trying to use these tools wherever possible even if it does slow me down a bit initially.

In terms of the http://en.wikipedia.org/wiki/Four_stages_of_competence[four stages of competency model] I would say I've moved from being 'unconsciously incompetent' with respect to sed and awk to being 'consciously incompetent'.

Now I just need to reach competence!
Increasing team sizes: Parallelising work
Date: 2010-11-26 03:53:33

One of the trickiest things to do when working in bigger teams is ensuring that it is possible to parallelise the work we have across the number of pairs that we have available.

From my experience this problem happens much less frequently in smaller teams.  Perhaps inevitably it's much easier to find 2 or 3 things that can be worked on in parallel than it is to find 6 or 7 or more.

As a result we can sometimes end up with the situation where 2 stories are played in parallel with a slight dependency between them.

It may be possible to start those two stories at the same time but one may rely on an implementation of the other in order for it to be considered  complete.

It's not an ideal situation but it still seems doable if we ensure that the two pairs work closely together both metaphorically and in terms of their physical proximity.

I think a more useful strategy is to look at how many things can be worked on in parallel and then deciding the team size rather than choosing the team size and then trying to find a way to make the way the stories are written/played fit around this decision.

This is rarely what happens since budgets/need to get to market quickly often take precedence so we end up working in a sub optimal way.

While this is a trade off that the business may be happy to make I still think it's useful to identify the risk we're assuming by taking this approach as well as recognising that *the amount of work we can flow through the system is limited by how much we can process in parallel*.
Interviewing: Communication
Date: 2010-11-26 03:50:20

I've been in India for around 4 months and in that time I think I've probably interviewed more people than I have in the last 4 years.

Over this time I've come to realise that the two main things I'm looking for in candidates are passion and ability to communicate effectively.

It's relatively easy to pick up on whether someone is passionate about what they do in a conversation or while pairing with them but I find the communication aspect a bit more tricky.

I'm typically trying to see whether the candidate can explain things at various levels of abstraction, moving up and down the levels as appropriate to get their point across.

With some people it's really easy for me because they're able to do this flawlessly without much feedback from me about whether I understand what they're talking about and if they need to reframe.

However, in the majority of interviews I end up in the situation where the candidate perhaps isn't explaining something in a way that I can understand.

Either they're giving way too much irrelevant technical detail or end up beating around the bush at a high level and not really answering the question.

If this situation happened on a team I was working on then I would certainly consider it my job to try and guide the conversation so that we could both get what we want out of it.

After all communication is very much a two way thing.

In the interview context I do the same thing but I would expect the candidate to pick up the hints that I'm not understanding them easily and adjust the way that they reply to future questions to take that into account.

If they don't seem to take that feedback on board then it's quite likely that I'll make the judgement that they're not able to communicate very clearly and we won't proceed with the candidate.

I'd be intrigued to hear the approaches others take because it does feel a little bit like I'm doing it wrong in this respect.
Active Record: Nested attributes
Date: 2010-11-09 18:37:10

I recently learnt about quite a neat feature of Active Record called http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html[nested attributes] which allows you to save attributes on associated records of a parent model.

It's been quite useful for us as we have a few pages in our application where the user is able to update models like this.

We would typically end up with parameters coming into the controller like this:

[source,ruby]
----

class FoosController < ApplicationController
   def update
      # params = { :id => "1", :foo => { :baz => "new_baz", :bar_attributes => { :value => "something" } } }
      Foo.update_instance(params[:id], params[:foo])
      ...
   end
end
----

Our original implementation of 'update_instance' looked like this:

[source,ruby]
----

class Foo < ActiveRecord::Base
   has_one :bar

   class << self
      def update_instance(id, attributes_to_update)
         instance = Foo.find(id)
         instance.attributes = attributes_to_update
         instance
      end
   end
end
----

Unfortunately when we execute that code the 'bar' association gets completely removed because we didn't specify the id of 'bar' when we were updating the attributes.

We need to change the code slightly to make sure it doesn't do that:

[source,ruby]
----

class Foo < ActiveRecord::Base
   has_one :bar

   class << self
      def update_instance(id, attributes_to_update)
         instance = Foo.find(id)
         attributes_to_update[:bar_attributes][:id] = instance.bar.id
         instance.attributes = attributes_to_update
         instance
      end
   end
end
----

It now works as we'd expect.

There's other cool stuff that you can do with nested attributes described on the documentation page if you have 'has_many' associations but for now we're just using the simpler 'has_one'.
Consulting is like inception
Date: 2010-11-30 19:25:16

My colleague Jason Yip http://twitter.com/jchyip/status/4701457760649217[recently tweeted the following]...

____
Sometimes consulting reminds me of the movie Inception
____

...which reminded me of a conversation I was having with a colleague here who's been working on consulting engagements here for the last few months.

I was describing some of the things that I wanted to change on my team and she pointed out that I always described each change as something that I wanted to change rather than something which I wanted to see change.

I think this is subconsciously the result of wanting to believe that we've influenced something and are actually adding some sort of value to the team we're working on.

In reality though it's rare that we can suggest a change and others will just agree with it straight away - I've failed with this approach a significant number of times.

In Inception the conspirators want to plant a thought into the victim's mind but they don't want him to know that they've done it - it should seem like it was his own thought.

My colleague pointed out that the same is true when we're trying to influence change.

Suggesting a change is unlikely to work but dropping ideas to different people and then letting them run with them might eventually result in change happening even though it may be a slow process.

The problem is that it's quite difficult to take your own ego out of the equation and let a positive change happen without the credit necessarily being given to you.

I'm still struggling to get past that stage but hopefully soon I shall get there...