Два года с Go

Сейчас подвожу итоги где-то 2-х лет разработки серии проектов на Go и довольно приятно удивляюсь тому, насколько хорошую защиту от дурака имеет Go по-умолчанию. Выстрелить себе в ногу просто невероятно сложно и в общем случае разработчик может просто сконцентрироваться на задаче не думая про UB, особенности move semantic и кучу других вещей, которые постоянно должны быть в голове у C++ разработчика.

Если отбросить очень сильное упрощение языка и попытаться выделить какие же именно решения позволили сильно упростить работу, то я бы отметил два: 1) отсутствие классов и наследования, 2) запрет на циклические импорты.

Continue reading

ML не взлетает…

В начале этого года меня довольно сильно проперло с  машинного обучения. Настолько сильно что я прошел Deep Learning Specialization и стал размышлять на тему того, что дальше делать и как это монетизировать.

В плане того, что делать дальше курсы в рамках  Deep Learning Specialization довольно наглядно показали что тема откровенно бездонная, и если хочется не просто как-то решать задачи при помощи TensorFlow и иже с ними, но и понимать то что делаешь, то нужно копать отсюда и ужина, который ожидается в лучшем случае через несколько лет. Я было даже взялся за Mathematics for Machine Learning, чтобы освежить школьную математику, которая была само собой благополучно забыта за 20 лет после окончания школы. Но что-то мне начало казаться, что так слона не съесть, так как он слишком велик. У меня вообще сложилось ощущение что люди в ML делятся на две категории: одни понимают как оно работает, а вторые просто используют инструменты без понимания что внутри. И само собой, этих самых вторых около 98%, что выглядит очень страшно…

С монетизацией тоже не всё понятно. Несмотря на шумиху вокруг ML, тема довольно нишевая и если приглядется к вакансиям в мире ML, то нормальный уровень (текущий, грубо говоря) дохода гарантирует только звездный уровень с PhD в данной области в придачу. Возникает довольно твердое убеждение что успешно продать ML в дополнение к моей основной специализации скорей всего не выйдет. А если что-то нельзя продать, то зачем оно нужно?

Плюс мир ML чем-то напоминает мир JavaScript с новыми прорывными решениями по нескольку раз в год, что сильно контрастирует с моей текущей специализацией. Те же сети и системная разработка позволяет довольно прохладно относиться к гонке за новинками, так как нового тут не так уж и много. К примеру те же несчастные корутины, которые “вот наконец решат все проблемы разработки сетевых приложений на C++”, обсасывают со всех сторон уже третий год, и реализации в 3-х основных компиляторах как разом как небыло, так и нет. Хорошо если через год-другой выкатят…

Но так как учить что-то надо всегда и во всех ситуациях, я на некотором распутье, то-ли продолжить копать ML, но не очень понятно как и в каком направлении, то-ли… ну, к примеру, посмотреть на blockchain, с куда более близкими криптографией, сетями и т.п.

CppCon 2018

В этом году мне посчастливилось в третий раз оказаться на конференции CppCon. Как и в прошлые годы, на конференции можно найти интересные доклады из практически любой области применения C++. Если сравнивать с конференциями прошлый лет, то в 2018 году вышло на уровне 2016, просто конференция 2017 была особенно прекрасной по содержанию 🙂
Внезапно самыми интересными для меня в этом году оказались не доклады Гуру С++, которые на этом деле собаку съели, а выступления не замеченных мной ранее докладчиков.
  1. Текущая ситуация, когда сообщество информационной безопасности стоит особняком от сообщества разработчиков, мне кажется в корне не верной и доклад Software Vulnerabilities in C and C++ как раз был направлен на устранение данного безобразия. Это просто замечательное начинание, так как конференции типа BlackHat и PHdays скучны для разработчиков, а сами безопасники к нам не ходят. В результате образуется нелепый вакуум, хотя в теории оба сообщества должны тесно работать друг с другом.
  2. Идея доклада Better C++ using Machine Learning on Large Projects вроде и лежит на поверхности, но решились реализовать такое только в Ubisoft Montreal. Суть идеи проста: у нас есть история коммитов и история ошибок. А что будет если их объединить и натренировать сеть? Может даже получиться не только предсказать будет ли в коммите дефект (с довольно хорошей вероятность 75%), но и автоматом предложить код с исправлением?
  3. Как неожиданно выяснилось, прямой конкурент Maya и 3D MAX пишет команда из 25 человек и очень успешно занимается этим последний 21 год. Вызовы и их решение в докладе Patterns and Techniques Used in the Houdini 3D Graphics Application.
  4. Довольно хороший рассказ про организацию сборочного пайплайна (правда у нас лучше вышел) в докладе Big Infrastructure at a Small Scale.
  5. Многопоточность – боль для очень и очень многих включая меня. What do you mean “thread-safe”? обобщает вопросы связанные с безопасностью разработки многопоточного кода на концептуальном уровне. В вроцессе много думал и планирую пересмотреть.
Остальное интересное и не очень:
  1. Начиналось все со Страуструпа и Concepts: The Future of Generic Programming. Скучно, как и все виденные мной предыдущие его выступления, но не пойти на Самого тоже никак.
  2. Очень-очень хороший доклад от Kate Gregory Simplicity: not just for beginners. Хорош он в первую очередь тем, что призывает и доступно объясняет что же такое простой код, к которому все разработчики должны стремиться.
  3. Доклад Саттера как-то смутно отложился в голове, вроде всё здорово и увлекательно, но… то-ли “но к чему это”, то-ли “а зачем столько лишних слов” не давали мне покоя на докладе Thoughts on a More Powerful and Simpler C++. Самое главное что я из него вынес и собираюсь как можно скорее опробовать флаг -Wlifetime, пиару которого была посвящена половина этого доклада. Да, вторая половина про метаклассы, которые постепенно начинают принимать очертания и лет через 10 мы их получим, если повезет.
  4. Закрывал конференцию доклад про нашумевшую уязвимость Spectre: Secrets, Side-Channels, Sandboxes, and Security с живой демкой и кучей ассемблерного кода. Было невероятно интересно и познавательно.
  5. Часто задавался вопросом “как же работает отладчик”, но ленился найти на него ответ и тут всё взяли да рассказали на How C++ Debuggers Work. Про отладчики было вообще много, как потому что  Backtrace активно пиарятся, так и потому, что писать нормально поставить процесс разработки на C++ выходит сильно не у всех.
К сожалению я упустил целую кучу потенциально интересных докладов, которые теперь жду на YouToube:
  1. Git, CMake, Conan – How to ship and reuse our C++ projects и Debug C++ Without Running я пропустил из-за энергичного и очень посредственного доклада Александреску Expect the Expected.
Ну а самым разорчаровывающим докладом где, как мне кажется, никто не понял зачем докладчик вообще вышел на сцену был Interfaces matter: High Performance and Heap Allocated Containers. В итоге вместо часа доклад уложился в 30 минут и вопросов не было от слова совсем, так как единственные вопрос “а к чему тут это все было?” как-то не удобно задавать…
Удивительным изменением в этом году было количество рускоговорящих на конференции, по моим прикидкам около 10, может быть 15% от общего числа посетителей. В итоге мы весело и познавательно посидели небольшой компанией в человек 20 в баре перед отъездом, жаль только из Касперского на конференции я никого из знакомых не увидел.

Зачем и кому нужен Go?

Так вышло, что последнии 2 года я довольно плотно работаю не только с давно привычными мне C++ и Python, но и Go. Как мне кажется, 2 года довольно приличный срок для того чтобы сформировать свое мнение о каком-либо инструменте, так что, пора им поделиться. Так же, по моим ощущениям, про Go обычно пишут люди из небольших компаний и стартапов, я же буду писать с точки зрения разработчика из матерой корпорации специализирующейся на разработке ПО.

Когда Go не нужен и не полезен

Начнем с самого важного: при каких условиях этот язык скорее вреден.
Continue reading

Командная строка и Windows

Надо признать, что время не стоит на месте и за те 9 лет что я не работал с Windows много что изменилось. Довольно неожиданным для меня открытием оказалось современное состояние командной строки на Windows, которая дошла до некого рабочего состояния. Не совсем, конечно, Vim так же хреново работает как и раньше, но всё же. Итак, как сделать окружение Windows относительно удобным для того, кто привык к *NIX. Continue reading

Информативная обработка ошибок в Go

Концепт обработки ошибок в Go довольно интересен в первую очередь тем, что ошибка в Go это просто произвольный объект поддерживающий интерфейс с функцией Error() string. Подобный подход превращает ошибку в некий гибрид Boolean с текстовым описанием и изрядная часть кодовой базы Go проектов выглядит так:

func foo(val int) error {
    if val == 42 {
        return fmt.Errorf("42 is not allowed")
    }
    // normal workflow
    return nil
}
...
err := foo(1)
if err != nil {
// do some error handling
}
// normal workflow

Continue reading

9 лет с macOS

Внезапно осознал, что приблизительно 9 лет назад, в 2009 году, я перешел с Windows на Mac OS X. Сейчас, не дотянув 1 года до ровных 10 лет, я окончательно ушел с macOS на Linux + Windows. Всё это, само собой, относится к повседневному домашнему использованию и мелким личным проектам, на работе как были все 3 платформы с macOS в качестве основной рабочей среды, так и остались.

В 2009 году решения от Apple действительно впечатляли как своими дизайнерскими и инженерными решениями, так и тем что “всё просто работает”. Да и в профессиональном плане эта миграция 9-ти летней давности была очень удачным решением для меня. Именно благодаря этому я в своё время оказался в Лаборатории Касперского и получил невероятно интересный и полезный опыт. Но время шло, конкуренты развивались, Apple деградировал и в последнии годы я был вынужден сначала уйти с iOS на Android, который внезапно стал предлагать на много более адекватное сочетание цены/качества, а потом и на PC индивидуальной сборки.

В принципе, для человека занимающегося графическим дизайном или просто использующего компьютер для набора текстов, интернета и просмотра фильмов, но практически не играющий в ресурсоемкие игры решения Apple (iMac, все виды MacBook) до сих пор на высоте как минимум с точки зрения железа. К сожалению с точки зрения софта ситуация не столько радужная до боли стала напоминать древние Windows, когда до выхода SP1 о переходе на новую версию ОС и думать было нечего, так как с большой вероятностью что-то отваливалось. Так что на macOS всё до сих пор вроде “просто работает”, но только после Нового Года. Каждую осень выходит нечто непотребное, это нечто усиленно латают 2-3 месяца и после НГ уже можно обновляться на новую ОС.

Хотя дальнейшая пригодность macOS для дизайнеров мне кажется тоже под большим вопросом после новости о том, что OpenCL объявлен устаревшим, так как миграция всех продуктов со сложными расчетами на Metal Performance Shaders, который поддерживается исключительно Apple, мне кажется довольно невероятным развитием событий. Собственно, отношение к GPGPU со стороны Apple для меня и стало последней каплей. Мало того, что на всех компьютерах устанавливаются GPU от AMD, так еще и никакое кросс-платформенное API типа Vulkan, а теперь еще и OpenCL, не поддерживается. Хотя и до последнего анонса максимально поддерживаемая версия OpenCL была всего лишь 1.2.

В процессе миграции на Windows + Linux я с удивлением осознал что за прошедшие 9 лет Windows так и не стал дружественной к разработчику платформой. Всё те же пляски вокруг установки разных SDK, Студий, никакенная консоль, нет менеджера пакетов даже для продуктов Майкрософт… Ту же CUDA я так и не смог нормально запустить на Windows за где-то 8 часов чистого времени (то не та версия студии, то компонент уже установлен, но часть dll почему-то не установилась вообще, то еще 1001 невнятная проблема) но сделал это за 15 минут на Ubuntu, что мне кажется довольно показательно, с Ubuntu я ведь те же 9 лет не имел дела.

В итоге у меня теперь Windows для C1 и Photoshop, к сожалению на Linux нет и не будет ничего сопоставимого, и Ubuntu для всего остального

Coursera, Глубокое обучение

Обычно я довольно скептично отношусь к около-IT онлайн-курсам. То слишком много воды, то слишком мало нового, то слишком медленный прогресс. Выходит проще взять документацию по интересующей тематике, найти подходящие заметки в блогах или книги и разобраться самостоятельно. До того как я наткнулся на специализацию по Глубокому обучению от Эндрю Ына, единственным исключением для меня был разве что курс на той же Coursera по алгоритмам Тима Рафгардена. А вот с курсом Глубоким обучением я сильно увлекся тематикой.

Курс Глубокое обучение прекрасен по большому счету вообще во всем: хорошо структурированная и продуманная теоретическая часть, интересная практическая часть на Python с использованием NumPy и переходом к TensorFlow в конце второй ступени, адекватные домашние задания. До того как начать этот курс я попробовал начать курс на fast.ai, но был довольно сильно разочарован сильнейшим перекосом в сторону практики, где всё демонстрируется на основе собственной надстройки толи над TensorFlow, толи над PyTourch. В принципе название курса на fast.ai – “Практическое машинное обучение для кодера” верное, делай что сказали без понимания базы и будет тебе счастье. Ну, возможно, кого-то такой подход и устраивает, я через пару недель сдался и пошел искать нечто более глубокое, так как имея ответ на вопрос “почему”, дойти до “как” в разы проще.

Если говорить про уровень начальной подготовки для специализации Глубокое обучение, то нужно помнить кое-какие моменты из старших классов школы, такие как производные, умножение матриц и простейшие элементы из математической нотации (такие как ∑, ℝ). Кроме того, нужно иметь хотя бы поверхностное представление о Python и Jupiter (бывший IPython). В зависимости от начальной теоретической базы, в неделю на курс будет уходить где-то от 4 и до 8 часов если исходить из стандартного темпа прохождения курса.

Все домашние задания в рамках курса выполняются в “тетрадях” Jupiter на серверах Coursera. Хотя если захочется копнуть поглубже и развить тему самостоятельно, то возникает необходимость либо в аренде мощностей в облаке (AWS, PaperSpace, и т.п.) либо сборке собственного компьютера под свои задачи, так как требуется довольно производительно GPU с поддержкой CUDA. После многочисленных таймаутов и отвалившихся сессий у облачных провайдеров я просто собрал себе подходящий компьютер дома. Но, еще раз подчеркну, это НЕ нужно если идти исключительно в рамках курса.

На данный момент я прошел 2 курса из 5 в рамках специализации и надо признать, понимание того “что такое DL” появилось и начинает обретать какие-то форму. Возможно, я изменю свое мнение о специализации когда дойду до конца, но пока что всё просто великолепно

С++ и надежный, безопасный код

Довольно часто можно встретить высказывания о том, что C++ и надежный, безопасный и легко поддерживаемых код несовместимы. Особенно часто такими высказываниями грешат адепты управляемых языков и довольно долгое время это было в общем-то небезосновательно. Сам я остро почувствовал данную проблему с C++ после того как основательно погрузился в Go, где благодаря большому количеству утилит для автоматического анализа кода, удается добиться приличного уровня кодовой базы проекта с относительно не высокими временными затратами. К счастью, в мире C++ в последние годы ситуация сильно изменилась и получить сопоставимый по качеству уровень стало возможно с приблизительно сопоставимыми усилиями.

Единый стиль форматирования

Казалось бы, единый стиль форматирования проекта – это мелочь, но ведь не просто так почти каждая уважающая себя компания имеет увесистый документ “BestCompanyInTheWorld Coding Standard”, который как минимум на половину состоит из того, как код должен быть отформатирован. При этом, код в BestCompanyInTheWorld почти наверняка отформатирован вразнобой, так как применение стандарта контролируется в лучшем случае в процессе ревью, но кто же помнит все эти хитросплетения пробелов и скобок? Работая с Go я впервые оценил прелесть того, что весь код включая сторонние библиотеки действительно написан в едином стиле, так как существует единое правило форматирования для всего языка. Эта казалось бы мелочь очень сильно упрощает работу над чужой кодовой базой и в случае с Go легко достигается автоматически при помощи доступных по умолчанию форматтеров.
Continue reading

Rust и Я

У меня, как наверное и у многих других C++ разработчиков какие-то сложные отношения с Rust. Этот язык вроде как и очень сильно нравится и в то же время всё сложно. На сей раз моя попытка заняться Rust в серьез зашла куда дальше чем обычно (обычно я после нескольких небольших тестиков удовлетворенно забрасывал изучение) – я нашел компанию которой нужны Rust разработчики, связался с ними и взял тестовое задание. Тестовое задание просто восхитительное, не сложное, но помогает понять главное – хочешь ли ты связываться с языком или нет?

На тестовое задание я честно потратил часов 8 и за это время успел заглянуть в tokio, которая, как я понимаю, является образцово-показательной библиотекой для написания асинхронных сетевых приложений. Честно говоря, я до сих пор в состоянии смятении, но точно знаю одно – видеть такое и не дай бог поддерживать на постоянной основе я точно не хочу. К примеру, вот кусок кода, который читает данные из канала и шлет их по TCP:

Box::new(tcp.map(move |stream| {
    let (sink, stream) = stream.framed(Bytes).split();
    pool.execute(stdin.forward(sink).then(|result| {
        if let Err(e) = result {
            panic!("failed to write to socket: {}", e)
        }
        Ok(())
    })).unwrap();
    stream
}).flatten_stream())

Несколькими месяцами раньше я баловался с биндингами к libClang, где было всё читабельно и очевидно, что наводит на мысли, что написать на Rust можно писать как в адекватном и легко поддерживаемом стиле, так и городить write-only код в духе приведенного выше. И надо отметить что в примере выше чувствуется и стиль и задумка. Если в него какое-то время повтыкать (желательно в IDE с навигацией, очень рекомендую IntelliJ Rust), то становится понятно что хотел сказать автор и почему. Только вот “НУ ЗАЧЕМ?!?!” не покидает.

В итоге мне в очередной раз стало казаться, что за пределами небольших сообществ гиков Rust взлететь не может, так как поддерживать столь неочевидные решения должно быть даже дороже чем решения на C++ с ручным управлением памятью (в конце концов, санитайзерами можно отловить практически всё). Не знаю чем это вызвано, скорей всего тем, что Rust развивает комьюнити гиков, а C++ комитет старперов. В результате в Rust тянут все, что круто выглядит, а в C++ только то, что “мегамозги” одобрили. Побочным эффектом этого выступает то, что в Rust многие удобные вещи доступны сразу или почти сразу, а в C++ это “наверное будет реализовано после C++20” (да-да, это я про Meta).

Наверное, меня всё равно не отпустит и баловаться с Rust я не перестану. Но вот подаваться на позицию “Rust разработчик” я довольно долгое время точно не буду, сообщество должно наиграться в “zero cost abstractions” для начала