Wednesday, January 30, 2008

BT in Software Engineering

Many people have the opinion that Computer Science graduates are not being well prepared for the road ahead, and I completely agree. I don't want to repeat any of the arguments or my personal take on the exact problems with today's curriculum, but I do want to broadcast an idea of where the solution needs to come from.

I think we need to separate Technology from Science and the Arts. I want my (future) son to go to a 4-year University and get a Bachelor of Technology. Science relates to facts, theories, and formulas. Arts relates to creativity, culture, and individualism. Neither of these describes technology related fields, and coming to that realization is what we need.

We've seen the beginning of it. New buildings on campus to house computer science and other engineering programs. The equipment that students interact with has changed. But did the way we teach change?

Our world isn't built on formulas, theories, and laws like the traditional science programs. Our world is built on best practices, innovation, collaboration, adaptability, and abstract concepts. You can't learn best practices from a book. You don't experience innovation through canned programming assignments. Collaboration isn't taught by sitting in a classroom with 50 other students, staring at a projector screen. The world has evolved and so should our teaching methods.

AgileTeams: What does it take to be Great?

It can take some time, but with the right guidance, an agile team can become good and solid relatively quickly. It depends on many things like how much experience each individual has working on an agile team to the meshing of the best practices each has picked up along the way. However, taking the team to the next level can be difficult. In my experience, the items I've listed below can take a good agile team and turn it into a great agile team. At a glance, they don't seem like anything difficult, yet for some reason I've seen teams struggle with these items over and over. However, when a team does reach that point where all these items are coming naturally, you see a big difference in productivity, efficiency, communication, and sense of ownership. Let me know what you think.

1. Use of the Project Tracking Tool


Whether you're using ScrumWorks, XPLanner, note cards, or another project tracking tool, here are a few things I've picked up that seem to really make a difference.


1) Lump Sum Tasks

Sometimes when you come out of backlog selection, you've got a thorough understanding of what it takes to complete a story, and sometimes you don't. If you're not quite ready to break the tasks down completely, just enter a lump sum task. As you identify individual tasks, remove hours from the lump sum and place them in your new task. The goal here is to eliminate surprises. You don't want your team thinking that you're almost done with a story, and then for the next 2 weeks you just continue to add new tasks out of the blue.

2) Overhead
Don't make the mistake of thinking your project tracking tool was only built to track user stories. By leaving out overhead tasks that are going to take up your time, you're depriving the team of having a true understanding of what needs done. For example, say your team has the responsibility of managing a small open source project. When a support request comes in from the community, identify it in your project tracking tool. You don't want to hide the fact it's something that needs done.

3) Enforce Updating
This is a big one. As easy as it is to update your project tracking tool each day, it seems just as easy to forget. This one is easy to address though. Just show your project tracking tool during the daily stand-up. When people give their reports, they should point out the exact tasks they're reporting against. It becomes very apparent when the tool isn't being updated as it should be. You get someone saying they've completed a task, but for some reason it isn't shown as completed in the tool.

The point here is to maintain high visibility into the current progress of the sprint and its individual stories and tasks.



2. Accountability


An Example:
I report Monday that I'm going to commit to finishing tasks ABC and DEF, each taking approximately 4 hours. Tuesday I give a report that I completed task ABC and that I'm going to commit to finishing task DEF today.

This should immediately throw up a red flag for you. 8 hours of work just turned into 16 hours of work and everyone should be asking why. What are some scenarios as to why this is now going to take me twice as long as I reported out yesterday?

1) Task ABC did only take 4 hours, but I'm really stuck on task DEF.
In this case, I'm saying that I think task DEF will take me 3x as long as I originally thought. That's quite an increase in hours. If this situation was exposed in the daily stand-up, the team could make the decision as to whether or not I should get some help instead of trying to tackle it on my own.


2) Task ABC ended up taking me 8 hours, and I think the same will happen with DEF.

This is a signal that I'm consistently underestimating the time it will take me to complete a task (or at least tasks of this nature). Someone should point this out to me and encourage me to analyze the situation so that I may be able to improve my accuracy in estimation.

3) I've had something come up and was in meetings half the day Monday. The same will happen again Tuesday.
Apparently I didn't think it was a big deal that this work would take 2 days instead of one. Maybe however, one of my other team members was expecting me to be available this afternoon and needed my help. In this case I failed to report an impediment that showed up and kept me from completing these 2 tasks on schedule. In addition, I didn't relay to the team that I would be unavailable this afternoon.

4) I felt like playing Solitaire for half the day and only got around to working on task ABC.
In this case, you've got to expose me as a slacker. I'm holding back the team by only giving about 50% effort. The team could do much better with another resource in my place (read this).



3. Sprint Retrospective


The sprint retrospective, in my opinion, is one of the most overlooked tools for improving team performance. Having the opportunity to sit down and reflect on the previous sprint(s) is priceless. However, it's not good enough just to identify what went well, what didn't go well, and areas for improvement. You MUST act on your findings.

If you've seen concerns or areas for improvement come up over and over again in your retros, someone should be waving giant red flags all over the place. It's THE signal that you're not making the most of your retro. It is crucial that your team takes the initiative to act on the items you've identified. This doesn't mean just saying, "Lets all try to work on {areaOfImprovement} this sprint." Put in the extra effort and track these items. This could be done in your project tracking tool, or maybe by revisiting your action items at a certain interval throughout the sprint.

Wednesday, January 23, 2008

Trust All Certificates

Need to establish an Https connection and don't care about validating the server's unsigned certificate? Don't want to mess with importing the server's certificate into a local keystore? This won't show you how to ignore those SSLHandshakeExceptions due to unsigned certs, but it will show you how to get rid of them all together!

Step 1:


Implement the X509TrustManager Interface as follows.

public class TrustEverythingTrustManager implements X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}

public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { }

public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { }
}


Step 2:


Implement the HostnameVerifier Interface as follows.

public class VerifyEverythingHostnameVerifier implements HostnameVerifier {

public boolean verify(String string, SSLSession sslSession) {
return true;
}
}


Step 3:


Initialize an SSLContext with your TrustEverythingTrustManager and set the context as the default SSL socket factory on the HttpsURLConnection class.

TrustManager[] trustManager = new TrustManager[] {new TrustEverythingTrustManager()};

// Let us create the factory where we can set some parameters for the connection
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManager, new java.security.SecureRandom());
} catch (NoSuchAlgorithmException e) {
// do nothing
}catch (KeyManagementException e) {
// do nothing
}

HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());


Step 4:


Open the connection and set your VerifyEverythingHostnameVerifier as the HostnameVerifier.

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new VerifyEverythingHostnameVerifier());



Thats it. Done and Done!