tag:blogger.com,1999:blog-85967331922741089522024-03-12T09:44:07.443+02:00Programming stuffSergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.comBlogger321125tag:blogger.com,1999:blog-8596733192274108952.post-19429317707276549722019-12-03T09:45:00.000+02:002019-12-03T09:45:50.874+02:00Главный навык программиста<p>Я заметил, что опытных специалистов из разных областей объединяет как минимум одна вещь: осторожность в суждениях.<p>Если вы спросите программиста, повара или фитнес тренера о чем-то довольно сложном, то ответ его будет довольно обтекаемым, либо же он задаст несколько наводящих вопросов, чтобы узнать контекст получше.<p>Нужно ли писать тесты? Важно ли качество кода? Какая лучшая степень прожарки мяса? С чем лучше всего сочетается белое вино? Нужно ли делать жим лежа со становой или турника будет достаточно?<p>Когда я рассматриваю источники информации по некоторой теме я ищу в авторе глубину и осторожность. Желание дать фундаментальные принципы, а не конкретные ответы на сложные вопросы. В этом плане старина Боб Мартин меня давно разочаровал. Когда-то он для меня был автором лучших книг и статей, но его категоричность, негибкость в суждениях и неумение смотреть на проблемы шире перевели его в категорию "анти"-авторов. В категорию людей, чье мнение скорее опасно для индустрии, чем полезно.<p>Моя нелюбовь к старине Бобу началась с его книги "Принципы, паттерны и методики гибкой разработки на языке C#" (<a href="http://sergeyteplyakov.blogspot.com/2013/12/about-agile-principles-patterns-and.html">вот большая критическая статья на эту тему</a>), но дядюшка Боб периодически выдает и вот, после очередного его высказывания, мне захотелось подумать над поднятой им темой более подробно.<p>Итак, вот его <a href="https://twitter.com/unclebobmartin/status/1200074140637642754?s=20">твит</a>:<p>When you read code, the race, religion, politics, gender, and orientation of the author are irrelevant and invisible. The only thing you can tell about the author is their ability to write well organized code. Nothing else matters.<p>Это единственный твит, здесь нет контекста, нет продолжения от автора, так что многие вещи я буду додумывать. А учитывая мою нелюбовь к автору, я могу быть весьма предвзятым. Но поскольку сам автор не соизволил дополнить свою мысль, то я не вижу в этом ничего плохого.<p>Структура твита. Автор вначале говорит о расе, религии, ориентации и поле, как о несущественных вещах в контексте анализа кода. Да. С этим никто не будет спорить. Это так. Но потом он заявляет, что единственная вещь, которая говорит об авторе кода - это его умение писать хороший код и что ничего другое не важно.<p>Здесь используется довольно грязный трюк с подменой понятий и отсутствием причинно-следственной связи между двумя частями твита. Тот факт, что мы не должны судить об авторе кода по его "внешним атрибутам" не делает "хорошо структурированный код" важным. И с чего старина Боб решил, что должно какое-то одно главное качество, характеризующее специалиста?<p>Поскольку тема эта интересна, то давайте немного пофилософствуем по этому поводу.<p>"Что самое главное в жизни?", может спросить Боб. "Семья, конечно", ответит один. "А как же здоровье? Если нет здоровья, то радости от семьи будет не много.", возразит второй. "А как же призвание, а деньги? На одной семье, пусть и здоровой, далеко не уедешь! Нужно ж еще и кушать вкусно, да и делом интересным заниматься!", скажет третий. "Ну а помощь другим? Это ж тоже важно! А друзья? А карьера? А красивое тело?".<p>Мне кажется, что жизнь достаточно сложная штука, чтобы в ней была одна единственная главная вещь, всецело определяющая ее суть . Жизнь - это игра не совсем с фиксированной суммой. В разумных пределах можно делать больше и успевать больше. Семья может мотивировать заниматься другими делами, например, своим здоровьем и даже карьерой. А приходя с работы, которая тебя радуем, может оставаться больше сил, чтобы поиграть с ребенком и насладиться временем, проведенным наедине со своим партнером. Жизнь многогранна и не может всецело определяться чем-то одним.<p>Работа программиста несколько проще, чем жизнь в целом, но и она достаточно сложна и многогранна. Чего стоит хорошо структурированный код, который решает не ту проблему? А если автор хорошо структурированного кода токсичен и из-за него вся команда разваливается? А если хорошо структурированный код использует странные или даже неверные паттерны, многословен или дублирует код, написанный в другом месте?<p>Уметь писать хороший код очень полезно, но я не могу назвать этот навык главным и самым ценным навыком программиста. Если на то уж пошло, то умение читать реальный (читай плохой) код является более полезным навыком, ведь большую часть времени мы проводим в анализе существующего кода и поиска правильного места для вставки или изменения функционала.<p>Если же задаться вопросом о главном навыке (навыках?) специалиста из любой области, то я бы сказал, что это умение учиться и критически мыслить (да, и не быть м#$@ком). Эти два ключевых мета-навыка позволят развить любые другие.<p>Я заметил, что лучшие инженеры учатся постоянно. И не столько читая книги, сколько потребляя информацию в процессе решения реальных проблем. Они мыслят более масштабно, и не боятся нарушить статус-кво, задавая неудобные вопросы. А ту ли проблему мы решаем? А что же на самом деле нужно нашим пользователям? А не стоит ли заменить/переписать ключевой компонент? А не залипли ли мы с этими практиками, которые работали когда-то, а сейчас дают больше вреда, чем пользы?<p>Хороший специалист может увидеть проблему (в себе, в коде, архитектуре или подходах), подумать об альтернативах и изучить наиболее подходящее решение.<p>Мне может лишь в страшном сне привидеться, что вся команда состоит из однотипных людей. Людей с одним, даже самым лучшим единственным навыком. Хорошая команда - это разнообразие в лучшем понимании этого слова. Разнообразие характеров, навыков, подходов. Их должны объединять схожие принципы и ценности, но попытка грести всех под одну гребенку вызывает у меня лишь недоумение.<p>Мне тоже хочется найти простое решение таких сложных проблем, как разработка ПО. "Развивай навык Х и ты будешь отличным специалистом!". Но мир и разработка ПО достаточно сложны и многогранны, чтобы был один главный навык, который бы в одиночку смог бы решить все наши проблемы.Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com14tag:blogger.com,1999:blog-8596733192274108952.post-21219837402706285732019-03-12T04:40:00.002+02:002019-03-12T04:40:51.038+02:00О пользе ведения блога<p>Пришло время ответить на вторую часть вопроса, который я поднял в предыдущем посте «<a href="http://sergeyteplyakov.blogspot.com/2019/02/blog-post.html">Я выгорел?</a>: Насколько полезно вести блог: с профессиональной, финансовой и других точек зрения?
<p>Как и у многих других занятий, у ведения блога есть две стороны. Видимая всем верхушка айсберга и кропотливая работа, невидимая окружающим. Когда мы видим, что кому-то блог принес прямые или косвенные финансовые, то мы оцениваем их без учета вложенного труда.
<p>Я знаю людей, которым блог, выступления на конференциях или участие в опен-сорс проектах помогли в поиске новой работы или в продвижении на текущей. Если вы следите за .NET сообществом, то, может быть, заметили, что довольно многие MVP (Most Valuable Professional) оказываются в итоге сотрудниками Майкрософта. Мой путь, собственно, очередной тому пример.
<p>Но здесь важно не путать корреляцию и казуацию. Видимая активность в интернете помогает в создании связей, которые можно использовать в поиске работы, но большинство MVP – это талантливые люди, и они в состоянии найти работу путем прямого инвестирования времени в этот процесс.
<p>Создание публичного профиля, такого как блог или гитхаб, требует времени и постоянных усилий. А это значит, что мотивация вида «это позволит мне устроиться на хорошую работу через 4.5 года» работать не будет. Мозгу нужно постоянное подкрепление: «пишу блог» - получаю какую-то радость. Никакой дисциплины не хватит, если время между действием и поощрением исчисляется годами.
<p>Блоггинг, опен-сорс и публичные выступления – это не единственный способ получения хорошей работы. Есть случаи, когда все это сработало, но ведь на каждого MVP, который нашел хорошую работу, есть десятки не-MVP, которые нашли работу не хуже.
<p><b>Так стоит ли вести блог для карьерных целей</b>? Я бы сказал, <b>нет</b>.
<p>Если мотивация лишь финансовая, то ее будет недостаточно. Если хочется найти работу за границей, то есть другие варианты: самый простой – бодишопы. Если же хочется сразу в крупную компанию, то активное участие в открытых проектах кажется наиболее полезным. Плюс можно ловить выездные hiring ивенты. Ведение же блога кажется наименее управляемым процессом поиска работы за границей.
<p><b>Позитивная сторона блоггинга</b>
<p>Есть много талантливых разработчиков, которые работают с 9 до 5 и их опыту и навыкам можно только позавидовать. Есть же такие, кто работает с 9 до 5, а потом занимается серьезными сторонними проектами дома, причем делают это много лет подряд. Другие просто проходят курсы на курсере и других источниках и пилят небольшие домашние проекты типа умного дома, чисто для себя.
<p><b>Кристаллизация знания</b>. Я долгое время, использовал блог в качестве катализатора саморазвития. Даже не слишком продвинутый пост требует детального изучения темы, что потом можно использовать напрямую в работе или за чашечкой кофе, объясняя эту тему своим коллегам.
<p><b>Мотивация. </b>Когда я беру новую тему для изучения, мне нужна цель (зачем я изучаю это) и критерии завершения задачи (опубликованный пост в блоге). Это переводит задачу из разряда важных и несрочных в категорию важных и срочных. Дедлайны фиктивные, но даже они позволяют бороться с прокрастинацией.
<p>Многие коллеги в моей команде впитывают новые знания очень быстро в процессе решения повседневных задач. У меня такой подход работает лишь частично, например, когда нужно изучить что-то очень специализированное. Изучение же новых концепций или техник требует более осознанного подхода к обучению.
<p><b>Взгляд на себя со стороны.</b> Мне очень нравится возможность общения с собой в прошлом. Чтение своих собственных постов через несколько лет, это все равно, что чтения своего старого кода. Процесс этот вызывает смешанные эмоции, но очень отрезвляет и реально позволяет посмотреть на себя со стороны и оценить прогресс собственного роста.
<p><b>Навыки письменной коммуникации</b>. Это может звучать банально, но написание статьей – это полезный навык. Тут и выделение ключевых моментов, и умение ясно изложить и обосновать свое мнение, и умение находить хорошие источники информации по заданной теме, и умение выбора доходчивых примеров, и просто умение изучать что-то новое. А если писать на английском, то тут открывается целый мир новых идиом и языковых конструкций.
<p><b>Новые знакомства. </b>Это может звучать еще банальнее, но благодаря блогу я познакомился с десятками очень интересных людей. Есть и другие способы социализации, но блоггинг для меня является центральным способом поиска хороших знакомств.
<p><b>Негативная сторона блоггинга</b>
<p>Ведение блога – это <b>трудоемкий процесс</b>. И это главная причина, по которой хороших блогов так мало. Очень сложно написать пост, который будет интересен широкой аудитории, будет интересно писать и будет раскрывать тему на уровне, максимально полезном большинству читателей. Для одних – тема не будет интересной, для других – будет слишком много подробностей, а для третьих – их будет слишком мало.
<p>Можно потратить десятки часов на пост и получить лишь пару негативных комментариев. Даже когда пишешь вроде бы для себя, отсутствие реакции или один лишь негатив, может подорвать веру в саму необходимость блоггинга.
<p>Писать нужно исключительно для себя и не думать слишком много об аудитории, и тем более о <b>монетизации</b> и любой другой <b>финансовой выгоде</b>. Попытка мыслить рационально о пользе блога приведет к печальным выводам: ведение блога экономически невыгодно. Но в долгосрочной перспективе польза <a href="https://en.wikipedia.org/wiki/Compound_interest">накапливается</a>, но возможно это, если блог приносит удовольствие здесь и сейчас. Именно поэтому я пишу о том, что интересует меня. В этом случае усилия по определению не будут потрачены зря.
<p><b>Остерегайтесь своих собственных коммитментов</b>. Я ставил себе цель: публиковать посты раз в 2 недели. И вокруг этого строил все свое самообразование. Но такой темп стимулирует более глубокое изучение уже известных тем и не дает сосредоточиться на новом.
<p>Ты, вроде бы, и готов взять за что-то совсем другое, но привычка публикации детальных постов и кривая обучения делают этот подход несостоятельным. В результате, можно застрять в уютном мире знакомых вещей и никогда из него не выбраться.
<p><b>Так стоит ли мне вести блог?</b>
<p>Если цели только лишь краткосрочные – то нет. Если есть открытые проекты и с самореализацией на текущем проекте все хорошо, то выгоды от блоггинга тоже будут небольшие. А вот если чувствуется, что чего-то не хватает, что хочется капнуть в глубь технологий, но не хватает мотивации, то блог в этом вполне может помочь. </p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com13tag:blogger.com,1999:blog-8596733192274108952.post-81705766237535442382019-02-19T08:26:00.003+02:002019-02-19T17:55:51.991+02:00Я выгорел?<p>Или почему я намного меньше пишу в блогах.
<p>Мне недавно задали два вопроса: 1) не выгорел ли я, поскольку стал совсем мало блогать, и 2) стоит ли вести блог вообще и какие в этом преимущества?
<p>Сегодня я попробую разобраться в себе и ответить на первый вопрос, ну а на второй отвечу отдельным постом.
<p>Где-то год назад я начал слушать в дороге разные подкасты и самым моим любимым был (и остается) <a href="http://www.hellointernet.fm/">Hello Internet</a>. В одном из первых выпусков, <a href="https://www.youtube.com/user/CGPGrey">CGPGrey</a> привел довольно любопытную аналогию. Человек – это такой себе аккумулятор, к которому параллельно через резисторы подключены несколько лампочек: семья, работа, спортивная форма, хобби, друзья и т.д. И человек может менять сопротивление определенного резюка и, таким образом, тратить больше жизненной энергии на одну лампочку, уменьшая свечение всех остальных.
<p>Эта аналогия далека от идеала. Прежде всего потому, что количество энергии не является постоянным и зависит от того, на какие «лампочки» мы тратим энергию и как часто это делаем. Например, направив энергию лишь в одно русло мы, со временем, уменьшим запасы нашего аккумулятора и наоборот, подбирая правильный баланс мы можем этот запас увеличить.
<p>Хоть аналогия и не идеальна она прекрасно иллюстрирует главную сложность в жизни: поиск баланса между разными аспектами жизни и правильное распределенные нашего времени и энергии.
<p>В разные моменты времени у человека есть тенденция залипать на одном, игнорируя другое. Будучи подростком, мы забиваем на здоровье, на второй план отходит семья и мы тратим все наши силы на друзей и хобби.
<p>В начале нашей профессиональной карьеры в нас зачастую играют амбиции, и мы выкручиваем на полную «лампочки» работы и профессионального саморазвития. Но это редко длится вечно.
<p>Когда у нас появляется наша собственная семья распределение энергии меняется.
<p>Во-первых, больше энергии уходит на семью хотим мы этого или нет, а во-вторых, происходит некоторое профессиональное насыщение и мы попадаем под <a href="https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D1%83%D0%B1%D1%8B%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%B4%D0%BE%D1%85%D0%BE%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D0%B8">закон убывающей доходности</a> (diminishing returns) в вопросах саморазвития.
<p>Когда мы начинаем чем-то заниматься, то мы удваиваем наши знания каждые несколько месяцев. Поработав же 10 или 20 лет происходит профессиональное насыщение. Одни языки сменяют другие, молодые активисты новых технологий с пеной у рта доказывают, что они отыскали серебряную пулю. А на тебя лишь накатывает смутное подозрение, что ты такое уже где-то видел.
<p>Это не означает, что ты перестаешь развиваться, просто у тебя немного стихает мотивация трещать об этом на каждом углу.
<p>В определенный моменты ты понимаешь, что лампочка саморазвития у тебя горит даже сильнее чем раньше, просто сейчас ты изучаешь не подробности асинков в си-диезе, а, например, изучаешь <a href="https://www.youtube.com/watch?v=NNnIGh9g6fA">эволюционную биологию</a> или, быть может, кулинарию.
<p>В последнее время, я не раз сталкивался с мнением о пользе переноса знаний из одной дисциплины в другую. Возьмем, к примеру поведенческую психологию.
<p>Рассмотрим донорство органов в Германии и Дании. Эти страны достаточно похожи с точки зрения уровня жизни и культуры, но в Германии донорами органов становятся на порядок меньше людей, чем в Дании. Вопрос: почему? Дело в том, что в Дании донорство осуществляется по принципу opt-out, а в Германии – по принципу opt-in. Т.е. в Дании нужно отказаться от донорства, а в Германии – наоборот, с ним нужно согласиться.
<p>Но есть проблема. Когда человек сталкивается со сложным выбором, к которому он не готов, то он подсознательно старается отложить это решение и просто соглашается с «конфигурацией по умолчанию». Почему это важно знать программистам и UX дизайнерам? Да потому что эта же особенность проявляется и в использовании программ большинством пользователей: лишь малая толика людей ковыряется в настройках и меняет конфигурацию по умолчанию. Если что-то не включено по умолчанию, то для большинства пользователей это «что-то» не существует.
<p>Теперь давайте возьмем такое когнитивное искажение как «якорение» (anchoring). Вот небольшой пример. Давайте проведем опрос о том, в каком возрасте умер, ну, не знаю, Ницше. И для первой группы вопрос будет таким: «В каком возрасте умер Ницше, при учете, что он пережил свое тридцатилетие?», а второй – «В каком возрасте умер Ницше, при учете, что он не дожил до 100 лет?». Мы увидим, что ответы будут сильно отличаться. В первом случае средний возраст будет существенно ниже, чем во втором случае.
<p>Я на личном опыте столкнулся с проблемой якорения. Мы были с семьей в ресторане и семья за соседним столиком, услышав, что мы говорим по-русски, рассказала о возможной скидке в 10% с чека, если мы зачекинимся на фейсбуке. Мы их поблагодарили, но «трюком» не воспользовались. Но в момент выписывания чаевых, вместо 20% я неосознанно выписал 10%.
<p>Якорение часто проявляется во время планирования задач. Если один из разработчиков первым сказал, что фичу можно сделать за 2 дня, то все будут отталкиваться от этой «оценки» и будут стараться лишь ее скорректировать. Именно с этим борется planning poker, когда каждый член проекта записывает свою оценку на листочке и лишь когда все готовы, «карты вскрываются».
<p>Напоследок, мы можем взять экономическое понятие – sunk cost fallacy. Идея этого явления в том, что чем больше мы вкладываем сил и средств во что-то, тем тяжелее нам быть по этому поводу объективным. Это явление проявляется на уровне человека, который спорит, что старый язык программирования или технология все еще лучшее средство для решения всех проблем. На уровне команды, которая уперлась рогом в текущие архитектурные ограничения и не в состоянии сделать шаг назад и посмотреть на проблему с другой точки зрения. Или на уровне организации, которая не может уйти от старой бизнес-модели, которая уже не применима.
<p>И продолжать можно очень долго. Копнув достаточно хорошо в некоторую тему, можно с удивлением обнаружить, что все то, что мы так плохо учили в школе, является весьма интересной штукой. Да не просто интересной, так еще и полезной в жизни.
<p>Мне очень понравилась идея изучения чего-то нового кусками по 20 часов (<a href="https://www.youtube.com/watch?v=5MgBikgcWnY&t=3s">The first 20 hours – how to learn anything</a>): ты берешь какую-то тему, находишь вменяемые источники по ней и изучаешь ее 20 часов, применяя всякие там <a href="https://en.wikipedia.org/wiki/Practice_(learning_method)#Deliberate_practice">deliberate practice</a> и т.п.
<p>Жалкие 20 часов не сделают тебя экспертом в этой области, но этого будет достаточно, чтобы с нею познакомиться и решить, а нужно ли оно тебе. Таймбоксинг вообще отличная практика в управлении проектами, и мы можем перенести эту же идею из мира разработки ПО в нашу жизнь.
<p>Ну а теперь мы можем вернуться к вопросу выгорания. Так что же такое?
<p>Как по мне, выгорание – это уменьшение запасов нашей батарейки с жизненной энергией. Выгорание – это когда ты тратишь меньше времени на изучение языков программирования, *и* проводишь меньше времени с семьей и друзьями, *и* не занимаешься своим здоровьем, *и* ничем другим не интересуешься.
<p>Выгорание – это порочный круг уменьшения жизненной энергии. Видимое же уменьшение яркости одной «лампочки» не является признаком выгорания. Это вполне может говорить о перераспределении энергии и что сейчас она направлена в другие русла.</p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com10tag:blogger.com,1999:blog-8596733192274108952.post-80917279412900005482019-02-12T05:59:00.001+02:002019-02-12T21:23:49.752+02:00Не очень занимательный C#<p>Я как-то не особо лезу со своими комментариями к другим людям, а уж тем более к постам на хабре. Но вчера вот листал RSS-ленту и увидел интригующее название поста – <a href="https://habr.com/ru/company/veeam/blog/439478/">"Занимательный C#. Пять примеров для кофе-брейка"</a>.
<p>Итить, думаю, дай-ка зайду, посмотрю, что да как.
<p>И вот первая загадка – что выдаст следующий код: <pre style="font-family: consolas; background: #1e1e1e; color: gainsboro"><span style="color: #569cd6">using</span> System;<br> <br><span style="color: #569cd6">public</span> <span style="color: #569cd6">struct</span> <span style="color: #86c691">SDummy</span> : <span style="color: #b8d7a3">IDisposable</span><br>{<br> <span style="color: #569cd6">private</span> <span style="color: #569cd6">bool</span> _dispose;<br> <span style="color: #569cd6">public</span> <span style="color: #569cd6">void</span> Dispose() <span style="color: #b4b4b4">=></span> _dispose <span style="color: #b4b4b4">=</span> <span style="color: #569cd6">true</span>;<br> <br> <span style="color: #569cd6">public</span> <span style="color: #569cd6">bool</span> GetDispose() <span style="color: #b4b4b4">=></span> _dispose;<br> <br> <span style="color: #569cd6">private</span> <span style="color: #569cd6">static</span> <span style="color: #569cd6">void</span> Main(<span style="color: #569cd6">string</span>[] args)<br> {<br> <span style="color: #569cd6">var</span> d <span style="color: #b4b4b4">=</span> <span style="color: #569cd6">new</span> <span style="color: #86c691">SDummy</span>();<br> <span style="color: #569cd6">using</span> (d)<br> {<br> <span style="color: #4ec9b0">Console</span><span style="color: #b4b4b4">.</span>WriteLine(d<span style="color: #b4b4b4">.</span>GetDispose());<br> }<br> <span style="color: #4ec9b0">Console</span><span style="color: #b4b4b4">.</span>WriteLine(d<span style="color: #b4b4b4">.</span>GetDispose());<br> }<br>}</pre>
<p> <p>Ну, думаю, ок. Странно начинать с изменяемых структур и особенностей блока using, ну, ничего.
<p>Открыл объяснение, а в нем говорится, что причина странного поведения в упаковке, дескать. Компилятор зовет Dispose метод через каст: ((IDisposable)myStruct).Dispose(), ну а каст структуры к интерфейсу, как известно, приводит к упаковке.
<p>Вот те на, подумалось мне. Мало того, что черти дают достаточно невменяемые и не практичные загадки, так еще и ответы у них неверные.
<p>Я добавил <a href="https://habr.com/ru/company/veeam/blog/439478/#comment_19733008">комментарий</a>, после чего началось небольшое обсуждение. Дескать, сам Эрик "уже давно в фейсбуке работает" Липперт <a href="https://stackoverflow.com/a/2413844/250833">писал</a>, что упаковка в блоке using быть должна и компилятор нарушает спеку и все такое... (хотя сегодня это и не так).
<p>Меня смутило две вещи: то, как авторы загадки пытались выкрутиться и найти оправдание своей ошибке. Ну, и главное, что они полезли в дебри, не выяснив, что же в этих дебрях происходит. Да не просто полезли, они этим дебрям еще и учат.
<p>Что в этом плохого?
<p>Структуры в C# имеют две особенности – они являются "значениями", и могут располагаться напрямую в памяти контейнера (в стеке, регистрах и напрямую в других объектах).
<p>Первое говорит о том, что в рантайме структуры по умолчанию копируются и то, что компилятор старается обеспечить семантику значения (т.е. неизменяемость) путем встраивания туда-сюда создание защитных копий (чтобы вызов метода или свойства, например, на неизменяемом поле ни в коем разе значение этого поля не поменял).
<p>Второе же (место жизни структуры) может привести к упаковке т.е. к созданию копии структуры в куче.
<p>Два этих отличия очень важны и в голове они, по-хорошему, должны лежать на разных полочках. Ибо каждый из них достаточно сложен, может меняться и развиваться по мере развития языка, да и проявляются эти особенности по-разному.
<p>Вот, например, семантика значения и защитные копии стали гораздо более распространенной бедой с выходом C# 7x с их модификаторами ‘in’ и возвратом по неизменяемой ссылке (readonly refs) (вот, например, много буков по этому поводу - <a href="https://blogs.msdn.microsoft.com/seteplia/2018/03/07/the-in-modifier-and-the-readonly-structs-in-c/">The ‘in’-modifier and the readonly structs in C#</a>).
<p>А самая большая беда проявляется с изменяемыми структурами, когда скрытая копия «прячет» изменения состояния, поскольку произойти они могут на временной копии. Не столь серьезное последствие заключается в некоторой потери производительности за счет создания копии, что решается путем использования readonly структур.
<p>Упаковка же происходит совсем в других местах, при кастах к объектам/интерфейсам и в более экзотических случаях, типа при вызове методов из System.Object или System.ValueType (когда, например, Equals/GetHashCode не переопределены). А проявляется она путем увеличения давления на сборку мусора, что может аукнуться за счет тормозов сборщика мусора.
<p>Так это я все к чему: учить других – это хорошо. Это просто здорово! Но касаясь всяких закоулков языка и рантайма, хорошо бы понимать, что, да как на самом деле происходит под капотом, да и желательно разбираться, почему происходит все именно так, а не иначе.</p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com9tag:blogger.com,1999:blog-8596733192274108952.post-62041684732118222722018-08-08T07:23:00.002+03:002018-08-08T07:23:11.857+03:00О мотивации<p>Я не могу делать вещи, которые мне не интересны. От слова совсем.
<p>Когда мы с супругой рассматривали вопрос о переезде в Киев, то главной моей проблемой было то, что в крупной компании я не смогу выбирать то, над чем я буду работать. Это меня не просто пугало, это приводило меня в ужас. Плюс, обычные страхи перед новым.
<p>Я часто вижу, что мои коллеги могут пилить практически что угодно. Обсудили на стендапе или при встрече с менеджером и все. Они могут заниматься практически любой самой нудной задачей. Я помню, как мой скип пару лет назад презентовал свой новый проект, который потенциально перечеркивал работу целой команды за последний год. При этом один из моих коллег знал об этой инициативе и все равно усердно продолжал заниматься текущим проектом. Проектом, который вполне мог умереть через несколько недель.
<p>Как и для многих других, меня в общем случае мотивируют три вещи: автономность (autonomy), мастерство (mastery) и цель (purpose). Но они для меня играют разное значение.
<p>Цель для программиста – это не красивый код и не расширябельная архитектура. Это решение некоторой проблемы пользователей. Наличие цели для меня важно, но не сверх критично. Я занимался довольно активно проектами, цели которых были мне не совсем ясны, поскольку я был оторван от конечных пользователей довольно сильно. Аутсорс, видите ли.
<p>Требования к автономности бывают заложены в человеке, а бывает приходят с опытом. Для меня автономность всегда была необходимым условием работы. Если вы говорите, что и как мне делать, то я наверняка скажу, куда вам идти. Всегда интересно понимать, какую проблему мы хотим решить, после чего гораздо легче выбрать наиболее подходящее решение.
<p>Но самым главным для меня всегда было мастерство. Причем мастерство не абстрактное, а практическое. Важно не просто знать определение принципа замещения Лисков и что в общем случае квадрат не стоит наследовать от прямоугольника, но и уметь применять это у себя на проекте.
<p>В теории игр есть понятие взаимодополняющих и взаимоисключающих стимулов. В первом случае усилия, прилагаемые человеком в одном направлении, помогают достижению целей в другом. Например, занятие своим физическим здоровьем помогает в развитии умственных способностей. Во втором же случае, усилия в одном направлении мешают достижению других целей. Подковерные игры и пивас с менеджером, например, помогают в карьере, но могут навредить отношениям с коллегами и посадить печень.
<p>Правильная инвестиция собственных усилий легко может дать плоды в разных направлениях.
<p>Возьмем, к примеру, саморазвитие.
<p>Изучение чего-то нового само по себе может быть не сверх интересным занятием и приводить к малому выбросу допамина. Но ведь можно изучить что-то, сваять пост в интернетах, выстуть с докладом на митапе/конференции, обсудить проблему с коллегами и, в конце концов, применить знания у себя на проекте. В этом случае потраченное время хорошо окупается и дает эффект с самых разных сторон, приводит к неоднократному «вознаграждению» и, главное, оттачивает твое мастерство.
<p>Это делать не всегда просто, но, как показывает практика, вполне возможно. Достаточно глубокий опыт уважают, и он требуется и ценится на многих проектах, даже в аутсорсах.</p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com4tag:blogger.com,1999:blog-8596733192274108952.post-74812683957771345842018-07-30T08:43:00.002+03:002018-07-30T08:43:44.588+03:00Эффект плато<p>Время от времени с головой и карьерой начинают твориться довольно страшные вещи: все начинает если не напрягать, то точно приносить меньше удовольствия. Работа не прет. Проекты не прут. Ничего новое не радует и не интересует. Вопрос: почему?
<p>У меня есть некоторые мысли по этому поводу.
<p>Есть такая штука – допамин. Он вырабатывается, когда вы ожидаете доставки нового ай-фона, «встречи» с любимой/любимым вечером или в момент укуса вкусного мороженого жарким летним днем. Допамин – это сильнейшее штыриво, которое вырабатывается от ожидания чего-то приятного или прямо в момент его наступления.
<p>Когда начинается карьера программиста, то с допамином нет никаких проблем. Ты каждый день узнаешь что-то новое: технологии, процессы, паттерны, практики. Вокруг все новое и моменты «просветления» происходят довольно часто. Возникает чувство, что мозг и опыт развиваются по закону Мура и каждые 18 месяцев количество знаний удваивается.
<p>Тоже самое происходит и с первыми проектами: ощущение «творения» возникает постоянно. Исправил маленькую багу – молодец. Применил новый паттерн – красава. Починил билд – отлично. Задизайнил и довел до ума новую фичу – да вообще тебе цены нет.
<p>Тут появляется социализация и оценка твоих способностей другими. Можно на кухне блеснуть цитатой из Рихтера, помочь дельным советом менее опытному коллеге, да и просто поспорить на технические темы во время стендапа.
<p>С финансами и карьерой тоже идет все хорошо. Подъем зарплаты и новые лычки идут не реже раза в год, а уже через пять лет ты оказываешься на вершине пищевой цепочки с лычкой синьера и опытом посещения нескольких зарубежных курортов.
<p>И потом мир начинает немного меняться.
<p>Ну, с миром-то все нормально. Но твое восприятие становится несколько иным.
<p>Опыт, который рос так стремительно, растет уже не так быстро. Ты, вроде бы, и читаешь что-то постоянно, может даже в опен-сорс контрибьютишь, а может еще и в бложик чего-то пишешь. Но что-то не так. Опять-таки, все так. Но даже линейный рост опыта, добиться которого не так и просто, не дает ощущения постоянного удвоения опыта. Да и расширение кругозора лишь дает понять, как мало на самом деле ты знаешь.
<p>Это же происходит с карьерой и ощущением от завершенных задач. Выше «синьера» прыгать сложно, да и не ясно, куда именно. А с задачами вообще беда получается: все одно и тоже, формошлепство, дата-сайенс, веб, базы данных. Декораторы, синглтоны и фабрики. И дурацкие обсуждение того, чем монады хороши, и почему ООП уже не торт.
<p>Так что же происходит?
<p>Да, ничего. Просто многое из того, что штырило раньше было частью «внешней» мотивации. Допаминчик вырабатывался в ожидании того, что тебя похвалит кто-то другой, что ты блеснешь своими знаниями перед коллегой, и что после закрытия неуловимого бага, тим-лид хлопнет по спине, и скажет, что ты крут.
<p>Сложно учить что-то новое в течении двух месяцев, только ради того, чтобы было о чем поговорить за чашкой кофе с коллегами. Многовато работы для однократного выброса допамина.
<p>Новые задачи и даже новая ответственность тоже может приносить меньше радости. Ощущений от починенного первого бага может быть больше, чем от двух месяцев работы, когда твоя главная задача была заархитектурить что-то. Можно и нужно ценить результат командной работы, но это не просто сделать.
<p>Есть несколько способов смягчения этой проблемы.
<p><b>Во-первых</b>, нужно понять, что подобная ситуация является нормальной. Эффект новизны играет важную роль в выработке допамина и придется либо смириться с его уменьшением или постоянно делать что-то хоть немного новое: в своей области, смежной или в чем-то совершенно новом.
<p><b>Во-вторых</b>, можно сменить обстановку таким образом, чтобы внешние стимулы продолжали толкать тебя вперед. Например, карьерная лестница в крупной продуктовой компании может быть существенно длиннее и «путешествие» по ней может быть одним из таких стимулов. Радость познания и общения можно усилить за счет менторства, блогания или за счет выступления на митапах/конференциях.
<p><b>В-третьих</b>, можно прислушаться к себе и понять, что же может толкать тебя изнутри. Если нравится больше кодить, то может стоит забить на свои глупые тим-лидские амбиции и заняться архитектурой или стать «просто разработчиком»? А может тебе просто нравиться изучать что-то новое, так может стоит продолжать это делать, даже если это никак не поможет твоей карьере?
<p>А может стоит вообще уделить больше времени своему хобби и таки научиться рисовать, готовить или танцевать. Может увлечение психологией и не нужно тебе сейчас, но эти знания могут вполне пригодиться через пару лет в работе, если судьба занесет в менеджерские ряды.
<p>Все это я к чему? Если плато не угрожает карьере, то вполне нормально переключаться и искать себя в чем-то другом. Искусственное толкание себя вперед может привести к выгоранию, а вот временное переключение на что-то другое вполне может освежить мозги и вернуть радость от работы и жизни.</p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com21tag:blogger.com,1999:blog-8596733192274108952.post-80756138721134970102018-07-04T09:05:00.000+03:002018-07-04T09:11:08.833+03:00Сдвиг массива влево на N элементов<div dir="ltr" style="text-align: left;" trbidi="on">
Есть ряд способов сдвинуть массив влево на N элементов. Можно взять и сделать N сдвигов по одному элементу, получив квадратичную сложность. Можно создать целевой массив по размеру исходного и вычислить положение каждого элемента после сдвига. Хорошо, но скорость линейна, затраты по памяти - тоже.
<br />
Если чутка подумать, то можно придумать реализацию, которая мутирует массив и дает линейную скорость и константные затраты по памяти. Но есть один очень элегантный способ – из 3-х строк на основе чудо Span of T<t> из System.Memory:</t><br />
<pre style="background: #1e1e1e;"><span style="font-family: "consolas";"><span style="color: #569cd6;"><span style="font-size: 10pt;">public</span></span><span style="font-size: 10pt;"><span style="color: gainsboro;"> </span><span style="color: #569cd6;">static</span><span style="color: gainsboro;"> </span><span style="color: #569cd6;">void</span><span style="color: gainsboro;"> RotateLeft(</span><span style="color: #569cd6;">int</span><span style="color: gainsboro;">[] input, </span><span style="color: #569cd6;">int</span></span></span><span style="font-size: 10pt;"><span style="font-family: "consolas";"><span style="color: gainsboro;"> direction)
{
input</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">AsSpan(</span><span style="color: #b5cea8;">0</span><span style="color: gainsboro;">, direction)</span><span style="color: #b4b4b4;">.</span></span><span style="font-family: "consolas";"><span style="color: gainsboro;">Reverse();
input</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">AsSpan(direction)</span><span style="color: #b4b4b4;">.</span></span></span><span style="font-family: "consolas";"><span style="font-size: 10pt;"><span style="color: gainsboro;">Reverse();
input</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">AsSpan()</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">Reverse();
}</span></span></span></pre>
Идея такая: чтобы сдвинуть массив из K элементов на N элементов влево, нужно перевернуть первые N элементов в массиве, затем последние K - N -1 элементов, а затем перевернуть весь массив:<br />
<pre style="background: #1e1e1e;"><span style="font-family: "consolas";"><span style="color: #57a64a;"><span style="font-size: 10pt;">// direction == 2, input.Length == 7</span></span><span style="font-size: 10pt;">
<span style="color: gainsboro;">input</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">AsSpan(</span><span style="color: #b5cea8;">0</span><span style="color: gainsboro;">, direction)</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">Reverse();</span>
<span style="color: #57a64a;">// [2][1][3][4][5][6][7]</span>
<span style="color: gainsboro;">input</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">AsSpan(direction)</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">Reverse();</span>
<span style="color: #57a64a;">// [2][1][7][6][5][4][3]</span>
<span style="color: gainsboro;">input</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">AsSpan()</span><span style="color: #b4b4b4;">.</span><span style="color: gainsboro;">Reverse();</span></span><span style="color: #57a64a; font-size: 10pt;">// [3][4][5][6][7][1][2]</span></span></pre>
<br />
Получается два прохода по массиву, но зато с читабельностью решения все очень ОК.</div>
Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com26tag:blogger.com,1999:blog-8596733192274108952.post-23855339543709778762018-07-03T08:39:00.002+03:002018-07-03T08:39:19.404+03:00Welcome, так сказать, back:)<p>Мне вот тут подумалось, что блоггинга мне не хватает. Причем не очень хочется писать чего-то длинное и сильно умное. Для этого, у меня теперь <a href="http://blogs.msdn.microsoft.com/seteplia/">на английском блог</a> есть. Хочется чего-то простого и легковесного, типа журнала живого. Вроде бы есть всякие Г+ и фейсбуки, но их формат мне все равно не нравится. Если захочешь чего-нить своего потом найти там, заморишься.</p>
<p>Так что я решил восстановить блог, но в формате, о чем пишется, о том и буду писать. В основном о технологиях, о книжках читаемых и мыслях при этом в голову приходящих.</p>
<p>Вот и сейчас просто хочется поделиться загадкой, которую вчера <a href="http://gurmeet.net/puzzles/fox-in-a-hole/index.html">решал</a>:</p>
<p>Есть пять нор, расположенных в ряд. В одной из них сидит лиса. Каждую ночь лиса перебирается в соседнюю норму слева или справа. Каждое утро вы можете проверить одну нору на выбор. Какая должна быть стратегия проверки нор, чтобы в конечном итоге лиса была поймана?</p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com21tag:blogger.com,1999:blog-8596733192274108952.post-49077077468012489012017-10-20T04:55:00.001+03:002017-10-20T04:57:09.167+03:00Анонс конференции DotNext 2017 Moscow<p>Пришло время очередной конференции <a href="https://dotnext-moscow.ru/">DotNext Moscow</a> и организаторы предложили их поддержать, на что я с радостью согласился. Итак, промокод <b>TeplyakovPromo</b> дает скидку в 10%.</p><p>Сам я не смогу ни выступить, ни послушать выступления вживую, но буду очень рад поделиться своим мнением по поводу предстоящих выступлений. Ниже представлены выступления, на которые я бы пошел, будь у меня такая возможность, и которые я буду ожидать для просмотра в офф-лайне.<h3>День 1</h3><p><strong>1. Андрей Акиньшин – </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/6a4afxs2sqmwws0yuoc06s/"><strong>Поговорим про performance-тестирование</strong></a><p><a href="https://twitter.com/andrey_akinshin">Андрей</a> – один из авторов популярной микро-бенчмарк фреймворка <a href="https://github.com/dotnet/BenchmarkDotNet">BenchmarkDotNet</a>, который в этом году (если не ошибаюсь) присоединился к .NET Foundation и является маст-хев тулом для всех любителей пооптимизячить.<p>Тема перф-тестирования, на самом деле, очень интересна и весьма слабо покрыта в тырнетах. Я не знаю, о чем будет говорить Андрей, но я бы выделил несколько аспектов:<p>· Бенчмаркинг<p>· Автоматизированное тестирование потребления памяти определенным куском кода<p>· Автоматизированная валидация производительности путем запуска интеграционных тестов и сбора телеметрии<p>В моем текущем проекте, например, весьма серьезное внимание уделено последнему пункту, когда система прогоняется на тестовом сервере с разными сценариями, а анализ ведется путем анализа телеметрии.<p><strong>2. Сергей Быков – </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/3oijz3tvmqm4euicyia2yw/"><strong>Назад в будущее: построение эффективных облачных сервисов с помощью Orleans</strong></a><p>Сергей – автор <a href="https://github.com/dotnet/orleans">Orleans</a>, очень популярного фреймворка для построение распределенных приложений на основе модели акторов. Сам я таким не занимаюсь, но точно бы не упустил шанс послушать этот доклад.<p><strong>3. Дино Эспозито – </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/4nzkhrbjcqqsiuwwcmamga/"><strong>I have a microservices architecture and I didn’t know</strong></a><p>Опять-таки, тема не моя, но Дино – это очень именитый спикер, и тема весьма наболевшая. <p><strong>4. Марк «Я могу и ФП, и ООП» Сииман – </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/20wwzs2qeuuykg86cc6ams/"><strong>From dependency injection to dependency rejection</strong></a><p>Этот доклад я бы ни за что не пропустил. Макр – известный спикер, автор книги <a href="https://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/dp/1935182501">“Dependency Injection in .NET”</a>, а ныне активный участник F# Community. Это значит, что Марк понимает, как ОО, так и ФП миры, что позволяет ему выбирать лучшее из двух и вдумчиво объединять эти парадигмы (ИМХО, лучший подход из всех возможных – ОО-компонентизация и «слоеность» + ФП реализация компонентов).<p><strong>5. Raffaele Rialdi - </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/1zii5rwvmmokc0wiigqaw8/"><strong>Runtime code generation techniques in real life scenarios</strong></a><p>Тема генерации кода во время исполнении мне близка и я ею достаточно часто пользуюсь в работе. Одним из таких примеров является оптимизация фабричного метода по созданию объектов, описанная в посте <a href="https://blogs.msdn.microsoft.com/seteplia/2017/02/01/dissecting-the-new-constraint-in-c-a-perfect-example-of-a-leaky-abstraction/">Dissecting the new() constraint in C#: a perfect example of a leaky abstraction</a>. Даже в моей практике набралось с десяток примеров, и я бы с радостью послушал об опыте других.<p><strong>6. Karel Zikmund – </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/3hcuoycrw4egcs0mkewoio/"><strong>High Performance Networking in .NET Core</strong></a><p>Однозначный маст-визит для всех, кто интересуется разработкой высокопроизводительных приложений в .NET. Karel работает в команде .NET Core и хорошо знает, о чем будет говорить. Сейчас идет серьезный пуш в сторону low-allocations и в целом high-performance для всего сетевого стека и других ключевых компонент.NET.<p>Я бы сказал, что на этот доклад нужно идти, даже если вы не интересуетесь high-load и всем таким, просто, чтобы посмотреть, как делается история. Все же не каждый год крупные компании решаются на серьезный редизайн core-компонентов.<h3>День 2</h3><p><strong>1. Егор Бугаенко – </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/3ehxgjdfiiws4kkygqa4qc/"><strong>TDD вверх ногами</strong></a><p>Как вы, наверное, знаете, у меня весьма однозначное отношение к тестированию и весьма неоднозначное отношение к TDD. А тут такой повод! <a href="https://twitter.com/yegor256">Егор</a> – весьма интересный спикер, который отличается несколько необычными взглядами на общепринятые вещи. Я не знаю (вру, <a href="http://www.yegor256.com/2017/03/24/tdd-that-works.html">знаю</a>), что будет на выступлении, но интересная точка зрения автора и интересный доклад гарантирован.<p><strong>2. Вагиф Абилов – </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/3n90v5rogcu2cyq4s4awuc/"><strong>Akka Streams для простых смертных</strong></a><p>Как я уже писал, я не занимаюсь распределенными системами, но тема акторов мне достаточно интересна, чтобы посетить доклад Вагифа.<p><strong>3. Валерий Петров – </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/3g9dliup84imoeeyukce0w/"><strong>Модель памяти в .NET</strong></a><p>Модель памяти – это достаточно мутная, вывихивающая мозг концепция, готовить правильно которую могут с десяток человек на планете. Но это не значит, что вам не нужно знать, что это такое.<p>Ну а если эта тема не интересна, то есть смысл обратить внимание на доклад Володи Кочеткова <a href="https://dotnext-moscow.ru/2017/msk/talks/7alwdnxp0kayquoukwmky8/">Побеждая инъекции</a>. <p><strong>4. Денис Иванов - </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/39r6jbkc1iokuy8mmmqggy/"><strong>Apache Kafka и рективные микросервисы на .NET Core</strong></a><p>Денис смог собрать кучку buzzword-ов в теме доклада, но я бы пошел на него ради того, чтобы послушать о реальном использовании .NET Core в продакшне. <p><strong>5. Виталий Езепчук – </strong><a href="https://dotnext-moscow.ru/2017/msk/talks/2une17wri88koasqqwgyek/"><strong>Поединок: .NET Core против Java</strong></a><p>Идея доклада – огонь: сравнить два популярных ран-тайма. Я понятия не имею, как можно провести честное сравнение, когда у этих двух сред столь разная история, и столь разный набор плюсов и минусов. Java славится значительно бОльшим числом различных оптимизаций в ран-тайме, в то время, как в CLR есть поддержка обобщений и значимые типы. К сожалению, я могу предположить результат сравнения, но последить за таким поединком не отказался бы. <p>Ну вот и все. Программа оказалась не просто годной, а, прямо-таки, очень хорошей. Я нашел интересную тему в каждом временном слоте, а иногда пришлось хорошенько подумать, чтобы выбрать наилучший вариант!<p>Организаторам – респект, а вам – отличной конференции!Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com10tag:blogger.com,1999:blog-8596733192274108952.post-39847876278324374962017-09-06T08:01:00.001+03:002017-09-06T08:01:43.711+03:00Структура управляемого объекта. Части 1 и 2<p>Что-то я забросил публикацию аннонсов своего англоязычного блога, что не хорошо. Исправляюсь. <p>Так вот, меня всегда интересовали несколько моментов с точки зрения структуры (layout) объекта: почему управляемый указатель указывает в середину объекта? Почему object header хранится по негативному индексу и что же именно может храниться в заголовке объекта? <p>На первый вопрос ответ дается в первом посте: <a href="https://blogs.msdn.microsoft.com/seteplia/2017/05/26/managed-object-internals-part-1-layout/">Managed Object Internals, Part 1</a>. Спойлеры: причина историческая, хотя есть и определенные сведения о том, что причины были связаны с эффективностью. <p>Во втором посте – <a href="https://blogs.msdn.microsoft.com/seteplia/2017/09/06/managed-object-internals-part-2-object-header-layout-and-the-cost-of-locking/">Managed Object Internals, Part 2. Object header layout and the cost of locking</a> в деталях рассматривается структура object header-а, а также концепция thin lock-ов. Интересно, что thin lock-и мало где описаны и о них мало кто знает. Thin lock – это более оптимальная реализация блокировок, добавленная в CLR 2.0, которая позволяет синхронизироваться на объекте с нулевыми (практически) накладными расходами за счет сохранения информации о блокировки внутри object header-а.</p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com2tag:blogger.com,1999:blog-8596733192274108952.post-57674077857150985152017-08-24T03:56:00.001+03:002017-08-24T03:58:55.767+03:00О книге Ф. Друкера «Эффективный руководитель»<p align="justify">Неспособность сконцентрироваться на чем-то более вменяемом, привели меня к чтения очередной около менеджерской книги. На этот раз, книги <a href="https://www.ozon.ru/context/detail/id/25588139/">«Эффективный руководитель»</a> Друкера.<p align="justify"><a href="https://lh3.googleusercontent.com/-FltedTAEC6Y/WZ4ky6w3RnI/AAAAAAAARuU/RRzk_T2DAoMm0fy6vejanqrUFyplFqTMwCHMYCw/s1600-h/Image"><img width="333" height="480" title="Друкер" align="left" style="border: 0px currentcolor; border-image: none; float: left; display: inline; background-image: none;" alt="Друкер" src="https://lh3.googleusercontent.com/-n34w8sYXVEk/WZ4kzrxHAuI/AAAAAAAARuY/1OcyBKBS-_0zv_r9gll5EWncaHGlBmnKQCHMYCw/Image?imgmax=800" border="0"><br></a><p align="justify">Выбор пал на нее благодаря интересным отзывам, найденым в сети. Судя по ним, книга – огонь, цитат – больше, чем в книге Буча <a href="http://sergeyteplyakov.blogspot.com/2009/09/blog-post_15.html">по дизайну и ООП</a>, мудрости – хватит на три жизни и все такое. Вот, думаю, оно!<p align="justify">Но, как это часто бывает, что-то пошло не так.<p align="justify">Ну, для начала, первое издание книги написано 50 лет назад. Что само по себе ничего не значит. <a href="http://sergeyteplyakov.blogspot.com/2009/02/blog-post.html">Дядюшка Брукс</a> поведал нам о своей истории 42 года назад, и ничего, помимо некоторых технических архаизмов, книга сегодня заходит просто на ура.<p align="justify">ЦИТАТА: <i>Еесли и существует какой-нибудь главный секрет эффективности, то это концентрация.</i><p align="justify">У Друкера архаизмы проявляются в нескольких вещах. Многие примеры идут из 60-х, что неплохо, само по себе. Но часто отсылки идут к истокам и решениям, принятым в 20-х годах, в таких компаниях как Bell Telephone System или General Motors с последующим анализом их влияния на современность. А вот современность по меркам книги – это и есть те самые 60-е. Нет ничего плохого в анализе действий Макнамары, Эйзенхауэра или Кеннеди, но мне их сложно анализировать, поскольку я недостаточно хорошо знаю то время. Моя «современность» начинается несколько позже. Значительно позже.<p align="justify">Особенно повеселило описание компьютеров и анализ их влияния в будущем на работу руководителейJ. Подобные отсылки к прошлому не являются сами по себе чем-то плохим. Просто эти примеры сложно сегодня совместить с реальными событиями и с действиями современного руководителя.<p align="justify">Но самая главная проблема книги, ИМХО, это количество пространных рассуждений.<p align="justify"><i>Сегодня потребность общества в эффективных руководителях еще заметнее. Сплоченность и надежность все больше зависят от комбинации психологических и социальных потребностей работника умственного труда с целями организации и всего индустрального общества. Обычно работник умственного труда не составляет экономмической проблемы. Чаще всего он хорошо обеспечен, что дает ему уверенность в себе, а знания обеспечивают его способностью к мобильности. Но его психологические потребности и личная ценностная ориентация могут удовлетворяться только работой и положением в соответствущей организации. Он считается – и сам себя считает – профессионалом. При этом он наемный работник, который выполняет приказы свыше. Он действует в сфере умственного труда, но направляет свои знания и возможности на достижение целей организации.</i><p align="justify">О`Кей. Согласен со всем. Но, ..., я как-то не понял, что автор хотел этим сказатьJ. Конечно, это не совсем честно, выдирать цитату из завершающей части книги и с ее помощью обвинять автора в многословности. Тут и перевод мог добавить сложности, да и мои способности восприятия мудрости могли быть не на высоте.<p align="justify">Но этой цитатой я старался показать проблему книги: в ней много размышлений, часть из которых носят весьма общий характер. Возможно, если читатель совсем уж в теме (правда, хз, в какой), то все сразу становится на свои места. Но если нет, то как-то становится сложно увидеть цельную картину. За сложными предложениями и длинными абзацами мне было тяжело вычленить суть. Соотнести это с моим опытом, понять, что мне следуюет или не следует делать.<p align="justify">Что грустно, поскольку хороших-то мыслей в книге достаточно.<p align="justify">ЦИТАТА: <i>Руководитель, подбирающий в организацию людей без недостатков, в лучшем случае наберет посредственный персонал.</i><p align="justify">Вот, как раз хороший пример, связанный с подбором персонала.<p align="justify">ЦИТАТА: <i>Эффективно работающие руководители знают, что их подчиненным платят за выполнение работы, а не за то, чтобы они радовали своих начальников.</i><p align="justify">Но ведь хорошо!<p align="justify">ЦИТАТА: <i>Эффективные руководители редко питают иллюзии относительно того, что две посредственности добьются такого же результата, как один блестящий работник. Им известно, что, как правило, двое посредственных работников работают даже хуже, чем один хороший, так как они просто мешают друг другу.</i><p align="justify">Во многих обзорах книги делается акцент на методиках эффективности, приводимых в книге, но мне лично реально понравилась лишь четвертая глава, из которой я тут наглым образом дергаю цитаты. В ней говорится о развитии сильных сторон – себя самого, своих подчиненных и своего руководителя, а также о подборе людей. Но даже в этой главе, как по мне, воды много, и нужно хорошо поработать, чтобы из нее намыть горсточку самородков.<p align="justify">ЦИТАТА: <i>Подбирая кадры, нужно обращать внимание на сильные стороны сотрудника в какой-либо одной области, а не на посредственные навыки во многих сферах.</i><p align="justify">В книге есть хорошие темы, но подача материала мне не подошла. Мне сложно читать столько воды, столько рассуждений, каждый раз заставляя себя вдумываться в каждое предложение, стараясь не упустить мысль. Часто бывает, что после прочтения 3-х или 4-х страниц ты осознаешь, что только что прочитал лишь первый пункт некоторой вселенской мудрости, полностью забыв, о чем в целом идет речь. <p align="justify">В результате, вместо чтения книги, я бы рекомендовал погуглить десяток обзоров и кратких выжимок из книги, по которым легко можно почерпнуть все нужное, серьезно сэкономив свое время. А если отрывки действительно зацепят, то только после этого брать книгу, набираться мудрости путем терпеливого ее чтения.Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com3tag:blogger.com,1999:blog-8596733192274108952.post-12452016976315497502017-08-14T19:01:00.001+03:002017-08-14T19:01:23.274+03:00О книге Джона Сонмеза “The Complete Software Developer’s Career Guide”<p align="justify">Если честно, у меня не совсем однозначное отношение к автору книги – Джону Сонмезу (John Sonmez). Это довольно известный парень, автор пары книг, 55 курсов на Pluralsight (о чем он напоминает не менее 10 раз в своей последней книге), автор блога <a href="https://simpleprogrammer.com/">SimpleProgrammer.com</a> и ютюб канала Simple Programmer. Он «вышел на пенсию» в 32 и «отдыхает» в свое удовольствие, работая на себя часов по 8 в день.<p align="justify">Неоднозначность автора напрямую связана с его сильными сторонами. Джон весьма хорош в продажах, уверенный в себе, в прекрасной физической форме, острый на словцо и все такое. Такой себе задрот-пикапер, добившийся успеха во всех аспектах жизни. <p align="justify">Основное направление его бизнеса – это консультации программистов по развитию софт-скиллов. И у него самого с этими скиллами все в полном порядке. Иногда, он вдохновляет, но иногда порядком раздражает своими «я смог, значит каждый сможет» и «ну, я об этом писал в этом посте, идите там посмотрите».<p align="justify">Теперь к книге.<p align="justify">По словам автора, книга <a href="https://www.amazon.com/Complete-Software-Developers-Career-Guide/dp/0999081411/ref=sr_1_1?ie=UTF8&qid=1502725692&sr=8-1&keywords=john+sonmez">“The Complete Software Developer’s Career Guide”</a> покрывает все аспекты карьеры программиста: начиная от обучения и поиска работы, заканчивая продвижением по службе и началом своего дела.<p align="justify">Это действительно так, и книга, действительно, будет полезна многим разработчикам, особенно тем, кто хочет познакомиться с особенностями работы в Штатах.<p align="justify"><b>Поиск работы. </b>Очевидно, что для разработчиков с разным уровнем некоторые знания будут неактуальны. Если вы уже давно работаете, то вопросы выбора колледжа или код-кампа будут, интернатуры, поиска первой работы и т.п. будут не актуальными. Хотя если у вас есть детки, то, вполне возможно, эти сведения будут не бесполезными. <p align="justify">С другой стороны, автор покрывает и такие моменты, как контрактор vs. эмплой. Что может быть полезно нашим новоприбывшим в Штаты людям.<p align="justify">Джон также дает советы по переговорам с HR-ами и явно советует не раскрывать карты о своей текущей зарплате и даже не называть свои ожидания. Дескать, кто говорит первым, тот оказывается в менее выгодном положении.<p align="justify">Еще, автор, дает вменяемый совет о последовательном подходе к обучению, что, опять же, будет полезно каждому. Например, при обучении чему-то новому следовать такому подходу:<p align="justify">· Обзор чего-то нового, чтобы понять, что можно решить с помощью этого.<p align="justify">· Понять, как начать это что-то использовать.<p align="justify">· Узнать 20% этого нового, чтобы покрыть 80% юз-кейсов.<p align="justify"><b>Обзор мира разработки ПО.</b> Раздел мало полезный для профессионального разработчика.<p align="justify"><b>Работа в коллективе и продвижение по службе. </b>Здесь уже начинаются вещи, полезные даже зрелым разработчикам, но, со спецификой американского рынка.<p align="justify">Я обратил внимание, что корпоративные культуры, промоушены и другие вещи, связанные с карьерой, сильно отличаются «здесь» и «там». Если в Киеве сидение на месте уже является достаточным основанием для повышения зарплаты, то в больших конторах в Штатах это не так.<p align="justify">Советы Джона будут очень полезны нашему брату, который приехал недавно или который лишь собирается приехать.<p align="justify">Например, следует в начале ревью периода вполне вменяемым образом сформировать цель на год и делать постоянные чек-поинты с возможностью коррекции курса. Это не гарантирует результат, особенно, если чек-поинты и соглашения являются устными. Но если менеджер не сильно против твоего продвижения, то явный, даже вербальный контракт, вполне может в этом деле помочь.<p align="justify">Очень понравилась мысль о любимом местном понятии “work/life balance”. Джон советует не противопоставлять эти два понятия, а сделать работу неотъемлемой и приятной частью своей жизни. Да, идеальная работа бывает лишь в сказках, но в наших с вами силах сделать ее разумно-приятной.<p align="justify">Я уже несколько раз замечал, что в нормальном коллективе тебе вполне под силу выбрать работу, которая хотя бы более или менее тебе по душе. Или же подтянуть определенные скиллы/технологии и предложить что-то новое, опять же, более приятное тебе лично. Тебе не дадут рисовать котиков и решать интегралы, но ты вполне можешь перетянуть на себя задачи по автоматизации чего-нибудь или другие полезные для команды задачи, которые тебе по душе.<p align="justify">Найти баланс между полезным и интересным можно. Он не будет идеальным, но работа при этом будет скорее радовать, чем откровенно напрягать.<p align="justify"><b>Собственный бренд и саморазвитие.</b><p align="justify">И тут Остапа понесло. <p align="justify">Саморазвитие, самопродвижение, само-пиар. Все это темы близкие Джону до глубины души. Джон знает и любит это дело. И ключевым аспектом развития как себя, так и своего бренда, считает блоггинг. И тут я с автором полностью согласен.<p align="justify">Блоггинг позволяет прокачать коммуникационные скиллы, будет стимулировать процесс изучения нового и дисцилляции старых знаний. Ну и конечно, блоггинг может помочь в карьере. Даже если у вас не выйдет начать свой бизнес, как начал автор книги, то вполне возможно, блог может помочь в вашем будущем трудоустройстве, как это произошло в моем случае.<p align="justify">Для меня блоггинг также является осью саморазвития и основой сети общения.<p align="justify">Помимо блоггинга, автор рассматривает и другие моменты: менторинг, публичные выступления, домашние проекты, чтение книг и статей.<p align="justify">И в этом случае, автор дает понять о важности двух вещей: наличие плана и последовательного его исполнения. Первое помогает понять, что куда нам нужно идти, и какие ключевые вещи использовать, а упрямство и последовательность позволят довести дело до конца.<p align="justify">Саморазвитие – это процесс, причем бесконечный. И тут важно настроить себя на то, что быстрых результатов не будет, да и вообще понять, что результат (карьера и финансы) являются лишь побочным результатом этого процесса. <p align="justify"><b>Сомнительные моменты.</b><p align="justify">Как и любая другая книга, книга Джона не идеальна. Есть некоторые моменты, с которыми сложно согласиться. Например, Джон тратит десяток-два страниц убеждая в важности одежды. Дескать, нужно одеваться на два уровня выше своей текущей позиции. Но у меня, например, бос моего боса моего боса ходит в шортах (это Brian Hurry) и ничего. Я совсем не чувствую, что одеваясь в костюм ты произведешь лучшее впечатление.<p align="justify">Еще автор советует, очень советует, найти профессионального писателя резюме. Ну, сомнительно это для меня.<p align="justify">Да и водички с повторениями тоже прилично.<p align="justify"><b>Главный вывод/мотив книги</b>.<p align="justify">В книге много полезных мыслей советов, но ключево, имхо один: <b>будьте последовательными</b>. Нет, не так. <b>Набросайте план и последовательно идите к его выполнению</b>. План не должен быть точным. Над ним не нужно неделю работать.<p align="justify">И не рассчитывай на быстрый результат. Его не будет. Не будет быстрого продвижения по службе. Не будет сразу же восторженных комментариев к вновь созданному блогу. Даже посетителей толком не будет. Ничего. Это нормально.<p align="justify">Наберитесь терпения. Пусть сам процесс доставляет удовольствие и результат придет.<p align="justify">Вердикт: <b>чтиво</b>.</p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com6tag:blogger.com,1999:blog-8596733192274108952.post-53172546563870948212017-02-21T17:54:00.001+02:002017-02-21T17:55:20.427+02:00Оптимизация типового пути исполнения<p>Роясь недавно в исходниках TPL Dataflow я заметил некоторый паттерн: многие функции разбиты на две. Основная называется обычным образом, <b>AddElement</b> или что-то в этом роде, а вторая – <b>AddElement</b><b>_Slow</b>. <p>При этом мне очень понравилась причина, по которой это дело делалось: эта оптимизация позволяет заинлайнить метод в типовом кейсе. Казалось бы, а есть ли в этом толк? И, как оказалось, что есть (я бы удивился, если бы камрад Тауб решил бы использовать подобную оптимизацию не проверив, что она имеет смысл). <p>В результате, если вы пишите библиотеку или работаете над очень горячим куском вашего приложения, то такой подход вполне оправдан: если метод имеет типовой быстрый и нетиповой медленный пути исполнения, то второй кейс разумно выделить в отдельный метод, что сделает основной метод более пригодным для инлайна. <p>Ну, и подробности, у меня в англоязычном посте: <a href="https://blogs.msdn.microsoft.com/seteplia/2017/02/21/a-common-execution-path-optimization/">“A common execution path optimization”</a>.</p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com12tag:blogger.com,1999:blog-8596733192274108952.post-13486491770300407182017-02-07T07:59:00.001+02:002017-02-07T08:01:34.640+02:00О «маркировке» объекта во время сборки мусора или Рихтер был не прав<p align="justify">Сегодня речь пойдет о бесполезной, с практической точки зрения, информации о внутренностях CLR и сборщика мусора. <p align="justify">Многие из нас изучали внутренности .NET и CLR по книге Джеффри Рихтера “CLR via C#”. Книга просто замечательной, глубокая, детальная и очень точная. Но, как это обычно бывает, даже Рихтер иногда ошибается (пусть и в деталях). <p align="justify">Вот цитата: <p align="justify"><i>When the CLR starts a GC, the CLR first suspends all threads in the process. This prevents threads from accessing objects and changing their state while the CLR examines them. Then, the CLR performs what is called the marking phase of the GC. <b>First, it walks through all the objects in the heap setting a bit (contained in the sync block index field) to 0</b>. This indicates that all objects should be deleted. Then, the CLR looks at all active roots to see which objects they refer to. This is what makes the CLR’s GC a reference tracking GC. If a root contains null, the CLR ignores the root and moves on to examine the next root.</i> <p align="justify"><i>Any root referring to an object on the heap causes the CLR to mark that object. <b>Marking an object means that the CLR sets the bit in the object’s sync block index to 1.</b> When an object is marked, the CLR examines the roots inside that object and marks the objects they refer to. If the CLR is about to mark an already-marked object, then it does not examine the object’s fields again. This prevents an infinite loop from occurring in the case where you have a circular reference.</i> <p align="justify">И что же здесь не так?</p> </p></p></p></p></p><a href="http://sergeyteplyakov.blogspot.com/2017/02/marking-phase-implementation-details.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com23tag:blogger.com,1999:blog-8596733192274108952.post-28770096447996234072017-02-03T07:26:00.001+02:002017-02-03T07:27:40.692+02:00О “вреде” книг: напутствие любому программисту<p align="justify">Недавно наткнулся на любопытную статью под названием <a href="http://blogerator.org/page/knigi-sovety-nachinajushhemu-programmistu-ucheba-obrazovanie-it">«О вреде книг: напутствие начинающему программисту»</a>. Идея в статье простая: книги – это скорее опасно, и лучше практика с пополнением теории по ходу дела, да и образование современное – ни к черту.</p> <p align="justify">Мне сложно судить о современном программистском образовании в России/Украине (эта тема также поднимается в статье). У меня самого нет специализированного образования (я по образованию «специалист» в области систем автоматизированного управления), да и с момента получения оного прошло уже довольно много времени (19 лет с момента поступления в университет). Но мне явно есть что сказать по поводу самообразования и использования книг в этом процессе. <p align="justify">Как и любым инструментом, книгами нужно пользоваться правильно. И дело тут не столько в книгах, сколько способностях мозга усваивать новую информацию и в подходах, которые помогут сделать этот процесс наиболее эффективным.</p> </p><a href="http://sergeyteplyakov.blogspot.com/2017/02/reading-books-considered-harmful.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com14tag:blogger.com,1999:blog-8596733192274108952.post-63371025149237405202017-02-01T08:19:00.001+02:002017-02-01T08:20:25.322+02:00Исследуем new() ограничение в C#<p align="justify">В предыдущей заметке я спросил у многоуважаемой аудитории, что мне делать с англоязычными постами. Мнения разделились: часть аудитории согласились с публикацией здесь лишь анонсов, а другая часть посоветовала переводить. Я, правда, хотел бы переводить, но не уверен, что у меня хватит запала.</p> <p align="justify">Поэтому я решил, что вместо перевода или простых ссылок, я буду делать здесь довольно развернутые анонсы, с превьюхой англоязычного поста. Так что эти публикации можно будет рассматривать в виде таких себе «трейлеров», да и обсуждать здесь на великом и могучем. <p align="justify">Ну а теперь, к теме сегодняшней публикации. <p align="justify">Я уже несколько раз затрагивал вопрос реализации одной довольно простой возможности языка C# - ограничения обобщений <b>new</b><b>()</b>, что она, дескать, реализована через <b>Activator</b><b>.CreateInstance</b> (да и то, не всегда;), подробности – в оригинале!). <p align="justify">Проблем у этого аспекта аж две (что и делает <b>new</b><b>()</b> ограничение выдающейся дырявой абстракцией): низкая производительность и хитрость с обработкой исключений. <p align="justify">Так вот, у нас на проекте, активное использование <b>new</b><b> T</b><b>()</b> весьма быстро вылезло в профилировщике, было починено с весьма заметным приростом end-to-end времени исполнения. Там мы прикрутили простое решение на основе деревьев выражения и про это забыли. <p align="justify">А не так давно на <a href="https://ru.stackoverflow.com/questions/607803/%D0%9A%D0%BE%D0%B3%D0%B4%D0%B0-%D0%BC%D0%BE%D0%B6%D0%B5%D1%82-%D0%BF%D1%80%D0%B8%D0%B3%D0%BE%D0%B4%D0%B8%D1%82%D1%81%D1%8F-%D0%BF%D1%80%D0%BE%D1%81%D1%82%D1%80%D0%B0%D0%BD%D1%81%D1%82%D0%B2%D0%BE-%D0%B8%D0%BC%D0%B5%D0%BD-system-reflection-emit/608238#608238">ru.stackoverflow.com</a> был задан вопрос по поводу кодогенерации и примеров ее применения, что дало дополнительную почву для размышлений на эту же тему. В результате были перекопаны следующие вещи, чтобы добиться эффективности кастомного активатора равных вызову делегата вида <b>() => </b><b>new</b><b> CustomNode</b><b>()</b>: <ul> <li> <div align="justify">Как именно реализован активатор (с его кэшами, багами в кэше, и довольно необычным способом создания пустого экземпляра).</div></li> <li> <div align="justify">Как именно компилируются деревья выражений и почему получаемый в результате делегат медленнее рукописного.</div></li> <li> <div align="justify">Как скомпилировать выражение в динамический метод руками.</div></li> <li> <div align="justify">Как внутри устроены обобщения и почему для ссылочных типов вызов одного обобщенного метода из другого имеет ненулевые накладные расходы.</div></li></ul> <p align="justify">В результате работы над постом, была получена обобщенная фабрика, эффективность которой равна эффективности делегата, создающего конкретный экземпляр. Что, как мне кажется, весьма интересный результат;) <p align="justify">Понятное дело, что подробности – по ссылке: <a href="https://blogs.msdn.microsoft.com/seteplia/2017/02/01/dissecting-the-new-constraint-in-c-a-perfect-example-of-a-leaky-abstraction/">Dissecting the new() constraint in C#: a perfect example of a leaky abstraction</a>. <p align="justify">З.Ы. Я надеюсь, что читать такое введение интереснее, чем просто увидеть ссылку. <p align="justify">З.Ы.Ы. Пожелания, предложения и все такое, всячески приветствуется. </p>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com11tag:blogger.com,1999:blog-8596733192274108952.post-23048975560798257272017-01-19T08:44:00.001+02:002017-01-19T08:45:17.989+02:00Ретроспектива 2016<p align="justify">Ёлки выброшены (нет, моя – в гараже!), и трудовые выходные перешли в не менее трудовые будни нового года, а значит пришло время подвести итоги года прошедшего. Пусть и с опозданием. <p align="justify">Как известно, 2016-й был непростым годом (четный год таковым быть не может) и по блогу это заметно. За прошлый год можно было заметить следующие тренды: я начал заниматься ErrorProne.NET (правда потом забил), в начале года я допилил Code Contracts и с тех пор только принимал пул рекветы (все еще не знаю, что делать с поддержкой VS 2017), начал блог на английском, ну и написал полтора-два десятка статей на разные темы. <p align="justify">Теперь об этом и другом, более подробно (с)J</p> </p></p><a href="http://sergeyteplyakov.blogspot.com/2017/01/retrospective-2016.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com11tag:blogger.com,1999:blog-8596733192274108952.post-64561128089839964082016-12-19T08:00:00.001+02:002016-12-19T08:01:13.051+02:00Реализация синглтонов в .NET: Field-like vs. Lazy<p align="justify">Недавно один из читателей задал вопрос по поводу разницы между двумя реализациями синглтонов: через обычное статическое поле или же через статическое поле, содержащее <b>Lazy</b><b><T</b><b>></b>: <pre style="font-family: ; background: #1e1e1e; color: ; line-height: normal"><font face="Consolas"><span style="color: "><font color="#569cd6">public</font></span><font color="#dadada"> </font><span style="color: "><font color="#569cd6">class</font></span><font color="#dadada"> </font><span style="color: "><font color="#4ec9b0">FieldLikeSingleton</font></span><br><span style="color: "><font color="#dcdcdc">{</font></span><br><font color="#dadada"> </font><span style="color: "><font color="#57a64a">// Вариант C# 6</font></span><br><font color="#dadada"> </font><span style="color: "><font color="#569cd6">public</font></span><font color="#dadada"> </font><span style="color: "><font color="#569cd6">static</font></span><font color="#dadada"> </font><span style="color: "><font color="#4ec9b0">FieldLikeSingleton</font></span><font color="#dadada"> </font><span style="color: "><font color="#dcdcdc">Instance</font></span><font color="#dadada"> </font><span style="color: "><font color="#dcdcdc">{</font></span><font color="#dadada"> </font><span style="color: "><font color="#569cd6">get</font></span><span style="color: "><font color="#dcdcdc">;</font></span><font color="#dadada"> </font><span style="color: "><font color="#dcdcdc">}</font></span><font color="#dadada"> </font><span style="color: "><font color="#b4b4b4">=</font></span><font color="#dadada"> </font><span style="color: "><font color="#569cd6">new</font></span><font color="#dadada"> </font><span style="color: "><font color="#4ec9b0">FieldLikeSingleton</font></span><span style="color: "><font color="#dcdcdc">();</font></span><br></font><font face="Consolas"><font color="#dadada"> <br> </font><span style="color: "><font color="#569cd6">private</font></span><font color="#dadada"> </font><font color="#dcdcdc"><span style="color: ">FieldLikeSingleton</span><span style="color: ">()</span></font><font color="#dadada"> </font></font><font face="Consolas"><font color="#dcdcdc"><span style="color: ">{}</span><br><span style="color: ">}</span></font><br><font color="#dadada"> </font><br><span style="color: "><font color="#569cd6">public</font></span><font color="#dadada"> </font><span style="color: "><font color="#569cd6">class</font></span><font color="#dadada"> </font><span style="color: "><font color="#4ec9b0">FieldLikeLazySingleton</font></span><br><span style="color: "><font color="#dcdcdc">{</font></span><br><font color="#dadada"> </font><span style="color: "><font color="#569cd6">private</font></span><font color="#dadada"> </font><span style="color: "><font color="#569cd6">static</font></span><font color="#dadada"> </font><span style="color: "><font color="#569cd6">readonly</font></span><font color="#dadada"> </font><span style="color: "><font color="#4ec9b0">Lazy</font></span><span style="color: "><font color="#dcdcdc"><</font></span><span style="color: "><font color="#4ec9b0">FieldLikeLazySingleton</font></span><span style="color: "><font color="#dcdcdc">></font></span><font color="#dadada"> </font><span style="color: "><font color="#dcdcdc">_instance</font></span><font color="#dadada"> </font><span style="color: "><font color="#b4b4b4">=</font></span></font><font face="Consolas"><font color="#dadada"> <br> </font><span style="color: "><font color="#569cd6">new</font></span><font color="#dadada"> </font><span style="color: "><font color="#4ec9b0">Lazy</font></span><span style="color: "><font color="#dcdcdc"><</font></span><span style="color: "><font color="#4ec9b0">FieldLikeLazySingleton</font></span><span style="color: "><font color="#dcdcdc">>(()</font></span><font color="#dadada"> </font><span style="color: "><font color="#b4b4b4">=></font></span><font color="#dadada"> </font><span style="color: "><font color="#569cd6">new</font></span><font color="#dadada"> </font><span style="color: "><font color="#4ec9b0">FieldLikeLazySingleton</font></span><span style="color: "><font color="#dcdcdc">());</font></span><br></font><font face="Consolas"><font color="#dadada"> <br> </font><span style="color: "><font color="#569cd6">public</font></span><font color="#dadada"> </font><span style="color: "><font color="#569cd6">static</font></span><font color="#dadada"> </font><span style="color: "><font color="#4ec9b0">FieldLikeLazySingleton</font></span><font color="#dadada"> </font><span style="color: "><font color="#dcdcdc">Instance</font></span><font color="#dadada"> </font><span style="color: "><font color="#b4b4b4">=></font></span><font color="#dadada"> </font><span style="color: "><font color="#dcdcdc">_instance</font></span><span style="color: "><font color="#b4b4b4">.</font></span><font color="#dcdcdc"><span style="color: ">Value</span><span style="color: ">;</span></font><br></font><font face="Consolas"><font color="#dadada"> <br> </font><span style="color: "><font color="#569cd6">private</font></span><font color="#dadada"> </font><font color="#dcdcdc"><span style="color: ">FieldLikeLazySingleton</span><span style="color: ">()</span></font><font color="#dadada"> </font><font color="#dcdcdc"><span style="color: ">{}</span><br><span style="color: ">}</span></font></font></pre>
<p align="justify">Для простоты, первую реализацию я буду называть field-like реализацией (*), а вторую – ленивой.
<p align="justify"> </p>
</p></p><a href="http://sergeyteplyakov.blogspot.com/2016/12/singleton-implementation-in-net-field.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com13tag:blogger.com,1999:blog-8596733192274108952.post-34338686018252250982016-11-21T06:17:00.001+02:002016-11-22T17:46:58.214+02:00Горизонтальные и вертикальные слои приложения<p align="justify">«У лука есть слои, и у людоедов есть слои! Ты понял?» - Шрек </p> <p align="justify">Эта заметка навеяна выступлением <a href="https://lostechies.com/jimmybogard/">Jimmy Bogard</a> на 0redev под названием <a href="https://vimeo.com/190925521">“Solid Architecture in Slices not Layers”</a>, которую я всячески рекомендую. <p align="justify">Как и у людоеда, у любого современного приложения есть слои. Классической моделью является мордочка наверху, бизнес-логика по центру и базейка снизу. Такое разделение вполне уместно и определяется множеством причин. <p align="justify"><b>Conway</b><b>’s</b><b> Law</b> <p align="justify">Любой сложный проект требует вовлечения людей с разной специализацией и интересами. Кто-то пилит базы данных, кто-то лабает UI, а кто-то отвечает за логику. Такое разделение позволяет людям специализировать, а менеджеру масштабировать разработку: выделяя группы и подгруппы, отвечающие за отдельные куски. <p align="justify">Такой разделение еще сильнее выстраивает барьеры между слоями приложения, поскольку тут начинает во всей красе проявляться <a href="https://en.wikipedia.org/wiki/Conway's_law">Conway’s Law</a>, когда архитектура приложения начинает повторять структуру организации.</p> </p></p></p></p><a href="http://sergeyteplyakov.blogspot.com/2016/11/horizontal-and-vertical-architectural.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com21tag:blogger.com,1999:blog-8596733192274108952.post-30739904611688844742016-11-14T22:24:00.001+02:002016-11-14T22:24:48.794+02:00Памятка ынтырпрайз кодера<p align="justify">После прочтения <a href="https://www.goodreads.com/review/show/502289467">“Release It!”</a> захотелось сохранить ряд мыслей по поводу разработки распределенного ынтырпрайз софта. То, о чем нужно думать, что нужно подпилить, о чем нужно не забыть и т.п. <p align="justify"><b>1. Все что может отвалиться, обязательно отвалится</b> <p align="justify">База ляжет, удаленный веб-сервис начнет тупить, перестанет проходить автортизация, ажура начнет отбивать запросы (throttling). Это значит, что любое взаимодействие с внешними системами должно это учитывать. К сожалению, это легче сказать, чем сделать, поскольку современные библиотеки для распределенного взаимодействия слоены до нельзя и с точки зрения API не вполне очевидно, что именно может пойти не так, какие исключения могут вылететь, и что с ними нужно будет делать.</p> </p></p><a href="http://sergeyteplyakov.blogspot.com/2016/11/memo-for-enterprise-dev.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com20tag:blogger.com,1999:blog-8596733192274108952.post-41982956126816606442016-10-24T07:48:00.001+03:002016-10-24T07:49:24.174+03:00Менторинг и парное программирование<p align="justify">В комментариях к прошлой заметке <a href="http://sergeyteplyakov.blogspot.com/2016/10/pair-programming.html">о парном программировании</a>, несколько человек выразили несогласие по поводу моей фразы о неэффективности использования этого подхода для обучения молодых специалистов. Поскольку тема менторства мне близка и интересна, я хочу развить эту мысль. <p align="justify">Итак, прежде всего немного контекста. В прошлой заметке шла речь об анализе классического подхода, описанного Кентом Беком в его «Экстремальном программировании», когда ни одна строка кода не попадает в финальный репозиторий, если над ней не работало два человека одновременно. Это весьма специфический вид совместной работы, главной целью которого является повышение качества кода. Обучение, обмен опытом, интересное время препровождение, все это пусть и полезные, но второстепенные артефакты этой активности. <p align="justify">Работа в паре действительно может быть полезна для обмена опытом, вклиниванием нового сотрудника в проект или для обучения падавана мастером. Но в этом случае, это не будет «парным программированием» в классическом понимании, это будет парная работа с совершенно другим подходом со стороны обоих участников. <p align="justify">Теперь давайте об этом более подробно.</p> </p></p></p><a href="http://sergeyteplyakov.blogspot.com/2016/10/mentoring-and-pair-programming.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com0tag:blogger.com,1999:blog-8596733192274108952.post-10606015229534664272016-10-17T08:21:00.001+03:002016-10-17T08:26:48.003+03:00О парном программировании<p align="justify">Идея парного программирования в том, что работа над любым продуктовым кодом должна вестись совместно: вместе дизайним, пилим, ломаем и чиним. По идее, не должно быть ни одной закоммиченной строки кода, которые не прошли бы через 4 руки. И хотя в некоторых случаях совместная работа может быть полезной и продуктивной, но в подобной формулировке мне она всегда казалась через чур экстремальной.</p> <p align="justify">До последнего времени у меня не было личного опыта парного программирования, поэтому мое мнение было сугубо теоретическим. За последние полгода у меня появился какой-то опыт, и именно им и хотелось бы поделиться. <p align="justify"><a href="https://lh3.googleusercontent.com/-yQIFc1GBTp4/WARhFYY7h_I/AAAAAAAARS8/IQJjdvWbEks/s1600-h/PairProgramming%25255B6%25255D.jpg"><img title="PairProgramming" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="PairProgramming" src="https://lh3.googleusercontent.com/-x8ZUfvwJkEI/WARhF4w3ZCI/AAAAAAAARTA/EpvBiE7ORUI/PairProgramming_thumb%25255B2%25255D.jpg?imgmax=800" width="640" height="479"></a> <p align="justify">Итак, начнем с проблем.</p> </p></p><a href="http://sergeyteplyakov.blogspot.com/2016/10/pair-programming.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com13tag:blogger.com,1999:blog-8596733192274108952.post-5794191827058035062016-09-29T08:09:00.001+03:002016-09-29T08:09:26.212+03:00Hero Pattern<p align="justify">На некоторых особо популярных мировых галерах нередко можно встретить заболевание под названием Hero Pattern. Идея его в том, что гребец трудится усердно и много, монополизируя некоторый фронт работ, чтобы показать свою ценность и получить годовые плюшки с возможным повышением по службе. <p align="justify">Насколько я знаю, подобный недуг встречается довольно редко на отечественных фермах. Причин здесь несколько. Во-первых, местные люксофты все же больше сосредоточены на аутстафе, когда в продвижении тела заинтересовано не только оно само, но и пм, и другие местные стейкхолдеры. Во-вторых, отечественный рынок труда моложе, что выражается в существенно более высоком темпе роста компаний, что упрощает продвижение по службе. <p align="justify">Динамичность рынка труда требует роста на всех уровнях. Гребцы поматерее выдвигаются в рулевые, что автоматом выстилает дорогу в синьеры всем желающим. Просто нахождение тела на проекте автоматом дает ему шансы на продвижение независимо от талантов и умений. Наличие головы на плечах позволит довольно уверенно двигаться наверх внутри конторы. А в случае проблем на текущем месте, всегда найдется другой епам, которому позарез нужно стартовать очередной проект, и который не пожидится на +500 в месяц за тебя красивого. <p align="justify"></p> </p></p></p><a href="http://sergeyteplyakov.blogspot.com/2016/09/hero-pattern.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com22tag:blogger.com,1999:blog-8596733192274108952.post-82841595689995162842016-09-19T07:35:00.001+03:002016-09-19T07:35:34.482+03:00О шаринге знаний и компетенций с коллегами<p align="justify">Один из читателей недавно задал вопрос, подумать над которым, имхо, будет полезно многим: насколько полезно/уместно делиться своими знаниями с коллегами по работе? Не просто с коллегами по цеху через блоги/выступления, а именно с коллегами по команде. Ведь подобное действия могут уменьшить удельную ценность гребца, что может сказаться на его продвижения по службе. <p align="justify">Для меня лично вопрос делиться знаниями или нет не стоит вообще. Я делюсь техническими знаниями, как и знаниями по проекту не потому, что хочу или не хочу продвинуться. Я это делаю, поскольку это неотъемлемая часть меня и моего рабочего процесса. Для меня всегда было важно помочь младшему коллеге, дать совет члену другой команды, если он уместен, или поговорить с руководителем о том, что команда движется в каком-то странном направлении. <p align="justify">Для меня – делиться знаниями, даже скудными, это означает узнавать что-то лучше самому. Когда приходится рассказывать об архитектуре или используемых паттернах своему коллеге, то ты автоматически воспроизводишь все решение в голове и оцениваешь его валидность/корректность. Если коллега опытный, то он легко подправит твое понимание проблемы. Если же он новичок, то его стеклянные глаза будут прекрасным индикатором кривизны архитектуры или показателем полного отсутствия у тебя скила по донесению сложных вещей слушателю.</p> </p></p><a href="http://sergeyteplyakov.blogspot.com/2016/09/on-knowledge-sharing.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com17tag:blogger.com,1999:blog-8596733192274108952.post-50525938677535148952016-09-05T22:55:00.001+03:002016-09-05T22:56:13.695+03:00Инкапсуляция и сокрытие информации<p align="justify">В области проектирования существует два понятия, которые часто используются совместно – инкапсуляция (encapsulation) и сокрытие информации (information hiding). <p align="justify">Понятие инкапсуляции обычно используется в контексте ОО-языков и означает сокрытие данных (*). Открытые изменяемые (**) данные нарушают инкапсуляцию, поскольку теперь любой клиент класса сможет изменить внутреннее состояние объекта без ведома самого класса. Это может нарушить некоторые инварианты, т.е. условия на которые расчитывал автор класса и на которые, формально или неформально, должны полагаться его клиенты. <p align="justify">(*) – иногда понятие инкапсуляции применяется в более широком смысле. Например, говорят, что фабрика «инкапсулирует» информацию о конкретном типе создаваемого объекта. В этом контексте инкапсуляция является синонимом сокрытия информации. <p align="justify">(**) – хотя принято считать, что у класса недолжно вообще быть открытых данных, но с практической точки зрения, открытое неизменяемое поле хоть и нарушает инкапсуляцию, обычно не приводит к таким же серьезным проблемам сопровождения, как открытые изменяемые данные. <div align="justify"> </div></p></p></p></p><a href="http://sergeyteplyakov.blogspot.com/2016/09/encapsulation-and-information-hiding.html#more">Читать дальше...</a>Sergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.com7