Голос Сіетла: розмовляємо з Сергієм Тепляковым

Останні дві мої статті — інтерв'ю зі спікерами однієї конференції. Мені здалося цікавим поговорити з людиною, який свого часу відмовився виступати на цій конференції, «за одного маленького сімейного обставини». Цей чоловік — Сергій SergeyT Тепляков, MVP, автор чудової книги про патерни проектування, адепт TDD, нині розробник Tools for Software Engineers Microsoft і мейнтейнер бібліотеки Code Contracts.

Під катом багато тексту про конференції, TDD, парне програмування, архітектуру Code Contracts, хабру.



Про конференціях з точки зору Слухача
Сергій, добрий день. Навіщо люди відвідують конференції? Навіщо їх варто відвідувати?
Я, чесно зізнатися, толком і не відвідував конференцій, якщо не був там спікером. Але от кожен раз, коли я там був, то головне, що виносив звідти – це натхнення. Так, може бути, це звучить завищена, але конференції і спілкування з розумними колегами для мене завжди були найкращою мотивацією: вивчити щось нове, поділитися чимось старим або просто продовжувати свій розвиток, як фахівця і як людини.

Ти прочитав і дав огляди на дуже багато книг. Що можеш порадити в плані конференцій?
Досить складно дати конкретне питання на досить загальне питання. Тут важливо розуміти, що саме вам там потрібно: зарядитися енергією? Познайомитися та/або поспілкуватися з цікавими людьми? Поповнити якісь конкретні знання? Якщо останнє, то замість конференції потрібно взяти пару розумних книг, а от якщо один з перших пунктів, то знову-таки потрібно з'ясувати якість і цікавість конференції і самостійно вирішити: йти чи ні.

Як оцінити конференцію за програмою?
Конференцію потрібно оцінювати за спікерам і йти потрібно не на тему, а саме на людину.
Якщо виступає Андрій Акіньшин, то я піду його послухати не залежно від того, про що він буде говорити, про пристрої Stopwatch-а чи про тему, взагалі не пов'язаної з продуктивністю. Оскільки я впевнений, що якість буде високою і я дізнаюся з нього досить багато нового.

Ок, а як оцінювати спікерів?
Досить просто, насправді. Якщо спікер відомий гарними виступами — йдеш. Якщо спікер не знайомий, але побіжний гуглеж виводить тебе на його блог, github або хабру — оцінюєш матеріал. Якщо спікер не знайомий і не гуглится — краще піти на щось інше.

Про конференціях з точки зору Спікера
З відвідуванням зрозуміло. Можеш розповісти, навіщо люди виступають на конференціях?
Думаю, це питання самореалізації або підтвердження певного рівня розвитку: «Так, я доріс до певного рівня, коли мені не страшно виходити перед багатьма людьми і ділитися своїм досвідом: як позитивним, так і негативним. Мені не соромно зізнатися в тому, чого я не знаю, оскільки я знаю досить корисних речей, якими цікаво поділитися». Для мене виступ взагалі, і на конференціях зокрема, було таким собі показником розвитку. Починалося все з розмовою за чашкою кави, або в процесі вливання в новий колектив, коли ти починаєш більш впевнено спілкуватися з колегами, ділячись досвідом, відстоюючи свою думку. Після цього йдуть локальні виступи на всяких митапах і юзер-групах, після чого вже не страшно виступити перед кількома сотнями.

Окремий плюс: валідація знань в процесі підготовки. Знаєш фразу: хочеш чогось навчитися — навчи іншого. Підготовка до виступу може зайняти в 10-20 разів більше часу, ніж сам виступ, і весь цей час ти цілеспрямовано копаєш одну тему. Бувають звичайно експерти, розповідають\пишуть щось цікаве без плану, але таких мало. З ходу можу згадати хіба що Кріса Брума, одного з архітекторів CLR. Він більшість постів писав прямо з голови, а якось раз зробив вступ “Раніше я піднімав теми які не вимагали від мене додаткових досліджень. Цю статтю я віддав на попереднє рев'ю, бо на деякі питання у мене не було відповідей.". Так що конференція — це ще мотиватор вивчити щось детальніше, структурувати знання.

А як зрозуміти, що «зараз я знаю досить корисних речей, і мені дійсно є про що розповісти»?
Як я вже говорив, найпростіше обкатати матеріал «на кішечках». Це можуть бути посиденьки за кавою, корпоративні виступи, замітки в блозі або в будь-якому іншому вигляді.
Тут дуже важливо провалидировать свої знання на кого-то, щоб не виявилося, що твої знання не сильно відповідають реальності або не є такими вже глибокими і/або цікавими. Є варіант валідації свого досвіду з допомогою гитхабов та інших опенсорсов. Якщо ти пофиксил пару багів в Розлине і запропонував варіант дизайну, який схвалили старожили проекту чи інші учасники, то це має бути достатнім свідченням твого досвіду та зрілості.

тобто, детально ти не готуєшся? Лише канва?
Канва, обов'язковий підрядник (хоч я його і не дивлюся в процесі виступу), і все. Різниця між виступом і написанням посту не так і велика: вступ, розповідь, висновок; тобі потрібно подати думка, ти прикидаєш, що знає читач, які місця потрібно пояснити, які просто згадати. В пості, правда, можна на щось послатися, а ось на конференції сказати «хлопці, спочатку прочитайте ось ці три статейки, а потім возвразайтесь» вже не вийде.

Ти виступаєш в Штатах?
Поки немає. Пріоритети інші. Плюс, рівень розмовної англійської не дозволяє вільно розмовляти. Як я вже говорив, я зазвичай не промовляю все заздалегідь, а просто готую план і розповідаю по ньому, а в таких речах мова дуже важливий. Важко виступати, коли не можеш висловити нічого понад підготовленого, коли навіть пожартувати не в змозі. А ще впевненість потрібна. У нас в MS є традиція: іноді хлопці збираються командою або проектом в кімнаті з ланчем, і там хтось розповідає колегам про цікавих технічних штуках. Поки я виступаю тільки там.

Яка аудиторія в твоїх MS посиденьках? Порівняно з конференцією?
Серед слухачів іноді зустрічаються люди, які приходять помірятися патернами. Серед колег такого зазвичай не буває, а ось на конференціях трапляється. З такими товаришами треба вміти працювати.

Соромно визнати, але один раз я виступив у ролі такого товариша. Як з такими працювати?
Тут треба зрозуміти, чого хоче слухач; можливо, задаючи питання, людина дійсно намагається щось зрозуміти, наприклад, він спец-суміжник, або просто колега з багатим досвідом в іншій мові. Якщо ти думаєш, що можеш відповісти на питання, але це довго\складно — запропонуй обговорити після виступу. Якщо він тебе підводить до відповіді «я не знаю» — кажи «я не знаю, погуглю, зв'яжуся з вами після». Бувають, ти посилаєшся на Ріхтера, а з тобою починають спори типу «Ріхтер говорив не так...», «цього не було...», такого роду спори звичайно неконструктивні й досить послатися на «після виступу», ввічливо.

TDD
Класична схема: тест-код-рефакторинг. Наскільки я зрозумів з твоїх статей, ти їй дотримуєшся остільки-оскільки. Як визначити, коли потрібно їй слідувати, а коли ні? Як утримуватися від скочування до «да ладно, весь проект вже без тестів, і до цієї фиче нічого писати не буду»?
Чесно сказати, я практично не використовую TDD в його класичному поданні. Я пишу багато тестів, але не пишу їх до коду. Мій цикл виглядає приблизно таким чином:
  • Дивимося на проблему і намагаємося побачити високорівневі компоненти. Можливо, беремо олівець і малюємо квадратики з відносинами. Це дозволяє побачити картину цілком і те, які подкомпоненти в неї входять. Після цього можна накидати високорівневий тест кейс, але зазвичай я обходжуся без цього.
  • Після цього починаємо декомпозировать систему знизу-вгору (до цього ми спробували розібрати/розмалювати проблему за принципом зверху вниз). Беремо один з листових класів і починаємо думати, чим він є.
  • Після цього я переходжу до реалізації, накидаю каркаси функцій, можливо розставляючи контракти.
  • Потім переходжу до реалізації певної функції, і лише після її написання додаю тест.


Виходить зовсім не test-first, але мені зручніше «бачити» дизайн в коді і вже валідувати його коректність за допомогою тестів. Мені не зручно «вирощувати» дизайн за допомогою тестів, для мене таке переключення «тест»-«код» сильно відволікає.

Тепер давай перейдемо до другого питання: «як утриматися від скочування». Тут все простіше.

Кілька років тому я займався просуванням («продаванием») юніт-тестування замовнику. І я ні тоді, не зараз не акцентував увагу на регресійної складової на якість дизайну і т. п. Я намагався показати, як тести допомагають тут і зараз: «ок, нам потрібно додати нову фічу. Але замість того, щоб перевіряти її осудність шляхом деплоя сервака з подальшим проклацыванием 73 пунктів у UI-е, чому б не додати простий юніт-тест, який перевірить найбільш складну функціональність? Так, доведеться трошки подумати, як виділити цю можливість в окремий компонент, а це швидше, ніж вся ця каламуть з ручним тестуванням».

Іншими словами, якщо мені потрібно зробити мінімально осудна додаток нетривіальною складності, я буду думати про те, як винести нову логіку в окремий клас/метод, щоб його можна було легко протестувати. Коли все дуже запущено, то це не завжди легко зробити і не завжди це працює, але, як це не дивно, для мене це працює в більшості випадків.

Буває, що все дуже запущено і новий функціонал – це варіації старого, коли зміни вносяться в групу існуючих класів. У цьому випадку думаємо, як покрити все це добро інтеграційними тестами, після чого вирішуємо, чи буде виправданим клин-ап існуючого коду, будуть суттєві зміни у кусках чи ні? Якщо мова йде про погане код, який ми збираємося активно розвивати, то я спробую обґрунтувати більш адекватні зміни перед внесенням суттєвих функціональних змін. Якщо ж код мертвий і не буде розвиватися, то тут доведеться тестувати ручками.

Коли тести писати не потрібно? Або ти тестируешь все, аж до PS скриптів?
Є ряд речей, покривати тестами які немає ніякого сенсу. PS-скрипти – це один з них. Оскільки PowerShell за своєю природою щільно працює з оточенням, то тестувати скрипти ізольовано – дуже складно. Крім того, PowerShell – це трохи божевільна штука, і без реальних даних ти просто не будеш знати, чого від нього чекати і працює твій скрипт чи ні.

Є досить багато речей, які я не тестую безпосередньо. Якщо багато легасі коду, то тут потрібні кілька інтеграційних тестів, а юніт-тести з високим покриттям коштує вже писати для нових компонентів. Є речі, які повинні бути покриті тестами, але це будуть не модульні тести, а інтеграційні, які швидше перевіряти базову валідність. До цього відносяться тести бази даних та комунікаційних речей, типу WCF.

Як і з багатьма іншими речами, потрібно розуміти, що тести – це інструмент, а не самоціль. При цьому потрібно змінювати ставлення до інструменту в процесі роботи. Якщо тестів багато, і вони ловлять постійні регресії – це добре. Якщо тестів багато і вони постійно ламаються, – то це погано. Але тут важливо не кидатися з крайності в крайність, не прибивати всі тести одним махом, вважаючи їх марними. Тут треба подумати, як ми тестуємо, що ми тестуємо, хороший наш дизайн? Зазвичай тендітні тести – це симптом більш загальної проблеми – проблеми з дизайном, високою в'язкістю і з тестами, які перевіряють деталі реалізації, а не поведінка абстракції.

Парне програмування
Як написання тестів поєднується з парним програмуванням? У тебе було кілька статей на тему парного програмування, але прямого зв'язку з тестами я не помітив.
Теоретично, робота в парі передбачає розподіл ролей, коли один лабає тести, а другий – логіку. На жаль, у мене не дуже багато досвіду класичного парного програмування, при якій ми йшли цим принципом.

В результаті я завжди працював в парі так, щоб було комфортно обом. Це означає, що тести писалися так, як ми вважали за потрібне. Часто це були інтеграційні тести, які покривали досить великі шматки, після чого ми разом працювали над реалізацією. Повноцінні тести ми ж потім додавали по одному.

Але тут потрібно розуміти, що якщо TDD – це справа в деякій мірі особисте, то TDD в парі – це справа цієї самої пари. Пара повинна визначитися з тим, як їй бути ефективною. В моїй роботі ми не соромилися говорити про те, що зараз варто робити, а що ні. Тут догм бути ніяких не має.

Як домовлятися з агресивними напарниками, як з незручними, закритими?
У мене досвіду не особливо багато, все-таки парне програмування — підхід досить рідкісний в індустрії, як у Штатах, так і на Україні. У нас є чимало розумних людей на проектах, але я не готовий прогать з партнером «зі стелі». На мій погляд, парне програмування неефективно якщо одна людина акуратний в коді, іншої немає, або один швидко пише, інший вдумливо, або один агресивний інший сором'язливий. Будь я в такій парі — спробував би уникнути такого. Дуже мало людей мені підійдуть чисто психологічно. Це я саме про парне програмування кажу. Якщо потрібно менторить — думаю, відсотків 90 мене влаштують, я знайду до них підхід.

Як ти сам почав кодити в парі?
Я брав участь у хакатоне, і заджойнился до одного з колег для створення наступної версії Code Search, це пошуковий движок для referencesource.microsoft.com — попередня версія багато зайвих даних тримала в пам'яті. У мене був відповідний досвід у Elastic Search, я заджойнился. Ти знаєш хакатони: часу мало, треба зробити багато, часу і можливості розділити роботу не було, і ми сиділи за одним компом набираючи один код. Вийшло вдало, і з тих пір деякі завдання кодим парою, благо через кілька місяців опинилися на одному проекті. Але ще раз повторюся, це рідкість. На Україні я про таке взагалі не чув, MS чув про одну команду практикує регулярне парне програмування, але це крапля в морі.

У нас бувало з колегами, що ми сперечаємося з якогось приводу трохи довше ніж треба, дуже непоступливі. Такі обговорення можна вважати ПП?
Це завжди так, особливо, якщо хто-то в команді новачок. Коли притретесь, пободаетесь — можете спробувати покодить в парі. Коли вже з'ясуйте, хто чого вартий, коли зрозумієте що «ну так, людина вперта, але думки слушні, ну так, я теж не подарунок, але теж привношу користь», тоді можна пробувати. До цього буде досить складно комунікувати, та й користі буде мало. Якби ти працював з профі парного програмування, який дуже швидко адаптується — можна було б спробувати, але це явище ще більш рідкісне, ніж звичайний «парник».

Як готуєшся до парного програмування?
Аж ніяк. Взагалі. Хіба що, варто в контекст вникнути до початку роботи, а так взагалі нічого не потрібно.

заважає мовний бар'єр?
Взагалі не заважає. Загальний проект, спільну мову програмування, загальна предметна область. У самому крайньому випадку можна взяти папірець і накреслити на ній щось.

Інструментальний бар'єр?
Так, це класика. Мій приятель R#-хейтер, я ж скоріше навпаки. Іноді ми ржем з цього. Тобто кодишь ти такий, ставиш фігурну дужку, тут у тебе все вирівнювання з незвички летить, і ти такий, «стоп, горщик, не вари, Ctrl+Z, все відміняється...». Начебто дрібниці, інші переноси, дужки, хоткей, але спостерігати за процесом забавно. З іншого боку, непоганий спосіб перейняти навички використання тулзы. Останнім часом я чую фрази на кшталт «не хочу зізнаватися, але ось ця фіча R# мені подобається». Тобто, спочатку чоловік не любив R# з-за гальм на великих проектах, а тепер починає цінувати. Плюс, у нас були відмінності в тулзах для diff-merge, цікаво було подивитися за аналогом. Мені взагалі спостереження подобається найбільше в процесі, починаючи від підходу до дизайну, закінчуючи використовуваними тулами. Тобто, ти не мануал читаєш, а дивишся як жива людина справляється із завданням «на льоту». Дуже зручно.

Code Contracts
Ти один з розробників Code Contracts. Як ти почав працювати з проектом?
Я є давнім шанувальником контрактного програмування. Почалася моя любов після знайомства з книгою Бертрана Мейєра «Об'єктно-орієнтоване побудова програмних систем». Обдумування дизайну в термінах відповідальності дозволяє істотно спростити розробку, дозволяє зробити його більш чистим.

На платформі .NET для цих цілей давно існує бібліотека CodeContracts, і я її використовую вже давно. Десь за рік до переходу в MS я написав плагін R# для спрощення контрактного програмування, і використання цієї либы. Плагін відловлює типові помилки Code Contracts, дозволяє додавати Contract.Requires(arg != null) контракти і робить ряд інших корисних речей. У перший рік роботи в MS я зробив невелику тулзу для Applications Insights. Вона виявилася корисної для Майка Барнета, одного з авторів Code Contracts. Потім я перейшов в іншу команду, і так вийшло, що ця команда щосили використовує Code Contracts і це один з найбільших користувачів Code Contracts в MS. Після виходу VS 2015 ми могли відмовитися від Code Contracts, або виправити бібліотеку, щоб вона могла підтримувати C# 6.0. В результаті я півтора-два місяці активно займався доопрацюванням Code Contracts. Саме в цей період часу я був найактивніше на github. Крім додавання нових можливостей були полагоджені ряд особливостей, які Code Contracts нормально ніколи не підтримував, зокрема, постусловия в асинхронних методи. Після цього я став одним з мейнтейнерів бібліотеки. Зараз я займаюся проектом у вільний від роботи час, але займаюся значно менше часу, ніж хотілося б.

Чому?
Інші пріоритети.

Новий проект?
Новий, але пов'язаний з Code Contracts.

Не розумію.
У Code Contracts є кілька серйозних проблем, які ускладнюють розвиток. Проект великий, складний, сотні тисяч рядків місцями заплутаного коду. Крім того, бібліотека призначена для аналізу і зміни IL коду, без прив'язки до конкретного .NET мови або компілятору.

Бібліотека містить три основних компоненти.
  • Інфраструктура (Common Compler Infrastrucutre, CCI) — декомпилит IL об'єктну модель (Abstract Syntax Tree, AST). AST на виході виходить мутабельное, низькорівневе. Замикань немає, async немає, блоків ітераторів немає.
  • Статичний верифікатор CC Check, перевіряє валідність контрактів під час білду. Тобто, вона парсити AST, і якщо бачить метод з NotNull «анотацією» намагається довести, що Null цей метод ніколи не прийде.
  • Runtime IL Rewriter (CC Rewrite). Займається трансформацією dll файлів під час білду. Перетворює звернення до класу Contract в різні конструкції: генерацію виключення, в Debug.Assert або просто видаляє твердження цілком. Це окрема утиліта, не пов'язана з верификатором.


У цього підходу є важлива особливість: різні компілятори і навіть різні версії одного компілятора, генерують різний IL-код для одних і тих самих синтаксичних конструкцій. А CCI надає лише тонку обгортку над IL: там немає лябда-виразів, ітераторів або асинхронних методів. Ти бачиш, що в тебе створюється об'єкт деякого класу, але ти не знаєш, це реальний клас, створений програмістом, або згенерований компіляторів в результаті використання лямбда-вирази. Точніше ти можеш про це дізнатися, оскільки компілятори використовують спеціальні патерни генерації коду. Тому ccrewrite аналізує код, дивиться на імена типів і вже по них визначає, чи є це клас-замикання, клас для ітератора або асинхронного методу або щось ще.

При цьому патерни змінюються в різних версіях компілятора. Для тих же лямбд C# 5.0 генерував статичне поле з делегатом, а в C# 6.0 з'явився новий тип класів-замикань. Розробники мови C# з'ясували, що экземплярные методи дешевше статичних, тому тепер для «незахватывающих» лямбда-виразів генерується сінглтон замість статичної змінної.

Абсолютно божевільний приклад можна привести для асинхронних методів. Компілятор C# 6.0 генерує різний код в залежності від кількості await-операторів у методі: якщо await-ів немає вийде один код, якщо await тільки один — інший, і так далі.

І ми мусимо враховувати усі ці деталі. Кожен раз коли компілятор починає інакше обробляє мовну конструкцію — треба міняти і верифікатор, і Rewriter. Кожна зміна мови — це велика і серйозна робота: потрібно не тільки внести підтримку нових мовних конструкцій, але й перевірити, що всі старі конструкції продовжують працювати, та ще й зворотну сумісність зберегти.

Окрема проблема: дуже важко чинити баги. Можна просидіти 8 годин заради двох рядків фікса. Так я бився з одним з багів, коли у створеному узагальненому методі всередині узагальненого класу в певному випадку тип аргументу був !T, а не !!T (це означає, що використовувався узагальнений параметр типу, а не узагальнений параметр методу).

Загалом, AST генерується CCI занадто низькорівневе, що виливається в дуже складну підтримку. З кожною новою версією мови компілятора доводиться проробляти все більше тяжкої та невдячної роботи.

Ще одна проблема: негативний вплив CC Rewrite на час білду. CC Rewriter недетермінованої. Тобто, ти береш одну DLL, двічі викликаєш CC Rewriter — і гарантовано отримуєш два різних бінарника. Для сучасних білд систем це дуже велика проблема; фактично втрачається можливість кешування і інкрементальних білдів. Тобто, якщо ти використовуєш CC Rewrite і вніс зміну в один файл — ти гарантовано повинен перебилдить всі рішення. Якщо ж ти не використовуєш CC Rewrite — ти можеш перебилдить тільки один проект і всіх його прямих клієнтів. На сотні проектів використання CC Rewrite збільшує час білду в рази.

Плюс, CC Rewriter при перезапису хачит pdb, і не завжди це робить коректно, що негативно позначається на дебаге. З недавнього — мій колега просто не міг займатися дебагом без відключення CC Rewriter, у нього з'їжджає call stack, неправильні показувалися локальні змінні, весь debug experience був втрачений.

З-за цих проблем ми з колегою зараз працюємо над Source Level Rewriter (SL Rewriter). Тобто, ми не оперуємо IL, ми змінюємо високорівневий код. З недоліків — це тільки утиліта тільки для C#.

тобто, ви берете Roslyn-дерево, зраджуєте його, і віддаєте компілятор? Звичайний фіксер?
Саме. Roslyn надає рівно той механізм, який нам потрібен. Ми беремо наш Workspace, шукаємо всі звернення до контрактів, і вставляємо потрібні нам фрагменти.

Якщо ви використовуєте Roslyn, ви обмежені# 6.0?
Майже. Насправді, нас більше хвилює інтеграція з компілятором, але це тема для окремої розмови.

Де можна помацати Source Level Rewriter?
Зараз це внутрішній продукт, який пиляють 2 людини. Поки що він не готовий, але як тільки він буде коректно працювати у нас в команді — ми його расшарим…

Будуть прогнози про швидкодію? Зараз Code Contracts часто лають за «заторможенність».
Дивись, CC Check дуже повільний. Для коректної роботи ти повинен розставити дуже багато анотацій, і білд ста тисяч рядків коду буде займати хвилини, а то і десятки хвилин. Потім ще треба висновок проаналізувати. Коротше, повільний і неефективний інструмент з точки зору розробника. Точніше, ідея хороша, але завдання дуже складна і повільно вирішується. Я знаю буквально кілька команд активно його використовують. Моя команда відмовилася від нього два роки тому і ніхто не прагне знову його використовувати.

Тепер CC Rewrite. Як я вже говорив, він істотно впливає на білд-процес. Є кінцеві трюки, наприклад відключити його локально і використовувати тільки на білд-машині, але уповільнення все-таки є.

Набагато важливіше вплив на рантайм. З контрактами дуже легко розплодити зайві перевірки. Так, якщо у тебе є важкі інваріантів на класі в початок і кінець кожного відкритого методу додадуться перевірки. Або контракти на колекцію — ти повинен проитерировать всю колекцію. Особливо це може бути помітно якщо у тебе є ланцюжок з п'яти методів пробігають по колекції. Або перевірка рекурсії, на обмеження виклику контрактів в глибину. Вона використовує виклик до thread local, що додає гальм. Одним тільки відключенням цієї перевірки ми підвищили end-to-end продуктивність на 15%. Подібних деталей не сильно багато, але про них варто знати.

З іншого боку, ми зараз пиляємо білд-движок, це системне і чимала кодова база. Нам доводиться налаштовувати контракти для мінімально впливу на продуктивність в рантайме, але відмовлятися від контрактів ми не хочемо: повідомлення від контрактів в одержуваних нами креш-дампи дають дуже багато корисної інформації, домогтися цього іншими стандартними засобами — значно складніше.

Крім того, треба сказати, що для більшості додаток накладні витрати на рантайм будуть мінімальні.

тобто, для малих проектів інструмент можна використовувати без налаштувань?

Для малих — так. Для середніх можна поставити тільки перевірку передумов і відкритих методів, тоді імпакт буде мінімальний. Ключову функціональність, ретельно покриту тестами, можна налаштувати на видалення всіх контрактів з рантайма. Інструмент настроюється — їм цілком можна (і варто) користуватися. Тюнить його доведеться тільки на великих проектах.

Питання про хабру.
Чому ти на неї прийшов?
Ух… давно це було. Я прийшов на хабр в 2010-му, коли rsdn вже помирав, dou.ua вже був, але не був настільки популярним. Хабр в той час активно розвивався, з безліччю глибоких технічних постів і, найголовніше, з високим рівнем сигнал-шум. Його було цікаво читати, в нього було цікаво писати. Публікації там – це був найпростіший спосіб обговорити якусь технічну проблему. Так, не всі коментарі були однаково корисні, але в той момент це було мені цікаво.

Чому ти пішов з хабры?
Передусім змінився я, змінилися мої інтереси. Я продовжую писати в своєму блозі, часто вибираючи більш філософські теми, і там вже склалася певна аудиторія, з якою цікаво, яка знає мене і мої інтереси. Писати ж паралельно в блозі і на хабре — не зовсім правильно. Після того як мої останні «паралельні» пости зібрали більше коментарів у блозі — я практично перестав писати на хабр.

Я все ще читаю хабр, але частіше завдяки соц-мереж та інших способів. Рівень шуму шляхом читання RSS для мене занадто високий: мабуть, я не цікавлюся всім, що цікаво аудиторії хабра, яка стала ще більш різноманітною. При цьому я часто потрапляю на відмінні статті, вдумливі, глибокі і цікаві.

Крім того, хабр – це найбільший IT-портал, за допомогою якого можна почерпнути багато корисної інформації. Вивчаючи конкретну тему я все ще часто там буваю, якщо шукаю в російськомовному сегменті.




Від автора: наша розмова з Сергієм вийшов дещо сумбурною і порушив відразу кілька непов'язаних тим. Якщо я щось упустив — Сергій доступний в приват і коментарях. Відповідь може йти більше звичайного, враховуйте часовий пояс: час Сіетла відрізняється від московського на 11 годин.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.