Лаборатория Математики и Программирования Сергея Бобровского – Telegram
Лаборатория Математики и Программирования Сергея Бобровского
1.29K subscribers
1.19K photos
24 videos
931 links
ЛаМПовое с Бобровским
Download Telegram
...Если вы будете пытаться измерять "продуктивность" разработчиков, отслеживая количество закомиченных строк кода, число исправленных ошибок, среднее число комментариев по каждой правке кода и т.д., то люди сосредоточатся на игре в такую систему, чтобы набирать в ней баллы, вместо того чтобы учиться правильным вещам и делать свою работу хорошо.

играть в глупые игры, выигрывать глупые призы...
16👍9🔥4🫡4
Синхронизм двух отчётов курсантов :)

"Первые трудности были связаны с установкой фаззера на рабочий MacBook (хотел протестировать рабочий код).
Для установки требуется полноценный Clang, который содержит libFuzzer (как понял на Mac стоит урезанная версия Apple Clang).
Для решения данного вопроса потребовалось установить LLVM. Установить с первого раза не удалось. Потребовалось несколько вечеров, чтобы настроить окружение для установки Atheris."

"Вообще сложности возникли только с макбуком, который я неданво получил и все ещё настраиваю. Пришлось собирать из исходников clang; потому что apple поставляет огрызок llvm без libFuzz."

=

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

"And no, I do not have last Tuesday’s list of what is and isn’t supported under Linux, nor do I have next Tuesday’s list, which will in all probability be a different list."

-- Terry Lambert
отец FreeBSD, написавший в Apple 6% OS X kernel
🤔11🤝41👍1
C++ + его экосистема -- это уже реальная секта, порог входа весьма высокий, посторонним в :)

Конечно, секты круче исповедующих Лисп уже никогда не будет, но вот плюсисты к ним энергично подтягиваются.
🤯16👍8🔥4👏1
Нужно ли в случае проблем выбрасывать исключение в конструкторе?
Это спорная тема, по которой высказывается даже Microsoft Learn.
Anonymous Poll
57%
нужно
43%
не нужно
🤔172🤯1
Ко вчерашнему опросу, посмотрите, противоположные взгляды разделились примерно поровну. Попробую немного пояснить.

Исключения -- это по сути современные GOTO (динамическая типизация, скрытая в статической типизации). Когда конструктор выбрасывает исключение, он пытается вернуть что-то, отличное от явно запрошенного типа.

Начинающие часто делают такую ошибку: надо написать функцию, возвращающую сумму значений из набора файлов, а если там возникнет любая ошибка (от отсутствия файла до записанного в него нечислового значения), то что с ней делать? выбрасывать своё исключение? что-то "ошибочное" (null/None) возвращать в качестве результата?

Отсюда мы плавно переходим к фабрикам и монадам :)

Но есть нюанс: что делать, если некоторые данные в конструкторе недоступны сразу, и должны быть получены с помощью асинхронного вызова (что само по себе не здорово, но вот такой легаси-код вам достался)?

Это особенно актуально при активном использовании IoC-контейнеров, которые так любимы в мэйнстриме: если мы ждём отложенного поступления данных, а затем строим поведенческий класс, то у нас нет других вариантов, кроме явного вызова конструктора -- который ярые сторонники IoC как раз отвергают сходу.

Расскажу дальше чуть подробнее.
13🤔5🫡4👍1🤯1
...Основная засада в том, что большинство систем типов (даже самые академические!) терпят неудачу в ситуациях вроде исключения в конструкторе. Мы хотели бы стереть с помощью типов грань между временем выполнения и временем компиляции, но это требует от системы типов наличия условий и итераций (зависимостей от значений), тьюринговой полноты, и тут в любом случае возникают большие сложности применения типизации к значениям в рантайме.

Вообще, это большая тема, насколько активно и как правильно использовать конструкторы.

Универсального ответа, что делать с исключением в конструкторе, у меня нету :) Если язык достаточно продвинутый, на сегодня в мэйнстриме это наверное только TypeScript (что немудрено, его автор Хейлсберг ранее придумал Delphi и C#), тогда можно например задать тип конструктора как
Dwarf | ValidationException

Если же в случае ошибки вы хотите возвращать null, то тогда используйте фабричный метод, который выдаст Dwarf | null

В общем случае, проблема не в поведении времени выполнения, а в том, насколько соответствующий исходный код типизирован и выразителен.
В Python например вы не используете new, и конструктор там выглядит как функция, что очень здорово :)

dwarf = Dwarf()

И как раз за счёт своей гибкости Python позволяет (как и TS) наглядно записывать типы-объединения (PEP 604), поэтому мы можем конструктор и фабричный метод типизировать совершенно по-разному, и это просто великолепно.

Dwarf | None
Self | None

Тут можно строить очень интересные паттерны, сравнимые с продвинутыми фабричными методами, в том числе "умные конструкторы", которые скрывают недостатки исходного конструктора и принуждают использовать более тонкие подходы. Python, Kotlin, Swift, Go, Rust -- список нонконформистов можно продолжать. Например, в Kotlin есть extension methods, которые отнюдь не синтаксический сахар или эквивалент статическим методам Java. Наверно, можно даже сказать, что это в некотором смысле тайп-классы из ФП, или монады из LINQ...

Ладно, больше не буду морочить вам голову :)
12🫡7👍5
Валидация на стороне сервера -- пустая трата времени. Да или нет?
Anonymous Poll
7%
да
93%
нет
Ну, с Днём Программиста!

Хорошая новость-1, что пока цены для новеньких я повышать не планирую (а кто уже занимается, схема цен замораживается навсегда на момент записи на мои курсы),
однако, все тренды идут к этому :) Я жду, например, 110 к октябрю.
Куда ещё теперь вкладывать эти бессмысленные бумажки, как не в собственное развитие?

Хорошая новость-2, что AI научился писать промпты для AI лучше людей.

Процессы самосовершенствования искусственного интеллекта ускоряются в геометрической прогрессии; обратный отсчёт пошёл на месяцы? :)
🎉15🤯72👏21
По поводу валидации на сервере.

В Dwarf Fortress борода дварфа каждый день увеличивается на 1 единицу длины. Фронтенд запросом API получил JSON, увеличил поле beard на +1 и отправил его обратно. Но по правилам длина бороды не может превышать 1000 единиц. Где её контролировать?

Конечно, на сервере валидация обязательно нужна, но лучше всего, чтобы она была везде.
Что легче: добавить доп.проверку бороды на фронте, или дополнительно парсить ответ сервера на предмет ошибки, если с бородой пошло "что-то" (что?) не так? Понятно, что магические числа вроде 1000 это совсем плохо, поэтому можно добавить запрос по конфигурационным настройкам, и т.п.

Проблема в том, что если клиент написан не на JavaScript, а на другом языке, где нету нативной поддержки JSON (без "ручной" сериализации/десериализации) -- например, это мобильное приложение, то в случае, когда на сервере структура дварфа изменится (добавится новое поле), может поломаться и и фронтенд, и серверная логика игры (например, дополнительное поле, неизвестное клиенту, всегда будет уходить из фронтенда на сервер как null).

Поэтому обычно от сервера в таких случаях требуют не менять схему API-ответа вообще, а если что-то там изменилось, следует создать новую версию и предоставлять её отдельно по другому URI, например api/dwarf/v2/123.json. Клиенты переберутся на неё постепенно (как наивно полагает тимлид :).

Да, но если API активно развивается, то не успеем мы оглянуться, как окажемся на v256, и, скорее всего, многие (если не все) из этих версий будут нуждаться в поддержке!

Как легко и просто реализовывать подобные API на сотню разных версий, не ломая фронтенд и не требуя его переделки, скоро расскажу курсантам в СильныхИдеях всем в основном паблике вк.
🔥21👍5🙏2🫡2👏1
Пятница -- отличный день задеплоить что-нибудь в прод.
😁25💯8👍7🫡3🤔2
В конце августа 14 японских заводов Toyota остановились из-за того, что на каком-то сервере переполнился диск. Это всё, что надо знать о современном уровне system design в самых топовых компаниях.
👍13😁5👌5🫡3💯2
Важная характеристика сеньора, создающего действительно надёжное программное обеспечение -- это идея приоритета спецификации над кодом. Потому что программа, которая никогда не ошибалась, всё равно может ошибиться в любой момент.

Например, код даёт более строгие гарантии, нежели подразумеваемы спецификацией, и на эту разницу какие-нибудь дотошные программисты обязательно западут.

=

-- Эй, бэкенд! Нафига вы сломали API инвентаря дварфа? Раньше JSON приходил с ключами, упорядоченными по именам.
-- Нет, это не было гарантировано API, не стоит на это полагаться.
-- Ну и что, зато это разумная и удобная для фронтенда вещь, на которую мы рассчитываем, и её изменение -- это нарушение!

=

"Since the release of Go 1.0, the runtime has randomized map iteration order. Programmers had begun to rely on the stable iteration order of early versions of Go, which varied between implementations, leading to portability bugs."

В инженерии есть такой принцип робастности/надёжности Постела:
"для того, чтобы сделать надежный протокол, нужно как можно точнее придерживаться спецификаций, и в то же время «прощать» тех партнеров, кто не следует спецификациям в точности. Прощать до тех пор, пока вы в состоянии понять, что они хотят сказать."

Но в программировании это прямой рецепт создания хрупкого программного обеспечения.
5👍1🫡1
Когда месяцами пишешь на F#, а затем возвращаешься к C#, мозг немедленно клинит :)
Не получается нормально написать и 20 строчек работающего императивного кода.
Тут поможет книга наподобие "Functional Programming in C#", чтобы вернуться обратно к шарпу.
Но уже никак нельзя развидеть, насколько прост и элегантен фуллстек F# ...
🤔13🫡5👍3
От одного из моих лучших курсантов после задания Hard Work "3+4 важных качества хорошего кода"...

"Во-первых, мне нужно больше уделять время проектированию системы, а не написанию кода. Кол-во плохого кода не идет ни в какое сравнение с хорошим кодом (включающий все 7 свойств).
Спроектировав алгебру, корректность которой можно доказать через Z3 мне не составит написать код, логически верный.
Во-вторых, я пересмотрел свое отношение к паттернам проектирования. До сего момента я искренне не понимал, в чем заключается их польза, но вот теперь, посмотрев на все 7 свойств, на то, как я отношусь в созданию системы, то отношусь к ним как к инструментам, которые действительно могут помочь. Это звучит странно, но для меня это дАвний баг в мышлении.
В-третьих, мое мировоззрение ещё раз перевернулось относительно качество создания систем. Посмотрев свои проекты, ни один из них не соответствует идеалу, даже на текущий момент времени.
Где-то все время обманывал себя, сам того не замечая...."
🤔19🫡76👍1🐳1
Интересный тренд.
Казалось бы, как это, уходить от чистого ФП к Rust, почему? Ну, лучшая эргономика, высокая производительность, прямой и простой синтаксис + сильные статические гарантии.
🤔16🔥3🫡31
Не знаю, насколько это очевидно (или неочевидно), но правильное думание о любом прикладном проекте должно происходить на достаточно высоком уровне абстракции, когда существует одна, единая концептуальная модель данных. По форме она обычно реализуется двойственно: реляционная схема и объектно-ориентированная "доменная" модель, однако это просто неразрывные представления одной и той же модели. Потому что существует только один мир, который вы моделируете.
5🤔5🫡3
Arial -- отличный фонт для редактора кода. Вы сохраняете кучу горизонтального пространства.
19🐳3🫡3😁1
Я единственный, кто разговаривает вслух с самим собой во время программирования?
Anonymous Poll
19%
Да
81%
Нет
Двойная антиутопия: AI становится всё тупее и тупее, потому что начинает обучаться на своих собственных результатах. Но люди об этом не знают, потому что они тоже становятся тупее.

Инсайдеры меты заявляют, что они намерены открыть исходный код каждой модели вплоть до AGI, так что никакие safe API не помешают злодеям. Эксперты по биооружию полагают, что мы уже всего в 1-3 годах от появления моделей "SuperEbolaGPT" (на основе llama2), которые за тысячу долларов и несколько часов в обход всех защит пошагово проведут до "результата", с которым пока невероятно успешно справляются лишь уиллисы и стэтхемы в боевиках...
🤔14🫡3😁2👌1💯1
Вы отлично справляетесь со своей увлекательной работой программистом, зарабатываете на достойную жизнь, и всё кажется прекрасным.

Затем вы получаете электронное письмо или сообщение в мессенджерах или линкедите с оффером, который кажется слишком хорошим, чтобы быть правдой: у рекрутера есть для вас отличная вакансия, и вы смотритесь как идеальный кандидат для этой роли!

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

А потом (я много раз предупреждал!) всё становится, хм, немного странным...

Полный материал "Как вас рекрутеры обманывают" будет для курсантов на треке "Бесстрашных переговорах о зарплате", и также скоро выложу его для донов в группе "Материалы для неначинающих программистов".
🔥9👍51
Плюсисты, вы сегодня действительно так пишете? Это круто ) Это уже какой-то другой мир. Реально подумываю о курсе по type-level design на C++.

Правда, даже продвинутые гуру cs говорят, что такое умение пока никому не дано :) Но почему бы не попробовать?
(Возьмусь за 1 миллион рублей :)

P.S. темплейты плюсов тьюринг-полные...
🤯11🤩4🐳32👍2