maxcode.dev
100 subscribers
9 photos
9 links
Download Telegram
Стек вызовов

На собеседованиях часто дают задачи на рекурсию, а потом просят перерешать без рекурсии. Зачем? 🤦🏻‍♂️

Дело в том, что рекурсивное решение потенциально приводит к переполнению call stack (стека вызовов). Проблема в том, что часто собеседующий сам не понимает, в каком случае этот самый колстек переполняется. Например, некоторые думают, что глубина стека измеряется максимальным количеством рекурсивных вызовов.

Давайте позапускаем код и ответим на следующие вопросы:

✓ В чем измеряется размер кол стека и можно ли его измнить?
✓ Что хранится на стеке?
✓ Сколько раз можно вызвать функцию рекурсивно?
✓ Как переполнить стек без рекурсии и даже без вызова функций вообще?

https://www.youtube.com/watch?v=D6MGnUBSdSU

PS. Видео про то, как решать задачи на рекурсию с помощью рекурсии и без рекурсии, будет отдельно. Напоминаю, что задачи на рекурсию у нас вот здесь: https://maxcode.dev/courses/recursion
13👍2🔥2
🚀 Особенности Promise.race

Продолжаю записывать видео на ютуб. И новое видео про Promise.race:
https://www.youtube.com/watch?v=wJW4UEMBgGY

Вообще из всех четырех методов, позволяющих работать с промисами конкурентно, Promise.race самый простой. Во всех остальных мы собираем какой-то массив, дожидаемся окончания работы всех промисов, а еще нужно не забыть учесть порядок. Тут алгоритм гораздо проще.

Поэтому в новом видео я концентрируюсь на общих для всех методов принципах:

✓ Что принимают race/all/allSettled/any и почему это опять iterable
✓ Как обрабатывается ситуация, когда внутри лежит не промис
✓ Что будет если передать пустой итерабл или вообще не итерабл

Статические методы

Когда мы проходим тему ООП и разбираем статические методы, всегда возникает вопрос, зачем они вообще нужны, если мы можем обычную функцию создать. В целом мой ответ обычно заключается в том, что статические методы реально и не нужны, а были содраны с джавы, где нельзя создать функцию отдельно от класса.

Но Promise.race отличный пример, где активно используется факт того, что функция race лежит в классе Promise. Разбираю это в конце видео, если что, есть таймкоды 😉

На сайте обновил шпаргалку по промисам.

Многие теряются в нестандартных ситуациях, например, когда мы методом catch подписываемся на fulfilled промис. Или не понимают, как определяется статус промиса, который возвращается из then.

Я постарался описать всё это поведение. Будет полезно перечитать, даже если мы уже с вами разбирали асинхронность. Ну а с кем мы еще не дошли до асинхронного программирования, это будет полезной теорией, потому что нормальной теории в интернете очень мало.
🔥73👍3
Зачем нужен React ⚛️

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

Напомню, что React вышел в паблик в 2013 году, а до этого использовался внутри Фейсбука, где его и разработали. Это, кстати, к вопросу как часто во фронтенде что-то меняется и нужно учить что-то новое. Не часто, 10 лет не меняется.

И я вспомнил про Александра Соловьева, у которого был доклад в 2014 году. Это вам ретроспективно сейчас расскажут, почему реакт стал успешным. Но лучше послушать это от человека из 2014 года. Примеры кода интересные там. Как вы знаете, до функциональных компонентов с хуками были классы. Но классы в джаваскрипте появились в ES2015. Что же было до них? :)

В общем, я пересмотрел доклад (само выступление 18 минут или 9 минут на 2x) и Александр рассказывает всё очень правильно. Вот ссылка: https://www.youtube.com/watch?v=aFUiULAC6zk

А теперь давайте я кратко перескажу две важные вещи, которые нам дал React.

1️⃣ Реакт позволил объединить HTML и CSS, повышая cohesion. Кохижн — это когда штуки, которые об одном, лежат рядом. Ну, типа, есть папка с компонентом, а рядом с ним CSS-модули, картинки для этого компонента, вспомогательные функции и тесты. А 20 лет назад отдельно был целиком HTML всего сайта и отдельно джаваскрипт, который в этом большом файле искал по селекторам нужные куски.

Сюда же идет удобная работа с событиями. Мы особо не разбираем на занятиях работу с событиями браузера напрямую, потому что рыночек порешал и для работы вам это особо не нужно. Но есть много проблем, которые реакт решает, предоставляя вам простой пропс onClick.

Кстати, кохижн — это один из принципов GRASP (wikipedia). По-моему, GRASP в сто раз важнее SOLID, но об этом в другой раз давайте.

2️⃣ Реакт решил проблему комбинаторного взрыва. Когда у вас много кусков системы, которые влияют друг на друга, то при изменении одного из них, нужно учесть это в других. Если у вас 10 модулей, то взаимодействий между ними 10 × 9 = 90 (каждый с каждым). А в случае реакта мы должны для каждого компонета уазать, как он влияет на стейт и в кажом компоненте указать, как он от стейта зависит. Это 10 + 10 = 20 взаимодействий. В первом случае ментальная сложность программы растет квадратично, во втором — линейно.

Из минусов Александр называет отсутвие Model Layer, то есть слоя с данными, грубо говоря. Это та проблема, которую потом будут решать стейт-менеджеры типа редакса. Но редакс будет представлен Даней Абрамовым только через год.

Кстати, примерно в это время Абрамов выступает на митапах в Питере на русском языке, рассказывая про сам React. Есть запись с испорченным звуком (https://www.youtube.com/watch?v=nwtQMSFikUk). Организаторы митапа ее скрыли, потому поиском не найти.

Наконец, еще можно посмотреть доклад от разработчиков реакта 2013 года, где они его представляют, тоже полезно (https://www.youtube.com/watch?v=GW0rj4sNH2w). Но там не так весело, как у Соловьева.
🔥16👍1
29 лет 🎉

Википедия со ссылкой на оригинальную новость (сохраненную веб-архивом) говорит, что 4 декабря 1995 можно считать днем рождения джаваскрипта.

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

Например, вот таймлайн языков по годам. Можно провести более глубокий анализ, но видно, что Java, PHP, Ruby и JavaScript все в 1995 году появились. Это как 1999 в истории кино: Зеленая миля, Матрица, Бойцовский клуб, Шестое чувство, Мумия и так далее. Так что все в рамках мейнстрима.

Помимо года в табличке указывается, наследником каких языков был новый язык. У JS это Self (прототипное наследование), C (синтаксис) и Scheme (функции высшего порядка).

В 2015, когда существенно менялась спецификация EcmaScript (ES5 → ES6), Allen Wirfs-Brock был ее редактором и к двадцатилетию подготовил книжку «JavaScript: The First 20 Years» (ссылка на пдфку с его сайта), где постарался восстановить логику принимаемых решений, подкрепив ее историческими документами.

Это я к чему. Бросайте смотреть блогеров на ютубе (особено русскоязычных), которые пересказывают друг друга, по дороге теряя смысл излагаемого материала. Читайте первоисточники. Если интересна история языка, например, то читайте тексты людей, которые эту историю создавали 😉
🎉16👍3🔥1
Как вы знаете, наш канал в первую очередь не про фронтенд, а про деньги. И сегодня мы поговорим про финансирование терроризма.

Обычно мы договариваемся, что вы оплачиваете занятия переводом на карту через СБП по номеру телефона. И иногда у меня ученики спрашивают про налоговую и когда за мной придут.

Давайте расскажу. Так как вся наша деятельность происходит в контуре некого государства, то оно тоже хочет быть в доле. И как мы поняли за последние три года, забрать деньги не самое страшное, что может государство может с тобой сделать. Поэтому с нами рубрика «плоти нологи».

1. Самозанятость

Для того, чтобы платить налоги, можно оформить ИП или самозанятость. У самозанятости есть одно главное ограничение: через нее можно проводить суммарно до 2.4 млн в год. В остальном — одни преимущества. Оформляется в несколько кликов через приложение на айфоне, не нужно никаких документов, отдавать налогами надо 4% с платежа.

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

Промежуточный итог: банк не в курсе, плачу я налоги или нет, потому что это делается через приложение налоговой.

2. Налоговая

Мы все, конечно, под колпаком, и налоговая прекрасно знает, кто кому, когда и что переводит. Но если вы занимаетесь репетиторством или сдаете квартиру, вы мелкая рыбешка для них.

С другой стороны, до 2020 года, например, мелкой рыбешкой также считались вкладчики банков. А теперь я плачу почти 15% с 20% годовых на вкладах (3% с капитала в год получается). Люди — новая нефть, так что за всеми рано или поздно придут. Но за репетиторами не сегодня.

Промежуточный итог: со всякими предъявами придет не налоговая.

3. Банки и Набиуллина

На практике (моей, хе-хе) приходят банки. Причем не с тем, что ты не платишь налоги, а со 115 ФЗ.

ФЗ — это федеральный закон. 155 ФЗ — это федеральный закон «О противодействии легализации (отмыванию) доходов, полученных преступным путем, и финансированию терроризма».

Если вкратце, то банки не хотят получит нагоняй от госпожи Набиуллиной за то, что у них много стремных клиентов с непоятными платежами. Кстати, им есть чего бояться, так-то. В 2013 году в России было больше 1000 банков, сейчас чуть больше 300. Так что это наша «Баффи — истребительница вампиров»: «Эльвира — истребительница банков».

В общем, тут мораль в том, что банки не лично против тебя настроены, а против большого процента клиентов с сомнительной историей операций, потому что боятся санкций со стороны ЦБ. Если банку не нравятся твои операции, то они могут заблокировать счет и запросить документы, подтверждающие операции. И вот тут есть два типа банков.

4. Банки и я

В позапрошлом году мне 115 ФЗ пригрозил Тинькофф. Они попросили предоставить документы, но дали неделю на выход, если не договоримся. Но, в общем, договорились, потому что по-другому было бы больно. Это мой основной брокер, было бы неудобно управлять своим портфелем, не имея возможности заводить туда деньги. Это первый тип банков: вежливо присылают письмо и дают время на выход.

А бывают второго типа. На днях у меня тупо перестало открываться приложение банка УБРиР на телефоне. После того, как оно не открывалось несколько дней, я позвонил на горячую линию, где оператор создал заявку по моей проблеме. И спустя еще какое-то время мне пришло письмо, где просят объяснить происхождение моих миллионов.

Вы у меня спрашивали: почему деньги переводятся на неизвестный банк УБРиР. Отвечаем: потому что этот банк я ценю чуть меньше, чем Тинькофф, и если (и когда) за мной придут, то перейдем на другой банк. И вот этот день настал. Но в России осталось еще 300 банков, продолжаем работу.
🔥9😎4👍21
Мемы для лайков прилагаются
😁17🤣5
⚛️ Опенсорс и обучение

На прошлой неделе разбирали с ученицей редакс. Я попросил в качестве домашнего задания по инструкции из официальной документации добавить в проект redux-thunk.

Оказалось, что документация частично устарела, т.к. год назад в рамках большого рефакторинга — по переезду на новую систему импортов — импорты, собственно, и поменялись.

Мне кажется, ученица мне не поверила, что мы должны поправить документацию редакса. Но я поправил: https://github.com/reduxjs/redux/pull/4779 🙂

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

Если без шуток, то абсолютно нормально, если вы даже в процессе обучения находите какие-то проблемы в инструментах, которыми вы пользуетесь, особенно, если речь про маленькие библиотеки. Почти всегда их делают обычные люди, такие же как вы.

⭐️ Какой опыт можно получить, даже поправив несколько строчек в документации:

✓ Работа с git (fork, pull reuest, rebase в случае замечаний)
✓ Оформление issue и процесс contribution. Если изменение не очевидное, то нужно в определенном формате описать проблему
✓ Практика английского языка
✓ Знакомство с code of conduct (правилами поведения) при общении с другими программистами
✓ Узнать, какие технологии используются для тех же доков

⭐️ Если речь идет про изменения в коде, то выхлопа еще больше:

✓ Снова практика английского языка, но в плане кода (посмотреть, как называются файлы, переменные, функции)
✓ Пример архитектуры (на занятиях мы обычно пишем не очень большие вещи, а архитектура лучше видна на них)
✓ Увидеть процессы CI/CD (что происходит c кодом после пуша)
✓ Примеры продвинутых возможностей тайпскрипта (на занятиях мы многое разбираем, но мне не хватает примеров объяснить, зачем нужны сложные дженерики).

Вообще @reduxjs как семейство библиотек находится в очень хорошем состоянии. Mark Erikson проделал большую работу. Библиотеки redux и redux-toolkit полезно изучить, просто ознакомившись с кодом. На занятиях мы часто целиком реализуем redux, т.к. это наглядный пример двух концепций: event emitter и middleware. В redux-toolkit тоже много интересного, особенно с точки зрения тайпскрипта.

А коммитить в опенсорс для того, чтобы найти первую работу, если что, ужасная идея. Я вообще не понимаю, почему ее кто-то всерьез обсуждает. Даже не знаю, нужно ли подробнее объяснять, почему это бесполезно.
🔥15👍61
Рынок труда через 10 лет. Часть 1 🧑🏻‍💻

Напишу о том, что меня пугает на рынке труда. Про ИИ я даже не вижу смысла говорить (хотя на занятиях всех приходится успокаивать).

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

Но с кем вы конкурируете?

1. Студенты, которые учили программирование

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

Условно 90% из выпускников найдут работу и даже не почувствуют, что есть конкуренция. Типа 100 человек на 90 вакансий.

2. Люди без профильного образования (но с опытом или хорошими знаниями)

Еще одна часть вакансий уйдет на людей, которые хорошо подготовились. Если вы пришли на собеседование и просто ответили правильно на все вопросы, то условно в 70% случаев вас возьмут, потому что такие люди редкость. В основном люди никогда не получали навыки обучения, не могут сформулировать мысль и врут. Очень легко выделиться на фоне.

3. Все остальные (выпускники курсов, самоучки с низким уровнем)

Это часть рынка, где 100 человек на одно место. Отсюда из возникает ощущение, что в айти какая-то дикая конкуренция. Но эта конкуренция находится в красной зоне. В зеленой + синей зонах тоже сейчас есть небольшая конкуренция, но на несколько порядков ниже.

Сейчас достаточно выйти из красной зоны наверх. Конкуренция там будет минимальная, 12 человек на 10 мест, вы этого не почувствуете.
🔥12
Рынок труда через 10 лет. Часть 2 🧑🏻‍🎓

Теперь поговорим про демографию. На картинке изображена демографическая пирамида на начало 2024 года. Каждая горизонтальная полоска — люди одного возраста. Синие — мальчики (до 30 лет их побольше), красные — девочки (справа сверху видно, насколько пенсионерок больше, чем пенсионеров).

Количество родившихся детей считается по простой формуле:

Количество детей = Количество родителей × Количество детей на женщину

Оттолкнувшись ото дна 99 года (в 98 году объявили двойной дефолт и рожать не хотелось) и серьезно усилив рост маткапиталом с 2007 года, мы доехали от 1.16 ребенка на женщину к 1.78 в 2015 году. Все это время рожали дети перестройки, которых самих было много (на картинке это возраст ≈40 лет).

В 2015 году доллар переставился в два раза с 30 до 60 рублей. В 2014 и 2015 годах инфляция была выше, чем в 2022. Желание рожать уменьшилось. Впрочем, и рожать стало практически некому. Родителями начали становиться представители малочисленного поколения девяностых.

В результате до 2015 года перемножались два больших числа, а после — два маленьких.

⚠️ Теперь самое важное! Первым детям маткапитала исполнилось 18, они пошли в вузы. Через пару лет количество выпускников начнет стабильно расти на протяжении 10 лет. И к 2036 году вырастет на треть!

Это мотивированные дети, которые знают, что в айти есть деньги. Которые осознанно получают высшее образование и имеют хорошую базу. Мне кажется, вас не должен пугать ChatGPT, потому что это такой же иструмент как интернет или IDE.

Я думаю, что вас должен напрягать тренд, что в ближайшие 15 лет давление со стороны квалифицированных кадров будет стабильно расти, а зеленой и синей зонах наконец появится конкуренция. Хорошая новость — следующим поколениям будет еще труднее, чем вам!

🇷🇺 Это работает только для России, потому что у нас нет квалифицированных мигрантов и сильно расшатанная демографическая пирамида, на которой заметны подобные волны. В США, например, тенденция совсем другая. За последние 10 лет планочка по алгоритмическим задачам на собеседованиях в FAANG только повышалась.

PS Чтобы не заканчивать на грустной ноте, хочу обратить внимание, что сейчас на пике находится количество пятиклассников. По сути сейчас самое сложное время, чтобы поступать в хорошие школы. Буквально со следующего года количество школьников, которых будут отправлять в физмат-школы, будет падать на 3% ежегодно. Так что тем, кто родит детей сегодня, бонус: через 10-15 лет конкурс будет на 40% ниже!
🔥16
2
Наша новая рубрика — объяснение мемов и скриншотов из твитера.

Допустим, у нас есть цикл for, в котором мы увеличиваем счетчик цикла на 1. Типа такого


for (let i=0; i<N; i++);


В твите утверждается, что для каких-то N этот цикл будет работать бесконечно, потому что в какой-то момент i перестанет изменяться, потому что джаваскрипт так работает 🤷🏻

В чем тут проблема?
👍5
🧮 Числа с плавающей запятой

Когда мы говорим про тип number, то нужно понимать, что он специально создан так, чтобы он мог хранить очень маленькие числа (с достаточным количеством знаков после запятой) и очень большие числа (но для них будет храниться только порядок).

Например, 2e100 + 2e50 === 2e100. То есть гугол + корень из гугла равно гугол. Потому что когда вы прибавляете к числу со 100 нулями число с 50 нулями, число не особо сильнот отличиается от исходного.

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


let x = Number.MAX_SAFE_INTEGER; // 9007199254740991
x = x + 1; // 9007199254740992
x = x + 1; // 9007199254740992


Вот мы и застряли. Сколько раз плюc-плюс ни делай, x увеличиваться не будет.
👍5
⚡️Что такое O(n) на практике

А теперь давайте подумаем, сколько времени будет работать такой цикл, в котором мы идем до этого числа.

На занятиях по алгоритмам я спрашиваю, сколько времени работает функция со сложностью O(n). Например, когда мы ищем макисмальный элемент в массиве. Это не корректный вопрос, но часто оказывается, что люди не представляют, сколько времени выполняется код в принципе.

Примерно 20 лет назад прирост тактовой частоты процессоров остановился на отметке около 4 ГГц. Поэтому последние 20 лет мы можем достаточно точно отвечать на вопрос, сколько работает обычный цикл for примерно на любом устройстве. Для этого достаточно вспомнить, что такое гигагерц.

✓ гига — греческая приставка, означающая 1 млрд (10 ** 9)
✓ герц — единица измерения. 1 Гц = 1 / с (один делить на секунду)

Например, частота обновления экрана 60 Гц означает, что картинка на экране меняутся 60 раз в секунду.

Соответственно, 1 ГГц ≈ 1 млрд операций в секунду. Сейчас даже не так важно каких операций.


console.time("⏱️");
for(let i = 0; i < 1e9; i++);
console.timeEnd("⏱️");


Можете запустить у себя в браузере, например. Цикл с миллиардом шагов работает примерно 1 секунду.

Сколько понадобится времени, чтобы дойти до Number.MAX_SAFE_INTEGER?

✓ MAX_SAFE_INTEGER = 2 ** 53
✓ За секунду мы делаем примерно 2 ** 30 операций
✓ Итого такой цикл займет 2 53 / 2 30 = 2 ** 23 ≈ 8 млн секунд
✓ Переведем в минуты/часы/дни/месяцы: 8000000 / 60 / 60 / 24 / 30 ≈ 3 месяца

То есть вся эта проблема возникнет только если мы будем крутить холостой цикл на протяжении трех месяцев. А если в цикле что-то будет происходить, то еще дольше. То есть да, в какой-то момент цикл зависнет на одном значении i. Но этот момент произойдет через несколько месяцев непрерывной работы.
👍10
🤓 Мораль

Очень полезно понимать ограничения концепций, с которыми мы работаем (IEEE 754, IEEE Standard for Floating-Point Arithmetic). Но еще важнее понимать физические ограничения (тактовая частота процессора), при которых эти проблемы могут возникнуть примерно никогда.

Еще полезно понимать, какого порядка могут быть числа, описывающие различные значения из реального мира. И уметь сравнивать порядки этих чисел.

Кстати, в ЕГЭ по математике (в базовом, для гуманитариев) есть такая задача, где нужно сопоставить величину и ее значение. Как вы понимаете, если это есть в ЕГЭ, значит, в какой-то момент пришло осознание, что не все одиннадцатиклассники с таким справляются 🙄🔫
👍6🌚1
💣 Где читать теорию по TypeScript?

К сожалению, нормальных материалов по тайпскрипту я не нашел. Обычно все просто пересказывают документацию, не отвечая на главные вопросы: зачем и почему.

Зачем это нужно? Почему так сделали?

🤔 Почему Promise<T> параметризуется одним типом, который описывает значение value, а не двумя, например, Promise<T, E> с типами для value и reason?
🤔 Зачем в Record<string, number> нужно два типа в дженерике, если ключ у объекта это все равно всегда строка?
🤔 Почему это вообще называется дженерик? Это индийские медицинские препараты, что ли?
🤔 Зачем писать foo<T extends X>(arg: T), если можно просто написать foo(arg: X)?
🤔 Почему для arr: number[] = [] arr[10] имеет тип number, хотя там может быть undefined, если в массиве меньше элементов?

А самое главное, во всех этих видосах почти не типизируют рантайм код. Тему дженериков объясняют, показывая определение интерфейсов и типов. В первую очередь учат типизировать код, который в рантайме будет удален. А как типизировать функции, которые уже написаны на джаваскрипте, никто не рассказывает.

Тайп гарды объясняют на ООП-примерах с птичками и собачками. Я не знаю. Что вы чаще делаете на джаваскрипте? Пишете классы или используете методы массивов filter и every, которые активно используют тайп гарды?

Я накидал примерный план того, какая теория нужна для решения задач, и написал вводную часть про дженерики: стандартные дженерики для коллекций (Array, Record, Promise) и дженерик-функции (какую проблему они решают, зачем нужен extends и почему вообще в качестве названия фичи языка используется, блин, прилагательное).

Вот статья про использование джененириков в функциях: https://maxcode.dev/roadmaps/typescript/generic-functions

И, соответственно, список задач, на которых можно отрабатывать теорию https://maxcode.dev/roadmaps/typescript
👏8🔥52