StarTeam install woes

Share:        

I spent two hours trying to figure out why StarTeam 2008 Release 2 Client wouldn’t install correctly on my machine. Whenever I’d launch it, I’d get a “Could not create the Java virtual machine” error.

Rather than being a problem locating the Java Virtual Machine, as I’d previously thought, turns out it’s a memory allocation issue. In StarTeamCP.stjava, the default option set is “-Xmx1024m”. My machine doesn’t have a gig of RAM to spare for a Java VM, hence the error. By setting it to “-Xmx512m”, I was able to get up and running.

I’m posting this in the hopes someone can profit from my struggles this morning. Deep shame be unto Borland for:

1) Making the default 1 GB, which is unrealistic for quite a few machines, mine included
2) Not putting it in their Platform Notes with the release documentation.


Pulling names from a hat with LINQ

Share:        

Each week at work, we have a Lunch and Learn sessions for developers. Sometimes, we assign a programming problem, and people solve it during the course of the week and present their solutions in the following session. Lately, even though we’re a C# shop, we’ve taken to getting problems from RubyQuiz. We’ve found them to be a good fit for us, as most of the problems can be solved to some degree within the two hours per week we’re alloted for skill development.

We recently assigned the Secret Santas problem. For those of you who don’t know this Christmas tradition, some large families and groups have enough people that it is a burden to buy every other person a present. Instead, each person draws a name from a hat, and buys a present for just that person. The full problem description is at the Ruby Quiz web site.

Solving these problems isn’t a serious challenge, but looking at the - approaches people take is fascinating.

The approach I liked best was my co-worker’s, who used a ring. In real life, essentially he would had everyone form in a circle in a random order, and each person gave a gift to the person on their right.

I chose to put the names in a collection, and to use LINQ to pull random members from the collection. It turns out this concept can be rather useful, so I’m presenting it here. As with everything in this blog, it’s released under the Creative Commons Attribution 3.0 Unported license.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Domain
{
    public static class IEnumerableExtensions
    {
        //private static readonly RandomNumberGenerator RNG;
        private static readonly Random _random;

        static IEnumerableExtensions()
        {
            // 8 ms to initialize
            _random = new Random();

            // 650ms to initialize
            //RNG = RandomNumberGenerator.Create();
        }

        // ~80 ms/record
        private static int ChooseRandomIndex(int range)
        {
            return _random.Next(range);
        }

        // ~10 ms/record
        //private static int ChooseRandomIndex(int range)
        //{
        //    var bytes = new byte[4];
        //    RNG.GetNonZeroBytes(bytes);
        //    uint randomInteger = BitConverter.ToUInt32(bytes, 0);
        //    return Convert.ToInt32(randomInteger % range);
        //}

        public static T TakeRandomOrDefault<T>(this IEnumerable<T> sequence)
        {
            if (!sequence.Any())
                return default(T);

            return GetRandomItem(sequence);
        }

        public static T TakeRandomOrDefault<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
        {
            return TakeRandomOrDefault(sequence.Where(predicate));
        }

        /// <exception cref=”ArgumentException”>sequence</exception>
        public static T TakeRandom<T>(this IEnumerable<T> sequence)
        {
            if (!sequence.Any())
                throw new ArgumentException(sequence, Cant get random member of an empty sequence);

            return GetRandomItem(sequence);
        }

        /// <exception cref=”ArgumentException”>sequence</exception>
        public static T TakeRandom<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
        {
            return TakeRandom(sequence.Where(predicate));
        }

        private static T GetRandomItem<T>(IEnumerable<T> sequence)
        {
            int chosenIndex = ChooseRandomIndex(sequence.Count());
            return chosenIndex > 0
                       ? sequence.Skip(chosenIndex).First()
                       : sequence.First();
        }
    }
}

From looking at the code, you can see that I tried different random number generators. I wasn’t surprised that the RandomNumberGenerator from the System.Security.Cryptography namespace is expensive to construct, but I found it interesting that it gets random data appreciably faster than the Random class. My benchmarking wasn’t extensive, just some elapsed times gleaned from running my unit tests.

Enjoy!


Whole Basketball Team

Share:        

One of the thornier agile concepts around my workplace is what XP calls “whole team”, where people put getting tasks done over their job titles.

I got to demonstrate this firsthand in my team this week, as we’re completely blocked by some testing tasks. We have a practice in place forbidding developers to write test cases for their own code (which would be a bit like students writing their own final exams), but we can certainly execute test cases written by others on the team. Can, being the key word.

I like to think of scrum teams like basketball teams. (Rugby’s not big here.) And, of American professional sports, basketball suits scrum well. Here, I’m referring to the role players play on a team. Everyone plays defense. Everyone plays offense. Everyone takes a shot at the basket sometimes. Yet everyone has a specialty. One guy is a 3-point man. Another blocks shots.

On my scrum “basketball” team, I’m definitely a forward and the team captain. I score 20+ points a game, 10+ assists, and call the plays on the court. But yesterday, I took to the court as a QA shooting guard.

That’s right, to the amazement of some of my developer colleagues, I executed some test cases in Quality Center, our test tracking tool. It was an educational experience!

The team’s QA specialist and I learned some interesting things. He learned that his test cases assumed some tribal knowledge that wasn’t in the test scripts. I learned that this particular troublesome piece of functionality is hard to test. In troubleshooting, I learned some interesting things about the environment and how the moving part I’d been enhancing in isolation fit in its habitat. And I may have even uncovered an issue! :)

I’d highly recommend the experience of doing another person’s job for a day, if you get a chance. It can be rather refreshing and eye-opening! Honestly, though, I’m glad to be back playing forward again.


Review: Pragmatic Thinking and Learning

Share:        

I had a chance to read Pragmatic Thinking and Learning: Refactor Your Wetware when the office was not exactly closed, but brought to a standstill by heavy snowfall. I work right upside the Front Range in Golden, and we were getting inches of snow in an hour, and people were genuinely concerned about being able to get out of the parking lot if the snow continued much longer.

The book brings some of the latest cognitive science to software engineers. Andy Hunt begins by explaining the Dreyfus Model of Skill Acquisition, which marks the transformation people make when acquiring a skill in five stages: novice, advanced beginner, competent, proficient, and expert. He applies the model to learning, explaining what people at each stage need to continue learning, and what traits they must acquire to proceed. For example, it explains why the mandatory training at work is so ineffective for me: the corporate videos assume that I am a novice, whereas I am at least competent at skills like navigating ethical dilemmas and security consciousness.

Next, the book offers a model of the mind as a computer. As a professional in the computing industry, I found the model compelling and elegant. If you gravitate towards this analogy as I do, you would love this book. He talks about L-mode (linear) and R-mode (rich), and how to get the most out of R-mode. These used to be labeled left-brain and right-brain thinking, but researchers know now that both modes of thinking can occur in both hemispheres. L-mode is single-threaded and plods along linearly and literally. R-mode is like Google, a pattern matching dynamo, but that can’t communicate verbally. The techniques to invite R-mode to play are well-presented.

The book moves on to talk about the “bugs” inherent in the wetware (cognitive biases) and ways to overcome them. Most of this section was good refresher for me, but I found the section on generational bias the most interesting.

Finally, the book delves into techniques to facilitate the journey. I already use quite a few of these techniques, such as GTD (David Allen’s “getting things done”) and maintaining an “exocortex”. I would be lost without my notebooks! I certainly intend to use a Moleskin for my next notebook. I also use FreeMind, a mind-mapping tool. In fact, the notes I took while reading this book are in that tool.

I wish that Mr. Hunt would have gone into more detail in some areas. I found myself saying, “Thank goodness I already knew about that.” But, then again, I didn’t find the need to research much further, except extended learning about the Dreyfus Model, so perhaps this is a testament to Mr. Hunt knowing his audience.

I recommend this book heartily!


What a difference a day makes

Share:        

In less than 24 hours at work, I completely changed the direction of my scrum team and had most of us co-located into an office.

After a laborious release to add some functionality to a tightly-coupled area of the application, I wrote a proposal, which was accepted. Our team was working on a re-imagining of a piece of our product as a module guided by domain-driven design. Management trusted our judgment and supported the project, but some of the senior staff didn’t get it. There were a lot of questions: “Why are you re-writing the … ‘module’?; it works fine” and “What is it you’re working on again?” We’ve been talking about our plans in detail in our developer’s book club and “lunch and learn” sessions, but only a third of the development staff showed up regularly. There were other barriers. For example, our requests to co-locate were met with the assessment that our team wasn’t the best size fit for the recently-vacated office we were vying for.

Tuesday afternoon, the whole product team had a meeting about our goals for 2009. I said our scrum team was worried about communicating the architectural changes we’re planning, because, in many ways we’d been preaching to the choir and wanted to expand our audience.

Then, a quiet-spoken, well-trusted senior architect went on a rant. I don’t know how else to describe it. He was upset about the project’s bug count, which had increased noticeably last year. He was worried that the division’s hellbent focus on new customer functionality sacrificed product stability, and would not concede the point. The product owner got upset, because she felt her resource constraints were clear and pointed out no team would sign up for just squashing bugs. The COO, quietly listening in the back, pitched the idea of farming out some of the work to resources outside our office, but the idea was met with skepticism. (For the record, I supported the idea. A few bugs we don’t fix is better than zero, yielding dividends in the long run.)

Afterward, I talked with my cohort and shared the idea that was forming in my head. Our team would take that bug-slaying assignment. We have several projects with client commitments for the next few months, and we’re having trouble getting people on-board with the domain-driven design approach. This combination seems like a wonderful opportunity to do some education and get more people involved in the up-front modeling that’s required. In return, my only stipulation was a firm commitment to resuming the project once the client went live.

My manager wasn’t overjoyed with the news, but saw the wisdom in it after I explained the rationale. He made my development partner in crime and I swear we would stay until the end of the year. And, he tasked us not to do the bug-slaying in a piecemeal fashion, but to take the time to also fix design flaws as we encountered them. I added that we’d be laying some foundation for the new architecture – putting interfaces in place, adding dependency injection, and the like.

We also got another concession: sanctioned work time for us to develop training materials and a couple hours a week each for people to practice these new skills.

And, miraculously, when management embraced the bug-slayer idea wholeheartedly, the room fell into our laps!

I went home Tuesday worried about what I’d signed myself up for.

Yesterday morning, we moved in. The room had already been set up for a team, but I didn’t like the arrangement of the furniture, so I changed it. The room had been ringed with 4-foot tables along the walls. Instead, I wanted to replicate the feeling of having cubes partially separated with half-height walls. It allowed my mate and I to talk freely, and offered just enough sound buffering.

I lost square footage and my whiteboard (temporarily), but I gained a window seat in a semi-quiet space. I set two of the tables facing each other, relying on our monitors to mimic the cube walls. Having my cohort sitting across from me has made conversations much easier. Instead of IM or walking through the maze, we just look at each other. Already, we’ve been able to plan how we’re going to teach DDD to the rest of the group while working on getting the “Bob Zombie” project out the door at the same time.

“Bob” is a play on the project number (“808” => BOB), and “Zombie” is a commentary on the former state of the project. Bob Zombie is definitely a cautionary tale about calling a project “done” before it’s “done done”. After it was declared done, the team was disbanded, only later to discover an emergent requirement. Without resources, it languished for months. Until now.