Не только на достаточно профессиональных курсах, но и в хорошем университете на занятиях по системному программированию вас вполне могут учить такой сермяжной "мудрости" 50-летней давности, что для того, чтобы создать новый процесс в Unix, вам надо создать копию существующего процесса, а затем настроить его для другой задачи. Это выглядит странно, но аргументы обычно приводятся достаточно весомые, поэтому такая рекомендация обычно воспринимается спокойно, хотя и с оговорками.
Однако вот отличная статья топовых исследователей ОС:
"A fork() in the road"
— Microsoft Research, Boston University, ETH Zurich.
Они там как раз утверждают то, что и хотелось бы сегодня (а не вчера) слышать от онлайн-курсов и университетов, уважающих себя и своих учеников: Unix API fork() -- это пережиток прошлого, непригодный для большинства случаев использования и нарушающий концептуальный дизайн.
In this paper, we argue that fork was a clever hack for machines and programs of the 1970s that has long outlived its usefulness and is now a liability. We catalog the ways in which fork is a terrible abstraction for the modern programmer to use, describe how it compromises OS implementations, and propose alternatives. As the designers and implementers of operating systems, we should acknowledge that fork’s continued existence as a first-class OS primitive holds back systems research, and deprecate it. As educators, we should teach fork as a historical artifact, and not the first process creation mechanism students encounter.
Их аргументы железны, предлагаемые альтернативы подробно описаны, и я предоставляю вам самим ознакомиться с ними. И тут между строк скрыт крайне поучительный обобщённый урок в плане проектирования систем, правильного думания над проектом, мета-правило, которое для моих курсантов разберу в СильныхИдеях.
Однако вот отличная статья топовых исследователей ОС:
"A fork() in the road"
— Microsoft Research, Boston University, ETH Zurich.
Они там как раз утверждают то, что и хотелось бы сегодня (а не вчера) слышать от онлайн-курсов и университетов, уважающих себя и своих учеников: Unix API fork() -- это пережиток прошлого, непригодный для большинства случаев использования и нарушающий концептуальный дизайн.
In this paper, we argue that fork was a clever hack for machines and programs of the 1970s that has long outlived its usefulness and is now a liability. We catalog the ways in which fork is a terrible abstraction for the modern programmer to use, describe how it compromises OS implementations, and propose alternatives. As the designers and implementers of operating systems, we should acknowledge that fork’s continued existence as a first-class OS primitive holds back systems research, and deprecate it. As educators, we should teach fork as a historical artifact, and not the first process creation mechanism students encounter.
Их аргументы железны, предлагаемые альтернативы подробно описаны, и я предоставляю вам самим ознакомиться с ними. И тут между строк скрыт крайне поучительный обобщённый урок в плане проектирования систем, правильного думания над проектом, мета-правило, которое для моих курсантов разберу в СильныхИдеях.
👍5
Из чата с курсантом, по развитию карьеры. 50 вакансий -- это статистически значимая выборка!
Евгений:
...я посмотрел около 50 вакансий дата инженера в основных индустриях, где с данными работают (ИТ, телеком, банки, ритейл).
Везде в принципе одно и тоже просят:
- sql и всё смежное по субд (прям отличный уровень нужен, не просто select) (может стоит все-таки ваш курс по SQL пройти, если там есть какая-нибудь теория по БД);
- python,scala,java (обычно один или два языка просят, скалу часто вижу в требованиях);
- hadoop,apache airflowи тд (программы для работы с big data; их много достаточно);
- все остальное что касается ETL процессов
На сеньорских позициях встречается подобное:
- Опыт разработки высоконагруженных бэкенд сервисов на Java, Scala или Python;
Вообще как мне кажется (дилетанским взглядом конечно) дата инженер похож на backend разработчика, который использует в работе много разных big data штук, типо оркестраторов и так далее. А в остальном как будто требования пересекаются в 70-80% случаев.
Мой ответ:
Да, безусловно, 80% это бэкенд, 20% специфика, акцент на ETL (вся унылая грязная работа по очистке датасетов, которую обычно сваливают на джуниоров :) работа с моделями это элитное сеньорское). Вообще, бэк рулит везде, даже для фронтенда немножко ) Я поэтому на нём и делаю основной акцент.
Отличное знание SQL и БД в датасайнсе абсолютно обязательно, прочитайте от корки до корки учебник Бьюли "Изучаем SQL" но это лишь начало, главное уверенно решать middle-hard задачки на хакерранге и codewars, очень правильный навык дата-моделирования при этом вырабатывается. И конечно поизучать классику
"Системы баз данных. Полный курс" Ульмана.
Я кстати раньше рекомендовал ещё "SQL и реляционная теория. Как грамотно писать код на SQL" Дейта, но это не для слабаков из мэйнстрима, сложная, много теории, очень мощная, реальный хардкор,
90% профи многих этих принципиально важных вещей не знают, рекомендую.
Евгений:
...я посмотрел около 50 вакансий дата инженера в основных индустриях, где с данными работают (ИТ, телеком, банки, ритейл).
Везде в принципе одно и тоже просят:
- sql и всё смежное по субд (прям отличный уровень нужен, не просто select) (может стоит все-таки ваш курс по SQL пройти, если там есть какая-нибудь теория по БД);
- python,scala,java (обычно один или два языка просят, скалу часто вижу в требованиях);
- hadoop,apache airflowи тд (программы для работы с big data; их много достаточно);
- все остальное что касается ETL процессов
На сеньорских позициях встречается подобное:
- Опыт разработки высоконагруженных бэкенд сервисов на Java, Scala или Python;
Вообще как мне кажется (дилетанским взглядом конечно) дата инженер похож на backend разработчика, который использует в работе много разных big data штук, типо оркестраторов и так далее. А в остальном как будто требования пересекаются в 70-80% случаев.
Мой ответ:
Да, безусловно, 80% это бэкенд, 20% специфика, акцент на ETL (вся унылая грязная работа по очистке датасетов, которую обычно сваливают на джуниоров :) работа с моделями это элитное сеньорское). Вообще, бэк рулит везде, даже для фронтенда немножко ) Я поэтому на нём и делаю основной акцент.
Отличное знание SQL и БД в датасайнсе абсолютно обязательно, прочитайте от корки до корки учебник Бьюли "Изучаем SQL" но это лишь начало, главное уверенно решать middle-hard задачки на хакерранге и codewars, очень правильный навык дата-моделирования при этом вырабатывается. И конечно поизучать классику
"Системы баз данных. Полный курс" Ульмана.
Я кстати раньше рекомендовал ещё "SQL и реляционная теория. Как грамотно писать код на SQL" Дейта, но это не для слабаков из мэйнстрима, сложная, много теории, очень мощная, реальный хардкор,
90% профи многих этих принципиально важных вещей не знают, рекомендую.
🔥19✍3🫡2❤1🏆1
Надо ли доводить код до совершенства?
Если вы всегда стремитесь приводить в порядок всё, что выглядит беспорядочным, то вы будете тратить почти всё своё время на рефакторинг и чистоту кода, и совсем мало времени на внедрение новых фич.
Если вместо этого вы сосредоточитесь на развитии проекта и написании нового кода независимо от беспорядка, то этот беспорядок будет накапливаться в виде технического долга, а новые изменения и улучшения будут становиться все сложнее и труднее.
Если вы попытаетесь соблюсти баланс и, например, регулярно выделять время на периодический рефакторинг и улучшение того, что уже было нафигачено, то ситуация станет совсем печальной :) подобный улучшайзинг аналогичен взятию кредита под огромные проценты.
Либо вы всю жизнь учитесь тому, как правильно проектировать систему с самого начала, чтобы она не запутывалась, и как сразу писать ясный и безошибочный код, либо вот это вот всё.
Если вы всегда стремитесь приводить в порядок всё, что выглядит беспорядочным, то вы будете тратить почти всё своё время на рефакторинг и чистоту кода, и совсем мало времени на внедрение новых фич.
Если вместо этого вы сосредоточитесь на развитии проекта и написании нового кода независимо от беспорядка, то этот беспорядок будет накапливаться в виде технического долга, а новые изменения и улучшения будут становиться все сложнее и труднее.
Если вы попытаетесь соблюсти баланс и, например, регулярно выделять время на периодический рефакторинг и улучшение того, что уже было нафигачено, то ситуация станет совсем печальной :) подобный улучшайзинг аналогичен взятию кредита под огромные проценты.
Либо вы всю жизнь учитесь тому, как правильно проектировать систему с самого начала, чтобы она не запутывалась, и как сразу писать ясный и безошибочный код, либо вот это вот всё.
🔥13🤔11✍2🫡2👍1
Холодная суровая правда о колледже и университете состоит в том, что это пустая трата времени и денег. Существует масса ценных ресурсов и куча репетиторов, которые потенциально помогут вам обучиться полезным навыкам и найти высокооплачиваемую работу.
Однако если меня спрашивают, стоит ли им бросить универ, я всегда говорю "нет! продолжайте заниматься!". Причина, по которой я советую им остаться, заключается в том, чтобы развивать в себе выдержку, упорство и дисциплину. Это важно, так что слушайте внимательно.
Многие люди не могут придерживаться чего-то одного, не могут сконцентрироваться на важном и полезном для них, не способны ни один длительный проект довести до конца. И это одна из главных причин, по которой они НИКОГДА не заработают много денег. Вот почему они застревают в своих 9-18, пока в 65 лет не становятся старыми и морщинистыми.
Поверьте мне, если вы сможете заниматься чем-то одним хотя бы 2 года... Я гарантирую, что вы превзойдёте в этом любого из своих сверстников.
Из многих сотен ребят все мои курсы, мою Школу до конца за последние три года прошло всего два человека, и ещё считанные единицы с тренинга по проектированию higher work к этому подбираются. А 99% просто не способны даже такое не очень долгое время учиться нужному и полезному. По сути, они предают сами себя. Ну штош...
В результате 1 процент упорных и настойчивых получает огромное конкурентное преимущество над массовкой слабаков. И это хорошо, очень этому рад и концентрируюсь на занятиях именно с этой маленькой интеллектуальной элитой.
Однако если меня спрашивают, стоит ли им бросить универ, я всегда говорю "нет! продолжайте заниматься!". Причина, по которой я советую им остаться, заключается в том, чтобы развивать в себе выдержку, упорство и дисциплину. Это важно, так что слушайте внимательно.
Многие люди не могут придерживаться чего-то одного, не могут сконцентрироваться на важном и полезном для них, не способны ни один длительный проект довести до конца. И это одна из главных причин, по которой они НИКОГДА не заработают много денег. Вот почему они застревают в своих 9-18, пока в 65 лет не становятся старыми и морщинистыми.
Поверьте мне, если вы сможете заниматься чем-то одним хотя бы 2 года... Я гарантирую, что вы превзойдёте в этом любого из своих сверстников.
Из многих сотен ребят все мои курсы, мою Школу до конца за последние три года прошло всего два человека, и ещё считанные единицы с тренинга по проектированию higher work к этому подбираются. А 99% просто не способны даже такое не очень долгое время учиться нужному и полезному. По сути, они предают сами себя. Ну штош...
В результате 1 процент упорных и настойчивых получает огромное конкурентное преимущество над массовкой слабаков. И это хорошо, очень этому рад и концентрируюсь на занятиях именно с этой маленькой интеллектуальной элитой.
🔥18🫡10👍2🤝2👌1
Как писать программы без ошибок? Прикладывайте усилия к структурированию ответов на вопрос "почему эта функция/программа корректна?" на уровне их спецификаций, проверяйте эти ответы с помощью системы типов, и тесты во многих случаях вообще не понадобятся.
Для императивных/"ооп" программистов более приземлённый совет: начинайте всегда со структур данных, а не с алгоритмов. Если вы вложите соответствующие усилия в формализацию задачи, то алгоритмы последуют из этого естественно, просто как (рекурсивный) "обход" этих структур данных.
Например, есть такая штука, как джанглоид -- кусочек кода, который синтезируется автоматически и выполняет некоторый условно клиентский запрос к API на основании заданных типов входных и выходных значений. Так вот, формальная теория джанглоидов была разработана в начале 2000-х, задолго до явления хипстерских AI-ассистантов. Джанглоиды отлично комбинируются, и на их основе для Eclipse (основной Java IDE того времени) был разработан плагин, который выдавал адекватные подсказки и варианты кода, и, в частности, нашёл решение 18 из 20 задач =>
"Jungloid mining: helping to navigate the API jungle"
Это я к тому, что если чётко описать типы входных и выходных данных функции, определить в спецификации пред- и пост-условия, то её логика будет столь прозрачна, что её можно формировать достаточно простыми приёмами, "не думая". Причём специально под это есть хорошие практики, в СильныхИдеях разбирал одну такую в материале "Как проектировать ко-рекурсивные программы" (структура программы естественно следует за используемой ей структурой данных).
Для императивных/"ооп" программистов более приземлённый совет: начинайте всегда со структур данных, а не с алгоритмов. Если вы вложите соответствующие усилия в формализацию задачи, то алгоритмы последуют из этого естественно, просто как (рекурсивный) "обход" этих структур данных.
Например, есть такая штука, как джанглоид -- кусочек кода, который синтезируется автоматически и выполняет некоторый условно клиентский запрос к API на основании заданных типов входных и выходных значений. Так вот, формальная теория джанглоидов была разработана в начале 2000-х, задолго до явления хипстерских AI-ассистантов. Джанглоиды отлично комбинируются, и на их основе для Eclipse (основной Java IDE того времени) был разработан плагин, который выдавал адекватные подсказки и варианты кода, и, в частности, нашёл решение 18 из 20 задач =>
"Jungloid mining: helping to navigate the API jungle"
Это я к тому, что если чётко описать типы входных и выходных данных функции, определить в спецификации пред- и пост-условия, то её логика будет столь прозрачна, что её можно формировать достаточно простыми приёмами, "не думая". Причём специально под это есть хорошие практики, в СильныхИдеях разбирал одну такую в материале "Как проектировать ко-рекурсивные программы" (структура программы естественно следует за используемой ей структурой данных).
🔥16🫡3⚡2❤2👍1
Поводом к очередному материалу для СильныхИдей стала консультация ребят, которые занимаются реверс-инжинирингом софта наших теперь уже недружественных друзей, которые сбежали, наплевав на все платные лицензии, однако их софт продолжает эксплуатироваться (буквально, в КИИ), но не то что исходников, теперь и секьюрных патчей за свои уплоченные денежки не получишь. Но баги надо как-то фиксить, и вот ребята теперь дизассемблируют бинарники, пытаясь что-то где-то там подправить в плане безопасности.
Но вот факт: большинство недостатков в вашей системе в плане безопасности невозможно использовать.
Если вы не специалист по ИБ, это утверждение может сбить вас с толку. Что такое косяк с безопасностью, если не то, что может позволить злоумышленнику получить контроль над вашей системой или похитить ваши данные?
Ну, посмотрите например стандарт безопасного кодирования института программной инженерии SEI (авторы CMM и PSP) при университете Карнеги-Меллона, и вы увидите, что то, что отметит типовой эксперт по ИБ -- это множество мелких деталей, которые можно заметить с первого взгляда, при стандартном code review. Они утверждают, что если сделать всё это стилистически правильно, то ваше программное обеспечение, скорее всего, будет безопасным. Написание правильного кода подразумевает создание модулей, которые могут быть рассмотрены по отдельности.
Однако создание эксплойтов через воспроизведение ошибок заключается в долгом и нудном поиске длинных цепочек событий во всей программе, которые приводят к тому, что она переходит в "плохое" состояние. И тот факт, что нельзя гарантировать, что буфер не переполнится, очень далёк от прикладной проверки возможности Heartbleed (неправильно сформированное значение в пакете действительно будет использовано таким образом, что позволит злоумышленнику прочитать данные).
Между мышлением разработчика и мышлением хакера имеются кардинальные различия. Это принципиально разные думательные машики, которые встраиваются в ум качественно разными способами и приёмами. У каждой из них своя математическая логика (у программистов -- логика Хоара прежде всего). Чтобы тут не путаться, дам курсантам в СильныхИдеях, которых учу ясному формальному мышлению классического разработчика, чёткое научное определение модели мышления разработчика эксплойтов, как правильно рассуждать в хакерской парадигме, по материалу исследователей формальной (и несовместимой с хоаровской) хакерской логики из фейспалма и University College London.
Но вот факт: большинство недостатков в вашей системе в плане безопасности невозможно использовать.
Если вы не специалист по ИБ, это утверждение может сбить вас с толку. Что такое косяк с безопасностью, если не то, что может позволить злоумышленнику получить контроль над вашей системой или похитить ваши данные?
Ну, посмотрите например стандарт безопасного кодирования института программной инженерии SEI (авторы CMM и PSP) при университете Карнеги-Меллона, и вы увидите, что то, что отметит типовой эксперт по ИБ -- это множество мелких деталей, которые можно заметить с первого взгляда, при стандартном code review. Они утверждают, что если сделать всё это стилистически правильно, то ваше программное обеспечение, скорее всего, будет безопасным. Написание правильного кода подразумевает создание модулей, которые могут быть рассмотрены по отдельности.
Однако создание эксплойтов через воспроизведение ошибок заключается в долгом и нудном поиске длинных цепочек событий во всей программе, которые приводят к тому, что она переходит в "плохое" состояние. И тот факт, что нельзя гарантировать, что буфер не переполнится, очень далёк от прикладной проверки возможности Heartbleed (неправильно сформированное значение в пакете действительно будет использовано таким образом, что позволит злоумышленнику прочитать данные).
Между мышлением разработчика и мышлением хакера имеются кардинальные различия. Это принципиально разные думательные машики, которые встраиваются в ум качественно разными способами и приёмами. У каждой из них своя математическая логика (у программистов -- логика Хоара прежде всего). Чтобы тут не путаться, дам курсантам в СильныхИдеях, которых учу ясному формальному мышлению классического разработчика, чёткое научное определение модели мышления разработчика эксплойтов, как правильно рассуждать в хакерской парадигме, по материалу исследователей формальной (и несовместимой с хоаровской) хакерской логики из фейспалма и University College London.
👍9🔥2❤1
Знакомые пацаны-скалисты из финтеха звали к себе посоветовали глянуть ZIO -- внезапно действительно оказалась крутая вещь, рекомендую!
Type-safe, composable asynchronous and concurrent programming for Scala
Особенно им понравился мой коммент, что дескать
ZIO[R, E, A] (an immutable value that lazily describes a workflow or job) -- это великолепная и отлично масштабирующаяся абстракция гексагональной архитектуры, причём шикарно эээ композиционирующаяся (русского не хватает, composable), и даже фрактальная по сути!
Type-safe, composable asynchronous and concurrent programming for Scala
Особенно им понравился мой коммент, что дескать
ZIO[R, E, A] (an immutable value that lazily describes a workflow or job) -- это великолепная и отлично масштабирующаяся абстракция гексагональной архитектуры, причём шикарно эээ композиционирующаяся (русского не хватает, composable), и даже фрактальная по сути!
👍2👏1
Смешное: как я ни пытался заставить ChatGPT-4 (!) закодить простейшую задачку на питоне -- сгенерировать список всех файлов и каталогов в заданном каталоге, включая список всех файлов и каталогов одного уровня вложенности если включён флажок (простая задачка для моих начинающих курсантов с околонуля), оно так и не смогло.
Генерит код, который при флажке выдаёт все вложенные подкаталоги (оно и понятно, тупо берёт os.walk). И как я не возмущался и не уточнял что и как именно надо сделать, так и не исправилось. Ну, за такое даже из стажёров сразу выгоняют.
Может и вышло бы, если целый час детально уточнять и мучить промтами на такой элементарной задачке, что требуется; да, но час сеньора стоит в 10 раз дороже часа джуниора.
А вы говорите, скоро заменит профессиональных программистов....
С другой стороны, никто и не обещал, что AI действительно буквально будет писать любой код, нет конечно. Его относительный успех в кодинге объясняется прежде всего тем, что миллионы программистов (да и вообще белковые мозги в целом) мыслят крайне шаблонно, и число типовых приёмов в programming in small оказалось невелико, сотни, может быть тысячи, их надо просто уметь комбинировать. Если задача похожа на что-то ранее решавшееся, может быть решена по аналогии короткой комбинацией паттернов, то AI дописывает, а если хотя бы немного оригинальное, где надо немножечко оригинально подумать в формате символьных вычислений, сразу пасует. На codeforces например AI откровенно зашкварилось, вообще ничего не может.
Генерит код, который при флажке выдаёт все вложенные подкаталоги (оно и понятно, тупо берёт os.walk). И как я не возмущался и не уточнял что и как именно надо сделать, так и не исправилось. Ну, за такое даже из стажёров сразу выгоняют.
Может и вышло бы, если целый час детально уточнять и мучить промтами на такой элементарной задачке, что требуется; да, но час сеньора стоит в 10 раз дороже часа джуниора.
А вы говорите, скоро заменит профессиональных программистов....
С другой стороны, никто и не обещал, что AI действительно буквально будет писать любой код, нет конечно. Его относительный успех в кодинге объясняется прежде всего тем, что миллионы программистов (да и вообще белковые мозги в целом) мыслят крайне шаблонно, и число типовых приёмов в programming in small оказалось невелико, сотни, может быть тысячи, их надо просто уметь комбинировать. Если задача похожа на что-то ранее решавшееся, может быть решена по аналогии короткой комбинацией паттернов, то AI дописывает, а если хотя бы немного оригинальное, где надо немножечко оригинально подумать в формате символьных вычислений, сразу пасует. На codeforces например AI откровенно зашкварилось, вообще ничего не может.
👍15🤯4🔥3🫡1
Жаловаться на то, что тестирование (в целом) замедляет разработку, всё равно что жаловаться на то, что тормоза замедляют гоночный автомобиль.
(с) Кент Бек
(с) Кент Бек
❤14👍7👏2🔥1
Я никогда не был поклонником правил.
Ну... не тех правил, которым другие люди говорят нам следовать беспрекословно.
Такие правила меня раздражают...
Однако я считаю, что иметь свой собственный набор правил очень важно.
Особенно когда речь идёт о том, чтобы стать лучшим программистом... или вообще стать лучшим в чём-либо.
Это не значит, что вы никогда не должны нарушать свои собственные правила...
Но гораздо легче добиться успеха в качестве разработчика и раскрыть свой дополнительный потенциал, если у вас есть свод правил, которым вы должны следовать... даже если это просто руководство к действию.
За последние несколько лет я открыл несколько правил, выработанных за почти 45 лет программирования, создания бесчисленных программных продуктов... и оказания специализированных консультационных услуг серьёзным компаниям и стартапам, но главное -- благодаря регулярному изучению научных конференций по программированию и computer science. Главное, что в этих правилах собраны очень сильные, официально рецензируемые рекомендации с подобных конференций, чем кроме меня больше никто в России не занимается.
Послушайте, есть множество людей, которые стали отличными разработчиками и заработали много денег...
Но они редко тратят время на деконструкцию того, что они узнали, и создание правил о своих знаниях...
И КАК они достигли огромных прорывов.
Я нашёл время, чтобы сделать это.
Я изложил эти правила в виде простого в исполнении процесса -- практического тренинга по проектированию и программной инженерии.
Он называется Higher Work.
Единичные зарубежные аналоги стоят многие тысячи долларов, а мой для моих курсантов бесплатен.
Вот и всё.
Ну... не тех правил, которым другие люди говорят нам следовать беспрекословно.
Такие правила меня раздражают...
Однако я считаю, что иметь свой собственный набор правил очень важно.
Особенно когда речь идёт о том, чтобы стать лучшим программистом... или вообще стать лучшим в чём-либо.
Это не значит, что вы никогда не должны нарушать свои собственные правила...
Но гораздо легче добиться успеха в качестве разработчика и раскрыть свой дополнительный потенциал, если у вас есть свод правил, которым вы должны следовать... даже если это просто руководство к действию.
За последние несколько лет я открыл несколько правил, выработанных за почти 45 лет программирования, создания бесчисленных программных продуктов... и оказания специализированных консультационных услуг серьёзным компаниям и стартапам, но главное -- благодаря регулярному изучению научных конференций по программированию и computer science. Главное, что в этих правилах собраны очень сильные, официально рецензируемые рекомендации с подобных конференций, чем кроме меня больше никто в России не занимается.
Послушайте, есть множество людей, которые стали отличными разработчиками и заработали много денег...
Но они редко тратят время на деконструкцию того, что они узнали, и создание правил о своих знаниях...
И КАК они достигли огромных прорывов.
Я нашёл время, чтобы сделать это.
Я изложил эти правила в виде простого в исполнении процесса -- практического тренинга по проектированию и программной инженерии.
Он называется Higher Work.
Единичные зарубежные аналоги стоят многие тысячи долларов, а мой для моих курсантов бесплатен.
Вот и всё.
👍23🔥7❤2👏1🤔1
Я всегда подчёркиваю важность изучения глубоких концепций, а не поверхностных примеров. Например, сейчас готовлю материал для СильныхИдей, с помощью которого хочу научить программистов отключаться от мусорных каталогов со схемами рефакторинга и понять, что большинство знакомых им рефакторингов вытекают из единичных основных алгебраических законов, таких как тождество X^2*A = X^A * X^A, которое легко выводится из аксиом школьной алгебры, и соответствует замене функции, принимающей булевы аргументы, двумя функциями. Все приёмы рефакторинга, которые я знаю, легко выводятся буквально одношаговыми сокращениями конструкций языка программирования через простейшие алгебраические законы.
Есть например такое преобразование, которое заменяет функции высшего порядка эквивалентными функциями первого порядка. С его помощью в частности, было показано соответствие между многими парадигмами семантики языков программирования. Я понял (с помощью сингапурского профессора :) вездесущность этого преобразования как техники рефакторинга: оно неявно используется в самых разных задачах -- от придания рекурсивной функции итеративности до создания распределённой программы. И тем не менее, в литературе по рефакторингу об этом совершенно нигде не упоминается.
В соответствующем материале моим курсантам я расскажу об этой технике и её использовании, и о том, как обучение распознаванию соответствующих случаев может помочь программисту легче понимать и принимать компромиссы при выборе схемы проектирования. Эта техника родилась в ходе исследований компиляторов, подпитывается формальной семантикой, и будет ярким примером того, как исследования в области языков программирования могут быть переведены в полезные практические советы по повседневному кодингу.
P.S. За мои почти 45 лет работы в ИТ могу сказать определённо только одно: есть очень мало вещей в программировании, которые однозначно и безоговорочно можно считать хорошей идеей. Почти всегда всё зависит от ситуации и контекста использования. Поэтому с особой тщательностью отбираю такие золотые крупицы ценных знаний в СильныеИдеи для курсантов, сейчас там около 50 материалов + формат Higher Work (практика в этом всём).
Есть например такое преобразование, которое заменяет функции высшего порядка эквивалентными функциями первого порядка. С его помощью в частности, было показано соответствие между многими парадигмами семантики языков программирования. Я понял (с помощью сингапурского профессора :) вездесущность этого преобразования как техники рефакторинга: оно неявно используется в самых разных задачах -- от придания рекурсивной функции итеративности до создания распределённой программы. И тем не менее, в литературе по рефакторингу об этом совершенно нигде не упоминается.
В соответствующем материале моим курсантам я расскажу об этой технике и её использовании, и о том, как обучение распознаванию соответствующих случаев может помочь программисту легче понимать и принимать компромиссы при выборе схемы проектирования. Эта техника родилась в ходе исследований компиляторов, подпитывается формальной семантикой, и будет ярким примером того, как исследования в области языков программирования могут быть переведены в полезные практические советы по повседневному кодингу.
P.S. За мои почти 45 лет работы в ИТ могу сказать определённо только одно: есть очень мало вещей в программировании, которые однозначно и безоговорочно можно считать хорошей идеей. Почти всегда всё зависит от ситуации и контекста использования. Поэтому с особой тщательностью отбираю такие золотые крупицы ценных знаний в СильныеИдеи для курсантов, сейчас там около 50 материалов + формат Higher Work (практика в этом всём).
👍14🔥5
Про ИТ-стартапы -- в какой области создавать?
Мета-идею вам расскажет любой инфоцыган: посмотрите, где есть спрос, и идите туда. Более инженерный подход таков:
-- Однозначно, в ИТ есть множество тем, по которым явно не так много достаточно исчёрпывающих ресурсов, эти темы буквально на поверхности. Ну например, очень горячая: как вообще выживать начинающему тимлиду :)
-- Соответственно, создаёте и долгосрочно развиваете (это ключевое) ресурс (например, сайт + блог), содержащий по теме лучшие практики, решения известных проблем, примеры и т.д. (всё что жизнеспособно для этой темы).
-- Подобные ресурсы будут реально ценны для многих людей.
Из моего недавнего опыта, такая темка как управление версиями REST API. Как вы разрабатываете свои схемы данных, стараясь обеспечить как расширение API, так и сохранение обратной совместимости. Однако в ряде ситуаций отказ от обратной совместимости тоже будет хорошей идеей + надо также учитывать разницу между управлением версиями внутренних и клиентских API и т. д. и т. п.
В мире сегодня только официально насчитывается около 70 тысяч SaaS-компаний (ну и REST API как таковой вообще в любом проекте наверное сегодня имеется). Допустим, что из них как минимум 10 тысяч организаций явно интересуются этой проблемой. Сколько таких в России? Многие сотни точно, особенно с учётом вала проектов по импортозамещению.
Пусть на создание курса/учебника по версионному управлению REST API потребуется даже год работы, а в результате его применения средняя компания сэкономит в год 500 человеко-часов программистов на избавлении от кривых и несогласованных апишек. Если бы я был глобальным министром ИТ, пытающимся улучшить отрасль в целом, имело бы смысл заплатить одному человеку миллион рублей за написание учебника или курса по управлению версиями API. Это тема, с которой сталкивается далеко не каждый разработчик, но ею занимаются сотни или даже тысячи компаний, и хотя тема довольно широкая, она достаточно специфична, чтобы можно было объединить опыт и идеи в одном ресурсе.
И таких точечно-актуальных тем самого разного масштаба полным полно, ну например навскидку: миграции баз данных, корпоративные поисковые системы, рекомендательные системы, системы управления рабочими задачами, преобразование данных между разными форматами, тэгирование, как использовать конкретные популярные API (Github или OpenAI) и т. д.
Только тут конечно важно понимать, что без поддержки со стороны можно потратить год на написание такой книги, а потом купят её два с половиной человека (скорее всего). Усилий в продвижение подобных инфопродуктов, сколь бы полезными они ни были сами по себе, надо вкладывать, увы, ещё побольше, нежели в их создание.
Мета-идею вам расскажет любой инфоцыган: посмотрите, где есть спрос, и идите туда. Более инженерный подход таков:
-- Однозначно, в ИТ есть множество тем, по которым явно не так много достаточно исчёрпывающих ресурсов, эти темы буквально на поверхности. Ну например, очень горячая: как вообще выживать начинающему тимлиду :)
-- Соответственно, создаёте и долгосрочно развиваете (это ключевое) ресурс (например, сайт + блог), содержащий по теме лучшие практики, решения известных проблем, примеры и т.д. (всё что жизнеспособно для этой темы).
-- Подобные ресурсы будут реально ценны для многих людей.
Из моего недавнего опыта, такая темка как управление версиями REST API. Как вы разрабатываете свои схемы данных, стараясь обеспечить как расширение API, так и сохранение обратной совместимости. Однако в ряде ситуаций отказ от обратной совместимости тоже будет хорошей идеей + надо также учитывать разницу между управлением версиями внутренних и клиентских API и т. д. и т. п.
В мире сегодня только официально насчитывается около 70 тысяч SaaS-компаний (ну и REST API как таковой вообще в любом проекте наверное сегодня имеется). Допустим, что из них как минимум 10 тысяч организаций явно интересуются этой проблемой. Сколько таких в России? Многие сотни точно, особенно с учётом вала проектов по импортозамещению.
Пусть на создание курса/учебника по версионному управлению REST API потребуется даже год работы, а в результате его применения средняя компания сэкономит в год 500 человеко-часов программистов на избавлении от кривых и несогласованных апишек. Если бы я был глобальным министром ИТ, пытающимся улучшить отрасль в целом, имело бы смысл заплатить одному человеку миллион рублей за написание учебника или курса по управлению версиями API. Это тема, с которой сталкивается далеко не каждый разработчик, но ею занимаются сотни или даже тысячи компаний, и хотя тема довольно широкая, она достаточно специфична, чтобы можно было объединить опыт и идеи в одном ресурсе.
И таких точечно-актуальных тем самого разного масштаба полным полно, ну например навскидку: миграции баз данных, корпоративные поисковые системы, рекомендательные системы, системы управления рабочими задачами, преобразование данных между разными форматами, тэгирование, как использовать конкретные популярные API (Github или OpenAI) и т. д.
Только тут конечно важно понимать, что без поддержки со стороны можно потратить год на написание такой книги, а потом купят её два с половиной человека (скорее всего). Усилий в продвижение подобных инфопродуктов, сколь бы полезными они ни были сами по себе, надо вкладывать, увы, ещё побольше, нежели в их создание.
🔥8🤔4✍2👍2
Не перестаю удивляться глубине падения мэйнстрима :)
Ну например, вы создаёте очередной поисковик котиков, для чего берёте готовое key-value хранилище, в котором храните индексы в вашем поисковике (b-tree).
Да, но ваше готовое key-value хранилище внутри себя, в файле файловой системы на своём внутреннем уровне тоже хранит свои индексы (b-tree).
Да, но ваша файловая система на своём уровне тоже хранит свои индексы файловых дескрипторов (b-tree)...
Ну и зачем нужны эти три эквивалентных по сути уровня?
Если хотите получить выигрыш в производительности в 1000 раз, пишите б-три на сишечке для bare metal, ну как минимум как можно более нативно.
Очень хорошо погуглить например "erlang bare metal"
Ну например, вы создаёте очередной поисковик котиков, для чего берёте готовое key-value хранилище, в котором храните индексы в вашем поисковике (b-tree).
Да, но ваше готовое key-value хранилище внутри себя, в файле файловой системы на своём внутреннем уровне тоже хранит свои индексы (b-tree).
Да, но ваша файловая система на своём уровне тоже хранит свои индексы файловых дескрипторов (b-tree)...
Ну и зачем нужны эти три эквивалентных по сути уровня?
Если хотите получить выигрыш в производительности в 1000 раз, пишите б-три на сишечке для bare metal, ну как минимум как можно более нативно.
Очень хорошо погуглить например "erlang bare metal"
🔥15🫡3👏2👍1
Простой пример логических уровней думания о коде. Есть общеизвестные правила DRY и SoC, которые плохо обученные программисты (сокр. попы) реализуют примерно так: завидя схожие куски кода, бездумно бросаются рефакторить их в одну функцию с настроечными параметрами (DRY), а завидя один здоровый монолитный кус кода, бездумно бросаются делить его на несколько автономных, изолированных, иногда даже чистых функций (SoC).
Подождите, это совсем неверный подход, сплошная робертмартинфаулерщина.
Правильно так: если две (возможно, вообще не похожих) части кода реализуют одну бизнес-концепцию, то их надо объединить (возможно, не в одну функцию, но как минимум в одну синтаксическую или семантическую единицу -- в один файл, в один класс), а если часть кода реализует две или более бизнес-концепций, то её надо соответственно разделить.
Принцип SRP должен превалировать именно в смысле бизнес-логики.
Подождите, это совсем неверный подход, сплошная робертмартинфаулерщина.
Правильно так: если две (возможно, вообще не похожих) части кода реализуют одну бизнес-концепцию, то их надо объединить (возможно, не в одну функцию, но как минимум в одну синтаксическую или семантическую единицу -- в один файл, в один класс), а если часть кода реализует две или более бизнес-концепций, то её надо соответственно разделить.
Принцип SRP должен превалировать именно в смысле бизнес-логики.
👍15✍8👏2🫡2🔥1
Про хипстерский полиморфизм в не-очень-хипстерских языках.
"Обычный" полиморфизм (как в дженериках Java) позволяет писать функции над конкретными контейнерами с произвольным типом данных, например: написать функцию над List<X> для любого типа X. Но чтобы писать функции над любым контейнером -- например, одну функцию, которая работает и со списками, и с деревьями -- нужно уметь абстрагировать и List<X>, и Tree<X>, в F<X>, где F представляет функцию произвольного типа.
Некоторые языки, включая Haskell, допускают подобный полиморфизм второго порядка, но большинство языков с поддержкой полиморфизма этого не умеют. Но есть трюк, как превратить этот вид полиморфизма высшего порядка в то, что Java или OCaml могут обработать -- расскажу скоро об этом курсантам в СильныхИдеях, а главное, про соответствующую думательную машинку, универсальную технику, родившуюся из исследований в области компиляции функционально-логических языков в языки логического программирования "первого порядка" вроде Пролога. Она охватывает и полиморфизм высшего порядка, и неблокирующий ввод/вывод, и трансформации рекурсии-итерации, и распределённые вычисления, и т. п.
"Обычный" полиморфизм (как в дженериках Java) позволяет писать функции над конкретными контейнерами с произвольным типом данных, например: написать функцию над List<X> для любого типа X. Но чтобы писать функции над любым контейнером -- например, одну функцию, которая работает и со списками, и с деревьями -- нужно уметь абстрагировать и List<X>, и Tree<X>, в F<X>, где F представляет функцию произвольного типа.
Некоторые языки, включая Haskell, допускают подобный полиморфизм второго порядка, но большинство языков с поддержкой полиморфизма этого не умеют. Но есть трюк, как превратить этот вид полиморфизма высшего порядка в то, что Java или OCaml могут обработать -- расскажу скоро об этом курсантам в СильныхИдеях, а главное, про соответствующую думательную машинку, универсальную технику, родившуюся из исследований в области компиляции функционально-логических языков в языки логического программирования "первого порядка" вроде Пролога. Она охватывает и полиморфизм высшего порядка, и неблокирующий ввод/вывод, и трансформации рекурсии-итерации, и распределённые вычисления, и т. п.
🔥8👏3👍2
У меня есть небольшой дополнительный курс "Быстрая прокачка в ООП" - 9 контринтуитивных правил, одно из которых предлагает в частности выделять все перечислимые сущности в программе в отдельные типы. И тут даже профессиональные разработчики допускают типичные ошибки, и потом жалуются, что код дескать со временем только усложняется.
Например, список инвентаря героя желательно делать не как обычный стандартный контейнер List<Item> , для которого допустима куча совсем ненужных и потенциально опасных операций, а как класс HeroItems. Для него допустим лишь небольшой набор операций -- например, по Id предмета изменить его износ или стоимость, или выбросить предмет, и т. п.
Человек пишет класс, в котором объявляет приватный список List<Item> и публичные методы с наглядными именами и удобными параметрами для работы с ним. Вроде как всё получилось здорово?
Однако по мере развития проекта оказывается, что над элементами списка требуется ещё много чего другого делать; в класс напихиваются методы, во многом аналогичные операциям над стандартным списком, и код просто впустую разбухает и разбухает. И через некоторое время принимается волевое решение вообще избавиться от класса HeroItems и вернуться обратно к List<Item>)))
(Что, впрочем, со временем всё равно приводит к множеству других проблем...)
Да, потому что тут (в обоих этих случаях) был нарушен важный и весьма глубокий универсальный принцип хорошего дизайна, который начинается не с выписывания классов "здравым смыслом", а с проектирования алгебры автономных АТД со своими операциями; соответствующую методику разбираем в частности на третьем курсе по ООАП.
Засада в том, что любая подобная методика подразумевает довольно много абстрактного и глубокого думания в далёком отрыве от кода, и вот 98% прошедших этот курс нифига особо не думают, а просто отделываются интуитивным коротеньким описанием множеств классов, которые ум генерирует на быстром мышлении S1, без тяжёлого интеллектуального напряга.
И в результате получают именно тот "результат", на который я исходно и рассчитывал: когда в последнем задании они собирают прототип, то оказывается, что он вообще получился не работоспособным, в проекте зияют огромные дыры и пустоты :) Тут и возникает то самое важное понимание, которого я планировал добиться, ну и на следующей паре итераций по методике результаты уже получаются достаточно удовлетворительные.
Например, список инвентаря героя желательно делать не как обычный стандартный контейнер List<Item> , для которого допустима куча совсем ненужных и потенциально опасных операций, а как класс HeroItems. Для него допустим лишь небольшой набор операций -- например, по Id предмета изменить его износ или стоимость, или выбросить предмет, и т. п.
Человек пишет класс, в котором объявляет приватный список List<Item> и публичные методы с наглядными именами и удобными параметрами для работы с ним. Вроде как всё получилось здорово?
Однако по мере развития проекта оказывается, что над элементами списка требуется ещё много чего другого делать; в класс напихиваются методы, во многом аналогичные операциям над стандартным списком, и код просто впустую разбухает и разбухает. И через некоторое время принимается волевое решение вообще избавиться от класса HeroItems и вернуться обратно к List<Item>)))
(Что, впрочем, со временем всё равно приводит к множеству других проблем...)
Да, потому что тут (в обоих этих случаях) был нарушен важный и весьма глубокий универсальный принцип хорошего дизайна, который начинается не с выписывания классов "здравым смыслом", а с проектирования алгебры автономных АТД со своими операциями; соответствующую методику разбираем в частности на третьем курсе по ООАП.
Засада в том, что любая подобная методика подразумевает довольно много абстрактного и глубокого думания в далёком отрыве от кода, и вот 98% прошедших этот курс нифига особо не думают, а просто отделываются интуитивным коротеньким описанием множеств классов, которые ум генерирует на быстром мышлении S1, без тяжёлого интеллектуального напряга.
И в результате получают именно тот "результат", на который я исходно и рассчитывал: когда в последнем задании они собирают прототип, то оказывается, что он вообще получился не работоспособным, в проекте зияют огромные дыры и пустоты :) Тут и возникает то самое важное понимание, которого я планировал добиться, ну и на следующей паре итераций по методике результаты уже получаются достаточно удовлетворительные.
👍12🔥9
Как Amazon Prime Video повысил масштабируемость и сократил стоимость сопровождения проекта в 10 раз, отказавшись от безсерверной лямбда-архитектуры в пользу монолита :)
🤔5🔥3
Ещё в 90-е, когда я писал свои первые книги по программированию, довольно быстро обнаружил в существовавших учебниках систематическую ошибку подразумеваемых коротких расстояний в понимании (а у меня всяческих книг по программированию и computer science до сих пор дома сотни). Интернет позволил оперативно получать обратную связь, и я быстро выяснил, что у 90% начинающих большая проблема в понимании понятия "переменная".
Я сделал всего один шаг назад, уделив особый акцент этой теме, и мой самоучитель программирования стал бестселлером того времени. В моём сегодняшнем курсе для начинающих с нуля по многим темам я вот так отступаю на шаг назад, избегая любых умолчаний, и набралась интересная статистика по типовым ошибкам -- уже чуть более абстрактным. Сегодня я хорошо вижу, как сделать второй шаг назад, чтобы приблизить процесс обучения программированию с нуля к идеальному, но -- мои начальные курсы в ноябре 22-го я закрыл навсегда, и сосредотачиваюсь исключительно не переподготовке профессиональных разработчиков с хорошим опытом.
Сегодня множество курсов тоже разбирают понятие переменной достаточно подробно, но по-прежнему остаются только на одном понятийном шаге. Они рассказывают например такую ересь, что дескать Python отлично подходит для начального обучения программированию, предлагая на своих курсах унылую метафору "переменная -- это просто коробка для хранения".
Почему это не так?
Состояние -- это крайне вредная концепция для начинающих, особенно если язык допускает его свободное использование. Конечно, State нужно уметь применять, но очень осторожно, редко и максимально безопасно. Продвинутое программирование стремится к иммутабельности и stateless (и на уровне кода, и на уровне архитектуры, и на уровне тестов), а раннее или излишнее использование состояния быстро приводит к беспорядку и запутыванию (прежде всего в голове разработчика). Недаром в Оксфорде с первого же курса принуждают к хаскелю, и в итоге человек становится способен общаться на уровне цивилизованного undergraduate.
Я сделал всего один шаг назад, уделив особый акцент этой теме, и мой самоучитель программирования стал бестселлером того времени. В моём сегодняшнем курсе для начинающих с нуля по многим темам я вот так отступаю на шаг назад, избегая любых умолчаний, и набралась интересная статистика по типовым ошибкам -- уже чуть более абстрактным. Сегодня я хорошо вижу, как сделать второй шаг назад, чтобы приблизить процесс обучения программированию с нуля к идеальному, но -- мои начальные курсы в ноябре 22-го я закрыл навсегда, и сосредотачиваюсь исключительно не переподготовке профессиональных разработчиков с хорошим опытом.
Сегодня множество курсов тоже разбирают понятие переменной достаточно подробно, но по-прежнему остаются только на одном понятийном шаге. Они рассказывают например такую ересь, что дескать Python отлично подходит для начального обучения программированию, предлагая на своих курсах унылую метафору "переменная -- это просто коробка для хранения".
Почему это не так?
Состояние -- это крайне вредная концепция для начинающих, особенно если язык допускает его свободное использование. Конечно, State нужно уметь применять, но очень осторожно, редко и максимально безопасно. Продвинутое программирование стремится к иммутабельности и stateless (и на уровне кода, и на уровне архитектуры, и на уровне тестов), а раннее или излишнее использование состояния быстро приводит к беспорядку и запутыванию (прежде всего в голове разработчика). Недаром в Оксфорде с первого же курса принуждают к хаскелю, и в итоге человек становится способен общаться на уровне цивилизованного undergraduate.
❤15🫡5👍4✍2🔥1
Есть распространённое и верное по большому счёту мнение, что идеи сегодня ничего не стоят, главное -- это их реализация и маркетинг. Действительно, за подавляющее большинство идей никто не даст и двух копеек, их в сети полным полно.
Но вот идеи с реальным потенциалом прорастания, с планом продаж, с маркетинговым планом, с планом роста, который можно обосновать и защитить... Вещи, которые можно сделать сейчас, вещи, где можно создать дрянной прототип -- и всё равно продать его, и не обязательно создавать идеальную вещь, она и так проявится на рынке... эти идеи очень редки.
Например, вероятно, это транзакционная модель программирования -- без эксплицитной сетевой работы или многопоточности: вы пишете обычный код, а система сама распределяет модель по ядрам, процессам и серверам, спекулятивно запуская обновления данных, затем фиксируя их или прерывая...
Но вот идеи с реальным потенциалом прорастания, с планом продаж, с маркетинговым планом, с планом роста, который можно обосновать и защитить... Вещи, которые можно сделать сейчас, вещи, где можно создать дрянной прототип -- и всё равно продать его, и не обязательно создавать идеальную вещь, она и так проявится на рынке... эти идеи очень редки.
Например, вероятно, это транзакционная модель программирования -- без эксплицитной сетевой работы или многопоточности: вы пишете обычный код, а система сама распределяет модель по ядрам, процессам и серверам, спекулятивно запуская обновления данных, затем фиксируя их или прерывая...
❤12🫡3👏1🤯1
Разработчик -- это тот, кто пишет код, а инженер -- это тот, кто проектирует решения с помощью кода и system design. С некоторой расплывчатостью на границах между собственно инженерией и тем, как видят продукт заказчики и пользователи.
🫡10🤔9✍1🔥1
Какой метод обучения проектированию и system design самый лучший?
Ну, если бы я точно знал, что у кого-то есть такой метод более лучший, чем у меня, я бы сразу пошёл к нему учиться, а потом стал бы сам его преподавать :)
Поэтому я и учился так не один раз, и продолжаю изучать темки, которые преподаёт небольшое число продвинутых PhD (по всему миру их меньше пальцев на руках!), и адаптирую их для моей Школы.
Просто учебного контента даже из единичных сильных источников много, и его творческая фильтрация и переработка требует прилично времени.
При этом конечно у меня возникает определённая профессиональная деформация: ребята, которые занимаются на Higher Work, судя по их отчётам, думают над своими конкретными проектами уже куда круче, чем я сам бы смог на их месте :) А я же сдвигаюсь именно в область подготовки соответствующих образовательных материалов, вот закончил на днях новый курс "Основы функционального программирования": в целом, ничего инновационного, но постарался сделать супер-компактно, выжимка из выжимок из выжимок.
...то, что я делаю, ну в некотором смысле экзистенциальное хакерство :) взлом ритмов курсов, похищение смыслов, ... самых вкусных полезняшек, свёртка, адаптация под примерный уровень занимающихся.
И это отнюдь не даётся легко. По крайней мере, с языками программирования и этими вашими веб-фреймворками, у вас есть куча онлайн-курсов и гайдов начиная с уровня “hello world”. Всё в мире проектирования и формальных подходов спрятано в научных статьях, толстых книгах по 5000 рублей и курсах по нескольку тысяч долларов.
Ну, если бы я точно знал, что у кого-то есть такой метод более лучший, чем у меня, я бы сразу пошёл к нему учиться, а потом стал бы сам его преподавать :)
Поэтому я и учился так не один раз, и продолжаю изучать темки, которые преподаёт небольшое число продвинутых PhD (по всему миру их меньше пальцев на руках!), и адаптирую их для моей Школы.
Просто учебного контента даже из единичных сильных источников много, и его творческая фильтрация и переработка требует прилично времени.
При этом конечно у меня возникает определённая профессиональная деформация: ребята, которые занимаются на Higher Work, судя по их отчётам, думают над своими конкретными проектами уже куда круче, чем я сам бы смог на их месте :) А я же сдвигаюсь именно в область подготовки соответствующих образовательных материалов, вот закончил на днях новый курс "Основы функционального программирования": в целом, ничего инновационного, но постарался сделать супер-компактно, выжимка из выжимок из выжимок.
...то, что я делаю, ну в некотором смысле экзистенциальное хакерство :) взлом ритмов курсов, похищение смыслов, ... самых вкусных полезняшек, свёртка, адаптация под примерный уровень занимающихся.
И это отнюдь не даётся легко. По крайней мере, с языками программирования и этими вашими веб-фреймворками, у вас есть куча онлайн-курсов и гайдов начиная с уровня “hello world”. Всё в мире проектирования и формальных подходов спрятано в научных статьях, толстых книгах по 5000 рублей и курсах по нескольку тысяч долларов.
🫡7👍6❤4🔥2