🤓 Мораль
Очень полезно понимать ограничения концепций, с которыми мы работаем (IEEE 754, IEEE Standard for Floating-Point Arithmetic). Но еще важнее понимать физические ограничения (тактовая частота процессора), при которых эти проблемы могут возникнуть примерно никогда.
Еще полезно понимать, какого порядка могут быть числа, описывающие различные значения из реального мира. И уметь сравнивать порядки этих чисел.
Кстати, в ЕГЭ по математике (в базовом, для гуманитариев™) есть такая задача, где нужно сопоставить величину и ее значение. Как вы понимаете, если это есть в ЕГЭ, значит, в какой-то момент пришло осознание, что не все одиннадцатиклассники с таким справляются 🙄🔫
Очень полезно понимать ограничения концепций, с которыми мы работаем (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
К сожалению, нормальных материалов по тайпскрипту я не нашел. Обычно все просто пересказывают документацию, не отвечая на главные вопросы: зачем и почему.
Зачем это нужно? Почему так сделали?
🤔 Почему 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
👏10🔥5❤2
🤦🏻♂️ Собеседования 2025
Я сейчас собираю подборки задач с собеседований, например, в Яндекс (https://maxcode.dev/interview/yandex).
Для этого отсматриваю записи реальных собеседований. И вот принес вам одно с вайбами из новогодней серии Черного зеркала (хорошая серия, кстати).
Ссылка на собеседование: https://www.youtube.com/watch?v=RCNQWtd1GOg
Это пример того, как в 2025 проходят собеседования некоторые кандидаты. Вдесятером. Создается звонок на много человек, все слушают вопросы в прямом эфире, а потом кидают в чатик ответы, откуда главный герой их зачитывает.
С одной стороны — кандидаты, которые обсуждают, что между двумя собеседованиями надо успеть «накуриться», а собеседующий «из таких, у кого помидоры покупаю».
С другой стороны — непрофессиональное собеседование с заходами а-ля «что нового появилось в ES2015» (в 2025 году) и закрытыми вопросами (Работал с гитом? Да. Следующий вопрос).
Под видео на ютубе есть таймкоды. Вопросы максимально стандартные. Все это мы разбираем на занятиях. И все это очень просто. Намного проще того, что хорошо бы реально знать.
В очередной раз имеем подтверждение тезиса, что в 2025 году пройти собеседование намного проще, чем попасть на него.
Да, когда вы откликаетесь на вакансию, вы видите сотни откликов от других кандидатов. Но если вы попали на собеседование, то вы конкурируете вот с этим. И тут достаточно нормально ответить на вопросы и показать знания.
Я сейчас собираю подборки задач с собеседований, например, в Яндекс (https://maxcode.dev/interview/yandex).
Для этого отсматриваю записи реальных собеседований. И вот принес вам одно с вайбами из новогодней серии Черного зеркала (хорошая серия, кстати).
Ссылка на собеседование: https://www.youtube.com/watch?v=RCNQWtd1GOg
Это пример того, как в 2025 проходят собеседования некоторые кандидаты. Вдесятером. Создается звонок на много человек, все слушают вопросы в прямом эфире, а потом кидают в чатик ответы, откуда главный герой их зачитывает.
С одной стороны — кандидаты, которые обсуждают, что между двумя собеседованиями надо успеть «накуриться», а собеседующий «из таких, у кого помидоры покупаю».
С другой стороны — непрофессиональное собеседование с заходами а-ля «что нового появилось в ES2015» (в 2025 году) и закрытыми вопросами (Работал с гитом? Да. Следующий вопрос).
Под видео на ютубе есть таймкоды. Вопросы максимально стандартные. Все это мы разбираем на занятиях. И все это очень просто. Намного проще того, что хорошо бы реально знать.
В очередной раз имеем подтверждение тезиса, что в 2025 году пройти собеседование намного проще, чем попасть на него.
Да, когда вы откликаетесь на вакансию, вы видите сотни откликов от других кандидатов. Но если вы попали на собеседование, то вы конкурируете вот с этим. И тут достаточно нормально ответить на вопросы и показать знания.
👍18❤1🔥1
🛠️ Полифил Object.groupBy
Записал видео, где реализую свою версию groupBy. Писать полифилы полезно с точки зрения обучения. Одной задачей сразу можно покрыть несколько тем:
1. Функциональное программирование: метод принимает функцию
2. Прототипное наследование: метод возвращает null prototype object
3. Итераторы: groupBy принимает iterable, а не только массив
4. Современный синтаксис: nullish coalescing assignment
5. Производительность: если написать неаккуратно, то получаем решение за O(n²) вместо O(n)
6. Полезные фичи TypeScript: дженерик с несколькими параметрами, extends, Record и Partial
Видео: https://www.youtube.com/watch?v=lrlG3Nu6cgo
Записал видео, где реализую свою версию groupBy. Писать полифилы полезно с точки зрения обучения. Одной задачей сразу можно покрыть несколько тем:
1. Функциональное программирование: метод принимает функцию
2. Прототипное наследование: метод возвращает null prototype object
3. Итераторы: groupBy принимает iterable, а не только массив
4. Современный синтаксис: nullish coalescing assignment
5. Производительность: если написать неаккуратно, то получаем решение за O(n²) вместо O(n)
6. Полезные фичи TypeScript: дженерик с несколькими параметрами, extends, Record и Partial
Видео: https://www.youtube.com/watch?v=lrlG3Nu6cgo
YouTube
Полифил Object.groupBy (реализация метода groupBy)
Телеграм с новостями: https://t.me/maxcodedev
Ссылка на задачу: https://maxcode.dev/problems/object-group-by/
00:00 План видео
00:25 Как работает Object.groupBy
01:20 Первая реализация
04:42 Проблема 1. Время работы
12:35 Использование оператора ??=
15:48…
Ссылка на задачу: https://maxcode.dev/problems/object-group-by/
00:00 План видео
00:25 Как работает Object.groupBy
01:20 Первая реализация
04:42 Проблема 1. Время работы
12:35 Использование оператора ??=
15:48…
🔥9❤1🙏1
Еще один полезный навык — работа с источниками. Тоже на примере Object.groupBy покажу.
1. Спецификация EcmaScript
Когда мы пользуемся каким-то стандартным методом, мы не особо задумываемся: что еще можно туда передать? что будет, если передать что-то не то? какие операции происходят неявно? какими словами можно писать поведение функции?
2. Реализация v8 (Chrome)
Самая непонятная реализация, которая еще и написана на языке torque (вообще v8 — это двигатель внутреннего сгорания, torque — это вращающий момент). Ее сложно читать, но тут интересно, какие именно оптимизации движка используются. Например, groupBy принимает iterable, но если приходит массив, то мы идем по индексам.
3. Реализация JavaScriptCore (Safari)
Тут уже более понятный код. Есть особенности, связанные с удовлетворением спецификации и переиспользованием кода (используются специальные внутренние функции типа @putByValDirect и @toPropertyKey), но код написан на обычном джаваскрипте и понятнее, чем спецификация или реализация v8.
4. Стандартные типы TypeScript
Конкретно тут тип такой же, как я рассказал в видео. Но интересно вот что. У вас на собеседованиях часто спрашивают, чем отличаются type и interface в тайпскрипте. Вообще говоря, нормальный ответ: почти ничем. Но на собеседовании нужно по пунктам перечислять минорные различия.
Одно из них — что интерфесы «мержатся», то есть обяединяются. Если у вас в одном месте в коде написано interface A { x: number }, а в другом interface A { y: string }, то тайпскрипт будет проверять, что у A есть оба поля.
Таким же способом в тайпскрипте добавляются типы новых фич языка. Когда выходит очередная версия EcmaScript, разработчики тайпскрипта просто добавляют новый файл с типами, где описывают новые методы). Выглядит это так:
- es5.d.ts — описан конструктор Object и методы прототипа, которые были еще до ES6
- es2015.core.d.ts — новые фичи ES6 (например, getOwnPropertySymbols для только что появившихся символов)
- es2017.object.d.ts — появляются методы, возвращающие итераторы (key, values, entries)
- es2019.object.d.ts — статический метод fromEntries
- es2022.object.d.ts — статический метод hasOwn
- es2024.object.d.ts — статический метод groupBy
А потом тайпскрипт автоматически мержит все эти типы и мы получаем тип Object со всеми методами, которые появлялись в языке в разное время!
1. Спецификация EcmaScript
Когда мы пользуемся каким-то стандартным методом, мы не особо задумываемся: что еще можно туда передать? что будет, если передать что-то не то? какие операции происходят неявно? какими словами можно писать поведение функции?
2. Реализация v8 (Chrome)
Самая непонятная реализация, которая еще и написана на языке torque (вообще v8 — это двигатель внутреннего сгорания, torque — это вращающий момент). Ее сложно читать, но тут интересно, какие именно оптимизации движка используются. Например, groupBy принимает iterable, но если приходит массив, то мы идем по индексам.
3. Реализация JavaScriptCore (Safari)
Тут уже более понятный код. Есть особенности, связанные с удовлетворением спецификации и переиспользованием кода (используются специальные внутренние функции типа @putByValDirect и @toPropertyKey), но код написан на обычном джаваскрипте и понятнее, чем спецификация или реализация v8.
4. Стандартные типы TypeScript
Конкретно тут тип такой же, как я рассказал в видео. Но интересно вот что. У вас на собеседованиях часто спрашивают, чем отличаются type и interface в тайпскрипте. Вообще говоря, нормальный ответ: почти ничем. Но на собеседовании нужно по пунктам перечислять минорные различия.
Одно из них — что интерфесы «мержатся», то есть обяединяются. Если у вас в одном месте в коде написано interface A { x: number }, а в другом interface A { y: string }, то тайпскрипт будет проверять, что у A есть оба поля.
Таким же способом в тайпскрипте добавляются типы новых фич языка. Когда выходит очередная версия EcmaScript, разработчики тайпскрипта просто добавляют новый файл с типами, где описывают новые методы). Выглядит это так:
- es5.d.ts — описан конструктор Object и методы прототипа, которые были еще до ES6
- es2015.core.d.ts — новые фичи ES6 (например, getOwnPropertySymbols для только что появившихся символов)
- es2017.object.d.ts — появляются методы, возвращающие итераторы (key, values, entries)
- es2019.object.d.ts — статический метод fromEntries
- es2022.object.d.ts — статический метод hasOwn
- es2024.object.d.ts — статический метод groupBy
А потом тайпскрипт автоматически мержит все эти типы и мы получаем тип Object со всеми методами, которые появлялись в языке в разное время!
GitHub
v8/src/builtins/object-groupby.tq at main · v8/v8
The official mirror of the V8 Git repository. Contribute to v8/v8 development by creating an account on GitHub.
🔥10🤯4❤1