воскресенье, 7 апреля 2019 г.

Failure Checklist

Just about a year ago - early 2018 - I decided that I am ready to quit the job and build a business of my own in the wild. I won't go through the details of how I came to that and what happenned next - the important part is that after 8 months I have found myself running out of cash and not knowing what I can do except to look for a new employer.

By the end of 2018 I have successfully landed a job - a great one, by the way. So now I am safe and already had some time to contemplate my attempts at business. Here are the key conclusions that I made from the analysis of what I did and how that led me to the failure:

1. If you go into business, you absolutely have to design a sales proposition that would clearly show your potential customers what you are offering, how much it costs and exactly how much they would benefit from it. In other words, you have to present your customers a cost-benefit analysis of your offering. Once you have it, advertise it a lot and do be ready to pay for the ads.

2. Be sure to prepare a financial model of every business project that you are trying to build. If the model shows adequate income, don't abandon it even if you see only modest earnings per unit - you just have to scale it properly.

3. Your business model doesn't have to be cool or show few competitors, but it absolutely must allow for reasonable net income in the target market. Other things do not matter much.

4. You have to be ready to overcome difficulties, do something when it's not clear what to do and ask other people for help at solving the problems of your business. The only allowed reasons to abandon a business are poor cash flow or the act of discovering why your model can't generate proper income. No other difficulties can be a valid reason to quit trying.

5. You have to go and sell your product in each and every possible way - including those, which are least comfortable (or even painful) for you. You must not stop trying to sell until you understand why your attempts fail and why you can't fix that for an acceptable price.

6. Your work must be focused on closing the key needs or problems of your customers in the first place - not on something that you find important or cool. Whatever you add to your product or service must be helping you sell it. Of course, you have to start with identifying what are these things crucial to your existing and future customers.

7. It is important to extrapolate your positive experience and translate every successful deal into a clear offer that would be interesting for a wider market. Once you figure out how to adapt what you have done for one client to the needs of many others, go and sell it to them.

8. Focus on just one or two (absolute maximum!) projects at a time. Don't dive into any new shiny projects until you finish the current one. Remember, there is one good reason to abandon a project: either it fails to generate adequate net income or you absolutely can't find a way to live to the moment when it would finally start bringing that income.

These thoughts look obvious, but when it came to the actual work I managed to violate each and every one of them. I learned the lesson the hard way, but the next time I venture into something new, this will be a good checklist to validate what I am doing on a daily basis. If, on the other side, you are just about to start a business of your own, this may help you avoid the mistakes that I made.

суббота, 30 марта 2019 г.

The Moneyball Takeaways

I recently watched the Moneyball movie - a biopic after Billy Beane, the manager of the Oakland Athletics baseball team. It’s hard to imagine anything less relevant to me than baseball, but the movie is in large not about the game itself, but rather about how it’s managed and changed, so it did hit the right strings. 

The plot revolves around a baseball team manager trying to change the rules and build a team that would win under severe budget constraints - totally about management and, particularly, change management. Below are the key thoughts that got running through my head by the time the end titles made it to the screen.

  1. If you gonna change the rules, there would be people who will oppose you. No exceptions. 
  2. If you gonna change all the rules, almost everyone will oppose.
  3. There still will be people who support you - keep them, teach them, trust them and respect them.
  4. Building a winning team is not about picking the top players - it’s rather about picking the right ones, who cover the needs of the team.
  5. The needs of the team is what it has to do to win - preferably, expressed in figures. Nothing else matters.
  6. Winning is all about performance, performance is all about measurement - neither is about whom you like and whom you don’t.
  7. While building a team you will certainly have to hire people, but likewise you will have to fire someone.
  8. By the time the game begins the manager’s job is done - they can only watch how it develops and make a note of any required adjustments.
  9. The fact that you succeed at changing the world doesn’t mean that you win. 

пятница, 10 ноября 2017 г.

Use Trello as the good old day planner

In the old days of my first attempts to plan my work ahead instead of simply following the stream of life I used a paper-based personal day planner - a thing that everyone had at some point. It is a great tool that has almost everything that one needs to plan their days. But it's also another large and heavy thing, which you have to carry with you. Also, because it's pen and paper it becomes a mess for example when you have to adjust your plan because something went wrong, and it is limited in space. Thus, with time I switched to Trello as my organizer and followed the Getting Things Done methodology in it. It works great, but I always missed the ability to plan the following day accurately and to follow that plan closely, which I could do with the paper thing. Recently I discovered a way to fix that and it boosted my productivity tremendously.

My Trello board for daily activities is constituted of several lists, such as Incoming, Wait, Office - Do and Wilderness - Do. The latter two are action lists - they consist of the things that I am going to do at the office and elsewhere. During the day I go through the cards in these two lists, do them one by one, and archive each one when it's done.

When I first switched to this approach I lacked the ability to plan the next day - action lists could include lots of cards that would span several days and it didn't work well for planning. Sometimes I would make a kind of plan on a piece of paper, but in most cases I simply didn't do it. This made me miss the paper organizer. This problemm however, is easy to fix without leaving the comfort of Trello.

At first I simply added a card called "Day boundary" with a black label to my two action lists. I don't use black label for anything else so it is easy to spot this card among others. The meaning of it is simple: whatever is above it should be done today; what goes below will be done on any other day. This trick helped a lot: I could plan my day now. Whenever something changed I could easily adjust plans by moving things that do not fit the day anymore under that "Day boundary". The approach however was not perfect. Too frequently at the end of the day I would see a lot of cards above the black one, indicating that I failed to do all that I planned. While this can happen, seeing this every other day means I wasn't doing good job at planning.

I felt the longing for the paper organizer again. What I missed about it was the ability to see that between 13:00 and 14:00 I should be occuppied with one thing and also that if I don't finish it on time the things planned for later hours will drift by that much. This makes me more disciplined. Also, when laying out a plan in a paper organizer you have to fit its points into hour lines, which means you assess how long each one will take and whether they fit the day. In Trello I only had a list of things that I was going to complete over a very long period - one day - and it was very easy to make mistakes about how much I can put in.

So I made the next step and just added several more black cards to the action lists and labeled them with time: 9:00, 12:00, 15:00, 18:00, 21:00. It was enough to transform my Trello into as good an organizer as the paper planner. Now, every evening I fill the gaps between these black cards with action cards. Whatever falls between the 12:00 card and the 15:00 card is planned to be completed during that exact period of time. It also made my planning more realistic - I have to assess whether particular cards fit into a shorter period of 3 hours or not. To make that easier I made a custom of writing the amount of time allocated for every activity on its card (you can see the numbers in parenthesis).

During the day I still archive the action cards once I finish working on them. With the new organization this means that I can easily see how much I lag behind or how far I am ahead of plan. If it's 16:00 and I still have any non-black cards above the 15:00 one, then something went wrong. If all cards are below and there aren't too many of them between 15:00 and 18:00, I am likely good. It's 17:00 now, so you can see that I am falling behind a bit, but not too much. With these recent changes I returned to the state when what I planned for a day is actually done on that day. I may fail a little here or there, but generally it works well.

It doesn't matter much which tool you use to organize yourself as long as it makes you feel comfortable and allows to make a plan and see clearly how it is going while you're working through it. Trello's flexibility lets you achieve that easily and in a very visual form, so if you're not using anything specific right now it may be a good way to go.

If you have a different approach to preparing a plan for a day and working with it, please share it here! Maybe something about it makes you feel sick? If so, leave a comment and who knows - maybe we can find a solution together.

понедельник, 12 июня 2017 г.

The Simplest Way to Mess Up om/build

I played with ClojureScript Om recently and, while working on a stupidly simple task, stumbled into a strange problem when my components losed state and got re-rendered whenver a user attempted any interactions that caused the underlying data to change.

I had a component that was bound to a path in app state holding a vector of maps. It consisted of several identical components, whose purpose was to edit values in these maps. Each of these editors updated the corresponding value during the onChange event - whenever a user would edit the text in them. An important detail is also that these editors had state - they could either be in "view" mode (rendered as <span>) or in the "edit" mode (rendered as <input>). The thing transitions to the "edit" mode when it is clicked and jumps back after user hits Enter in the input or moves focus somewhere else. It all worked pretty fine until I actually started editing stuff - whenever I pressed a key all the components would get re-rendered and, more importantly, lose the editing state.

I attempted some debugging and code tweaking, but nothing helped or even shed the light on what was going on - I saw that the controls were re-rendering, saw that their state was lost immediately after edits and later even noticed that they are being mounted as new ones after edits. This later observation explained the problem with lost state, but didn't give me much clue onto why that was happenning. However the thing got clear after I read the documentation for om's build and build-all functions a couple times:

(defn build
  ([f x] ...)
  ([f x m] ...))
Constructs an Om component. f must be a function that returns an instance of om.core/IRender or om.core/IRenderState. f must take two arguments - a value and the backing Om component usually referred to as the owner. f can take a third argument if :opts is specified in m. The component is identified by the function f. Changing f to a different function will construct a new component, while changing the return value will not change component. x can be any value. m is an optional map of options.

At some point I noticed my dumb mistake - I was calling build-all like this:
(defn component [data owner]
     (render [_]
         (om/build-all (fn [data owner opts]
                        (if some-condition
                          (edit-component1 data owner opts)
                          (edit-component2 data owner opts)))
                       (:attributes data)
                       {:key :attribute-id
                        :opts {}})]))))

Which means that on each render of the parent component I would pass a new function to build-all. Because components "are identified by their functions", that meant that on every change of the underlying state the parent component will start re-rendering the child ones, see a new function created by the (fn []) form and believe that it is rendering new components. Thus it won't even want to connect the old state to them and they will be rendered in the default "view" state.

Simply changing my code to the following dirty thing immediately resolved the issue:
(defn edit-component [data owner opts]
 (if some-condition
   (edit-component1 data owner opts)
   (edit-component2 data owner opts)))

(defn component [data owner]
     (render [_]
         (om/build-all edit-component
                       (:attributes data)
                       {:key :attribute-id
                        :opts {}})]))))

The conclusion is simple: never ever pass to build or build-all a function that you create in the render method of the parent component or in any other bit of code that is called multiple times over the lifetime of your components. If you do this you will get new components built everytime and thus lose whatever information you associate with them (plus some time for their creation). I hope that you never commit this mistake, because that's one of the dumb things that require time to spot, but if you are unfortunate to run into it, this note may help.

понедельник, 29 мая 2017 г.

(= (+ clojure emacs) :happiness)

I started programming in Clojure quite long ago and despite all the great advice spread through the Internet kept using Sublime Text editor for it (it's an awesome thing, anyway). However some months ago I stumbled upon Emacs - maybe after talking to some Haskell-ists. Yes, it felt totally unfamiliar and awkward and I had to spend minutes trying to accomplish the simplest things that took me an instant to do in other editors. Still, I can't explain why, it felt quite likeable and more suitable for doing Clojure. The funny part though is that I'm only starting to learn the full power of Emacs as a Clojure programming environment. Literally, it took me almost half a year to get accustomed with the editor and its addons - mostly Cider - to understand how much one can do there.

Even though there are guides on the web explaining what a Clojurist can do in Emacs (for example here and here), I feel the need to list the basic tricks that I have learnt here. For some it may soften the learning curve, others will possibly provide some greate advice to me. And it will certainly help me if I somehow got struck by amnesia in these dangerous times.

First things first. Once I run Emacs to do some Clojure or ClojureScript I make sure to press C-c M-j or C-c M-J (for cljs) to launch a REPL and have it ready. Most of the cider's awesome stuff won't work without that, but it is also simply stupid to do Clojure without having a hot REPL nearby.

At first I used to copy and paste lines from code buffers to REPL and run them there, when I wanted to check whether something would work. Quite recently I discovered that this is stupid as well. One can simply place a cursor at the end of an expression and type C-c C-e - cider will evaluate the expression and show the result right next to it!

I had some problems with that though, because once I wanted to copy the result of that expression elsewhere and couldn't figure out a way to do that. Fortunately, one can get pretty close: C-c C-p will also evaluate the last expression, but the pretty-printed result will appear in a special buffer. Afterwards you can go to that buffer, skim through it and copy the required bits.

The last time I used that trick my goal was to select some values from the database (yes, with Clojure, because with Emacs it's closer that any other gateway to the DB) and use them as parameters to test my web-service. I made calls to that service through a plugin for Google Chrome (yes, not familiar with curl), but I should definitely change that to running requests right from Emacs itself - that should be pretty easy. Frankly speaking, I don't know any other development environment that allows to make a couple calls and check whether a webservice that you're hacking together yields the expected results without even leaving the window (correction: buffer) in which you write the service's code.

The last big thing on my list are tests. I used to run tests through the terminal, like lein test. Yes, that means spinning up a JVM, which is 15+ seconds at best. Try to imagine my feelings when I first discovered that I can run all tests in a namespace simply by pressing C-c C-t C-n, while there. Even better, I can run the tests that I have for one of my modules (i.e. namespaces) without leaving the buffer of that namespace - with those same keys. This one, however, requires that the namespace with tests is called <the thing that you're testing>-test - it took me some time to learn and get accustomed to, but that's not a big deal. Also, while the cursor is on a particular test case I can run it with C-c C-t C-t. Then change it and run again in an instant. As a C# programmer I love Visual Studio, but unit tests experience there is by no means close to what you see in Emacs with Cider.

Sometimes I would also type C-c C-x just to see that my code still compiles - that's cider refresh, which reloads everything.

And one more thing, that makes cider-ed Emacs a true development environment is the M-. hotkey, that navigates you to the definition of whatever you're looking at. It does have glitches from time to time, but it's there.

There's a ton of other greatness in Cider, I'm sure. Many bits are easy to find and learn through the hotkeys reference C-h C-m - I simply didn't internalize most of it yet. For example, there are keys and commands for macro expansion and multiple other things. Still, even with the few tricks that I mentioned above I get programming experience that simply seems out of reach for the other languages and environments that I worked with. If you do Clojure and your environment of choice doesn't give you the same capabilities, you should definitely check out Emacs!

вторник, 11 апреля 2017 г.

Takeaways: Ideal Executive by Ichak Kalderon Adizes

This entry also appears in my other blog.

I have already recommended the Management and Mismanagement Styles book by Ichak Kalderon Adizes earlier and now there is another title by Adizes that should draw your attention The book is called The Ideal Executive. Why you cannot be one and to do about it, which actually precedes the Management Styles. The two share some portion of content, but focus on slightly different aspects of management and are both definitely worth reading. To get you the idea and make myself a short summary I will list the key things, which I noted in the Ideal Executive.

First of all, both books use the same framework to reason about managers and their work - PAEI. The acronym stands for four distinct functions that a manager should perform: Production, Administration, Entrepreneurship and Integration. They are explained in great detail in the books, but the key idea about these is that all four are crucial to proper management. At the same time because they sometimes come in conflict with each other, no single person can execute all of them alone, which is why there is no such thing as an ideal executive. The only reasonable way to address this issue is to assemble a team of managers, each of whom masters in some of these functions, and let it drive the organization forward. The books focus on this idea and revolve around its various implications.

Adizes goes deeply into analyzing various aspects of the management job and of the idea of a management team, mapping them to the PAEI framework. I will just list various disconnected bits that attracted my attention in the book:

• The solution to the "no ideal manager problem" is a management mix of several people with different approaches: P will focus on what we have and how to get the best out of it, E will introduce desires and drive progress, A will make sure that everyone is doing what they should, I will connect and encourage everyone;
• Even though current objectives of the members may differ significantly, the team must have common long-term interests. Management means not only making decisions, but also implementing them. The latter doesn't happen if long term interests of the team-members are in conflict;
• Four factors that enable trust and respect in an organization are: people, process that includes communication, structure that allows people to match their interests to interests of the entire organization and ensures that reward meets responsibility, common vision and values ensured by leaders
• Structure must reasonably define the responsibilities, the extent of freedom for decision making and rewards allocation for P, A, E, I styles, because in each case these things should be different;
• Managers of different styles need different approaches because to large extent they speak different languages. Even "yes" and "no" may mean different things to them;
• When arriving into high-P's office don't start explanation from the early days of humanity - start at the end and with the conclusions, then move to additional info. High-P's hate extra details - they want to get things done as quickly as possible;
• When you are about to introduce your cool new idea to a high-E make an obvious mistake right in the beginning of your explanation of the problem - fixing it would allow high-E to feel his contribution to the solution. Otherwise he may get unhappy about you making a decision without his input;
• Conflict is an important part of the work and management process. It should not be avoided, but should be kept constructive through proper management;
• When discussing a decision and there is no consensus break all the apparent issues into three categories: questions, doubts and objections. Collaborate to answer questions first, then label doubts as questions and objections as doubts, answer the new questions. On the last stage you will hopefully have only the questions that were initially considered objections and will likely be able to resolve them as well. This looks like a psychological trick making people in the room focus on collaboration and making an idea workable instead of opposing it;
• Leader is a person who does Integration and one other function excellently and is at least good with the other too;
• Leader is like a thumb - its presence unites other fingers into a functional hand;
• Good leader acts as a servant, who creates the circumstances in which others can shine;
• Good leader can be distinguished by the scars on his tongue, because he keeps biting it to keep quiet when there is too much temptation to engage into a loud debate;
• Best managers keep calm when a conflict rises. The hotter the conflict, the calmer the manager;
• A manager must be able to hire, use, develop and reward people who don't look like him;
• Create circumstances in which conflict serves as an education tool and stays constructive;
• Organization is what it does for others. Answering the following questions helps understand it better and formulate its goals and values:
○ Who are the customers and what do they want?
○ Which of their needs do we address?
○ Which of their needs we don't address?
○ What are our abilities - what we can do?
• The goals and values should be periodically reviewed - otherwise you will get stuck in a set of irrelevant rules, which will prevent growth of the company;
• Currently management schools teach correct answers instead of teaching how to ask the right questions;

The book is a pleasure to read, and at the same time it provides a lot of advice in regards to management. This advice comes in a solid yet simple framework that helps reason about what one should be doing at his or her job and how it is different from what he or she is actually doing. The nice thing is that both the advice and the framework are very practical - learning these helped me notice many new things about the behavior of my colleagues and see some underdeveloped areas in my our activities, thus growing one step closer to the non-existent ideal manager.

понедельник, 13 марта 2017 г.

What I Expect from a Developer’s Resumé

This post also appears in my blog on Medium.

On a recent local programmers meetup we discussed the topic of writing a developer's CV in such a way that it allows one to get to an interview past the initial screening. As this is closely related to my posts on interviewing developers, I will cover what we discussed and what are the things, which when seen in a programmer's resume make the team-lead in me eager to meet its owner in person.

For all technical positions the first thing that both the recruiter and the team lead will search in a CV is work experience with relevant technologies and tools. This is the easiest one, because if you have it you just need to make it stand out. To do so make sure that you resume has the keywords that describe the technologies that you would like to work with. While people are quite different from Google search engine, when I look for a new hire I inevitably have to scan dozens of CVs and the easier it is for me to spot the names of the technologies that I need, the higher the chance that I will pay attention to the candidate. Trivial, right? Just remember that you have to be honest about what you have experience with and what you don't - if you're caught lying about these things, you will likely be wiped out from the list of candidates at the same instant.

On the other side, a resume consisting solely of keywords will be even less successful than a resume with no single one. That's because merely "knowing" all the buzzwords doesn't make you a professional, while having lots of achievements in the field of software development does. Here make sure that every job or internship mentioned in the CV lists every one of your accomplishments on that position - ideally, focus on what you have done instead of what you have been doing. Moreover, don't stop on the jobs - remember all the pet projects that you had done alone or with your friends, remember every conference that you talked at and the articles that you have written - all of these underline the experience that you reported and show that you're a person of achievement.

Such activities as pet projects and extra education - an open-source library that you helped to develop or a course that you have taken online - also show that you are willing and capable of learning new skills and technologies. That's especially good if these go beyond your main programming language or framework of choice, because breadth of experience demonstrates your ability to adapt to changing circumstances and employ different mind-models and approaches. Mentioning such activities in a resume also draws a potential employers' attention to one more thing - your fascination with the profession and desire to work and learn beyond your day job, which by itself puts you in front of the crowd.

Another important note is that all of us look for reliable employees, which in particular means that we want them to stay with us as long as possible. Planting a developer into the team and bringing him or her up to speed may take an awful lot of time, so when the process starts I want to be as confident about the result as possible. Essentially this means that a CV consisting of a long list of short jobs - e.g. those under 18 months each - will at least get me concerned. That's not something that you can change about your resume right now, but the thing is certainly worth remembering when you think over your next career move. I don't mean that you should stick to one job for decades, but after you're sort of settled with your career people may expect that you don't change employers too often.

Finally, the resume must allow you to express yourself in a clear and comprehensible manner. In particular this means that you should adhere to the generally adopted standards, such as listing your jobs from the most to the least recent one, displaying a photo of yours and so on. However, there is more to this, because to show that you're a person worth speaking to you must be polite and caring. In written communication that means that you don't brag too much, your language is good, its style is appropriate and there aren't many typos. You will also want to save your interviewers the time needed to find you at Facebook, Twitter, GitHub and elsewhere, showing that you have things to share and don't put crazy stuff up for public display.

It's that simple in regards to the contents of a resume, but I also have a couple suggestions in regards to the process of producing it. First of all, be sure to use external help when preparing the resume. Simply ask a friend, a teacher or even me to review the resume - an extra pair of eyes will spot mistakes and unclear sentences, which will help you look better. Some people prefer to ask a professional to prepare a CV for them. Here I can't advice much as I never used such a service, but it may well be a good move. In my experience, though, having someone proofread the CV is just enough. The last advice is similarly simple, even though less obvious - prepare your resume in advance and always have it ready. You never know when you will have a chance to apply for your dream job and don't want the need to write up a whole new CV to be an obstacle for that. This is not mention the fact that from time to time a friend of yours may run into you shouting something like "We desperately need a good programmer on that project! Could you send me your resume right now?!" More opportunities is better, so be prepared.

As you can see, there is no rocket science about producing a good resume and all of the above advice aligns well with what common sense would suggest. At the same time, if you follow these simple guidelines you will help recruiters and managers spot what they look for in your CV and thus increase your chance to hit an interview.  That's it for this article and I hope that the advice is valuable. If you still have any questions on what to include in your resume, please ask in the comments. If, instead, you have a better idea in regards to what a good resume should look like, be sure to share it here!