воскресенье, 13 декабря 2015 г.

Focus

There was obviously little activity in this blog during the recent months and I feel great returning here. The blog always gave me an opportunity to step back and think over my actions and choices. However, this year I was so focused on a single thing - my day job - that only one post had made it here. Now I want to check with myself what this attitude gave me and what it stole from me.

Last February my priorities changed dramatically. In about two months after becoming a team-lead I discovered that whatever I was doing was not enough to do good with new duties. I was both overwhelmed with the tasks and problems that fell on our team and saw clearly that we don't perform as good as we could do. Part of my natural response to this discovery was to ramp up the amount of time that I dedicated to the job.

There are lots of reasons why I'm happy with this choice. Firstly, putting more effort into work made me learn a lot and build up new skills in the areas of my responsibility. Because it was my duty to process all the requests that arrived at our queue, I learnt to do this efficiently and obtained a lot of domain knowledge. In other words, it turned out that it's enough to push me into a partially familiar field and show no way out to make me learn it deeply. My expertise grew enormously over the last year and being really focused on the job helped here a lot (yes, there are lots of things in my field that I still don't know or understand not good enough - I'm speaking only of the delta). Moreover, spending a lot of time studying and resolving various issues - some being totally unclear at first - I not only learnt new areas of the domain, but also developed a skill of learning faster.

At the same time, through spending extra hours on duty I came to see clear that sometimes one cannot address problems by simply working harder. When you do a lot and it doesn't help, you start to see deficiencies and acknowledge the need for changes in one aspect of the job or another. A different edge of this same idea is that one cannot do everything on his own. No matter how hard you try, there is always less done than left to do. These discoveries, combined with high exposure to the issues that we face, constant analysis of our work and search for means to improve it - all of these being enabled by having extra time - certainly brought positive results and helped me develop myself both as a developer and as a manager.

On the other side, the same willingness to work more than 5x9 had a negative impact on the manager role of me, because having more time I could in many cases take the responsibility for any new urgent issue or task. While this attitude helped me tackle problems in time and develop my own skills, it hampered the team's collective progress. Any problem brings new knowledge and shows ways for development, so I simply stole a lot of opportunities from my fellow team-members and hampered knowledge distribution.

Generally speaking, while my attitude helped me grow in terms of knowledge, skills and career, it also shadowed both opportunities and problems. It is a very important lesson for me: whenever one decides to tackle a surge in the amount of tasks by throwing in more (his own) manforce, he misses an opportunity to find more intelligent ways to solve problems and to use them as the points of growth .

These are the effects of the extra work on my job, but there are also those that go beyond my office life. First of all, I left the attempts to do programming and software development in the outside - this means all side jobs and projects. While these used to bring new opportunities and ability to study unfamiliar areas, that's not something that I regret much. Being focused on one area allowed me to grow more than attempts to handle both the main job and one or two similarly looking activities would permit.

What I do regret is that leaving less time for myself I started to pay less attention to continued study and learning new things - both around software development and outside this field. I totally stopped exploration of new programming languages and tools and did much less learning in other areas than I used to - namely, I didn't complete a single online course over the recent months. That's certainly something that I shouldn't have forsaken:  these activities could both help me do my job better and make me expand my knowledge and interests.

Another thing that I dislike is that I quit writing for the blog. Here the reason is not only that the blog has become a silent and lonely place - it was never crowded here. The real problem is that writing less I lost the habit to deeply think over whatever I do and to search for interesting problems and irregularities in my activities. Of course, I do reflect on my decisions and actions, but without regular writing I hardly do it in a systematic and efficient way. Moreover, without posting to the blog I avoid sharing my ideas, which is not a big loss for society, but a shameful cowardice of me.

As with any choice, there do exist both positive and negative sides to putting most of your effort into one area of your life. I see these and despite the cons I am going to continue along the road that I started almost a year ago. However, even though I will continue to pursue that sweet feeling of exhaustion, I do need to make certain adjustments to address some of the problems. In particular I will certainly pay more attention to the supporting activities like learning and blogging - these allow to widen perspective and spot issues that stay invisible when you are constantly inside the problem-solving loop. At the same time, staying focused on my job I will have to pay more attention to the things that I am busy with. After all, being totally occupied with the day-to-day activities is a direct way to keep doing wrong things. So I only need more thinking, more analysis, more writing and the same amount of job. Good to know the solution to one's problems, huh?

пятница, 20 марта 2015 г.

Developing a New Feature

I recently finished working a new piece of functionality on my job and it was a whole lot of experience. Even though that's not the first significant feature that I produced and I do know what the process usually looks like, some of its aspects caught me off-guard once again. It is wonderful how many surprises the process of development bears for a developer and how these same surprises continue to happen even after one passes through the process several times.

Of course it all starts with enthusiasm. If you don't hate your job, new challenging tasks always spur eagerness in you. Interestingly, the process of reading through the feature specification and long lists of requirements usually even makes it grow. The same is true about the attempts to lay out the general ideas about the solution and outline each of its components. More broadly, any planning and preparation activities increase willingness to get the problem solved and even despite seeing numerous problems, we tend to maintain motivation and good mood when getting ready for the actual work. Indeed, no matter what, we plan for success and the more we plan the more real it feels even when one sees that there are plenty of issues to overcome. One may even interpret this observation as a bit of advice - whenever you feel overwhelmed with problems and questions it may be a good idea to go and do a bit of planning - even though it might feel like you have already laid out everything, rethinking a particular piece of work might not only help understand it better, but also encourage you to do it.

However, once everything is planned and scheduled, one has to start development and produce some, preferably working, code. While the process usually starts smoothly, on some stage you smash into a seemingly impenetrable obstacle - confusion. Speaking of me, when planning I tend to thoroughly analyze various details of the future solution and study the existing bits of code, but I am not required to produce anything working right away on this stage and can be satisfied with a set of ideas and questions pinned down on a sheet of paper. On the other side, when getting down to implementation one has to squeeze new code into the mass of the application in such a manner that both old and new bits work. The sources of confusion are plenty here: sometimes you will try to add a new line of code in a method only to notice that you need to carry in 5 more arguments for it, which would make the method much less comprehensible and elegant (let alone the case when it is not elegant already). Or rather, you may find yourself in a situation when you want to change a long run of code, but feel that you miss some important ideas about it.

In my case this confusion - or maybe we should call it frustration? - is usually caused by a combination of two factors: the lack of understanding of the domain and imperfections of the legacy code on top of which (or more likely, inside which) I add new functionality. This doesn't mean that I start working on a feature or project without any knowledge of the domain - there's just always something that one doesn't understand and this is the norm. Similarly, the people who wrote the code that I have to work with are usually smart professionals, but their code is good for the task that they were solving - not always for the problem that I am currently addressing. While one cannot escape these difficulties, there is a way to tackle them - in the world of programming this is done well by refactoring the existing program or component and gradually injecting new pieces into it. While refactoring for its own sake might well be considered a bad practice, refactoring as a way to understand the code is a totally different story. Judging from my experience, there is hardly any other way to comprehend a considerably large class or method. Additionally, if you are changing the code anyway why shouldn't you make it more succinct and elegant as well?

Now, let's pretend I have paved my way around first obstacles and tackled the difficulties - what next? First of all, there are first pieces of a reward waiting for me. After I put some time into a feature, my head gradually wraps around it and I start feeling that I am able to address all the problems in a holistic and elegant manner and even make the existing solution a bit more efficient. This confidence alone greatly helps to move forward. Bad news is that these moments of high spirits usually alternate with periods when one notices more and more unforeseen issues. It feels like the more problems you solve, the more of them jump at you from nowhere. Even though good preliminary analysis and planning are supposed to reduce the amount of surprises of this flavor to minimum, they are never totally avoided. Sources might be different: sometimes a customer visits you with a shiny new idea or a forgotten nuance, in other cases you find out that a little change in one place impacts a distant component in an unpleasant way, or maybe you notice that what seemed a perfectly efficient and elegant redesign turns into an ugly muddle in light of a tiny edge case that you missed. The general idea is that one should expect the unexpected, because it always happens - usually in large amounts.

Fortunately, at some stage the task that looked like a mess of deeply intertwined problems becomes manageable and the carefully crafted solution takes the form of a solid thing. You start to address newly found problems with great ease and with even more impressing speed. You know the answers for most questions that one might ask in relation to the feature and to its neighbors. Furthermore, you are able to explain yourself and anyone willing to listen why the answers are those that you give. This is the state of expertise - both in the problem and in the solution (read implementation) - that is by itself a perfect reward for all efforts, weekends spent at the office and even sleepless nights marked with never ending search for a solution to some nasty problem. No matter whether the feature is small or large, isolated or integrated with a dozen other modules, one should feel proud when they reach this level of understanding and familiarity with it.

When the thing is almost done, however, new surprises come in. Like the final of any Hollywood movie provides some clue to a sequel, any feature added to a software product opens the door to dozens other enhancements, improvements and, well, bugs. I thought that my inability to foresee all these consequences is caused by the lack of experience, but it looks like even a group of experts can't always predict which problems a portion of new functionality may bring to existence. This basically means that there is no end to any particular feature or component. More precisely, the development can only be finished when we decide to finish it - you can't just do all of it. While this might feel depressing, there is hardly anything bad about the fact that there is always some work to be done. One should just remember this and be ready to postpone or reject some of the new ideas when they block completion of the feature. This will free you from the current burden and let you analyze all these new pieces together in a calm and reasonable manner. What's more important however, is that this way you will finally be able to mark the work item as resolved in the issue tracker or move the sticker forward on your Agile board, face the sweet feeling of achievement and have some celebration, because the thing is shipped!

While the process of developing new functionality is often an interesting and challenging activity, it might be difficult at times. You should just be ready to find yourself confused, frustrated and overwhelmed. These bad moments are simply a part of the process and their presence by no means suggests that something is wrong with the feature being developed or with you, as the developer. Eventually, these feelings will give place to satisfaction and pride with the awesome component that you deliver and with the new level of expertise that you reach through this undertaking.