Lately I have been struggling to find time to code. As a lead on a team the size of ours my day is usually peppered with meetings, CI server shenanigans, process questions about blocked story cards and occasionally a really fun bug. Every one of those things is enjoyable in it's own right and help the team move forward but I definitely enjoy the times when I can get my fingers on the keyboard.
When I am given the opportunity to dedicate some time to coding outside of the job I like to make the most of it. Whether it's the local user group meetings or the weekly lunch time code club, I genuinely look forward to sitting down for a bit and doing nothing else. There is no substitute, as they say. And these days it doesn't really even matter all that much to me what language I am writing.
At many of these events, however, I have found myself disheartened by the number of people who are unwilling to take the keyboard. Actually, that's not the whole truth. I find myself disheartened by the number of people who will tell you at length how they would approach the problem, but don't seem to be doing much, if any, coding.
I started to write a bit here on why I think this occurs, but in all honesty, I don't really care all that much and I am probably wrong anyway. What I will say is that about six months ago I was at a Global Day of Code Retreat event here in Columbus, Ohio. During that day one of the constraints put on me was to pair with another developer silently for roughly an hour. And during that time my pair partner and I turned out some really decent, very expressive code.
Afterward we both agreed that the silence limitation turned out to be quite eye opening. We confused the hell out of each other a few times and rewrote each other's stuff more than a few times but once the debate in code was over and the dust settled, we had gotten further on the solution than with any of my other pair partners all day. Even if we hadn't though I would still say being forced to express my ideas solely in code was refreshing. As it turns out developers can have a perfectly fine discourse right in the editor and arrive at a very good end result. Furthermore, we don't have to live with a busted idea for more than the time it takes to revert or refactor.
So I say fight the habit to socialize every idea before you lay it down in code. Resist the human urge to gain acceptance ahead of time and get your ideas written and compiled as fast as you can. Code it. If it stinks, recode it, or throw it away. That's what git reset --hard is for right!? Go forth and be awesome...or be wrong. Who cares which? Just be coding.
Tuesday, June 4, 2013
Thursday, May 30, 2013
Standing Up for Stand Up
Earlier this week a disagreement occurred amongst some technical team leaders regarding how stand up meetings should be held. One camp felt the meetings were becoming a bit cluttered. The team is a remote team and several interested parties from the home location like to participate in the daily stand up via Google Hangout. One of a few complaints is that the cross site communication makes the stand up kludgy. There are regular interruptions to repeat things, for instance, since the microphone is directional, etc, etc. Other annoyances were also noted.
The other camp insists that the good that comes from the cross site participation far outweighs any headache it causes. The home location values maintaining a strong relationship with the remote team and accepts the soft costs of doing so. As is usually the case, both camps are correct and are now entangled in a very fine grained philosophical disagreement.
But none of that is as important as the fact that it caused me to gut check my own reasoning and make sure that I was staying true to the principles that guide me as a leader. You see, I believe that a human being's best work is the result of a harmony amongst the many forces acting on that person's life. I think this because I latched on to the teachings of Lao-tse very early in my own life and value them even more today than I did 25 years ago.
One does not need to know very much about Lao-tse or the Tao Te Ching to know that he believed a perfect harmony between heaven and earth existed naturally and could be found by anyone. The idea he put forth is that the more a person interferes with the natural order of things the more that person will struggle against, and retreat from, harmony. I am convinced that this concept is important to the technical work we do and the way in which we lead our technical teams. There are examples of similar or identical thoughts all over the software world about "signal to noise ratio" or "context switching" and slightly more etherial things like "flow state".
So bringing the point back to the decisions that impact development teams, I stand firm on the opinion that genuine annoyances are to be removed. Knowing the human beings that choose to team with you is the job of a leader. Working towards harmony through techniques and tools and improved (or removed) process is a leader's responsibility. Above all else, the people who you ask to follow you deserve an opportunity to be happy and do the best work they are capable of doing. In doing so they may experience their true nature without the arbitrary and false interferences business would otherwise impose.
These are lofty goals. It is likely that, as a leader, I will fall short of these goals on many occasions. The desire and effort to achieve these things will give me an opportunity to expose my true nature, however. And for that reason, I have no choice in the matter.
Completing our round trip then, what should be done with the stand up meetings? Give the remote team what they want so they can go be productive without being annoyed. The need to coordinate between sites is an artificial constraint that the leadership has imposed on the project. It is the job of those same leaders to find ways to satisfy the tangential needs of the project and not impede the harmony that naturally exists between a developer, a keyboard, and problem in need of solving.
That's the way Lao-tse saw it then and that's the way I see it now.
The other camp insists that the good that comes from the cross site participation far outweighs any headache it causes. The home location values maintaining a strong relationship with the remote team and accepts the soft costs of doing so. As is usually the case, both camps are correct and are now entangled in a very fine grained philosophical disagreement.
But none of that is as important as the fact that it caused me to gut check my own reasoning and make sure that I was staying true to the principles that guide me as a leader. You see, I believe that a human being's best work is the result of a harmony amongst the many forces acting on that person's life. I think this because I latched on to the teachings of Lao-tse very early in my own life and value them even more today than I did 25 years ago.
One does not need to know very much about Lao-tse or the Tao Te Ching to know that he believed a perfect harmony between heaven and earth existed naturally and could be found by anyone. The idea he put forth is that the more a person interferes with the natural order of things the more that person will struggle against, and retreat from, harmony. I am convinced that this concept is important to the technical work we do and the way in which we lead our technical teams. There are examples of similar or identical thoughts all over the software world about "signal to noise ratio" or "context switching" and slightly more etherial things like "flow state".
So bringing the point back to the decisions that impact development teams, I stand firm on the opinion that genuine annoyances are to be removed. Knowing the human beings that choose to team with you is the job of a leader. Working towards harmony through techniques and tools and improved (or removed) process is a leader's responsibility. Above all else, the people who you ask to follow you deserve an opportunity to be happy and do the best work they are capable of doing. In doing so they may experience their true nature without the arbitrary and false interferences business would otherwise impose.
These are lofty goals. It is likely that, as a leader, I will fall short of these goals on many occasions. The desire and effort to achieve these things will give me an opportunity to expose my true nature, however. And for that reason, I have no choice in the matter.
Completing our round trip then, what should be done with the stand up meetings? Give the remote team what they want so they can go be productive without being annoyed. The need to coordinate between sites is an artificial constraint that the leadership has imposed on the project. It is the job of those same leaders to find ways to satisfy the tangential needs of the project and not impede the harmony that naturally exists between a developer, a keyboard, and problem in need of solving.
That's the way Lao-tse saw it then and that's the way I see it now.
Tuesday, September 18, 2012
Hiring Agile Software Developers
Attracting and hiring the right people to form an Agile Development team is tough. And anyone who has ever had to handle the coaching or removal of an underperforming or ill-fitting team member knows how important it is to make good hiring decisions. A bad hire can become a drain on a team and even worse, take time away from coaching, skill uplift, and recognition of top performers.
So how do you know if you are hiring a person that is going to fit on the team and perform? And equally important, how do you know if they are any good at designing and writing software? You have to audition them and you have to be ready to get into the nuts and bolts of their history in this craft. So many employers, especially large employers, scan resumes for keywords, schedule interviews, and then don't go much further than to check that a candidate shows up on time, has a firm handshake, and wears appropriate attire. Not good enough...not even close.In some cases this happens because a non-technical person is working alone hiring people for technical positions. I have known more than a few managers, good ones, that are not current in the technologies their team uses and therefore feel outgunned when they have to interview a candidate. Sometimes this works out, but in many cases that candidate gets hired and becomes that person in your group that you look at and shake your head...wondering how in the world the two of you ended up on the same team with the same title and are SO different. If you are one of these leaders, knock it off! Go get some help from an awesome developer you trust and start doing the job correctly.
More often and more tragically, though, the group or individual running the screening process is very skilled technically and simply not using the correct tools to perform the task. Not many of us appeared in the software development profession with a great understanding of what type of questions to ask a person when interviewing and what technical drills to put them through to give us insight into their abilities. In far too many instances I have seen a developer or technical lead get asked a few minutes prior to the interview to "sit in" and then subsequently help make a hiring decision. As Agilists and Craftspeople conducting ourselves in this manner is not acceptable and is a disservice to everyone involved.
If we are going to be diligent and give candidates a proper look then we need a consistent audition process. You don't want to go into the interview/audition process without a plan and depending on where in the world you work you are most likely required to provide every candidate with the same screening process so that you are sure to be impartial and unbiased. All that being said, if you interview developers with any regularity, you must define an audition process.
You may wonder where to start or think that planning an audition is tough, but honestly it turns out to be one of the more enjoyable things to do as a developer. My response to this challenge was simply to understand the needs of the team as criteria and then script an audition process that exposed the presence or lack of those traits in candidates. The higher the expectations of the role and the more tenured the candidate the more lengthy and complicated the audition becomes. My recommendation is to therefore start simple and build into the more complex, kind of like everything else we do in this trade!
Below is an example of my audition process for candidates that are newly graduated and/or just beginning in their software development career. This flow was derived knowing that my recruiting department will have done some basic initial screening and that I had already been through at least one 30 minute telephone conversation with these candidates as a second filter. I already knew where they were with Agile, XP, etc. and in most cases they had little or no exposure. The team I wrote this audition script for holds a person's attitude to be *almost* as important as their technical ability. The ideal candidate will have the positive, self-motivated attitude of a good Agilist and the chops to pair up and code and learn like a champ. Based on environmental factors I also knew going in that I was only likely to ever get about 90 minutes to spend with a prospect. Lastly, I believe this process is very much a two way interaction and I use it to introduce people to our corporate culture and allow them to gauge fit as well.
Developer Audition – (Entry Level/90 Mins)
Introduction
09:00 - Greet at lobby (Tech Lead)
09:00-09:05 - Ride up to team space floor. Introduce Tech Lead in more detail. Describe and settle on agenda. Offer restroom/water.
Cultural Fit
09:05-09:15 - Tour team space. Introduce candidate to team leads/members as available and describe roles. Pick up other team leads who will attend audition.
09:15-09:40 - Proceed to conference room. Describe Culture (ex: Agile, Poly-skilling, Teaching Days, Standing Teams, Continuous Improvement, Retrospectives...)
Some Suggested Questions Regarding Cultural Fit
09:40-09:50 - Candidate Questions/Break if needed
- Describe the work environment from your work history in which you were most productive and happy.
- Describe the most effective roles a good manager plays with the staff he/she manages.
- What is your preferred work style, alone or in teams? => What percentage breakdown between the two suits you the best?
- When working in a team, describe your mostly likely role on that team. How would other team members describe you?
Technical Aptitude
09:50-10:20 - Using the whiteboard and Tech Lead's PC in the conference room. Although a quality technical solution is important, also of interest in this segment of the audition are the questions asked, what resources are used to problem solve, and how the algorithm is determined. Assuming the candidate attempts the solution most people go to first, involving an array, it is very important to gauge how he/she feels about having that solution refactored.
- On the whiteboard, in any syntax or plain English, describe the logic to take in a string and return the characters in the string in the reverse order. (5 minutes)
- On the whiteboard, write a HelloWorld program in Java or another syntax of candidate's choosing. (5 minutes)
- On the PC, in a pair with the Tech Lead, NOT using an IDE, with access to the Java 6 API on-line, write a Java Hello World style program returning any string the candidate chooses. (5 minutes)
- On the PC in a pair with the Tech Lead, NOT using and IDE, with access to the Java 6 API on-line, extend program from step 3 with logic to also dynamically return the reverse of the string returned above. (10 minutes)
- If we don't hit the preferred solution the first time, refactor the previous exercise to look more like the code below. (5 minutes)
10:20-10:30 - Candidate Questions/Wrap up/Walk out
One Sample Solution to Questions 3-5 (an actual contribution :-)
class HelloWorld {
public static void main(String[] args) {
String myText = "Hello World";
String myTextBackwards = reverseMyString(myText);
System.out.println(myText);
System.out.println(myTextBackwards);
}
private static String reverseMyString(String myText) {
StringBuffer tempText = new StringBuffer(myText);
return tempText.reverse().toString();
}
}As you can see, there is not a lot to it. You may choose to do much more with the technical audition based on your needs, but some basic exercise such as this or any of the multitude of simple Coding Katas out there will get you started. For the more experienced candidate and/or more tenured role I would highly recommend also having them pair with one or more developers on the team. Just be sure that person has been briefed on what to evaluate so the expectations are clear and consistent. Having a properly planned audition will demonstrate that you are part of a professional organization that takes the hiring process seriously and allow your team to make an informed decision with consistent data points for each candidate.
Saturday, September 15, 2012
Grabbing Photos from the Web with Groovy
I recently had occasion to bulk download some photos from a web based photo album. By "had occasion" I of course mean to say that my wife told me she would very much like to have the photos and I was therefore inclined to get them for her.
The particular site for this effort offers up the photos in a custom javascript slideshow presentation. Intentionally or otherwise, they have obscured the actual location of the photos by burying the URLs. I assume this is in an effort to keep the average user from easily downloading the photos, thus depending on the provider for digital copies and/or printing. It could just be a byproduct of the site design I suppose. A quick peek under the hood, however, and the exact URL of every unique photo was tucked into a variable in the javascript. I cut and pasted the list of URLs from the javascript into a text file and proceeded to write a short piece of Groovy code to go get them all and deposit them on my local machine.
Both file handing and URLs are things that Groovy does pretty well so I didn't figure it would take much. First things first, define the input file:
Next up, run through each line of the file, each of which is the URL of a unique photo. This is easily achieved with the "eachline" methods Groovy gives us, one of which feeds two arguments into a closure, the line and the line number:
The particular site for this effort offers up the photos in a custom javascript slideshow presentation. Intentionally or otherwise, they have obscured the actual location of the photos by burying the URLs. I assume this is in an effort to keep the average user from easily downloading the photos, thus depending on the provider for digital copies and/or printing. It could just be a byproduct of the site design I suppose. A quick peek under the hood, however, and the exact URL of every unique photo was tucked into a variable in the javascript. I cut and pasted the list of URLs from the javascript into a text file and proceeded to write a short piece of Groovy code to go get them all and deposit them on my local machine.
Both file handing and URLs are things that Groovy does pretty well so I didn't figure it would take much. First things first, define the input file:
def inputFile = new File('/SomePath/YourInputHere.txt')
Next up, run through each line of the file, each of which is the URL of a unique photo. This is easily achieved with the "eachline" methods Groovy gives us, one of which feeds two arguments into a closure, the line and the line number:
inputFile.eachLine { lineContent, lineNumber -> ....}
Define an output file to deposit the photo to once it has been read. Uniqueness was achieved in the file name by using a GString with the line number variable embedded:
def outFile = new File("/Path/photo${lineNumber}.jpg").newOutputStream()
Lastly, read from the URL into the output file and close up the output file:
outFile << new URL(lineContent).openStream()
outFile.close()
When it is all assembled it looks like this:
def inputFile = new File('/SomePath/YourInputHere.txt')
inputFile.eachLine { lineContent, lineNumber ->
def outFile = new File("/Path/photo${lineNumber}.jpg").newOutputStream()
outFile << new URL(lineContent).openStream()
outFile.close()
}
So, five pretty easy lines of code and the wife was happy. Gotta love Groovy.
def inputFile = new File('/SomePath/YourInputHere.txt')
inputFile.eachLine { lineContent, lineNumber ->
def outFile = new File("/Path/photo${lineNumber}.jpg").newOutputStream()
outFile << new URL(lineContent).openStream()
outFile.close()
}
So, five pretty easy lines of code and the wife was happy. Gotta love Groovy.
Subscribe to:
Posts (Atom)