Saturday, August 23, 2008

О проблемах с code reviews

Кросс-пост с персонального как обычно...
--- 

Да-да, знаю... Очень необычно ругаться на code reviews (ревизии кода), особенно в мире где они воспринимаются чуть ли не как одиннадцатая заповедь, за неуважение к которой легко угодить на костер... Так что, потерпите немного ереси, я все обьясню!

Итак... Я не говорю, что ревизия кода – это плохо. Просто все в нашем грешном мире имеет свои преимущества и недостатки. Или как говорили утомленные мудростью греков римляне – cons et pros. Так вот, я хотел бы обратить ваше внимание на некоторую con ревизии кода, которая обычно не упоминается вслух...

Представьте себе, вы работаете в небольшой команде и вы все жутко заняты создавая новый продукт. Обратите внимание: «жутко заняты». И – удивительно, не правда ли? – как и в любом другом продукте, у вас есть баги. А баг – это такая штука, которую надо чинить. Без дураков, не шучу....

Теперь, вопрос на засыпку. Как вы будете чинить баг? Насколько я знаю, есть только две философии как это делать: заплатки и рефакторинг. Ну, да, да, есть еще идиотское «просто почини его», но мы не будем опускаться так низко, правда? Идиоты, которые не понимают о чем я говорю, могут прогуляться и не лезть в наши разговоры. А для нас – оставшихся – выбор все-таки есть. Итак, заплатки или рефакторинг?

Так, как вы думаете, что является правильным способом исправления багов? Да-да, есть случаи, когда заплатки – это верное решение. Например, Quick Fix Engineering – когда нужно доставить заплатку критическому пользователю с несколькими тысячами копий вашего софта. Другой пример – когда продукт уже давно сделан, и все что вы хотите – это трогать его как можно меньше. Ну, и, наконец, ситуации, когда каждый фикс – это очень большой риск. Скажем, когда вы исправляете софт для космического аппарата на орбите Юпитера... real time… и любой баг оставит ваших заказчиков с куском мертвого железа, стоящего много-много миллионов долларов на ... той самой орбите Юпитера.

Однако в большинстве случаев я бы поспорил, что в терминах «хорошего инжиниринга» рефакторинг обычно превосходит заплатки. Well… не просто превосходит... а как бы это сказать... «как бык овцу»! Не, правда. Дайте обьяснить на примере.

Учитывая короткий размер статьи, мне придется привести довольно примитивный пример, но все-таки, весьма наглядный, как мне кажется. Итак, представьте себе, что у вас есть метод ЗагрузкаЗакончена(), которая вызывается в момент, когда закончена загрузка куска медиа, и которая означает, что вы можете начать загрузку следующего куска. И тут вы заметили, что один из ваших коллег вставил в нее какой-то совершенно идиотский код. Нет, будем справедливы, код был бы совершенно неидиотским, если бы он бы вставлен не в ЗагрузкаЗакончена(), а в ЗагрузкаЗаконченаНаФиг(). Ну, что поделать, неудачный идентификтор. Но в результате, у вас выбор из двух опций:

1. Просто перенести код из ЗагрузкаЗакончена() в ЗагурзкаЗаконченаНаФиг(). Баг будет исправлен. Исправление занимает несколько строк перенесенных чуть-чуть вниз в файле.

2. Сделать (1) и переименовать ЗагрузкаЗакончена() в РазрешитьЗагрузкуСледующегоФайла(), чем, собственно, эта функция и является, тем самым предотвратив подобыне ошибки раз и навсегда. Исправление заденет дюжину-другую файлов.

Теперь, не забывайте, ваша команда действительно занята. Каковы ваши шансы получить code review (ревизию кода) быстро, при выборе (1) или при выборе (2)? Ага. Ну, да. Точно. 1. При попытке (2), парни быстро взглянут на список измененных файлов и тут же выпадут в осадок. Причем по хорошей причине. А вам совершенно не в кайф держать код черт-те-сколько на своей машине и тянуть с чекином, верно? Вот-вот.

А каков результат? Результат в том, что ваш продукт получит заплатку, а не рефакторинг. И через неделю другую, кто-то другой опять вляпается в этот самый ЗагрузкаЗакончена(), и вы будете править следующий баг-близнец... Хорошо, если такой же, а то и похуже...

Не знаю, честно, как это выглядит? Я и вправду о чем-то серьезном говорю, или мне мерещится?

Tuesday, August 12, 2008

THOU SHALT GIVE MNEMONIC NAMES TO THY VARIABLES или о важности мнемоники

Кросс-пост с персонального блога...

В воскресенье убил почти шесть часов на вылавливание одного бага. Полное сумасшествие - все нормально, все работает, одна строчка выкидывает тонны строк в выходной файл без малейших проблем, через несколько строчек то же самое просто не работает, хоть убейся...

Программка сканирует тысячи (а точнее сотни тысяч) лог файлов и пытается превратить их в большую таблицу. Каждый лог файл исправно появляется в большой таблице, а вот в аггрегированной - фиг - появляется меньше одного процента... Ну, ясное дело, подозрения на локи, на параллельное исполнение, на неправильные ключи... Ан, нет, все вроде правильно, а все равно ни фига не работает! Ну, да, должны отфильтроваться записи приходящие от пользователей вне США, но вот в общем-то и все. И не так и много их должно быть, поскольку сайт заботливо сам признается, что не может их обслужить. А получается почти ничего.

Нет, честно. И вот, после шести часов я внимательно поглядел и понял... оказывается логическая переменная GeoFence, предназначенная для отличия записей с IP адресов внутри США от оных вне, означает что запись таки пришла из США... Обычно в таких случаях пишут много плохо читабельных символов вроде #$%&! @#& *()+ @#$%! Ну, и так далее....

В общем, переименование переменной в NoGeoFence и быстрая проверка мест, где она используется исправила проблему в пять минут, последовавших за этим открытием. А сколько на нее потратил времени, чтобы найти.... Нет, правда... "абыдно, да"?

Wednesday, August 6, 2008

The Long Tail by Chris Anderson

Long Tail, The, Revised and Updated Edition: Why the Future of Business is Selling Less of More by Chris Anderson – Hyperion, 2006/2008,  267 p., ISBN 978-1-4013-0966-4

This book is almost a classic by now, so if you did not heard about it, at least briefly going through pages may be a great idea. Although it’s not the reason I decided to write about it.

The key idea of the book is that for certain markets, where cost of production is low, cost of delivery is low and cost of filters, which let you distinct good things from bad, is low, the majority of revenue may come not from a few hits selling at large numbers, but rather from a huge number of items selling very little each. “Long tail” refers to the long tail of the distribution curve, where these “bottom-sellers” reside. In particular, it’s shown that in markets like digital music, DVD rental, print-on-demand books and so on, the long tail may bring the majority of revenue. Indeed, 100,000 items selling 10 times per quarter is like one bestseller selling one million copies per quarter. The difference is, it’s not easy to find such a bestseller in the modern world, and those 100,000 titles from self-publishing and self-production are easy.

In fact, finding hits become more and more hard, because hits today sell less than they used before. For example, today’s top TV show would not make it even the first 10 in 70s. The author attributes it to rise of Internet and digital technologies, which reduced price of production and distribution and extended the choice. Hence, concludes the author, presented with more choice, customers started to use it, and hence less of the same market went to hits, and more to the long tail, which fits customer demand much better.

Here I’d like if not argue then at least complement that with another reason that the author did not mention or know about. It’s true that presented with more choice people buy more diverse, however there is another very material reason for the rise of long tail. And that reason is the transition from industrial to knowledge society.

Industrial society consists mostly of industrial workers. These are the main category of consumers for industrial society. Let’s consider how industrial workers are raised, in a sense, how industrial society “produces” its main category of consumers.

Industrial worker normally graduates from a high school: a highly uniform institution imprinting millions of children every year with about the same set of basic knowledge, skills and propaganda stereotypes no matter which country it serves. Granted, stereotypes impressed on students in United States were different from the ones in Soviet Union or Western Europe, but within a single economy it was uniform. It was (and still is) essentially highly standardized mass production, like production of bolts and nuts. Yes, in Europe nuts are metric – millimeters, and in US they are in inches, but it’s still the same within a single economy. And so were people produced by the mass school.

And when you have a lot of standardized nuts, you get a huge market for standardized bolts. Because most of your consumers have similar background, prepared by the school, same basic knowledge, same dictionary, same stereotypes, in the end, same memes populating their minds. So the same TV show was good for a lot of them, same music was likable to a lot of them and the same advertising was making a lot of them buy. This was the making of hits: mass markets are created by standardized consumers, which the standardized school system provided.

With the knowledge society, more and more consumers become knowledge workers (the term introduced in 60s by Peter Drucker, sometimes referred as “the father of American corporate management”, see, for example, The Essential Drucker: In One Volume the Best of Sixty Years of Peter Drucker's Essential Writings on Management). And “more” means “majority”. See for example, The Rise of the Creative Class: And How It's Transforming Work, Leisure, Community and Everyday Life by Richard Florida. Knowledge worker is a very different beast than an industrial worker. Knowledge worker normally has at least bachelor degree, and colleges are not uniform, they are very different, and so are professions that they teach. This means that the consumers become segmented, and not just because of different backgrounds like before, but because of the economy, because there is a systematic force in place that fragments them by their background, beliefs and stereotypes.

For example, consider software engineer at software startup and mechanical engineer at Boeing or Ford. First one must innovate; “innovate or die” is pretty much a business model of most software startups. Second ones have to prevent crash, and innovate means for them a risk of crash. Once it comes under the skin, it affect how they react on advertising, politics, everything. It affects what they watch, what they buy, whom do they vote for.

Of course, hits won’t go away, we still have highly uniform basic education system, which still provides quite a bit of common background, but the more segmented will become consumers, the less will go to hits, and more will go to the long tail. And knowledge industry cannot exist without making its workers – and also main consumers – segmented.

Juts thought, it may be worth sharing.