вторник, 25 октября 2016 г.

Interviewing Developers

Our company has been experiencing rapid growth during the recent years, which means we were hiring a lot. Managing one of our teams I took my part in the process and conducted a significant number of interviews. When I first faced the task of evaluating a candidate for the software engineer position a couple years ago it felt very awkward and difficult, but over time I developed a general approach that helps me go through the interviews easily and quite efficiently.

Of course the key point about the interview is which questions to ask. In the beginning my attempts to come up with relevant and challenging ones were very painful. I struggled a lot and jumped from one topic to the other always being sure that I miss something important. However, when we speak of technical knowledge and skills, it turns out that the most fruitful questions to ask are quite simple. For example, I usually focus on basic textbook-level Object-Oriented Programming and C# topics. Keeping things simple you may quickly see that the candidate demonstrates only shallow knowledge and, which is more important, inability to explain technical stuff in plain and simple words with reasonable examples. Such an outcome means an end to an interview - if a person can't discuss basics they likely won't be able to reason clearly about the complex stuff that your team deals with. On the other side, the potential employee may show great ability to articulate the subject and its practical implications in such a way that you see the experience behind their words and learn quickly that you're not wasting time with them. In this case you may proceed with more complex problems, but this is rarely necessary unless you're looking for some very specific skills. 

Simple practice exercise have the same advantages and provide enough insight into the way the candidate reasons and knows his tools. Even the easiest programming problems usually give enough room for mistakes and bugs and allow to get a good evaluation of a programmer's skills. It may be a good idea to challenge the candidate with some really serious coding puzzle, but you definitely don't want to start with that. Because the technical interview is to large extent about assessing candidate's abilities to analyze problems and explain solutions we also always offer a logic problem. Being an exercise suitable for the 5th grade or something like that, it still tells a lot about the way a person would analyze the situation and draw conclusions, not to speak of their explanation skills.

Still, you don't want you candidates to spend the whole interview fighting boolean algebra, so you will need some reasonable practice problems. One good place to look for these is the domain that your software models. It is usually enough to spend a couple minutes thinking of what you do on duty to come up with a couple great yet moderately difficult problems. Just keep in mind that these should not require too much context or be too large, so that you can stick them into the timeframe of the interview. For instance, my list of practice problems includes an SQL question that I faced when developing one of our features - it is a pretty real-life yet very simple and thought provoking problem.

While technical questions usually take the most of my interview time, I also dig into the personal experience and attitude. Our HR talks to every candidate before I get to them, but I still find it very important to discuss the potential employee's background and soft skills. Anyway, I have to check whether the person will fit into the team and will be able and willing to do a good job. In additional to usual questions on their duties on the last job I love to ask for a couple achievements, which they feel proud of - people are frequently taken aback and start to dig for their best, which makes the answer very valuable. In addition to unveiling the candidate's experience, such questions allow to assess personal traits. For instance, I can learn a lot about the person's involvement into their job - good candidate would usually be able and happy to speak about their duties and achievements, explain them in depth and do it in such a way that I will get interested even with little context. The way a candidate speaks of his tasks and situation in the office also tells a lot about their attitude and motivation and may uncover teamwork-related risks.

To ensure that both technical and non-technical questions are informative and easy to handle I have them written out carefully and usually ask the same ones, mostly in the same order. Even though this might not seem important, it plays a great role as it prevents hesitation and fears of forgetting something crucial. Additionally, if I follow more or less the same path through the interview, it becomes easier to utilize past experience to spot patterns in the way candidates respond and dive deeper into certain subjects. Finally, this helps to compare candidates to each other, which is quite hard otherwise.

Another aspect of conducting interview, that I find very important, is to be kind. When I am open, attentive and helpful I can definitely learn more about a person than if I demonstrate them my superiority or show that I want to get away as fast as possible. A candidate in an interview usually puts enough emotional pressure on themselves, so there is no need to introduce any artificial stress. This helps not only throughout the interview, but after it as well: I may decide to make an offer and in this case I'd better have the person willing to work with me - not being frightened to death.

Thanks to all these tiny how-to's I got much better at doing interviews, but I still face certain issues. In particular, sometimes I pay too much attention to the person's communication skills. While their ability to speak and listen means a lot and helps both integrate them into the team and teach whatever is important to our business, there are many valuable hires in the world of programming who might be a bit tough to talk to. I also tend to try too hard to find pros about the candidate - in particular when it is already obvious that I won't hire or recommend them. I constantly fight this trait, but it requires a degree of discipline to cut off all of my willingness to understand the person better and say a firm "no" quickly. One inevitable consequence is that my interviews take a lot of time, but at least I know how to shorten them.

Still, the most unpleasant problem about interviewing and hiring may come in the process of making a hiring decision. It can be really tough when I think good of the candidate, but at the same time have a feeling that something's wrong with them. In most cases such sensation means no offer - even though I can't explain what bothers me, the hesitation is a good indicator of hidden problems, which may surface later. In spite of knowing the general rule "doubt = no hire", I sometimes have a hard time making the "no" decision and need to work on that too.

Despite these issues, the simple practices outlined above, like having a regular question list and focusing on candidates' reasoning abilities allowed me to become more efficient and confident on the interviewing side. In particular, this helped to hire several great team-members who have already delivered great results and became valuable employees. Overall, interviewing is not too difficult a process, but it takes some time to get it right. I'm still actively working on improving in this area, so please share your insights and how-to's!

понедельник, 26 сентября 2016 г.

The Inmates Are Running the Asylum

I recently finished reading The Inmates Are Running an Asylum book by Alan Cooper, which dives deeply into the question of how software design should be performed. There are great many interesting ideas and a lot of thoughts that anyone working in a software company may want to consider. Even though I can't agree with the views of the book to the point, I liked it and will try to cover both the thoughts that fascinated me and those that seemed questionable.

At the core of the book lies a simple idea that when we are going to manufacture something - possibly that's a piece of software - we should design it upfront and do that properly. Design at its core means establishing the overall structure of the product mainly from the point of interactions with users - down to UI design, but well beyond it. The term 'properly' is an equally sophisticated thing and expands to many different recommendations, warnings and tools. Some that stand out are: finish working on the design before you start coding; detach designers from coders; use certain techniques to channel design and limit the scope effectively.

The idea that we should put some effort into design before development can hardly surprise anyone. Even those who preach that a programmer should just hack the code till the product is born would likely agree that certain amount of careful and structured thinking has to precede creation of the first lines of code. The explicitly stated suggestion that coders should not do design and even that the designers should better be somewhat isolated from those who program is more controversial. Still, it makes a lot of sense, because programmers (and I speak of myself in particular) tend to focus on implementation details and reduce the domain to the level of their apparent technical capabilities. This strongly affects the point of view and ability to see what we are going to build, for whom and why - we mostly pay attention to how it is going to be built. At the same time, software should be designed not just to be buildable, but to deliver value in an easy to use manner. Our ability to provide value to the users is usually limited by poor understanding of their needs - that's something that most of the programmers faced at least once during their career. With usability we fail in a more subtle way - we make the thing easy to use, but only for the folks that look like ourselves, because that's what our experience and customs drive us to. In most cases, however, the users are people with a very different background, so we unwillingly make sure that they have hard time with our product. While these claims may raise some disagreement, they look valid, even though are not always the best to follow from the practical point of view.

At the same time, I couldn't agree with denouncing of the act of prototyping. The reasoning for claiming it bad is that prototypes tend to stick and in many cases to become the first version and the core of the final product, being least suitable for that due to their nature. That happens because programmers don't like to throw their creations away and managers, avoiding what looks like wasted effort, like it even less. While it definitely can be very hard to get rid of the code that is already written, I still don't think that the technique of prototyping a part of the solution should be disposed of. We should simply use it with care and be ready to dump weeks of our work into a waste bin because the goal of a prototype is not to serve as an actual basement for the final version, but to provide grounds for decision making that brings us to the finished product.

What makes the book very practical and valuable is the design tool that Alan offers - personas. The idea boils down to making up a narrow set of characters that depict future users of the product and allowing these fictional dudes to wholly drive the design process. Interestingly, the book suggests that the design team should give each persona a name and photo, assign user roles and thoroughly describe their background. Such characters would allow to speak of the product in terms of the needs of concrete, although unreal, people who are expected to use it. I must admit that I have never tried this approach, but it seems very powerful to me, because it gives a framework to ask proper questions about the thing in the making and to ensure that design stays on the right track, as we develop the product exclusively for our personas. This means that if there is no persona that needs a particularly fancy button, the button will never make it into the final design. The book goes even further with this suggesting that in most cases it is not right to subside to the customer's attempts to squeeze another feature from the development team unless our personas justify it. This idea rests on the assumption that a good design based on the right set of characters would cover the needs of the user, while anything that is injected into the product in spite of the design will give birth only to inconsistencies that will eventually ruin the software. Sure, rejecting client's request is a tough thing to do, but there is something to the idea of declaring clearly what your user looks like and staying by that declaration - it could certainly make some of our creations more consistent.

While I liked most of the core ideas in the book, it still raises concerns in regards to its practical applicability. The problem with the entire design framework presented by Alan Cooper is that it requires great upfront costs with the possibility of getting nothing but experience as an outcome. The biggest share of these costs comes in the form of the time spent without delivering any kind of a marketable product. In the modern world, when everyone strives to squeeze time to market as much as possible, it is difficult to take a path that promises to double it (in the best case). It also seems nearly impossible to incorporate this design and development methodology into an existing process - it can work great from the beginning, but when there are established constraints of an existing product, anyone trying to inject a serious design into a working motor will likely fail.

Overall, I definitely recommend this great practical book to anyone working in the software industry, as it gave me a new perspective into the development process and explained some very useful tools like personas. It also conveys greatly the idea that usability is born - or buried - deep under the hood of any software and can't be just added on top of a finished product, which is something that you want to keep in mind. Finally, a ton of examples - both related to software and beyond the industry - show that many things that we use nowadays are designed poorly and are still hard to use, which means there are lots of opportunities for making the world a better place.

понедельник, 29 августа 2016 г.

Developers on Watch

In a software development company that works for external customers it is common to spend significant amount of time dealing with external issue reports. While being tedious, this activity still conceals great potential for the development team's efficiency improvement and professional growth. At the same time this process is frequently organized in such a way that it never allows to get these benefits. In particular, that was the case in our team not so long ago, but we were able to change this for good.

Developing the ERP product we do face lots of support requests from our customers, some of which get escalated to development and turn into bug reports or new functionality proposals. Originally, there was a single person responsible for monitoring the queue of such items in each development team - the team leader. He would constantly keep an eye on the list of new bugs, analyze them one by one, which sometimes means debugging, comment them to provide first clues to the reporters and ensure that they are handled in a timely manner.

This approach has apparent problems, the most obvious of which is the lack of resilience. When the team leader is suddenly out of office, it is difficult for the team to take charge of the incoming requests because no one is used to the process. And even when the lead's absence is planned certain effort is required to ensure that someone on the team knows what to do about the queue and understands his responsibility for that - again, because the team members are not familair with the activity. This approach also puts significant load on the team leader and reduces his availability for other tasks - both organizational and development - which is rarely what we want. At the same time, when he actually has to do other job, fresh high-priority issues may be assigned to other developers and disrupt their plans in a chaotic manner. 

To get the idea of a better organization of this process it is worthwhile to examine the things that constitute it. Handling of any external request always starts with analysis of its validity, asking for additional information from the reporter, search for similar requests in the issue tracker or forwarding the problem to another team responsible for it. Subsequent analysis may require debugging and playing with the application and is usually aimed at both tracing down the root of the problem and providing a workaround or hotfix if it is required. In some cases one may produce the actual fix for the problem in the code - usually that happens either when the fix is simple or if the issue is very urgent (bad motivation, but that's another story). Frequently, though, the process ends with consolidating all the obtained information in the issue report and dispatching it to the most appropriate developer to be fixed sooner or later. The common feature of all of the above tasks - except possibly choosing the right assignee and implementing the actual fix - is that they can be done by any developer. Combined with the problems outlined above this idea brings us to a reasonable alternative implementation.

Instead of forcing all the activities associated with analysis and distribution of the new issue reports on one person it is way more efficient to evenly distribute this activity between all the available developers. The easiest way to organize this is to have them take turns so that each week one developer is fully responsible for managing the queue and has very few or no other tasks - in our team we call it Watch. While this process does require some degree of organization, it is not very difficult to put together. One has to carefully maintain the sequence of watchers and ensure that each team-member knows when it's time for him or her to go on duty. It is also crucial - especially at the beginning - to produce a piece of internal documentation explaining what processing a new issue report means and conveying the objectives of the process clearly. Major goal here is to encourage communication between the person who handles the requests and all the other team-members, such as product managers, other developers and support - it is vitally important for proper analysis of issues and for making the right choice of the way to handle them. Finally, to make sure that everyone who goes on Watch is efficient at it, someone should monitor quality of the results - this can be done by means of a regular review of several random closed cases with each developer or through any similar process.

While, unlike the original approach where one person is fully and permanently responsible for the job of handling incoming requests, the Watch process requires a bit more effort to establish and maintain, its enormous benefits to the entire team fully justify the cost. Most obviously, it enables better load balancing and - through explicitly securing one developer for unplanned activities - better planning. In addition to that it makes the team more resilient improving distribution of knowledge on different aspects of the product between team-members. This is especially helpful when there is a degree of specialization in the team. Importantly for support and customers, such organization also decreases the time required to respond on a ticket, because the developer in charge of the queue is not loaded with other tasks and focuses solely on making the issue reporters happier. The fact that the process encourages collaboration and forces regular changes of the work mode - between development and support-like activities - contributes even more to the overall efficiency. Finally, when developers face a load of raw external bug reports from time to time, they become more aware of customers' needs and position and thus more motivated to do a better job.

As usual, these benefits don't come at no cost and there are some problems that one may face while establishing Watch in a development team. In particular, developers accept this activity differently and some may really hate it - especially in the beginning - which may require additional management work and certain adjustments. The way people handle the bug reports also may differ. For example, some initially focus on fixing items instead of doing faster pre-processing to provide quick response to the customer and adequate information to the person who can address the issue better. Or it may happen the other way around and you may face a situation when very little analysis is performed before stacking a request into the backlog. What may be most scary, almost inevitably performance of the team will drop after the process is introduced - each week one developer will devotes all of his or her time to an unfamiliar activity instead of actual development, but this is a short term effect and it diminishes quite quickly.

We faced some of these issues when we introduced this process in our team, but despite this the change looks totally positive. The fact that I, as a team leader, got partially freed of this activity and now have more time for other business obviously makes me happy, but its effect on our cumulative efficiency is way more important. In particular, the process boosted developers' expertise and domain knowledge growth significantly. I also saw it work great during my recent vacation without any extra effort on my side - last year it was different. However, what surprised me most about this organizational change is that, while originally I expected a strong pushback it was accepted positively by the teammates. So it is almost a year since we began our Watch and I'm absolutely sure that I would never go back to the old way of handling incoming issues.

воскресенье, 17 июля 2016 г.

Everyone on your team is important

Over the course of my career in software development I got used to the idea that the key thing we deal with everyday is complexity. It shows up on different stages of our jobs, but most interesting cases are of course tricky bugs. Sometimes the issues reported by our QAs and especially by end-users get so messy that it takes a full crew of professionals to fix them. I have faced one such example recently and in addition to providing valuable experience and the feeling of satisfaction in the end, it served as an evidence supporting that all the roles we have in our team are of great importance and play best when assembled into a team.

About a year ago we have fixed a couple minor issues in our system. To be sure that we have that piece of functionality working properly despite any future changes we decided to create automated tests for it. Our QA engineers did get to this task, but because life is what happens when you have other plans, that happened only recently. Roughly at the same time another member of our team has found an issue in a distant part of the system, totally unrelated to that first bug, and fixed it using a certain code construct.

Once these two things met in our repository the new tests failed. It so happened that the developer who was digging into the failure wasn't in any way familiar with any of the two changes. The error conditions turned out to be tricky, so some folks joined investigation and it was eventually traced down to that seemingly unrelated last fix to be routed to the appropriate platform developer and fixed there. The importance of this event however took some more time to be recognized.

Another chapter of this story starts several months earlier. One of our customers filed an unpleasant data bug that we never managed to reproduce and understand. It was hanging there unresolved and made partners, so to say, unhappy. It's high severity kept it visible for us, but we still weren't able to do anything about the issue - till the moment when the events described in previous paragraphs took place. When I was doing a daily review of recent and priority items, I stumbled upon this nasty bug first and then spotted the one that caused all the mess outlined above. Something about them looked similar. The way the latter one was fixed suggested a new idea for repro steps for the former. Late at night this fresh approach was attempted and yielded positive result - we not only understood the reason behind the high-priority issue, but also knew that it is now fixed and could report that to everyone concerned - the problem was with the same code construct and the same platform issue that started the first bug.

This basically means that the data problem that we were so worried about took us a couple QA engineers, two developers, a product manager and a team-lead doing their usual jobs to track it down and fully understand - not to mention the significant amount of time spanned by all the activities that led us to this result. This might indicate problems with the product being developed or with the process, but the truth about software development is that such problems that eat enormous resources do happen and, if you are working on a large and sophisticated piece of code, you can only minimize them - not get rid of them completely. Complex issues also require different people to handle them - sometimes just to throw enough pairs of eyes and points of view at the problem. Even worse, there is an element of a slot machine to this requirement, because you can only partially design how and when someone of your team-mates will play his role in such a process - in most cases these revelations and discoveries happen merely because a number of people are doing their work properly.

Software development is sometimes messy work - especially when we speak of business applications. I would like to say that it doesn't have to be like that, but it seems that for most products getting complex enough to give birth to problems of this kind is just a matter of time. As a result we do need all of our people in their positions - QA engineers, developers, analysts and so one. This incident that we faced highlights the fact that even when I have no clue at all about the job that some people are doing at our office, it is still very valuable. The beauty of a development company and its processes is that one day any one of us - or rather an unexpected combination of our efforts - may save the company from something nasty or bring it to a new solid achievement. This simple idea is also a great motivator, because when I get tired with the routine and think that the work I am doing is useless, I can remember how almost the whole our team won the battle with that bug and see that one day me doing my job may save some thousands bucks for the company and countless hours of work to my colleagues.

вторник, 14 июня 2016 г.

Take-aways from the Getting Things Done book by David Allen

Over the recent years I heard about the Getting Things Done methodology here and there, but only recently I finally read the book by David Allen and got closely acquainted with its idea. It turned out that I already employed some of the techniques that make up this famous self-organization system, but in most cases never acknowledged that there are bits of GTD among my tools. More importantly, the book taught me some new tricks and the proper way to combine and use the tools.

The most well-known bits of GTD are inbox and action lists. The inbox is used to record every bit of information that arrives to you for subsequent sorting. The action lists - to keep track of the actions that you need to take on duty, at home, when there is time to make a call, etc. I was already confidently using these by the time of reading the book, so this part didn't surprise me. The concept of projects, however, was more of a new thing to me. In Allen's terminology a project is anything that you're going to do and that will take more than one step to accomplish. This a bit unusual understanding of the term is combined with the idea that one must maintain a full list of their projects and review it regularly to decide on next actions. This implies that every week you take time and go through the entire list and for each project decide what you will do next to get the thing moving forward - and add these actions to your lists. This (quite obvious, to be honest) way to handle projects is my most valuable take-away from the GTD book, because when I am serious about weekly reviews it results in advancing a lot of things that I would normally forget about. Instead of making me drown in a chaos of numerous small projects, which I originally expected, this approach actually helps me follow all the projects that I deem important and makes sure that each of them is gradually moved to completion.

Another idea that resonated with me greatly was that one should have a reference info storage and have it in perfect order. And the order here is not just a matter of beauty, but a quality that allows one to put something in easily or to get whatever they need at a particular moment quickly. One manifestation of this idea is that reference information gets separated clearly from the next actions information. For me this played a huge role, because I'm the kind of a person who's obsessed with historical data, archives of all sorts and being able to remember what I was doing on a particular day three months ago. While this might be important in some cases, to achieve results one should see the current context and aim for future, using the past only as a reference. This transformed some of my routines a lot and helped to progress more efficiently both at my work and with other parts of my life.

Another goal that one sets when implementing GTD is to build a reliable system of reminders and ensure that one remembers the right things at the right time. That's the famous wait list as well as the usage of the calendar and even the checklists (which I embraced as a great tool before diving into GTD). It turns out, however, that there is only one way to achieve this goal - that is to organize all the information on next actions and events properly and review it regularly. Regular routines seem to be the second pillar of GTD - together with ordering your life. These are applied virtually to everything - from the mission and principles to the projects and next actions lists - and I can confidently say that regular reviews of my current standing are so critical to efficiency, that I could get little use from the GTD system without this bit. On the other hand, having finally developed a habit of doing these reviews, I now see way more control over different parts of my life and a significant increase in ability to control progress towards multiple unrelated goals.

There are many other useful ideas, but David Allen certainly explains them better than I, so if you're interested you should read it. I was quite impressed - in particular, because it was easy to apply some of the suggested approaches and to see how these yield more control over my life. Another thing that makes the book a great read is that it is very practical and goes to the level of an engineering textbook into the details of organizing yourself. At the same time it doesn't offer a magic pill being pretty honest about the amount of time and effort that one has to invest into personal management to implement the suggested approaches. If you're OK with that and are interested in pursuing efficiency, I do recommend to read the book and to make that investment because it will pay off quite quickly. Have a nice reading!

воскресенье, 15 мая 2016 г.

Using an external JavaScript library in your ClojureScript application

My recent playing with ClojureScript and Om was a great trip into the field of functional front-end programming. However it was disrupted by a small yet irritating problem. I wanted to consume an external JavaScript library - the client for Trello API - in my Om application and call a method of the object defined there. It all worked fine while I was developing the thing, but the first attempt to deploy it to the production server resulted in my application not working and spitting errors like "Trello.rf is not a function".

This problem is caused by ClojureScript munging names during compilation, which is disabled - as well as other optimizations - in the default dev profile. Because the idea of using an external JS library is not something completely stupid, there are some ways to avoid munging external names - outlined here and here. The approach with the externs file is quite easy to adopt, but it took me some experimenting to make it work, so I will describe it step-by-step here to have a reference in future.

Inputs first. I have a ClojureScript Om application enabled by cljsbuild 1.1.3. The compiled JavaScript is served from the /resources/public/js folder (or from somewhere under it). My application uses the Trello client JS library to make one call to the Trello.authorize method. The Trello library has to be brought in through the index.html like this:

<script src="https://api.trello.com/1/client.js?key=myappkey"></script>
<script src="js/compiled/trellodonelist.js" type="text/javascript"></script>

To prevent ClojureScript compiler from turning the names defined in the external library into strange symbols we only need to introduce an externs file and supply its name to the compiler. All this is done in three simple steps:

1. Create a plain JavaScript file and store it in a place where the compiler will be able to find it. I chose /resources/public/js/externs.js (the name doesn't matter that much).

2. In the externs.js file touch all the names from external libraries that you plan to refer in your app. For me that looked like:

var Trello = {};
Trello.authorize = function() {};

3. In your html refer the externs file along with the external library and your compiled ClojureScript:

<script src="js/externs.js" type="text/javascript"></script>
<script src="https://api.trello.com/1/client.js?key=myappkey"></script>
<script src="js/compiled/trellodonelist.js" type="text/javascript"></script>

4. In the project.clj file add the path to the externs file in a vector under [:cljsbuild :builds :app :compiler :externs]. You aim for something like this:

(defproject trellodonelist "0.1.0-SNAPSHOT"
  ; various meaningful things
      {:source-paths ["src/cljs"]
       :compiler {:main trellodonelist.core
                  :asset-path "js/compiled/out"
                  :output-to "resources/public/js/compiled/trellodonelist.js"
                  :output-dir "resources/public/js/compiled/out"
                  :source-map-timestamp true

                  ; this one
                  :externs ["resources/public/js/externs.js"]}}}}

  ; other meaningful things

I had to play a bit with various locations of externs.js and missed one thing or another, but the above setup finally did the trick. Now, even if the ClojureScript is compiled with all the optimizations, the compiler is aware of the names brought in from the external libs and won't change them.

There are some other ways to make external names work and I recommend to read the articles mentioned above to get a better understanding of the reasons behind the issue and a wider set of alternative solutions. For my simple case the self-made externs file seemed the easiest and the most concise approach - maybe it will suit you as well. Happy coding!

воскресенье, 1 мая 2016 г.


Some months ago we wanted to get a new developer on the team. My personal desire was to get him as soon as possible and of course I needed our recruiter's help with this. We had a short discussion with the lady about the kind of a person we'd like to hire and I was sure that we got on the same page and seeing the right candidate is only a matter of days. However, some weeks passed and I wasn't getting any resumés and not a single interview was scheduled. I was concerned almost to the point of going to the recruiter with the WTF?! expression in my face. Fortunately, though I chose to spend some 20 minutes writing a short description of two types of candidates that fitted my needs and emailing these to her.

What happened next surprised me a lot. Almost instantly I started getting a constant stream of CVs that matched my descriptions. It took us a couple days to schedule the first interview and only two or three weeks later (which means pretty soon in this context) we made an offer to a bright young fellow.

This story taught me a great lesson. I may believe that I have agreed on the goals and plans with someone, but if there is a slightest chance that doing some simple thing may help them get going I should do it without doubt and waiting. Spoken agreements made with your peers in a walkway are rarely clear and may easily get pushed away by newer and more comprehensible tasks coming from elsewhere. On the other side, taking some initiative to follow up and elaborate the problem may bring tremendous results.

Another example that I have on the same matter is concerned with an internal knowledgebase for developers. Despite having a vast code base rich with patterns and non-trivial solutions to various problems, we had limited guidance on this treasure and the reasoning behind its bits. Certainly our developers could benefit from a knowledgebase that would collect advice on various development questions.

I had a plenty of ideas on why we didn't have the knowledgebase, including the conspiracy theory that my other colleagues knew why such a thing wouldn't work. It turned out, though, that the only real reason for its absence was that being loaded with other tasks we simply didn't chose to set it up at some point. Thus, once a dedicated section was created in our internal wiki and declared a place to store all development-related knowledge, I started seeing different people contributing an article or two or simply voicing  support for the idea.

Starting things is difficult and if that's true for you, it's likely the same way for your friends and colleagues. Sometimes people lack a clear picture of the destination, in other cases they simply don't perceive the goal as important to anyone. No matter what's the core reason, just showing some gentle initiative may be enough to start the fire and get things going. It's only important to remember that initiative is not just about talking or thinking - it's all about acting, making the first step and showing the way.