*** ВНИМАНИЕ: Блог переехал на другой адрес - demin.ws ***

вторник, 27 декабря 2011 г.

Steve Jobs: The Exclusive Biography / Биография Стива Джобса от Уолтера Айзексона

Note: This post is in two languages. The English one is the second.


Биография Стива Джобса от Уолтера Айзексона от Уолтера Айзексона

Я думал, что биографии читают только "старые люди", но эта книга доказала мне обратное. Поддавшись на рекламу, и ведомый моим недавно начавшимся увлечением продукций Apple, я начал читать.

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

Можно говорить, что это конъюнктура и попытка сыграть на ситуации, что Стив только что умер, но, несмотря на все эти предрассудки, я подсел практически сразу.

Уж не знаю, в чем тут дело, может просто автор мастер своего дела, но я так и не оторвался, пока не прочитал до конца.

Вывод: настоятельно рекомендую, даже для принципиальных нелюбителей Эппла.


Steve Jobs: The Exclusive Biography by Walter Isaacson

I thought that biographies are for "old people". This book has changed that mindset in me. Being driven by massive ads and recently emerged love with Apple products and philosophy I had started reading.

Initially it was like an expanded version of "Pirates of Silicon Valley" which I, frankly, liked, but as reading progressed I had just fallen in love with this book and weren't able to stop.

The book can be treated as conjuncture or just an attempt to leverage the situation that Steve has just passed away. I was fully biased but after the first chapter I was hooked.

It is fascinating reading. Maybe just because the author is talented, I don't know.

Conclusion: strongly recommend.

суббота, 24 декабря 2011 г.

The world is flat 3.0 / Плоский мир 3.0

Note: This post is in two languages. The English one is the second.


Я снова вернулся к аудиокнигам. 40-50 минут в день по дороге на работу и потом обратно позволяют поглощать книги с приличной скоростью.

Из недавнего.

"The world is flat 3.0: A Brief History of the Twenty-first Century", Thomas L. Friedman

Убийственная книга для осознания, что:

  • сейчас индивидуумы могут спокойно конкурировать с корпорациями
  • важность инженерного, а особенно компьютерного, образования растет семимильными шагами, и это не дань моде, а объективная реальность
  • количество мест на планете, где можно жить и зарабатывать достойные деньги и развиваться уже не сужается к Штатами (разве не забавно слышать такое от коренного американца-консерватора) и некоторыми странам Европы
  • Индия, Китай, Россия и многие другие страны начали сильнейшую конкурецию на рынке труда с тем же США уже без массового отъезда специалистов
  • постоянное самообразование - это едиственный способ не быть вытолкнутым с рынка труда

И многое многое другое.

Не буду скрывать, были моменты в жизни, когда я думал, что занимаюсь чем-то не тем (хотя профессию я не выбирал, она сама меня выбрала), и лучше бы мне работать, например, в области недвижимости, природных ресурсов, рекламы или медиа. Если у кого-то есть хоть минимальные подобные сомнения - это книга вытрет их навсегда и, возможно, подскажет путь.

Это очень интересное и познавательное чтиво.


I've come back to audiobooks. 40-50 minutes per day when heading an office and then back allow to consume books with decent speed.

A recent.

"The world is flat 3.0: A Brief History of the Twenty-first Century", Thomas L. Friedman

This is a killer book to understand or even discover that nowadays:

  • individuals can compete with corporations
  • importance of engineering and especially computer education is increasing enormously
  • number of places on the Earth when you can have decent life doing what you love to do is not narrowed to the US and a few EU countries anymore
  • India, China, Russia and many other countries have a very strong position competing with even US now without immigration
  • permanent self education and nurturing your curiosity (CQ + PQ always greater that IQ) is the only way to remain valuable

And many other topics.

Frankly, there were moments in my life when I doubted and thought I would be better off doing, for instance, real estate, natural resources, ads or media rather than software. If you have even a tiny similar concern this book will wipe it out forever, and maybe even show the way.

To conclude: very useful, interesting and fascinating reading.

среда, 21 декабря 2011 г.

Виртуальные private-функции в C++ / Virtual private functions in C++

Note: This post is in two languages. The English one is the second.


Наткнулся на интересный, как мне показалось, код. Там использовалась виртуальная private функция. Прием немного странный, но сейчас не об этом.

Сначала мне показалось, что такой код не должен компилироваться, так как если функция private, она недоступна для использования в дочерних классах. Наблюдался какой-то очередной пробел в моих знаниях по C++.

Я написал программу:

#include <iostream>

class A {
public:
  void bar() { foo(); }
private:
  virtual void foo() = 0;
};

class B: public A {
private:
  virtual void foo() { std::cout << "B::foo()" << std::endl; }
};

int main(int argc, char* argv[]) {
  A* a = new B();
  a->bar();
  delete a;
  return 0;
}

И VS2010 и GCC прекрасно его съели, и программа печатает "B::foo()".

Напрашивание такое объяснение - механизм виртуальных функций (технически переопределение функций через vtable) - это runtime, а public/private - это compile time. Получается, что в compile time все законно, и разделение на private/protected/public не зависит от виртуальности функции, а в runtime класс B просто подставляет другую функцию через vtable уже вне зависимости от private/public.


I have come across an interesting in my point of view bit of code. There was a virtual private function. The approach is odd at the first place and I thought it shouldn't even compile, but surprisingly it did. I felt that this was yet another gap in my C++.

I wrote this code:

#include <iostream>

class A {
public:
  void bar() { foo(); }
private:
  virtual void foo() = 0;
};

class B: public A {
private:
  virtual void foo() { std::cout << "B::foo()" << std::endl; }
};

int main(int argc, char* argv[]) {
  A* a = new B();
  a->bar();
  delete a;
  return 0;
}

VS2010 and GCC compile it perfectly and it prints out "B::foo()".

I have concluded that the virtual function mechanism usually implemented via vtable is runtime, but public/private is compile time, and they don't depend on each other.

воскресенье, 18 декабря 2011 г.

Ведение блога на GitHub / GitHub as a blog engine

Note: This post is an attempt to adopt a technique of creating posts in two languages. Instead of maintaining two separate blogs I want to kill two birds with one stone – still write on my native language for majority of the readers and plus have an opportunity to practice in English with a few English speaking readers. The post has two parts. The second is a translation to English. Any feedback regarding the language is appreciated, even in comments.


Сказать, что Blogspot меня бесит – это ничего не сказать. Единственное для чего он нужен, как мне кажется – это быстрая индексация в Google.

Артемий Лебедев как-то отлично сказал, что презирает всякую хрень типа SEO, так как надо создавать интересный и читаемый контент, а не суетиться по мелочи на его раздаче. Поэтому его ЖЖ использует стандартный шаблон без каких-либо попыток выглядеть “клевым”. Но его контент делает блог одним из лидеров в российском прокате.

Да и кого сейчас волнует дизайн блога? Все равно подавляющее количество читателей видят твой блог через призму Google Reader’а.

Но оставим одиозного Лебедева и вернемся к нашим специализированным техническим блогам. Как написал Том Престон-Вернер, один их основателей Github, что ведя блог, он хочем писать посты, а не подкручивать там и сям шаблоны и прочие техдетали всяких WordPress’ов и Mephisto’в.

Подобная же мысль мучает меня с первого дня использования Блогспота. Только недавно я более менее устаканил процесс написания постов, используя ReST. Сейчас я пишу и храню посты в этой разметке, а перед публикацией прогоняю через пару доморощенным скриптов типа “ReST > HTML > Фильтрованный Для Блогспота HTML”. Хотя проблема хостинга картинок все равно решается вручную заранее.

Уже сотни раз я подумывал о собственной платформе на том же WordPress’е, но природная лень и нежелание тратить ни секунды на администрирование всегда останавливало.

Сейчас у меня очередной приступ ненависти к Блогспоту и, как следствие, исследование альтернатив.

Удивительно, но как-то никогда не задумывался, что блог может на быть статическом движке.

А что, если переехать на GitHub Pages? Там суть в том, что один из твоих репозиториев может стать вебсайтом, который работает на статическом движке Jekyll.

Сразу убиваются несколько зайцев. Работаешь в нормальной разметке и используешь git для выкладывания постов. Пишешь и отлаживаешь пост локально. Затем “git push origin master” и все – пост выложен. Текст можно писать не в идиотском HTML, а в Markdown или Textile. ReST, конечно, круче, но это не смертельно.

Более того GitHub Pages позволяет интегрироваться с полноценным доменом второго уровня.

Далее тема комментариев. Не то, чтобы программировать свой движок для комментирования, а даже просто настроить WordPress – лично у меня нет никакого желания. Поэтому одна их самых простых альтернатив – Disqus.

Анализ посещаемости решается через Google Analytics.

Что остается?

Иногда люди таки ходят на сайт блога напрямую – для поиска старых постов или узнать об авторе что-нибудь социальное. Вот тут, конечно, всякие примочки типа гугловских гаджетов – поиск, каталог по датам, интеграция с социальными сетями и т.д. – имеют смысл. На Блогспоте ты их добавляешь кликом мышки, а для собственного блога надо будет тратить реальное время.

Но, возвращаясь к вопросу – а нужны ли все эти гаджеты? Если контент в блоге интересен – он найдет своего читателя. Сарафанное радио в виде твитера или фейсбука приведет тебе читателей, если будет что читать.

А если уж говорить на “раскрутке” – та же публикация удавшихся постов на Харбе приводит в сто раз более читателей, чем суета с дизайном сайта.

Вот такие мысли.


To say that Blogspot (Blogger) infuriates me is to say nothing. The only benefit of it is fast indexing by Google.

Artemy Lebedev said that he despises all this SEO bullshit because it is much more productive to focus on creating great posts rather than thinking how to attract more readers. His LJ uses a default template without even minor tweaks to make it looking “cool”. Despite of this his blog is in Russian Top 10.

Nobody reads blogs directly nowadays. Everybody uses Google Reader or other aggregators making the design of blogs absolutely pointless.

Anyway let’s leave odious Lebedev and come back to our techy blogs. Tom Preston-Werner, one of the Github founders, said that he wanted to write posts but not tweaking different templates or keeping the version of WordPress or Mephisto up to date.

A similar thought haunts me from the day one of using Blogspot. Only recently I have sorted a way of creating post by using ReST. Now I write posts in this markup and convert to HTML before publishing by a few handcrafted scripts. Unfortunately hosting for images is not automated in anyway.

Many times I wanted to migrate to a standalone platform, for example, WordPress. But my laziness and unwillingness to spend even a second on its maintenance always stopped me.

At the moment I have another attack of hate to Blogspot and as a consequence look for alternatives.

Surprisingly I never considered using static blog engines.

What if just simply migrate to GitHub Pages? It converts one of your repositories to a website which can be also processed by Jekyll, a static engine from Tom Preston-Werner.

I could kill a few birds with one stone – to use a proper markup language, Markdown or Textile, instead of bloody HTML and to manage publishing by git. Of course ReST is better but I can cope with it.

Also GitHub Pages can be integrated with your own domain if needed.

Comments and discussions. Disqus seems to be an easiest way to sort it without any hassle.

Google Analytics perfectly works with any engine where you can insert their JavaScript hook into pages.

What is still missing?

Sometimes people still visit blogs directly, for instance, to find previous posts or explore “social” details. In this case all these bells and whistles in a form of JavaScript gadgets are very useful and save a lot of time. Blogspot allows adding them in a few clicks.

But coming back to the question at the beginning – do I really need them? If the content is interesting the audience will inevitably find you. A word of mouth in a form of Twitter or Facebook will attract people. But if the content is crap all those bells and whistles (and SEO) will not help.

суббота, 10 декабря 2011 г.

Задача расположения восьми ферзей на Erlang'e

Знаю, что баян, но для меня было весьма показательно.

Например, вот вариант, который я написал где-то за полчаса:

-module(queens_classic).
-export([solve/0]).

solve() ->
    solve(lists:seq(1, 8), lists:seq(1, 15 + 15), 1, []).

print_board([]) -> io:format("~n", []);
print_board([H|T]) ->
    Line = [string:copies(". ", H - 1), "@ ", string:copies(". ", 8 - H)],
    io:format("~s~n", [Line]),
    print_board(T).

solve(_, _, Cols, Result) when Cols > 8 ->
    io:format("~p~n", [Result]),
    print_board(Result);

solve(Rows, Diags, Col, Result) ->
    lists:foreach(fun(Row) ->
                     D1 = Row + Col,
                     D2 = Row - Col + 8 + 15,
                     T = lists:member(Row, Rows) andalso
                         lists:member(D1, Diags) andalso
                         lists:member(D2, Diags),
                     if T ->
                         Rows1 = Rows -- [Row],
                         Diags1 = Diags -- [D1, D2],
                         solve(Rows1, Diags1, Col + 1, [Row | Result]);
                        true -> void
                     end
                  end, Rows).

Выглядит ужасно, и стиль однозначно понятно какой: C/Python на стероидах (циклы, if'ы).

А вот над этим вариантом я провозился несколько часов:

-module(queens).
-export([solve/0]).

solve() ->
    solve(1, []).

print_board([]) -> io:format("~n", []);
print_board([{_X, Y}|T]) ->
    Line = [string:copies(". ", Y - 1), "@ ", string:copies(". ", 8 - Y)],
    io:format("~s~n", [Line]),
    print_board(T).

solve(X, Taken) when X > 8 ->
    io:format("~p~n", [Taken]),
    print_board(Taken);

solve(X, Taken) ->
    L = [{X, Y} || Y <- lists:seq(1, 8), not under_attack({X, Y}, Taken)],
    row(L, Taken).

row([], _) -> [];
row([{X, Y}|L], Taken) ->
    solve(X + 1, [{X, Y} | Taken]),
    row(L, Taken).

under_attack(_, []) -> false;
under_attack({X, Y}, [{Xt, Yt}|L]) ->
    Y == Yt orelse abs(Y - Yt) == abs(X - Xt) orelse
    under_attack({X, Y}, L).

Вся работа со списками вручную без циклоподобных конструкций.

Печатает типа такого:

[4,7,5,2,6,1,3,8]
. . . @ . . . .
. . . . . . @ .
. . . . @ . . .
. @ . . . . . .
. . . . . @ . .
@ . . . . . . .
. . @ . . . . .
. . . . . . . @

[5,7,2,6,3,1,4,8]
. . . . @ . . .
. . . . . . @ .
. @ . . . . . .
. . . . . @ . .
. . @ . . . . .
@ . . . . . . .
. . . @ . . . .
. . . . . . . @

...

Увы, но вот эта версия мне кажется более красивой с точки зрения фукнционального стиля.

На всякий случай Makefile для обоих вариантов:

target = queens

all:
    erlc $(target).erl
    erl -noshell -s $(target) solve -s init stop

classic:
    erlc $(target)_classic.erl
    erl -noshell -s $(target)_classic solve -s init stop

clean:
    -rm *.beam *.dump

среда, 7 декабря 2011 г.

Visual Studio 11 Developer Preview

Поставил на рабочий ноут Visual Studio 11 Developer Preview.

Погонял разные самопальные бенчмарки типа решета Эратосфена, vector<int> vs vector<bool>, std::string vs char* и т.д., пытаясь выявить улучшения или ухудшения в оптимизации. Лично я ничего кардинального не выявил по сравнению с версией 10.

Очевидно, что статический анализ кода и его безопасность в целом сейчас как никогда в моде, поэтому производители компиляторов постепенно закручивают гайки, превращая предупреждения в ошибки.

Например с ключом "/sdl" Студия 11 будет считать приведенные ниже предупреждения ошибками.

Warning Command line switch Description
C4146 /we4146 A unary minus operator was applied to an unsigned type, resulting in an unsigned result
C4308 /we4308 A negative integral constant converted to unsigned type, resulting in a possibly meaningless result
C4532 /we4532 Use of “continue”, “break” or “goto” keywords in a __finally/finally block has undefined behavior during abnormal termination
C4533 /we4533 Code initializing a variable will not be executed
C4700 /we4700 Use of an uninitialized local variable
C4789 /we4789 Buffer overrun when specific C run-time (CRT) functions are used
C4995 /we4995 Use of a function marked with pragma deprecated
C4996 /we4996 Use of a function marked as deprecated

Ссылки по теме: